refactor: static strict_filters, disable settigns when rendering

This commit is contained in:
harttle
2016-11-09 02:37:52 +08:00
parent 4bdc169d0f
commit cb3378b648
7 changed files with 41 additions and 41 deletions
+3 -3
View File
@@ -9,7 +9,7 @@ const Render = require('./src/render.js');
const lexical = require('./src/lexical.js'); const lexical = require('./src/lexical.js');
const Tag = require('./src/tag.js'); const Tag = require('./src/tag.js');
const Filter = require('./src/filter.js'); const Filter = require('./src/filter.js');
const Template = require('./src/parser'); const Parser = require('./src/parser');
const Syntax = require('./src/syntax.js'); const Syntax = require('./src/syntax.js');
const tags = require('./tags'); const tags = require('./tags');
const filters = require('./filters'); const filters = require('./filters');
@@ -25,7 +25,7 @@ var _engine = {
this.options = options; this.options = options;
this.tag = tag; this.tag = tag;
this.filter = filter; this.filter = filter;
this.parser = Template(tag, filter); this.parser = Parser(tag, filter);
this.renderer = Render(); this.renderer = Render();
tags(this); tags(this);
@@ -127,7 +127,7 @@ function factory(options) {
var engine = Object.create(_engine); var engine = Object.create(_engine);
engine.init(Tag(), Filter(), options); engine.init(Tag(), Filter(options), options);
return engine; return engine;
} }
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "shopify-liquid", "name": "shopify-liquid",
"version": "1.3.3", "version": "1.4.0",
"description": "Liquid template engine for JavaScript, Node.js and Browser", "description": "Liquid template engine for JavaScript, Node.js and Browser",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
+14 -5
View File
@@ -1,10 +1,12 @@
const lexical = require('./lexical.js'); const lexical = require('./lexical.js');
const Syntax = require('./syntax.js'); const Syntax = require('./syntax.js');
const assert = require('./util/assert.js'); const assert = require('./util/assert.js');
const _ = require('./util/underscore.js');
var valueRE = new RegExp(`${lexical.value.source}`, 'g'); var valueRE = new RegExp(`${lexical.value.source}`, 'g');
module.exports = function() { module.exports = function(options) {
options = _.assign({}, options);
var filters = {}; var filters = {};
var _filterInstance = { var _filterInstance = {
@@ -19,10 +21,17 @@ module.exports = function() {
var name = match[1], argList = match[2] || '', filter = filters[name]; var name = match[1], argList = match[2] || '', filter = filters[name];
if (typeof filter !== 'function'){ if (typeof filter !== 'function'){
return { if(options.strict_filters){
name: name, throw new TypeError(`undefined filter: ${name}`);
error: new TypeError(`undefined filter: ${name}`) }
}; this.name= name;
this.filter= x => x;
this.args= [];
return this;
//return {
//name: name,
//error: new TypeError(`undefined filter: ${name}`)
//};
} }
var args = []; var args = [];
+3 -13
View File
@@ -49,19 +49,9 @@ var render = {
evalOutput: function(template, scope) { evalOutput: function(template, scope) {
assert(scope, 'unable to evalOutput: scope undefined'); assert(scope, 'unable to evalOutput: scope undefined');
var val = Syntax.evalExp(template.initial, scope); return template.filters.reduce(
template.filters.some(filter => { (prev, filter) => filter.render(prev, scope),
if (filter.error) { Syntax.evalExp(template.initial, scope));
if (scope.get('liquid.strict_filters')) {
throw filter.error;
} else {
val = '';
return true;
}
}
val = filter.render(val, scope);
});
return val;
} }
}; };
+1 -2
View File
@@ -14,10 +14,9 @@ describe('filter', function() {
filter.clear(); filter.clear();
scope = Scope.factory(); scope = Scope.factory();
}); });
it('should return undefined when not registered', function() { it('should return default filter when not registered', function() {
var result = filter.construct('foo'); var result = filter.construct('foo');
expect(result.name).to.equal('foo'); expect(result.name).to.equal('foo');
expect(result.error).to.be.an('Error');
}); });
it('should throw when filter name illegal', function() { it('should throw when filter name illegal', function() {
+8 -6
View File
@@ -5,7 +5,7 @@ const mock = require('mock-fs');
chai.use(require("chai-as-promised")); chai.use(require("chai-as-promised"));
describe('liquid', function() { describe('liquid', function() {
var engine, ctx; var engine, strictEngine, ctx;
beforeEach(function() { beforeEach(function() {
ctx = { ctx = {
name: 'harttle', name: 'harttle',
@@ -18,6 +18,11 @@ describe('liquid', function() {
root: '/root/', root: '/root/',
extname: '.html' extname: '.html'
}); });
strictEngine = Liquid({
root: '/root',
extname: '.html',
strict_filters: true
});
mock({ mock({
'/root/files/foo.html': 'foo', '/root/files/foo.html': 'foo',
'/root/files/name.html': 'My name is {{name}}.', '/root/files/name.html': 'My name is {{name}}.',
@@ -40,13 +45,10 @@ describe('liquid', function() {
return engine.parseAndRender('foo{{zzz}}bar', ctx).should.eventually.equal('foobar'); return engine.parseAndRender('foo{{zzz}}bar', ctx).should.eventually.equal('foobar');
}); });
it('should render as null when filter undefined', function() { it('should render as null when filter undefined', function() {
return engine.parseAndRender('{{arr | filter1}}', ctx).should.eventually.equal(''); return engine.parseAndRender('{{"foo" | filter1}}', ctx).should.eventually.equal('foo');
}); });
it('should throw upon undefined filter when strict_filters set', function() { it('should throw upon undefined filter when strict_filters set', function() {
var opts = { return expect(strictEngine.parseAndRender('{{arr | filter1}}', ctx)).to
strict_filters: true
};
return expect(engine.parseAndRender('{{arr | filter1}}', ctx, opts)).to
.be.rejectedWith(/undefined filter: filter1/); .be.rejectedWith(/undefined filter: filter1/);
}); });
}); });
+8 -8
View File
@@ -130,14 +130,6 @@ describe('error', function() {
expect(e.message).to.contain('undefined variable: a'); expect(e.message).to.contain('undefined variable: a');
}); });
}); });
it('should throw RenderError when filter not defined', function() {
return expect(strictEngine.parseAndRender('{{1 | a}}')).to.eventually
.be.rejected
.then(function(e) {
expect(e).to.have.property('name', 'RenderError');
expect(e.message).to.contain('undefined filter: a');
});
});
it('should contain template content in err.message', function() { it('should contain template content in err.message', function() {
var html = ['1st', '2nd', '3rd', 'X{%throwingTag%} Y', '5th', '6th', '7th']; var html = ['1st', '2nd', '3rd', 'X{%throwingTag%} Y', '5th', '6th', '7th'];
var message = [ var message = [
@@ -207,6 +199,14 @@ describe('error', function() {
} }
}); });
}); });
it('should throw RenderError when filter not defined', function() {
return expect(strictEngine.parseAndRender('{{1 | a}}')).to.eventually
.be.rejected
.then(function(e) {
expect(e).to.have.property('name', 'ParseError');
expect(e.message).to.contain('undefined filter: a');
});
});
it('should throw ParseError when tag not closed', function() { it('should throw ParseError when tag not closed', function() {
return expect(engine.parseAndRender('{% if %}')).to.eventually return expect(engine.parseAndRender('{% if %}')).to.eventually
.be.rejected .be.rejected