mirror of
https://github.com/harttle/liquidjs.git
synced 2026-10-03 00:55:13 -07:00
chore(TypeScript): fix linting and generate .d.ts
This commit is contained in:
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
node_modules
|
node_modules
|
||||||
dist
|
dist
|
||||||
build
|
demo
|
||||||
coverage
|
coverage
|
||||||
|
|||||||
+3
-1
@@ -15,6 +15,8 @@
|
|||||||
],
|
],
|
||||||
"rules": {
|
"rules": {
|
||||||
"no-var": 2,
|
"no-var": 2,
|
||||||
"prefer-const": 2
|
"prefer-const": 2,
|
||||||
|
"no-unused-vars": "off",
|
||||||
|
"@typescript-eslint/no-unused-vars": ["error", { "vars": "all", "args": "after-used", "ignoreRestSiblings": false }]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@
|
|||||||
"types": "dist/liquid.d.ts",
|
"types": "dist/liquid.d.ts",
|
||||||
"browser": "dist/liquid.js",
|
"browser": "dist/liquid.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"lint": "eslint src/ test/ *.js",
|
"lint": "eslint . --ext .ts --ext .js",
|
||||||
"unit": "mocha -r ts-node/register -r tsconfig-paths/register test/unit/**.ts",
|
"unit": "mocha -r ts-node/register -r tsconfig-paths/register test/unit/**.ts",
|
||||||
"e2e": "npm run build && mocha -r ts-node/register -r tsconfig-paths/register test/e2e/**/*.ts",
|
"e2e": "npm run build && mocha -r ts-node/register -r tsconfig-paths/register test/e2e/**/*.ts",
|
||||||
"test": "npm run unit && npm run e2e",
|
"test": "npm run unit && npm run e2e",
|
||||||
|
|||||||
@@ -25,5 +25,5 @@ export default {
|
|||||||
'escape': escape,
|
'escape': escape,
|
||||||
'escape_once': str => escape(unescape(str)),
|
'escape_once': str => escape(unescape(str)),
|
||||||
'newline_to_br': v => v.replace(/\n/g, '<br />'),
|
'newline_to_br': v => v.replace(/\n/g, '<br />'),
|
||||||
'strip_html': v => String(v).replace(/<script.*?<\/script>|<!--.*?-->|<style.*?<\/style>|<.*?>/g, ''),
|
'strip_html': v => String(v).replace(/<script.*?<\/script>|<!--.*?-->|<style.*?<\/style>|<.*?>/g, '')
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export default {
|
|||||||
return Math.round(v * amp) / amp
|
return Math.round(v * amp) / amp
|
||||||
},
|
},
|
||||||
'plus': bindFixed((v, arg) => Number(v) + Number(arg)),
|
'plus': bindFixed((v, arg) => Number(v) + Number(arg)),
|
||||||
'times': (v, arg) => v * arg,
|
'times': (v, arg) => v * arg
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFixed (v) {
|
function getFixed (v) {
|
||||||
|
|||||||
@@ -28,5 +28,5 @@ export default {
|
|||||||
let ret = arr.slice(0, l).join(' ')
|
let ret = arr.slice(0, l).join(' ')
|
||||||
if (arr.length > l) ret += o
|
if (arr.length > l) ret += o
|
||||||
return ret
|
return ret
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { RenderBreakError } from 'src/util/error'
|
import { RenderBreakError } from 'src/util/error'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
render: async function (scope) {
|
render: async function () {
|
||||||
throw new RenderBreakError('break')
|
throw new RenderBreakError('break')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
import assert from 'src/util/assert'
|
import assert from 'src/util/assert'
|
||||||
import { identifier } from 'src/parser/lexical'
|
import { identifier } from 'src/parser/lexical'
|
||||||
import { CaptureScope } from 'src/scope/scopes'
|
import { CaptureScope } from 'src/scope/scopes'
|
||||||
|
import TagToken from 'src/parser/tag-token'
|
||||||
|
import Token from 'src/parser/token'
|
||||||
|
import Scope from 'src/scope/scope'
|
||||||
|
|
||||||
const re = new RegExp(`(${identifier.source})`)
|
const re = new RegExp(`(${identifier.source})`)
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
parse: function (tagToken, remainTokens) {
|
parse: function (tagToken: TagToken, remainTokens: Token[]) {
|
||||||
const match = tagToken.args.match(re)
|
const match = tagToken.args.match(re)
|
||||||
assert(match, `${tagToken.args} not valid identifier`)
|
assert(match, `${tagToken.args} not valid identifier`)
|
||||||
|
|
||||||
@@ -13,14 +16,14 @@ export default {
|
|||||||
this.templates = []
|
this.templates = []
|
||||||
|
|
||||||
const stream = this.liquid.parser.parseStream(remainTokens)
|
const stream = this.liquid.parser.parseStream(remainTokens)
|
||||||
stream.on('tag:endcapture', token => stream.stop())
|
stream.on('tag:endcapture', () => stream.stop())
|
||||||
.on('template', tpl => this.templates.push(tpl))
|
.on('template', tpl => this.templates.push(tpl))
|
||||||
.on('end', x => {
|
.on('end', () => {
|
||||||
throw new Error(`tag ${tagToken.raw} not closed`)
|
throw new Error(`tag ${tagToken.raw} not closed`)
|
||||||
})
|
})
|
||||||
stream.start()
|
stream.start()
|
||||||
},
|
},
|
||||||
render: async function (scope, hash) {
|
render: async function (scope: Scope) {
|
||||||
const html = await this.liquid.renderer.renderTemplates(this.templates, scope)
|
const html = await this.liquid.renderer.renderTemplates(this.templates, scope)
|
||||||
const ctx = new CaptureScope()
|
const ctx = new CaptureScope()
|
||||||
ctx[this.variable] = html
|
ctx[this.variable] = html
|
||||||
|
|||||||
@@ -15,16 +15,16 @@ export default {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
.on('tag:else', () => (p = this.elseTemplates))
|
.on('tag:else', () => (p = this.elseTemplates))
|
||||||
.on('tag:endcase', token => stream.stop())
|
.on('tag:endcase', () => stream.stop())
|
||||||
.on('template', tpl => p.push(tpl))
|
.on('template', tpl => p.push(tpl))
|
||||||
.on('end', x => {
|
.on('end', () => {
|
||||||
throw new Error(`tag ${tagToken.raw} not closed`)
|
throw new Error(`tag ${tagToken.raw} not closed`)
|
||||||
})
|
})
|
||||||
|
|
||||||
stream.start()
|
stream.start()
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function (scope, hash) {
|
render: function (scope) {
|
||||||
for (let i = 0; i < this.cases.length; i++) {
|
for (let i = 0; i < this.cases.length; i++) {
|
||||||
const branch = this.cases[i]
|
const branch = this.cases[i]
|
||||||
const val = evalExp(branch.val, scope)
|
const val = evalExp(branch.val, scope)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ export default {
|
|||||||
.on('token', token => {
|
.on('token', token => {
|
||||||
if (token.name === 'endcomment') stream.stop()
|
if (token.name === 'endcomment') stream.stop()
|
||||||
})
|
})
|
||||||
.on('end', x => {
|
.on('end', () => {
|
||||||
throw new Error(`tag ${tagToken.raw} not closed`)
|
throw new Error(`tag ${tagToken.raw} not closed`)
|
||||||
})
|
})
|
||||||
stream.start()
|
stream.start()
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { RenderBreakError } from 'src/util/error'
|
import { RenderBreakError } from 'src/util/error'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
render: async function (scope) {
|
render: async function () {
|
||||||
throw new RenderBreakError('continue')
|
throw new RenderBreakError('continue')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ const groupRE = new RegExp(`^(?:(${rValue.source})\\s*:\\s*)?(.*)$`)
|
|||||||
const candidatesRE = new RegExp(rValue.source, 'g')
|
const candidatesRE = new RegExp(rValue.source, 'g')
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
parse: function (tagToken, remainTokens) {
|
parse: function (tagToken) {
|
||||||
let match = groupRE.exec(tagToken.args)
|
let match = groupRE.exec(tagToken.args)
|
||||||
assert(match, `illegal tag: ${tagToken.raw}`)
|
assert(match, `illegal tag: ${tagToken.raw}`)
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ export default {
|
|||||||
assert(this.candidates.length, `empty candidates: ${tagToken.raw}`)
|
assert(this.candidates.length, `empty candidates: ${tagToken.raw}`)
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function (scope, hash) {
|
render: function (scope) {
|
||||||
const group = evalValue(this.group, scope)
|
const group = evalValue(this.group, scope)
|
||||||
const fingerprint = `cycle:${group}:` + this.candidates.join(',')
|
const fingerprint = `cycle:${group}:` + this.candidates.join(',')
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
import assert from 'src/util/assert'
|
import assert from 'src/util/assert'
|
||||||
import { identifier } from 'src/parser/lexical'
|
import { identifier } from 'src/parser/lexical'
|
||||||
import { CaptureScope, AssignScope, DecrementScope } from 'src/scope/scopes'
|
import { CaptureScope, AssignScope, DecrementScope } from 'src/scope/scopes'
|
||||||
|
import TagToken from 'src/parser/tag-token'
|
||||||
|
import Scope from 'src/scope/scope'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
parse: function (token) {
|
parse: function (token: TagToken) {
|
||||||
const match = token.args.match(identifier)
|
const match = token.args.match(identifier)
|
||||||
assert(match, `illegal identifier ${token.args}`)
|
assert(match, `illegal identifier ${token.args}`)
|
||||||
this.variable = match[0]
|
this.variable = match[0]
|
||||||
},
|
},
|
||||||
render: function (scope, hash) {
|
render: function (scope: Scope) {
|
||||||
let context = scope.findContextFor(
|
let context = scope.findContextFor(
|
||||||
this.variable,
|
this.variable,
|
||||||
ctx => {
|
ctx => {
|
||||||
|
|||||||
@@ -18,16 +18,16 @@ export default {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
.on('tag:else', () => (p = this.elseTemplates))
|
.on('tag:else', () => (p = this.elseTemplates))
|
||||||
.on('tag:endif', token => stream.stop())
|
.on('tag:endif', () => stream.stop())
|
||||||
.on('template', tpl => p.push(tpl))
|
.on('template', tpl => p.push(tpl))
|
||||||
.on('end', x => {
|
.on('end', () => {
|
||||||
throw new Error(`tag ${tagToken.raw} not closed`)
|
throw new Error(`tag ${tagToken.raw} not closed`)
|
||||||
})
|
})
|
||||||
|
|
||||||
stream.start()
|
stream.start()
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function (scope, hash) {
|
render: function (scope) {
|
||||||
for (const branch of this.branches) {
|
for (const branch of this.branches) {
|
||||||
const cond = evalExp(branch.cond, scope)
|
const cond = evalExp(branch.cond, scope)
|
||||||
if (isTruthy(cond)) {
|
if (isTruthy(cond)) {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ export default {
|
|||||||
assert(match, `illegal identifier ${token.args}`)
|
assert(match, `illegal identifier ${token.args}`)
|
||||||
this.variable = match[0]
|
this.variable = match[0]
|
||||||
},
|
},
|
||||||
render: function (scope, hash) {
|
render: function (scope) {
|
||||||
let context = scope.findContextFor(
|
let context = scope.findContextFor(
|
||||||
this.variable,
|
this.variable,
|
||||||
ctx => {
|
ctx => {
|
||||||
|
|||||||
@@ -15,7 +15,10 @@ import tablerow from './tablerow'
|
|||||||
import unless from './unless'
|
import unless from './unless'
|
||||||
import Break from './break'
|
import Break from './break'
|
||||||
import Continue from './continue'
|
import Continue from './continue'
|
||||||
|
import ITagImplOptions from 'src/template/tag/itag-impl-options'
|
||||||
|
|
||||||
export default {
|
const tags: { [key: string]: ITagImplOptions } = {
|
||||||
assign, 'for': For, capture, 'case': Case, comment, include, decrement, increment, cycle, 'if': If, layout, block, raw, tablerow, unless, 'break': Break, 'continue': Continue
|
assign, 'for': For, capture, 'case': Case, comment, include, decrement, increment, cycle, 'if': If, layout, block, raw, tablerow, unless, 'break': Break, 'continue': Continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default tags
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ export default {
|
|||||||
})
|
})
|
||||||
stream.start()
|
stream.start()
|
||||||
},
|
},
|
||||||
render: function (scope, hash) {
|
render: function () {
|
||||||
return this.tokens.map(token => token.raw).join('')
|
return this.tokens.map(token => token.raw).join('')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export default {
|
|||||||
let p
|
let p
|
||||||
const stream = this.liquid.parser.parseStream(remainTokens)
|
const stream = this.liquid.parser.parseStream(remainTokens)
|
||||||
.on('start', () => (p = this.templates))
|
.on('start', () => (p = this.templates))
|
||||||
.on('tag:endtablerow', token => stream.stop())
|
.on('tag:endtablerow', () => stream.stop())
|
||||||
.on('template', tpl => p.push(tpl))
|
.on('template', tpl => p.push(tpl))
|
||||||
.on('end', () => {
|
.on('end', () => {
|
||||||
throw new Error(`tag ${tagToken.raw} not closed`)
|
throw new Error(`tag ${tagToken.raw} not closed`)
|
||||||
@@ -35,7 +35,7 @@ export default {
|
|||||||
|
|
||||||
collection = collection.slice(offset, offset + limit)
|
collection = collection.slice(offset, offset + limit)
|
||||||
const cols = hash.cols || collection.length
|
const cols = hash.cols || collection.length
|
||||||
const contexts = collection.map((item, i) => {
|
const contexts = collection.map(item => {
|
||||||
const ctx = {}
|
const ctx = {}
|
||||||
ctx[this.variable] = item
|
ctx[this.variable] = item
|
||||||
return ctx
|
return ctx
|
||||||
|
|||||||
@@ -6,21 +6,21 @@ export default {
|
|||||||
this.elseTemplates = []
|
this.elseTemplates = []
|
||||||
let p
|
let p
|
||||||
const stream = this.liquid.parser.parseStream(remainTokens)
|
const stream = this.liquid.parser.parseStream(remainTokens)
|
||||||
.on('start', x => {
|
.on('start', () => {
|
||||||
p = this.templates
|
p = this.templates
|
||||||
this.cond = tagToken.args
|
this.cond = tagToken.args
|
||||||
})
|
})
|
||||||
.on('tag:else', () => (p = this.elseTemplates))
|
.on('tag:else', () => (p = this.elseTemplates))
|
||||||
.on('tag:endunless', token => stream.stop())
|
.on('tag:endunless', () => stream.stop())
|
||||||
.on('template', tpl => p.push(tpl))
|
.on('template', tpl => p.push(tpl))
|
||||||
.on('end', x => {
|
.on('end', () => {
|
||||||
throw new Error(`tag ${tagToken.raw} not closed`)
|
throw new Error(`tag ${tagToken.raw} not closed`)
|
||||||
})
|
})
|
||||||
|
|
||||||
stream.start()
|
stream.start()
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function (scope, hash) {
|
render: function (scope) {
|
||||||
const cond = evalExp(this.cond, scope)
|
const cond = evalExp(this.cond, scope)
|
||||||
return isFalsy(cond)
|
return isFalsy(cond)
|
||||||
? this.liquid.renderer.renderTemplates(this.templates, scope)
|
? this.liquid.renderer.renderTemplates(this.templates, scope)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export interface LiquidOptions {
|
export interface LiquidOptions {
|
||||||
/** `root` is a directory or an array of directories to resolve layouts and includes, as well as the filename passed in when calling `.renderFile()`. If an array, the files are looked up in the order they occur in the array. Defaults to `["."]`*/
|
/** `root` is a directory or an array of directories to resolve layouts and includes, as well as the filename passed in when calling `.renderFile()`. If an array, the files are looked up in the order they occur in the array. Defaults to `["."]` */
|
||||||
root?: string | string[]
|
root?: string | string[]
|
||||||
/** `extname` is used to lookup the template file when filepath doesn't include an extension name. Eg: setting to `".html"` will allow including file by basename. Defaults to `""`. */
|
/** `extname` is used to lookup the template file when filepath doesn't include an extension name. Eg: setting to `".html"` will allow including file by basename. Defaults to `""`. */
|
||||||
extname?: string
|
extname?: string
|
||||||
@@ -8,17 +8,17 @@ export interface LiquidOptions {
|
|||||||
/** `dynamicPartials`: if set, treat `<filepath>` parameter in `{%include filepath %}`, `{%layout filepath%}` as a variable, otherwise as a literal value. Defaults to `true`. */
|
/** `dynamicPartials`: if set, treat `<filepath>` parameter in `{%include filepath %}`, `{%layout filepath%}` as a variable, otherwise as a literal value. Defaults to `true`. */
|
||||||
dynamicPartials?: boolean
|
dynamicPartials?: boolean
|
||||||
/** `strict_filters` is used to enable strict filter existence. If set to `false`, undefined filters will be rendered as empty string. Otherwise, undefined filters will cause an exception. Defaults to `false`. */
|
/** `strict_filters` is used to enable strict filter existence. If set to `false`, undefined filters will be rendered as empty string. Otherwise, undefined filters will cause an exception. Defaults to `false`. */
|
||||||
strict_filters?: boolean
|
strict_filters?: boolean // eslint-disable-line
|
||||||
/** `strict_variables` is used to enable strict variable derivation. If set to `false`, undefined variables will be rendered as empty string. Otherwise, undefined variables will cause an exception. Defaults to `false`. */
|
/** `strict_variables` is used to enable strict variable derivation. If set to `false`, undefined variables will be rendered as empty string. Otherwise, undefined variables will cause an exception. Defaults to `false`. */
|
||||||
strict_variables?: boolean
|
strict_variables?: boolean // eslint-disable-line
|
||||||
/** `trim_tag_right` is used to strip blank characters (including ` `, `\t`, and `\r`) from the right of tags (`{% %}`) until `\n` (inclusive). Defaults to `false`. */
|
/** `trim_tag_right` is used to strip blank characters (including ` `, `\t`, and `\r`) from the right of tags (`{% %}`) until `\n` (inclusive). Defaults to `false`. */
|
||||||
trim_tag_right?: boolean
|
trim_tag_right?: boolean // eslint-disable-line
|
||||||
/** `trim_tag_left` is similar to `trim_tag_right`, whereas the `\n` is exclusive. Defaults to `false`. See Whitespace Control for details. */
|
/** `trim_tag_left` is similar to `trim_tag_right`, whereas the `\n` is exclusive. Defaults to `false`. See Whitespace Control for details. */
|
||||||
trim_tag_left?: boolean
|
trim_tag_left?: boolean // eslint-disable-line
|
||||||
/** ``trim_value_right` is used to strip blank characters (including ` `, `\t`, and `\r`) from the right of values (`{{ }}`) until `\n` (inclusive). Defaults to `false`. */
|
/** ``trim_value_right` is used to strip blank characters (including ` `, `\t`, and `\r`) from the right of values (`{{ }}`) until `\n` (inclusive). Defaults to `false`. */
|
||||||
trim_value_right?: boolean
|
trim_value_right?: boolean // eslint-disable-line
|
||||||
/** `trim_value_left` is similar to `trim_value_right`, whereas the `\n` is exclusive. Defaults to `false`. See Whitespace Control for details. */
|
/** `trim_value_left` is similar to `trim_value_right`, whereas the `\n` is exclusive. Defaults to `false`. See Whitespace Control for details. */
|
||||||
trim_value_left?: boolean
|
trim_value_left?: boolean // eslint-disable-line
|
||||||
/** `greedy` is used to specify whether `trim_left`/`trim_right` is greedy. When set to `true`, all consecutive blank characters including `\n` will be trimed regardless of line breaks. Defaults to `true`. */
|
/** `greedy` is used to specify whether `trim_left`/`trim_right` is greedy. When set to `true`, all consecutive blank characters including `\n` will be trimed regardless of line breaks. Defaults to `true`. */
|
||||||
greedy?: boolean
|
greedy?: boolean
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-7
@@ -3,7 +3,7 @@ import * as Types from './types'
|
|||||||
import * as template from 'template'
|
import * as template from 'template'
|
||||||
import * as _ from './util/underscore'
|
import * as _ from './util/underscore'
|
||||||
import ITemplate from './template/itemplate'
|
import ITemplate from './template/itemplate'
|
||||||
import * as tokenizer from './parser/tokenizer'
|
import Tokenizer from './parser/tokenizer'
|
||||||
import Render from './render/render'
|
import Render from './render/render'
|
||||||
import Tag from './template/tag/tag'
|
import Tag from './template/tag/tag'
|
||||||
import Filter from './template/filter'
|
import Filter from './template/filter'
|
||||||
@@ -20,6 +20,7 @@ export default class Liquid {
|
|||||||
private cache: object
|
private cache: object
|
||||||
private parser: Parser
|
private parser: Parser
|
||||||
private renderer: Render
|
private renderer: Render
|
||||||
|
private tokenizer: Tokenizer
|
||||||
|
|
||||||
constructor (options: LiquidOptions = {}) {
|
constructor (options: LiquidOptions = {}) {
|
||||||
options = _.assign({}, defaultOptions, options)
|
options = _.assign({}, defaultOptions, options)
|
||||||
@@ -31,31 +32,32 @@ export default class Liquid {
|
|||||||
this.options = options
|
this.options = options
|
||||||
this.parser = new Parser(this)
|
this.parser = new Parser(this)
|
||||||
this.renderer = new Render()
|
this.renderer = new Render()
|
||||||
|
this.tokenizer = new Tokenizer(this.options)
|
||||||
|
|
||||||
_.forOwn(builtinTags, (conf, name) => this.registerTag(name, conf))
|
_.forOwn(builtinTags, (conf, name) => this.registerTag(name, conf))
|
||||||
_.forOwn(builtinFilters, (handler, name) => this.registerFilter(name, handler))
|
_.forOwn(builtinFilters, (handler, name) => this.registerFilter(name, handler))
|
||||||
}
|
}
|
||||||
parse(html: string, filepath?: string) {
|
parse (html: string, filepath?: string) {
|
||||||
const tokens = tokenizer.parse(html, filepath, this.options)
|
const tokens = this.tokenizer.tokenize(html, filepath)
|
||||||
return this.parser.parse(tokens)
|
return this.parser.parse(tokens)
|
||||||
}
|
}
|
||||||
render(tpl: Array<ITemplate>, ctx?: object, opts?: LiquidOptions) {
|
render (tpl: Array<ITemplate>, ctx?: object, opts?: LiquidOptions) {
|
||||||
opts = _.assign({}, this.options, opts)
|
opts = _.assign({}, this.options, opts)
|
||||||
const scope = new Scope(ctx, opts)
|
const scope = new Scope(ctx, opts)
|
||||||
return this.renderer.renderTemplates(tpl, scope)
|
return this.renderer.renderTemplates(tpl, scope)
|
||||||
}
|
}
|
||||||
async parseAndRender(html: string, ctx?: object, opts?: LiquidOptions) {
|
async parseAndRender (html: string, ctx?: object, opts?: LiquidOptions) {
|
||||||
const tpl = await this.parse(html)
|
const tpl = await this.parse(html)
|
||||||
return this.render(tpl, ctx, opts)
|
return this.render(tpl, ctx, opts)
|
||||||
}
|
}
|
||||||
async getTemplate(file, root) {
|
async getTemplate (file, root) {
|
||||||
const filepath = await template.resolve(file, root, this.options)
|
const filepath = await template.resolve(file, root, this.options)
|
||||||
return this.respectCache(filepath, async () => {
|
return this.respectCache(filepath, async () => {
|
||||||
const str = await template.read(filepath)
|
const str = await template.read(filepath)
|
||||||
return this.parse(str, filepath)
|
return this.parse(str, filepath)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
async renderFile(file, ctx?: object, opts?: LiquidOptions) {
|
async renderFile (file, ctx?: object, opts?: LiquidOptions) {
|
||||||
opts = _.assign({}, opts)
|
opts = _.assign({}, opts)
|
||||||
const templates = await this.getTemplate(file, opts.root)
|
const templates = await this.getTemplate(file, opts.root)
|
||||||
return this.render(templates, ctx, opts)
|
return this.render(templates, ctx, opts)
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import Token from './token'
|
import Token from './token'
|
||||||
|
|
||||||
export default class DelimitedToken extends Token {
|
export default class DelimitedToken extends Token {
|
||||||
trim_left: boolean
|
trimLeft: boolean
|
||||||
trim_right: boolean
|
trimRight: boolean
|
||||||
constructor(raw, pos, input, file, line) {
|
constructor (raw, pos, input, file, line) {
|
||||||
super(raw, pos, input, file, line)
|
super(raw, pos, input, file, line)
|
||||||
this.trim_left = raw[2] === '-'
|
this.trimLeft = raw[2] === '-'
|
||||||
this.trim_right = raw[raw.length - 3] === '-'
|
this.trimRight = raw[raw.length - 3] === '-'
|
||||||
this.value = raw.slice(this.trim_left ? 3 : 2, this.trim_right ? -3 : -2).trim()
|
this.value = raw.slice(this.trimLeft ? 3 : 2, this.trimRight ? -3 : -2).trim()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import Token from './token'
|
import Token from './token'
|
||||||
|
|
||||||
export default class HTMLToken extends Token {
|
export default class HTMLToken extends Token {
|
||||||
constructor(str, begin, input, file, line) {
|
constructor (str, begin, input, file, line) {
|
||||||
super(str, begin, input, file, line)
|
super(str, begin, input, file, line)
|
||||||
this.type = 'html'
|
this.type = 'html'
|
||||||
this.value = str
|
this.value = str
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import DelimitedToken from './delimited-token'
|
import DelimitedToken from './delimited-token'
|
||||||
|
|
||||||
export default class OutputToken extends DelimitedToken {
|
export default class OutputToken extends DelimitedToken {
|
||||||
constructor(raw, pos, input, file, line) {
|
constructor (raw, pos, input, file, line) {
|
||||||
super(raw, pos, input, file, line)
|
super(raw, pos, input, file, line)
|
||||||
this.type = 'output'
|
this.type = 'output'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,18 +2,16 @@ import { ParseError } from '../util/error'
|
|||||||
import Liquid from 'src/liquid'
|
import Liquid from 'src/liquid'
|
||||||
import ParseStream from './parse-stream'
|
import ParseStream from './parse-stream'
|
||||||
import Token from './token'
|
import Token from './token'
|
||||||
import Tag from 'src/template/tag/tag'
|
|
||||||
import HTMLToken from './html-token'
|
|
||||||
import TagToken from './tag-token'
|
import TagToken from './tag-token'
|
||||||
import OutputToken from './output-token'
|
import OutputToken from './output-token'
|
||||||
|
import Tag from 'src/template/tag/tag'
|
||||||
import Output from 'src/template/output'
|
import Output from 'src/template/output'
|
||||||
import HTML from 'src/template/html'
|
import HTML from 'src/template/html'
|
||||||
import Value from 'src/template/value'
|
|
||||||
|
|
||||||
export default class Parser {
|
export default class Parser {
|
||||||
liquid: Liquid
|
liquid: Liquid
|
||||||
|
|
||||||
constructor(liquid: Liquid) {
|
constructor (liquid: Liquid) {
|
||||||
this.liquid = liquid
|
this.liquid = liquid
|
||||||
}
|
}
|
||||||
parse (tokens: Array<Token>) {
|
parse (tokens: Array<Token>) {
|
||||||
@@ -27,10 +25,10 @@ export default class Parser {
|
|||||||
parseToken (token: Token, remainTokens: Array<Token>) {
|
parseToken (token: Token, remainTokens: Array<Token>) {
|
||||||
try {
|
try {
|
||||||
if (token.type === 'tag') {
|
if (token.type === 'tag') {
|
||||||
return new Tag(token, remainTokens, this.liquid)
|
return new Tag(token as TagToken, remainTokens, this.liquid)
|
||||||
}
|
}
|
||||||
if (token.type === 'output') {
|
if (token.type === 'output') {
|
||||||
return new Output(token, this.liquid.options.strict_filters)
|
return new Output(token as OutputToken, this.liquid.options.strict_filters)
|
||||||
}
|
}
|
||||||
return new HTML(token)
|
return new HTML(token)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import * as lexical from './lexical'
|
|||||||
export default class TagToken extends DelimitedToken {
|
export default class TagToken extends DelimitedToken {
|
||||||
name: string
|
name: string
|
||||||
args: string
|
args: string
|
||||||
constructor(raw, pos, input, file, line) {
|
constructor (raw, pos, input, file, line) {
|
||||||
super(raw, pos, input, file, line)
|
super(raw, pos, input, file, line)
|
||||||
this.type = 'tag'
|
this.type = 'tag'
|
||||||
const match = this.value.match(lexical.tagLine)
|
const match = this.value.match(lexical.tagLine)
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@ export default class Token {
|
|||||||
input: string
|
input: string
|
||||||
file: string
|
file: string
|
||||||
value: string
|
value: string
|
||||||
constructor(raw, pos, input, file, line) {
|
constructor (raw, pos, input, file, line) {
|
||||||
this.line = line
|
this.line = line
|
||||||
this.raw = raw
|
this.raw = raw
|
||||||
this.input = input
|
this.input = input
|
||||||
|
|||||||
+44
-39
@@ -2,52 +2,57 @@ import whiteSpaceCtrl from './whitespace-ctrl'
|
|||||||
import HTMLToken from './html-token'
|
import HTMLToken from './html-token'
|
||||||
import TagToken from './tag-token'
|
import TagToken from './tag-token'
|
||||||
import OutputToken from './output-token'
|
import OutputToken from './output-token'
|
||||||
|
import { LiquidOptions, defaultOptions } from 'src/liquid-options'
|
||||||
|
|
||||||
enum ParseState { HTML, OUTPUT, TAG }
|
enum ParseState { HTML, OUTPUT, TAG }
|
||||||
|
|
||||||
export function parse (input: string, file?: string, options?) {
|
export default class Tokenizer {
|
||||||
const tokens = []
|
options: LiquidOptions
|
||||||
let p = 0
|
constructor (options: LiquidOptions = defaultOptions) {
|
||||||
let line = 1
|
this.options = options
|
||||||
let state = ParseState.HTML
|
}
|
||||||
let buffer = ''
|
tokenize (input: string, file?: string) {
|
||||||
let bufferBegin = 0
|
const tokens = []
|
||||||
|
let p = 0
|
||||||
|
let line = 1
|
||||||
|
let state = ParseState.HTML
|
||||||
|
let buffer = ''
|
||||||
|
let bufferBegin = 0
|
||||||
|
|
||||||
while(p < input.length) {
|
while (p < input.length) {
|
||||||
if (input[p] === '\n') line++
|
if (input[p] === '\n') line++
|
||||||
const bin = input.substr(p, 2)
|
const bin = input.substr(p, 2)
|
||||||
if (state === ParseState.HTML) {
|
if (state === ParseState.HTML) {
|
||||||
if (bin === '{{' || bin === '{%') {
|
if (bin === '{{' || bin === '{%') {
|
||||||
if (buffer) tokens.push(new HTMLToken(buffer, bufferBegin, input, file, line))
|
if (buffer) tokens.push(new HTMLToken(buffer, bufferBegin, input, file, line))
|
||||||
buffer = bin
|
buffer = bin
|
||||||
bufferBegin = p
|
bufferBegin = p
|
||||||
|
p += 2
|
||||||
|
state = bin === '{{' ? ParseState.OUTPUT : ParseState.TAG
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
} else if (state === ParseState.OUTPUT && bin === '}}') {
|
||||||
|
buffer += '}}'
|
||||||
|
tokens.push(new OutputToken(buffer, bufferBegin, input, file, line))
|
||||||
p += 2
|
p += 2
|
||||||
state = bin === '{{' ? ParseState.OUTPUT : ParseState.TAG
|
buffer = ''
|
||||||
|
bufferBegin = p
|
||||||
|
state = ParseState.HTML
|
||||||
|
continue
|
||||||
|
} else if (bin === '%}') {
|
||||||
|
buffer += '%}'
|
||||||
|
tokens.push(new TagToken(buffer, bufferBegin, input, file, line))
|
||||||
|
p += 2
|
||||||
|
buffer = ''
|
||||||
|
bufferBegin = p
|
||||||
|
state = ParseState.HTML
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
buffer += input[p++]
|
||||||
}
|
}
|
||||||
else if (state === ParseState.OUTPUT && bin === '}}') {
|
if (buffer) tokens.push(new HTMLToken(buffer, bufferBegin, input, file, line))
|
||||||
buffer += '}}'
|
|
||||||
tokens.push(new OutputToken(buffer, bufferBegin, input, file, line))
|
|
||||||
p += 2
|
|
||||||
buffer = ''
|
|
||||||
bufferBegin = p
|
|
||||||
state = ParseState.HTML
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
else if (bin === '%}') {
|
|
||||||
buffer += '%}'
|
|
||||||
tokens.push(new TagToken(buffer, bufferBegin, input, file, line))
|
|
||||||
p += 2
|
|
||||||
buffer = ''
|
|
||||||
bufferBegin = p
|
|
||||||
state = ParseState.HTML
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
buffer += input[p++]
|
|
||||||
}
|
|
||||||
if (buffer) tokens.push(new HTMLToken(buffer, bufferBegin, input, file, line))
|
|
||||||
|
|
||||||
whiteSpaceCtrl(tokens, options)
|
whiteSpaceCtrl(tokens, this.options)
|
||||||
return tokens
|
return tokens
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,46 +1,47 @@
|
|||||||
import { assign } from 'src/util/underscore'
|
import { assign } from 'src/util/underscore'
|
||||||
import TagToken from './tag-token'
|
import DelimitedToken from 'src/parser/delimited-token'
|
||||||
import OutputToken from './output-token'
|
import Token from 'src/parser/token'
|
||||||
import HTMLToken from './html-token'
|
import TagToken from 'src/parser/tag-token'
|
||||||
|
import { LiquidOptions } from 'src/liquid-options'
|
||||||
|
|
||||||
export default function whiteSpaceCtrl (tokens, options) {
|
export default function whiteSpaceCtrl (tokens: Token[], options: LiquidOptions) {
|
||||||
options = assign({ greedy: true }, options)
|
options = assign({ greedy: true }, options)
|
||||||
let inRaw = false
|
let inRaw = false
|
||||||
|
|
||||||
tokens.forEach((token, i) => {
|
tokens.forEach((token: Token, i: number) => {
|
||||||
if (shouldTrimLeft(token, inRaw, options)) {
|
if (shouldTrimLeft(token as DelimitedToken, inRaw, options)) {
|
||||||
trimLeft(tokens[i - 1], options.greedy)
|
trimLeft(tokens[i - 1], options.greedy)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (token.type === 'tag' && token.name === 'raw') inRaw = true
|
if (token.type === 'tag' && (token as TagToken).name === 'raw') inRaw = true
|
||||||
if (token.type === 'tag' && token.name === 'endraw') inRaw = false
|
if (token.type === 'tag' && (token as TagToken).name === 'endraw') inRaw = false
|
||||||
|
|
||||||
if (shouldTrimRight(token, inRaw, options)) {
|
if (shouldTrimRight(token as DelimitedToken, inRaw, options)) {
|
||||||
trimRight(tokens[i + 1], options.greedy)
|
trimRight(tokens[i + 1], options.greedy)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function shouldTrimLeft (token, inRaw, options) {
|
function shouldTrimLeft (token: DelimitedToken, inRaw: boolean, options) {
|
||||||
if (inRaw) return false
|
if (inRaw) return false
|
||||||
if (token.type === 'tag') return token.trim_left || options.trim_tag_left
|
if (token.type === 'tag') return token.trimLeft || options.trim_tag_left
|
||||||
if (token.type === 'output') return token.trim_left || options.trim_value_left
|
if (token.type === 'output') return token.trimLeft || options.trim_value_left
|
||||||
}
|
}
|
||||||
|
|
||||||
function shouldTrimRight (token, inRaw, options) {
|
function shouldTrimRight (token: DelimitedToken, inRaw: boolean, options) {
|
||||||
if (inRaw) return false
|
if (inRaw) return false
|
||||||
if (token.type === 'tag') return token.trim_right || options.trim_tag_right
|
if (token.type === 'tag') return token.trimRight || options.trim_tag_right
|
||||||
if (token.type === 'output') return token.trim_right || options.trim_value_right
|
if (token.type === 'output') return token.trimRight || options.trim_value_right
|
||||||
}
|
}
|
||||||
|
|
||||||
function trimLeft (token, greedy) {
|
function trimLeft (token: Token, greedy: boolean) {
|
||||||
if (!token || token.type !== 'html') return
|
if (!token || token.type !== 'html') return
|
||||||
|
|
||||||
const rLeft = greedy ? /\s+$/g : /[\t\r ]*$/g
|
const rLeft = greedy ? /\s+$/g : /[\t\r ]*$/g
|
||||||
token.value = token.value.replace(rLeft, '')
|
token.value = token.value.replace(rLeft, '')
|
||||||
}
|
}
|
||||||
|
|
||||||
function trimRight (token, greedy) {
|
function trimRight (token: Token, greedy: boolean) {
|
||||||
if (!token || token.type !== 'html') return
|
if (!token || token.type !== 'html') return
|
||||||
|
|
||||||
const rRight = greedy ? /^\s+/g : /^[\t\r ]*\n?/g
|
const rRight = greedy ? /^\s+/g : /^[\t\r ]*\n?/g
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import { stringify, create } from 'src/util/underscore'
|
|
||||||
import { RenderBreakError, RenderError } from 'src/util/error'
|
import { RenderBreakError, RenderError } from 'src/util/error'
|
||||||
import assert from 'src/util/assert'
|
import assert from 'src/util/assert'
|
||||||
import Scope from 'src/scope/scope'
|
|
||||||
|
|
||||||
export default class Render {
|
export default class Render {
|
||||||
async renderTemplates (templates, scope) {
|
async renderTemplates (templates, scope) {
|
||||||
|
|||||||
+2
-2
@@ -15,7 +15,7 @@ export default class Scope {
|
|||||||
strict_variables: false,
|
strict_variables: false,
|
||||||
strict_filters: false,
|
strict_filters: false,
|
||||||
root: []
|
root: []
|
||||||
} , opts)
|
}, opts)
|
||||||
this.contexts = [ctx || {}]
|
this.contexts = [ctx || {}]
|
||||||
}
|
}
|
||||||
getAll () {
|
getAll () {
|
||||||
@@ -59,7 +59,7 @@ export default class Scope {
|
|||||||
}
|
}
|
||||||
return this.contexts.splice(i, 1)[0]
|
return this.contexts.splice(i, 1)[0]
|
||||||
}
|
}
|
||||||
findContextFor (key: string, filter = (arg => true)) {
|
findContextFor (key: string, filter: ((conttext: object) => boolean) = () => true) {
|
||||||
for (let i = this.contexts.length - 1; i >= 0; i--) {
|
for (let i = this.contexts.length - 1; i >= 0; i--) {
|
||||||
const candidate = this.contexts[i]
|
const candidate = this.contexts[i]
|
||||||
if (!filter(candidate)) continue
|
if (!filter(candidate)) continue
|
||||||
|
|||||||
@@ -13,21 +13,21 @@ export default class Filter {
|
|||||||
args: string[]
|
args: string[]
|
||||||
private static impls: {[key: string]: impl} = {}
|
private static impls: {[key: string]: impl} = {}
|
||||||
|
|
||||||
constructor (str: string, strict_filters: boolean = false) {
|
constructor (str: string, strictFilters: boolean = false) {
|
||||||
let match = lexical.filterLine.exec(str)
|
const match = lexical.filterLine.exec(str)
|
||||||
assert(match, 'illegal filter: ' + str)
|
assert(match, 'illegal filter: ' + str)
|
||||||
|
|
||||||
const name = match[1]
|
const name = match[1]
|
||||||
const argList = match[2] || ''
|
const argList = match[2] || ''
|
||||||
const impl = Filter.impls[name]
|
const impl = Filter.impls[name]
|
||||||
if (!impl && strict_filters) throw new TypeError(`undefined filter: ${name}`)
|
if (!impl && strictFilters) throw new TypeError(`undefined filter: ${name}`)
|
||||||
|
|
||||||
this.name = name
|
this.name = name
|
||||||
this.impl = impl || (x => x)
|
this.impl = impl || (x => x)
|
||||||
this.args = this.parseArgs(argList)
|
this.args = this.parseArgs(argList)
|
||||||
}
|
}
|
||||||
parseArgs (argList: string): string[] {
|
parseArgs (argList: string): string[] {
|
||||||
let match, args = []
|
let match; const args = []
|
||||||
while ((match = valueRE.exec(argList.trim()))) {
|
while ((match = valueRE.exec(argList.trim()))) {
|
||||||
const v = match[0]
|
const v = match[0]
|
||||||
const re = new RegExp(`${v}\\s*:`, 'g')
|
const re = new RegExp(`${v}\\s*:`, 'g')
|
||||||
@@ -42,7 +42,7 @@ export default class Filter {
|
|||||||
args.unshift(value)
|
args.unshift(value)
|
||||||
return this.impl.apply(null, args)
|
return this.impl.apply(null, args)
|
||||||
}
|
}
|
||||||
static register(name, filter) {
|
static register (name, filter) {
|
||||||
Filter.impls[name] = filter
|
Filter.impls[name] = filter
|
||||||
}
|
}
|
||||||
static clear () {
|
static clear () {
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
import Template from 'src/template/template'
|
import Template from 'src/template/template'
|
||||||
import Scope from 'src/scope/scope'
|
|
||||||
import ITemplate from 'src/template/itemplate'
|
import ITemplate from 'src/template/itemplate'
|
||||||
import Token from 'src/parser/token'
|
import Token from 'src/parser/token'
|
||||||
|
|
||||||
export default class extends Template implements ITemplate {
|
export default class extends Template implements ITemplate {
|
||||||
str: string
|
str: string
|
||||||
constructor(token: Token) {
|
constructor (token: Token) {
|
||||||
super(token)
|
super(token)
|
||||||
this.str = token.value
|
this.str = token.value
|
||||||
}
|
}
|
||||||
async render(scope: Scope): Promise<string> {
|
async render (): Promise<string> {
|
||||||
return this.str
|
return this.str
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,14 +3,15 @@ import { stringify } from 'src/util/underscore'
|
|||||||
import Template from 'src/template/template'
|
import Template from 'src/template/template'
|
||||||
import ITemplate from 'src/template/itemplate'
|
import ITemplate from 'src/template/itemplate'
|
||||||
import Scope from 'src/scope/scope'
|
import Scope from 'src/scope/scope'
|
||||||
|
import OutputToken from 'src/parser/output-token'
|
||||||
|
|
||||||
export default class Output extends Template implements ITemplate {
|
export default class Output extends Template implements ITemplate {
|
||||||
value: Value
|
value: Value
|
||||||
constructor(token, strict_filters?) {
|
constructor (token: OutputToken, strictFilters?: boolean) {
|
||||||
super(token)
|
super(token)
|
||||||
this.value = new Value(token.value, strict_filters)
|
this.value = new Value(token.value, strictFilters)
|
||||||
}
|
}
|
||||||
async render(scope: Scope) {
|
async render (scope: Scope): Promise<string> {
|
||||||
const html = await this.value.value(scope)
|
const html = await this.value.value(scope)
|
||||||
return stringify(html)
|
return stringify(html)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { evalValue } from 'src/render/syntax'
|
|||||||
*/
|
*/
|
||||||
export default class Hash {
|
export default class Hash {
|
||||||
[key: string]: any
|
[key: string]: any
|
||||||
constructor(markup, scope) {
|
constructor (markup, scope) {
|
||||||
let match
|
let match
|
||||||
hashCapture.lastIndex = 0
|
hashCapture.lastIndex = 0
|
||||||
while ((match = hashCapture.exec(markup))) {
|
while ((match = hashCapture.exec(markup))) {
|
||||||
|
|||||||
@@ -6,5 +6,5 @@ import ITagImpl from './itag-impl'
|
|||||||
|
|
||||||
export default interface ITagImplOptions {
|
export default interface ITagImplOptions {
|
||||||
parse?: (this: ITagImpl, token: TagToken, remainingTokens: Array<Token>) => void
|
parse?: (this: ITagImpl, token: TagToken, remainingTokens: Array<Token>) => void
|
||||||
render?: (this: ITagImpl, scope: Scope, hash: Hash) => string | Promise<string>
|
render?: (this: ITagImpl, scope: Scope, hash: Hash) => any | Promise<any>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { create } from 'src/util/underscore'
|
import { create, stringify } from 'src/util/underscore'
|
||||||
import { stringify } from 'src/util/underscore'
|
|
||||||
import assert from 'src/util/assert'
|
import assert from 'src/util/assert'
|
||||||
|
import Scope from 'src/scope/scope'
|
||||||
import ITagImpl from './itag-impl'
|
import ITagImpl from './itag-impl'
|
||||||
import ITagImplOptions from './itag-impl-options'
|
import ITagImplOptions from './itag-impl-options'
|
||||||
import Liquid from 'src/liquid'
|
import Liquid from 'src/liquid'
|
||||||
@@ -8,26 +8,27 @@ import Hash from './hash'
|
|||||||
import Template from 'src/template/template'
|
import Template from 'src/template/template'
|
||||||
import ITemplate from 'src/template/itemplate'
|
import ITemplate from 'src/template/itemplate'
|
||||||
import TagToken from 'src/parser/tag-token'
|
import TagToken from 'src/parser/tag-token'
|
||||||
|
import Token from 'src/parser/token'
|
||||||
|
|
||||||
export default class Tag extends Template implements ITemplate {
|
export default class Tag extends Template implements ITemplate {
|
||||||
name: string
|
name: string
|
||||||
token: TagToken
|
token: TagToken
|
||||||
private impl: ITagImpl
|
private impl: ITagImpl
|
||||||
static impls: object = {}
|
static impls: { [key: string]: ITagImplOptions } = {}
|
||||||
|
|
||||||
constructor (token, tokens, liquid: Liquid) {
|
constructor (token: TagToken, tokens: Token[], liquid: Liquid) {
|
||||||
super(token)
|
super(token)
|
||||||
this.name = token.name
|
this.name = token.name
|
||||||
|
|
||||||
const impl = Tag.impls[token.name]
|
const impl = Tag.impls[token.name]
|
||||||
assert(impl, `tag ${token.name} not found`)
|
assert(impl, `tag ${token.name} not found`)
|
||||||
this.impl = create(impl)
|
this.impl = create<ITagImplOptions, ITagImpl>(impl)
|
||||||
this.impl.liquid = liquid
|
this.impl.liquid = liquid
|
||||||
if (this.impl.parse) {
|
if (this.impl.parse) {
|
||||||
this.impl.parse(token, tokens)
|
this.impl.parse(token, tokens)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async render (scope) {
|
async render (scope: Scope) {
|
||||||
const hash = new Hash(this.token.args, scope)
|
const hash = new Hash(this.token.args, scope)
|
||||||
const impl = this.impl
|
const impl = this.impl
|
||||||
if (typeof impl.render !== 'function') {
|
if (typeof impl.render !== 'function') {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import Token from 'src/parser/token'
|
|||||||
|
|
||||||
export default class Template {
|
export default class Template {
|
||||||
token: Token;
|
token: Token;
|
||||||
constructor(token) {
|
constructor (token) {
|
||||||
this.token = token;
|
this.token = token
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import Scope from 'src/scope/scope'
|
|||||||
export default class {
|
export default class {
|
||||||
initial: any
|
initial: any
|
||||||
filters: Array<any>
|
filters: Array<any>
|
||||||
constructor(str: string, strict_filters?: boolean) {
|
constructor (str: string, strictFilters?: boolean) {
|
||||||
let match = lexical.matchValue(str)
|
let match = lexical.matchValue(str)
|
||||||
assert(match, `illegal value string: ${str}`)
|
assert(match, `illegal value string: ${str}`)
|
||||||
|
|
||||||
@@ -20,9 +20,9 @@ export default class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.initial = initial
|
this.initial = initial
|
||||||
this.filters = filters.map(str => new Filter(str, strict_filters))
|
this.filters = filters.map(str => new Filter(str, strictFilters))
|
||||||
}
|
}
|
||||||
value(scope: Scope) {
|
value (scope: Scope) {
|
||||||
return this.filters.reduce(
|
return this.filters.reduce(
|
||||||
(prev, filter) => filter.render(prev, scope),
|
(prev, filter) => filter.render(prev, scope),
|
||||||
evalExp(this.initial, scope))
|
evalExp(this.initial, scope))
|
||||||
|
|||||||
+11
-11
@@ -16,14 +16,14 @@ abstract class LiquidError {
|
|||||||
private input: string
|
private input: string
|
||||||
private token: Token
|
private token: Token
|
||||||
private originalError: Error
|
private originalError: Error
|
||||||
constructor(err, token) {
|
constructor (err, token) {
|
||||||
this.input = token.input
|
this.input = token.input
|
||||||
this.line = token.line
|
this.line = token.line
|
||||||
this.file = token.file
|
this.file = token.file
|
||||||
this.originalError = err
|
this.originalError = err
|
||||||
this.token = token
|
this.token = token
|
||||||
}
|
}
|
||||||
captureStackTrace(obj) {
|
captureStackTrace (obj) {
|
||||||
this.name = obj.constructor.name
|
this.name = obj.constructor.name
|
||||||
|
|
||||||
captureStack.call(obj)
|
captureStack.call(obj)
|
||||||
@@ -37,32 +37,32 @@ abstract class LiquidError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class TokenizationError extends LiquidError {
|
export class TokenizationError extends LiquidError {
|
||||||
constructor(message, token) {
|
constructor (message, token) {
|
||||||
super({message}, token)
|
super({ message }, token)
|
||||||
super.captureStackTrace(this)
|
super.captureStackTrace(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TokenizationError.prototype = _.create(Error.prototype)
|
TokenizationError.prototype = _.create(Error.prototype) as any
|
||||||
TokenizationError.prototype.constructor = TokenizationError
|
TokenizationError.prototype.constructor = TokenizationError
|
||||||
|
|
||||||
export class ParseError extends LiquidError {
|
export class ParseError extends LiquidError {
|
||||||
constructor(err, token) {
|
constructor (err, token) {
|
||||||
super(err, token)
|
super(err, token)
|
||||||
_.assign(this, err)
|
_.assign(this, err)
|
||||||
super.captureStackTrace(this)
|
super.captureStackTrace(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ParseError.prototype = _.create(Error.prototype)
|
ParseError.prototype = _.create(Error.prototype) as any
|
||||||
ParseError.prototype.constructor = ParseError
|
ParseError.prototype.constructor = ParseError
|
||||||
|
|
||||||
export class RenderError extends LiquidError {
|
export class RenderError extends LiquidError {
|
||||||
constructor(err, tpl) {
|
constructor (err, tpl) {
|
||||||
super(err, tpl.token)
|
super(err, tpl.token)
|
||||||
_.assign(this, err)
|
_.assign(this, err)
|
||||||
super.captureStackTrace(this)
|
super.captureStackTrace(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RenderError.prototype = _.create(Error.prototype)
|
RenderError.prototype = _.create(Error.prototype) as any
|
||||||
RenderError.prototype.constructor = RenderError
|
RenderError.prototype.constructor = RenderError
|
||||||
|
|
||||||
export class RenderBreakError {
|
export class RenderBreakError {
|
||||||
@@ -73,7 +73,7 @@ export class RenderBreakError {
|
|||||||
this.message = message + ''
|
this.message = message + ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RenderBreakError.prototype = _.create(Error.prototype)
|
RenderBreakError.prototype = _.create(Error.prototype) as any
|
||||||
RenderBreakError.prototype.constructor = RenderBreakError
|
RenderBreakError.prototype.constructor = RenderBreakError
|
||||||
|
|
||||||
export class AssertionError {
|
export class AssertionError {
|
||||||
@@ -83,7 +83,7 @@ export class AssertionError {
|
|||||||
this.message = message + ''
|
this.message = message + ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AssertionError.prototype = _.create(Error.prototype)
|
AssertionError.prototype = _.create(Error.prototype) as any
|
||||||
AssertionError.prototype.constructor = AssertionError
|
AssertionError.prototype.constructor = AssertionError
|
||||||
|
|
||||||
function mkContext (input, targetLine) {
|
function mkContext (input, targetLine) {
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
export function anySeries (iterable, iteratee) {
|
export function anySeries (iterable, iteratee) {
|
||||||
let ret: Promise<any> = Promise.reject(new Error('init'))
|
let ret: Promise<any> = Promise.reject(new Error('init'))
|
||||||
iterable.forEach(function (item, idx) {
|
iterable.forEach(function (item, idx) {
|
||||||
ret = ret.catch(e => iteratee(item, idx, iterable))
|
ret = ret.catch(() => iteratee(item, idx, iterable))
|
||||||
})
|
})
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ const formatCodes = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
(formatCodes as any).h = formatCodes.b;
|
(formatCodes as any).h = formatCodes.b;
|
||||||
(formatCodes as any).N = formatCodes.L;
|
(formatCodes as any).N = formatCodes.L
|
||||||
|
|
||||||
export default function (d, format) {
|
export default function (d, format) {
|
||||||
let output = ''
|
let output = ''
|
||||||
|
|||||||
+18
-17
@@ -6,11 +6,11 @@ const arrToStr = Array.prototype.toString
|
|||||||
* @param {any} value The value to check.
|
* @param {any} value The value to check.
|
||||||
* @return {Boolean} Returns true if value is a string, else false.
|
* @return {Boolean} Returns true if value is a string, else false.
|
||||||
*/
|
*/
|
||||||
export function isString (value) {
|
export function isString (value: any) {
|
||||||
return toStr.call(value) === '[object String]'
|
return toStr.call(value) === '[object String]'
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isFunction (value) {
|
export function isFunction (value: any) {
|
||||||
return typeof value === 'function'
|
return typeof value === 'function'
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,7 +24,7 @@ export function promisify (fn) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function stringify (value) {
|
export function stringify (value: any): string {
|
||||||
if (isNil(value)) return ''
|
if (isNil(value)) return ''
|
||||||
if (isFunction(value.to_liquid)) return stringify(value.to_liquid())
|
if (isFunction(value.to_liquid)) return stringify(value.to_liquid())
|
||||||
if (isFunction(value.toLiquid)) return stringify(value.toLiquid())
|
if (isFunction(value.toLiquid)) return stringify(value.toLiquid())
|
||||||
@@ -34,7 +34,7 @@ export function stringify (value) {
|
|||||||
return toStr.call(value)
|
return toStr.call(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
function defaultToString (value) {
|
function defaultToString (value: any): string {
|
||||||
const cache = []
|
const cache = []
|
||||||
return JSON.stringify(value, (key, value) => {
|
return JSON.stringify(value, (key, value) => {
|
||||||
if (isObject(value)) {
|
if (isObject(value)) {
|
||||||
@@ -47,20 +47,20 @@ function defaultToString (value) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function create (proto) {
|
export function create<T1 extends object, T2 extends T1 = T1> (proto: T1): T2 {
|
||||||
return Object.create(proto)
|
return Object.create(proto)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isNil (value) {
|
export function isNil (value: any): boolean {
|
||||||
return value === null || value === undefined
|
return value === null || value === undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isArray (value) {
|
export function isArray (value: any): boolean {
|
||||||
// be compatible with IE 8
|
// be compatible with IE 8
|
||||||
return toStr.call(value) === '[object Array]'
|
return toStr.call(value) === '[object Array]'
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isError (value) {
|
export function isError (value: any): boolean {
|
||||||
const signature = toStr.call(value)
|
const signature = toStr.call(value)
|
||||||
// [object XXXError]
|
// [object XXXError]
|
||||||
return signature.substr(-6, 5) === 'Error' ||
|
return signature.substr(-6, 5) === 'Error' ||
|
||||||
@@ -75,7 +75,7 @@ export function isError (value) {
|
|||||||
* @param {Function} iteratee The function invoked per iteration.
|
* @param {Function} iteratee The function invoked per iteration.
|
||||||
* @return {Object} Returns object.
|
* @return {Object} Returns object.
|
||||||
*/
|
*/
|
||||||
export function forOwn (object, iteratee) {
|
export function forOwn (object, iteratee: ((val: any, key: string, obj: object) => boolean | void)) {
|
||||||
object = object || {}
|
object = object || {}
|
||||||
for (const k in object) {
|
for (const k in object) {
|
||||||
if (object.hasOwnProperty(k)) {
|
if (object.hasOwnProperty(k)) {
|
||||||
@@ -96,21 +96,22 @@ export function forOwn (object, iteratee) {
|
|||||||
* @param {...Object} sources The source objects.
|
* @param {...Object} sources The source objects.
|
||||||
* @return {Object} Returns object.
|
* @return {Object} Returns object.
|
||||||
*/
|
*/
|
||||||
export function assign (obj, ...srcs) {
|
export function assign (obj: object, ...srcs: object[]): object {
|
||||||
obj = isObject(obj) ? obj : {}
|
obj = isObject(obj) ? obj : {}
|
||||||
srcs.forEach(src => binaryAssign(obj, src))
|
srcs.forEach(src => binaryAssign(obj, src))
|
||||||
return obj
|
return obj
|
||||||
}
|
}
|
||||||
|
|
||||||
function binaryAssign(target, src) {
|
function binaryAssign (target: object, src: object): object {
|
||||||
for(let key in src) if (src.hasOwnProperty(key)) target[key] = src[key]
|
for (const key in src) if (src.hasOwnProperty(key)) target[key] = src[key]
|
||||||
|
return target
|
||||||
}
|
}
|
||||||
|
|
||||||
export function last (arr) {
|
export function last (arr: any[]): any {
|
||||||
return arr[arr.length - 1]
|
return arr[arr.length - 1]
|
||||||
}
|
}
|
||||||
|
|
||||||
export function uniq (arr) {
|
export function uniq (arr: any[]): any[] {
|
||||||
const u = {}
|
const u = {}
|
||||||
const a = []
|
const a = []
|
||||||
for (let i = 0, l = arr.length; i < l; ++i) {
|
for (let i = 0, l = arr.length; i < l; ++i) {
|
||||||
@@ -129,7 +130,7 @@ export function uniq (arr) {
|
|||||||
* @param {any} value The value to check.
|
* @param {any} value The value to check.
|
||||||
* @return {Boolean} Returns true if value is an object, else false.
|
* @return {Boolean} Returns true if value is an object, else false.
|
||||||
*/
|
*/
|
||||||
export function isObject (value) {
|
export function isObject (value: any): boolean {
|
||||||
const type = typeof value
|
const type = typeof value
|
||||||
return value !== null && (type === 'object' || type === 'function')
|
return value !== null && (type === 'object' || type === 'function')
|
||||||
}
|
}
|
||||||
@@ -156,9 +157,9 @@ export function range (start: number, stop?: number, step?: number) {
|
|||||||
return arr
|
return arr
|
||||||
}
|
}
|
||||||
|
|
||||||
export function padStart(str: any, length: number, ch: string = ' ') {
|
export function padStart (str: any, length: number, ch: string = ' ') {
|
||||||
str = String(str)
|
str = String(str)
|
||||||
let n = length - str.length
|
let n = length - str.length
|
||||||
while(n-- > 0) str = ch + str
|
while (n-- > 0) str = ch + str
|
||||||
return str
|
return str
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"env": {
|
||||||
|
"mocha": true
|
||||||
|
},
|
||||||
|
"plugins": [
|
||||||
|
"mocha"
|
||||||
|
],
|
||||||
|
"rules": {
|
||||||
|
"no-unused-expressions": "off",
|
||||||
|
"no-new": "off"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,12 +1,9 @@
|
|||||||
var chai = require('chai')
|
import { expect } from 'chai'
|
||||||
var Liquid = require('../..')
|
import Liquid from '../..'
|
||||||
var expect = chai.expect
|
|
||||||
|
|
||||||
chai.use(require('chai-as-promised'))
|
|
||||||
|
|
||||||
describe('.evalValue()', function () {
|
describe('.evalValue()', function () {
|
||||||
var engine
|
var engine
|
||||||
beforeEach(() => engine = new Liquid())
|
beforeEach(() => { engine = new Liquid() })
|
||||||
|
|
||||||
it('should throw when scope undefined', function () {
|
it('should throw when scope undefined', function () {
|
||||||
expect(() => engine.evalValue('{{"foo"}}')).to.throw(/scope undefined/)
|
expect(() => engine.evalValue('{{"foo"}}')).to.throw(/scope undefined/)
|
||||||
|
|||||||
+1
-5
@@ -1,12 +1,8 @@
|
|||||||
import * as chai from 'chai'
|
import { expect } from 'chai'
|
||||||
import * as request from 'supertest'
|
import * as request from 'supertest'
|
||||||
import * as express from 'express'
|
import * as express from 'express'
|
||||||
import * as mock from 'mock-fs'
|
import * as mock from 'mock-fs'
|
||||||
import Liquid from '../../dist/liquid.common.js'
|
import Liquid from '../../dist/liquid.common.js'
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
|
|
||||||
const expect = chai.expect
|
|
||||||
chai.use(chaiAsPromised)
|
|
||||||
|
|
||||||
describe('express()', function () {
|
describe('express()', function () {
|
||||||
var app, engine
|
var app, engine
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
var chai = require('chai')
|
import Liquid from '../..'
|
||||||
var Liquid = require('../..')
|
import { expect, use } from 'chai'
|
||||||
var expect = chai.expect
|
import * as chaiAsPromised from 'chai-as-promised'
|
||||||
|
|
||||||
chai.use(require('chai-as-promised'))
|
use(chaiAsPromised)
|
||||||
|
|
||||||
describe('.parseAndRender()', function () {
|
describe('.parseAndRender()', function () {
|
||||||
var engine, strictEngine
|
var engine, strictEngine
|
||||||
@@ -12,19 +12,23 @@ describe('.parseAndRender()', function () {
|
|||||||
strict_filters: true
|
strict_filters: true
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
it('should stringify object', function () {
|
it('should stringify object', async function () {
|
||||||
var ctx = { obj: { foo: 'bar' } }
|
var ctx = { obj: { foo: 'bar' } }
|
||||||
return expect(engine.parseAndRender('{{obj}}', ctx)).to.eventually.equal('{"foo":"bar"}')
|
const html = await engine.parseAndRender('{{obj}}', ctx)
|
||||||
|
return expect(html).to.equal('{"foo":"bar"}')
|
||||||
})
|
})
|
||||||
it('should stringify array ', function () {
|
it('should stringify array ', async function () {
|
||||||
var ctx = { arr: [-2, 'a'] }
|
var ctx = { arr: [-2, 'a'] }
|
||||||
return expect(engine.parseAndRender('{{arr}}', ctx)).to.eventually.equal('[-2,"a"]')
|
const html = await engine.parseAndRender('{{arr}}', ctx)
|
||||||
|
return expect(html).to.equal('[-2,"a"]')
|
||||||
})
|
})
|
||||||
it('should render undefined as empty', function () {
|
it('should render undefined as empty', async function () {
|
||||||
return expect(engine.parseAndRender('foo{{zzz}}bar', {})).to.eventually.equal('foobar')
|
const html = await engine.parseAndRender('foo{{zzz}}bar', {})
|
||||||
|
return expect(html).to.equal('foobar')
|
||||||
})
|
})
|
||||||
it('should render as null when filter undefined', function () {
|
it('should render as null when filter undefined', async function () {
|
||||||
return expect(engine.parseAndRender('{{"foo" | filter1}}', {})).to.eventually.equal('foo')
|
const html = await engine.parseAndRender('{{"foo" | filter1}}', {})
|
||||||
|
return expect(html).to.equal('foo')
|
||||||
})
|
})
|
||||||
it('should throw upon undefined filter when strict_filters set', function () {
|
it('should throw upon undefined filter when strict_filters set', function () {
|
||||||
return expect(strictEngine.parseAndRender('{{"foo" | filter1}}', {})).to
|
return expect(strictEngine.parseAndRender('{{"foo" | filter1}}', {})).to
|
||||||
@@ -38,22 +42,24 @@ describe('.parseAndRender()', function () {
|
|||||||
engine.parse('<html><head>{{obj}}</head></html>')
|
engine.parse('<html><head>{{obj}}</head></html>')
|
||||||
}).to.not.throw()
|
}).to.not.throw()
|
||||||
})
|
})
|
||||||
it('should render template multiple times', function () {
|
it('should render template multiple times', async function () {
|
||||||
var ctx = { obj: { foo: 'bar' } }
|
const ctx = { obj: { foo: 'bar' } }
|
||||||
var template = engine.parse('{{obj}}')
|
const template = engine.parse('{{obj}}')
|
||||||
return engine.render(template, ctx)
|
const result = await engine.render(template, ctx)
|
||||||
.then(result => expect(result).to.equal('{"foo":"bar"}'))
|
expect(result).to.equal('{"foo":"bar"}')
|
||||||
.then(() => engine.render(template, ctx))
|
const result2 = await engine.render(template, ctx)
|
||||||
.then((result) => expect(result).to.equal('{"foo":"bar"}'))
|
expect(result2).to.equal('{"foo":"bar"}')
|
||||||
})
|
})
|
||||||
it('should render filters', function () {
|
it('should render filters', async function () {
|
||||||
var ctx = { names: ['alice', 'bob'] }
|
var ctx = { names: ['alice', 'bob'] }
|
||||||
var template = engine.parse('<p>{{names | join: ","}}</p>')
|
var template = engine.parse('<p>{{names | join: ","}}</p>')
|
||||||
return expect(engine.render(template, ctx)).to.eventually.equal('<p>alice,bob</p>')
|
const html = await engine.render(template, ctx)
|
||||||
|
return expect(html).to.equal('<p>alice,bob</p>')
|
||||||
})
|
})
|
||||||
it('should render accessive filters', function () {
|
it('should render accessive filters', async function () {
|
||||||
var src = '{% assign my_array = "apples, oranges, peaches, plums" | split: ", " %}' +
|
var src = '{% assign my_array = "apples, oranges, peaches, plums" | split: ", " %}' +
|
||||||
'{{ my_array | first }}'
|
'{{ my_array | first }}'
|
||||||
return expect(engine.parseAndRender(src)).to.eventually.equal('apples')
|
const html = await engine.parseAndRender(src)
|
||||||
|
return expect(html).to.equal('apples')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
+24
-26
@@ -1,9 +1,6 @@
|
|||||||
var chai = require('chai')
|
import { expect } from 'chai'
|
||||||
var mock = require('mock-fs')
|
import * as mock from 'mock-fs'
|
||||||
var Liquid = require('../..')
|
import Liquid from '../..'
|
||||||
var expect = chai.expect
|
|
||||||
|
|
||||||
chai.use(require('chai-as-promised'))
|
|
||||||
|
|
||||||
describe('#renderFile()', function () {
|
describe('#renderFile()', function () {
|
||||||
var engine
|
var engine
|
||||||
@@ -24,28 +21,28 @@ describe('#renderFile()', function () {
|
|||||||
afterEach(function () {
|
afterEach(function () {
|
||||||
mock.restore()
|
mock.restore()
|
||||||
})
|
})
|
||||||
it('should render file', function () {
|
it('should render file', async function () {
|
||||||
return expect(engine.renderFile('/root/files/foo.html', {}))
|
const html = await engine.renderFile('/root/files/foo.html', {})
|
||||||
.to.eventually.equal('foo')
|
return expect(html).to.equal('foo')
|
||||||
})
|
})
|
||||||
it('should find files without extname', function () {
|
it('should find files without extname', async function () {
|
||||||
var engine = new Liquid({ root: '/root' })
|
var engine = new Liquid({ root: '/root' })
|
||||||
return expect(engine.renderFile('/root/files/bar', {}))
|
const html = await engine.renderFile('/root/files/bar', {})
|
||||||
.to.eventually.equal('bar')
|
return expect(html).to.equal('bar')
|
||||||
})
|
})
|
||||||
it('should accept relative path', function () {
|
it('should accept relative path', async function () {
|
||||||
return expect(engine.renderFile('files/foo.html'))
|
const html = await engine.renderFile('files/foo.html')
|
||||||
.to.eventually.equal('foo')
|
return expect(html).to.equal('foo')
|
||||||
})
|
})
|
||||||
it('should resolve array as root', function () {
|
it('should resolve array as root', async function () {
|
||||||
engine = new Liquid({
|
engine = new Liquid({
|
||||||
root: ['/boo', '/root/'],
|
root: ['/boo', '/root/'],
|
||||||
extname: '.html'
|
extname: '.html'
|
||||||
})
|
})
|
||||||
return expect(engine.renderFile('files/foo.html'))
|
const html = await engine.renderFile('files/foo.html')
|
||||||
.to.eventually.equal('foo')
|
return expect(html).to.equal('foo')
|
||||||
})
|
})
|
||||||
it('should default root to cwd', function () {
|
it('should default root to cwd', async function () {
|
||||||
var files = {}
|
var files = {}
|
||||||
files[process.cwd() + '/foo.html'] = 'FOO'
|
files[process.cwd() + '/foo.html'] = 'FOO'
|
||||||
mock(files)
|
mock(files)
|
||||||
@@ -53,15 +50,16 @@ describe('#renderFile()', function () {
|
|||||||
engine = new Liquid({
|
engine = new Liquid({
|
||||||
extname: '.html'
|
extname: '.html'
|
||||||
})
|
})
|
||||||
return expect(engine.renderFile('foo.html'))
|
const html = await engine.renderFile('foo.html')
|
||||||
.to.eventually.equal('FOO')
|
return expect(html).to.equal('FOO')
|
||||||
})
|
})
|
||||||
it('should render file with context', function () {
|
it('should render file with context', async function () {
|
||||||
return expect(engine.renderFile('/root/files/name.html', { name: 'harttle' }))
|
const html = await engine.renderFile('/root/files/name.html', { name: 'harttle' })
|
||||||
.to.eventually.equal('My name is harttle.')
|
return expect(html).to.equal('My name is harttle.')
|
||||||
})
|
})
|
||||||
it('should use default extname', function () {
|
it('should use default extname', async function () {
|
||||||
return expect(engine.renderFile('files/name', { name: 'harttle' })).to.eventually.equal('My name is harttle.')
|
const html = await engine.renderFile('files/name', { name: 'harttle' })
|
||||||
|
return expect(html).to.equal('My name is harttle.')
|
||||||
})
|
})
|
||||||
it('should throw with lookup list when file not exist', function () {
|
it('should throw with lookup list when file not exist', function () {
|
||||||
engine = new Liquid({
|
engine = new Liquid({
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
import * as chai from 'chai'
|
import { expect } from 'chai'
|
||||||
import Liquid from '../..'
|
import Liquid from '../..'
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
|
|
||||||
const liquid = new Liquid()
|
const liquid = new Liquid()
|
||||||
const expect = chai.expect
|
|
||||||
chai.use(chaiAsPromised)
|
|
||||||
|
|
||||||
const cases = [
|
const cases = [
|
||||||
{
|
{
|
||||||
@@ -445,6 +442,9 @@ const cases = [
|
|||||||
describe('Whitespace Control', function () {
|
describe('Whitespace Control', function () {
|
||||||
cases.forEach(item => it(
|
cases.forEach(item => it(
|
||||||
item.text,
|
item.text,
|
||||||
() => expect(liquid.parseAndRender(item.text)).to.eventually.equal(item.expected)
|
async () => {
|
||||||
|
const html = await liquid.parseAndRender(item.text)
|
||||||
|
expect(html).to.equal(item.expected)
|
||||||
|
}
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
|
|||||||
+38
-42
@@ -1,11 +1,10 @@
|
|||||||
import Liquid from '../../dist/liquid.js'
|
import Liquid from '../../dist/liquid.js'
|
||||||
import { createFakeServer, useFakeXMLHttpRequest } from 'sinon'
|
import { createFakeServer, useFakeXMLHttpRequest } from 'sinon'
|
||||||
import * as chai from 'chai'
|
import { expect, use } from 'chai'
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
import { JSDOM } from 'jsdom'
|
import { JSDOM } from 'jsdom'
|
||||||
|
import * as chaiAsPromised from 'chai-as-promised'
|
||||||
|
|
||||||
const expect = chai.expect
|
use(chaiAsPromised)
|
||||||
chai.use(chaiAsPromised)
|
|
||||||
|
|
||||||
describe('xhr', () => {
|
describe('xhr', () => {
|
||||||
if (+process.version.match(/^v(\d+)/)[1] < 8) {
|
if (+process.version.match(/^v(\d+)/)[1] < 8) {
|
||||||
@@ -24,7 +23,7 @@ describe('xhr', () => {
|
|||||||
includeNodeLocations: true
|
includeNodeLocations: true
|
||||||
});
|
});
|
||||||
(global as any).XMLHttpRequest = useFakeXMLHttpRequest();
|
(global as any).XMLHttpRequest = useFakeXMLHttpRequest();
|
||||||
(global as any).document = dom.window.document;
|
(global as any).document = dom.window.document
|
||||||
engine = new Liquid({
|
engine = new Liquid({
|
||||||
root: 'https://example.com/views/',
|
root: 'https://example.com/views/',
|
||||||
extname: '.html'
|
extname: '.html'
|
||||||
@@ -36,97 +35,94 @@ describe('xhr', () => {
|
|||||||
delete (global as any).document
|
delete (global as any).document
|
||||||
})
|
})
|
||||||
describe('#renderFile()', () => {
|
describe('#renderFile()', () => {
|
||||||
it('should support without extname', () => {
|
it('should support without extname', async () => {
|
||||||
return expect(engine.renderFile('hello', { name: 'alice1' }))
|
const html = await engine.renderFile('hello', { name: 'alice1' })
|
||||||
.to.eventually.equal('hello alice1')
|
return expect(html).to.equal('hello alice1')
|
||||||
})
|
})
|
||||||
it('should support with extname', () => {
|
it('should support with extname', async () => {
|
||||||
return expect(engine.renderFile('hello.html', { name: 'alice2' }))
|
const html = await engine.renderFile('hello.html', { name: 'alice2' })
|
||||||
.to.eventually.equal('hello alice2')
|
return expect(html).to.equal('hello alice2')
|
||||||
})
|
})
|
||||||
it('should support with absolute path', () => {
|
it('should support with absolute path', async () => {
|
||||||
server.respondWith('GET', 'https://example.com/foo.html',
|
server.respondWith('GET', 'https://example.com/foo.html',
|
||||||
[200, { 'Content-Type': 'text/plain' }, 'foo'])
|
[200, { 'Content-Type': 'text/plain' }, 'foo'])
|
||||||
return expect(engine.renderFile('/foo.html'))
|
const html = await engine.renderFile('/foo.html')
|
||||||
.to.eventually.equal('foo')
|
return expect(html).to.equal('foo')
|
||||||
})
|
})
|
||||||
it('should support with url', () => {
|
it('should support with url', async () => {
|
||||||
return expect(engine.renderFile('https://example.com/views/hello.html', { name: 'alice4' }))
|
const html = await engine.renderFile('https://example.com/views/hello.html', { name: 'alice4' })
|
||||||
.to.eventually.equal('hello alice4')
|
return expect(html).to.equal('hello alice4')
|
||||||
})
|
})
|
||||||
it('should support include', () => {
|
it('should support include', async () => {
|
||||||
server.respondWith('GET', 'https://example.com/views/hello.html',
|
server.respondWith('GET', 'https://example.com/views/hello.html',
|
||||||
[200, { 'Content-Type': 'text/plain' }, "hello {% include 'name.html' %}"])
|
[200, { 'Content-Type': 'text/plain' }, "hello {% include 'name.html' %}"])
|
||||||
server.respondWith('GET', 'https://example.com/views/name.html',
|
server.respondWith('GET', 'https://example.com/views/name.html',
|
||||||
[200, { 'Content-Type': 'text/plain' }, '{{name}}'])
|
[200, { 'Content-Type': 'text/plain' }, '{{name}}'])
|
||||||
return expect(engine.renderFile('hello.html', { name: 'alice5' }))
|
const html = await engine.renderFile('hello.html', { name: 'alice5' })
|
||||||
.to.eventually.equal('hello alice5')
|
return expect(html).to.equal('hello alice5')
|
||||||
})
|
})
|
||||||
it('should throw 404', () => {
|
it('should throw 404', () => {
|
||||||
return expect(engine.renderFile('/not/exist.html'))
|
return expect(engine.renderFile('/not/exist.html'))
|
||||||
.to.be.rejectedWith('Not Found')
|
.to.be.rejectedWith('Not Found')
|
||||||
})
|
})
|
||||||
it('should throw error', function (done) {
|
it('should throw error', function () {
|
||||||
engine.renderFile('hello.html')
|
const result = expect(engine.renderFile('hello.html'))
|
||||||
.then(() => done('should not be resolved'))
|
.to.be.rejectedWith('An error occurred whilst receiving the response.');
|
||||||
.catch(function (e) {
|
|
||||||
expect(e.message).to.equal('An error occurred whilst receiving the response.')
|
|
||||||
done()
|
|
||||||
});
|
|
||||||
(global as any).XMLHttpRequest.onCreate = function (request) {
|
(global as any).XMLHttpRequest.onCreate = function (request) {
|
||||||
setTimeout(() => request.error())
|
setTimeout(() => request.error())
|
||||||
}
|
}
|
||||||
|
return result
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('#renderFile() with root specified', () => {
|
describe('#renderFile() with root specified', () => {
|
||||||
it('should support undefined root', () => {
|
it('should support undefined root', async () => {
|
||||||
engine = new Liquid({
|
engine = new Liquid({
|
||||||
extname: '.html'
|
extname: '.html'
|
||||||
})
|
})
|
||||||
server.respondWith('GET', 'https://example.com/foo/hello.html',
|
server.respondWith('GET', 'https://example.com/foo/hello.html',
|
||||||
[200, { 'Content-Type': 'text/plain' }, 'hello {{name}}'])
|
[200, { 'Content-Type': 'text/plain' }, 'hello {{name}}'])
|
||||||
return expect(engine.renderFile('hello.html', { name: 'alice5' }))
|
const html = await engine.renderFile('hello.html', { name: 'alice5' })
|
||||||
.to.eventually.equal('hello alice5')
|
return expect(html).to.equal('hello alice5')
|
||||||
})
|
})
|
||||||
it('should support empty root', () => {
|
it('should support empty root', async () => {
|
||||||
engine = new Liquid({
|
engine = new Liquid({
|
||||||
root: '',
|
root: '',
|
||||||
extname: '.html'
|
extname: '.html'
|
||||||
})
|
})
|
||||||
server.respondWith('https://example.com/foo/hello.html',
|
server.respondWith('https://example.com/foo/hello.html',
|
||||||
[200, { 'Content-Type': 'text/plain' }, 'hello {{name}}'])
|
[200, { 'Content-Type': 'text/plain' }, 'hello {{name}}'])
|
||||||
return expect(engine.renderFile('hello.html', { name: 'alice5' }))
|
const html = await engine.renderFile('hello.html', { name: 'alice5' })
|
||||||
.to.eventually.equal('hello alice5')
|
return expect(html).to.equal('hello alice5')
|
||||||
})
|
})
|
||||||
it('should support with relative path', () => {
|
it('should support with relative path', async () => {
|
||||||
engine = new Liquid({
|
engine = new Liquid({
|
||||||
root: './views/',
|
root: './views/',
|
||||||
extname: '.html'
|
extname: '.html'
|
||||||
})
|
})
|
||||||
server.respondWith('GET', 'https://example.com/foo/views/hello.html',
|
server.respondWith('GET', 'https://example.com/foo/views/hello.html',
|
||||||
[200, { 'Content-Type': 'text/plain' }, 'hello {{name}}'])
|
[200, { 'Content-Type': 'text/plain' }, 'hello {{name}}'])
|
||||||
return expect(engine.renderFile('hello.html', { name: 'alice5' }))
|
const html = await engine.renderFile('hello.html', { name: 'alice5' })
|
||||||
.to.eventually.equal('hello alice5')
|
return expect(html).to.equal('hello alice5')
|
||||||
})
|
})
|
||||||
it('should support with absolute path', () => {
|
it('should support with absolute path', async () => {
|
||||||
engine = new Liquid({
|
engine = new Liquid({
|
||||||
root: '/views/',
|
root: '/views/',
|
||||||
extname: '.html'
|
extname: '.html'
|
||||||
})
|
})
|
||||||
server.respondWith('GET', 'https://example.com/views/hello.html',
|
server.respondWith('GET', 'https://example.com/views/hello.html',
|
||||||
[200, { 'Content-Type': 'text/plain' }, 'hello {{name}}'])
|
[200, { 'Content-Type': 'text/plain' }, 'hello {{name}}'])
|
||||||
return expect(engine.renderFile('hello.html', { name: 'alice5' }))
|
const html = await engine.renderFile('hello.html', { name: 'alice5' })
|
||||||
.to.eventually.equal('hello alice5')
|
return expect(html).to.equal('hello alice5')
|
||||||
})
|
})
|
||||||
it('should support with url', () => {
|
it('should support with url', async () => {
|
||||||
engine = new Liquid({
|
engine = new Liquid({
|
||||||
root: 'https://foo.com/bar/',
|
root: 'https://foo.com/bar/',
|
||||||
extname: '.html'
|
extname: '.html'
|
||||||
})
|
})
|
||||||
server.respondWith('GET', 'https://foo.com/bar/hello.html',
|
server.respondWith('GET', 'https://foo.com/bar/hello.html',
|
||||||
[200, { 'Content-Type': 'text/plain' }, 'hello {{name}}'])
|
[200, { 'Content-Type': 'text/plain' }, 'hello {{name}}'])
|
||||||
return expect(engine.renderFile('hello.html', { name: 'alice5' }))
|
const html = await engine.renderFile('hello.html', { name: 'alice5' })
|
||||||
.to.eventually.equal('hello alice5')
|
return expect(html).to.equal('hello alice5')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('cache options', () => {
|
describe('cache options', () => {
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
import * as chai from 'chai'
|
import { expect } from 'chai'
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
import Liquid from '../../src/liquid'
|
import Liquid from '../../src/liquid'
|
||||||
|
|
||||||
chai.use(chaiAsPromised)
|
|
||||||
const expect = chai.expect
|
|
||||||
|
|
||||||
const ctx = {
|
const ctx = {
|
||||||
date: new Date(),
|
date: new Date(),
|
||||||
foo: 'bar',
|
foo: 'bar',
|
||||||
@@ -21,12 +17,13 @@ const ctx = {
|
|||||||
}
|
}
|
||||||
let liquid
|
let liquid
|
||||||
|
|
||||||
function test (src, dst) {
|
async function test (src, dst) {
|
||||||
return expect(liquid.parseAndRender(src, ctx)).to.eventually.equal(dst)
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
|
return expect(html).to.equal(dst)
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('filters', function () {
|
describe('filters', function () {
|
||||||
before(() => liquid = new Liquid())
|
before(() => { liquid = new Liquid() })
|
||||||
describe('abs', function () {
|
describe('abs', function () {
|
||||||
it('should return 3 for -3', () => test('{{ -3 | abs }}', '3'))
|
it('should return 3 for -3', () => test('{{ -3 | abs }}', '3'))
|
||||||
it('should return 2 for arr[0]', () => test('{{ arr[0] | abs }}', '2'))
|
it('should return 2 for arr[0]', () => test('{{ arr[0] | abs }}', '2'))
|
||||||
|
|||||||
+2
-2
@@ -7,13 +7,13 @@ const expect = chai.expect
|
|||||||
describe('Liquid', function () {
|
describe('Liquid', function () {
|
||||||
describe('#constructor()', function () {
|
describe('#constructor()', function () {
|
||||||
it('should throw on illegal root', function () {
|
it('should throw on illegal root', function () {
|
||||||
expect(() => new (Liquid as any)({root: {}})).to.throw(/illegal root/)
|
expect(() => new (Liquid as any)({ root: {} })).to.throw(/illegal root/)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('#plugin()', function () {
|
describe('#plugin()', function () {
|
||||||
it('should call plugin on the instance', async function () {
|
it('should call plugin on the instance', async function () {
|
||||||
const engine = new Liquid()
|
const engine = new Liquid()
|
||||||
engine.plugin(function (Liquid) {
|
engine.plugin(function () {
|
||||||
this.registerFilter('foo', x => `foo${x}foo`)
|
this.registerFilter('foo', x => `foo${x}foo`)
|
||||||
})
|
})
|
||||||
const html = await engine.parseAndRender('{{"bar"|foo}}')
|
const html = await engine.parseAndRender('{{"bar"|foo}}')
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
import * as chai from 'chai'
|
import { expect } from 'chai'
|
||||||
import * as mock from 'mock-fs'
|
import * as mock from 'mock-fs'
|
||||||
import Liquid from '../../../src/liquid'
|
import Liquid from '../../../src/liquid'
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
|
|
||||||
const expect = chai.expect
|
|
||||||
chai.use(chaiAsPromised)
|
|
||||||
|
|
||||||
describe('LiquidOptions#cache', function () {
|
describe('LiquidOptions#cache', function () {
|
||||||
let engine
|
let engine
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
import Liquid from '../../../src/liquid'
|
import Liquid from 'src/liquid'
|
||||||
import * as chai from 'chai'
|
import { expect } from 'chai'
|
||||||
|
|
||||||
const expect = chai.expect
|
|
||||||
chai.use(require('chai-as-promised'))
|
|
||||||
|
|
||||||
describe('LiquidOptions#strict_*', function () {
|
describe('LiquidOptions#strict_*', function () {
|
||||||
let engine
|
let engine
|
||||||
@@ -13,9 +10,9 @@ describe('LiquidOptions#strict_*', function () {
|
|||||||
extname: '.html'
|
extname: '.html'
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
it('should not throw when strict_variables false (default)', function () {
|
it('should not throw when strict_variables false (default)', async function () {
|
||||||
return expect(engine.parseAndRender('before{{notdefined}}after', ctx)).to
|
const html = await engine.parseAndRender('before{{notdefined}}after', ctx)
|
||||||
.eventually.equal('beforeafter')
|
return expect(html).to.equal('beforeafter')
|
||||||
})
|
})
|
||||||
it('should throw when strict_variables true', function () {
|
it('should throw when strict_variables true', function () {
|
||||||
const tpl = engine.parse('before{{notdefined}}after')
|
const tpl = engine.parse('before{{notdefined}}after')
|
||||||
|
|||||||
@@ -1,62 +1,58 @@
|
|||||||
import * as chai from 'chai'
|
import { expect } from 'chai'
|
||||||
import Liquid from '../../../src/liquid'
|
import Liquid from '../../../src/liquid'
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
|
|
||||||
const expect = chai.expect
|
|
||||||
chai.use(chaiAsPromised)
|
|
||||||
|
|
||||||
describe('LiquidOptions#trimming', function () {
|
describe('LiquidOptions#trimming', function () {
|
||||||
const ctx = { name: 'harttle' }
|
const ctx = { name: 'harttle' }
|
||||||
|
|
||||||
describe('tag trimming', function () {
|
describe('tag trimming', function () {
|
||||||
it('should respect trim_tag_left', function () {
|
it('should respect trim_tag_left', async function () {
|
||||||
const engine = new Liquid({ trim_tag_left: true })
|
const engine = new Liquid({ trim_tag_left: true })
|
||||||
return expect(engine.parseAndRender(' \n \t{%if true%}foo{%endif%} '))
|
const html = await engine.parseAndRender(' \n \t{%if true%}foo{%endif%} ')
|
||||||
.to.eventually.equal('foo ')
|
return expect(html).to.equal('foo ')
|
||||||
})
|
})
|
||||||
it('should respect trim_tag_right', function () {
|
it('should respect trim_tag_right', async function () {
|
||||||
const engine = new Liquid({ trim_tag_right: true })
|
const engine = new Liquid({ trim_tag_right: true })
|
||||||
return expect(engine.parseAndRender('\t{%if true%}foo{%endif%} \n'))
|
const html = engine.parseAndRender('\t{%if true%}foo{%endif%} \n')
|
||||||
.to.eventually.equal('\tfoo')
|
return expect(html).to.equal('\tfoo')
|
||||||
})
|
})
|
||||||
it('should not trim value', function () {
|
it('should not trim value', async function () {
|
||||||
const engine = new Liquid({ trim_tag_left: true, trim_tag_right: true })
|
const engine = new Liquid({ trim_tag_left: true, trim_tag_right: true })
|
||||||
return expect(engine.parseAndRender('{%if true%}a {{name}} b{%endif%}', ctx))
|
const html = await engine.parseAndRender('{%if true%}a {{name}} b{%endif%}', ctx)
|
||||||
.to.eventually.equal('a harttle b')
|
return expect(html).to.equal('a harttle b')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('value trimming', function () {
|
describe('value trimming', function () {
|
||||||
it('should respect trim_value_left', function () {
|
it('should respect trim_value_left', async function () {
|
||||||
const engine = new Liquid({ trim_value_left: true })
|
const engine = new Liquid({ trim_value_left: true })
|
||||||
return expect(engine.parseAndRender(' \n \t{{name}} ', ctx))
|
const html = await engine.parseAndRender(' \n \t{{name}} ', ctx)
|
||||||
.to.eventually.equal('harttle ')
|
return expect(html).to.equal('harttle ')
|
||||||
})
|
})
|
||||||
it('should respect trim_value_right', function () {
|
it('should respect trim_value_right', async function () {
|
||||||
const engine = new Liquid({ trim_value_right: true })
|
const engine = new Liquid({ trim_value_right: true })
|
||||||
return expect(engine.parseAndRender(' \n \t{{name}} ', ctx))
|
const html = await engine.parseAndRender(' \n \t{{name}} ', ctx)
|
||||||
.to.eventually.equal(' \n \tharttle')
|
return expect(html).to.equal(' \n \tharttle')
|
||||||
})
|
})
|
||||||
it('should respect not trim tag', function () {
|
it('should respect not trim tag', async function () {
|
||||||
const engine = new Liquid({ trim_value_left: true, trim_value_right: true })
|
const engine = new Liquid({ trim_value_left: true, trim_value_right: true })
|
||||||
return expect(engine.parseAndRender('\t{% if true %} aha {%endif%}\t'))
|
const html = await engine.parseAndRender('\t{% if true %} aha {%endif%}\t')
|
||||||
.to.eventually.equal('\t aha \t')
|
return expect(html).to.equal('\t aha \t')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('greedy', function () {
|
describe('greedy', function () {
|
||||||
const src = '\n {%-if true-%}\n a \n{{-name-}}{%-endif-%}\n '
|
const src = '\n {%-if true-%}\n a \n{{-name-}}{%-endif-%}\n '
|
||||||
it('should enable greedy by default', function () {
|
it('should enable greedy by default', async function () {
|
||||||
const engine = new Liquid()
|
const engine = new Liquid()
|
||||||
return expect(engine.parseAndRender(src, ctx))
|
const html = await engine.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('aharttle')
|
return expect(html).to.equal('aharttle')
|
||||||
})
|
})
|
||||||
it('should respect to greedy:false by default', function () {
|
it('should respect to greedy:false by default', async function () {
|
||||||
const engine = new Liquid({ greedy: false })
|
const engine = new Liquid({ greedy: false })
|
||||||
return expect(engine.parseAndRender(src, ctx))
|
const html = await engine.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('\n a \nharttle ')
|
return expect(html).to.equal('\n a \nharttle ')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('markup', function () {
|
describe('markup', function () {
|
||||||
it('should support trim using markup', function () {
|
it('should support trim using markup', async function () {
|
||||||
const engine = new Liquid()
|
const engine = new Liquid()
|
||||||
const src = [
|
const src = [
|
||||||
'{%- assign username = "John G. Chalmers-Smith" -%}',
|
'{%- assign username = "John G. Chalmers-Smith" -%}',
|
||||||
@@ -67,9 +63,10 @@ describe('LiquidOptions#trimming', function () {
|
|||||||
'{%- endif -%}'
|
'{%- endif -%}'
|
||||||
].join('\n')
|
].join('\n')
|
||||||
const dst = 'Wow, John G. Chalmers-Smith, you have a long name!'
|
const dst = 'Wow, John G. Chalmers-Smith, you have a long name!'
|
||||||
return expect(engine.parseAndRender(src)).to.eventually.equal(dst)
|
const html = await engine.parseAndRender(src)
|
||||||
|
return expect(html).to.equal(dst)
|
||||||
})
|
})
|
||||||
it('should not trim when not specified', function () {
|
it('should not trim when not specified', async function () {
|
||||||
const engine = new Liquid()
|
const engine = new Liquid()
|
||||||
const src = [
|
const src = [
|
||||||
'{% assign username = "John G. Chalmers-Smith" %}',
|
'{% assign username = "John G. Chalmers-Smith" %}',
|
||||||
@@ -80,7 +77,8 @@ describe('LiquidOptions#trimming', function () {
|
|||||||
'{% endif %}'
|
'{% endif %}'
|
||||||
].join('\n')
|
].join('\n')
|
||||||
const dst = '\n\n Wow, John G. Chalmers-Smith, you have a long name!\n'
|
const dst = '\n\n Wow, John G. Chalmers-Smith, you have a long name!\n'
|
||||||
return expect(engine.parseAndRender(src)).to.eventually.equal(dst)
|
const html = await engine.parseAndRender(src)
|
||||||
|
return expect(html).to.equal(dst)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
+24
-19
@@ -1,14 +1,9 @@
|
|||||||
import * as chai from 'chai'
|
import * as chai from 'chai'
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
import * as sinonChai from 'sinon-chai'
|
|
||||||
import * as sinon from 'sinon'
|
|
||||||
import Scope from '../../src/scope/scope'
|
import Scope from '../../src/scope/scope'
|
||||||
import Output from '../../src/template/output'
|
import Output from '../../src/template/output'
|
||||||
|
import OutputToken from 'src/parser/output-token'
|
||||||
import Filter from 'src/template/filter'
|
import Filter from 'src/template/filter'
|
||||||
|
|
||||||
chai.use(sinonChai)
|
|
||||||
chai.use(chaiAsPromised)
|
|
||||||
|
|
||||||
const expect = chai.expect
|
const expect = chai.expect
|
||||||
|
|
||||||
describe('Output', function () {
|
describe('Output', function () {
|
||||||
@@ -16,41 +11,51 @@ describe('Output', function () {
|
|||||||
Filter.clear()
|
Filter.clear()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should respect to .to_liquid() method', function () {
|
it('should respect to .to_liquid() method', async function () {
|
||||||
const scope = new Scope({
|
const scope = new Scope({
|
||||||
bar: { to_liquid: x => 'custom' }
|
bar: { to_liquid: () => 'custom' }
|
||||||
})
|
})
|
||||||
return expect(new Output({value: 'bar'}).render(scope)).to.eventually.equal('custom')
|
const output = new Output({ value: 'bar' } as OutputToken)
|
||||||
|
const html = await output.render(scope)
|
||||||
|
return expect(html).to.equal('custom')
|
||||||
})
|
})
|
||||||
it('should stringify objects', function () {
|
it('should stringify objects', async function () {
|
||||||
const scope = new Scope({
|
const scope = new Scope({
|
||||||
foo: { obj: { arr: ['a', 2] } }
|
foo: { obj: { arr: ['a', 2] } }
|
||||||
})
|
})
|
||||||
return expect(new Output({value: 'foo'}).render(scope)).to.eventually.equal('{"obj":{"arr":["a",2]}}')
|
const output = new Output({ value: 'foo' } as OutputToken)
|
||||||
|
const html = await output.render(scope)
|
||||||
|
return expect(html).to.equal('{"obj":{"arr":["a",2]}}')
|
||||||
})
|
})
|
||||||
it('should skip circular property', function () {
|
it('should skip circular property', async function () {
|
||||||
const ctx = { foo: { num: 2 }, bar: 'bar' } as any
|
const ctx = { foo: { num: 2 }, bar: 'bar' } as any
|
||||||
ctx.foo.circular = ctx
|
ctx.foo.circular = ctx
|
||||||
const scope = new Scope(ctx)
|
const output = new Output({ value: 'foo' } as OutputToken)
|
||||||
return expect(new Output({value: 'foo'}).render(scope)).to.eventually.equal('{"num":2,"circular":{"bar":"bar"}}')
|
const html = await output.render(new Scope(ctx))
|
||||||
|
return expect(html).equal('{"num":2,"circular":{"bar":"bar"}}')
|
||||||
})
|
})
|
||||||
it('should skip function property', function () {
|
it('should skip function property', async function () {
|
||||||
const scope = new Scope({ obj: { foo: 'foo', bar: x => x } })
|
const scope = new Scope({ obj: { foo: 'foo', bar: x => x } })
|
||||||
return expect(new Output({value: 'obj'}).render(scope)).to.eventually.equal('{"foo":"foo"}')
|
const output = new Output({ value: 'obj' } as OutputToken)
|
||||||
|
const html = await output.render(scope)
|
||||||
|
return expect(html).to.equal('{"foo":"foo"}')
|
||||||
})
|
})
|
||||||
it('should respect to .toString()', async () => {
|
it('should respect to .toString()', async () => {
|
||||||
const scope = new Scope({ obj: { toString: () => 'FOO' } })
|
const scope = new Scope({ obj: { toString: () => 'FOO' } })
|
||||||
const str = await new Output({value: 'obj'}).render(scope)
|
const output = new Output({ value: 'obj' } as OutputToken)
|
||||||
|
const str = await output.render(scope)
|
||||||
return expect(str).to.equal('FOO')
|
return expect(str).to.equal('FOO')
|
||||||
})
|
})
|
||||||
it('should respect to .to_s()', async () => {
|
it('should respect to .to_s()', async () => {
|
||||||
const scope = new Scope({ obj: { to_s: () => 'FOO' } })
|
const scope = new Scope({ obj: { to_s: () => 'FOO' } })
|
||||||
const str = await new Output({value: 'obj'}).render(scope)
|
const output = new Output({ value: 'obj' } as OutputToken)
|
||||||
|
const str = await output.render(scope)
|
||||||
return expect(str).to.equal('FOO')
|
return expect(str).to.equal('FOO')
|
||||||
})
|
})
|
||||||
it('should respect to .liquid_method_missing()', async () => {
|
it('should respect to .liquid_method_missing()', async () => {
|
||||||
const scope = new Scope({ obj: { liquid_method_missing: x => x.toUpperCase() } })
|
const scope = new Scope({ obj: { liquid_method_missing: x => x.toUpperCase() } })
|
||||||
const str = await new Output({value: 'obj.foo'}).render(scope)
|
const output = new Output({ value: 'obj.foo' } as OutputToken)
|
||||||
|
const str = await output.render(scope)
|
||||||
return expect(str).to.equal('FOO')
|
return expect(str).to.equal('FOO')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
+7
-16
@@ -1,24 +1,14 @@
|
|||||||
import * as chai from 'chai'
|
import { expect } from 'chai'
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
import * as sinonChai from 'sinon-chai'
|
|
||||||
import * as sinon from 'sinon'
|
|
||||||
import Scope from '../../src/scope/scope'
|
import Scope from '../../src/scope/scope'
|
||||||
import Token from 'src/parser/token'
|
import Token from '../../src/parser/token'
|
||||||
import Tag from 'src/template/tag/tag'
|
import Tag from 'src/template/tag/tag'
|
||||||
import Filter from 'src/template/filter'
|
import Filter from 'src/template/filter'
|
||||||
import Render from '../../src/render/render'
|
import Render from '../../src/render/render'
|
||||||
import Parser from '../../src/parser/parser'
|
|
||||||
import HTML from 'src/template/html'
|
import HTML from 'src/template/html'
|
||||||
|
|
||||||
chai.use(sinonChai)
|
|
||||||
chai.use(chaiAsPromised)
|
|
||||||
|
|
||||||
const expect = chai.expect
|
|
||||||
const parser = new Parser(null)
|
|
||||||
let render
|
|
||||||
|
|
||||||
describe('render', function () {
|
describe('render', function () {
|
||||||
beforeEach(function () {
|
let render
|
||||||
|
before(function () {
|
||||||
Filter.clear()
|
Filter.clear()
|
||||||
Tag.clear()
|
Tag.clear()
|
||||||
render = new Render()
|
render = new Render()
|
||||||
@@ -29,10 +19,11 @@ describe('render', function () {
|
|||||||
expect(render.renderTemplates([])).to.be.rejectedWith(/scope undefined/)
|
expect(render.renderTemplates([])).to.be.rejectedWith(/scope undefined/)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should render html', function () {
|
it('should render html', async function () {
|
||||||
const scope = new Scope()
|
const scope = new Scope()
|
||||||
const token = { type: 'html', value: '<p>' } as Token
|
const token = { type: 'html', value: '<p>' } as Token
|
||||||
return expect(render.renderTemplates([new HTML(token)], scope)).to.eventually.equal('<p>')
|
const html = await render.renderTemplates([new HTML(token)], scope)
|
||||||
|
return expect(html).to.equal('<p>')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
+5
-5
@@ -1,14 +1,14 @@
|
|||||||
import * as chai from 'chai'
|
import * as chai from 'chai'
|
||||||
import Tag from 'src/template/tag/tag'
|
import Tag from 'src/template/tag/tag'
|
||||||
import TagToken from 'src/parser/tag-token'
|
|
||||||
import Scope from 'src/scope/scope'
|
import Scope from 'src/scope/scope'
|
||||||
import * as sinon from 'sinon'
|
import * as sinon from 'sinon'
|
||||||
import * as sinonChai from 'sinon-chai'
|
import * as sinonChai from 'sinon-chai'
|
||||||
import Liquid from 'src/liquid'
|
import Liquid from 'src/liquid'
|
||||||
|
import TagToken from 'src/parser/tag-token'
|
||||||
|
|
||||||
chai.use(sinonChai)
|
chai.use(sinonChai)
|
||||||
const expect = chai.expect
|
const expect = chai.expect
|
||||||
const liquid = new Liquid();
|
const liquid = new Liquid()
|
||||||
|
|
||||||
describe('tag', function () {
|
describe('tag', function () {
|
||||||
let scope
|
let scope
|
||||||
@@ -29,14 +29,14 @@ describe('tag', function () {
|
|||||||
type: 'tag',
|
type: 'tag',
|
||||||
value: 'foo',
|
value: 'foo',
|
||||||
name: 'foo'
|
name: 'foo'
|
||||||
}, [], liquid)
|
} as TagToken, [], liquid)
|
||||||
}).to.throw(/tag foo not found/)
|
}).to.throw(/tag foo not found/)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should register simple tag', function () {
|
it('should register simple tag', function () {
|
||||||
expect(function () {
|
expect(function () {
|
||||||
Tag.register('foo', {
|
Tag.register('foo', {
|
||||||
render: x => 'bar'
|
render: () => 'bar'
|
||||||
})
|
})
|
||||||
}).not.throw()
|
}).not.throw()
|
||||||
})
|
})
|
||||||
@@ -50,7 +50,7 @@ describe('tag', function () {
|
|||||||
type: 'tag',
|
type: 'tag',
|
||||||
value: 'foo',
|
value: 'foo',
|
||||||
name: 'foo'
|
name: 'foo'
|
||||||
}
|
} as TagToken
|
||||||
await new Tag(token, [], liquid).render(scope)
|
await new Tag(token, [], liquid).render(scope)
|
||||||
expect(spy).to.have.been.called
|
expect(spy).to.have.been.called
|
||||||
})
|
})
|
||||||
|
|||||||
+40
-37
@@ -1,9 +1,8 @@
|
|||||||
import Liquid from 'src/liquid'
|
import Liquid from 'src/liquid'
|
||||||
import * as chai from 'chai'
|
import { expect, use } from 'chai'
|
||||||
import * as sinonChai from 'chai-as-promised'
|
import * as chaiAsPromised from 'chai-as-promised'
|
||||||
|
|
||||||
chai.use(sinonChai)
|
use(chaiAsPromised)
|
||||||
const expect = chai.expect
|
|
||||||
|
|
||||||
describe('tags/assign', function () {
|
describe('tags/assign', function () {
|
||||||
const liquid = new Liquid()
|
const liquid = new Liquid()
|
||||||
@@ -12,65 +11,69 @@ describe('tags/assign', function () {
|
|||||||
const ctx = {}
|
const ctx = {}
|
||||||
return expect(liquid.parseAndRender(src, ctx)).to.be.rejectedWith(/illegal/)
|
return expect(liquid.parseAndRender(src, ctx)).to.be.rejectedWith(/illegal/)
|
||||||
})
|
})
|
||||||
it('should support assign to a string', function () {
|
it('should support assign to a string', async function () {
|
||||||
const src = '{% assign foo="bar" %}{{foo}}'
|
const src = '{% assign foo="bar" %}{{foo}}'
|
||||||
return expect(liquid.parseAndRender(src))
|
const html = await liquid.parseAndRender(src)
|
||||||
.to.eventually.equal('bar')
|
return expect(html).to.equal('bar')
|
||||||
})
|
})
|
||||||
it('should support assign to a number', function () {
|
it('should support assign to a number', async function () {
|
||||||
const src = '{% assign foo=10086 %}{{foo}}'
|
const src = '{% assign foo=10086 %}{{foo}}'
|
||||||
return expect(liquid.parseAndRender(src))
|
const html = await liquid.parseAndRender(src)
|
||||||
.to.eventually.equal('10086')
|
return expect(html).to.equal('10086')
|
||||||
})
|
})
|
||||||
it('should shading rather than overwriting', function () {
|
it('should shading rather than overwriting', async function () {
|
||||||
const ctx = { foo: 'foo' }
|
const ctx = { foo: 'foo' }
|
||||||
const src = '{% assign foo="FOO" %}{{foo}}'
|
const src = '{% assign foo="FOO" %}{{foo}}'
|
||||||
return liquid.parseAndRender(src, ctx)
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.then(x => {
|
expect(html).to.equal('FOO')
|
||||||
expect(x).to.equal('FOO')
|
expect(ctx.foo).to.equal('foo')
|
||||||
expect(ctx.foo).to.equal('foo')
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
it('should assign as array', function () {
|
it('should assign as array', async function () {
|
||||||
const src = '{% assign foo=(1..3) %}{{foo}}'
|
const src = '{% assign foo=(1..3) %}{{foo}}'
|
||||||
return expect(liquid.parseAndRender(src))
|
const html = await liquid.parseAndRender(src)
|
||||||
.to.eventually.equal('[1,2,3]')
|
return expect(html).to.equal('[1,2,3]')
|
||||||
})
|
})
|
||||||
it('should assign as filter result', function () {
|
it('should assign as filter result', async function () {
|
||||||
const src = '{% assign foo="a b" | capitalize | split: " " | first %}{{foo}}'
|
const src = '{% assign foo="a b" | capitalize | split: " " | first %}{{foo}}'
|
||||||
return expect(liquid.parseAndRender(src))
|
const html = await liquid.parseAndRender(src)
|
||||||
.to.eventually.equal('A')
|
return expect(html).to.equal('A')
|
||||||
})
|
})
|
||||||
it('should assign as filter across multiple lines as result', function () {
|
it('should assign as filter across multiple lines as result', async function () {
|
||||||
const src = `{% assign foo="a b"
|
const src = `{% assign foo="a b"
|
||||||
| capitalize
|
| capitalize
|
||||||
| split: " "
|
| split: " "
|
||||||
| first %}{{foo}}`
|
| first %}{{foo}}`
|
||||||
return expect(liquid.parseAndRender(src))
|
const html = await liquid.parseAndRender(src)
|
||||||
.to.eventually.equal('A')
|
return expect(html).to.equal('A')
|
||||||
})
|
})
|
||||||
it('should assign var-1', function () {
|
it('should assign var-1', async function () {
|
||||||
const src = '{% assign var-1 = 5 %}{{ var-1 }}'
|
const src = '{% assign var-1 = 5 %}{{ var-1 }}'
|
||||||
return expect(liquid.parseAndRender(src)).to.eventually.equal('5')
|
const html = await liquid.parseAndRender(src)
|
||||||
|
return expect(html).to.equal('5')
|
||||||
})
|
})
|
||||||
it('should assign var-', function () {
|
it('should assign var-', async function () {
|
||||||
const src = '{% assign var- = 5 %}{{ var- }}'
|
const src = '{% assign var- = 5 %}{{ var- }}'
|
||||||
return expect(liquid.parseAndRender(src)).to.eventually.equal('5')
|
const html = await liquid.parseAndRender(src)
|
||||||
|
return expect(html).to.equal('5')
|
||||||
})
|
})
|
||||||
it('should assign -var', function () {
|
it('should assign -var', async function () {
|
||||||
const src = '{% assign -let = 5 %}{{ -let }}'
|
const src = '{% assign -let = 5 %}{{ -let }}'
|
||||||
return expect(liquid.parseAndRender(src)).to.eventually.equal('5')
|
const html = await liquid.parseAndRender(src)
|
||||||
|
return expect(html).to.equal('5')
|
||||||
})
|
})
|
||||||
it('should assign -5-5', function () {
|
it('should assign -5-5', async function () {
|
||||||
const src = '{% assign -5-5 = 5 %}{{ -5-5 }}'
|
const src = '{% assign -5-5 = 5 %}{{ -5-5 }}'
|
||||||
return expect(liquid.parseAndRender(src)).to.eventually.equal('5')
|
const html = await liquid.parseAndRender(src)
|
||||||
|
return expect(html).to.equal('5')
|
||||||
})
|
})
|
||||||
it('should assign 4-3', function () {
|
it('should assign 4-3', async function () {
|
||||||
const src = '{% assign 4-3 = 5 %}{{ 4-3 }}'
|
const src = '{% assign 4-3 = 5 %}{{ 4-3 }}'
|
||||||
return expect(liquid.parseAndRender(src)).to.eventually.equal('5')
|
const html = await liquid.parseAndRender(src)
|
||||||
|
return expect(html).to.equal('5')
|
||||||
})
|
})
|
||||||
it('should not assign -6', function () {
|
it('should not assign -6', async function () {
|
||||||
const src = '{% assign -6 = 5 %}{{ -6 }}'
|
const src = '{% assign -6 = 5 %}{{ -6 }}'
|
||||||
return expect(liquid.parseAndRender(src)).to.eventually.equal('-6')
|
const html = await liquid.parseAndRender(src)
|
||||||
|
return expect(html).to.equal('-6')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
+10
-12
@@ -1,26 +1,24 @@
|
|||||||
import Liquid from 'src/liquid'
|
import Liquid from 'src/liquid'
|
||||||
import * as chai from 'chai'
|
import { expect, use } from 'chai'
|
||||||
|
import * as chaiAsPromised from 'chai-as-promised'
|
||||||
|
|
||||||
const expect = chai.expect
|
use(chaiAsPromised)
|
||||||
chai.use(require('chai-as-promised'))
|
|
||||||
|
|
||||||
describe('tags/capture', function () {
|
describe('tags/capture', function () {
|
||||||
const liquid = new Liquid()
|
const liquid = new Liquid()
|
||||||
|
|
||||||
it('should support capture', function () {
|
it('should support capture', async function () {
|
||||||
const src = '{% capture f %}{{"a" | capitalize}}{%endcapture%}{{f}}'
|
const src = '{% capture f %}{{"a" | capitalize}}{%endcapture%}{{f}}'
|
||||||
return expect(liquid.parseAndRender(src))
|
const html = await liquid.parseAndRender(src)
|
||||||
.to.eventually.equal('A')
|
return expect(html).to.equal('A')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should shading rather than overwriting', function () {
|
it('should shading rather than overwriting', async function () {
|
||||||
const src = '{% capture var %}10{% endcapture %}{{var}}'
|
const src = '{% capture var %}10{% endcapture %}{{var}}'
|
||||||
const ctx = { 'var': 20 }
|
const ctx = { 'var': 20 }
|
||||||
return liquid.parseAndRender(src, ctx)
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.then(x => {
|
expect(html).to.equal('10')
|
||||||
expect(x).to.equal('10')
|
expect(ctx.var).to.equal(20)
|
||||||
expect(ctx.var).to.equal(20)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should throw on invalid identifier', function () {
|
it('should throw on invalid identifier', function () {
|
||||||
|
|||||||
+18
-18
@@ -1,8 +1,8 @@
|
|||||||
import Liquid from 'src/liquid'
|
import Liquid from 'src/liquid'
|
||||||
import * as chai from 'chai'
|
import { expect, use } from 'chai'
|
||||||
|
import * as chaiAsPromised from 'chai-as-promised'
|
||||||
|
|
||||||
const expect = chai.expect
|
use(chaiAsPromised)
|
||||||
chai.use(require('chai-as-promised'))
|
|
||||||
|
|
||||||
describe('tags/case', function () {
|
describe('tags/case', function () {
|
||||||
const liquid = new Liquid()
|
const liquid = new Liquid()
|
||||||
@@ -12,42 +12,42 @@ describe('tags/case', function () {
|
|||||||
return expect(liquid.parseAndRender(src))
|
return expect(liquid.parseAndRender(src))
|
||||||
.to.be.rejectedWith(/{% case "foo"%} not closed/)
|
.to.be.rejectedWith(/{% case "foo"%} not closed/)
|
||||||
})
|
})
|
||||||
it('should hit the specified case', function () {
|
it('should hit the specified case', async function () {
|
||||||
const src = '{% case "foo"%}' +
|
const src = '{% case "foo"%}' +
|
||||||
'{% when "foo" %}foo{% when "bar"%}bar' +
|
'{% when "foo" %}foo{% when "bar"%}bar' +
|
||||||
'{%endcase%}'
|
'{%endcase%}'
|
||||||
return expect(liquid.parseAndRender(src))
|
const html = await liquid.parseAndRender(src)
|
||||||
.to.eventually.equal('foo')
|
return expect(html).to.equal('foo')
|
||||||
})
|
})
|
||||||
it('should resolve empty string if not hit', function () {
|
it('should resolve empty string if not hit', async function () {
|
||||||
const src = '{% case empty %}' +
|
const src = '{% case empty %}' +
|
||||||
'{% when "foo" %}foo{% when ""%}bar' +
|
'{% when "foo" %}foo{% when ""%}bar' +
|
||||||
'{%endcase%}'
|
'{%endcase%}'
|
||||||
const ctx = {
|
const ctx = {
|
||||||
empty: ''
|
empty: ''
|
||||||
}
|
}
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('bar')
|
return expect(html).to.equal('bar')
|
||||||
})
|
})
|
||||||
it('should accept empty string as branch name', function () {
|
it('should accept empty string as branch name', async function () {
|
||||||
const src = '{% case false %}' +
|
const src = '{% case false %}' +
|
||||||
'{% when "foo" %}foo{% when ""%}bar' +
|
'{% when "foo" %}foo{% when ""%}bar' +
|
||||||
'{%endcase%}'
|
'{%endcase%}'
|
||||||
return expect(liquid.parseAndRender(src))
|
const html = await liquid.parseAndRender(src)
|
||||||
.to.eventually.equal('')
|
return expect(html).to.equal('')
|
||||||
})
|
})
|
||||||
it('should support boolean case', function () {
|
it('should support boolean case', async function () {
|
||||||
const src = '{% case false %}' +
|
const src = '{% case false %}' +
|
||||||
'{% when "foo" %}foo{% when false%}bar' +
|
'{% when "foo" %}foo{% when false%}bar' +
|
||||||
'{%endcase%}'
|
'{%endcase%}'
|
||||||
return expect(liquid.parseAndRender(src))
|
const html = await liquid.parseAndRender(src)
|
||||||
.to.eventually.equal('bar')
|
return expect(html).to.equal('bar')
|
||||||
})
|
})
|
||||||
it('should support else branch', function () {
|
it('should support else branch', async function () {
|
||||||
const src = '{% case "a" %}' +
|
const src = '{% case "a" %}' +
|
||||||
'{% when "b" %}b{% when "c"%}c{%else %}d' +
|
'{% when "b" %}b{% when "c"%}c{%else %}d' +
|
||||||
'{%endcase%}'
|
'{%endcase%}'
|
||||||
return expect(liquid.parseAndRender(src))
|
const html = await liquid.parseAndRender(src)
|
||||||
.to.eventually.equal('d')
|
return expect(html).to.equal('d')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
+15
-15
@@ -1,8 +1,8 @@
|
|||||||
import Liquid from 'src/liquid'
|
import Liquid from 'src/liquid'
|
||||||
import * as chai from 'chai'
|
import { expect, use } from 'chai'
|
||||||
|
import * as chaiAsPromised from 'chai-as-promised'
|
||||||
|
|
||||||
const expect = chai.expect
|
use(chaiAsPromised)
|
||||||
chai.use(require('chai-as-promised'))
|
|
||||||
|
|
||||||
describe('tags/comment', function () {
|
describe('tags/comment', function () {
|
||||||
const liquid = new Liquid()
|
const liquid = new Liquid()
|
||||||
@@ -11,24 +11,24 @@ describe('tags/comment', function () {
|
|||||||
return expect(liquid.parseAndRender(src))
|
return expect(liquid.parseAndRender(src))
|
||||||
.to.be.rejectedWith(/{% comment %} not closed/)
|
.to.be.rejectedWith(/{% comment %} not closed/)
|
||||||
})
|
})
|
||||||
it('should ignore plain string', function () {
|
it('should ignore plain string', async function () {
|
||||||
const src = 'My name is {% comment %}super{% endcomment %} Shopify.'
|
const src = 'My name is {% comment %}super{% endcomment %} Shopify.'
|
||||||
return expect(liquid.parseAndRender(src))
|
const html = await liquid.parseAndRender(src)
|
||||||
.to.eventually.equal('My name is Shopify.')
|
return expect(html).to.equal('My name is Shopify.')
|
||||||
})
|
})
|
||||||
it('should ignore output tokens', function () {
|
it('should ignore output tokens', async function () {
|
||||||
const src = '{% comment %}\n{{ foo}} \n{% endcomment %}'
|
const src = '{% comment %}\n{{ foo}} \n{% endcomment %}'
|
||||||
return expect(liquid.parseAndRender(src))
|
const html = await liquid.parseAndRender(src)
|
||||||
.to.eventually.equal('')
|
return expect(html).to.equal('')
|
||||||
})
|
})
|
||||||
it('should ignore tag tokens', function () {
|
it('should ignore tag tokens', async function () {
|
||||||
const src = '{% comment %}{%if true%}true{%else%}false{%endif%}{% endcomment %}'
|
const src = '{% comment %}{%if true%}true{%else%}false{%endif%}{% endcomment %}'
|
||||||
return expect(liquid.parseAndRender(src))
|
const html = await liquid.parseAndRender(src)
|
||||||
.to.eventually.equal('')
|
return expect(html).to.equal('')
|
||||||
})
|
})
|
||||||
it('should ignore un-balenced tag tokens', function () {
|
it('should ignore un-balenced tag tokens', async function () {
|
||||||
const src = '{% comment %}{%if true%}true{%else%}false{% endcomment %}'
|
const src = '{% comment %}{%if true%}true{%else%}false{% endcomment %}'
|
||||||
return expect(liquid.parseAndRender(src))
|
const html = await liquid.parseAndRender(src)
|
||||||
.to.eventually.equal('')
|
return expect(html).to.equal('')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
+13
-15
@@ -1,16 +1,16 @@
|
|||||||
import Liquid from 'src/liquid'
|
import Liquid from 'src/liquid'
|
||||||
import * as chai from 'chai'
|
import { expect, use } from 'chai'
|
||||||
|
import * as chaiAsPromised from 'chai-as-promised'
|
||||||
|
|
||||||
const expect = chai.expect
|
use(chaiAsPromised)
|
||||||
chai.use(require('chai-as-promised'))
|
|
||||||
|
|
||||||
describe('tags/cycle', function () {
|
describe('tags/cycle', function () {
|
||||||
const liquid = new Liquid()
|
const liquid = new Liquid()
|
||||||
|
|
||||||
it('should support cycle', function () {
|
it('should support cycle', async function () {
|
||||||
const src = "{% cycle '1', '2', '3' %}"
|
const src = "{% cycle '1', '2', '3' %}"
|
||||||
return expect(liquid.parseAndRender(src + src + src + src))
|
const html = await liquid.parseAndRender(src + src + src + src)
|
||||||
.to.eventually.equal('1231')
|
return expect(html).to.equal('1231')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should throw when cycle candidates empty', function () {
|
it('should throw when cycle candidates empty', function () {
|
||||||
@@ -18,23 +18,21 @@ describe('tags/cycle', function () {
|
|||||||
.to.be.rejectedWith(/empty candidates/)
|
.to.be.rejectedWith(/empty candidates/)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support cycle in for block', function () {
|
it('should support cycle in for block', async function () {
|
||||||
const src = '{% for i in (1..5) %}{% cycle one, "e"%}{% endfor %}'
|
const src = '{% for i in (1..5) %}{% cycle one, "e"%}{% endfor %}'
|
||||||
const ctx = {
|
const ctx = {
|
||||||
one: 1
|
one: 1
|
||||||
}
|
}
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('1e1e1')
|
return expect(html).to.equal('1e1e1')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support cycle group', function () {
|
it('should support cycle group', async function () {
|
||||||
const src = "{% cycle one: '1', '2', '3'%}" +
|
const src = "{% cycle one: '1', '2', '3'%}" +
|
||||||
"{% cycle 1: '1', '2', '3'%}" +
|
"{% cycle 1: '1', '2', '3'%}" +
|
||||||
"{% cycle 2: '1', '2', '3'%}"
|
"{% cycle 2: '1', '2', '3'%}"
|
||||||
const ctx = {
|
const ctx = { one: 1 }
|
||||||
one: 1
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
}
|
return expect(html).to.equal('121')
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
|
||||||
.to.eventually.equal('121')
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
+25
-27
@@ -1,8 +1,8 @@
|
|||||||
import Liquid from 'src/liquid'
|
import Liquid from 'src/liquid'
|
||||||
import * as chai from 'chai'
|
import { expect, use } from 'chai'
|
||||||
|
import * as chaiAsPromised from 'chai-as-promised'
|
||||||
|
|
||||||
const expect = chai.expect
|
use(chaiAsPromised)
|
||||||
chai.use(require('chai-as-promised'))
|
|
||||||
|
|
||||||
describe('tags/decrement', function () {
|
describe('tags/decrement', function () {
|
||||||
const liquid = new Liquid()
|
const liquid = new Liquid()
|
||||||
@@ -12,49 +12,47 @@ describe('tags/decrement', function () {
|
|||||||
return expect(liquid.parseAndRender(src, ctx)).to.be.rejectedWith(/illegal/)
|
return expect(liquid.parseAndRender(src, ctx)).to.be.rejectedWith(/illegal/)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should decrement undefined variable', function () {
|
it('should decrement undefined variable', async function () {
|
||||||
const src = '{% decrement var %}{% decrement var %}{% decrement var %}'
|
const src = '{% decrement var %}{% decrement var %}{% decrement var %}'
|
||||||
return expect(liquid.parseAndRender(src))
|
const html = await liquid.parseAndRender(src)
|
||||||
.to.eventually.equal('-1-2-3')
|
return expect(html).to.equal('-1-2-3')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should decrement defined variable', function () {
|
it('should decrement defined variable', async function () {
|
||||||
const src = '{% decrement var %}{% decrement var %}{% decrement var %}'
|
const src = '{% decrement var %}{% decrement var %}{% decrement var %}'
|
||||||
const ctx = { 'var': 10 }
|
const ctx = { 'var': 10 }
|
||||||
return liquid.parseAndRender(src, ctx)
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.then(x => {
|
expect(html).to.equal('987')
|
||||||
expect(x).to.equal('987')
|
expect(ctx.var).to.equal(7)
|
||||||
expect(ctx.var).to.equal(7)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should be independent from assign', function () {
|
it('should be independent from assign', async function () {
|
||||||
const src = '{% assign var=10 %}{% decrement var %}{% decrement var %}{% decrement var %}'
|
const src = '{% assign var=10 %}{% decrement var %}{% decrement var %}{% decrement var %}'
|
||||||
return expect(liquid.parseAndRender(src))
|
const html = await liquid.parseAndRender(src)
|
||||||
.to.eventually.equal('-1-2-3')
|
return expect(html).to.equal('-1-2-3')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should be independent from capture', function () {
|
it('should be independent from capture', async function () {
|
||||||
const src = '{% capture var %}10{% endcapture %}{% decrement var %}{% decrement var %}{% decrement var %}'
|
const src = '{% capture var %}10{% endcapture %}{% decrement var %}{% decrement var %}{% decrement var %}'
|
||||||
return expect(liquid.parseAndRender(src))
|
const html = await liquid.parseAndRender(src)
|
||||||
.to.eventually.equal('-1-2-3')
|
return expect(html).to.equal('-1-2-3')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should not shading assign', function () {
|
it('should not shading assign', async function () {
|
||||||
const src = '{% assign var=10 %}{% decrement var %}{% decrement var %}{% decrement var %} {{var}}'
|
const src = '{% assign var=10 %}{% decrement var %}{% decrement var %}{% decrement var %} {{var}}'
|
||||||
return expect(liquid.parseAndRender(src))
|
const html = await liquid.parseAndRender(src)
|
||||||
.to.eventually.equal('-1-2-3 10')
|
return expect(html).to.equal('-1-2-3 10')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should not shading capture', function () {
|
it('should not shading capture', async function () {
|
||||||
const src = '{% capture var %}10{% endcapture %}{% decrement var %}{% decrement var %}{% decrement var %} {{var}}'
|
const src = '{% capture var %}10{% endcapture %}{% decrement var %}{% decrement var %}{% decrement var %} {{var}}'
|
||||||
return expect(liquid.parseAndRender(src))
|
const html = await liquid.parseAndRender(src)
|
||||||
.to.eventually.equal('-1-2-3 10')
|
return expect(html).to.equal('-1-2-3 10')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should share the same variable with increment', function () {
|
it('should share the same variable with increment', async function () {
|
||||||
const src = '{%increment var%}{%increment var%}{%decrement var%}{%decrement var%}{%increment var%}'
|
const src = '{%increment var%}{%increment var%}{%decrement var%}{%decrement var%}{%increment var%}'
|
||||||
return expect(liquid.parseAndRender(src))
|
const html = await liquid.parseAndRender(src)
|
||||||
.to.eventually.equal('01100')
|
return expect(html).to.equal('01100')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
+75
-75
@@ -1,8 +1,8 @@
|
|||||||
import Liquid from 'src/liquid'
|
import Liquid from 'src/liquid'
|
||||||
import * as chai from 'chai'
|
import { expect, use } from 'chai'
|
||||||
|
import * as chaiAsPromised from 'chai-as-promised'
|
||||||
|
|
||||||
const expect = chai.expect
|
use(chaiAsPromised)
|
||||||
chai.use(require('chai-as-promised'))
|
|
||||||
|
|
||||||
describe('tags/for', function () {
|
describe('tags/for', function () {
|
||||||
let liquid, ctx
|
let liquid, ctx
|
||||||
@@ -22,28 +22,28 @@ describe('tags/for', function () {
|
|||||||
emptyArray: []
|
emptyArray: []
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
it('should support array', function () {
|
it('should support array', async function () {
|
||||||
const src = '{%for c in alpha%}{{c}}{%endfor%}'
|
const src = '{%for c in alpha%}{{c}}{%endfor%}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('abc')
|
return expect(html).to.equal('abc')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support object', function () {
|
it('should support object', async function () {
|
||||||
const src = '{%for item in obj%}{{item[0]}},{{item[1]}}-{%else%}b{%endfor%}'
|
const src = '{%for item in obj%}{{item[0]}},{{item[1]}}-{%else%}b{%endfor%}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('foo,bar-coo,haa-')
|
return expect(html).to.equal('foo,bar-coo,haa-')
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('scope', function () {
|
describe('scope', function () {
|
||||||
it('should read super scope', function () {
|
it('should read super scope', async function () {
|
||||||
const src = '{%for a in (1..2)%}{{num}}{%endfor%}'
|
const src = '{%for a in (1..2)%}{{num}}{%endfor%}'
|
||||||
return expect(liquid.parseAndRender(src, { num: 1 }))
|
const html = await liquid.parseAndRender(src, { num: 1 })
|
||||||
.to.eventually.equal('11')
|
return expect(html).to.equal('11')
|
||||||
})
|
})
|
||||||
it('should write super scope', function () {
|
it('should write super scope', async function () {
|
||||||
const src = '{%for a in (1..2)%}{{num}}{%assign num = 2%}{%endfor%}'
|
const src = '{%for a in (1..2)%}{{num}}{%assign num = 2%}{%endfor%}'
|
||||||
return expect(liquid.parseAndRender(src, { num: 1 }))
|
const html = await liquid.parseAndRender(src, { num: 1 })
|
||||||
.to.eventually.equal('12')
|
return expect(html).to.equal('12')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -62,45 +62,45 @@ describe('tags/for', function () {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe('else', function () {
|
describe('else', function () {
|
||||||
it('should goto else for empty array', function () {
|
it('should goto else for empty array', async function () {
|
||||||
const src = '{%for c in emptyArray%}a{%else%}b{%endfor%}'
|
const src = '{%for c in emptyArray%}a{%else%}b{%endfor%}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('b')
|
return expect(html).to.equal('b')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should treat non-empty string as one single element', function () {
|
it('should treat non-empty string as one single element', async function () {
|
||||||
const src = '{%for c in "abc"%}x{{c}}{%else%}y{%endfor%}'
|
const src = '{%for c in "abc"%}x{{c}}{%else%}y{%endfor%}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('xabc')
|
return expect(html).to.equal('xabc')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should goto else for empty string', function () {
|
it('should goto else for empty string', async function () {
|
||||||
const src = '{%for c in ""%}a{%else%}b{%endfor%}'
|
const src = '{%for c in ""%}a{%else%}b{%endfor%}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('b')
|
return expect(html).to.equal('b')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should goto else for empty string object', function () {
|
it('should goto else for empty string object', async function () {
|
||||||
// it should be false although `new String` is none-conform
|
// it should be false although `new String` is none-conform
|
||||||
const src = '{%for c in strObj%}a{%else%}b{%endfor%}'
|
const src = '{%for c in strObj%}a{%else%}b{%endfor%}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('b')
|
return expect(html).to.equal('b')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should goto else for empty object', function () {
|
it('should goto else for empty object', async function () {
|
||||||
const src = '{%for c in emptyObj%}a{%else%}b{%endfor%}'
|
const src = '{%for c in emptyObj%}a{%else%}b{%endfor%}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('b')
|
return expect(html).to.equal('b')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should goto else for null-prototyped object', function () {
|
it('should goto else for null-prototyped object', async function () {
|
||||||
const src = '{%for c in nullProtoObj%}a{%else%}b{%endfor%}'
|
const src = '{%for c in nullProtoObj%}a{%else%}b{%endfor%}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('b')
|
return expect(html).to.equal('b')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support for with forloop', function () {
|
it('should support for with forloop', async function () {
|
||||||
const src = '{%for c in alpha%}' +
|
const src = '{%for c in alpha%}' +
|
||||||
'{{forloop.first}}.{{forloop.index}}.{{forloop.index0}}.' +
|
'{{forloop.first}}.{{forloop.index}}.{{forloop.index0}}.' +
|
||||||
'{{forloop.last}}.{{forloop.length}}.' +
|
'{{forloop.last}}.{{forloop.length}}.' +
|
||||||
@@ -110,41 +110,41 @@ describe('tags/for', function () {
|
|||||||
const dst = 'true.1.0.false.3.3.2a\n' +
|
const dst = 'true.1.0.false.3.3.2a\n' +
|
||||||
'false.2.1.false.3.2.1b\n' +
|
'false.2.1.false.3.2.1b\n' +
|
||||||
'false.3.2.true.3.1.0c\n'
|
'false.3.2.true.3.1.0c\n'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal(dst)
|
return expect(html).to.equal(dst)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support for with continue', function () {
|
it('should support for with continue', async function () {
|
||||||
const src = '{% for i in (1..5) %}' +
|
const src = '{% for i in (1..5) %}' +
|
||||||
'{{i}}{% continue %}after' +
|
'{{i}}{% continue %}after' +
|
||||||
'{% endfor %}'
|
'{% endfor %}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('12345')
|
return expect(html).to.equal('12345')
|
||||||
})
|
})
|
||||||
it('should support for with break', function () {
|
it('should support for with break', async function () {
|
||||||
const src = '{% for i in (one..5) %}' +
|
const src = '{% for i in (one..5) %}' +
|
||||||
'{% if i == 4 %}{% break %}{% endif %}' +
|
'{% if i == 4 %}{% break %}{% endif %}' +
|
||||||
'{{ i }}' +
|
'{{ i }}' +
|
||||||
'{% endfor %}'
|
'{% endfor %}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('123')
|
return expect(html).to.equal('123')
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('limit', function () {
|
describe('limit', function () {
|
||||||
it('should support for with limit', function () {
|
it('should support for with limit', async function () {
|
||||||
const src = '{% for i in (1..5) limit:2 %}{{ i }}{% endfor %}'
|
const src = '{% for i in (1..5) limit:2 %}{{ i }}{% endfor %}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('12')
|
return expect(html).to.equal('12')
|
||||||
})
|
})
|
||||||
it('should set forloop.last properly', function () {
|
it('should set forloop.last properly', async function () {
|
||||||
const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.last}} {%endfor%}'
|
const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.last}} {%endfor%}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('false true ')
|
return expect(html).to.equal('false true ')
|
||||||
})
|
})
|
||||||
it('should set forloop.first properly', function () {
|
it('should set forloop.first properly', async function () {
|
||||||
const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.first}} {%endfor%}'
|
const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.first}} {%endfor%}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('true false ')
|
return expect(html).to.equal('true false ')
|
||||||
})
|
})
|
||||||
it('should set forloop.length properly', function () {
|
it('should set forloop.length properly', function () {
|
||||||
const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.length}} {%endfor%}'
|
const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.length}} {%endfor%}'
|
||||||
@@ -154,50 +154,50 @@ describe('tags/for', function () {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe('offset', function () {
|
describe('offset', function () {
|
||||||
it('should support offset with limit', function () {
|
it('should support offset with limit', async function () {
|
||||||
const src = '{% for i in (1..10) limit:2 offset:5%}{{ i }}{% endfor %}'
|
const src = '{% for i in (1..10) limit:2 offset:5%}{{ i }}{% endfor %}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('67')
|
return expect(html).to.equal('67')
|
||||||
})
|
})
|
||||||
it('should set index properly', function () {
|
it('should set index properly', async function () {
|
||||||
const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.index}} {%endfor%}'
|
const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.index}} {%endfor%}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('1 2 ')
|
return expect(html).to.equal('1 2 ')
|
||||||
})
|
})
|
||||||
it('should set index0 properly', function () {
|
it('should set index0 properly', async function () {
|
||||||
const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.index0}} {%endfor%}'
|
const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.index0}} {%endfor%}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('0 1 ')
|
return expect(html).to.equal('0 1 ')
|
||||||
})
|
})
|
||||||
it('should set rindex properly', function () {
|
it('should set rindex properly', async function () {
|
||||||
const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.rindex}} {%endfor%}'
|
const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.rindex}} {%endfor%}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('2 1 ')
|
return expect(html).to.equal('2 1 ')
|
||||||
})
|
})
|
||||||
it('should set rindex0 properly', function () {
|
it('should set rindex0 properly', async function () {
|
||||||
const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.rindex0}} {%endfor%}'
|
const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.rindex0}} {%endfor%}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('1 0 ')
|
return expect(html).to.equal('1 0 ')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('reverse', function () {
|
describe('reverse', function () {
|
||||||
it('should support for reversed in the last position', function () {
|
it('should support for reversed in the last position', async function () {
|
||||||
const src = '{% for i in (1..5) limit:2 reversed %}{{ i }}{% endfor %}'
|
const src = '{% for i in (1..5) limit:2 reversed %}{{ i }}{% endfor %}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('21')
|
return expect(html).to.equal('21')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support for reversed in the first position', function () {
|
it('should support for reversed in the first position', async function () {
|
||||||
const src = '{% for i in (1..5) reversed limit:2 %}{{ i }}{% endfor %}'
|
const src = '{% for i in (1..5) reversed limit:2 %}{{ i }}{% endfor %}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('21')
|
return expect(html).to.equal('21')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support for reversed in the middle position', function () {
|
it('should support for reversed in the middle position', async function () {
|
||||||
const src = '{% for i in (1..5) offset:2 reversed limit:4 %}{{ i }}{% endfor %}'
|
const src = '{% for i in (1..5) offset:2 reversed limit:4 %}{{ i }}{% endfor %}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('543')
|
return expect(html).to.equal('543')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
+49
-52
@@ -1,8 +1,5 @@
|
|||||||
import Liquid from 'src/liquid'
|
import Liquid from 'src/liquid'
|
||||||
import * as chai from 'chai'
|
import { expect } from 'chai'
|
||||||
|
|
||||||
const expect = chai.expect
|
|
||||||
chai.use(require('chai-as-promised'))
|
|
||||||
|
|
||||||
describe('tags/if', function () {
|
describe('tags/if', function () {
|
||||||
const liquid = new Liquid()
|
const liquid = new Liquid()
|
||||||
@@ -18,99 +15,99 @@ describe('tags/if', function () {
|
|||||||
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 nested', function () {
|
it('should support nested', async function () {
|
||||||
const src = '{%if false%}{%if true%}{%else%}a{%endif%}{%endif%}'
|
const src = '{%if false%}{%if true%}{%else%}a{%endif%}{%endif%}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('')
|
return expect(html).to.equal('')
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('single value as condition', function () {
|
describe('single value as condition', function () {
|
||||||
it('should support boolean', function () {
|
it('should support boolean', async function () {
|
||||||
const src = '{% if false %}1{%elsif true%}2{%else%}3{%endif%}'
|
const src = '{% if false %}1{%elsif true%}2{%else%}3{%endif%}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('2')
|
return expect(html).to.equal('2')
|
||||||
})
|
})
|
||||||
it('should treat Array truthy', function () {
|
it('should treat Array truthy', async function () {
|
||||||
const src = '{%if emptyArray%}a{%endif%}'
|
const src = '{%if emptyArray%}a{%endif%}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('a')
|
return expect(html).to.equal('a')
|
||||||
})
|
})
|
||||||
it('should return true if empty string', function () {
|
it('should return true if empty string', async function () {
|
||||||
const src = '{%if emptyString%}a{%endif%}'
|
const src = '{%if emptyString%}a{%endif%}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('a')
|
return expect(html).to.equal('a')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('expression as condition', function () {
|
describe('expression as condition', function () {
|
||||||
it('should support ==', function () {
|
it('should support ==', async function () {
|
||||||
const src = '{% if 2==3 %}yes{%else%}no{%endif%}'
|
const src = '{% if 2==3 %}yes{%else%}no{%endif%}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('no')
|
return expect(html).to.equal('no')
|
||||||
})
|
})
|
||||||
it('should support >=', function () {
|
it('should support >=', async function () {
|
||||||
const src = '{% if 1>=2 and one<two %}a{%endif%}'
|
const src = '{% if 1>=2 and one<two %}a{%endif%}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('')
|
return expect(html).to.equal('')
|
||||||
})
|
})
|
||||||
it('should support !=', function () {
|
it('should support !=', async function () {
|
||||||
const src = '{% if one!=two %}yes{%else%}no{%endif%}'
|
const src = '{% if one!=two %}yes{%else%}no{%endif%}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('yes')
|
return expect(html).to.equal('yes')
|
||||||
})
|
})
|
||||||
it('should support value and expression', function () {
|
it('should support value and expression', async function () {
|
||||||
const src = `X{%if version and version != '' %}x{{version}}y{%endif%}Y`
|
const src = `X{%if version and version != '' %}x{{version}}y{%endif%}Y`
|
||||||
const ctx = { 'version': '' }
|
const ctx = { 'version': '' }
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('XY')
|
return expect(html).to.equal('XY')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('comparasion to null', function () {
|
describe('comparasion to null', function () {
|
||||||
it('should evaluate false for null < 10', function () {
|
it('should evaluate false for null < 10', async function () {
|
||||||
const src = '{% if null < 10 %}yes{% else %}no{% endif %}'
|
const src = '{% if null < 10 %}yes{% else %}no{% endif %}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('no')
|
return expect(html).to.equal('no')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should evaluate false for null > 10', function () {
|
it('should evaluate false for null > 10', async function () {
|
||||||
const src = '{% if null > 10 %}yes{% else %}no{% endif %}'
|
const src = '{% if null > 10 %}yes{% else %}no{% endif %}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('no')
|
return expect(html).to.equal('no')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should evaluate false for null <= 10', function () {
|
it('should evaluate false for null <= 10', async function () {
|
||||||
const src = '{% if null <= 10 %}yes{% else %}no{% endif %}'
|
const src = '{% if null <= 10 %}yes{% else %}no{% endif %}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('no')
|
return expect(html).to.equal('no')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should evaluate false for null >= 10', function () {
|
it('should evaluate false for null >= 10', async function () {
|
||||||
const src = '{% if null >= 10 %}yes{% else %}no{% endif %}'
|
const src = '{% if null >= 10 %}yes{% else %}no{% endif %}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('no')
|
return expect(html).to.equal('no')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should evaluate false for 10 < null', function () {
|
it('should evaluate false for 10 < null', async function () {
|
||||||
const src = '{% if 10 < null %}yes{% else %}no{% endif %}'
|
const src = '{% if 10 < null %}yes{% else %}no{% endif %}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('no')
|
return expect(html).to.equal('no')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should evaluate false for 10 > null', function () {
|
it('should evaluate false for 10 > null', async function () {
|
||||||
const src = '{% if 10 > null %}yes{% else %}no{% endif %}'
|
const src = '{% if 10 > null %}yes{% else %}no{% endif %}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('no')
|
return expect(html).to.equal('no')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should evaluate false for 10 <= null', function () {
|
it('should evaluate false for 10 <= null', async function () {
|
||||||
const src = '{% if 10 <= null %}yes{% else %}no{% endif %}'
|
const src = '{% if 10 <= null %}yes{% else %}no{% endif %}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('no')
|
return expect(html).to.equal('no')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should evaluate false for 10 >= null', function () {
|
it('should evaluate false for 10 >= null', async function () {
|
||||||
const src = '{% if 10 >= null %}yes{% else %}no{% endif %}'
|
const src = '{% if 10 >= null %}yes{% else %}no{% endif %}'
|
||||||
return expect(liquid.parseAndRender(src, ctx))
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.to.eventually.equal('no')
|
return expect(html).to.equal('no')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
+34
-37
@@ -1,9 +1,6 @@
|
|||||||
import Liquid from 'src/liquid'
|
import Liquid from 'src/liquid'
|
||||||
|
import { expect } from 'chai'
|
||||||
import * as mock from 'mock-fs'
|
import * as mock from 'mock-fs'
|
||||||
import * as chai from 'chai'
|
|
||||||
|
|
||||||
const expect = chai.expect
|
|
||||||
chai.use(require('chai-as-promised'))
|
|
||||||
|
|
||||||
describe('tags/include', function () {
|
describe('tags/include', function () {
|
||||||
let liquid
|
let liquid
|
||||||
@@ -16,21 +13,21 @@ describe('tags/include', function () {
|
|||||||
afterEach(function () {
|
afterEach(function () {
|
||||||
mock.restore()
|
mock.restore()
|
||||||
})
|
})
|
||||||
it('should support include', function () {
|
it('should support include', async function () {
|
||||||
mock({
|
mock({
|
||||||
'/current.html': 'bar{% include "bar/foo.html" %}bar',
|
'/current.html': 'bar{% include "bar/foo.html" %}bar',
|
||||||
'/bar/foo.html': 'foo'
|
'/bar/foo.html': 'foo'
|
||||||
})
|
})
|
||||||
return expect(liquid.renderFile('/current.html')).to
|
const html = await liquid.renderFile('/current.html')
|
||||||
.eventually.equal('barfoobar')
|
return expect(html).to.equal('barfoobar')
|
||||||
})
|
})
|
||||||
it('should support template string', function () {
|
it('should support template string', async function () {
|
||||||
mock({
|
mock({
|
||||||
'/current.html': 'bar{% include "bar/{{name}}" %}bar',
|
'/current.html': 'bar{% include "bar/{{name}}" %}bar',
|
||||||
'/bar/foo.html': 'foo'
|
'/bar/foo.html': 'foo'
|
||||||
})
|
})
|
||||||
return expect(liquid.renderFile('/current.html', { name: 'foo.html' })).to
|
const html = await liquid.renderFile('/current.html', { name: 'foo.html' })
|
||||||
.eventually.equal('barfoobar')
|
return expect(html).to.equal('barfoobar')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should throw when not specified', function () {
|
it('should throw when not specified', function () {
|
||||||
@@ -53,43 +50,43 @@ describe('tags/include', function () {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support include with relative path', function () {
|
it('should support include with relative path', async function () {
|
||||||
mock({
|
mock({
|
||||||
'/bar/foo.html': 'foo',
|
'/bar/foo.html': 'foo',
|
||||||
'/foo/relative.html': 'bar{% include "../bar/foo.html" %}bar'
|
'/foo/relative.html': 'bar{% include "../bar/foo.html" %}bar'
|
||||||
})
|
})
|
||||||
return expect(liquid.renderFile('foo/relative.html')).to
|
const html = await liquid.renderFile('foo/relative.html')
|
||||||
.eventually.equal('barfoobar')
|
return expect(html).to.equal('barfoobar')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support include: hash list', function () {
|
it('should support include: hash list', async function () {
|
||||||
mock({
|
mock({
|
||||||
'/hash.html': '{% assign name="harttle" %}{% include "user.html", role: "admin", alias: name %}',
|
'/hash.html': '{% assign name="harttle" %}{% include "user.html", role: "admin", alias: name %}',
|
||||||
'/user.html': '{{name}} : {{role}} : {{alias}}'
|
'/user.html': '{{name}} : {{role}} : {{alias}}'
|
||||||
})
|
})
|
||||||
return expect(liquid.renderFile('hash.html')).to
|
const html = await liquid.renderFile('hash.html')
|
||||||
.eventually.equal('harttle : admin : harttle')
|
return expect(html).to.equal('harttle : admin : harttle')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support include: parent scope', function () {
|
it('should support include: parent scope', async function () {
|
||||||
mock({
|
mock({
|
||||||
'/scope.html': '{% assign shape="triangle" %}{% assign color="yellow" %}{% include "color.html" %}',
|
'/scope.html': '{% assign shape="triangle" %}{% assign color="yellow" %}{% include "color.html" %}',
|
||||||
'/color.html': 'color:{{color}}, shape:{{shape}}'
|
'/color.html': 'color:{{color}}, shape:{{shape}}'
|
||||||
})
|
})
|
||||||
return expect(liquid.renderFile('scope.html')).to
|
const html = await liquid.renderFile('scope.html')
|
||||||
.eventually.equal('color:yellow, shape:triangle')
|
return expect(html).to.equal('color:yellow, shape:triangle')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support include: with', function () {
|
it('should support include: with', async function () {
|
||||||
mock({
|
mock({
|
||||||
'/with.html': '{% include "color" with "red", shape: "rect" %}',
|
'/with.html': '{% include "color" with "red", shape: "rect" %}',
|
||||||
'/color.html': 'color:{{color}}, shape:{{shape}}'
|
'/color.html': 'color:{{color}}, shape:{{shape}}'
|
||||||
})
|
})
|
||||||
return expect(liquid.renderFile('with.html')).to
|
const html = await liquid.renderFile('with.html')
|
||||||
.eventually.equal('color:red, shape:rect')
|
return expect(html).to.equal('color:red, shape:rect')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support nested includes', function () {
|
it('should support nested includes', async function () {
|
||||||
mock({
|
mock({
|
||||||
'/personInfo.html': 'This is a person {% include "card.html" %}',
|
'/personInfo.html': 'This is a person {% include "card.html" %}',
|
||||||
'/card.html': '<p>{{person.firstName}} {{person.lastName}}<br/>{% include "address" %}</p>',
|
'/card.html': '<p>{{person.firstName}} {{person.lastName}}<br/>{% include "address" %}</p>',
|
||||||
@@ -104,49 +101,49 @@ describe('tags/include', function () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return expect(liquid.renderFile('personInfo.html', ctx)).to
|
const html = await liquid.renderFile('personInfo.html', ctx)
|
||||||
.eventually.equal('This is a person <p>Joe Shmoe<br/>City: Dallas</p>')
|
return expect(html).to.equal('This is a person <p>Joe Shmoe<br/>City: Dallas</p>')
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('static partial', function () {
|
describe('static partial', function () {
|
||||||
it('should support filename with extention', function () {
|
it('should support filename with extention', async function () {
|
||||||
mock({
|
mock({
|
||||||
'/parent.html': 'X{% include child.html color:"red" %}Y',
|
'/parent.html': 'X{% include child.html color:"red" %}Y',
|
||||||
'/child.html': 'child with {{color}}'
|
'/child.html': 'child with {{color}}'
|
||||||
})
|
})
|
||||||
const staticLiquid = new Liquid({ dynamicPartials: false, root: '/' })
|
const staticLiquid = new Liquid({ dynamicPartials: false, root: '/' })
|
||||||
return expect(staticLiquid.renderFile('parent.html')).to
|
const html = await staticLiquid.renderFile('parent.html')
|
||||||
.eventually.equal('Xchild with redY')
|
return expect(html).to.equal('Xchild with redY')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support parent paths', function () {
|
it('should support parent paths', async function () {
|
||||||
mock({
|
mock({
|
||||||
'/parent.html': 'X{% include bar/./../foo/child.html %}Y',
|
'/parent.html': 'X{% include bar/./../foo/child.html %}Y',
|
||||||
'/foo/child.html': 'child'
|
'/foo/child.html': 'child'
|
||||||
})
|
})
|
||||||
const staticLiquid = new Liquid({ dynamicPartials: false, root: '/' })
|
const staticLiquid = new Liquid({ dynamicPartials: false, root: '/' })
|
||||||
return expect(staticLiquid.renderFile('parent.html')).to
|
const html = await staticLiquid.renderFile('parent.html')
|
||||||
.eventually.equal('XchildY')
|
return expect(html).to.equal('XchildY')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support subpaths', function () {
|
it('should support subpaths', async function () {
|
||||||
mock({
|
mock({
|
||||||
'/parent.html': 'X{% include foo/child.html %}Y',
|
'/parent.html': 'X{% include foo/child.html %}Y',
|
||||||
'/foo/child.html': 'child'
|
'/foo/child.html': 'child'
|
||||||
})
|
})
|
||||||
const staticLiquid = new Liquid({ dynamicPartials: false, root: '/' })
|
const staticLiquid = new Liquid({ dynamicPartials: false, root: '/' })
|
||||||
return expect(staticLiquid.renderFile('parent.html')).to
|
const html = await staticLiquid.renderFile('parent.html')
|
||||||
.eventually.equal('XchildY')
|
return expect(html).to.equal('XchildY')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support comma separated arguments', function () {
|
it('should support comma separated arguments', async function () {
|
||||||
mock({
|
mock({
|
||||||
'/parent.html': 'X{% include child.html, color:"red" %}Y',
|
'/parent.html': 'X{% include child.html, color:"red" %}Y',
|
||||||
'/child.html': 'child with {{color}}'
|
'/child.html': 'child with {{color}}'
|
||||||
})
|
})
|
||||||
const staticLiquid = new Liquid({ dynamicPartials: false, root: '/' })
|
const staticLiquid = new Liquid({ dynamicPartials: false, root: '/' })
|
||||||
return expect(staticLiquid.renderFile('parent.html')).to
|
const html = await staticLiquid.renderFile('parent.html')
|
||||||
.eventually.equal('Xchild with redY')
|
return expect(html).to.equal('Xchild with redY')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
+22
-24
@@ -1,49 +1,47 @@
|
|||||||
import Liquid from 'src/liquid'
|
import Liquid from 'src/liquid'
|
||||||
import * as chai from 'chai'
|
import { expect, use } from 'chai'
|
||||||
|
import * as chaiAsPromised from 'chai-as-promised'
|
||||||
|
|
||||||
const expect = chai.expect
|
use(chaiAsPromised)
|
||||||
chai.use(require('chai-as-promised'))
|
|
||||||
|
|
||||||
describe('tags/increment', function () {
|
describe('tags/increment', function () {
|
||||||
const liquid = new Liquid()
|
const liquid = new Liquid()
|
||||||
|
|
||||||
it('should increment undefined variable', function () {
|
it('should increment undefined variable', async function () {
|
||||||
const src = '{% increment one %}{% increment one %}{% increment one %}'
|
const src = '{% increment one %}{% increment one %}{% increment one %}'
|
||||||
return expect(liquid.parseAndRender(src))
|
const html = await liquid.parseAndRender(src)
|
||||||
.to.eventually.equal('012')
|
return expect(html).to.equal('012')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should increment defined variable', function () {
|
it('should increment defined variable', async function () {
|
||||||
const src = '{% increment one %}{% increment one %}{% increment one %}'
|
const src = '{% increment one %}{% increment one %}{% increment one %}'
|
||||||
const ctx = { one: 7 }
|
const ctx = { one: 7 }
|
||||||
return liquid.parseAndRender(src, ctx)
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
.then(x => {
|
expect(html).to.equal('789')
|
||||||
expect(x).to.equal('789')
|
expect(ctx.one).to.equal(10)
|
||||||
expect(ctx.one).to.equal(10)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should be independent from assign', function () {
|
it('should be independent from assign', async function () {
|
||||||
const src = '{% assign var=10 %}{% increment var %}{% increment var %}{% increment var %}'
|
const src = '{% assign var=10 %}{% increment var %}{% increment var %}{% increment var %}'
|
||||||
return expect(liquid.parseAndRender(src))
|
const html = await liquid.parseAndRender(src)
|
||||||
.to.eventually.equal('012')
|
return expect(html).to.equal('012')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should be independent from capture', function () {
|
it('should be independent from capture', async function () {
|
||||||
const src = '{% capture var %}10{% endcapture %}{% increment var %}{% increment var %}{% increment var %}'
|
const src = '{% capture var %}10{% endcapture %}{% increment var %}{% increment var %}{% increment var %}'
|
||||||
return expect(liquid.parseAndRender(src))
|
const html = await liquid.parseAndRender(src)
|
||||||
.to.eventually.equal('012')
|
return expect(html).to.equal('012')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should not shading assign', function () {
|
it('should not shading assign', async function () {
|
||||||
const src = '{% assign var=10 %}{% increment var %}{% increment var %}{% increment var %} {{var}}'
|
const src = '{% assign var=10 %}{% increment var %}{% increment var %}{% increment var %} {{var}}'
|
||||||
return expect(liquid.parseAndRender(src))
|
const html = await liquid.parseAndRender(src)
|
||||||
.to.eventually.equal('012 10')
|
return expect(html).to.equal('012 10')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should not shading capture', function () {
|
it('should not shading capture', async function () {
|
||||||
const src = '{% capture var %}10{% endcapture %}{% increment var %}{% increment var %}{% increment var %} {{var}}'
|
const src = '{% capture var %}10{% endcapture %}{% increment var %}{% increment var %}{% increment var %} {{var}}'
|
||||||
return expect(liquid.parseAndRender(src))
|
const html = await liquid.parseAndRender(src)
|
||||||
.to.eventually.equal('012 10')
|
return expect(html).to.equal('012 10')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
+34
-37
@@ -1,9 +1,6 @@
|
|||||||
import Liquid from 'src/liquid'
|
import Liquid from 'src/liquid'
|
||||||
|
import { expect } from 'chai'
|
||||||
import * as mock from 'mock-fs'
|
import * as mock from 'mock-fs'
|
||||||
import * as chai from 'chai'
|
|
||||||
|
|
||||||
const expect = chai.expect
|
|
||||||
chai.use(require('chai-as-promised'))
|
|
||||||
|
|
||||||
describe('tags/layout', function () {
|
describe('tags/layout', function () {
|
||||||
let liquid
|
let liquid
|
||||||
@@ -35,51 +32,51 @@ describe('tags/layout', function () {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('anonymous block', function () {
|
describe('anonymous block', function () {
|
||||||
it('should handle anonymous block', function () {
|
it('should handle anonymous block', async function () {
|
||||||
mock({
|
mock({
|
||||||
'/parent.html': 'X{%block%}{%endblock%}Y'
|
'/parent.html': 'X{%block%}{%endblock%}Y'
|
||||||
})
|
})
|
||||||
const src = '{% layout "parent.html" %}{%block%}A{%endblock%}'
|
const src = '{% layout "parent.html" %}{%block%}A{%endblock%}'
|
||||||
return expect(liquid.parseAndRender(src)).to
|
const html = await liquid.parseAndRender(src)
|
||||||
.eventually.equal('XAY')
|
return expect(html).to.equal('XAY')
|
||||||
})
|
})
|
||||||
it('should handle top level contents as anonymous block', function () {
|
it('should handle top level contents as anonymous block', async function () {
|
||||||
mock({
|
mock({
|
||||||
'/parent.html': 'X{%block%}{%endblock%}Y'
|
'/parent.html': 'X{%block%}{%endblock%}Y'
|
||||||
})
|
})
|
||||||
const src = '{% layout "parent.html" %}A'
|
const src = '{% layout "parent.html" %}A'
|
||||||
return expect(liquid.parseAndRender(src)).to
|
const html = await liquid.parseAndRender(src)
|
||||||
.eventually.equal('XAY')
|
return expect(html).to.equal('XAY')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
it('should handle named blocks', function () {
|
it('should handle named blocks', async function () {
|
||||||
mock({
|
mock({
|
||||||
'/parent.html': 'X{% block "a"%}{% endblock %}Y{% block b%}{%endblock%}Z'
|
'/parent.html': 'X{% block "a"%}{% endblock %}Y{% block b%}{%endblock%}Z'
|
||||||
})
|
})
|
||||||
const src = '{% layout "parent.html" %}' +
|
const src = '{% layout "parent.html" %}' +
|
||||||
'{%block a%}A{%endblock%}' +
|
'{%block a%}A{%endblock%}' +
|
||||||
'{%block b%}B{%endblock%}'
|
'{%block b%}B{%endblock%}'
|
||||||
return expect(liquid.parseAndRender(src)).to
|
const html = await liquid.parseAndRender(src)
|
||||||
.eventually.equal('XAYBZ')
|
return expect(html).to.equal('XAYBZ')
|
||||||
})
|
})
|
||||||
it('should support default block content', function () {
|
it('should support default block content', async function () {
|
||||||
mock({
|
mock({
|
||||||
'/parent.html': 'X{% block "a"%}A{% endblock %}Y{% block b%}B{%endblock%}Z'
|
'/parent.html': 'X{% block "a"%}A{% endblock %}Y{% block b%}B{%endblock%}Z'
|
||||||
})
|
})
|
||||||
const src = '{% layout "parent.html" %}{%block a%}a{%endblock%}'
|
const src = '{% layout "parent.html" %}{%block a%}a{%endblock%}'
|
||||||
return expect(liquid.parseAndRender(src)).to
|
const html = await liquid.parseAndRender(src)
|
||||||
.eventually.equal('XaYBZ')
|
return expect(html).to.equal('XaYBZ')
|
||||||
})
|
})
|
||||||
it('should handle nested block', function () {
|
it('should handle nested block', async function () {
|
||||||
mock({
|
mock({
|
||||||
'/grand.html': 'X{%block a%}G{%endblock%}Y',
|
'/grand.html': 'X{%block a%}G{%endblock%}Y',
|
||||||
'/parent.html': '{%layout "grand" %}{%block a%}P{%endblock%}',
|
'/parent.html': '{%layout "grand" %}{%block a%}P{%endblock%}',
|
||||||
'/main.html': '{%layout "parent"%}{%block a%}A{%endblock%}'
|
'/main.html': '{%layout "parent"%}{%block a%}A{%endblock%}'
|
||||||
})
|
})
|
||||||
return expect(liquid.renderFile('/main.html')).to
|
const html = await liquid.renderFile('/main.html')
|
||||||
.eventually.equal('XAY')
|
return expect(html).to.equal('XAY')
|
||||||
})
|
})
|
||||||
it('should not bleed scope into included layout', function () {
|
it('should not bleed scope into included layout', async function () {
|
||||||
mock({
|
mock({
|
||||||
'/parent.html': 'X{%block a%}{%endblock%}Y{%block b%}{%endblock%}Z',
|
'/parent.html': 'X{%block a%}{%endblock%}Y{%block b%}{%endblock%}Z',
|
||||||
'/main.html': '{%layout "parent"%}' +
|
'/main.html': '{%layout "parent"%}' +
|
||||||
@@ -87,55 +84,55 @@ describe('tags/layout', function () {
|
|||||||
'{%block b%}I{%include "included"%}J{%endblock%}',
|
'{%block b%}I{%include "included"%}J{%endblock%}',
|
||||||
'/included.html': '{%layout "parent"%}{%block a%}a{%endblock%}'
|
'/included.html': '{%layout "parent"%}{%block a%}a{%endblock%}'
|
||||||
})
|
})
|
||||||
return expect(liquid.renderFile('main')).to
|
const html = await liquid.renderFile('main')
|
||||||
.eventually.equal('XAYIXaYZJZ')
|
return expect(html).to.equal('XAYIXaYZJZ')
|
||||||
})
|
})
|
||||||
it('should support hash list', function () {
|
it('should support hash list', async function () {
|
||||||
mock({
|
mock({
|
||||||
'/parent.html': '{{color}}{%block%}{%endblock%}',
|
'/parent.html': '{{color}}{%block%}{%endblock%}',
|
||||||
'/main.html': '{% layout "parent.html" color:"black"%}{%block%}A{%endblock%}'
|
'/main.html': '{% layout "parent.html" color:"black"%}{%block%}A{%endblock%}'
|
||||||
})
|
})
|
||||||
return expect(liquid.renderFile('/main.html')).to
|
const html = await liquid.renderFile('/main.html')
|
||||||
.eventually.equal('blackA')
|
return expect(html).to.equal('blackA')
|
||||||
})
|
})
|
||||||
it('should support multiple hash', function () {
|
it('should support multiple hash', async function () {
|
||||||
mock({
|
mock({
|
||||||
'/parent.html': '{{color}}{{bg}}{%block%}{%endblock%}',
|
'/parent.html': '{{color}}{{bg}}{%block%}{%endblock%}',
|
||||||
'/main.html': '{% layout "parent.html" color:"black", bg:"red"%}{%block%}A{%endblock%}'
|
'/main.html': '{% layout "parent.html" color:"black", bg:"red"%}{%block%}A{%endblock%}'
|
||||||
})
|
})
|
||||||
return expect(liquid.renderFile('/main.html')).to
|
const html = await liquid.renderFile('/main.html')
|
||||||
.eventually.equal('blackredA')
|
return expect(html).to.equal('blackredA')
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('static partial', function () {
|
describe('static partial', function () {
|
||||||
it('should support filename with extention', function () {
|
it('should support filename with extention', async function () {
|
||||||
mock({
|
mock({
|
||||||
'/parent.html': '{{color}}{%block%}{%endblock%}',
|
'/parent.html': '{{color}}{%block%}{%endblock%}',
|
||||||
'/main.html': '{% layout parent.html color:"black"%}{%block%}A{%endblock%}'
|
'/main.html': '{% layout parent.html color:"black"%}{%block%}A{%endblock%}'
|
||||||
})
|
})
|
||||||
const staticLiquid = new Liquid({ root: '/', dynamicPartials: false })
|
const staticLiquid = new Liquid({ root: '/', dynamicPartials: false })
|
||||||
return expect(staticLiquid.renderFile('/main.html')).to
|
const html = await staticLiquid.renderFile('/main.html')
|
||||||
.eventually.equal('blackA')
|
return expect(html).to.equal('blackA')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support parent paths', function () {
|
it('should support parent paths', async function () {
|
||||||
mock({
|
mock({
|
||||||
'/foo/parent.html': '{{color}}{%block%}{%endblock%}',
|
'/foo/parent.html': '{{color}}{%block%}{%endblock%}',
|
||||||
'/main.html': '{% layout bar/../foo/parent.html color:"black"%}{%block%}A{%endblock%}'
|
'/main.html': '{% layout bar/../foo/parent.html color:"black"%}{%block%}A{%endblock%}'
|
||||||
})
|
})
|
||||||
const staticLiquid = new Liquid({ root: '/', dynamicPartials: false })
|
const staticLiquid = new Liquid({ root: '/', dynamicPartials: false })
|
||||||
return expect(staticLiquid.renderFile('/main.html')).to
|
const html = await staticLiquid.renderFile('/main.html')
|
||||||
.eventually.equal('blackA')
|
return expect(html).to.equal('blackA')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support subpaths', function () {
|
it('should support subpaths', async function () {
|
||||||
mock({
|
mock({
|
||||||
'/foo/parent.html': '{{color}}{%block%}{%endblock%}',
|
'/foo/parent.html': '{{color}}{%block%}{%endblock%}',
|
||||||
'/main.html': '{% layout foo/parent.html color:"black"%}{%block%}A{%endblock%}'
|
'/main.html': '{% layout foo/parent.html color:"black"%}{%block%}A{%endblock%}'
|
||||||
})
|
})
|
||||||
const staticLiquid = new Liquid({ root: '/', dynamicPartials: false })
|
const staticLiquid = new Liquid({ root: '/', dynamicPartials: false })
|
||||||
return expect(staticLiquid.renderFile('/main.html')).to
|
const html = await staticLiquid.renderFile('/main.html')
|
||||||
.eventually.equal('blackA')
|
return expect(html).to.equal('blackA')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
import Liquid from 'src/liquid'
|
import Liquid from 'src/liquid'
|
||||||
import * as chai from 'chai'
|
import { expect } from 'chai'
|
||||||
|
|
||||||
const expect = chai.expect
|
|
||||||
chai.use(require('chai-as-promised'))
|
|
||||||
|
|
||||||
describe('tags/raw', function () {
|
describe('tags/raw', function () {
|
||||||
const liquid = new Liquid()
|
const liquid = new Liquid()
|
||||||
@@ -13,11 +10,13 @@ describe('tags/raw', function () {
|
|||||||
it('should support raw 2', async function () {
|
it('should support raw 2', async function () {
|
||||||
const src = '{% raw %}{{ 5 | plus: 6 }}{% endraw %} is equal to 11.'
|
const src = '{% raw %}{{ 5 | plus: 6 }}{% endraw %} is equal to 11.'
|
||||||
const dst = '{{ 5 | plus: 6 }} is equal to 11.'
|
const dst = '{{ 5 | plus: 6 }} is equal to 11.'
|
||||||
return expect(liquid.parseAndRender(src)).to.eventually.equal(dst)
|
const html = await liquid.parseAndRender(src)
|
||||||
|
return expect(html).to.equal(dst)
|
||||||
})
|
})
|
||||||
it('should support raw 3', function () {
|
it('should support raw 3', async function () {
|
||||||
const src = '{% raw %}\n{{ foo}} \n{% endraw %}'
|
const src = '{% raw %}\n{{ foo}} \n{% endraw %}'
|
||||||
const dst = '\n{{ foo}} \n'
|
const dst = '\n{{ foo}} \n'
|
||||||
return expect(liquid.parseAndRender(src)).to.eventually.equal(dst)
|
const html = await liquid.parseAndRender(src)
|
||||||
|
return expect(html).to.equal(dst)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
+25
-20
@@ -1,19 +1,17 @@
|
|||||||
import Liquid from 'src/liquid'
|
import Liquid from 'src/liquid'
|
||||||
import * as chai from 'chai'
|
import { expect } from 'chai'
|
||||||
|
|
||||||
const expect = chai.expect
|
|
||||||
chai.use(require('chai-as-promised'))
|
|
||||||
|
|
||||||
describe('tags/tablerow', function () {
|
describe('tags/tablerow', function () {
|
||||||
const liquid = new Liquid()
|
const liquid = new Liquid()
|
||||||
|
|
||||||
it('should support tablerow', function () {
|
it('should support tablerow', async function () {
|
||||||
const src = '{% tablerow i in (1..3)%}{{ i }}{% endtablerow %}'
|
const src = '{% tablerow i in (1..3)%}{{ i }}{% endtablerow %}'
|
||||||
const dst = '<tr class="row1"><td class="col1">1</td><td class="col2">2</td><td class="col3">3</td></tr>'
|
const dst = '<tr class="row1"><td class="col1">1</td><td class="col2">2</td><td class="col3">3</td></tr>'
|
||||||
return expect(liquid.parseAndRender(src)).to.eventually.equal(dst)
|
const html = await liquid.parseAndRender(src)
|
||||||
|
return expect(html).to.equal(dst)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support cols', function () {
|
it('should support cols', async function () {
|
||||||
const src = '{% tablerow i in alpha cols:2 %}{{ i }}{% endtablerow %}'
|
const src = '{% tablerow i in alpha cols:2 %}{{ i }}{% endtablerow %}'
|
||||||
const ctx = {
|
const ctx = {
|
||||||
alpha: ['a', 'b', 'c']
|
alpha: ['a', 'b', 'c']
|
||||||
@@ -21,25 +19,29 @@ describe('tags/tablerow', function () {
|
|||||||
const dst =
|
const dst =
|
||||||
'<tr class="row1"><td class="col1">a</td><td class="col2">b</td></tr>' +
|
'<tr class="row1"><td class="col1">a</td><td class="col2">b</td></tr>' +
|
||||||
'<tr class="row2"><td class="col1">c</td></tr>'
|
'<tr class="row2"><td class="col1">c</td></tr>'
|
||||||
return expect(liquid.parseAndRender(src, ctx)).to.eventually.equal(dst)
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
|
return expect(html).to.equal(dst)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support cols set to 0', function () {
|
it('should support cols set to 0', async function () {
|
||||||
const src = '{% tablerow i in (1..3) cols:0 %}{{ i }}{% endtablerow %}'
|
const src = '{% tablerow i in (1..3) cols:0 %}{{ i }}{% endtablerow %}'
|
||||||
const dst = '<tr class="row1"><td class="col1">1</td><td class="col2">2</td><td class="col3">3</td></tr>'
|
const dst = '<tr class="row1"><td class="col1">1</td><td class="col2">2</td><td class="col3">3</td></tr>'
|
||||||
return expect(liquid.parseAndRender(src)).to.eventually.equal(dst)
|
const html = await liquid.parseAndRender(src)
|
||||||
|
return expect(html).to.equal(dst)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support empty tablerow', function () {
|
it('should support empty tablerow', async function () {
|
||||||
const src = '{% tablerow i in (1..0) cols:2 %}{{ i }}{% endtablerow %}'
|
const src = '{% tablerow i in (1..0) cols:2 %}{{ i }}{% endtablerow %}'
|
||||||
const dst = ''
|
const dst = ''
|
||||||
return expect(liquid.parseAndRender(src)).to.eventually.equal(dst)
|
const html = await liquid.parseAndRender(src)
|
||||||
|
return expect(html).to.equal(dst)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support empty array', function () {
|
it('should support empty array', async function () {
|
||||||
const src = '{% tablerow i in alpha.z cols:2 %}{{ i }}{% endtablerow %}'
|
const src = '{% tablerow i in alpha.z cols:2 %}{{ i }}{% endtablerow %}'
|
||||||
const dst = ''
|
const dst = ''
|
||||||
return expect(liquid.parseAndRender(src)).to.eventually.equal(dst)
|
const html = await liquid.parseAndRender(src)
|
||||||
|
return expect(html).to.equal(dst)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should throw when tablerow not closed', function () {
|
it('should throw when tablerow not closed', function () {
|
||||||
@@ -48,26 +50,29 @@ describe('tags/tablerow', function () {
|
|||||||
.to.be.rejectedWith(/tag .* not closed/)
|
.to.be.rejectedWith(/tag .* not closed/)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support tablerow with range', function () {
|
it('should support tablerow with range', async function () {
|
||||||
const src = '{% tablerow i in (1..5) cols:2 %}{{ i }}{% endtablerow %}'
|
const src = '{% tablerow i in (1..5) cols:2 %}{{ i }}{% endtablerow %}'
|
||||||
const dst =
|
const dst =
|
||||||
'<tr class="row1"><td class="col1">1</td><td class="col2">2</td></tr>' +
|
'<tr class="row1"><td class="col1">1</td><td class="col2">2</td></tr>' +
|
||||||
'<tr class="row2"><td class="col1">3</td><td class="col2">4</td></tr>' +
|
'<tr class="row2"><td class="col1">3</td><td class="col2">4</td></tr>' +
|
||||||
'<tr class="row3"><td class="col1">5</td></tr>'
|
'<tr class="row3"><td class="col1">5</td></tr>'
|
||||||
return expect(liquid.parseAndRender(src)).to.eventually.equal(dst)
|
const html = await liquid.parseAndRender(src)
|
||||||
|
return expect(html).to.equal(dst)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support tablerow with limit', function () {
|
it('should support tablerow with limit', async function () {
|
||||||
const src = '{% tablerow i in (1..5) cols:2 limit:3 %}{{ i }}{% endtablerow %}'
|
const src = '{% tablerow i in (1..5) cols:2 limit:3 %}{{ i }}{% endtablerow %}'
|
||||||
const dst =
|
const dst =
|
||||||
'<tr class="row1"><td class="col1">1</td><td class="col2">2</td></tr>' +
|
'<tr class="row1"><td class="col1">1</td><td class="col2">2</td></tr>' +
|
||||||
'<tr class="row2"><td class="col1">3</td></tr>'
|
'<tr class="row2"><td class="col1">3</td></tr>'
|
||||||
return expect(liquid.parseAndRender(src)).to.eventually.equal(dst)
|
const html = await liquid.parseAndRender(src)
|
||||||
|
return expect(html).to.equal(dst)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support tablerow with offset', function () {
|
it('should support tablerow with offset', async function () {
|
||||||
const src = '{% tablerow i in (1..5) cols:2 offset:3 %}{{ i }}{% endtablerow %}'
|
const src = '{% tablerow i in (1..5) cols:2 offset:3 %}{{ i }}{% endtablerow %}'
|
||||||
const dst = '<tr class="row1"><td class="col1">4</td><td class="col2">5</td></tr>'
|
const dst = '<tr class="row1"><td class="col1">4</td><td class="col2">5</td></tr>'
|
||||||
return expect(liquid.parseAndRender(src)).to.eventually.equal(dst)
|
const html = await liquid.parseAndRender(src)
|
||||||
|
return expect(html).to.equal(dst)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
+15
-15
@@ -1,37 +1,37 @@
|
|||||||
import Liquid from 'src/liquid'
|
import Liquid from 'src/liquid'
|
||||||
import * as chai from 'chai'
|
import { expect, use } from 'chai'
|
||||||
|
import * as chaiAsPromised from 'chai-as-promised'
|
||||||
|
|
||||||
const expect = chai.expect
|
use(chaiAsPromised)
|
||||||
chai.use(require('chai-as-promised'))
|
|
||||||
|
|
||||||
describe('tags/unless', function () {
|
describe('tags/unless', function () {
|
||||||
let liquid
|
let liquid
|
||||||
before(() => { liquid = new Liquid() })
|
before(() => { liquid = new Liquid() })
|
||||||
|
|
||||||
it('should render else when predicate yields true', function () {
|
it('should render else when predicate yields true', async function () {
|
||||||
// 0 is truthy
|
// 0 is truthy
|
||||||
const src = '{% unless 0 %}yes{%else%}no{%endunless%}'
|
const src = '{% unless 0 %}yes{%else%}no{%endunless%}'
|
||||||
return expect(liquid.parseAndRender(src))
|
const html = await liquid.parseAndRender(src)
|
||||||
.to.eventually.equal('no')
|
return expect(html).to.equal('no')
|
||||||
})
|
})
|
||||||
it('should render unless when predicate yields false', function () {
|
it('should render unless when predicate yields false', async function () {
|
||||||
const src = '{% unless false %}yes{%else%}no{%endunless%}'
|
const src = '{% unless false %}yes{%else%}no{%endunless%}'
|
||||||
return expect(liquid.parseAndRender(src))
|
const html = await liquid.parseAndRender(src)
|
||||||
.to.eventually.equal('yes')
|
return expect(html).to.equal('yes')
|
||||||
})
|
})
|
||||||
it('should reject when tag not closed', function () {
|
it('should reject when tag not closed', function () {
|
||||||
const src = '{% unless 1>2 %}yes'
|
const src = '{% unless 1>2 %}yes'
|
||||||
return expect(liquid.parseAndRender(src))
|
return expect(liquid.parseAndRender(src))
|
||||||
.to.be.rejectedWith(/tag {% unless 1>2 %} not closed/)
|
.to.be.rejectedWith(/tag {% unless 1>2 %} not closed/)
|
||||||
})
|
})
|
||||||
it('should render unless when predicate yields false and else undefined', function () {
|
it('should render unless when predicate yields false and else undefined', async function () {
|
||||||
const src = '{% unless 1>2 %}yes{%endunless%}'
|
const src = '{% unless 1>2 %}yes{%endunless%}'
|
||||||
return expect(liquid.parseAndRender(src))
|
const html = await liquid.parseAndRender(src)
|
||||||
.to.eventually.equal('yes')
|
return expect(html).to.equal('yes')
|
||||||
})
|
})
|
||||||
it('should render "" when predicate yields false and else undefined', function () {
|
it('should render "" when predicate yields false and else undefined', async function () {
|
||||||
const src = '{% unless 1<2 %}yes{%endunless%}'
|
const src = '{% unless 1<2 %}yes{%endunless%}'
|
||||||
return expect(liquid.parseAndRender(src))
|
const html = await liquid.parseAndRender(src)
|
||||||
.to.eventually.equal('')
|
return expect(html).to.equal('')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import { resolve } from '../../src/parser/template-browser'
|
import { resolve } from '../../src/parser/template-browser'
|
||||||
import * as chai from 'chai'
|
import { expect } from 'chai'
|
||||||
|
|
||||||
const expect = chai.expect
|
|
||||||
|
|
||||||
describe('template-browser', function () {
|
describe('template-browser', function () {
|
||||||
if (+process.version.match(/^v(\d+)/)[1] < 8) {
|
if (+process.version.match(/^v(\d+)/)[1] < 8) {
|
||||||
|
|||||||
@@ -1,11 +1,7 @@
|
|||||||
import { resolve } from '../../src/parser/template'
|
import { resolve } from '../../src/parser/template'
|
||||||
import * as mock from 'mock-fs'
|
import * as mock from 'mock-fs'
|
||||||
import * as chai from 'chai'
|
import { expect } from 'chai'
|
||||||
import * as path from 'path'
|
import * as path from 'path'
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
|
|
||||||
const expect = chai.expect
|
|
||||||
chai.use(chaiAsPromised)
|
|
||||||
|
|
||||||
describe('template', function () {
|
describe('template', function () {
|
||||||
before(function () {
|
before(function () {
|
||||||
@@ -14,10 +10,10 @@ describe('template', function () {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('#resolve()', function () {
|
describe('#resolve()', function () {
|
||||||
it('should resolve based on root', function () {
|
it('should resolve based on root', async function () {
|
||||||
const filepath = resolve('bar.html', '/foo', { root: [] })
|
const filepath = await resolve('bar.html', '/foo', { root: [] })
|
||||||
const expected = path.resolve('/foo/bar.html')
|
const expected = path.resolve('/foo/bar.html')
|
||||||
return expect(filepath).to.eventually.equal(expected)
|
return expect(filepath).to.equal(expected)
|
||||||
})
|
})
|
||||||
it('should resolve based on root', function () {
|
it('should resolve based on root', function () {
|
||||||
return expect(resolve('foo.html', '/foo', { root: [] }))
|
return expect(resolve('foo.html', '/foo', { root: [] }))
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
import { expect } from 'chai'
|
import { expect } from 'chai'
|
||||||
import { parse } from 'src/parser/tokenizer'
|
import Tokenizer from 'src/parser/tokenizer'
|
||||||
import TagToken from 'src/parser/tag-token'
|
import TagToken from 'src/parser/tag-token'
|
||||||
import OutputToken from 'src/parser/output-token'
|
import OutputToken from 'src/parser/output-token'
|
||||||
import HTMLToken from 'src/parser/html-token'
|
import HTMLToken from 'src/parser/html-token'
|
||||||
|
|
||||||
describe('tokenizer', function () {
|
describe('tokenizer', function () {
|
||||||
|
const tokenizer = new Tokenizer()
|
||||||
describe('parse', function () {
|
describe('parse', function () {
|
||||||
it('should handle plain HTML', function () {
|
it('should handle plain HTML', function () {
|
||||||
const html = '<html><body><p>Lorem Ipsum</p></body></html>'
|
const html = '<html><body><p>Lorem Ipsum</p></body></html>'
|
||||||
const tokens = parse(html)
|
const tokens = tokenizer.tokenize(html)
|
||||||
|
|
||||||
expect(tokens.length).to.equal(1)
|
expect(tokens.length).to.equal(1)
|
||||||
expect(tokens[0].value).to.equal(html)
|
expect(tokens[0].value).to.equal(html)
|
||||||
@@ -16,7 +17,7 @@ describe('tokenizer', function () {
|
|||||||
})
|
})
|
||||||
it('should handle tag syntax', function () {
|
it('should handle tag syntax', function () {
|
||||||
const html = '<p>{% for p in a[1]%}</p>'
|
const html = '<p>{% for p in a[1]%}</p>'
|
||||||
const tokens = parse(html)
|
const tokens = tokenizer.tokenize(html)
|
||||||
|
|
||||||
expect(tokens.length).to.equal(3)
|
expect(tokens.length).to.equal(3)
|
||||||
expect(tokens[1]).instanceOf(TagToken)
|
expect(tokens[1]).instanceOf(TagToken)
|
||||||
@@ -24,7 +25,7 @@ describe('tokenizer', function () {
|
|||||||
})
|
})
|
||||||
it('should handle value syntax', function () {
|
it('should handle value syntax', function () {
|
||||||
const html = '<p>{{foo | date: "%Y-%m-%d"}}</p>'
|
const html = '<p>{{foo | date: "%Y-%m-%d"}}</p>'
|
||||||
const tokens = parse(html)
|
const tokens = tokenizer.tokenize(html)
|
||||||
|
|
||||||
expect(tokens.length).to.equal(3)
|
expect(tokens.length).to.equal(3)
|
||||||
expect(tokens[1]).instanceOf(OutputToken)
|
expect(tokens[1]).instanceOf(OutputToken)
|
||||||
@@ -32,7 +33,7 @@ describe('tokenizer', function () {
|
|||||||
})
|
})
|
||||||
it('should handle consecutive value and tags', function () {
|
it('should handle consecutive value and tags', function () {
|
||||||
const html = '{{foo}}{{bar}}{%foo%}{%bar%}'
|
const html = '{{foo}}{{bar}}{%foo%}{%bar%}'
|
||||||
const tokens = parse(html)
|
const tokens = tokenizer.tokenize(html)
|
||||||
|
|
||||||
expect(tokens.length).to.equal(4)
|
expect(tokens.length).to.equal(4)
|
||||||
expect(tokens[0]).instanceOf(OutputToken)
|
expect(tokens[0]).instanceOf(OutputToken)
|
||||||
@@ -43,7 +44,7 @@ describe('tokenizer', function () {
|
|||||||
})
|
})
|
||||||
it('should keep white spaces and newlines', function () {
|
it('should keep white spaces and newlines', function () {
|
||||||
const html = '{%foo%}\n{%bar %} \n {%alice%}'
|
const html = '{%foo%}\n{%bar %} \n {%alice%}'
|
||||||
const tokens = parse(html)
|
const tokens = tokenizer.tokenize(html)
|
||||||
expect(tokens.length).to.equal(5)
|
expect(tokens.length).to.equal(5)
|
||||||
expect(tokens[1]).instanceOf(HTMLToken)
|
expect(tokens[1]).instanceOf(HTMLToken)
|
||||||
expect(tokens[1].raw).to.equal('\n')
|
expect(tokens[1].raw).to.equal('\n')
|
||||||
@@ -52,7 +53,7 @@ describe('tokenizer', function () {
|
|||||||
})
|
})
|
||||||
it('should handle multiple lines tag', function () {
|
it('should handle multiple lines tag', function () {
|
||||||
const html = '{%foo\na:a\nb:1.23\n%}'
|
const html = '{%foo\na:a\nb:1.23\n%}'
|
||||||
const tokens = parse(html)
|
const tokens = tokenizer.tokenize(html)
|
||||||
expect(tokens.length).to.equal(1)
|
expect(tokens.length).to.equal(1)
|
||||||
expect(tokens[0]).instanceOf(TagToken)
|
expect(tokens[0]).instanceOf(TagToken)
|
||||||
expect(tokens[0].args).to.equal('a:a\nb:1.23')
|
expect(tokens[0].args).to.equal('a:a\nb:1.23')
|
||||||
@@ -60,7 +61,7 @@ describe('tokenizer', function () {
|
|||||||
})
|
})
|
||||||
it('should handle multiple lines value', function () {
|
it('should handle multiple lines value', function () {
|
||||||
const html = '{{foo\n|date:\n"%Y-%m-%d"\n}}'
|
const html = '{{foo\n|date:\n"%Y-%m-%d"\n}}'
|
||||||
const tokens = parse(html)
|
const tokens = tokenizer.tokenize(html)
|
||||||
expect(tokens.length).to.equal(1)
|
expect(tokens.length).to.equal(1)
|
||||||
expect(tokens[0]).instanceOf(OutputToken)
|
expect(tokens[0]).instanceOf(OutputToken)
|
||||||
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}}')
|
||||||
|
|||||||
@@ -1,11 +1,8 @@
|
|||||||
import Liquid from '../../../src/liquid'
|
import { expect } from 'chai'
|
||||||
|
import Liquid from 'src/liquid'
|
||||||
import * as mock from 'mock-fs'
|
import * as mock from 'mock-fs'
|
||||||
import * as chai from 'chai'
|
|
||||||
import * as path from 'path'
|
import * as path from 'path'
|
||||||
|
|
||||||
const expect = chai.expect
|
|
||||||
chai.use(require('chai-as-promised'))
|
|
||||||
|
|
||||||
let engine = new Liquid()
|
let engine = new Liquid()
|
||||||
const strictEngine = new Liquid({
|
const strictEngine = new Liquid({
|
||||||
strict_variables: true,
|
strict_variables: true,
|
||||||
@@ -111,8 +108,9 @@ describe('error', function () {
|
|||||||
expect(err.name).to.equal('RenderError')
|
expect(err.name).to.equal('RenderError')
|
||||||
expect(err.message).to.contain('throwed by filter')
|
expect(err.message).to.contain('throwed by filter')
|
||||||
})
|
})
|
||||||
it('should not throw when variable undefined by default', function () {
|
it('should not throw when variable undefined by default', async function () {
|
||||||
return expect(engine.parseAndRender('X{{a}}Y')).to.eventually.equal('XY')
|
const html = await engine.parseAndRender('X{{a}}Y')
|
||||||
|
return expect(html).to.equal('XY')
|
||||||
})
|
})
|
||||||
it('should throw RenderError when variable not defined', async function () {
|
it('should throw RenderError when variable not defined', async function () {
|
||||||
const err = await expect(strictEngine.parseAndRender('{{a}}')).be.rejected
|
const err = await expect(strictEngine.parseAndRender('{{a}}')).be.rejected
|
||||||
|
|||||||
+18
-13
@@ -1,8 +1,9 @@
|
|||||||
const chai = require('chai')
|
import * as chai from 'chai'
|
||||||
const sinon = require('sinon')
|
import * as sinon from 'sinon'
|
||||||
|
import * as sinonChai from 'sinon-chai'
|
||||||
|
|
||||||
const expect = chai.expect
|
const expect = chai.expect
|
||||||
chai.use(require('chai-as-promised'))
|
chai.use(sinonChai)
|
||||||
chai.use(require('sinon-chai'))
|
|
||||||
|
|
||||||
const P = require('../../../src/util/promise')
|
const P = require('../../../src/util/promise')
|
||||||
|
|
||||||
@@ -32,10 +33,12 @@ describe('util/promise', function () {
|
|||||||
item => Promise.reject(new Error(item)))
|
item => Promise.reject(new Error(item)))
|
||||||
return expect(p).to.be.rejectedWith('third')
|
return expect(p).to.be.rejectedWith('third')
|
||||||
})
|
})
|
||||||
it('should resolve the value that first callback resolved', () => {
|
it('should resolve the value that first callback resolved', async () => {
|
||||||
const p = P.anySeries(['first', 'second'],
|
const result = await P.anySeries(
|
||||||
item => Promise.resolve(item))
|
['first', 'second'],
|
||||||
return expect(p).to.eventually.equal('first')
|
item => Promise.resolve(item)
|
||||||
|
)
|
||||||
|
return expect(result).to.equal('first')
|
||||||
})
|
})
|
||||||
it('should not call rest of callbacks once resolved', () => {
|
it('should not call rest of callbacks once resolved', () => {
|
||||||
const spy = sinon.spy()
|
const spy = sinon.spy()
|
||||||
@@ -50,10 +53,12 @@ describe('util/promise', function () {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('.mapSeries()', function () {
|
describe('.mapSeries()', function () {
|
||||||
it('should resolve when all resolved', function () {
|
it('should resolve when all resolved', async function () {
|
||||||
const p = P.mapSeries(['first', 'second', 'third'],
|
const result = P.mapSeries(
|
||||||
item => Promise.resolve(item))
|
['first', 'second', 'third'],
|
||||||
return expect(p).to.eventually.deep.equal(['first', 'second', 'third'])
|
item => Promise.resolve(item)
|
||||||
|
)
|
||||||
|
return expect(result).to.deep.equal(['first', 'second', 'third'])
|
||||||
})
|
})
|
||||||
it('should reject with the error that first callback rejected', () => {
|
it('should reject with the error that first callback rejected', () => {
|
||||||
const p = P.mapSeries(['first', 'second'],
|
const p = P.mapSeries(['first', 'second'],
|
||||||
@@ -66,7 +71,7 @@ describe('util/promise', function () {
|
|||||||
return P
|
return P
|
||||||
.mapSeries(
|
.mapSeries(
|
||||||
['first', 'second'],
|
['first', 'second'],
|
||||||
(item, idx) => new Promise(function (resolve, reject) {
|
(item, idx) => new Promise(function (resolve) {
|
||||||
if (idx === 0) {
|
if (idx === 0) {
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
spy1()
|
spy1()
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import * as chai from 'chai'
|
import * as chai from 'chai'
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
import * as sinonChai from 'sinon-chai'
|
import * as sinonChai from 'sinon-chai'
|
||||||
import * as sinon from 'sinon'
|
import * as sinon from 'sinon'
|
||||||
import Scope from '../../src/scope/scope'
|
import Scope from '../../src/scope/scope'
|
||||||
@@ -7,7 +6,6 @@ import Filter from 'src/template/filter'
|
|||||||
import Value from 'src/template/value'
|
import Value from 'src/template/value'
|
||||||
|
|
||||||
chai.use(sinonChai)
|
chai.use(sinonChai)
|
||||||
chai.use(chaiAsPromised)
|
|
||||||
|
|
||||||
const expect = chai.expect
|
const expect = chai.expect
|
||||||
const add = (l, r) => l + r
|
const add = (l, r) => l + r
|
||||||
@@ -41,7 +39,6 @@ describe('Value', function () {
|
|||||||
expect(tpl.filters.length).to.equal(2)
|
expect(tpl.filters.length).to.equal(2)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
it('should eval value', function () {
|
it('should eval value', function () {
|
||||||
Filter.register('date', (l, r) => l + r)
|
Filter.register('date', (l, r) => l + r)
|
||||||
Filter.register('time', (l, r) => l + 3 * r)
|
Filter.register('time', (l, r) => l + 3 * r)
|
||||||
|
|||||||
+7
-8
@@ -1,12 +1,11 @@
|
|||||||
import { read } from 'src/parser/template-browser'
|
import { read } from 'src/parser/template-browser'
|
||||||
import * as sinon from 'sinon'
|
import * as sinon from 'sinon'
|
||||||
import * as chai from 'chai'
|
import { expect, use } from 'chai'
|
||||||
|
import * as chaiAsPromised from 'chai-as-promised'
|
||||||
|
|
||||||
chai.use(require('chai-as-promised'))
|
use(chaiAsPromised)
|
||||||
|
|
||||||
const expect = chai.expect
|
describe('xhr', () => {
|
||||||
|
|
||||||
describe('template-browser', () => {
|
|
||||||
if (+process.version.match(/^v(\d+)/)[1] < 8) {
|
if (+process.version.match(/^v(\d+)/)[1] < 8) {
|
||||||
console.info('jsdom not supported, skipping xhr...')
|
console.info('jsdom not supported, skipping xhr...')
|
||||||
return
|
return
|
||||||
@@ -24,9 +23,9 @@ describe('template-browser', () => {
|
|||||||
delete (global as any).XMLHttpRequest
|
delete (global as any).XMLHttpRequest
|
||||||
})
|
})
|
||||||
describe('#read()', () => {
|
describe('#read()', () => {
|
||||||
it('should get corresponding text', () => {
|
it('should get corresponding text', async function () {
|
||||||
return expect(read('https://example.com/views/hello.html'))
|
const html = await read('https://example.com/views/hello.html')
|
||||||
.to.eventually.equal('hello {{name}}')
|
return expect(html).to.equal('hello {{name}}')
|
||||||
})
|
})
|
||||||
it('should throw 404', () => {
|
it('should throw 404', () => {
|
||||||
return expect(read('https://example.com/not/exist.html'))
|
return expect(read('https://example.com/not/exist.html'))
|
||||||
|
|||||||
Reference in New Issue
Block a user