diff --git a/.eslintignore b/.eslintignore index 00b694961..6fd6d6611 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,4 +1,4 @@ node_modules dist -build +demo coverage diff --git a/.eslintrc.json b/.eslintrc.json index 72fc0a478..60f8a7ee5 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -15,6 +15,8 @@ ], "rules": { "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 }] } } diff --git a/package.json b/package.json index 73fa32a56..76de9805e 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "types": "dist/liquid.d.ts", "browser": "dist/liquid.js", "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", "e2e": "npm run build && mocha -r ts-node/register -r tsconfig-paths/register test/e2e/**/*.ts", "test": "npm run unit && npm run e2e", diff --git a/src/builtin/filters/html.ts b/src/builtin/filters/html.ts index d2a95988e..2ba3a6453 100644 --- a/src/builtin/filters/html.ts +++ b/src/builtin/filters/html.ts @@ -25,5 +25,5 @@ export default { 'escape': escape, 'escape_once': str => escape(unescape(str)), 'newline_to_br': v => v.replace(/\n/g, '
'), - 'strip_html': v => String(v).replace(/|||<.*?>/g, ''), + 'strip_html': v => String(v).replace(/|||<.*?>/g, '') } diff --git a/src/builtin/filters/math.ts b/src/builtin/filters/math.ts index dac56af03..378248e1c 100644 --- a/src/builtin/filters/math.ts +++ b/src/builtin/filters/math.ts @@ -10,7 +10,7 @@ export default { return Math.round(v * amp) / amp }, 'plus': bindFixed((v, arg) => Number(v) + Number(arg)), - 'times': (v, arg) => v * arg, + 'times': (v, arg) => v * arg } function getFixed (v) { diff --git a/src/builtin/filters/string.ts b/src/builtin/filters/string.ts index 76af9a59a..1a5f1c054 100644 --- a/src/builtin/filters/string.ts +++ b/src/builtin/filters/string.ts @@ -28,5 +28,5 @@ export default { let ret = arr.slice(0, l).join(' ') if (arr.length > l) ret += o return ret - }, + } } diff --git a/src/builtin/tags/break.ts b/src/builtin/tags/break.ts index 9501e5ae6..c9fc868d6 100644 --- a/src/builtin/tags/break.ts +++ b/src/builtin/tags/break.ts @@ -1,7 +1,7 @@ import { RenderBreakError } from 'src/util/error' export default { - render: async function (scope) { + render: async function () { throw new RenderBreakError('break') } } diff --git a/src/builtin/tags/capture.ts b/src/builtin/tags/capture.ts index 5ae40f551..273991fd5 100644 --- a/src/builtin/tags/capture.ts +++ b/src/builtin/tags/capture.ts @@ -1,11 +1,14 @@ import assert from 'src/util/assert' import { identifier } from 'src/parser/lexical' 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})`) export default { - parse: function (tagToken, remainTokens) { + parse: function (tagToken: TagToken, remainTokens: Token[]) { const match = tagToken.args.match(re) assert(match, `${tagToken.args} not valid identifier`) @@ -13,14 +16,14 @@ export default { this.templates = [] 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('end', x => { + .on('end', () => { throw new Error(`tag ${tagToken.raw} not closed`) }) stream.start() }, - render: async function (scope, hash) { + render: async function (scope: Scope) { const html = await this.liquid.renderer.renderTemplates(this.templates, scope) const ctx = new CaptureScope() ctx[this.variable] = html diff --git a/src/builtin/tags/case.ts b/src/builtin/tags/case.ts index 751ffe083..cbc29d4b6 100644 --- a/src/builtin/tags/case.ts +++ b/src/builtin/tags/case.ts @@ -15,16 +15,16 @@ export default { }) }) .on('tag:else', () => (p = this.elseTemplates)) - .on('tag:endcase', token => stream.stop()) + .on('tag:endcase', () => stream.stop()) .on('template', tpl => p.push(tpl)) - .on('end', x => { + .on('end', () => { throw new Error(`tag ${tagToken.raw} not closed`) }) stream.start() }, - render: function (scope, hash) { + render: function (scope) { for (let i = 0; i < this.cases.length; i++) { const branch = this.cases[i] const val = evalExp(branch.val, scope) diff --git a/src/builtin/tags/comment.ts b/src/builtin/tags/comment.ts index 7b03844d5..6f0cc1beb 100644 --- a/src/builtin/tags/comment.ts +++ b/src/builtin/tags/comment.ts @@ -5,7 +5,7 @@ export default { .on('token', token => { if (token.name === 'endcomment') stream.stop() }) - .on('end', x => { + .on('end', () => { throw new Error(`tag ${tagToken.raw} not closed`) }) stream.start() diff --git a/src/builtin/tags/continue.ts b/src/builtin/tags/continue.ts index 93319c563..e9a573101 100644 --- a/src/builtin/tags/continue.ts +++ b/src/builtin/tags/continue.ts @@ -1,7 +1,7 @@ import { RenderBreakError } from 'src/util/error' export default { - render: async function (scope) { + render: async function () { throw new RenderBreakError('continue') } } diff --git a/src/builtin/tags/cycle.ts b/src/builtin/tags/cycle.ts index 951da0d07..6b3df487d 100644 --- a/src/builtin/tags/cycle.ts +++ b/src/builtin/tags/cycle.ts @@ -6,7 +6,7 @@ const groupRE = new RegExp(`^(?:(${rValue.source})\\s*:\\s*)?(.*)$`) const candidatesRE = new RegExp(rValue.source, 'g') export default { - parse: function (tagToken, remainTokens) { + parse: function (tagToken) { let match = groupRE.exec(tagToken.args) assert(match, `illegal tag: ${tagToken.raw}`) @@ -21,7 +21,7 @@ export default { assert(this.candidates.length, `empty candidates: ${tagToken.raw}`) }, - render: function (scope, hash) { + render: function (scope) { const group = evalValue(this.group, scope) const fingerprint = `cycle:${group}:` + this.candidates.join(',') diff --git a/src/builtin/tags/decrement.ts b/src/builtin/tags/decrement.ts index 87bebfbb2..ba0adeacf 100644 --- a/src/builtin/tags/decrement.ts +++ b/src/builtin/tags/decrement.ts @@ -1,14 +1,16 @@ import assert from 'src/util/assert' import { identifier } from 'src/parser/lexical' import { CaptureScope, AssignScope, DecrementScope } from 'src/scope/scopes' +import TagToken from 'src/parser/tag-token' +import Scope from 'src/scope/scope' export default { - parse: function (token) { + parse: function (token: TagToken) { const match = token.args.match(identifier) assert(match, `illegal identifier ${token.args}`) this.variable = match[0] }, - render: function (scope, hash) { + render: function (scope: Scope) { let context = scope.findContextFor( this.variable, ctx => { diff --git a/src/builtin/tags/if.ts b/src/builtin/tags/if.ts index 4ce0779e4..e3f5dc226 100644 --- a/src/builtin/tags/if.ts +++ b/src/builtin/tags/if.ts @@ -18,16 +18,16 @@ export default { }) }) .on('tag:else', () => (p = this.elseTemplates)) - .on('tag:endif', token => stream.stop()) + .on('tag:endif', () => stream.stop()) .on('template', tpl => p.push(tpl)) - .on('end', x => { + .on('end', () => { throw new Error(`tag ${tagToken.raw} not closed`) }) stream.start() }, - render: function (scope, hash) { + render: function (scope) { for (const branch of this.branches) { const cond = evalExp(branch.cond, scope) if (isTruthy(cond)) { diff --git a/src/builtin/tags/increment.ts b/src/builtin/tags/increment.ts index f0e850225..5cadcf10d 100644 --- a/src/builtin/tags/increment.ts +++ b/src/builtin/tags/increment.ts @@ -8,7 +8,7 @@ export default { assert(match, `illegal identifier ${token.args}`) this.variable = match[0] }, - render: function (scope, hash) { + render: function (scope) { let context = scope.findContextFor( this.variable, ctx => { diff --git a/src/builtin/tags/index.ts b/src/builtin/tags/index.ts index 87e7e08b8..757ed4c3d 100644 --- a/src/builtin/tags/index.ts +++ b/src/builtin/tags/index.ts @@ -15,7 +15,10 @@ import tablerow from './tablerow' import unless from './unless' import Break from './break' 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 } + +export default tags diff --git a/src/builtin/tags/raw.ts b/src/builtin/tags/raw.ts index 57f741aa7..280f09a04 100644 --- a/src/builtin/tags/raw.ts +++ b/src/builtin/tags/raw.ts @@ -13,7 +13,7 @@ export default { }) stream.start() }, - render: function (scope, hash) { + render: function () { return this.tokens.map(token => token.raw).join('') } } diff --git a/src/builtin/tags/tablerow.ts b/src/builtin/tags/tablerow.ts index fcc46a9c8..1c05d58c9 100644 --- a/src/builtin/tags/tablerow.ts +++ b/src/builtin/tags/tablerow.ts @@ -19,7 +19,7 @@ export default { let p const stream = this.liquid.parser.parseStream(remainTokens) .on('start', () => (p = this.templates)) - .on('tag:endtablerow', token => stream.stop()) + .on('tag:endtablerow', () => stream.stop()) .on('template', tpl => p.push(tpl)) .on('end', () => { throw new Error(`tag ${tagToken.raw} not closed`) @@ -35,7 +35,7 @@ export default { collection = collection.slice(offset, offset + limit) const cols = hash.cols || collection.length - const contexts = collection.map((item, i) => { + const contexts = collection.map(item => { const ctx = {} ctx[this.variable] = item return ctx diff --git a/src/builtin/tags/unless.ts b/src/builtin/tags/unless.ts index a95345d9c..ff93fc742 100644 --- a/src/builtin/tags/unless.ts +++ b/src/builtin/tags/unless.ts @@ -6,21 +6,21 @@ export default { this.elseTemplates = [] let p const stream = this.liquid.parser.parseStream(remainTokens) - .on('start', x => { + .on('start', () => { p = this.templates this.cond = tagToken.args }) .on('tag:else', () => (p = this.elseTemplates)) - .on('tag:endunless', token => stream.stop()) + .on('tag:endunless', () => stream.stop()) .on('template', tpl => p.push(tpl)) - .on('end', x => { + .on('end', () => { throw new Error(`tag ${tagToken.raw} not closed`) }) stream.start() }, - render: function (scope, hash) { + render: function (scope) { const cond = evalExp(this.cond, scope) return isFalsy(cond) ? this.liquid.renderer.renderTemplates(this.templates, scope) diff --git a/src/liquid-options.ts b/src/liquid-options.ts index f4e4b9c13..bf9ee75c2 100644 --- a/src/liquid-options.ts +++ b/src/liquid-options.ts @@ -1,5 +1,5 @@ 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[] /** `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 @@ -8,17 +8,17 @@ export interface LiquidOptions { /** `dynamicPartials`: if set, treat `` parameter in `{%include filepath %}`, `{%layout filepath%}` as a variable, otherwise as a literal value. Defaults to `true`. */ 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?: 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?: 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?: 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?: 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?: 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?: 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?: boolean } diff --git a/src/liquid.ts b/src/liquid.ts index ceb33dbed..c559d7f81 100644 --- a/src/liquid.ts +++ b/src/liquid.ts @@ -3,7 +3,7 @@ import * as Types from './types' import * as template from 'template' import * as _ from './util/underscore' import ITemplate from './template/itemplate' -import * as tokenizer from './parser/tokenizer' +import Tokenizer from './parser/tokenizer' import Render from './render/render' import Tag from './template/tag/tag' import Filter from './template/filter' @@ -20,6 +20,7 @@ export default class Liquid { private cache: object private parser: Parser private renderer: Render + private tokenizer: Tokenizer constructor (options: LiquidOptions = {}) { options = _.assign({}, defaultOptions, options) @@ -31,31 +32,32 @@ export default class Liquid { this.options = options this.parser = new Parser(this) this.renderer = new Render() + this.tokenizer = new Tokenizer(this.options) _.forOwn(builtinTags, (conf, name) => this.registerTag(name, conf)) _.forOwn(builtinFilters, (handler, name) => this.registerFilter(name, handler)) } - parse(html: string, filepath?: string) { - const tokens = tokenizer.parse(html, filepath, this.options) + parse (html: string, filepath?: string) { + const tokens = this.tokenizer.tokenize(html, filepath) return this.parser.parse(tokens) } - render(tpl: Array, ctx?: object, opts?: LiquidOptions) { + render (tpl: Array, ctx?: object, opts?: LiquidOptions) { opts = _.assign({}, this.options, opts) const scope = new Scope(ctx, opts) 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) return this.render(tpl, ctx, opts) } - async getTemplate(file, root) { + async getTemplate (file, root) { const filepath = await template.resolve(file, root, this.options) return this.respectCache(filepath, async () => { const str = await template.read(filepath) return this.parse(str, filepath) }) } - async renderFile(file, ctx?: object, opts?: LiquidOptions) { + async renderFile (file, ctx?: object, opts?: LiquidOptions) { opts = _.assign({}, opts) const templates = await this.getTemplate(file, opts.root) return this.render(templates, ctx, opts) diff --git a/src/parser/delimited-token.ts b/src/parser/delimited-token.ts index 0655a8d16..6b48b4c95 100644 --- a/src/parser/delimited-token.ts +++ b/src/parser/delimited-token.ts @@ -1,12 +1,12 @@ import Token from './token' export default class DelimitedToken extends Token { - trim_left: boolean - trim_right: boolean - constructor(raw, pos, input, file, line) { + trimLeft: boolean + trimRight: boolean + constructor (raw, pos, input, file, line) { super(raw, pos, input, file, line) - this.trim_left = raw[2] === '-' - this.trim_right = raw[raw.length - 3] === '-' - this.value = raw.slice(this.trim_left ? 3 : 2, this.trim_right ? -3 : -2).trim() + this.trimLeft = raw[2] === '-' + this.trimRight = raw[raw.length - 3] === '-' + this.value = raw.slice(this.trimLeft ? 3 : 2, this.trimRight ? -3 : -2).trim() } } diff --git a/src/parser/html-token.ts b/src/parser/html-token.ts index 6bfc73829..c87c63ba1 100644 --- a/src/parser/html-token.ts +++ b/src/parser/html-token.ts @@ -1,7 +1,7 @@ import Token from './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) this.type = 'html' this.value = str diff --git a/src/parser/output-token.ts b/src/parser/output-token.ts index 81c72c35f..294399e54 100644 --- a/src/parser/output-token.ts +++ b/src/parser/output-token.ts @@ -1,7 +1,7 @@ import DelimitedToken from './delimited-token' export default class OutputToken extends DelimitedToken { - constructor(raw, pos, input, file, line) { + constructor (raw, pos, input, file, line) { super(raw, pos, input, file, line) this.type = 'output' } diff --git a/src/parser/parser.ts b/src/parser/parser.ts index bdc529fbe..a480bb35b 100644 --- a/src/parser/parser.ts +++ b/src/parser/parser.ts @@ -2,18 +2,16 @@ import { ParseError } from '../util/error' import Liquid from 'src/liquid' import ParseStream from './parse-stream' import Token from './token' -import Tag from 'src/template/tag/tag' -import HTMLToken from './html-token' import TagToken from './tag-token' import OutputToken from './output-token' +import Tag from 'src/template/tag/tag' import Output from 'src/template/output' import HTML from 'src/template/html' -import Value from 'src/template/value' export default class Parser { liquid: Liquid - constructor(liquid: Liquid) { + constructor (liquid: Liquid) { this.liquid = liquid } parse (tokens: Array) { @@ -27,10 +25,10 @@ export default class Parser { parseToken (token: Token, remainTokens: Array) { try { if (token.type === 'tag') { - return new Tag(token, remainTokens, this.liquid) + return new Tag(token as TagToken, remainTokens, this.liquid) } 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) } catch (e) { diff --git a/src/parser/tag-token.ts b/src/parser/tag-token.ts index ab5dbe4c4..4d6b8abae 100644 --- a/src/parser/tag-token.ts +++ b/src/parser/tag-token.ts @@ -5,7 +5,7 @@ import * as lexical from './lexical' export default class TagToken extends DelimitedToken { name: string args: string - constructor(raw, pos, input, file, line) { + constructor (raw, pos, input, file, line) { super(raw, pos, input, file, line) this.type = 'tag' const match = this.value.match(lexical.tagLine) diff --git a/src/parser/token.ts b/src/parser/token.ts index c8e83a846..65b87cd55 100644 --- a/src/parser/token.ts +++ b/src/parser/token.ts @@ -5,7 +5,7 @@ export default class Token { input: string file: string value: string - constructor(raw, pos, input, file, line) { + constructor (raw, pos, input, file, line) { this.line = line this.raw = raw this.input = input diff --git a/src/parser/tokenizer.ts b/src/parser/tokenizer.ts index 073a445c1..3a80487ca 100644 --- a/src/parser/tokenizer.ts +++ b/src/parser/tokenizer.ts @@ -2,52 +2,57 @@ import whiteSpaceCtrl from './whitespace-ctrl' import HTMLToken from './html-token' import TagToken from './tag-token' import OutputToken from './output-token' +import { LiquidOptions, defaultOptions } from 'src/liquid-options' enum ParseState { HTML, OUTPUT, TAG } -export function parse (input: string, file?: string, options?) { - const tokens = [] - let p = 0 - let line = 1 - let state = ParseState.HTML - let buffer = '' - let bufferBegin = 0 +export default class Tokenizer { + options: LiquidOptions + constructor (options: LiquidOptions = defaultOptions) { + this.options = options + } + tokenize (input: string, file?: string) { + const tokens = [] + let p = 0 + let line = 1 + let state = ParseState.HTML + let buffer = '' + let bufferBegin = 0 - while(p < input.length) { - if (input[p] === '\n') line++ - const bin = input.substr(p, 2) - if (state === ParseState.HTML) { - if (bin === '{{' || bin === '{%') { - if (buffer) tokens.push(new HTMLToken(buffer, bufferBegin, input, file, line)) - buffer = bin - bufferBegin = p + while (p < input.length) { + if (input[p] === '\n') line++ + const bin = input.substr(p, 2) + if (state === ParseState.HTML) { + if (bin === '{{' || bin === '{%') { + if (buffer) tokens.push(new HTMLToken(buffer, bufferBegin, input, file, line)) + buffer = bin + 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 - 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 } + buffer += input[p++] } - else if (state === ParseState.OUTPUT && bin === '}}') { - 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)) + if (buffer) tokens.push(new HTMLToken(buffer, bufferBegin, input, file, line)) - whiteSpaceCtrl(tokens, options) - return tokens + whiteSpaceCtrl(tokens, this.options) + return tokens + } } diff --git a/src/parser/whitespace-ctrl.ts b/src/parser/whitespace-ctrl.ts index 39b0c33e0..65479ac01 100644 --- a/src/parser/whitespace-ctrl.ts +++ b/src/parser/whitespace-ctrl.ts @@ -1,46 +1,47 @@ import { assign } from 'src/util/underscore' -import TagToken from './tag-token' -import OutputToken from './output-token' -import HTMLToken from './html-token' +import DelimitedToken from 'src/parser/delimited-token' +import Token from 'src/parser/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) let inRaw = false - tokens.forEach((token, i) => { - if (shouldTrimLeft(token, inRaw, options)) { + tokens.forEach((token: Token, i: number) => { + if (shouldTrimLeft(token as DelimitedToken, inRaw, options)) { trimLeft(tokens[i - 1], options.greedy) } - if (token.type === 'tag' && token.name === 'raw') inRaw = true - if (token.type === 'tag' && token.name === 'endraw') inRaw = false + if (token.type === 'tag' && (token as TagToken).name === 'raw') inRaw = true + 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) } }) } -function shouldTrimLeft (token, inRaw, options) { +function shouldTrimLeft (token: DelimitedToken, inRaw: boolean, options) { if (inRaw) return false - if (token.type === 'tag') return token.trim_left || options.trim_tag_left - if (token.type === 'output') return token.trim_left || options.trim_value_left + if (token.type === 'tag') return token.trimLeft || options.trim_tag_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 (token.type === 'tag') return token.trim_right || options.trim_tag_right - if (token.type === 'output') return token.trim_right || options.trim_value_right + if (token.type === 'tag') return token.trimRight || options.trim_tag_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 const rLeft = greedy ? /\s+$/g : /[\t\r ]*$/g token.value = token.value.replace(rLeft, '') } -function trimRight (token, greedy) { +function trimRight (token: Token, greedy: boolean) { if (!token || token.type !== 'html') return const rRight = greedy ? /^\s+/g : /^[\t\r ]*\n?/g diff --git a/src/render/render.ts b/src/render/render.ts index 052b9f855..b1d3d9218 100644 --- a/src/render/render.ts +++ b/src/render/render.ts @@ -1,7 +1,5 @@ -import { stringify, create } from 'src/util/underscore' import { RenderBreakError, RenderError } from 'src/util/error' import assert from 'src/util/assert' -import Scope from 'src/scope/scope' export default class Render { async renderTemplates (templates, scope) { diff --git a/src/scope/scope.ts b/src/scope/scope.ts index 8a44eecac..e96ccf7d8 100644 --- a/src/scope/scope.ts +++ b/src/scope/scope.ts @@ -15,7 +15,7 @@ export default class Scope { strict_variables: false, strict_filters: false, root: [] - } , opts) + }, opts) this.contexts = [ctx || {}] } getAll () { @@ -59,7 +59,7 @@ export default class Scope { } 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--) { const candidate = this.contexts[i] if (!filter(candidate)) continue diff --git a/src/template/filter.ts b/src/template/filter.ts index 4ace21dd1..49a08f9fa 100644 --- a/src/template/filter.ts +++ b/src/template/filter.ts @@ -13,21 +13,21 @@ export default class Filter { args: string[] private static impls: {[key: string]: impl} = {} - constructor (str: string, strict_filters: boolean = false) { - let match = lexical.filterLine.exec(str) + constructor (str: string, strictFilters: boolean = false) { + const match = lexical.filterLine.exec(str) assert(match, 'illegal filter: ' + str) const name = match[1] const argList = match[2] || '' 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.impl = impl || (x => x) this.args = this.parseArgs(argList) } parseArgs (argList: string): string[] { - let match, args = [] + let match; const args = [] while ((match = valueRE.exec(argList.trim()))) { const v = match[0] const re = new RegExp(`${v}\\s*:`, 'g') @@ -42,7 +42,7 @@ export default class Filter { args.unshift(value) return this.impl.apply(null, args) } - static register(name, filter) { + static register (name, filter) { Filter.impls[name] = filter } static clear () { diff --git a/src/template/html.ts b/src/template/html.ts index 5902a4921..5e867364b 100644 --- a/src/template/html.ts +++ b/src/template/html.ts @@ -1,15 +1,14 @@ import Template from 'src/template/template' -import Scope from 'src/scope/scope' import ITemplate from 'src/template/itemplate' import Token from 'src/parser/token' export default class extends Template implements ITemplate { str: string - constructor(token: Token) { + constructor (token: Token) { super(token) this.str = token.value } - async render(scope: Scope): Promise { + async render (): Promise { return this.str } } diff --git a/src/template/output.ts b/src/template/output.ts index 79dae3eb1..15e09435c 100644 --- a/src/template/output.ts +++ b/src/template/output.ts @@ -3,14 +3,15 @@ import { stringify } from 'src/util/underscore' import Template from 'src/template/template' import ITemplate from 'src/template/itemplate' import Scope from 'src/scope/scope' +import OutputToken from 'src/parser/output-token' export default class Output extends Template implements ITemplate { value: Value - constructor(token, strict_filters?) { + constructor (token: OutputToken, strictFilters?: boolean) { 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 { const html = await this.value.value(scope) return stringify(html) } diff --git a/src/template/tag/hash.ts b/src/template/tag/hash.ts index d3b308da2..28e76fd0b 100644 --- a/src/template/tag/hash.ts +++ b/src/template/tag/hash.ts @@ -9,7 +9,7 @@ import { evalValue } from 'src/render/syntax' */ export default class Hash { [key: string]: any - constructor(markup, scope) { + constructor (markup, scope) { let match hashCapture.lastIndex = 0 while ((match = hashCapture.exec(markup))) { diff --git a/src/template/tag/itag-impl-options.ts b/src/template/tag/itag-impl-options.ts index 4200256a0..de8a745bf 100644 --- a/src/template/tag/itag-impl-options.ts +++ b/src/template/tag/itag-impl-options.ts @@ -6,5 +6,5 @@ import ITagImpl from './itag-impl' export default interface ITagImplOptions { parse?: (this: ITagImpl, token: TagToken, remainingTokens: Array) => void - render?: (this: ITagImpl, scope: Scope, hash: Hash) => string | Promise + render?: (this: ITagImpl, scope: Scope, hash: Hash) => any | Promise } diff --git a/src/template/tag/tag.ts b/src/template/tag/tag.ts index 091b161cf..265dd232f 100644 --- a/src/template/tag/tag.ts +++ b/src/template/tag/tag.ts @@ -1,6 +1,6 @@ -import { create } from 'src/util/underscore' -import { stringify } from 'src/util/underscore' +import { create, stringify } from 'src/util/underscore' import assert from 'src/util/assert' +import Scope from 'src/scope/scope' import ITagImpl from './itag-impl' import ITagImplOptions from './itag-impl-options' import Liquid from 'src/liquid' @@ -8,26 +8,27 @@ import Hash from './hash' import Template from 'src/template/template' import ITemplate from 'src/template/itemplate' import TagToken from 'src/parser/tag-token' +import Token from 'src/parser/token' export default class Tag extends Template implements ITemplate { name: string token: TagToken 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) this.name = token.name const impl = Tag.impls[token.name] assert(impl, `tag ${token.name} not found`) - this.impl = create(impl) + this.impl = create(impl) this.impl.liquid = liquid if (this.impl.parse) { this.impl.parse(token, tokens) } } - async render (scope) { + async render (scope: Scope) { const hash = new Hash(this.token.args, scope) const impl = this.impl if (typeof impl.render !== 'function') { diff --git a/src/template/template.ts b/src/template/template.ts index bfe74fbd0..46f2c4b71 100644 --- a/src/template/template.ts +++ b/src/template/template.ts @@ -2,7 +2,7 @@ import Token from 'src/parser/token' export default class Template { token: Token; - constructor(token) { - this.token = token; + constructor (token) { + this.token = token } } diff --git a/src/template/value.ts b/src/template/value.ts index 465b0602d..4fe5f4130 100644 --- a/src/template/value.ts +++ b/src/template/value.ts @@ -7,7 +7,7 @@ import Scope from 'src/scope/scope' export default class { initial: any filters: Array - constructor(str: string, strict_filters?: boolean) { + constructor (str: string, strictFilters?: boolean) { let match = lexical.matchValue(str) assert(match, `illegal value string: ${str}`) @@ -20,9 +20,9 @@ export default class { } 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( (prev, filter) => filter.render(prev, scope), evalExp(this.initial, scope)) diff --git a/src/util/error.ts b/src/util/error.ts index cd448038e..ebb0112f9 100644 --- a/src/util/error.ts +++ b/src/util/error.ts @@ -16,14 +16,14 @@ abstract class LiquidError { private input: string private token: Token private originalError: Error - constructor(err, token) { + constructor (err, token) { this.input = token.input this.line = token.line this.file = token.file this.originalError = err this.token = token } - captureStackTrace(obj) { + captureStackTrace (obj) { this.name = obj.constructor.name captureStack.call(obj) @@ -37,32 +37,32 @@ abstract class LiquidError { } export class TokenizationError extends LiquidError { - constructor(message, token) { - super({message}, token) + constructor (message, token) { + super({ message }, token) super.captureStackTrace(this) } } -TokenizationError.prototype = _.create(Error.prototype) +TokenizationError.prototype = _.create(Error.prototype) as any TokenizationError.prototype.constructor = TokenizationError export class ParseError extends LiquidError { - constructor(err, token) { + constructor (err, token) { super(err, token) _.assign(this, err) super.captureStackTrace(this) } } -ParseError.prototype = _.create(Error.prototype) +ParseError.prototype = _.create(Error.prototype) as any ParseError.prototype.constructor = ParseError export class RenderError extends LiquidError { - constructor(err, tpl) { + constructor (err, tpl) { super(err, tpl.token) _.assign(this, err) super.captureStackTrace(this) } } -RenderError.prototype = _.create(Error.prototype) +RenderError.prototype = _.create(Error.prototype) as any RenderError.prototype.constructor = RenderError export class RenderBreakError { @@ -73,7 +73,7 @@ export class RenderBreakError { this.message = message + '' } } -RenderBreakError.prototype = _.create(Error.prototype) +RenderBreakError.prototype = _.create(Error.prototype) as any RenderBreakError.prototype.constructor = RenderBreakError export class AssertionError { @@ -83,7 +83,7 @@ export class AssertionError { this.message = message + '' } } -AssertionError.prototype = _.create(Error.prototype) +AssertionError.prototype = _.create(Error.prototype) as any AssertionError.prototype.constructor = AssertionError function mkContext (input, targetLine) { diff --git a/src/util/promise.ts b/src/util/promise.ts index 430159b03..d529442e4 100644 --- a/src/util/promise.ts +++ b/src/util/promise.ts @@ -7,7 +7,7 @@ export function anySeries (iterable, iteratee) { let ret: Promise = Promise.reject(new Error('init')) iterable.forEach(function (item, idx) { - ret = ret.catch(e => iteratee(item, idx, iterable)) + ret = ret.catch(() => iteratee(item, idx, iterable)) }) return ret } diff --git a/src/util/strftime.ts b/src/util/strftime.ts index 7f7e1d377..bf4012a31 100644 --- a/src/util/strftime.ts +++ b/src/util/strftime.ts @@ -159,7 +159,7 @@ const formatCodes = { } }; (formatCodes as any).h = formatCodes.b; -(formatCodes as any).N = formatCodes.L; +(formatCodes as any).N = formatCodes.L export default function (d, format) { let output = '' diff --git a/src/util/underscore.ts b/src/util/underscore.ts index 5e49cdaf1..b9544e190 100644 --- a/src/util/underscore.ts +++ b/src/util/underscore.ts @@ -6,11 +6,11 @@ const arrToStr = Array.prototype.toString * @param {any} value The value to check. * @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]' } -export function isFunction (value) { +export function isFunction (value: any) { 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 (isFunction(value.to_liquid)) return stringify(value.to_liquid()) if (isFunction(value.toLiquid)) return stringify(value.toLiquid()) @@ -34,7 +34,7 @@ export function stringify (value) { return toStr.call(value) } -function defaultToString (value) { +function defaultToString (value: any): string { const cache = [] return JSON.stringify(value, (key, value) => { if (isObject(value)) { @@ -47,20 +47,20 @@ function defaultToString (value) { }) } -export function create (proto) { +export function create (proto: T1): T2 { return Object.create(proto) } -export function isNil (value) { +export function isNil (value: any): boolean { return value === null || value === undefined } -export function isArray (value) { +export function isArray (value: any): boolean { // be compatible with IE 8 return toStr.call(value) === '[object Array]' } -export function isError (value) { +export function isError (value: any): boolean { const signature = toStr.call(value) // [object XXXError] return signature.substr(-6, 5) === 'Error' || @@ -75,7 +75,7 @@ export function isError (value) { * @param {Function} iteratee The function invoked per iteration. * @return {Object} Returns object. */ -export function forOwn (object, iteratee) { +export function forOwn (object, iteratee: ((val: any, key: string, obj: object) => boolean | void)) { object = object || {} for (const k in object) { if (object.hasOwnProperty(k)) { @@ -96,21 +96,22 @@ export function forOwn (object, iteratee) { * @param {...Object} sources The source objects. * @return {Object} Returns object. */ -export function assign (obj, ...srcs) { +export function assign (obj: object, ...srcs: object[]): object { obj = isObject(obj) ? obj : {} srcs.forEach(src => binaryAssign(obj, src)) return obj } -function binaryAssign(target, src) { - for(let key in src) if (src.hasOwnProperty(key)) target[key] = src[key] +function binaryAssign (target: object, src: object): object { + 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] } -export function uniq (arr) { +export function uniq (arr: any[]): any[] { const u = {} const a = [] 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. * @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 return value !== null && (type === 'object' || type === 'function') } @@ -156,9 +157,9 @@ export function range (start: number, stop?: number, step?: number) { return arr } -export function padStart(str: any, length: number, ch: string = ' ') { +export function padStart (str: any, length: number, ch: string = ' ') { str = String(str) let n = length - str.length - while(n-- > 0) str = ch + str + while (n-- > 0) str = ch + str return str } diff --git a/test/.eslintrc.json b/test/.eslintrc.json new file mode 100644 index 000000000..14822e762 --- /dev/null +++ b/test/.eslintrc.json @@ -0,0 +1,12 @@ +{ + "env": { + "mocha": true + }, + "plugins": [ + "mocha" + ], + "rules": { + "no-unused-expressions": "off", + "no-new": "off" + } +} diff --git a/test/e2e/eval-value.ts b/test/e2e/eval-value.ts index c379162da..8efbbe490 100644 --- a/test/e2e/eval-value.ts +++ b/test/e2e/eval-value.ts @@ -1,12 +1,9 @@ -var chai = require('chai') -var Liquid = require('../..') -var expect = chai.expect - -chai.use(require('chai-as-promised')) +import { expect } from 'chai' +import Liquid from '../..' describe('.evalValue()', function () { var engine - beforeEach(() => engine = new Liquid()) + beforeEach(() => { engine = new Liquid() }) it('should throw when scope undefined', function () { expect(() => engine.evalValue('{{"foo"}}')).to.throw(/scope undefined/) diff --git a/test/e2e/express.ts b/test/e2e/express.ts index 7c4f8ad06..1ae026d1c 100644 --- a/test/e2e/express.ts +++ b/test/e2e/express.ts @@ -1,12 +1,8 @@ -import * as chai from 'chai' +import { expect } from 'chai' import * as request from 'supertest' import * as express from 'express' import * as mock from 'mock-fs' import Liquid from '../../dist/liquid.common.js' -import * as chaiAsPromised from 'chai-as-promised' - -const expect = chai.expect -chai.use(chaiAsPromised) describe('express()', function () { var app, engine diff --git a/test/e2e/parse-and-render.ts b/test/e2e/parse-and-render.ts index b3f579b36..c942267b9 100644 --- a/test/e2e/parse-and-render.ts +++ b/test/e2e/parse-and-render.ts @@ -1,8 +1,8 @@ -var chai = require('chai') -var Liquid = require('../..') -var expect = chai.expect +import Liquid from '../..' +import { expect, use } from 'chai' +import * as chaiAsPromised from 'chai-as-promised' -chai.use(require('chai-as-promised')) +use(chaiAsPromised) describe('.parseAndRender()', function () { var engine, strictEngine @@ -12,19 +12,23 @@ describe('.parseAndRender()', function () { strict_filters: true }) }) - it('should stringify object', function () { + it('should stringify object', async function () { 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'] } - 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 () { - return expect(engine.parseAndRender('foo{{zzz}}bar', {})).to.eventually.equal('foobar') + it('should render undefined as empty', async function () { + const html = await engine.parseAndRender('foo{{zzz}}bar', {}) + return expect(html).to.equal('foobar') }) - it('should render as null when filter undefined', function () { - return expect(engine.parseAndRender('{{"foo" | filter1}}', {})).to.eventually.equal('foo') + it('should render as null when filter undefined', async function () { + const html = await engine.parseAndRender('{{"foo" | filter1}}', {}) + return expect(html).to.equal('foo') }) it('should throw upon undefined filter when strict_filters set', function () { return expect(strictEngine.parseAndRender('{{"foo" | filter1}}', {})).to @@ -38,22 +42,24 @@ describe('.parseAndRender()', function () { engine.parse('{{obj}}') }).to.not.throw() }) - it('should render template multiple times', function () { - var ctx = { obj: { foo: 'bar' } } - var template = engine.parse('{{obj}}') - return engine.render(template, ctx) - .then(result => expect(result).to.equal('{"foo":"bar"}')) - .then(() => engine.render(template, ctx)) - .then((result) => expect(result).to.equal('{"foo":"bar"}')) + it('should render template multiple times', async function () { + const ctx = { obj: { foo: 'bar' } } + const template = engine.parse('{{obj}}') + const result = await engine.render(template, ctx) + expect(result).to.equal('{"foo":"bar"}') + const result2 = await engine.render(template, ctx) + expect(result2).to.equal('{"foo":"bar"}') }) - it('should render filters', function () { + it('should render filters', async function () { var ctx = { names: ['alice', 'bob'] } var template = engine.parse('

{{names | join: ","}}

') - return expect(engine.render(template, ctx)).to.eventually.equal('

alice,bob

') + const html = await engine.render(template, ctx) + return expect(html).to.equal('

alice,bob

') }) - it('should render accessive filters', function () { + it('should render accessive filters', async function () { var src = '{% assign my_array = "apples, oranges, peaches, plums" | split: ", " %}' + '{{ my_array | first }}' - return expect(engine.parseAndRender(src)).to.eventually.equal('apples') + const html = await engine.parseAndRender(src) + return expect(html).to.equal('apples') }) }) diff --git a/test/e2e/render-file.ts b/test/e2e/render-file.ts index 14c5c93d3..c2eaec566 100644 --- a/test/e2e/render-file.ts +++ b/test/e2e/render-file.ts @@ -1,9 +1,6 @@ -var chai = require('chai') -var mock = require('mock-fs') -var Liquid = require('../..') -var expect = chai.expect - -chai.use(require('chai-as-promised')) +import { expect } from 'chai' +import * as mock from 'mock-fs' +import Liquid from '../..' describe('#renderFile()', function () { var engine @@ -24,28 +21,28 @@ describe('#renderFile()', function () { afterEach(function () { mock.restore() }) - it('should render file', function () { - return expect(engine.renderFile('/root/files/foo.html', {})) - .to.eventually.equal('foo') + it('should render file', async function () { + const html = await engine.renderFile('/root/files/foo.html', {}) + 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' }) - return expect(engine.renderFile('/root/files/bar', {})) - .to.eventually.equal('bar') + const html = await engine.renderFile('/root/files/bar', {}) + return expect(html).to.equal('bar') }) - it('should accept relative path', function () { - return expect(engine.renderFile('files/foo.html')) - .to.eventually.equal('foo') + it('should accept relative path', async function () { + const html = await engine.renderFile('files/foo.html') + return expect(html).to.equal('foo') }) - it('should resolve array as root', function () { + it('should resolve array as root', async function () { engine = new Liquid({ root: ['/boo', '/root/'], extname: '.html' }) - return expect(engine.renderFile('files/foo.html')) - .to.eventually.equal('foo') + const html = await engine.renderFile('files/foo.html') + return expect(html).to.equal('foo') }) - it('should default root to cwd', function () { + it('should default root to cwd', async function () { var files = {} files[process.cwd() + '/foo.html'] = 'FOO' mock(files) @@ -53,15 +50,16 @@ describe('#renderFile()', function () { engine = new Liquid({ extname: '.html' }) - return expect(engine.renderFile('foo.html')) - .to.eventually.equal('FOO') + const html = await engine.renderFile('foo.html') + return expect(html).to.equal('FOO') }) - it('should render file with context', function () { - return expect(engine.renderFile('/root/files/name.html', { name: 'harttle' })) - .to.eventually.equal('My name is harttle.') + it('should render file with context', async function () { + const html = await engine.renderFile('/root/files/name.html', { name: 'harttle' }) + return expect(html).to.equal('My name is harttle.') }) - it('should use default extname', function () { - return expect(engine.renderFile('files/name', { name: 'harttle' })).to.eventually.equal('My name is harttle.') + it('should use default extname', async function () { + 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 () { engine = new Liquid({ diff --git a/test/e2e/whitespace-ctrl.ts b/test/e2e/whitespace-ctrl.ts index e3778c92d..c26e9a38d 100644 --- a/test/e2e/whitespace-ctrl.ts +++ b/test/e2e/whitespace-ctrl.ts @@ -1,10 +1,7 @@ -import * as chai from 'chai' +import { expect } from 'chai' import Liquid from '../..' -import * as chaiAsPromised from 'chai-as-promised' const liquid = new Liquid() -const expect = chai.expect -chai.use(chaiAsPromised) const cases = [ { @@ -445,6 +442,9 @@ const cases = [ describe('Whitespace Control', function () { cases.forEach(item => it( 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) + } )) }) diff --git a/test/e2e/xhr.ts b/test/e2e/xhr.ts index 8a4987910..b6c164512 100644 --- a/test/e2e/xhr.ts +++ b/test/e2e/xhr.ts @@ -1,11 +1,10 @@ import Liquid from '../../dist/liquid.js' import { createFakeServer, useFakeXMLHttpRequest } from 'sinon' -import * as chai from 'chai' -import * as chaiAsPromised from 'chai-as-promised' +import { expect, use } from 'chai' import { JSDOM } from 'jsdom' +import * as chaiAsPromised from 'chai-as-promised' -const expect = chai.expect -chai.use(chaiAsPromised) +use(chaiAsPromised) describe('xhr', () => { if (+process.version.match(/^v(\d+)/)[1] < 8) { @@ -24,7 +23,7 @@ describe('xhr', () => { includeNodeLocations: true }); (global as any).XMLHttpRequest = useFakeXMLHttpRequest(); - (global as any).document = dom.window.document; + (global as any).document = dom.window.document engine = new Liquid({ root: 'https://example.com/views/', extname: '.html' @@ -36,97 +35,94 @@ describe('xhr', () => { delete (global as any).document }) describe('#renderFile()', () => { - it('should support without extname', () => { - return expect(engine.renderFile('hello', { name: 'alice1' })) - .to.eventually.equal('hello alice1') + it('should support without extname', async () => { + const html = await engine.renderFile('hello', { name: 'alice1' }) + return expect(html).to.equal('hello alice1') }) - it('should support with extname', () => { - return expect(engine.renderFile('hello.html', { name: 'alice2' })) - .to.eventually.equal('hello alice2') + it('should support with extname', async () => { + const html = await engine.renderFile('hello.html', { name: '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', [200, { 'Content-Type': 'text/plain' }, 'foo']) - return expect(engine.renderFile('/foo.html')) - .to.eventually.equal('foo') + const html = await engine.renderFile('/foo.html') + return expect(html).to.equal('foo') }) - it('should support with url', () => { - return expect(engine.renderFile('https://example.com/views/hello.html', { name: 'alice4' })) - .to.eventually.equal('hello alice4') + it('should support with url', async () => { + const html = await engine.renderFile('https://example.com/views/hello.html', { name: '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', [200, { 'Content-Type': 'text/plain' }, "hello {% include 'name.html' %}"]) server.respondWith('GET', 'https://example.com/views/name.html', [200, { 'Content-Type': 'text/plain' }, '{{name}}']) - return expect(engine.renderFile('hello.html', { name: 'alice5' })) - .to.eventually.equal('hello alice5') + const html = await engine.renderFile('hello.html', { name: 'alice5' }) + return expect(html).to.equal('hello alice5') }) it('should throw 404', () => { return expect(engine.renderFile('/not/exist.html')) .to.be.rejectedWith('Not Found') }) - it('should throw error', function (done) { - engine.renderFile('hello.html') - .then(() => done('should not be resolved')) - .catch(function (e) { - expect(e.message).to.equal('An error occurred whilst receiving the response.') - done() - }); + it('should throw error', function () { + const result = expect(engine.renderFile('hello.html')) + .to.be.rejectedWith('An error occurred whilst receiving the response.'); (global as any).XMLHttpRequest.onCreate = function (request) { setTimeout(() => request.error()) } + return result }) }) describe('#renderFile() with root specified', () => { - it('should support undefined root', () => { + it('should support undefined root', async () => { engine = new Liquid({ extname: '.html' }) server.respondWith('GET', 'https://example.com/foo/hello.html', [200, { 'Content-Type': 'text/plain' }, 'hello {{name}}']) - return expect(engine.renderFile('hello.html', { name: 'alice5' })) - .to.eventually.equal('hello alice5') + const html = await engine.renderFile('hello.html', { name: 'alice5' }) + return expect(html).to.equal('hello alice5') }) - it('should support empty root', () => { + it('should support empty root', async () => { engine = new Liquid({ root: '', extname: '.html' }) server.respondWith('https://example.com/foo/hello.html', [200, { 'Content-Type': 'text/plain' }, 'hello {{name}}']) - return expect(engine.renderFile('hello.html', { name: 'alice5' })) - .to.eventually.equal('hello alice5') + const html = await engine.renderFile('hello.html', { name: 'alice5' }) + return expect(html).to.equal('hello alice5') }) - it('should support with relative path', () => { + it('should support with relative path', async () => { engine = new Liquid({ root: './views/', extname: '.html' }) server.respondWith('GET', 'https://example.com/foo/views/hello.html', [200, { 'Content-Type': 'text/plain' }, 'hello {{name}}']) - return expect(engine.renderFile('hello.html', { name: 'alice5' })) - .to.eventually.equal('hello alice5') + const html = await engine.renderFile('hello.html', { name: 'alice5' }) + return expect(html).to.equal('hello alice5') }) - it('should support with absolute path', () => { + it('should support with absolute path', async () => { engine = new Liquid({ root: '/views/', extname: '.html' }) server.respondWith('GET', 'https://example.com/views/hello.html', [200, { 'Content-Type': 'text/plain' }, 'hello {{name}}']) - return expect(engine.renderFile('hello.html', { name: 'alice5' })) - .to.eventually.equal('hello alice5') + const html = await engine.renderFile('hello.html', { name: 'alice5' }) + return expect(html).to.equal('hello alice5') }) - it('should support with url', () => { + it('should support with url', async () => { engine = new Liquid({ root: 'https://foo.com/bar/', extname: '.html' }) server.respondWith('GET', 'https://foo.com/bar/hello.html', [200, { 'Content-Type': 'text/plain' }, 'hello {{name}}']) - return expect(engine.renderFile('hello.html', { name: 'alice5' })) - .to.eventually.equal('hello alice5') + const html = await engine.renderFile('hello.html', { name: 'alice5' }) + return expect(html).to.equal('hello alice5') }) }) describe('cache options', () => { diff --git a/test/unit/filters.ts b/test/unit/filters.ts index 74144be54..daedd8cb5 100644 --- a/test/unit/filters.ts +++ b/test/unit/filters.ts @@ -1,10 +1,6 @@ -import * as chai from 'chai' -import * as chaiAsPromised from 'chai-as-promised' +import { expect } from 'chai' import Liquid from '../../src/liquid' -chai.use(chaiAsPromised) -const expect = chai.expect - const ctx = { date: new Date(), foo: 'bar', @@ -21,12 +17,13 @@ const ctx = { } let liquid -function test (src, dst) { - return expect(liquid.parseAndRender(src, ctx)).to.eventually.equal(dst) +async function test (src, dst) { + const html = await liquid.parseAndRender(src, ctx) + return expect(html).to.equal(dst) } describe('filters', function () { - before(() => liquid = new Liquid()) + before(() => { liquid = new Liquid() }) describe('abs', function () { it('should return 3 for -3', () => test('{{ -3 | abs }}', '3')) it('should return 2 for arr[0]', () => test('{{ arr[0] | abs }}', '2')) diff --git a/test/unit/liquid.ts b/test/unit/liquid.ts index a831078b1..3bf00f677 100644 --- a/test/unit/liquid.ts +++ b/test/unit/liquid.ts @@ -7,13 +7,13 @@ const expect = chai.expect describe('Liquid', function () { describe('#constructor()', 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 () { it('should call plugin on the instance', async function () { const engine = new Liquid() - engine.plugin(function (Liquid) { + engine.plugin(function () { this.registerFilter('foo', x => `foo${x}foo`) }) const html = await engine.parseAndRender('{{"bar"|foo}}') diff --git a/test/unit/options/cache.ts b/test/unit/options/cache.ts index 0a2e61c56..7ac742cd2 100644 --- a/test/unit/options/cache.ts +++ b/test/unit/options/cache.ts @@ -1,10 +1,6 @@ -import * as chai from 'chai' +import { expect } from 'chai' import * as mock from 'mock-fs' import Liquid from '../../../src/liquid' -import * as chaiAsPromised from 'chai-as-promised' - -const expect = chai.expect -chai.use(chaiAsPromised) describe('LiquidOptions#cache', function () { let engine diff --git a/test/unit/options/strict.ts b/test/unit/options/strict.ts index 24ac99f2a..04c30d53d 100644 --- a/test/unit/options/strict.ts +++ b/test/unit/options/strict.ts @@ -1,8 +1,5 @@ -import Liquid from '../../../src/liquid' -import * as chai from 'chai' - -const expect = chai.expect -chai.use(require('chai-as-promised')) +import Liquid from 'src/liquid' +import { expect } from 'chai' describe('LiquidOptions#strict_*', function () { let engine @@ -13,9 +10,9 @@ describe('LiquidOptions#strict_*', function () { extname: '.html' }) }) - it('should not throw when strict_variables false (default)', function () { - return expect(engine.parseAndRender('before{{notdefined}}after', ctx)).to - .eventually.equal('beforeafter') + it('should not throw when strict_variables false (default)', async function () { + const html = await engine.parseAndRender('before{{notdefined}}after', ctx) + return expect(html).to.equal('beforeafter') }) it('should throw when strict_variables true', function () { const tpl = engine.parse('before{{notdefined}}after') diff --git a/test/unit/options/trimming.ts b/test/unit/options/trimming.ts index f5be96e4d..899aced70 100644 --- a/test/unit/options/trimming.ts +++ b/test/unit/options/trimming.ts @@ -1,62 +1,58 @@ -import * as chai from 'chai' +import { expect } from 'chai' import Liquid from '../../../src/liquid' -import * as chaiAsPromised from 'chai-as-promised' - -const expect = chai.expect -chai.use(chaiAsPromised) describe('LiquidOptions#trimming', function () { const ctx = { name: 'harttle' } 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 }) - return expect(engine.parseAndRender(' \n \t{%if true%}foo{%endif%} ')) - .to.eventually.equal('foo ') + const html = await engine.parseAndRender(' \n \t{%if true%}foo{%endif%} ') + 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 }) - return expect(engine.parseAndRender('\t{%if true%}foo{%endif%} \n')) - .to.eventually.equal('\tfoo') + const html = engine.parseAndRender('\t{%if true%}foo{%endif%} \n') + 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 }) - return expect(engine.parseAndRender('{%if true%}a {{name}} b{%endif%}', ctx)) - .to.eventually.equal('a harttle b') + const html = await engine.parseAndRender('{%if true%}a {{name}} b{%endif%}', ctx) + return expect(html).to.equal('a harttle b') }) }) 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 }) - return expect(engine.parseAndRender(' \n \t{{name}} ', ctx)) - .to.eventually.equal('harttle ') + const html = await engine.parseAndRender(' \n \t{{name}} ', ctx) + 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 }) - return expect(engine.parseAndRender(' \n \t{{name}} ', ctx)) - .to.eventually.equal(' \n \tharttle') + const html = await engine.parseAndRender(' \n \t{{name}} ', ctx) + 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 }) - return expect(engine.parseAndRender('\t{% if true %} aha {%endif%}\t')) - .to.eventually.equal('\t aha \t') + const html = await engine.parseAndRender('\t{% if true %} aha {%endif%}\t') + return expect(html).to.equal('\t aha \t') }) }) describe('greedy', function () { 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() - return expect(engine.parseAndRender(src, ctx)) - .to.eventually.equal('aharttle') + const html = await engine.parseAndRender(src, ctx) + 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 }) - return expect(engine.parseAndRender(src, ctx)) - .to.eventually.equal('\n a \nharttle ') + const html = await engine.parseAndRender(src, ctx) + return expect(html).to.equal('\n a \nharttle ') }) }) describe('markup', function () { - it('should support trim using markup', function () { + it('should support trim using markup', async function () { const engine = new Liquid() const src = [ '{%- assign username = "John G. Chalmers-Smith" -%}', @@ -67,9 +63,10 @@ describe('LiquidOptions#trimming', function () { '{%- endif -%}' ].join('\n') 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 src = [ '{% assign username = "John G. Chalmers-Smith" %}', @@ -80,7 +77,8 @@ describe('LiquidOptions#trimming', function () { '{% endif %}' ].join('\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) }) }) }) diff --git a/test/unit/output.ts b/test/unit/output.ts index a279e2738..0d970af41 100644 --- a/test/unit/output.ts +++ b/test/unit/output.ts @@ -1,14 +1,9 @@ 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 Output from '../../src/template/output' +import OutputToken from 'src/parser/output-token' import Filter from 'src/template/filter' -chai.use(sinonChai) -chai.use(chaiAsPromised) - const expect = chai.expect describe('Output', function () { @@ -16,41 +11,51 @@ describe('Output', function () { Filter.clear() }) - it('should respect to .to_liquid() method', function () { + it('should respect to .to_liquid() method', async function () { 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({ 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 ctx.foo.circular = ctx - const scope = new Scope(ctx) - return expect(new Output({value: 'foo'}).render(scope)).to.eventually.equal('{"num":2,"circular":{"bar":"bar"}}') + const output = new Output({ value: 'foo' } as OutputToken) + 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 } }) - 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 () => { 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') }) it('should respect to .to_s()', async () => { 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') }) it('should respect to .liquid_method_missing()', async () => { 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') }) }) diff --git a/test/unit/render.ts b/test/unit/render.ts index 49d0254c1..f80345cea 100644 --- a/test/unit/render.ts +++ b/test/unit/render.ts @@ -1,24 +1,14 @@ -import * as chai from 'chai' -import * as chaiAsPromised from 'chai-as-promised' -import * as sinonChai from 'sinon-chai' -import * as sinon from 'sinon' +import { expect } from 'chai' 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 Filter from 'src/template/filter' import Render from '../../src/render/render' -import Parser from '../../src/parser/parser' 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 () { - beforeEach(function () { + let render + before(function () { Filter.clear() Tag.clear() render = new Render() @@ -29,10 +19,11 @@ describe('render', function () { expect(render.renderTemplates([])).to.be.rejectedWith(/scope undefined/) }) - it('should render html', function () { + it('should render html', async function () { const scope = new Scope() const token = { type: 'html', value: '

' } as Token - return expect(render.renderTemplates([new HTML(token)], scope)).to.eventually.equal('

') + const html = await render.renderTemplates([new HTML(token)], scope) + return expect(html).to.equal('

') }) }) }) diff --git a/test/unit/tag.ts b/test/unit/tag.ts index 7f8cc5647..ef8701bcb 100644 --- a/test/unit/tag.ts +++ b/test/unit/tag.ts @@ -1,14 +1,14 @@ import * as chai from 'chai' import Tag from 'src/template/tag/tag' -import TagToken from 'src/parser/tag-token' import Scope from 'src/scope/scope' import * as sinon from 'sinon' import * as sinonChai from 'sinon-chai' import Liquid from 'src/liquid' +import TagToken from 'src/parser/tag-token' chai.use(sinonChai) const expect = chai.expect -const liquid = new Liquid(); +const liquid = new Liquid() describe('tag', function () { let scope @@ -29,14 +29,14 @@ describe('tag', function () { type: 'tag', value: 'foo', name: 'foo' - }, [], liquid) + } as TagToken, [], liquid) }).to.throw(/tag foo not found/) }) it('should register simple tag', function () { expect(function () { Tag.register('foo', { - render: x => 'bar' + render: () => 'bar' }) }).not.throw() }) @@ -50,7 +50,7 @@ describe('tag', function () { type: 'tag', value: 'foo', name: 'foo' - } + } as TagToken await new Tag(token, [], liquid).render(scope) expect(spy).to.have.been.called }) diff --git a/test/unit/tags/assign.ts b/test/unit/tags/assign.ts index f88ac497a..f21dcffc0 100644 --- a/test/unit/tags/assign.ts +++ b/test/unit/tags/assign.ts @@ -1,9 +1,8 @@ import Liquid from 'src/liquid' -import * as chai from 'chai' -import * as sinonChai from 'chai-as-promised' +import { expect, use } from 'chai' +import * as chaiAsPromised from 'chai-as-promised' -chai.use(sinonChai) -const expect = chai.expect +use(chaiAsPromised) describe('tags/assign', function () { const liquid = new Liquid() @@ -12,65 +11,69 @@ describe('tags/assign', function () { const ctx = {} 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}}' - return expect(liquid.parseAndRender(src)) - .to.eventually.equal('bar') + const html = await liquid.parseAndRender(src) + 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}}' - return expect(liquid.parseAndRender(src)) - .to.eventually.equal('10086') + const html = await liquid.parseAndRender(src) + 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 src = '{% assign foo="FOO" %}{{foo}}' - return liquid.parseAndRender(src, ctx) - .then(x => { - expect(x).to.equal('FOO') - expect(ctx.foo).to.equal('foo') - }) + const html = await liquid.parseAndRender(src, ctx) + expect(html).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}}' - return expect(liquid.parseAndRender(src)) - .to.eventually.equal('[1,2,3]') + const html = await liquid.parseAndRender(src) + 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}}' - return expect(liquid.parseAndRender(src)) - .to.eventually.equal('A') + const html = await liquid.parseAndRender(src) + 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" | capitalize | split: " " | first %}{{foo}}` - return expect(liquid.parseAndRender(src)) - .to.eventually.equal('A') + const html = await liquid.parseAndRender(src) + 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 }}' - 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- }}' - 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 }}' - 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 }}' - 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 }}' - 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 }}' - return expect(liquid.parseAndRender(src)).to.eventually.equal('-6') + const html = await liquid.parseAndRender(src) + return expect(html).to.equal('-6') }) }) diff --git a/test/unit/tags/capture.ts b/test/unit/tags/capture.ts index 6e824328a..5a3b89872 100644 --- a/test/unit/tags/capture.ts +++ b/test/unit/tags/capture.ts @@ -1,26 +1,24 @@ 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 -chai.use(require('chai-as-promised')) +use(chaiAsPromised) describe('tags/capture', function () { const liquid = new Liquid() - it('should support capture', function () { + it('should support capture', async function () { const src = '{% capture f %}{{"a" | capitalize}}{%endcapture%}{{f}}' - return expect(liquid.parseAndRender(src)) - .to.eventually.equal('A') + const html = await liquid.parseAndRender(src) + 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 ctx = { 'var': 20 } - return liquid.parseAndRender(src, ctx) - .then(x => { - expect(x).to.equal('10') - expect(ctx.var).to.equal(20) - }) + const html = await liquid.parseAndRender(src, ctx) + expect(html).to.equal('10') + expect(ctx.var).to.equal(20) }) it('should throw on invalid identifier', function () { diff --git a/test/unit/tags/case.ts b/test/unit/tags/case.ts index 10595485c..483f5ec69 100644 --- a/test/unit/tags/case.ts +++ b/test/unit/tags/case.ts @@ -1,8 +1,8 @@ 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 -chai.use(require('chai-as-promised')) +use(chaiAsPromised) describe('tags/case', function () { const liquid = new Liquid() @@ -12,42 +12,42 @@ describe('tags/case', function () { return expect(liquid.parseAndRender(src)) .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"%}' + '{% when "foo" %}foo{% when "bar"%}bar' + '{%endcase%}' - return expect(liquid.parseAndRender(src)) - .to.eventually.equal('foo') + const html = await liquid.parseAndRender(src) + 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 %}' + '{% when "foo" %}foo{% when ""%}bar' + '{%endcase%}' const ctx = { empty: '' } - return expect(liquid.parseAndRender(src, ctx)) - .to.eventually.equal('bar') + const html = await liquid.parseAndRender(src, ctx) + 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 %}' + '{% when "foo" %}foo{% when ""%}bar' + '{%endcase%}' - return expect(liquid.parseAndRender(src)) - .to.eventually.equal('') + const html = await liquid.parseAndRender(src) + return expect(html).to.equal('') }) - it('should support boolean case', function () { + it('should support boolean case', async function () { const src = '{% case false %}' + '{% when "foo" %}foo{% when false%}bar' + '{%endcase%}' - return expect(liquid.parseAndRender(src)) - .to.eventually.equal('bar') + const html = await liquid.parseAndRender(src) + return expect(html).to.equal('bar') }) - it('should support else branch', function () { + it('should support else branch', async function () { const src = '{% case "a" %}' + '{% when "b" %}b{% when "c"%}c{%else %}d' + '{%endcase%}' - return expect(liquid.parseAndRender(src)) - .to.eventually.equal('d') + const html = await liquid.parseAndRender(src) + return expect(html).to.equal('d') }) }) diff --git a/test/unit/tags/comment.ts b/test/unit/tags/comment.ts index 14aaabc6e..cdd3644cb 100644 --- a/test/unit/tags/comment.ts +++ b/test/unit/tags/comment.ts @@ -1,8 +1,8 @@ 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 -chai.use(require('chai-as-promised')) +use(chaiAsPromised) describe('tags/comment', function () { const liquid = new Liquid() @@ -11,24 +11,24 @@ describe('tags/comment', function () { return expect(liquid.parseAndRender(src)) .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.' - return expect(liquid.parseAndRender(src)) - .to.eventually.equal('My name is Shopify.') + const html = await liquid.parseAndRender(src) + 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 %}' - return expect(liquid.parseAndRender(src)) - .to.eventually.equal('') + const html = await liquid.parseAndRender(src) + 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 %}' - return expect(liquid.parseAndRender(src)) - .to.eventually.equal('') + const html = await liquid.parseAndRender(src) + 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 %}' - return expect(liquid.parseAndRender(src)) - .to.eventually.equal('') + const html = await liquid.parseAndRender(src) + return expect(html).to.equal('') }) }) diff --git a/test/unit/tags/cycle.ts b/test/unit/tags/cycle.ts index fa965fae3..2c25cea59 100644 --- a/test/unit/tags/cycle.ts +++ b/test/unit/tags/cycle.ts @@ -1,16 +1,16 @@ 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 -chai.use(require('chai-as-promised')) +use(chaiAsPromised) describe('tags/cycle', function () { const liquid = new Liquid() - it('should support cycle', function () { + it('should support cycle', async function () { const src = "{% cycle '1', '2', '3' %}" - return expect(liquid.parseAndRender(src + src + src + src)) - .to.eventually.equal('1231') + const html = await liquid.parseAndRender(src + src + src + src) + return expect(html).to.equal('1231') }) it('should throw when cycle candidates empty', function () { @@ -18,23 +18,21 @@ describe('tags/cycle', function () { .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 ctx = { one: 1 } - return expect(liquid.parseAndRender(src, ctx)) - .to.eventually.equal('1e1e1') + const html = await liquid.parseAndRender(src, ctx) + 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'%}" + "{% cycle 1: '1', '2', '3'%}" + "{% cycle 2: '1', '2', '3'%}" - const ctx = { - one: 1 - } - return expect(liquid.parseAndRender(src, ctx)) - .to.eventually.equal('121') + const ctx = { one: 1 } + const html = await liquid.parseAndRender(src, ctx) + return expect(html).to.equal('121') }) }) diff --git a/test/unit/tags/decrement.ts b/test/unit/tags/decrement.ts index 44a7a5bf5..6dcf5ff7d 100644 --- a/test/unit/tags/decrement.ts +++ b/test/unit/tags/decrement.ts @@ -1,8 +1,8 @@ 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 -chai.use(require('chai-as-promised')) +use(chaiAsPromised) describe('tags/decrement', function () { const liquid = new Liquid() @@ -12,49 +12,47 @@ describe('tags/decrement', function () { 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 %}' - return expect(liquid.parseAndRender(src)) - .to.eventually.equal('-1-2-3') + const html = await liquid.parseAndRender(src) + 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 ctx = { 'var': 10 } - return liquid.parseAndRender(src, ctx) - .then(x => { - expect(x).to.equal('987') - expect(ctx.var).to.equal(7) - }) + const html = await liquid.parseAndRender(src, ctx) + expect(html).to.equal('987') + 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 %}' - return expect(liquid.parseAndRender(src)) - .to.eventually.equal('-1-2-3') + const html = await liquid.parseAndRender(src) + 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 %}' - return expect(liquid.parseAndRender(src)) - .to.eventually.equal('-1-2-3') + const html = await liquid.parseAndRender(src) + 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}}' - return expect(liquid.parseAndRender(src)) - .to.eventually.equal('-1-2-3 10') + const html = await liquid.parseAndRender(src) + 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}}' - return expect(liquid.parseAndRender(src)) - .to.eventually.equal('-1-2-3 10') + const html = await liquid.parseAndRender(src) + 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%}' - return expect(liquid.parseAndRender(src)) - .to.eventually.equal('01100') + const html = await liquid.parseAndRender(src) + return expect(html).to.equal('01100') }) }) diff --git a/test/unit/tags/for.ts b/test/unit/tags/for.ts index f16f6770b..db56b3c1b 100644 --- a/test/unit/tags/for.ts +++ b/test/unit/tags/for.ts @@ -1,8 +1,8 @@ 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 -chai.use(require('chai-as-promised')) +use(chaiAsPromised) describe('tags/for', function () { let liquid, ctx @@ -22,28 +22,28 @@ describe('tags/for', function () { emptyArray: [] } }) - it('should support array', function () { + it('should support array', async function () { const src = '{%for c in alpha%}{{c}}{%endfor%}' - return expect(liquid.parseAndRender(src, ctx)) - .to.eventually.equal('abc') + const html = await liquid.parseAndRender(src, ctx) + 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%}' - return expect(liquid.parseAndRender(src, ctx)) - .to.eventually.equal('foo,bar-coo,haa-') + const html = await liquid.parseAndRender(src, ctx) + return expect(html).to.equal('foo,bar-coo,haa-') }) 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%}' - return expect(liquid.parseAndRender(src, { num: 1 })) - .to.eventually.equal('11') + const html = await liquid.parseAndRender(src, { num: 1 }) + 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%}' - return expect(liquid.parseAndRender(src, { num: 1 })) - .to.eventually.equal('12') + const html = await liquid.parseAndRender(src, { num: 1 }) + return expect(html).to.equal('12') }) }) @@ -62,45 +62,45 @@ describe('tags/for', 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%}' - return expect(liquid.parseAndRender(src, ctx)) - .to.eventually.equal('b') + const html = await liquid.parseAndRender(src, ctx) + 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%}' - return expect(liquid.parseAndRender(src, ctx)) - .to.eventually.equal('xabc') + const html = await liquid.parseAndRender(src, ctx) + 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%}' - return expect(liquid.parseAndRender(src, ctx)) - .to.eventually.equal('b') + const html = await liquid.parseAndRender(src, ctx) + 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 const src = '{%for c in strObj%}a{%else%}b{%endfor%}' - return expect(liquid.parseAndRender(src, ctx)) - .to.eventually.equal('b') + const html = await liquid.parseAndRender(src, ctx) + 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%}' - return expect(liquid.parseAndRender(src, ctx)) - .to.eventually.equal('b') + const html = await liquid.parseAndRender(src, ctx) + 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%}' - return expect(liquid.parseAndRender(src, ctx)) - .to.eventually.equal('b') + const html = await liquid.parseAndRender(src, ctx) + 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%}' + '{{forloop.first}}.{{forloop.index}}.{{forloop.index0}}.' + '{{forloop.last}}.{{forloop.length}}.' + @@ -110,41 +110,41 @@ describe('tags/for', function () { const dst = 'true.1.0.false.3.3.2a\n' + 'false.2.1.false.3.2.1b\n' + 'false.3.2.true.3.1.0c\n' - 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 for with continue', function () { + it('should support for with continue', async function () { const src = '{% for i in (1..5) %}' + '{{i}}{% continue %}after' + '{% endfor %}' - return expect(liquid.parseAndRender(src, ctx)) - .to.eventually.equal('12345') + const html = await liquid.parseAndRender(src, ctx) + 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) %}' + '{% if i == 4 %}{% break %}{% endif %}' + '{{ i }}' + '{% endfor %}' - return expect(liquid.parseAndRender(src, ctx)) - .to.eventually.equal('123') + const html = await liquid.parseAndRender(src, ctx) + return expect(html).to.equal('123') }) 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 %}' - return expect(liquid.parseAndRender(src, ctx)) - .to.eventually.equal('12') + const html = await liquid.parseAndRender(src, ctx) + 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%}' - return expect(liquid.parseAndRender(src, ctx)) - .to.eventually.equal('false true ') + const html = await liquid.parseAndRender(src, ctx) + 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%}' - return expect(liquid.parseAndRender(src, ctx)) - .to.eventually.equal('true false ') + const html = await liquid.parseAndRender(src, ctx) + return expect(html).to.equal('true false ') }) it('should set forloop.length properly', function () { 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 () { - 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 %}' - return expect(liquid.parseAndRender(src, ctx)) - .to.eventually.equal('67') + const html = await liquid.parseAndRender(src, ctx) + 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%}' - return expect(liquid.parseAndRender(src, ctx)) - .to.eventually.equal('1 2 ') + const html = await liquid.parseAndRender(src, ctx) + 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%}' - return expect(liquid.parseAndRender(src, ctx)) - .to.eventually.equal('0 1 ') + const html = await liquid.parseAndRender(src, ctx) + 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%}' - return expect(liquid.parseAndRender(src, ctx)) - .to.eventually.equal('2 1 ') + const html = await liquid.parseAndRender(src, ctx) + 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%}' - return expect(liquid.parseAndRender(src, ctx)) - .to.eventually.equal('1 0 ') + const html = await liquid.parseAndRender(src, ctx) + return expect(html).to.equal('1 0 ') }) }) 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 %}' - return expect(liquid.parseAndRender(src, ctx)) - .to.eventually.equal('21') + const html = await liquid.parseAndRender(src, ctx) + 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 %}' - return expect(liquid.parseAndRender(src, ctx)) - .to.eventually.equal('21') + const html = await liquid.parseAndRender(src, ctx) + 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 %}' - return expect(liquid.parseAndRender(src, ctx)) - .to.eventually.equal('543') + const html = await liquid.parseAndRender(src, ctx) + return expect(html).to.equal('543') }) }) }) diff --git a/test/unit/tags/if.ts b/test/unit/tags/if.ts index 407f1f5be..c624a21e1 100644 --- a/test/unit/tags/if.ts +++ b/test/unit/tags/if.ts @@ -1,8 +1,5 @@ import Liquid from 'src/liquid' -import * as chai from 'chai' - -const expect = chai.expect -chai.use(require('chai-as-promised')) +import { expect } from 'chai' describe('tags/if', function () { const liquid = new Liquid() @@ -18,99 +15,99 @@ describe('tags/if', function () { return expect(liquid.parseAndRender(src, ctx)) .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%}' - return expect(liquid.parseAndRender(src, ctx)) - .to.eventually.equal('') + const html = await liquid.parseAndRender(src, ctx) + return expect(html).to.equal('') }) 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%}' - return expect(liquid.parseAndRender(src, ctx)) - .to.eventually.equal('2') + const html = await liquid.parseAndRender(src, ctx) + 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%}' - return expect(liquid.parseAndRender(src, ctx)) - .to.eventually.equal('a') + const html = await liquid.parseAndRender(src, ctx) + 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%}' - return expect(liquid.parseAndRender(src, ctx)) - .to.eventually.equal('a') + const html = await liquid.parseAndRender(src, ctx) + return expect(html).to.equal('a') }) }) describe('expression as condition', function () { - it('should support ==', function () { + it('should support ==', async function () { const src = '{% if 2==3 %}yes{%else%}no{%endif%}' - return expect(liquid.parseAndRender(src, ctx)) - .to.eventually.equal('no') + const html = await liquid.parseAndRender(src, ctx) + return expect(html).to.equal('no') }) - it('should support >=', function () { + it('should support >=', async function () { const src = '{% if 1>=2 and one 10', function () { + it('should evaluate false for null > 10', async function () { const src = '{% if null > 10 %}yes{% else %}no{% endif %}' - return expect(liquid.parseAndRender(src, ctx)) - .to.eventually.equal('no') + const html = await liquid.parseAndRender(src, ctx) + 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 %}' - return expect(liquid.parseAndRender(src, ctx)) - .to.eventually.equal('no') + const html = await liquid.parseAndRender(src, ctx) + 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 %}' - return expect(liquid.parseAndRender(src, ctx)) - .to.eventually.equal('no') + const html = await liquid.parseAndRender(src, ctx) + 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 %}' - return expect(liquid.parseAndRender(src, ctx)) - .to.eventually.equal('no') + const html = await liquid.parseAndRender(src, ctx) + 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 %}' - return expect(liquid.parseAndRender(src, ctx)) - .to.eventually.equal('no') + const html = await liquid.parseAndRender(src, ctx) + 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 %}' - return expect(liquid.parseAndRender(src, ctx)) - .to.eventually.equal('no') + const html = await liquid.parseAndRender(src, ctx) + 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 %}' - return expect(liquid.parseAndRender(src, ctx)) - .to.eventually.equal('no') + const html = await liquid.parseAndRender(src, ctx) + return expect(html).to.equal('no') }) }) }) diff --git a/test/unit/tags/include.ts b/test/unit/tags/include.ts index 798df1e32..eeeff8d55 100644 --- a/test/unit/tags/include.ts +++ b/test/unit/tags/include.ts @@ -1,9 +1,6 @@ import Liquid from 'src/liquid' +import { expect } from 'chai' 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 () { let liquid @@ -16,21 +13,21 @@ describe('tags/include', function () { afterEach(function () { mock.restore() }) - it('should support include', function () { + it('should support include', async function () { mock({ '/current.html': 'bar{% include "bar/foo.html" %}bar', '/bar/foo.html': 'foo' }) - return expect(liquid.renderFile('/current.html')).to - .eventually.equal('barfoobar') + const html = await liquid.renderFile('/current.html') + return expect(html).to.equal('barfoobar') }) - it('should support template string', function () { + it('should support template string', async function () { mock({ '/current.html': 'bar{% include "bar/{{name}}" %}bar', '/bar/foo.html': 'foo' }) - return expect(liquid.renderFile('/current.html', { name: 'foo.html' })).to - .eventually.equal('barfoobar') + const html = await liquid.renderFile('/current.html', { name: 'foo.html' }) + return expect(html).to.equal('barfoobar') }) 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({ '/bar/foo.html': 'foo', '/foo/relative.html': 'bar{% include "../bar/foo.html" %}bar' }) - return expect(liquid.renderFile('foo/relative.html')).to - .eventually.equal('barfoobar') + const html = await liquid.renderFile('foo/relative.html') + return expect(html).to.equal('barfoobar') }) - it('should support include: hash list', function () { + it('should support include: hash list', async function () { mock({ '/hash.html': '{% assign name="harttle" %}{% include "user.html", role: "admin", alias: name %}', '/user.html': '{{name}} : {{role}} : {{alias}}' }) - return expect(liquid.renderFile('hash.html')).to - .eventually.equal('harttle : admin : harttle') + const html = await liquid.renderFile('hash.html') + return expect(html).to.equal('harttle : admin : harttle') }) - it('should support include: parent scope', function () { + it('should support include: parent scope', async function () { mock({ '/scope.html': '{% assign shape="triangle" %}{% assign color="yellow" %}{% include "color.html" %}', '/color.html': 'color:{{color}}, shape:{{shape}}' }) - return expect(liquid.renderFile('scope.html')).to - .eventually.equal('color:yellow, shape:triangle') + const html = await liquid.renderFile('scope.html') + return expect(html).to.equal('color:yellow, shape:triangle') }) - it('should support include: with', function () { + it('should support include: with', async function () { mock({ '/with.html': '{% include "color" with "red", shape: "rect" %}', '/color.html': 'color:{{color}}, shape:{{shape}}' }) - return expect(liquid.renderFile('with.html')).to - .eventually.equal('color:red, shape:rect') + const html = await liquid.renderFile('with.html') + return expect(html).to.equal('color:red, shape:rect') }) - it('should support nested includes', function () { + it('should support nested includes', async function () { mock({ '/personInfo.html': 'This is a person {% include "card.html" %}', '/card.html': '

