From 0fd9a3fee1407adfe31931407cb4ad9d2719f429 Mon Sep 17 00:00:00 2001 From: Jeff Williams Date: Thu, 5 Jul 2012 00:00:03 -0700 Subject: [PATCH 1/3] replace broken --strict option with working --lenient option also fixes the test so that console.log actually works after it runs. --- rhino_modules/jsdoc/opts/parser.js | 5 ++--- rhino_modules/jsdoc/tag.js | 8 ++++---- test/specs/jsdoc/tag.js | 22 ++++++++++------------ 3 files changed, 16 insertions(+), 19 deletions(-) diff --git a/rhino_modules/jsdoc/opts/parser.js b/rhino_modules/jsdoc/opts/parser.js index 03839914..c1cbefc4 100644 --- a/rhino_modules/jsdoc/opts/parser.js +++ b/rhino_modules/jsdoc/opts/parser.js @@ -12,8 +12,7 @@ var common = { var argParser = new common.args.ArgParser(), ourOptions, defaults = { - destination: './out/', - strict: true + destination: './out/' }; argParser.addOption('t', 'template', true, 'The name of the template to use. Default: the "default" template'); @@ -23,7 +22,7 @@ argParser.addOption('T', 'test', false, 'Run all tests and quit.'); argParser.addOption('d', 'destination', true, 'The path to the output folder. Use "console" to dump data to the console. Default: console'); argParser.addOption('p', 'private', false, 'Display symbols marked with the @private tag. Default: false.'); argParser.addOption('r', 'recurse', false, 'Recurse into subdirectories when scanning for source code files.'); -argParser.addOption('s', 'strict', false, 'Exit immediately if a doclet is incomplete or contains errors. Default: true'); +argParser.addOption('l', 'lenient', false, 'Continue to generate output if a doclet is incomplete or contains errors. Default: false.'); argParser.addOption('h', 'help', false, 'Print this message and quit.'); argParser.addOption('X', 'explain', false, 'Dump all found doclet internals to console and quit.'); argParser.addOption('q', 'query', true, 'Provide a querystring to define custom variable names/values to add to the options hash.'); diff --git a/rhino_modules/jsdoc/tag.js b/rhino_modules/jsdoc/tag.js index db02bcc3..2368c5ef 100644 --- a/rhino_modules/jsdoc/tag.js +++ b/rhino_modules/jsdoc/tag.js @@ -86,15 +86,15 @@ exports.Tag = function(tagTitle, tagBody, meta) { } } - // validate the tag. for strict validation, throw an exception; otherwise, log a warning. + // validate the tag. in lenient mode, log a warning; otherwise, throw an exception. try { jsdoc.tag.validator.validate(this, meta); } catch (e) { - if (env.opts.strict) { - throw e; - } else { + if (env.opts.lenient) { console.log(e); + } else { + throw e; } } } diff --git a/test/specs/jsdoc/tag.js b/test/specs/jsdoc/tag.js index e2624338..eb701fab 100644 --- a/test/specs/jsdoc/tag.js +++ b/test/specs/jsdoc/tag.js @@ -8,31 +8,29 @@ describe("jsdoc/tag", function() { return tag; } - it("has strict validation enabled by default", function() { + it("is strict, not lenient, by default", function() { expect(badTag).toThrow(); }); - it("throws an exception for bad tags if strict validation is enabled", function() { - var strict = !!env.opts.strict; - - env.opts.strict = true; + it("throws an exception for bad tags if the lenient option is not enabled", function() { + var lenient = !!env.opts.lenient; + env.opts.lenient = false; expect(badTag).toThrow(); - env.opts.strict = strict; + env.opts.lenient = lenient; }); - it("doesn't throw an exception for bad tags if strict validation is disabled", function() { + it("doesn't throw an exception for bad tags if the lenient option is enabled", function() { /*jshint evil: true */ - var strict = !!env.opts.strict, - log = new Function(console.log); - + var lenient = !!env.opts.lenient, + log = eval(console.log); console.log = function() {}; - env.opts.strict = false; + env.opts.lenient = true; expect(badTag).not.toThrow(); - env.opts.strict = strict; + env.opts.lenient = lenient; console.log = log; }); }); \ No newline at end of file From 494af17d90ae376529f44de17320959fb1e860b7 Mon Sep 17 00:00:00 2001 From: Michael Mathews Date: Thu, 5 Jul 2012 22:10:07 +0100 Subject: [PATCH 2/3] Allow function to coerce command line arguments to a preferred type. Closes #143 --- node_modules/common/args.js | 11 +++++++++-- test/specs/common/args.js | 31 +++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 test/specs/common/args.js diff --git a/node_modules/common/args.js b/node_modules/common/args.js index efb56ae4..affdc79e 100644 --- a/node_modules/common/args.js +++ b/node_modules/common/args.js @@ -39,12 +39,14 @@ * @param {string} longName The equivalent long name of the option, entered like: --test. * @param {boolean} hasValue Does this option require a value? Like: -t templatename * @param {string} helpText + * @param {function} [coercer] A function to coerce the given value to a specific type. * @example * myParser.addOption('t', 'template', true, 'The path to the template.'); * myParser.addOption('h', 'help', false, 'Show the help message.'); */ - exports.ArgParser.prototype.addOption = function(shortName, longName, hasValue, helpText, canHaveMultiple) { - this._options.push({shortName: shortName, longName: longName, hasValue: hasValue, helpText: helpText, canHaveMultiple: (canHaveMultiple || false)}); + exports.ArgParser.prototype.addOption = function(shortName, longName, hasValue, helpText, canHaveMultiple, coercer) { + this._options.push({shortName: shortName, longName: longName, hasValue: hasValue, helpText: helpText, canHaveMultiple: (canHaveMultiple || false), coercer: coercer}); + if (shortName) { this._shortNameIndex[shortName] = this._options.length - 1; } @@ -139,9 +141,14 @@ name = option.longName; } + if (typeof option.coercer === 'function') { + value = option.coercer(value); + } + // Allow for multiple options of the same type to be present if (option.canHaveMultiple && hasOwnProperty.call(result, name)) { var val = result[name]; + if (val instanceof Array) { val.push(value); } else { diff --git a/test/specs/common/args.js b/test/specs/common/args.js new file mode 100644 index 00000000..2dd564c4 --- /dev/null +++ b/test/specs/common/args.js @@ -0,0 +1,31 @@ +describe("common/args", function() { + var common = {args: require('common/args')}, + argParser = new common.args.ArgParser(), + ourOptions; + + function trueFalse(v) { + var r = false; + if (v) { + if (v === 'true') { r = true; } + else if (v === 'false') { r = false; } + else { v = !!r; } + } + + return r; + } + + argParser.addOption('s', 'strict', true, 'Throw error on invalid input.', false, trueFalse); + argParser.addOption('n', 'name', true, 'The name of the project.', false); + + ourOptions = argParser.parse(['-s', 'true', '-n', 'true']); + + it('should corece a true value if a coercer is provided', function() { + expect(ourOptions.strict).toBeDefined(); + expect(ourOptions.strict).toEqual(true); + }); + + it('should corece a string value if a no coercer is provided', function() { + expect(ourOptions.name).toBeDefined(); + expect(ourOptions.name).toEqual('true'); + }); +}); \ No newline at end of file From 4ac7f4b488b6b648c9bf56959ca97b8deaa7f9ee Mon Sep 17 00:00:00 2001 From: Michael Mathews Date: Thu, 5 Jul 2012 22:23:49 +0100 Subject: [PATCH 3/3] Throw an error if user provides a command line arg value when none is allowed. Closes #142 --- node_modules/common/args.js | 3 +++ test/specs/common/args.js | 12 +++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/node_modules/common/args.js b/node_modules/common/args.js index affdc79e..bbef8152 100644 --- a/node_modules/common/args.js +++ b/node_modules/common/args.js @@ -135,6 +135,9 @@ } else { value = true; + if (next && next.charAt(0) !== '-') { + throw new Error( 'Command line option does not allow a value: ' + name ); + } } if (option.longName && shortName) { diff --git a/test/specs/common/args.js b/test/specs/common/args.js index 2dd564c4..e12836c9 100644 --- a/test/specs/common/args.js +++ b/test/specs/common/args.js @@ -15,7 +15,7 @@ describe("common/args", function() { } argParser.addOption('s', 'strict', true, 'Throw error on invalid input.', false, trueFalse); - argParser.addOption('n', 'name', true, 'The name of the project.', false); + argParser.addOption('n', 'name', true, 'The name of the project.'); ourOptions = argParser.parse(['-s', 'true', '-n', 'true']); @@ -28,4 +28,14 @@ describe("common/args", function() { expect(ourOptions.name).toBeDefined(); expect(ourOptions.name).toEqual('true'); }); + + function doParse() { + argParser.addOption('b', 'debug', false, 'Use debug mode.'); + argParser.parse(['-b', 'yesplease']); + } + + it('should throw an error if an option does not accept a value and one is given', function() { + expect(doParse).toThrow(); + }); + }); \ No newline at end of file