From a317b0df1a3c2d61e94fc2b344d3f3cbcadec106 Mon Sep 17 00:00:00 2001 From: ido Date: Tue, 2 Dec 2014 14:30:06 +0200 Subject: [PATCH] error handling + test --- bin/rt.js | 6 +++ playground/playground.rt.js | 4 +- src/api.js | 6 ++- src/cli.js | 84 ++++++++++++++++++++++++++++++------- src/context.js | 5 +-- src/formatters/stylish.js | 15 ++++--- src/reactTemplates.js | 7 +++- test/data/invalid-scope.rt | 3 ++ test/src/test.js | 36 ++++++++++++++-- 9 files changed, 133 insertions(+), 33 deletions(-) create mode 100755 bin/rt.js create mode 100644 test/data/invalid-scope.rt diff --git a/bin/rt.js b/bin/rt.js new file mode 100755 index 0000000..397103c --- /dev/null +++ b/bin/rt.js @@ -0,0 +1,6 @@ +#!/usr/bin/env node +'use strict'; +var cli = require('../src/cli'); +var exitCode = cli.execute(process.argv); +/*eslint no-process-exit:0*/ +process.exit(exitCode); \ No newline at end of file diff --git a/playground/playground.rt.js b/playground/playground.rt.js index 45d3009..61cbace 100644 --- a/playground/playground.rt.js +++ b/playground/playground.rt.js @@ -15,7 +15,7 @@ module.exports = function () { return React.DOM.div({}, React.DOM.div({ 'id': 'myTab', 'role': 'tabpanel', - 'className': 'code-area ' + (this.props.direction || 'vertical') + 'className': 'code-area ' + (this.props.direction === 'horizontal' && 'horizontal' || 'vertical') } /* Nav tabs */, React.DOM.ul({ 'className': 'nav nav-pills', 'role': 'tablist' @@ -69,7 +69,7 @@ module.exports = function () { 'readOnly': true })))), React.DOM.div({ 'key': 'result-area', - 'className': 'result-area well ' + (this.props.direction || 'vertical'), + 'className': 'result-area well ' + (this.props.direction === 'horizontal' && 'horizontal' || 'vertical'), 'style': { marginTop: '48px' } }, React.DOM.h2({}, 'Preview:'), React.DOM.form({ 'className': 'sample-view', diff --git a/src/api.js b/src/api.js index a48f386..f4ff5e8 100644 --- a/src/api.js +++ b/src/api.js @@ -9,8 +9,9 @@ var convertTemplateToReact = reactTemplates.convertTemplateToReact; * @param {string} source * @param {{commonJS:boolean}?} options * @param {string} target + * @param {CONTEXT} context */ -function convertFile(source, target, options) { +function convertFile(source, target, options, context) { // if (path.extname(filename) !== ".html") { // console.log('invalid file, only handle html files'); // return;// only handle html files @@ -19,7 +20,7 @@ function convertFile(source, target, options) { var fsUtil = require('./fsUtil'); if (!options.force && !fsUtil.isStale(source, target)) { - console.log('target file ' + chalk.cyan(target) + ' is up to date, skipping'); + context.info('target file ' + chalk.cyan(target) + ' is up to date, skipping'); return; } @@ -34,5 +35,6 @@ function convertFile(source, target, options) { module.exports = { // convertTemplateToReact: convertTemplateToReact, convertFile: convertFile, + context: require('./context'), _test: {} }; \ No newline at end of file diff --git a/src/cli.js b/src/cli.js index 7c1d98e..a546a75 100755 --- a/src/cli.js +++ b/src/cli.js @@ -12,26 +12,63 @@ var shell = require('./shell'); var pkg = require('../package.json'); var options = {commonJS: false, force: false, json: false}; -if (process.argv.length > 2) { - var files = []; - _.forEach(process.argv.slice(2),function (param) { +//if (process.argv.length > 2) { +// var files = []; +// _.forEach(process.argv.slice(2),function (param) { +// if (param === '-v' || param === '--version') { +// console.log(pkg.version); +// } else if (param === '-h' || param === '--help') { +// printHelp(); +// } else if (param === '-c' || param === '--common') { +// options.commonJS = true; +// } else if (param === '-f' || param === '--force') { +// options.force = true; +// } else if (param === '-j' || param === '--json') { // TODO use optionator +// context.options.format = 'json'; +// } else if (param !== '--no-color') { +// files.push(param); +// } +// }); +// _.forEach(files, handleSingleFile); +// shell.printResults(context); +//} else { +// printHelp(); +//} + +function parseOptions(args) { + var parsedOptions = {_: [], version: false, commonJS: false, force: false, format: 'stylish'}; + _.forEach(args, function (param) { if (param === '-v' || param === '--version') { - console.log(pkg.version); + parsedOptions.version = true; } else if (param === '-h' || param === '--help') { printHelp(); } else if (param === '-c' || param === '--common') { - options.commonJS = true; + parsedOptions.commonJS = true; } else if (param === '-f' || param === '--force') { - options.force = true; + parsedOptions.force = true; } else if (param === '-j' || param === '--json') { // TODO use optionator + parsedOptions.format = 'json'; context.options.format = 'json'; - } else { - files.push(param); + } else if (param !== '--no-color') { + parsedOptions._.push(param); } }); - _.forEach(files, handleSingleFile); -} else { - printHelp(); + return parsedOptions; +} + +function executeOptions(currentOptions) { + var ret = 0; + if (currentOptions.help) { + printHelp(); + } else if (currentOptions.version) { + console.log(pkg.version); + } else { + _.forEach(currentOptions._, function (f) { + handleSingleFile(f, currentOptions); + }); + ret = shell.printResults(context); + } + return ret; } function printHelp() { @@ -47,11 +84,12 @@ function printHelp() { console.log(' -j, --json Report output format. [stylish,json]'); // console.log(' -ft, --format Report output format. [stylish,json]'); console.log(' --common Use Common JS output. default: false'); + console.log(' -f --force Force creation of output. default: false'); } -function handleSingleFile(filename) { +function handleSingleFile(filename, currentOptions) { if (path.extname(filename) !== '.rt') { - console.log('invalid file, only handle rt files'); + context.error('invalid file, only handle rt files', filename); return;// only handle html files } // var html = fs.readFileSync(filename).toString(); @@ -62,7 +100,7 @@ function handleSingleFile(filename) { // var js = reactTemplates.convertTemplateToReact(html); // fs.writeFileSync(filename + '.js', js); try { - api.convertFile(filename, filename + '.js', options); + api.convertFile(filename, filename + '.js', currentOptions, context); } catch (e) { context.error(e.message, filename, e.line || -1, -1, e.index || -1); // if (options.json) { @@ -74,6 +112,20 @@ function handleSingleFile(filename) { // if (options.stack) // console.log(e.stack); } +} - shell.printResults(context); -} \ No newline at end of file +/** + * Executes the CLI based on an array of arguments that is passed in. + * @param {string|Array|Object} args The arguments to process. + * @returns {int} The exit code for the operation. + */ +function execute(args) { + if (args.length > 2) { + var opts = parseOptions(args.slice(2)); + return executeOptions(opts); + } + printHelp(); + return 0; +} + +module.exports = {execute: execute, executeOptions: executeOptions}; \ No newline at end of file diff --git a/src/context.js b/src/context.js index 44362a5..dbe4cdf 100644 --- a/src/context.js +++ b/src/context.js @@ -49,10 +49,7 @@ var context = { context.messages = []; }, hasErrors: function () { - var firstError = _.find(context.messages, function(message) { - return message.level === MESSAGE_LEVEL.ERROR; - }); - return !!firstError; + return _.some(context.messages, {level: MESSAGE_LEVEL.ERROR}); }, options: { verbose: false, diff --git a/src/formatters/stylish.js b/src/formatters/stylish.js index 35e3702..1336bee 100644 --- a/src/formatters/stylish.js +++ b/src/formatters/stylish.js @@ -29,17 +29,22 @@ module.exports = function (warnings, config) { return n === 1 ? single : plural; } -// context.report(JSON.stringify(warnings, undefined, 2)); + function lineText(line) { + return line < 1 ? '' : line; + } + + // context.report(JSON.stringify(warnings, undefined, 2)); var output = table( warnings.map(function (message) { return [ '', -// message.line || 0, -// message.column || 0, + message.file, + lineText(message.line || 0), + lineText(message.column || 0), getMessageType(message), -// message.message.replace(/\.$/, ""), + // message.message.replace(/\.$/, ""), message.msg -// chalk.gray(message.ruleId) + // chalk.gray(message.ruleId) ]; }), { diff --git a/src/reactTemplates.js b/src/reactTemplates.js index 225806d..1749cbc 100644 --- a/src/reactTemplates.js +++ b/src/reactTemplates.js @@ -98,7 +98,11 @@ function generateInjectedFunc(context, namePrefix, body, params) { return generatedFuncName; } - +/** + * @param {string} html + * @param node + * @return {number} + */ function getLine(html, node) { if (!node) { return 0; @@ -360,5 +364,6 @@ function convertTemplateToReact(html, options) { module.exports = { convertTemplateToReact: convertTemplateToReact, + RTCodeError: RTCodeError, _test: {} }; diff --git a/test/data/invalid-scope.rt b/test/data/invalid-scope.rt new file mode 100644 index 0000000..7bce3e7 --- /dev/null +++ b/test/data/invalid-scope.rt @@ -0,0 +1,3 @@ + +
+