{{person.firstName}} {{person.lastName}}
{% include "address" %}

', @@ -104,49 +101,49 @@ describe('tags/include', function () { } } } - return expect(liquid.renderFile('personInfo.html', ctx)).to - .eventually.equal('This is a person

Joe Shmoe
City: Dallas

') + const html = await liquid.renderFile('personInfo.html', ctx) + return expect(html).to.equal('This is a person

Joe Shmoe
City: Dallas

') }) describe('static partial', function () { - it('should support filename with extention', function () { + it('should support filename with extention', async function () { mock({ '/parent.html': 'X{% include child.html color:"red" %}Y', '/child.html': 'child with {{color}}' }) const staticLiquid = new Liquid({ dynamicPartials: false, root: '/' }) - return expect(staticLiquid.renderFile('parent.html')).to - .eventually.equal('Xchild with redY') + const html = await staticLiquid.renderFile('parent.html') + return expect(html).to.equal('Xchild with redY') }) - it('should support parent paths', function () { + it('should support parent paths', async function () { mock({ '/parent.html': 'X{% include bar/./../foo/child.html %}Y', '/foo/child.html': 'child' }) const staticLiquid = new Liquid({ dynamicPartials: false, root: '/' }) - return expect(staticLiquid.renderFile('parent.html')).to - .eventually.equal('XchildY') + const html = await staticLiquid.renderFile('parent.html') + return expect(html).to.equal('XchildY') }) - it('should support subpaths', function () { + it('should support subpaths', async function () { mock({ '/parent.html': 'X{% include foo/child.html %}Y', '/foo/child.html': 'child' }) const staticLiquid = new Liquid({ dynamicPartials: false, root: '/' }) - return expect(staticLiquid.renderFile('parent.html')).to - .eventually.equal('XchildY') + const html = await staticLiquid.renderFile('parent.html') + return expect(html).to.equal('XchildY') }) - it('should support comma separated arguments', function () { + it('should support comma separated arguments', async function () { mock({ '/parent.html': 'X{% include child.html, color:"red" %}Y', '/child.html': 'child with {{color}}' }) const staticLiquid = new Liquid({ dynamicPartials: false, root: '/' }) - return expect(staticLiquid.renderFile('parent.html')).to - .eventually.equal('Xchild with redY') + const html = await staticLiquid.renderFile('parent.html') + return expect(html).to.equal('Xchild with redY') }) }) }) diff --git a/test/unit/tags/increment.ts b/test/unit/tags/increment.ts index cc8b0527e..3a9420412 100644 --- a/test/unit/tags/increment.ts +++ b/test/unit/tags/increment.ts @@ -1,49 +1,47 @@ 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 -chai.use(require('chai-as-promised')) +use(chaiAsPromised) describe('tags/increment', function () { 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 %}' - return expect(liquid.parseAndRender(src)) - .to.eventually.equal('012') + const html = await liquid.parseAndRender(src) + 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 ctx = { one: 7 } - return liquid.parseAndRender(src, ctx) - .then(x => { - expect(x).to.equal('789') - expect(ctx.one).to.equal(10) - }) + const html = await liquid.parseAndRender(src, ctx) + expect(html).to.equal('789') + 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 %}' - return expect(liquid.parseAndRender(src)) - .to.eventually.equal('012') + const html = await liquid.parseAndRender(src) + 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 %}' - return expect(liquid.parseAndRender(src)) - .to.eventually.equal('012') + const html = await liquid.parseAndRender(src) + 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}}' - return expect(liquid.parseAndRender(src)) - .to.eventually.equal('012 10') + const html = await liquid.parseAndRender(src) + 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}}' - return expect(liquid.parseAndRender(src)) - .to.eventually.equal('012 10') + const html = await liquid.parseAndRender(src) + return expect(html).to.equal('012 10') }) }) diff --git a/test/unit/tags/layout.ts b/test/unit/tags/layout.ts index 7e2f845a8..1cfc2a957 100644 --- a/test/unit/tags/layout.ts +++ b/test/unit/tags/layout.ts @@ -1,9 +1,6 @@ import Liquid from 'src/liquid' +import { expect } from 'chai' 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 () { let liquid @@ -35,51 +32,51 @@ describe('tags/layout', function () { }) }) describe('anonymous block', function () { - it('should handle anonymous block', function () { + it('should handle anonymous block', async function () { mock({ '/parent.html': 'X{%block%}{%endblock%}Y' }) const src = '{% layout "parent.html" %}{%block%}A{%endblock%}' - return expect(liquid.parseAndRender(src)).to - .eventually.equal('XAY') + const html = await liquid.parseAndRender(src) + 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({ '/parent.html': 'X{%block%}{%endblock%}Y' }) const src = '{% layout "parent.html" %}A' - return expect(liquid.parseAndRender(src)).to - .eventually.equal('XAY') + const html = await liquid.parseAndRender(src) + return expect(html).to.equal('XAY') }) }) - it('should handle named blocks', function () { + it('should handle named blocks', async function () { mock({ '/parent.html': 'X{% block "a"%}{% endblock %}Y{% block b%}{%endblock%}Z' }) const src = '{% layout "parent.html" %}' + '{%block a%}A{%endblock%}' + '{%block b%}B{%endblock%}' - return expect(liquid.parseAndRender(src)).to - .eventually.equal('XAYBZ') + const html = await liquid.parseAndRender(src) + return expect(html).to.equal('XAYBZ') }) - it('should support default block content', function () { + it('should support default block content', async function () { mock({ '/parent.html': 'X{% block "a"%}A{% endblock %}Y{% block b%}B{%endblock%}Z' }) const src = '{% layout "parent.html" %}{%block a%}a{%endblock%}' - return expect(liquid.parseAndRender(src)).to - .eventually.equal('XaYBZ') + const html = await liquid.parseAndRender(src) + return expect(html).to.equal('XaYBZ') }) - it('should handle nested block', function () { + it('should handle nested block', async function () { mock({ '/grand.html': 'X{%block a%}G{%endblock%}Y', '/parent.html': '{%layout "grand" %}{%block a%}P{%endblock%}', '/main.html': '{%layout "parent"%}{%block a%}A{%endblock%}' }) - return expect(liquid.renderFile('/main.html')).to - .eventually.equal('XAY') + const html = await liquid.renderFile('/main.html') + 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({ '/parent.html': 'X{%block a%}{%endblock%}Y{%block b%}{%endblock%}Z', '/main.html': '{%layout "parent"%}' + @@ -87,55 +84,55 @@ describe('tags/layout', function () { '{%block b%}I{%include "included"%}J{%endblock%}', '/included.html': '{%layout "parent"%}{%block a%}a{%endblock%}' }) - return expect(liquid.renderFile('main')).to - .eventually.equal('XAYIXaYZJZ') + const html = await liquid.renderFile('main') + return expect(html).to.equal('XAYIXaYZJZ') }) - it('should support hash list', function () { + it('should support hash list', async function () { mock({ '/parent.html': '{{color}}{%block%}{%endblock%}', '/main.html': '{% layout "parent.html" color:"black"%}{%block%}A{%endblock%}' }) - return expect(liquid.renderFile('/main.html')).to - .eventually.equal('blackA') + const html = await liquid.renderFile('/main.html') + return expect(html).to.equal('blackA') }) - it('should support multiple hash', function () { + it('should support multiple hash', async function () { mock({ '/parent.html': '{{color}}{{bg}}{%block%}{%endblock%}', '/main.html': '{% layout "parent.html" color:"black", bg:"red"%}{%block%}A{%endblock%}' }) - return expect(liquid.renderFile('/main.html')).to - .eventually.equal('blackredA') + const html = await liquid.renderFile('/main.html') + return expect(html).to.equal('blackredA') }) describe('static partial', function () { - it('should support filename with extention', function () { + it('should support filename with extention', async function () { mock({ '/parent.html': '{{color}}{%block%}{%endblock%}', '/main.html': '{% layout parent.html color:"black"%}{%block%}A{%endblock%}' }) const staticLiquid = new Liquid({ root: '/', dynamicPartials: false }) - return expect(staticLiquid.renderFile('/main.html')).to - .eventually.equal('blackA') + const html = await staticLiquid.renderFile('/main.html') + return expect(html).to.equal('blackA') }) - it('should support parent paths', function () { + it('should support parent paths', async function () { mock({ '/foo/parent.html': '{{color}}{%block%}{%endblock%}', '/main.html': '{% layout bar/../foo/parent.html color:"black"%}{%block%}A{%endblock%}' }) const staticLiquid = new Liquid({ root: '/', dynamicPartials: false }) - return expect(staticLiquid.renderFile('/main.html')).to - .eventually.equal('blackA') + const html = await staticLiquid.renderFile('/main.html') + return expect(html).to.equal('blackA') }) - it('should support subpaths', function () { + it('should support subpaths', async function () { mock({ '/foo/parent.html': '{{color}}{%block%}{%endblock%}', '/main.html': '{% layout foo/parent.html color:"black"%}{%block%}A{%endblock%}' }) const staticLiquid = new Liquid({ root: '/', dynamicPartials: false }) - return expect(staticLiquid.renderFile('/main.html')).to - .eventually.equal('blackA') + const html = await staticLiquid.renderFile('/main.html') + return expect(html).to.equal('blackA') }) }) }) diff --git a/test/unit/tags/raw.ts b/test/unit/tags/raw.ts index a86ae7eae..c499badca 100644 --- a/test/unit/tags/raw.ts +++ b/test/unit/tags/raw.ts @@ -1,8 +1,5 @@ import Liquid from 'src/liquid' -import * as chai from 'chai' - -const expect = chai.expect -chai.use(require('chai-as-promised')) +import { expect } from 'chai' describe('tags/raw', function () { const liquid = new Liquid() @@ -13,11 +10,13 @@ describe('tags/raw', function () { it('should support raw 2', async function () { const src = '{% raw %}{{ 5 | plus: 6 }}{% endraw %} 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 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) }) }) diff --git a/test/unit/tags/tablerow.ts b/test/unit/tags/tablerow.ts index 0cc1e8169..fc736aec2 100644 --- a/test/unit/tags/tablerow.ts +++ b/test/unit/tags/tablerow.ts @@ -1,19 +1,17 @@ import Liquid from 'src/liquid' -import * as chai from 'chai' - -const expect = chai.expect -chai.use(require('chai-as-promised')) +import { expect } from 'chai' describe('tags/tablerow', function () { 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 dst = '123' - 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 ctx = { alpha: ['a', 'b', 'c'] @@ -21,25 +19,29 @@ describe('tags/tablerow', function () { const dst = 'ab' + 'c' - 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 dst = '123' - 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 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 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 () { @@ -48,26 +50,29 @@ describe('tags/tablerow', function () { .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 dst = '12' + '34' + '5' - 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 dst = '12' + '3' - 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 dst = '45' - return expect(liquid.parseAndRender(src)).to.eventually.equal(dst) + const html = await liquid.parseAndRender(src) + return expect(html).to.equal(dst) }) }) diff --git a/test/unit/tags/unless.ts b/test/unit/tags/unless.ts index efe8078eb..37eac9c1b 100644 --- a/test/unit/tags/unless.ts +++ b/test/unit/tags/unless.ts @@ -1,37 +1,37 @@ 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 -chai.use(require('chai-as-promised')) +use(chaiAsPromised) describe('tags/unless', function () { let 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 const src = '{% unless 0 %}yes{%else%}no{%endunless%}' - return expect(liquid.parseAndRender(src)) - .to.eventually.equal('no') + const html = await liquid.parseAndRender(src) + 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%}' - return expect(liquid.parseAndRender(src)) - .to.eventually.equal('yes') + const html = await liquid.parseAndRender(src) + return expect(html).to.equal('yes') }) it('should reject when tag not closed', function () { const src = '{% unless 1>2 %}yes' return expect(liquid.parseAndRender(src)) .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%}' - return expect(liquid.parseAndRender(src)) - .to.eventually.equal('yes') + const html = await liquid.parseAndRender(src) + 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%}' - return expect(liquid.parseAndRender(src)) - .to.eventually.equal('') + const html = await liquid.parseAndRender(src) + return expect(html).to.equal('') }) }) diff --git a/test/unit/template-browser.ts b/test/unit/template-browser.ts index a92b57566..8989c3d02 100644 --- a/test/unit/template-browser.ts +++ b/test/unit/template-browser.ts @@ -1,7 +1,5 @@ import { resolve } from '../../src/parser/template-browser' -import * as chai from 'chai' - -const expect = chai.expect +import { expect } from 'chai' describe('template-browser', function () { if (+process.version.match(/^v(\d+)/)[1] < 8) { diff --git a/test/unit/template.ts b/test/unit/template.ts index 55270717e..146549a07 100644 --- a/test/unit/template.ts +++ b/test/unit/template.ts @@ -1,11 +1,7 @@ import { resolve } from '../../src/parser/template' import * as mock from 'mock-fs' -import * as chai from 'chai' +import { expect } from 'chai' import * as path from 'path' -import * as chaiAsPromised from 'chai-as-promised' - -const expect = chai.expect -chai.use(chaiAsPromised) describe('template', function () { before(function () { @@ -14,10 +10,10 @@ describe('template', function () { }) }) describe('#resolve()', function () { - it('should resolve based on root', function () { - const filepath = resolve('bar.html', '/foo', { root: [] }) + it('should resolve based on root', async function () { + const filepath = await resolve('bar.html', '/foo', { root: [] }) 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 () { return expect(resolve('foo.html', '/foo', { root: [] })) diff --git a/test/unit/tokenizer.ts b/test/unit/tokenizer.ts index c74693efb..1171e1696 100644 --- a/test/unit/tokenizer.ts +++ b/test/unit/tokenizer.ts @@ -1,14 +1,15 @@ import { expect } from 'chai' -import { parse } from 'src/parser/tokenizer' +import Tokenizer from 'src/parser/tokenizer' import TagToken from 'src/parser/tag-token' import OutputToken from 'src/parser/output-token' import HTMLToken from 'src/parser/html-token' describe('tokenizer', function () { + const tokenizer = new Tokenizer() describe('parse', function () { it('should handle plain HTML', function () { const html = '

Lorem Ipsum

' - const tokens = parse(html) + const tokens = tokenizer.tokenize(html) expect(tokens.length).to.equal(1) expect(tokens[0].value).to.equal(html) @@ -16,7 +17,7 @@ describe('tokenizer', function () { }) it('should handle tag syntax', function () { const html = '

{% for p in a[1]%}

' - const tokens = parse(html) + const tokens = tokenizer.tokenize(html) expect(tokens.length).to.equal(3) expect(tokens[1]).instanceOf(TagToken) @@ -24,7 +25,7 @@ describe('tokenizer', function () { }) it('should handle value syntax', function () { const html = '

{{foo | date: "%Y-%m-%d"}}

' - const tokens = parse(html) + const tokens = tokenizer.tokenize(html) expect(tokens.length).to.equal(3) expect(tokens[1]).instanceOf(OutputToken) @@ -32,7 +33,7 @@ describe('tokenizer', function () { }) it('should handle consecutive value and tags', function () { const html = '{{foo}}{{bar}}{%foo%}{%bar%}' - const tokens = parse(html) + const tokens = tokenizer.tokenize(html) expect(tokens.length).to.equal(4) expect(tokens[0]).instanceOf(OutputToken) @@ -43,7 +44,7 @@ describe('tokenizer', function () { }) it('should keep white spaces and newlines', function () { const html = '{%foo%}\n{%bar %} \n {%alice%}' - const tokens = parse(html) + const tokens = tokenizer.tokenize(html) expect(tokens.length).to.equal(5) expect(tokens[1]).instanceOf(HTMLToken) expect(tokens[1].raw).to.equal('\n') @@ -52,7 +53,7 @@ describe('tokenizer', function () { }) it('should handle multiple lines tag', function () { 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[0]).instanceOf(TagToken) 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 () { 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[0]).instanceOf(OutputToken) expect(tokens[0].raw).to.equal('{{foo\n|date:\n"%Y-%m-%d"\n}}') diff --git a/test/unit/util/error.ts b/test/unit/util/error.ts index dda291c76..fc065475e 100644 --- a/test/unit/util/error.ts +++ b/test/unit/util/error.ts @@ -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 chai from 'chai' import * as path from 'path' -const expect = chai.expect -chai.use(require('chai-as-promised')) - let engine = new Liquid() const strictEngine = new Liquid({ strict_variables: true, @@ -111,8 +108,9 @@ describe('error', function () { expect(err.name).to.equal('RenderError') expect(err.message).to.contain('throwed by filter') }) - it('should not throw when variable undefined by default', function () { - return expect(engine.parseAndRender('X{{a}}Y')).to.eventually.equal('XY') + it('should not throw when variable undefined by default', async function () { + const html = await engine.parseAndRender('X{{a}}Y') + return expect(html).to.equal('XY') }) it('should throw RenderError when variable not defined', async function () { const err = await expect(strictEngine.parseAndRender('{{a}}')).be.rejected diff --git a/test/unit/util/promise.ts b/test/unit/util/promise.ts index 01d43de7d..1c551a99f 100644 --- a/test/unit/util/promise.ts +++ b/test/unit/util/promise.ts @@ -1,8 +1,9 @@ -const chai = require('chai') -const sinon = require('sinon') +import * as chai from 'chai' +import * as sinon from 'sinon' +import * as sinonChai from 'sinon-chai' + const expect = chai.expect -chai.use(require('chai-as-promised')) -chai.use(require('sinon-chai')) +chai.use(sinonChai) const P = require('../../../src/util/promise') @@ -32,10 +33,12 @@ describe('util/promise', function () { item => Promise.reject(new Error(item))) return expect(p).to.be.rejectedWith('third') }) - it('should resolve the value that first callback resolved', () => { - const p = P.anySeries(['first', 'second'], - item => Promise.resolve(item)) - return expect(p).to.eventually.equal('first') + it('should resolve the value that first callback resolved', async () => { + const result = await P.anySeries( + ['first', 'second'], + item => Promise.resolve(item) + ) + return expect(result).to.equal('first') }) it('should not call rest of callbacks once resolved', () => { const spy = sinon.spy() @@ -50,10 +53,12 @@ describe('util/promise', function () { }) }) describe('.mapSeries()', function () { - it('should resolve when all resolved', function () { - const p = P.mapSeries(['first', 'second', 'third'], - item => Promise.resolve(item)) - return expect(p).to.eventually.deep.equal(['first', 'second', 'third']) + it('should resolve when all resolved', async function () { + const result = P.mapSeries( + ['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', () => { const p = P.mapSeries(['first', 'second'], @@ -66,7 +71,7 @@ describe('util/promise', function () { return P .mapSeries( ['first', 'second'], - (item, idx) => new Promise(function (resolve, reject) { + (item, idx) => new Promise(function (resolve) { if (idx === 0) { setTimeout(function () { spy1() diff --git a/test/unit/value.ts b/test/unit/value.ts index 3749bab19..2941081dc 100644 --- a/test/unit/value.ts +++ b/test/unit/value.ts @@ -1,5 +1,4 @@ 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' @@ -7,7 +6,6 @@ import Filter from 'src/template/filter' import Value from 'src/template/value' chai.use(sinonChai) -chai.use(chaiAsPromised) const expect = chai.expect const add = (l, r) => l + r @@ -41,7 +39,6 @@ describe('Value', function () { expect(tpl.filters.length).to.equal(2) }) - it('should eval value', function () { Filter.register('date', (l, r) => l + r) Filter.register('time', (l, r) => l + 3 * r) diff --git a/test/unit/xhr.ts b/test/unit/xhr.ts index 3ff80636c..94bdc6d77 100644 --- a/test/unit/xhr.ts +++ b/test/unit/xhr.ts @@ -1,12 +1,11 @@ import { read } from 'src/parser/template-browser' 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('template-browser', () => { +describe('xhr', () => { if (+process.version.match(/^v(\d+)/)[1] < 8) { console.info('jsdom not supported, skipping xhr...') return @@ -24,9 +23,9 @@ describe('template-browser', () => { delete (global as any).XMLHttpRequest }) describe('#read()', () => { - it('should get corresponding text', () => { - return expect(read('https://example.com/views/hello.html')) - .to.eventually.equal('hello {{name}}') + it('should get corresponding text', async function () { + const html = await read('https://example.com/views/hello.html') + return expect(html).to.equal('hello {{name}}') }) it('should throw 404', () => { return expect(read('https://example.com/not/exist.html'))