refactor: use assert, fix: respect to express settings.views, close #16

This commit is contained in:
harttle
2016-11-03 00:43:23 +08:00
parent ce99bb56eb
commit f70b2ee203
25 changed files with 135 additions and 95 deletions
+2 -1
View File
@@ -1,5 +1,6 @@
const lexical = require('./lexical.js');
const Syntax = require('./syntax.js');
const assert = require('./util/assert.js');
var valueRE = new RegExp(`${lexical.value.source}`, 'g');
@@ -14,7 +15,7 @@ module.exports = function() {
},
parse: function(str) {
var match = lexical.filterLine.exec(str);
if (!match) throw new Error('illegal filter: ' + str);
assert(match, 'illegal filter: ' + str);
var name = match[1], argList = match[2] || '', filter = filters[name];
if (typeof filter !== 'function'){
+2 -1
View File
@@ -1,5 +1,6 @@
const lexical = require('./lexical.js');
const ParseError = require('./util/error.js').ParseError;
const assert = require('./util/assert.js');
module.exports = function(Tag, Filter) {
@@ -71,7 +72,7 @@ module.exports = function(Tag, Filter) {
function parseOutput(str) {
var match = lexical.matchValue(str);
if(!match) throw new Error(`illegal output string: ${str}`);
assert(match, `illegal output string: ${str}`);
var initial = match[0];
str = str.substr(match.index + match[0].length);
+14 -15
View File
@@ -2,13 +2,12 @@ const Syntax = require('./syntax.js');
const Promise = require('any-promise');
const mapSeries = require('./util/promise.js').mapSeries;
const RenderBreak = require('./util/error.js').RenderBreak;
const assert = require('./util/assert.js');
var render = {
renderTemplates: function(templates, scope, opts) {
if (!scope) throw new Error('unable to evalTemplates: scope undefined');
opts = opts || {};
opts.strict_filters = opts.strict_filters || false;
renderTemplates: function(templates, scope) {
assert(scope, 'unable to evalTemplates: scope undefined');
var html = '';
return mapSeries(templates, (tpl) => {
@@ -24,10 +23,10 @@ var render = {
function renderTemplate(template){
if (template.type === 'tag') {
return this.renderTag(template, scope, this.register)
return this.renderTag(template, scope)
.then(partial => partial === undefined ? '' : partial);
} else if (template.type === 'output') {
return Promise.resolve(this.evalOutput(template, scope, opts))
return Promise.resolve(this.evalOutput(template, scope))
.then(partial => partial === undefined ? '' : stringify(partial));
} else { // template.type === 'html'
return Promise.resolve(template.value);
@@ -35,25 +34,25 @@ var render = {
}
},
renderTag: function(template, scope, register) {
renderTag: function(template, scope) {
if (template.name === 'continue') {
return Promise.reject(new RenderBreak('continue'));
}
if (template.name === 'break') {
return Promise.reject(new RenderBreak('break'));
}
return template.render(scope, register);
return template.render(scope, this.register);
},
evalOutput: function(template, scope, opts) {
if (!scope) throw new Error('unable to evalOutput: scope undefined');
evalOutput: function(template, scope) {
assert(scope, 'unable to evalOutput: scope undefined');
var val = Syntax.evalExp(template.initial, scope);
template.filters.some(filter => {
if (filter.error) {
if (opts.strict_filters) {
if (this.register.strict_filters) {
throw filter.error;
} else { // render as null
val = '';
} else {
val = ''
return true;
}
}
@@ -62,8 +61,8 @@ var render = {
return val;
},
resetRegisters: function() {
return this.register = {};
initRegister: function(opts) {
return this.register = opts;
}
};
+5 -8
View File
@@ -1,5 +1,6 @@
const _ = require('./util/underscore.js');
const lexical = require('./lexical.js');
const assert = require('./util/assert.js');
var Scope = {
safeGet: function(str) {
@@ -35,14 +36,14 @@ var Scope = {
return this;
},
push: function(ctx) {
if (!ctx) throw new Error(`trying to push ${ctx} into scopes`);
assert(ctx, `trying to push ${ctx} into scopes`);
return this.scopes.push(ctx);
},
pop: function() {
return this.scopes.pop();
},
unshift: function(ctx) {
if (!ctx) throw new Error(`trying to push ${ctx} into scopes`);
assert(ctx, `trying to push ${ctx} into scopes`);
return this.scopes.unshift(ctx);
},
shift: function() {
@@ -92,9 +93,7 @@ var Scope = {
// foo[bar.coo]
if (delemiter !== "'" && delemiter !== '"') {
var j = matchRightBracket(str, i + 1);
if (j === -1) {
throw new Error(`unbalanced []: ${str}`);
}
assert(j !== -1, `unbalanced []: ${str}`);
name = str.slice(i + 1, j);
// foo[1]
if(lexical.isInteger(name)){
@@ -110,9 +109,7 @@ var Scope = {
// foo["bar"]
else {
var j = str.indexOf(delemiter, i + 2);
if (j === -1) {
throw new Error(`unbalanced ${delemiter}: ${str}`);
}
assert(j !== -1, `unbalanced ${delemiter}: ${str}`);
name = str.slice(i + 2, j);
seq.push(name);
name = '';
+2 -1
View File
@@ -1,8 +1,9 @@
const operators = require('./operators.js');
const lexical = require('./lexical.js');
const assert = require('../src/util/assert.js');
function evalExp(exp, scope) {
if (!scope) throw new Error('unable to evalExp: scope undefined');
assert(scope, 'unable to evalExp: scope undefined');
var operatorREs = lexical.operators,
match;
for (var i = 0; i < operatorREs.length; i++) {
+3 -4
View File
@@ -1,6 +1,7 @@
const lexical = require('./lexical.js');
const Promise = require('any-promise');
const Syntax = require('./syntax.js');
const assert = require('./util/assert.js');
function hash(markup, scope) {
var obj = {}, match;
@@ -18,10 +19,8 @@ module.exports = function() {
var _tagInstance = {
render: function(scope, register) {
var reg = register[this.name];
if(!reg) reg = register[this.name] = {};
var obj = hash(this.token.args, scope);
return this.tagImpl.render && this.tagImpl.render(scope, obj, reg) || Promise.resolve('');
return this.tagImpl.render && this.tagImpl.render(scope, obj, register) || Promise.resolve('');
},
parse: function(token, tokens){
this.type = 'tag';
@@ -29,7 +28,7 @@ module.exports = function() {
this.name = token.name;
var tagImpl = tagImpls[this.name];
if (!tagImpl) throw new Error(`tag ${this.name} not found`);
assert(tagImpl, `tag ${this.name} not found`);
this.tagImpl = Object.create(tagImpl);
if(this.tagImpl.parse){
this.tagImpl.parse(token, tokens);
+2 -3
View File
@@ -1,12 +1,11 @@
const lexical = require('./lexical.js');
const TokenizationError = require('./util/error.js').TokenizationError;
const _ = require('./util/underscore.js');
const assert = require('../src/util/assert.js');
function parse(html) {
var tokens = [];
if (!_.isString(html)) {
throw new TokenizationError('illegal input type');
}
assert(_.isString(html), new TokenizationError('illegal input type'));
var syntax = /({%(.*?)%})|({{(.*?)}})/g;
var result, htmlFragment, token;
+13
View File
@@ -0,0 +1,13 @@
const AssertionError = require('./error.js').AssertionError;
function assert(predicate, message) {
if (!predicate) {
if (message instanceof Error) {
throw message;
}
var message = message || `expect ${predicate} to be true`;
throw new AssertionError(message);
}
}
module.exports = assert;
+11 -1
View File
@@ -35,6 +35,16 @@ function RenderBreak(message){
RenderBreak.prototype = Object.create(Error.prototype);
RenderBreak.prototype.constructor = RenderBreak;
function AssertionError(message){
if(Error.captureStackTrace){
Error.captureStackTrace(this, this.constructor);
}
this.name = this.constructor.name;
this.message = message;
}
AssertionError.prototype = Object.create(Error.prototype);
AssertionError.prototype.constructor = AssertionError;
module.exports = {
TokenizationError, ParseError, RenderBreak
TokenizationError, ParseError, RenderBreak, AssertionError
};