filters: all

This commit is contained in:
harttle
2016-06-18 23:18:46 +08:00
parent b478c798fd
commit 4595e2872e
21 changed files with 627 additions and 211 deletions
+10
View File
@@ -38,6 +38,16 @@ describe('error', function() {
});
});
it('should throw ParseError when filter not exist', function() {
test(function(){
liquid.render('{{ a | xz }}', {});
}, function(err){
expect(err.name).to.equal('ParseError');
expect(err.message).to.equal('filter "xz" not found');
expect(err.input).to.equal('{{ a | xz }}');
expect(err.line).to.equal(1);
});
});
it('should throw ParseError when tag not exist', function() {
test(function(){
liquid.render('{% a %}', {});
+21 -3
View File
@@ -17,12 +17,30 @@ describe('filter', function() {
it('should throw when not registered', function() {
expect(function() {
filter.construct('foo');
}).to.throw(/filter foo not found/);
}).to.throw(/filter "foo" not found/);
});
it('should parse argument syntax', function(){
filter.register('foo', x => x);
var f = filter.construct('foo: a, "b"');
expect(f.name).to.equal('foo');
expect(f.args).to.deep.equal(['a', '"b"']);
});
it('should register a simple filter', function(){
filter.register('foo', x => x.toUpperCase());
expect(filter.construct('foo').render('foo', scope)).to.equal('FOO');
filter.register('upcase', x => x.toUpperCase());
expect(filter.construct('upcase').render('foo', scope)).to.equal('FOO');
});
it('should register a argumented filter', function(){
filter.register('add', (a, b) => a + b);
expect(filter.construct('add: 2').render(3, scope)).to.equal(5);
});
it('should register a multi-argumented filter', function(){
filter.register('add', (a, b, c) => a + b + c);
expect(filter.construct('add: 2, "c"').render(3, scope)).to.equal("5c");
});
it('should call filter with corrct arguments', function(){
+208 -5
View File
@@ -1,7 +1,8 @@
const chai = require("chai");
const expect = chai.expect;
var liquid = require('..')(), ctx;
var liquid = require('..')(),
ctx;
function test(src, dst) {
ctx = {
@@ -10,16 +11,21 @@ function test(src, dst) {
arr: [-2, 'a'],
obj: {
foo: 'bar'
}
},
posts: [{
category: 'foo'
}, {
category: 'bar'
}]
};
expect(liquid.render(src, ctx)).to.equal(dst);
}
describe('filters', function() {
it('should output object', function(){
it('should output object', function() {
test('{{obj}}', '{"foo":"bar"}');
});
it('should output array', function(){
it('should output array', function() {
test('{{arr}}', '[-2,"a"]');
});
it('should support abs', function() {
@@ -67,9 +73,206 @@ describe('filters', function() {
'Have you read 'James & the Giant Peach'?');
test('{{ "Tetsuro Takara" | escape }}', 'Tetsuro Takara');
});
it('should support escape_once', function() {
test('{{ "1 < 2 & 3" | escape_once }}', '1 &lt; 2 &amp; 3');
test('{{ "1 &lt; 2 &amp; 3" | escape_once }}', '1 &lt; 2 &amp; 3');
});
});
it('should support split/first', function() {
src = '{% assign my_array = "apples, oranges, peaches, plums" | split: ", " %}' +
'{{ my_array | first }}';
test(src, 'apples');
});
it('should support floor', function() {
test('{{ 1.2 | floor }}', '1');
test('{{ 2.0 | floor }}', '2');
test('{{ 183.357 | floor }}', '183');
test('{{ "3.5" | floor }}', '3');
});
it('should support join', function() {
src = '{% assign beatles = "John, Paul, George, Ringo" | split: ", " %}' +
'{{ beatles | join: " and " }}';
test(src, 'John and Paul and George and Ringo');
});
it('should support split/last', function() {
src = '{% assign my_array = "zebra, octopus, giraffe, tiger" | split: ", " %}' +
'{{ my_array|last }}';
test(src, 'tiger');
});
it('should support lstrip', function() {
src = '{{ " So much room for activities! " | lstrip }}';
test(src, 'So much room for activities! ');
});
it('should support map', function() {
test('{{posts | map: "category"}}', '["foo","bar"]');
});
it('should support minus', function() {
test('{{ 4 | minus: 2 }}', '2');
test('{{ 16 | minus: 4 }}', '12');
test('{{ 183.357 | minus: 12 }}', '171.357');
});
it('should support modulo', function() {
test('{{ 3 | modulo: 2 }}', '1');
test('{{ 24 | modulo: 7 }}', '3');
test('{{ 183.357 | modulo: 12 }}', '3.357');
});
it('should support string_with_newlines', function() {
src = '{% capture string_with_newlines %}\n' +
'Hello\n' +
'there\n' +
'{% endcapture %}' +
'{{ string_with_newlines | newline_to_br }}';
dst = '<br />' +
'Hello<br />' +
'there<br />';
test(src, dst);
});
it('should support plus', function() {
test('{{ 4 | plus: 2 }}', '6');
test('{{ 16 | plus: 4 }}', '20');
test('{{ 183.357 | plus: 12 }}', '195.357');
});
it('should support prepend', function() {
test('{% assign url = "liquidmarkup.com" %}' +
'{{ "/index.html" | prepend: url }}',
'liquidmarkup.com/index.html');
});
it('should support remove', function() {
test('{{ "I strained to see the train through the rain" | remove: "rain" }}',
'I sted to see the t through the ');
});
it('should support remove_first', function() {
test('{{ "I strained to see the train through the rain" | remove_first: "rain" }}',
'I sted to see the train through the rain');
});
it('should support replace', function() {
test('{{ "Take my protein pills and put my helmet on" | replace: "my", "your" }}',
'Take your protein pills and put your helmet on');
});
it('should support replace_first', function() {
test('{% assign my_string = "Take my protein pills and put my helmet on" %}\n' +
'{{ my_string | replace_first: "my", "your" }}',
'\nTake your protein pills and put my helmet on');
});
it('should support reverse', function() {
test('{{ "Ground control to Major Tom." | split: "" | reverse | join: "" }}',
'.moT rojaM ot lortnoc dnuorG');
});
it('should support round', function() {
test('{{1.2|round}}', '1');
test('{{2.7|round}}', '3');
test('{{183.357|round: 2}}', '183.36');
});
it('should support rstrip', function() {
test('{{ " So much room for activities! " | rstrip }}',
' So much room for activities!');
});
it('should support size', function() {
test('{{ "Ground control to Major Tom." | size }}', '28');
test('{% assign my_array = "apples, oranges, peaches, plums"' +
' | split: ", " %}{{ my_array | size }}',
'4');
});
it('should support slice', function() {
test('{{ "Liquid" | slice: 0 }}', 'L');
test('{{ "Liquid" | slice: 2 }}', 'q');
test('{{ "Liquid" | slice: 2, 5 }}', 'quid');
test('{{ "Liquid" | slice: -3, 2 }}', 'ui');
});
it('should support sort', function() {
test('{% assign my_array = "zebra, octopus, giraffe, Sally Snake"' +
' | split: ", " %}' +
'{{ my_array | sort | join: ", " }}',
'Sally Snake, giraffe, octopus, zebra');
});
it('should support split', function() {
test('{% assign beatles = "John, Paul, George, Ringo" | split: ", " %}' +
'{% for member in beatles %}' +
'{{ member }} ' +
'{% endfor %}',
'John Paul George Ringo ');
});
it('should support strip', function() {
test('{{ " So much room for activities! " | strip }}',
'So much room for activities!');
});
it('should support strip_tml', function() {
test('{{ "Have <em>you</em> read <strong>Ulysses</strong>?" | strip_html }}',
'Have you read Ulysses?');
test('{{"<br/><br />< p ></p></ p >" | strip_html }}', '');
});
it('should support strip_newlines', function() {
test('{% capture string_with_newlines %}\n' +
'Hello\nthere\n{% endcapture %}' +
'{{ string_with_newlines | strip_newlines }}',
'Hellothere');
});
it('should support times', function() {
test('{{ 3 | times: 2 }}', '6');
test('{{ 24 | times: 7 }}', '168');
test('{{ 183.357 | times: 12 }}', '2200.284');
});
it('should support truncate', function() {
test('{{ "Ground control to Major Tom." | truncate: 20 }}',
'Ground control to...');
test('{{ "Ground control to Major Tom." | truncate: 80 }}',
'Ground control to Major Tom.');
test('{{ "Ground control to Major Tom." | truncate: 25,", and so on" }}',
'Ground control, and so on');
test('{{ "Ground control to Major Tom." | truncate: 20, "" }}',
'Ground control to Ma');
});
it('should support truncatewords', function() {
test('{{ "Ground control to Major Tom." | truncatewords: 3 }}',
'Ground control to...');
test('{{ "Ground control to Major Tom." | truncatewords: 8 }}',
'Ground control to Major Tom.');
test('{{ "Ground control to Major Tom." | truncatewords: 3, "--" }}',
'Ground control to--');
test('{{ "Ground control to Major Tom." | truncatewords: 3, "" }}',
'Ground control to');
});
it('should support uniq', function() {
test('{% assign my_array = "ants, bugs, bees, bugs, ants" | split: ", " %}' +
'{{ my_array | uniq | join: ", " }}',
'ants, bugs, bees');
});
it('should support upcase', function() {
test('{{ "Parker Moore" | upcase }}', 'PARKER MOORE');
});
it('should support url_encode', function() {
test('{{ "[email protected]" | url_encode }}', 'john%40liquid.com');
test('{{ "Tetsuro Takara" | url_encode }}', 'Tetsuro%20Takara');
});
});
+44 -35
View File
@@ -1,70 +1,79 @@
var chai = require("chai");
var should = chai.should();
var expect = chai.expect;
var identifier = require('../lexical.js');
var lexical = require('../lexical.js');
describe('identifier', function() {
describe('lexical', function() {
it('should test filter syntax', function(){
lexical.filterLine.test('abs').should.equal(true);
lexical.filterLine.test('plus:1').should.equal(true);
lexical.filterLine.test('replace: "a", b').should.equal(true);
lexical.filterLine.test('foo: a, "b"').should.equal(true);
lexical.filterLine.test('abs | another').should.equal(false);
lexical.filterLine.test('join: "," | another').should.equal(false);
});
it('should test boolean literal', function() {
identifier.isLiteral('true').should.equal(true);
identifier.isLiteral('TrUE').should.equal(true);
identifier.isLiteral('false').should.equal(true);
lexical.isLiteral('true').should.equal(true);
lexical.isLiteral('TrUE').should.equal(true);
lexical.isLiteral('false').should.equal(true);
});
it('should test number literal', function() {
identifier.isLiteral('2.3').should.equal(true);
identifier.isLiteral('.3').should.equal(true);
identifier.isLiteral('-3.').should.equal(true);
identifier.isLiteral('23').should.equal(true);
lexical.isLiteral('2.3').should.equal(true);
lexical.isLiteral('.3').should.equal(true);
lexical.isLiteral('-3.').should.equal(true);
lexical.isLiteral('23').should.equal(true);
});
it("should test range literal", function() {
identifier.isRange("(12..32)").should.equal(true);
identifier.isRange("(12..foo)").should.equal(true);
identifier.isRange("(foo.bar..foo)").should.equal(true);
lexical.isRange("(12..32)").should.equal(true);
lexical.isRange("(12..foo)").should.equal(true);
lexical.isRange("(foo.bar..foo)").should.equal(true);
});
it('should test string literal', function() {
identifier.isLiteral('""').should.equal(true);
identifier.isLiteral('"a\'b"').should.equal(true);
identifier.isLiteral("''").should.equal(true);
identifier.isLiteral("'a bcd'").should.equal(true);
lexical.isLiteral('""').should.equal(true);
lexical.isLiteral('"a\'b"').should.equal(true);
lexical.isLiteral("''").should.equal(true);
lexical.isLiteral("'a bcd'").should.equal(true);
});
it("should test variable", function() {
identifier.isVariable("foo").should.equal(true);
identifier.isVariable("foo.bar.foo").should.equal(true);
identifier.isVariable("foo[0].b").should.equal(true);
lexical.isVariable("foo").should.equal(true);
lexical.isVariable("foo.bar.foo").should.equal(true);
lexical.isVariable("foo[0].b").should.equal(true);
});
it('should test none literal', function() {
identifier.isLiteral('2a').should.equal(false);
identifier.isLiteral('"x').should.equal(false);
identifier.isLiteral('a2').should.equal(false);
lexical.isLiteral('2a').should.equal(false);
lexical.isLiteral('"x').should.equal(false);
lexical.isLiteral('a2').should.equal(false);
});
it('should test none variable', function() {
identifier.isVariable("a.").should.equal(false);
identifier.isVariable(".b").should.equal(false);
identifier.isVariable(".").should.equal(false);
identifier.isVariable("0a").should.equal(false);
identifier.isVariable("[0][12].bar[0]").should.equal(false);
lexical.isVariable("a.").should.equal(false);
lexical.isVariable(".b").should.equal(false);
lexical.isVariable(".").should.equal(false);
lexical.isVariable("0a").should.equal(false);
lexical.isVariable("[0][12].bar[0]").should.equal(false);
});
it('should parse boolean literal', function() {
identifier.parseLiteral('true').should.equal(true);
identifier.parseLiteral('TrUE').should.equal(true);
identifier.parseLiteral('false').should.equal(false);
lexical.parseLiteral('true').should.equal(true);
lexical.parseLiteral('TrUE').should.equal(true);
lexical.parseLiteral('false').should.equal(false);
});
it('should parse number literal', function() {
identifier.parseLiteral('2.3').should.equal(2.3);
identifier.parseLiteral('.32').should.equal(0.32);
identifier.parseLiteral('-23.').should.equal(-23);
identifier.parseLiteral('23').should.equal(23);
lexical.parseLiteral('2.3').should.equal(2.3);
lexical.parseLiteral('.32').should.equal(0.32);
lexical.parseLiteral('-23.').should.equal(-23);
lexical.parseLiteral('23').should.equal(23);
});
it('should parse string literal', function() {
identifier.parseLiteral('"ab\'c"').should.equal("ab\'c");
lexical.parseLiteral('"ab\'c"').should.equal("ab\'c");
});
});
+20 -8
View File
@@ -8,14 +8,14 @@ chai.use(sinonChai);
var tag = require('../tag.js')();
var Scope = require('../scope.js');
var filter = require('../filter')();
var Render = require('../render.js')(filter, tag);
var render = Render.renderTemplates;
var evalFilter = Render.evalFilter;
var Render = require('../render.js');
var Template = require('../template.js')(tag, filter);
describe('render', function() {
var scope;
var scope, render;
beforeEach(function() {
render = Render(filter, tag);
scope = Scope.factory({
foo: {
bar: ['a', 2]
@@ -25,8 +25,18 @@ describe('render', function() {
tag.clear();
});
it('should stringify object', function() {
expect(Render.stringify({
foo: 'bar'
})).to.equal('{"foo":"bar"}');
});
it('should stringify object', function() {
expect(Render.stringify([1, 2, 3])).to.equal('[1,2,3]');
});
it('should render html', function() {
expect(render([{
expect(render.renderTemplates([{
type: 'html',
value: '<p>'
}], scope)).to.equal('<p>');
@@ -37,14 +47,16 @@ describe('render', function() {
var time = sinon.spy();
filter.register('date', date);
filter.register('time', time);
evalFilter('foo.bar[0] | date: "b" | time:2', scope);
var tpl = Template.parseOutput('foo.bar[0] | date: "b" | time:2');
render.evalOutput(tpl, scope);
expect(date).to.have.been.calledWith('a', 'b');
expect(time).to.have.been.calledWith('y', 2);
});
it('should eval filter', function() {
it('should eval output', function() {
filter.register('date', (l, r) => l + r);
filter.register('time', (l, r) => l + 3 * r);
expect(evalFilter('foo.bar[0] | date: "b" | time:2', scope)).to.equal('ab6');
var tpl = Template.parseOutput('foo.bar[0] | date: "b" | time:2');
expect(render.evalOutput(tpl, scope)).to.equal('ab6');
});
});
+9 -1
View File
@@ -28,7 +28,9 @@ describe('tags', function() {
};
});
it('should support assign', function() {
test('{% assign foo="bar"%}{{foo}}', 'bar');
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/);
@@ -146,6 +148,12 @@ describe('tags', function() {
test(src, dst);
});
it('should support empty tablerow', function() {
src = '{% tablerow i in (1..0) cols:2 %}{{ i }}{% endtablerow %}';
dst = '<table></table>';
test(src, dst);
});
it('should support tablerow with range', function() {
src = '{% tablerow i in (1..5) cols:2 %}{{ i }}{% endtablerow %}';
dst = '<table>' +
+43
View File
@@ -0,0 +1,43 @@
const chai = require("chai");
const sinon = require("sinon");
const sinonChai = require("sinon-chai");
const should = chai.should();
const expect = chai.expect;
chai.use(sinonChai);
var filter = require('../filter.js')();
var tag = require('../tag.js')();
var Template = require('../template.js');
describe('template', function() {
var scope, template, add = (l, r) => l + r;
beforeEach(function(){
filter.clear();
filter.register('add', add);
tag.clear();
template = Template(tag, filter);
});
it('should parse output string', function() {
var tpl = template.parseOutput('foo');
expect(tpl.type).to.equal('output');
expect(tpl.initial).to.equal('foo');
expect(tpl.filters).to.deep.equal([]);
});
it('should parse output string with a simple filter', function() {
var tpl = template.parseOutput('foo | add: 3, "foo"');
expect(tpl.initial).to.equal('foo');
expect(tpl.filters.length).to.equal(1);
expect(tpl.filters[0].filter).to.equal(add);
});
it('should parse output string with filters', function() {
var tpl = template.parseOutput('foo | add: "|" | add');
expect(tpl.initial).to.equal('foo');
expect(tpl.filters.length).to.equal(2);
});
});