From 31cd782ba7f14756eb974a30055f5e6c5e8f8102 Mon Sep 17 00:00:00 2001 From: Danny McClanahan Date: Thu, 15 Jun 2017 12:09:02 -0400 Subject: [PATCH] [CS2] CLI: Test option parsing for current CLI (#4565) * intermediate save * add note saying where OptionParser is used in coffee command * add some more work * fix flatten functions * refactor tests * add basic test * remove unused file * compilation now hangs * remove unnecessary changes * add tests!!! * clarify a test --- src/command.coffee | 7 +++- src/optparse.coffee | 3 ++ test/argument-parsing.coffee | 73 ++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 test/argument-parsing.coffee diff --git a/src/command.coffee b/src/command.coffee index e8676123..ceff61b5 100644 --- a/src/command.coffee +++ b/src/command.coffee @@ -61,10 +61,14 @@ notSources = {} watchedDirs = {} optionParser = null +exports.buildCSOptionParser = buildCSOptionParser = -> + new optparse.OptionParser SWITCHES, BANNER + # Run `coffee` by parsing passed options and determining what action to take. # Many flags cause us to divert before compiling anything. Flags passed after # `--` will be passed verbatim to your script as arguments in `process.argv` exports.run = -> + optionParser = buildCSOptionParser() parseOptions() # Make the REPL *CLI* use the global context so as to (a) be consistent with the # `node` REPL CLI and, therefore, (b) make packages that modify native prototypes @@ -400,7 +404,6 @@ printTokens = (tokens) -> # Use the [OptionParser module](optparse.html) to extract all options from # `process.argv` that are specified in `SWITCHES`. parseOptions = -> - optionParser = new optparse.OptionParser SWITCHES, BANNER o = opts = optionParser.parse process.argv[2..] o.compile or= !!o.output o.run = not (o.compile or o.print or o.map) @@ -449,7 +452,7 @@ forkNode = -> # Print the `--help` usage message and exit. Deprecated switches are not # shown. usage = -> - printLine (new optparse.OptionParser SWITCHES, BANNER).help() + printLine optionParser.help() # Print the `--version` message and exit. version = -> diff --git a/src/optparse.coffee b/src/optparse.coffee index 1d115c5d..b107b2f7 100644 --- a/src/optparse.coffee +++ b/src/optparse.coffee @@ -8,6 +8,9 @@ # # The first non-option is considered to be the start of the file (and file # option) list, and all subsequent arguments are left unparsed. +# +# The `coffee` command uses an instance of **OptionParser** to parse its +# command-line arguments in `src/command.coffee`. exports.OptionParser = class OptionParser # Initialize with a list of valid options, in the form: diff --git a/test/argument-parsing.coffee b/test/argument-parsing.coffee new file mode 100644 index 00000000..731d87a2 --- /dev/null +++ b/test/argument-parsing.coffee @@ -0,0 +1,73 @@ +{buildCSOptionParser} = require '../lib/coffeescript/command' + +optionParser = buildCSOptionParser() + +sameOptions = (opts1, opts2, msg) -> + ownKeys = Object.keys(opts1).sort() + otherKeys = Object.keys(opts2).sort() + arrayEq ownKeys, otherKeys, msg + for k in ownKeys + arrayEq opts1[k], opts2[k], msg + yes + +test "combined options are still split after initial file name", -> + argv = ['some-file.coffee', '-bc'] + parsed = optionParser.parse argv + expected = arguments: ['some-file.coffee', '-b', '-c'] + sameOptions parsed, expected + + argv = ['some-file.litcoffee', '-bc'] + parsed = optionParser.parse argv + expected = arguments: ['some-file.litcoffee', '-b', '-c'] + sameOptions parsed, expected + + argv = ['-c', 'some-file.coffee', '-bc'] + parsed = optionParser.parse argv + expected = + compile: yes + arguments: ['some-file.coffee', '-b', '-c'] + sameOptions parsed, expected + + argv = ['-bc', 'some-file.coffee', '-bc'] + parsed = optionParser.parse argv + expected = + bare: yes + compile: yes + arguments: ['some-file.coffee', '-b', '-c'] + sameOptions parsed, expected + +test "combined options are not split after a '--'", -> + argv = ['--', '-bc'] + parsed = optionParser.parse argv + expected = arguments: ['-bc'] + sameOptions parsed, expected + + argv = ['-bc', '--', '-bc'] + parsed = optionParser.parse argv + expected = + bare: yes + compile: yes + arguments: ['-bc'] + sameOptions parsed, expected + +test "options are not split after any '--'", -> + argv = ['--', '--', '-bc'] + parsed = optionParser.parse argv + expected = arguments: ['--', '-bc'] + sameOptions parsed, expected + + argv = ['--', 'some-file.coffee', '--', 'arg'] + parsed = optionParser.parse argv + expected = arguments: ['some-file.coffee', '--', 'arg'] + sameOptions parsed, expected + + argv = ['--', 'arg', 'some-file.coffee', '--', '-bc'] + parsed = optionParser.parse argv + expected = arguments: ['arg', 'some-file.coffee', '--', '-bc'] + sameOptions parsed, expected + +test "later '--' are removed", -> + argv = ['some-file.coffee', '--', '-bc'] + parsed = optionParser.parse argv + expected = arguments: ['some-file.coffee', '-bc'] + sameOptions parsed, expected