error handling + test

This commit is contained in:
ido 2014-12-02 14:30:06 +02:00
parent 0c58bbf1dd
commit a317b0df1a
9 changed files with 133 additions and 33 deletions

6
bin/rt.js Executable file
View File

@ -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);

View File

@ -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',

View File

@ -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: {}
};

View File

@ -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);
}
/**
* 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};

View File

@ -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,

View File

@ -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)
];
}),
{

View File

@ -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: {}
};

View File

@ -0,0 +1,3 @@
<!doctype rt>
<div rt-scope="a in a in a">
</div

View File

@ -9,6 +9,36 @@ var cheerio = require('cheerio');
var dataPath = path.resolve(__dirname, '..', 'data');
test('invalid tests', function (t) {
var files = [
{file: 'invalid-scope.rt', issue: new reactTemplates.RTCodeError('invalid scope part \'a in a in a\'', 14, 1)}
];
t.plan(files.length);
files.forEach(check);
function check(testFile) {
var filename = path.join(dataPath, testFile.file);
var html = fs.readFileSync(filename).toString();
var error = null;
try {
reactTemplates.convertTemplateToReact(html);
} catch (e) {
error = e;
}
t.deepEqual(errorEqual(error), errorEqual(testFile.issue), 'Expect convertTemplateToReact to throw an error');
}
});
function errorEqual(err) {
return {
index: err.index,
line: err.line,
message: err.message,
name: err.name
};
}
test('conversion test', function (t) {
var files = ['div.rt', 'test.rt', 'repeat.rt'];
t.plan(files.length);
@ -36,7 +66,7 @@ function normalizeHtml(html) {
}
test('html tests', function (t) {
var files = ['scope.rt', 'lambda.rt','eval.rt', 'props.rt'];
var files = ['scope.rt', 'lambda.rt', 'eval.rt', 'props.rt'];
t.plan(files.length);
files.forEach(check);
@ -49,10 +79,10 @@ test('html tests', function (t) {
var code = reactTemplates.convertTemplateToReact(html).replace(/\r/g, '');
var defineMap = {react: React, lodash: _};
var define = function (requirementsNames, content) {
var requirements = _.map(requirementsNames,function (reqName) {
var requirements = _.map(requirementsNames, function (reqName) {
return defineMap[reqName];
});
return content.apply(this,requirements);
return content.apply(this, requirements);
};
var comp = React.createFactory(React.createClass({
render: eval(code)