mirror of
https://github.com/harttle/liquidjs.git
synced 2026-09-17 05:10:40 -07:00
coverage
This commit is contained in:
+4
-4
@@ -6,12 +6,12 @@ var doubleQuoted = /"[^"]*"/;
|
||||
var quoteBalanced = new RegExp(`(?:${singleQuoted.source}|${doubleQuoted.source}|[^'"])*`);
|
||||
|
||||
var number = /(?:-?\d+\.?\d*|\.?\d+)/;
|
||||
var bool = /true|false/i;
|
||||
var bool = /true|false/;
|
||||
var identifier = /[a-zA-Z_$][a-zA-Z_$0-9]*/;
|
||||
var subscript = /\[\d+\]/;
|
||||
|
||||
var quoted = new RegExp(`(?:${singleQuoted.source}|${doubleQuoted.source})`);
|
||||
var literal = new RegExp(`(?:${quoted.source}|${bool.source}|${number.source})`, 'i');
|
||||
var literal = new RegExp(`(?:${quoted.source}|${bool.source}|${number.source})`);
|
||||
var variable = new RegExp(`${identifier.source}(?:\\.${identifier.source}|${subscript.source})*`);
|
||||
|
||||
// range related
|
||||
@@ -19,10 +19,10 @@ var rangeLimit = new RegExp(`(?:${variable.source}|${number.source})`);
|
||||
var range = new RegExp(`\\(${rangeLimit.source}\\.\\.${rangeLimit.source}\\)`);
|
||||
var rangeCapture = new RegExp(`\\((${rangeLimit.source})\\.\\.(${rangeLimit.source})\\)`);
|
||||
|
||||
var value = new RegExp(`(?:${literal.source}|${variable.source}|${range.source})`, 'i');
|
||||
var value = new RegExp(`(?:${literal.source}|${variable.source}|${range.source})`);
|
||||
|
||||
// hash related
|
||||
var hash = new RegExp(`(?:${identifier.source})\\s*:\\s*(?:${value.source})`, 'g');
|
||||
var hash = new RegExp(`(?:${identifier.source})\\s*:\\s*(?:${value.source})`);
|
||||
var hashCapture = new RegExp(`(${identifier.source})\\s*:\\s*(${value.source})`, 'g');
|
||||
|
||||
var tagLine = new RegExp(`^\\s*(${identifier.source})\\s*(.*)\\s*$`);
|
||||
|
||||
@@ -2,21 +2,6 @@ const lexical = require('./lexical.js');
|
||||
const Exp = require('./expression.js');
|
||||
const TokenizationError = require('./error.js').TokenizationError;
|
||||
|
||||
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(scope, obj, reg) || '';
|
||||
},
|
||||
parse: function(tokens){
|
||||
if(this.tagImpl.parse){
|
||||
this.tagImpl.parse(this.token, tokens);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
function hash(markup, scope) {
|
||||
var obj = {};
|
||||
lexical.hashCapture.lastIndex = 0;
|
||||
@@ -31,6 +16,27 @@ function hash(markup, scope) {
|
||||
module.exports = function() {
|
||||
var tagImpls = {};
|
||||
|
||||
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(scope, obj, reg) || '';
|
||||
},
|
||||
parse: function(token, tokens){
|
||||
this.type = 'tag';
|
||||
this.token = token;
|
||||
this.name = token.name;
|
||||
|
||||
var tagImpl = tagImpls[this.name];
|
||||
if (!tagImpl) throw new Error(`tag ${this.name} not found`);
|
||||
this.tagImpl = Object.create(tagImpl);
|
||||
if(this.tagImpl.parse){
|
||||
this.tagImpl.parse(token, tokens);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function register(name, tag) {
|
||||
if (typeof tag.render !== 'function') {
|
||||
throw new Error(`expect ${name}.render to be a function`);
|
||||
@@ -38,15 +44,9 @@ module.exports = function() {
|
||||
tagImpls[name] = tag;
|
||||
}
|
||||
|
||||
function construct(token) {
|
||||
var tagImpl = tagImpls[token.name];
|
||||
if (!tagImpl) throw new Error(`tag ${token.name} not found`);
|
||||
|
||||
function construct(token, tokens) {
|
||||
var instance = Object.create(_tagInstance);
|
||||
instance.token = token;
|
||||
instance.type = 'tag';
|
||||
instance.name = token.name;
|
||||
instance.tagImpl = Object.create(tagImpl);
|
||||
instance.parse(token, tokens);
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ module.exports = function(liquid) {
|
||||
}
|
||||
|
||||
if (!this.candidates.length){
|
||||
throw new Error(`illegal tag: ${tagToken.raw}`);
|
||||
throw new Error(`empty candidates: ${tagToken.raw}`);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
+7
-26
@@ -3,23 +3,11 @@ var lexical = Liquid.lexical;
|
||||
|
||||
module.exports = function(liquid) {
|
||||
liquid.registerTag('unless', {
|
||||
|
||||
parse: function(tagToken, remainTokens) {
|
||||
this.branches = [];
|
||||
this.elseTemplates = [];
|
||||
|
||||
var p, stream = liquid.parseStream(remainTokens)
|
||||
.onStart(x => this.branches.push({
|
||||
cond: tagToken.args,
|
||||
templates: p = []
|
||||
}))
|
||||
.onTag('elsif', token => {
|
||||
if (!this.branches[token.args]) {
|
||||
this.branches.push({
|
||||
cond: token.args,
|
||||
templates: p = []
|
||||
});
|
||||
}
|
||||
.onStart(x => {
|
||||
p = this.templates = [];
|
||||
this.cond = tagToken.args;
|
||||
})
|
||||
.onTag('else', token => this.elseTemplates = p = [])
|
||||
.onTag('endunless', token => stream.stop())
|
||||
@@ -32,17 +20,10 @@ module.exports = function(liquid) {
|
||||
},
|
||||
|
||||
render: function(scope, hash) {
|
||||
for (var i = 0; i < this.branches.length; i++) {
|
||||
var branch = this.branches[i];
|
||||
var cond = Liquid.evalExp(branch.cond, scope);
|
||||
cond = Liquid.isTruthy(cond);
|
||||
if (i === 0) cond = !cond;
|
||||
if (cond) {
|
||||
return liquid.renderTemplates(branch.templates, scope);
|
||||
}
|
||||
}
|
||||
return liquid.renderTemplates(this.elseTemplates, scope);
|
||||
var cond = Liquid.evalExp(this.cond, scope);
|
||||
return Liquid.isFalsy(cond) ?
|
||||
liquid.renderTemplates(this.templates, scope) :
|
||||
liquid.renderTemplates(this.elseTemplates, scope);
|
||||
}
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
+1
-1
@@ -77,7 +77,7 @@ module.exports = function(Tag, Filter) {
|
||||
|
||||
function parseTag(token, tokens) {
|
||||
if (token.name === 'continue' || token.name === 'break') return token;
|
||||
return Tag.construct(token).parse(tokens);
|
||||
return Tag.construct(token, tokens);
|
||||
}
|
||||
|
||||
function parseOutput(str) {
|
||||
|
||||
+3
-3
@@ -23,7 +23,7 @@ describe('tag', function() {
|
||||
type: 'tag',
|
||||
value: 'foo',
|
||||
name: 'foo'
|
||||
});
|
||||
}, []);
|
||||
}).to.throw(/tag foo not found/);
|
||||
});
|
||||
|
||||
@@ -52,7 +52,7 @@ describe('tag', function() {
|
||||
type: 'tag',
|
||||
value: 'foo',
|
||||
name: 'foo'
|
||||
}).render(scope, {});
|
||||
}, []).render(scope, {});
|
||||
expect(spy).to.have.been.called;
|
||||
});
|
||||
|
||||
@@ -68,7 +68,7 @@ describe('tag', function() {
|
||||
name: 'foo',
|
||||
args: 'aa:foo bb: arr[0] cc: 2.3'
|
||||
};
|
||||
tag.construct(token).render(scope, {});
|
||||
tag.construct(token, []).render(scope, {});
|
||||
expect(spy).to.have.been.calledWithMatch(scope, {
|
||||
aa: 'bar',
|
||||
bb: 2,
|
||||
|
||||
@@ -27,11 +27,13 @@ describe('tags', function() {
|
||||
emptyArray: []
|
||||
};
|
||||
});
|
||||
|
||||
it('should support assign', function() {
|
||||
test('{% assign foo="bar" %}{{foo}}', 'bar');
|
||||
test('{% assign foo=(1..3) %}{{foo}}', '[1,2,3]');
|
||||
test('{% assign foo="a b" | capitalize | split: " " | first %}{{foo}}', 'A');
|
||||
});
|
||||
|
||||
it('should support case', function() {
|
||||
testThrow('{% case "foo"%}', /{% case "foo"%} not closed/);
|
||||
test('{% case "foo"%}' +
|
||||
@@ -69,10 +71,22 @@ describe('tags', function() {
|
||||
testThrow('{% capture = %}{%endcapture%}', /= not valid identifier/);
|
||||
});
|
||||
|
||||
it('should throw when for capture closed', function() {
|
||||
testThrow('{%capture c%}{{c}}', /tag .* not closed/);
|
||||
});
|
||||
|
||||
it('should support for', function() {
|
||||
test('{%for c in alpha%}{{c}}{%endfor%}', 'abc');
|
||||
});
|
||||
|
||||
it('should throw when for not closed', function() {
|
||||
testThrow('{%for c in alpha%}{{c}}', /tag .* not closed/);
|
||||
});
|
||||
|
||||
it('should support for else', function() {
|
||||
test('{%for c in ""%}a{%else%}b{%endfor%}', 'b');
|
||||
});
|
||||
|
||||
it('should support for with forloop', function() {
|
||||
src = '{%for c in alpha%}' +
|
||||
'{{forloop.first}}.{{forloop.index}}.{{forloop.index0}}.' +
|
||||
@@ -117,6 +131,10 @@ describe('tags', function() {
|
||||
test(src + src + src + src, '1231');
|
||||
});
|
||||
|
||||
it('should throw when cycle candidates empty', function() {
|
||||
testThrow('{%cycle%}', /empty candidates/);
|
||||
});
|
||||
|
||||
it('should support cycle in for block', function() {
|
||||
src = '{% for i in (1..5) %}{% cycle one, "e"%}{% endfor %}';
|
||||
test(src, '1e1e1');
|
||||
|
||||
Reference in New Issue
Block a user