mirror of
https://github.com/bobwen-dev/react-templates
synced 2025-04-12 00:56:39 +02:00
error handling + test
This commit is contained in:
parent
0c58bbf1dd
commit
a317b0df1a
6
bin/rt.js
Executable file
6
bin/rt.js
Executable 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);
|
@ -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',
|
||||
|
@ -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: {}
|
||||
};
|
84
src/cli.js
84
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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};
|
@ -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,
|
||||
|
@ -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)
|
||||
];
|
||||
}),
|
||||
{
|
||||
|
@ -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: {}
|
||||
};
|
||||
|
3
test/data/invalid-scope.rt
Normal file
3
test/data/invalid-scope.rt
Normal file
@ -0,0 +1,3 @@
|
||||
<!doctype rt>
|
||||
<div rt-scope="a in a in a">
|
||||
</div
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user