Path: blob/main/src/vs/platform/environment/test/node/argv.test.ts
5222 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import assert from 'assert';6import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../base/test/common/utils.js';7import { formatOptions, Option, OptionDescriptions, Subcommand, parseArgs, ErrorReporter } from '../../node/argv.js';8import { addArg } from '../../node/argvHelper.js';910function o(description: string, type: 'boolean' | 'string' | 'string[]' = 'string'): Option<any> {11return {12description, type13};14}15function c(description: string, options: OptionDescriptions<any>): Subcommand<any> {16return {17description, type: 'subcommand', options18};19}2021suite('formatOptions', () => {2223test('Text should display small columns correctly', () => {24assert.deepStrictEqual(25formatOptions({26'add': o('bar')27}, 80),28[' --add bar']29);30assert.deepStrictEqual(31formatOptions({32'add': o('bar'),33'wait': o('ba'),34'trace': o('b')35}, 80),36[37' --add bar',38' --wait ba',39' --trace b'40]);41});4243test('Text should wrap', () => {44assert.deepStrictEqual(45formatOptions({46// eslint-disable-next-line local/code-no-any-casts47'add': o((<any>'bar ').repeat(9))48}, 40),49[50' --add bar bar bar bar bar bar',51' bar bar bar'52]);53});5455test('Text should revert to the condensed view when the terminal is too narrow', () => {56assert.deepStrictEqual(57formatOptions({58// eslint-disable-next-line local/code-no-any-casts59'add': o((<any>'bar ').repeat(9))60}, 30),61[62' --add',63' bar bar bar bar bar bar bar bar bar '64]);65});6667test('addArg', () => {68assert.deepStrictEqual(addArg([], 'foo'), ['foo']);69assert.deepStrictEqual(addArg([], 'foo', 'bar'), ['foo', 'bar']);70assert.deepStrictEqual(addArg(['foo'], 'bar'), ['foo', 'bar']);71assert.deepStrictEqual(addArg(['--wait'], 'bar'), ['--wait', 'bar']);72assert.deepStrictEqual(addArg(['--wait', '--', '--foo'], 'bar'), ['--wait', 'bar', '--', '--foo']);73assert.deepStrictEqual(addArg(['--', '--foo'], 'bar'), ['bar', '--', '--foo']);74});7576test('subcommands', () => {77assert.deepStrictEqual(78formatOptions({79'testcmd': c('A test command', { add: o('A test command option') })80}, 30),81[82' --testcmd',83' A test command'84]);85});8687ensureNoDisposablesAreLeakedInTestSuite();88});8990suite('parseArgs', () => {91function newErrorReporter(result: string[] = [], command = ''): ErrorReporter & { result: string[] } {92const commandPrefix = command ? command + '-' : '';93return {94onDeprecatedOption: (deprecatedId) => result.push(`${commandPrefix}onDeprecatedOption ${deprecatedId}`),95onUnknownOption: (id) => result.push(`${commandPrefix}onUnknownOption ${id}`),96onEmptyValue: (id) => result.push(`${commandPrefix}onEmptyValue ${id}`),97onMultipleValues: (id, usedValue) => result.push(`${commandPrefix}onMultipleValues ${id} ${usedValue}`),98getSubcommandReporter: (c) => newErrorReporter(result, commandPrefix + c),99result100};101}102103function assertParse<T>(options: OptionDescriptions<T>, input: string[], expected: T, expectedErrors: string[]) {104const errorReporter = newErrorReporter();105assert.deepStrictEqual(parseArgs(input, options, errorReporter), expected);106assert.deepStrictEqual(errorReporter.result, expectedErrors);107}108109test('subcommands', () => {110111interface TestArgs1 {112testcmd?: {113testArg?: string;114_: string[];115};116_: string[];117}118119const options1 = {120'testcmd': c('A test command', {121testArg: o('A test command option'),122_: { type: 'string[]' }123}),124_: { type: 'string[]' }125} as OptionDescriptions<TestArgs1>;126assertParse(127options1,128['testcmd', '--testArg=foo'],129{ testcmd: { testArg: 'foo', '_': [] }, '_': [] },130[]131);132assertParse(133options1,134['testcmd', '--testArg=foo', '--testX'],135{ testcmd: { testArg: 'foo', '_': [] }, '_': [] },136['testcmd-onUnknownOption testX']137);138139assertParse(140options1,141['--testArg=foo', 'testcmd', '--testX'],142{ testcmd: { testArg: 'foo', '_': [] }, '_': [] },143['testcmd-onUnknownOption testX']144);145146assertParse(147options1,148['--testArg=foo', 'testcmd'],149{ testcmd: { testArg: 'foo', '_': [] }, '_': [] },150[]151);152153assertParse(154options1,155['--testArg', 'foo', 'testcmd'],156{ testcmd: { testArg: 'foo', '_': [] }, '_': [] },157[]158);159160interface TestArgs2 {161testcmd?: {162testArg?: string;163testX?: boolean;164_: string[];165};166testX?: boolean;167_: string[];168}169170const options2 = {171'testcmd': c('A test command', {172testArg: o('A test command option')173}),174testX: { type: 'boolean', global: true, description: '' },175_: { type: 'string[]' }176} as OptionDescriptions<TestArgs2>;177assertParse(178options2,179['testcmd', '--testArg=foo', '--testX'],180{ testcmd: { testArg: 'foo', testX: true, '_': [] }, '_': [] },181[]182);183});184185ensureNoDisposablesAreLeakedInTestSuite();186});187188189