mirror of
https://github.com/harttle/liquidjs.git
synced 2026-10-03 00:55:13 -07:00
fix: whiteSpace Ctrl with compliance to shopify/liquid, working on #17
This commit is contained in:
@@ -38,3 +38,4 @@ jspm_packages
|
|||||||
|
|
||||||
# vim
|
# vim
|
||||||
.*.swp
|
.*.swp
|
||||||
|
package-lock.json
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ Otherwise, undefined variables will cause an exception. Defaults to `false`.
|
|||||||
|
|
||||||
* `trim_left` is similiar to `trim_right`, whereas the `\n` is exclusive. Defaults to `false`. See [Whitespace Control][whitespace control] for details.
|
* `trim_left` is similiar to `trim_right`, whereas the `\n` is exclusive. Defaults to `false`. See [Whitespace Control][whitespace control] for details.
|
||||||
|
|
||||||
* `greedy` is used to specify whether `trim_left`/`trim_right` is greedy. When set to `true`, all successive blank characters including `\n` will be trimed regardless of line breaks. Defaults to `false`.
|
* `greedy` is used to specify whether `trim_left`/`trim_right` is greedy. When set to `true`, all successive blank characters including `\n` will be trimed regardless of line breaks. Defaults to `true`.
|
||||||
|
|
||||||
## Use with Express.js
|
## Use with Express.js
|
||||||
|
|
||||||
|
|||||||
Generated
-4819
File diff suppressed because it is too large
Load Diff
+74
-50
@@ -4,92 +4,116 @@ const _ = require('./util/underscore.js')
|
|||||||
const assert = require('../src/util/assert.js')
|
const assert = require('../src/util/assert.js')
|
||||||
|
|
||||||
function parse (html, filepath, options) {
|
function parse (html, filepath, options) {
|
||||||
assert(_.isString(html), 'illegal input type')
|
assert(_.isString(html), 'illegal input')
|
||||||
|
|
||||||
html = whiteSpaceCtrl(html, options)
|
var rLiquid = /({%-?([\s\S]*?)-?%})|({{-?([\s\S]*?)-?}})/g
|
||||||
|
var currIndent = 0
|
||||||
var tokens = []
|
var lineNumber = LineNumber()
|
||||||
var syntax = /({%-?([\s\S]*?)-?%})|({{-?([\s\S]*?)-?}})/g
|
|
||||||
var result, htmlFragment, token
|
|
||||||
var lastMatchEnd = 0
|
var lastMatchEnd = 0
|
||||||
var lastMatchBegin = -1
|
var tokens = []
|
||||||
var parsedLinesCount = 0
|
|
||||||
|
|
||||||
while ((result = syntax.exec(html)) !== null) {
|
for (var match; (match = rLiquid.exec(html)); lastMatchEnd = rLiquid.lastIndex) {
|
||||||
// passed html fragments
|
if (match.index > lastMatchEnd) {
|
||||||
if (result.index > lastMatchEnd) {
|
tokens.push(parseHTMLToken(lastMatchEnd, match.index))
|
||||||
htmlFragment = html.slice(lastMatchEnd, result.index)
|
|
||||||
tokens.push({
|
|
||||||
type: 'html',
|
|
||||||
raw: htmlFragment,
|
|
||||||
value: htmlFragment
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
if (result[1]) {
|
tokens.push(match[1] ? parseTagToken(match) : parseOutputToken(match))
|
||||||
// tag appeared
|
}
|
||||||
token = factory('tag', 1, result)
|
if (html.length > lastMatchEnd) {
|
||||||
|
tokens.push(parseHTMLToken(lastMatchEnd, html.length))
|
||||||
|
}
|
||||||
|
whiteSpaceCtrl(tokens, options)
|
||||||
|
return tokens
|
||||||
|
|
||||||
|
function parseOutputToken (match) {
|
||||||
|
var token = factory('output', 3, match)
|
||||||
|
token.trim_left = (match[3].slice(0, 3) === '{{-')
|
||||||
|
token.trim_right = (match[3].slice(-3) === '-}}')
|
||||||
|
return token
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseTagToken (result) {
|
||||||
|
var token = factory('tag', 1, result)
|
||||||
var match = token.value.match(lexical.tagLine)
|
var match = token.value.match(lexical.tagLine)
|
||||||
if (!match) {
|
if (!match) {
|
||||||
throw new TokenizationError(`illegal tag syntax`, token)
|
throw new TokenizationError(`illegal tag syntax`, token)
|
||||||
}
|
}
|
||||||
token.name = match[1]
|
|
||||||
token.args = match[2]
|
|
||||||
|
|
||||||
// get last line indentation
|
return _.assign(token, {
|
||||||
var lineStart = (htmlFragment || '').split('\n')
|
name: match[1],
|
||||||
token.indent = lineStart[lineStart.length - 1].length
|
args: match[2],
|
||||||
|
trim_left: (result[1].slice(0, 3) === '{%-'),
|
||||||
tokens.push(token)
|
trim_right: (result[1].slice(-3) === '-%}'),
|
||||||
} else {
|
indent: currIndent
|
||||||
// output
|
})
|
||||||
token = factory('output', 3, result)
|
|
||||||
tokens.push(token)
|
|
||||||
}
|
|
||||||
lastMatchEnd = syntax.lastIndex
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// remaining html
|
function parseHTMLToken (begin, end) {
|
||||||
if (html.length > lastMatchEnd) {
|
var htmlFragment = html.slice(begin, end)
|
||||||
htmlFragment = html.slice(lastMatchEnd, html.length)
|
currIndent = _.last((htmlFragment || '').split('\n')).length
|
||||||
tokens.push({
|
|
||||||
|
return {
|
||||||
type: 'html',
|
type: 'html',
|
||||||
raw: htmlFragment,
|
raw: htmlFragment,
|
||||||
value: htmlFragment
|
value: htmlFragment
|
||||||
})
|
|
||||||
}
|
}
|
||||||
return tokens
|
}
|
||||||
|
|
||||||
function factory (type, offset, match) {
|
function factory (type, offset, match) {
|
||||||
return {
|
return {
|
||||||
type: type,
|
type: type,
|
||||||
raw: match[offset],
|
raw: match[offset],
|
||||||
value: match[offset + 1].trim(),
|
value: match[offset + 1].trim(),
|
||||||
line: getLineNum(match),
|
line: lineNumber.get(match),
|
||||||
input: html,
|
input: html,
|
||||||
file: filepath
|
file: filepath
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function getLineNum (match) {
|
function LineNumber () {
|
||||||
|
var parsedLinesCount = 0
|
||||||
|
var lastMatchBegin = -1
|
||||||
|
|
||||||
|
return {
|
||||||
|
get: function (match) {
|
||||||
var lines = match.input.slice(lastMatchBegin + 1, match.index).split('\n')
|
var lines = match.input.slice(lastMatchBegin + 1, match.index).split('\n')
|
||||||
parsedLinesCount += lines.length - 1
|
parsedLinesCount += lines.length - 1
|
||||||
lastMatchBegin = match.index
|
lastMatchBegin = match.index
|
||||||
return parsedLinesCount + 1
|
return parsedLinesCount + 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function whiteSpaceCtrl (html, options) {
|
function whiteSpaceCtrl (tokens, options) {
|
||||||
options = options || {}
|
options = _.assign({ greedy: true }, options)
|
||||||
if (options.trim_left) {
|
var inRaw = false
|
||||||
html = html.replace(/({[{%])-?/g, '$1-')
|
|
||||||
|
tokens.forEach((token, i) => {
|
||||||
|
if (!inRaw && (token.trim_left || options.trim_left)) {
|
||||||
|
trimLeft(tokens[i - 1], options.greedy)
|
||||||
}
|
}
|
||||||
if (options.trim_right) {
|
|
||||||
html = html.replace(/-?([%}]})/g, '-$1')
|
if (token.type === 'tag' && token.name === 'raw') inRaw = true
|
||||||
|
if (token.type === 'tag' && token.name === 'endraw') inRaw = false
|
||||||
|
|
||||||
|
if (!inRaw && (token.trim_right || options.trim_right)) {
|
||||||
|
trimRight(tokens[i + 1], options.greedy)
|
||||||
}
|
}
|
||||||
var rLeft = options.greedy ? /\s+({[{%]-)/g : /[\t\r ]*({[{%]-)/g
|
})
|
||||||
var rRight = options.greedy ? /(-[%}]})\s+/g : /(-[%}]})[\t\r ]*\n?/g
|
}
|
||||||
return html.replace(rLeft, '$1').replace(rRight, '$1')
|
|
||||||
|
function trimLeft (token, greedy) {
|
||||||
|
if (!token || token.type !== 'html') return
|
||||||
|
|
||||||
|
var rLeft = greedy ? /\s+$/g : /[\t\r ]*$/g
|
||||||
|
token.value = token.value.replace(rLeft, '')
|
||||||
|
}
|
||||||
|
|
||||||
|
function trimRight (token, greedy) {
|
||||||
|
if (!token || token.type !== 'html') return
|
||||||
|
|
||||||
|
var rRight = greedy ? /^\s+/g : /^[\t\r ]*\n?/g
|
||||||
|
token.value = token.value.replace(rRight, '')
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.parse = parse
|
exports.parse = parse
|
||||||
|
|||||||
@@ -70,11 +70,8 @@ function _assignBinary (dst, src) {
|
|||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
|
|
||||||
function echo (prefix) {
|
function last (arr) {
|
||||||
return v => {
|
return arr[arr.length - 1]
|
||||||
console.log('[' + prefix + ']', v)
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function uniq (arr) {
|
function uniq (arr) {
|
||||||
@@ -123,16 +120,18 @@ function range (start, stop, step) {
|
|||||||
return arr
|
return arr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// lang
|
||||||
exports.isString = isString
|
exports.isString = isString
|
||||||
exports.isObject = isObject
|
exports.isObject = isObject
|
||||||
exports.isArray = isArray
|
exports.isArray = isArray
|
||||||
exports.isNil = isNil
|
exports.isNil = isNil
|
||||||
exports.isError = isError
|
exports.isError = isError
|
||||||
|
|
||||||
|
// array
|
||||||
exports.range = range
|
exports.range = range
|
||||||
|
exports.last = last
|
||||||
|
|
||||||
|
// object
|
||||||
exports.forOwn = forOwn
|
exports.forOwn = forOwn
|
||||||
exports.assign = assign
|
exports.assign = assign
|
||||||
exports.uniq = uniq
|
exports.uniq = uniq
|
||||||
|
|
||||||
exports.echo = echo
|
|
||||||
|
|||||||
+15
-15
@@ -1,16 +1,16 @@
|
|||||||
module.exports = function (engine) {
|
module.exports = function (engine) {
|
||||||
require("./assign.js")(engine);
|
require('./assign.js')(engine)
|
||||||
require("./capture.js")(engine);
|
require('./capture.js')(engine)
|
||||||
require("./case.js")(engine);
|
require('./case.js')(engine)
|
||||||
require("./comment.js")(engine);
|
require('./comment.js')(engine)
|
||||||
require("./cycle.js")(engine);
|
require('./cycle.js')(engine)
|
||||||
require("./decrement.js")(engine);
|
require('./decrement.js')(engine)
|
||||||
require("./for.js")(engine);
|
require('./for.js')(engine)
|
||||||
require("./if.js")(engine);
|
require('./if.js')(engine)
|
||||||
require("./include.js")(engine);
|
require('./include.js')(engine)
|
||||||
require("./increment.js")(engine);
|
require('./increment.js')(engine)
|
||||||
require("./layout.js")(engine);
|
require('./layout.js')(engine)
|
||||||
require("./raw.js")(engine);
|
require('./raw.js')(engine)
|
||||||
require("./tablerow.js")(engine);
|
require('./tablerow.js')(engine)
|
||||||
require("./unless.js")(engine);
|
require('./unless.js')(engine)
|
||||||
};
|
}
|
||||||
|
|||||||
+5
-5
@@ -186,7 +186,7 @@ describe('liquid', function () {
|
|||||||
trim_left: true
|
trim_left: true
|
||||||
})
|
})
|
||||||
return expect(engine.parseAndRender(' \n \t{%if true%}foo{%endif%} '))
|
return expect(engine.parseAndRender(' \n \t{%if true%}foo{%endif%} '))
|
||||||
.to.eventually.equal(' \nfoo ')
|
.to.eventually.equal('foo ')
|
||||||
})
|
})
|
||||||
it('should trim_right for tags when trim_right=true', function () {
|
it('should trim_right for tags when trim_right=true', function () {
|
||||||
engine = Liquid({
|
engine = Liquid({
|
||||||
@@ -210,9 +210,9 @@ describe('liquid', function () {
|
|||||||
' Wow, {{ username }}, you have a long name!',
|
' Wow, {{ username }}, you have a long name!',
|
||||||
'{%- else -%}',
|
'{%- else -%}',
|
||||||
' Hello there!',
|
' Hello there!',
|
||||||
'{%- endif -%}\n'
|
'{%- endif -%}'
|
||||||
].join('\n')
|
].join('\n')
|
||||||
var dst = ' Wow, John G. Chalmers-Smith, you have a long name!\n'
|
var dst = 'Wow, John G. Chalmers-Smith, you have a long name!'
|
||||||
return expect(engine.parseAndRender(src)).to.eventually.equal(dst)
|
return expect(engine.parseAndRender(src)).to.eventually.equal(dst)
|
||||||
})
|
})
|
||||||
it('should not trim when not specified', function () {
|
it('should not trim when not specified', function () {
|
||||||
@@ -223,9 +223,9 @@ describe('liquid', function () {
|
|||||||
' Wow, {{ username }}, you have a long name!',
|
' Wow, {{ username }}, you have a long name!',
|
||||||
'{% else %}',
|
'{% else %}',
|
||||||
' Hello there!',
|
' Hello there!',
|
||||||
'{% endif %}\n'
|
'{% endif %}'
|
||||||
].join('\n')
|
].join('\n')
|
||||||
var dst = '\n\n Wow, John G. Chalmers-Smith, you have a long name!\n\n'
|
var dst = '\n\n Wow, John G. Chalmers-Smith, you have a long name!\n'
|
||||||
return expect(engine.parseAndRender(src)).to.eventually.equal(dst)
|
return expect(engine.parseAndRender(src)).to.eventually.equal(dst)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
+7
-7
@@ -12,37 +12,37 @@ describe('tags/if', function () {
|
|||||||
emptyArray: []
|
emptyArray: []
|
||||||
}
|
}
|
||||||
|
|
||||||
it('should support if 1', function () {
|
it('should throw if not closed', function () {
|
||||||
var src = '{% if false%}yes'
|
var src = '{% if false%}yes'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
return expect(liquid.parseAndRender(src, ctx))
|
||||||
.to.be.rejectedWith(/tag {% if false%} not closed/)
|
.to.be.rejectedWith(/tag {% if false%} not closed/)
|
||||||
})
|
})
|
||||||
it('should support if 2', function () {
|
it('should treat Array truthy', function () {
|
||||||
var src = '{%if emptyArray%}a{%endif%}'
|
var src = '{%if emptyArray%}a{%endif%}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
return expect(liquid.parseAndRender(src, ctx))
|
||||||
.to.eventually.equal('a')
|
.to.eventually.equal('a')
|
||||||
})
|
})
|
||||||
it('should support if 3', function () {
|
it('should support ==', function () {
|
||||||
var src = '{% if 2==3 %}yes{%else%}no{%endif%}'
|
var src = '{% if 2==3 %}yes{%else%}no{%endif%}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
return expect(liquid.parseAndRender(src, ctx))
|
||||||
.to.eventually.equal('no')
|
.to.eventually.equal('no')
|
||||||
})
|
})
|
||||||
it('should support if 4', function () {
|
it('should support >=', function () {
|
||||||
var src = '{% if 1>=2 and one<two %}a{%endif%}'
|
var src = '{% if 1>=2 and one<two %}a{%endif%}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
return expect(liquid.parseAndRender(src, ctx))
|
||||||
.to.eventually.equal('')
|
.to.eventually.equal('')
|
||||||
})
|
})
|
||||||
it('should support if 5', function () {
|
it('should support !=', function () {
|
||||||
var src = '{% if one!=two %}yes{%else%}no{%endif%}'
|
var src = '{% if one!=two %}yes{%else%}no{%endif%}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
return expect(liquid.parseAndRender(src, ctx))
|
||||||
.to.eventually.equal('yes')
|
.to.eventually.equal('yes')
|
||||||
})
|
})
|
||||||
it('should support if 6', function () {
|
it('should support boolean', function () {
|
||||||
var src = '{% if false %}1{%elsif true%}2{%else%}3{%endif%}'
|
var src = '{% if false %}1{%elsif true%}2{%else%}3{%endif%}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
return expect(liquid.parseAndRender(src, ctx))
|
||||||
.to.eventually.equal('2')
|
.to.eventually.equal('2')
|
||||||
})
|
})
|
||||||
it('should support if 7', function () {
|
it('should support nested', function () {
|
||||||
var src = '{%if false%}{%if true%}{%else%}a{%endif%}{%endif%}'
|
var src = '{%if false%}{%if true%}{%else%}a{%endif%}{%endif%}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
return expect(liquid.parseAndRender(src, ctx))
|
||||||
.to.eventually.equal('')
|
.to.eventually.equal('')
|
||||||
|
|||||||
+1
-88
@@ -1,6 +1,5 @@
|
|||||||
const chai = require('chai')
|
const chai = require('chai')
|
||||||
const parse = require('../src/tokenizer.js').parse
|
const parse = require('../src/tokenizer.js').parse
|
||||||
const whiteSpaceCtrl = require('../src/tokenizer.js').whiteSpaceCtrl
|
|
||||||
const expect = chai.expect
|
const expect = chai.expect
|
||||||
|
|
||||||
describe('tokenizer', function () {
|
describe('tokenizer', function () {
|
||||||
@@ -16,7 +15,7 @@ describe('tokenizer', function () {
|
|||||||
it('should throw when non-string passed in', function () {
|
it('should throw when non-string passed in', function () {
|
||||||
expect(function () {
|
expect(function () {
|
||||||
parse({})
|
parse({})
|
||||||
}).to.throw('illegal input type')
|
}).to.throw('illegal input')
|
||||||
})
|
})
|
||||||
it('should handle tag syntax', function () {
|
it('should handle tag syntax', function () {
|
||||||
var html = '<p>{% for p in a[1]%}</p>'
|
var html = '<p>{% for p in a[1]%}</p>'
|
||||||
@@ -70,90 +69,4 @@ describe('tokenizer', function () {
|
|||||||
expect(tokens[0].raw).to.equal('{{foo\n|date:\n"%Y-%m-%d"\n}}')
|
expect(tokens[0].raw).to.equal('{{foo\n|date:\n"%Y-%m-%d"\n}}')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('whitespace control', function () {
|
|
||||||
it('should not strip by default (tag)', function () {
|
|
||||||
expect(whiteSpaceCtrl('\n {%foo%} \n')).to.equal('\n {%foo%} \n')
|
|
||||||
})
|
|
||||||
it('should strip all blank characters before and after (tag)', function () {
|
|
||||||
expect(whiteSpaceCtrl(' \t\r{%-foo-%} \t\n')).to.equal('{%-foo-%}')
|
|
||||||
})
|
|
||||||
it('should not trim previous/next lines (tag)', function () {
|
|
||||||
expect(whiteSpaceCtrl(' \t\n {%-foo-%}')).to.equal(' \t\n{%-foo-%}')
|
|
||||||
expect(whiteSpaceCtrl('{%-foo-%} \n \tfoo')).to.equal('{%-foo-%} \tfoo')
|
|
||||||
})
|
|
||||||
it('should trim exactly one trailing CR (tag)', function () {
|
|
||||||
expect(whiteSpaceCtrl('{%-foo-%} \n\n')).to.equal('{%-foo-%}\n')
|
|
||||||
})
|
|
||||||
it('should trim exactly one trailing CR (tag)', function () {
|
|
||||||
expect(whiteSpaceCtrl('{%-foo-%} \n\n')).to.equal('{%-foo-%}\n')
|
|
||||||
})
|
|
||||||
it('should trim all leading/trailing blanks when options.greedy set (tag)', function () {
|
|
||||||
expect(whiteSpaceCtrl(' \n \n\t\r{%-foo-%}\n \n', {
|
|
||||||
greedy: true
|
|
||||||
})).to.equal('{%-foo-%}')
|
|
||||||
})
|
|
||||||
it('should strip whitespaces when set trim_left (tag)', function () {
|
|
||||||
expect(whiteSpaceCtrl('\n {%foo%} \n', {
|
|
||||||
trim_left: true
|
|
||||||
})).to.equal('\n{%-foo%} \n')
|
|
||||||
})
|
|
||||||
it('should strip whitespaces when set trim_right (tag)', function () {
|
|
||||||
expect(whiteSpaceCtrl('\n {%foo%} \n', {
|
|
||||||
trim_right: true
|
|
||||||
})).to.equal('\n {%foo-%}')
|
|
||||||
})
|
|
||||||
it('markup should has priority over options (tag)', function () {
|
|
||||||
expect(whiteSpaceCtrl('\n {%-foo%} \n', {
|
|
||||||
trim_left: false
|
|
||||||
})).to.equal('\n{%-foo%} \n')
|
|
||||||
})
|
|
||||||
it('should support a mix of markup and options (tag)', function () {
|
|
||||||
expect(whiteSpaceCtrl(' {%-foo%} \n', {
|
|
||||||
trim_left: true,
|
|
||||||
trim_right: true
|
|
||||||
})).to.equal('{%-foo-%}')
|
|
||||||
})
|
|
||||||
it('should not strip by default (value)', function () {
|
|
||||||
expect(whiteSpaceCtrl('\n {{foo}} \n')).to.equal('\n {{foo}} \n')
|
|
||||||
})
|
|
||||||
it('should strip all blank characters before and after (value)', function () {
|
|
||||||
expect(whiteSpaceCtrl(' \t\r{{-foo-}} \t\n')).to.equal('{{-foo-}}')
|
|
||||||
})
|
|
||||||
it('should not trim previous/next lines (value)', function () {
|
|
||||||
expect(whiteSpaceCtrl(' \t\n {{-foo-}}')).to.equal(' \t\n{{-foo-}}')
|
|
||||||
expect(whiteSpaceCtrl('{{-foo-}} \n \tfoo')).to.equal('{{-foo-}} \tfoo')
|
|
||||||
})
|
|
||||||
it('should trim exactly one trailing CR (value)', function () {
|
|
||||||
expect(whiteSpaceCtrl('{{-foo-}} \n\n')).to.equal('{{-foo-}}\n')
|
|
||||||
})
|
|
||||||
it('should trim exactly one trailing CR (value)', function () {
|
|
||||||
expect(whiteSpaceCtrl('{{-foo-}} \n\n')).to.equal('{{-foo-}}\n')
|
|
||||||
})
|
|
||||||
it('should trim all leading/trailing blanks when options.greedy set (value)', function () {
|
|
||||||
expect(whiteSpaceCtrl(' \n \n\t\r{{-foo-}}\n \n', {
|
|
||||||
greedy: true
|
|
||||||
})).to.equal('{{-foo-}}')
|
|
||||||
})
|
|
||||||
it('should strip whitespaces when set trim_left (value)', function () {
|
|
||||||
expect(whiteSpaceCtrl('\n {{foo}} \n', {
|
|
||||||
trim_left: true
|
|
||||||
})).to.equal('\n{{-foo}} \n')
|
|
||||||
})
|
|
||||||
it('should strip whitespaces when set trim_right (value)', function () {
|
|
||||||
expect(whiteSpaceCtrl('\n {{foo}} \n', {
|
|
||||||
trim_right: true
|
|
||||||
})).to.equal('\n {{foo-}}')
|
|
||||||
})
|
|
||||||
it('markup should has priority over options (value)', function () {
|
|
||||||
expect(whiteSpaceCtrl('\n {{-foo}} \n', {
|
|
||||||
trim_left: false
|
|
||||||
})).to.equal('\n{{-foo}} \n')
|
|
||||||
})
|
|
||||||
it('should support a mix of markup and options (value)', function () {
|
|
||||||
expect(whiteSpaceCtrl(' {{-foo}} \n', {
|
|
||||||
trim_left: true,
|
|
||||||
trim_right: true
|
|
||||||
})).to.equal('{{-foo-}}')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -62,16 +62,6 @@ describe('util/underscore', function () {
|
|||||||
expect(spy).to.have.been.calledOnce
|
expect(spy).to.have.been.calledOnce
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('.echo()', function () {
|
|
||||||
it('should be transparent', function () {
|
|
||||||
expect(_.echo('foo')('bar')).to.equal('bar')
|
|
||||||
})
|
|
||||||
it('should log the arguments', function () {
|
|
||||||
var log = sinon.spy(console, 'log')
|
|
||||||
_.echo('foo')('bar')
|
|
||||||
expect(log).to.have.been.calledWith('[foo]', 'bar')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
describe('.range()', function () {
|
describe('.range()', function () {
|
||||||
it('should return a range of integers', function () {
|
it('should return a range of integers', function () {
|
||||||
expect(_.range(3, 5)).to.deep.equal([3, 4])
|
expect(_.range(3, 5)).to.deep.equal([3, 4])
|
||||||
|
|||||||
@@ -0,0 +1,448 @@
|
|||||||
|
const chai = require('chai')
|
||||||
|
const expect = chai.expect
|
||||||
|
const Liquid = require('..')
|
||||||
|
const liquid = new Liquid()
|
||||||
|
chai.use(require('chai-as-promised'))
|
||||||
|
|
||||||
|
const cases = [
|
||||||
|
{
|
||||||
|
text: `
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
{{ 'John' }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
expected: `
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
John
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}, {
|
||||||
|
text: `
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
|
||||||
|
|
||||||
|
{{- 'John' -}}
|
||||||
|
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
expected: `
|
||||||
|
<div>
|
||||||
|
<p>John</p>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}, {
|
||||||
|
text: `
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
|
||||||
|
|
||||||
|
{%- if true -%}
|
||||||
|
yes
|
||||||
|
{%- endif -%}
|
||||||
|
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
expected: `
|
||||||
|
<div>
|
||||||
|
<p>yes</p>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}, {
|
||||||
|
text: `
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
{% if true %}
|
||||||
|
yes
|
||||||
|
{% endif %}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
expected: `
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
|
||||||
|
yes
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}, {
|
||||||
|
text: `
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
{% if false %}
|
||||||
|
no
|
||||||
|
{% endif %}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
expected: `
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}, {
|
||||||
|
text: '<p>{{- \'John\' -}}</p>',
|
||||||
|
expected: '<p>John</p>'
|
||||||
|
}, {
|
||||||
|
text: '<p>{%- if true -%}yes{%- endif -%}</p>',
|
||||||
|
expected: '<p>yes</p>'
|
||||||
|
}, {
|
||||||
|
text: '<p>{%- if false -%}no{%- endif -%}</p>',
|
||||||
|
expected: '<p></p>'
|
||||||
|
}, {
|
||||||
|
text: '<p> {%- if true %} yes {% endif -%} </p>',
|
||||||
|
expected: '<p> yes </p>'
|
||||||
|
}, {
|
||||||
|
text: '<p> {%- if false %} no {% endif -%} </p>',
|
||||||
|
expected: '<p></p>'
|
||||||
|
}, {
|
||||||
|
text: '<p> {% if true -%} yes {%- endif %} </p>',
|
||||||
|
expected: '<p> yes </p>'
|
||||||
|
}, {
|
||||||
|
text: '<p> {% if false -%} no {%- endif %} </p>',
|
||||||
|
expected: '<p> </p>'
|
||||||
|
}, {
|
||||||
|
text: '<p> {% if true -%} yes {% endif -%} </p>',
|
||||||
|
expected: '<p> yes </p>'
|
||||||
|
}, {
|
||||||
|
text: '<p> {% if false -%} no {% endif -%} </p>',
|
||||||
|
expected: '<p> </p>'
|
||||||
|
}, {
|
||||||
|
text: '<p> {%- if true %} yes {%- endif %} </p>',
|
||||||
|
expected: '<p> yes </p>'
|
||||||
|
}, {
|
||||||
|
text: '<p> {%- if false %} no {%- endif %} </p>',
|
||||||
|
expected: '<p> </p>'
|
||||||
|
}, {
|
||||||
|
text: `
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
{{- 'John' }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
expected: `
|
||||||
|
<div>
|
||||||
|
<p>John
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}, {
|
||||||
|
text: `
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
{%- if true %}
|
||||||
|
yes
|
||||||
|
{%- endif %}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
expected: `
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
yes
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}, {
|
||||||
|
text: `
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
{%- if false %}
|
||||||
|
no
|
||||||
|
{%- endif %}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
expected: `
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}, {
|
||||||
|
text: `
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
{{ 'John' -}}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
expected: `
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
John</p>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}, {
|
||||||
|
text: `
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
{% if true -%}
|
||||||
|
yes
|
||||||
|
{% endif -%}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
expected: `
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
yes
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}, {
|
||||||
|
text: `
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
{% if false -%}
|
||||||
|
no
|
||||||
|
{% endif -%}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
expected: `
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}, {
|
||||||
|
text: `
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
{%- if true %}
|
||||||
|
yes
|
||||||
|
{% endif -%}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
expected: `
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
yes
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}, {
|
||||||
|
text: `
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
{%- if false %}
|
||||||
|
no
|
||||||
|
{% endif -%}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
expected: `
|
||||||
|
<div>
|
||||||
|
<p></p>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}, {
|
||||||
|
text: `
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
{% if true -%}
|
||||||
|
yes
|
||||||
|
{%- endif %}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
expected: `
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
yes
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}, {
|
||||||
|
text: `
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
{% if false -%}
|
||||||
|
no
|
||||||
|
{%- endif %}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
expected: `
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}, {
|
||||||
|
text: `
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
{{- 'John' -}}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
expected: `
|
||||||
|
<div>
|
||||||
|
<p>John</p>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}, {
|
||||||
|
text: `
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
{%- if true -%}
|
||||||
|
yes
|
||||||
|
{%- endif -%}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
expected: `
|
||||||
|
<div>
|
||||||
|
<p>yes</p>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}, {
|
||||||
|
text: `
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
{%- if false -%}
|
||||||
|
no
|
||||||
|
{%- endif -%}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
expected: `
|
||||||
|
<div>
|
||||||
|
<p></p>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}, {
|
||||||
|
text: `
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
{{- 'John' -}},
|
||||||
|
{{- '30' -}}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
expected: `
|
||||||
|
<div>
|
||||||
|
<p>John,30</p>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}, {
|
||||||
|
text: `
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
{%- if true -%}
|
||||||
|
yes
|
||||||
|
{%- endif -%}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
expected: `
|
||||||
|
<div>
|
||||||
|
<p>yes</p>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}, {
|
||||||
|
text: `
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
{%- if false -%}
|
||||||
|
no
|
||||||
|
{%- endif -%}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
expected: `
|
||||||
|
<div>
|
||||||
|
<p></p>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}, {
|
||||||
|
text: `
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
{{- 'John' -}}
|
||||||
|
{{- '30' -}}
|
||||||
|
</p>
|
||||||
|
<b>
|
||||||
|
{{ 'John' -}}
|
||||||
|
{{- '30' }}
|
||||||
|
</b>
|
||||||
|
<i>
|
||||||
|
{{- 'John' }}
|
||||||
|
{{ '30' -}}
|
||||||
|
</i>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
expected: `
|
||||||
|
<div>
|
||||||
|
<p>John30</p>
|
||||||
|
<b>
|
||||||
|
John30
|
||||||
|
</b>
|
||||||
|
<i>John
|
||||||
|
30</i>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}, {
|
||||||
|
text: `
|
||||||
|
<div>
|
||||||
|
{%- if true -%}
|
||||||
|
{%- if true -%}
|
||||||
|
<p>
|
||||||
|
{{- 'John' -}}
|
||||||
|
</p>
|
||||||
|
{%- endif -%}
|
||||||
|
{%- endif -%}
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
expected: `
|
||||||
|
<div><p>John</p></div>
|
||||||
|
`
|
||||||
|
}, {
|
||||||
|
text: `
|
||||||
|
<div>
|
||||||
|
{% raw %}
|
||||||
|
{%- if true -%}
|
||||||
|
<p>
|
||||||
|
{{- 'John' -}}
|
||||||
|
</p>
|
||||||
|
{%- endif -%}
|
||||||
|
{% endraw %}
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
expected: `
|
||||||
|
<div>
|
||||||
|
|
||||||
|
{%- if true -%}
|
||||||
|
<p>
|
||||||
|
{{- 'John' -}}
|
||||||
|
</p>
|
||||||
|
{%- endif -%}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
describe('Whitespace Control', function () {
|
||||||
|
cases.forEach(item => it(
|
||||||
|
item.text,
|
||||||
|
() => expect(liquid.parseAndRender(item.text)).to.eventually.equal(item.expected)
|
||||||
|
))
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user