mirror of
https://github.com/harttle/liquidjs.git
synced 2026-10-04 17:45:13 -07:00
chore: migrate test cases from Chai to Jest
This commit is contained in:
@@ -0,0 +1,9 @@
|
|||||||
|
/** @type {import('ts-jest').JestConfigWithTsJest} */
|
||||||
|
module.exports = {
|
||||||
|
preset: 'ts-jest',
|
||||||
|
testEnvironment: 'node',
|
||||||
|
testMatch: ['**/*.spec.ts'],
|
||||||
|
collectCoverageFrom: [
|
||||||
|
'src/**/*.ts'
|
||||||
|
]
|
||||||
|
}
|
||||||
Generated
+6277
-24377
File diff suppressed because it is too large
Load Diff
+10
-16
@@ -16,8 +16,8 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"lint": "eslint \"**/*.mjs\" \"**/*.ts\" .",
|
"lint": "eslint \"**/*.mjs\" \"**/*.ts\" .",
|
||||||
"check": "npm run build && npm test && npm run lint && npm run perf:diff",
|
"check": "npm run build && npm test && npm run lint && npm run perf:diff",
|
||||||
"test": "nyc mocha \"test/**/*.ts\"",
|
"test": "jest --coverage",
|
||||||
"test:e2e": "mocha \"test/e2e/**/*.ts\"",
|
"test:e2e": "jest test/e2e",
|
||||||
"perf": "cd benchmark && npm ci && npm start",
|
"perf": "cd benchmark && npm ci && npm start",
|
||||||
"perf:diff": "bin/perf-diff.sh",
|
"perf:diff": "bin/perf-diff.sh",
|
||||||
"perf:engines": "cd benchmark && npm run engines",
|
"perf:engines": "cd benchmark && npm run engines",
|
||||||
@@ -63,23 +63,18 @@
|
|||||||
"@semantic-release/changelog": "^3.0.2",
|
"@semantic-release/changelog": "^3.0.2",
|
||||||
"@semantic-release/commit-analyzer": "^6.1.0",
|
"@semantic-release/commit-analyzer": "^6.1.0",
|
||||||
"@semantic-release/git": "^7.0.8",
|
"@semantic-release/git": "^7.0.8",
|
||||||
"@semantic-release/npm": "^5.1.8",
|
"@semantic-release/npm": "^9.0.2",
|
||||||
"@semantic-release/release-notes-generator": "^7.1.4",
|
"@semantic-release/release-notes-generator": "^7.1.4",
|
||||||
"@types/benchmark": "^1.0.31",
|
"@types/benchmark": "^1.0.31",
|
||||||
"@types/chai": "^4.1.7",
|
|
||||||
"@types/chai-as-promised": "^7.1.0",
|
|
||||||
"@types/express": "^4.17.2",
|
"@types/express": "^4.17.2",
|
||||||
|
"@types/jest": "^29.4.0",
|
||||||
"@types/jsdom": "^12.2.2",
|
"@types/jsdom": "^12.2.2",
|
||||||
"@types/mocha": "^5.2.6",
|
"@types/sinon": "^10.0.13",
|
||||||
"@types/sinon": "^7.0.6",
|
|
||||||
"@types/sinon-chai": "^3.2.2",
|
|
||||||
"@types/supertest": "^2.0.7",
|
"@types/supertest": "^2.0.7",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.6.0",
|
"@typescript-eslint/eslint-plugin": "^5.6.0",
|
||||||
"@typescript-eslint/parser": "^5.6.0",
|
"@typescript-eslint/parser": "^5.6.0",
|
||||||
"all-contributors-cli": "^6.24.0",
|
"all-contributors-cli": "^6.24.0",
|
||||||
"benchmark": "^2.1.4",
|
"benchmark": "^2.1.4",
|
||||||
"chai": "^4.2.0",
|
|
||||||
"chai-as-promised": "^7.1.1",
|
|
||||||
"coveralls": "^3.0.2",
|
"coveralls": "^3.0.2",
|
||||||
"cross-env": "^5.2.0",
|
"cross-env": "^5.2.0",
|
||||||
"eslint": "^7.32.0",
|
"eslint": "^7.32.0",
|
||||||
@@ -92,22 +87,21 @@
|
|||||||
"eslint-plugin-standard": "^4.0.0",
|
"eslint-plugin-standard": "^4.0.0",
|
||||||
"express": "^4.16.4",
|
"express": "^4.16.4",
|
||||||
"husky": "^4.2.5",
|
"husky": "^4.2.5",
|
||||||
|
"jest": "^29.5.0",
|
||||||
"jsdom": "^16.5.0",
|
"jsdom": "^16.5.0",
|
||||||
"mocha": "^9.0.1",
|
|
||||||
"nyc": "^15.1.0",
|
|
||||||
"regenerator-runtime": "^0.12.1",
|
"regenerator-runtime": "^0.12.1",
|
||||||
"rollup": "^2.61.0",
|
"rollup": "^2.61.0",
|
||||||
"rollup-plugin-replace": "^2.1.0",
|
"rollup-plugin-replace": "^2.1.0",
|
||||||
"rollup-plugin-typescript2": "^0.31.1",
|
"rollup-plugin-typescript2": "^0.31.1",
|
||||||
"rollup-plugin-uglify": "^6.0.4",
|
"rollup-plugin-uglify": "^5.0.2",
|
||||||
"rollup-plugin-version-injector": "^1.3.3",
|
"rollup-plugin-version-injector": "^1.3.3",
|
||||||
"semantic-release": "^19.0.3",
|
"semantic-release": "^19.0.3",
|
||||||
"sinon": "^7.5.0",
|
"sinon": "^15.0.2",
|
||||||
"sinon-chai": "^3.3.0",
|
|
||||||
"supertest": "^3.4.2",
|
"supertest": "^3.4.2",
|
||||||
|
"ts-jest": "^29.0.5",
|
||||||
"ts-node": "^8.0.2",
|
"ts-node": "^8.0.2",
|
||||||
"tslib": "^2.3.1",
|
"tslib": "^2.3.1",
|
||||||
"typedoc": "^0.19.2",
|
"typedoc": "^0.23.26",
|
||||||
"typedoc-plugin-markdown": "^2.2.17",
|
"typedoc-plugin-markdown": "^2.2.17",
|
||||||
"typescript": "^4.5.3"
|
"typescript": "^4.5.3"
|
||||||
},
|
},
|
||||||
|
|||||||
+3
-3
@@ -42,17 +42,17 @@ const input = './src/index.ts'
|
|||||||
const browserFS = {
|
const browserFS = {
|
||||||
include: './src/liquid-options.ts',
|
include: './src/liquid-options.ts',
|
||||||
delimiters: ['', ''],
|
delimiters: ['', ''],
|
||||||
'./fs/node': './fs/browser'
|
'./fs/fs-impl': './build/fs-impl-browser'
|
||||||
}
|
}
|
||||||
const browserStream = {
|
const browserStream = {
|
||||||
include: './src/emitters/index.ts',
|
include: './src/emitters/index.ts',
|
||||||
delimiters: ['', ''],
|
delimiters: ['', ''],
|
||||||
'./streamed-emitter': './streamed-emitter-browser'
|
'./streamed-emitter': '../build/streamed-emitter-browser'
|
||||||
}
|
}
|
||||||
const esmRequire = {
|
const esmRequire = {
|
||||||
include: './src/fs/node.ts',
|
include: './src/fs/node.ts',
|
||||||
delimiters: ['', ''],
|
delimiters: ['', ''],
|
||||||
'./node-require': './node-require.mjs'
|
'./node-require': '../build/node-require.mjs'
|
||||||
}
|
}
|
||||||
|
|
||||||
const nodeCjs = {
|
const nodeCjs = {
|
||||||
|
|||||||
@@ -1,16 +1,12 @@
|
|||||||
import * as fs from '../../../src/fs/browser'
|
import * as fs from './fs-impl-browser'
|
||||||
import * as sinon from 'sinon'
|
import * as sinon from 'sinon'
|
||||||
import { expect, use } from 'chai'
|
import { JSDOM } from 'jsdom'
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
|
|
||||||
use(chaiAsPromised)
|
|
||||||
|
|
||||||
describe('fs/browser', function () {
|
describe('fs/browser', function () {
|
||||||
if (+(process.version.match(/^v(\d+)/) as RegExpMatchArray)[1] < 8) {
|
if (+(process.version.match(/^v(\d+)/) as RegExpMatchArray)[1] < 8) {
|
||||||
console.info('jsdom not supported, skipping template-browser...')
|
console.info('jsdom not supported, skipping template-browser...')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const JSDOM = require('jsdom').JSDOM
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
const dom = new JSDOM(``, {
|
const dom = new JSDOM(``, {
|
||||||
url: 'https://example.com/foo/bar/',
|
url: 'https://example.com/foo/bar/',
|
||||||
@@ -24,51 +20,51 @@ describe('fs/browser', function () {
|
|||||||
})
|
})
|
||||||
describe('#resolve()', function () {
|
describe('#resolve()', function () {
|
||||||
it('should support relative root', function () {
|
it('should support relative root', function () {
|
||||||
expect(fs.resolve('./views/', 'foo', '')).to.equal('https://example.com/foo/bar/views/foo')
|
expect(fs.resolve('./views/', 'foo', '')).toBe('https://example.com/foo/bar/views/foo')
|
||||||
})
|
})
|
||||||
it('should treat root as directory', function () {
|
it('should treat root as directory', function () {
|
||||||
expect(fs.resolve('./views', 'foo', '')).to.equal('https://example.com/foo/bar/views/foo')
|
expect(fs.resolve('./views', 'foo', '')).toBe('https://example.com/foo/bar/views/foo')
|
||||||
})
|
})
|
||||||
it('should support absolute root', function () {
|
it('should support absolute root', function () {
|
||||||
expect(fs.resolve('/views', 'foo', '')).to.equal('https://example.com/views/foo')
|
expect(fs.resolve('/views', 'foo', '')).toBe('https://example.com/views/foo')
|
||||||
})
|
})
|
||||||
it('should support empty root', function () {
|
it('should support empty root', function () {
|
||||||
expect(fs.resolve('', 'page.html', '')).to.equal('https://example.com/foo/bar/page.html')
|
expect(fs.resolve('', 'page.html', '')).toBe('https://example.com/foo/bar/page.html')
|
||||||
})
|
})
|
||||||
it('should support full url as root', function () {
|
it('should support full url as root', function () {
|
||||||
expect(fs.resolve('https://example.com/views/', 'page.html', '')).to.equal('https://example.com/views/page.html')
|
expect(fs.resolve('https://example.com/views/', 'page.html', '')).toBe('https://example.com/views/page.html')
|
||||||
})
|
})
|
||||||
it('should add extname when absent', function () {
|
it('should add extname when absent', function () {
|
||||||
expect(fs.resolve('https://example.com/views/', 'page', '.html')).to.equal('https://example.com/views/page.html')
|
expect(fs.resolve('https://example.com/views/', 'page', '.html')).toBe('https://example.com/views/page.html')
|
||||||
})
|
})
|
||||||
it('should add extname for urls have searchParams', function () {
|
it('should add extname for urls have searchParams', function () {
|
||||||
expect(fs.resolve('https://example.com/views/', 'page?foo=bar', '.html')).to.equal('https://example.com/views/page.html?foo=bar')
|
expect(fs.resolve('https://example.com/views/', 'page?foo=bar', '.html')).toBe('https://example.com/views/page.html?foo=bar')
|
||||||
})
|
})
|
||||||
it('should not add extname when full url is given', function () {
|
it('should not add extname when full url is given', function () {
|
||||||
expect(fs.resolve('https://example.com/views/', 'https://google.com/page.php', '.html')).to.equal('https://google.com/page.php')
|
expect(fs.resolve('https://example.com/views/', 'https://google.com/page.php', '.html')).toBe('https://google.com/page.php')
|
||||||
})
|
})
|
||||||
it('should not add extname when already have one', function () {
|
it('should not add extname when already have one', function () {
|
||||||
expect(fs.resolve('https://example.com/views/', 'page.php', '.html')).to.equal('https://example.com/views/page.php')
|
expect(fs.resolve('https://example.com/views/', 'page.php', '.html')).toBe('https://example.com/views/page.php')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('#dirname()', () => {
|
describe('#dirname()', () => {
|
||||||
it('should return dirname of file', async function () {
|
it('should return dirname of file', async function () {
|
||||||
const val = fs.dirname('https://example.com/views/foo/bar')
|
const val = fs.dirname('https://example.com/views/foo/bar')
|
||||||
expect(val).to.equal('https://example.com/views/foo/')
|
expect(val).toBe('https://example.com/views/foo/')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('#exists()', () => {
|
describe('#exists()', () => {
|
||||||
it('should always return true', async function () {
|
it('should always return true', async function () {
|
||||||
const val = await fs.exists('/foo/bar')
|
const val = await fs.exists('/foo/bar')
|
||||||
expect(val).to.equal(true)
|
expect(val).toBe(true)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('#existsSync()', () => {
|
describe('#existsSync()', () => {
|
||||||
it('should always return true', function () {
|
it('should always return true', function () {
|
||||||
expect(fs.existsSync('/foo/bar')).to.equal(true)
|
expect(fs.existsSync('/foo/bar')).toBe(true)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -87,15 +83,15 @@ describe('fs/browser', function () {
|
|||||||
})
|
})
|
||||||
it('should get corresponding text', async function () {
|
it('should get corresponding text', async function () {
|
||||||
const html = await fs.readFile('https://example.com/views/hello.html')
|
const html = await fs.readFile('https://example.com/views/hello.html')
|
||||||
return expect(html).to.equal('hello {{name}}')
|
return expect(html).toBe('hello {{name}}')
|
||||||
})
|
})
|
||||||
it('should throw 404', () => {
|
it('should throw 404', () => {
|
||||||
return expect(fs.readFile('https://example.com/not/exist.html'))
|
return expect(fs.readFile('https://example.com/not/exist.html'))
|
||||||
.to.be.rejectedWith('Not Found')
|
.rejects.toHaveProperty('message', 'Not Found')
|
||||||
})
|
})
|
||||||
it('should throw error', function () {
|
it('should throw error', function () {
|
||||||
const result = expect(fs.readFile('https://example.com/views/hello.html'))
|
const result = expect(fs.readFile('https://example.com/views/hello.html'))
|
||||||
.to.be.rejectedWith('An error occurred whilst receiving the response.')
|
.rejects.toHaveProperty('message', 'An error occurred whilst receiving the response.')
|
||||||
server.requests[0].error()
|
server.requests[0].error()
|
||||||
return result
|
return result
|
||||||
})
|
})
|
||||||
@@ -118,11 +114,11 @@ describe('fs/browser', function () {
|
|||||||
})
|
})
|
||||||
it('should get corresponding text', function () {
|
it('should get corresponding text', function () {
|
||||||
const html = fs.readFileSync('https://example.com/views/hello.html')
|
const html = fs.readFileSync('https://example.com/views/hello.html')
|
||||||
return expect(html).to.equal('hello {{name}}')
|
return expect(html).toBe('hello {{name}}')
|
||||||
})
|
})
|
||||||
it('should throw 404', () => {
|
it('should throw 404', () => {
|
||||||
return expect(() => fs.readFileSync('https://example.com/not/exist.html'))
|
return expect(() => fs.readFileSync('https://example.com/not/exist.html'))
|
||||||
.to.throw('Not Found')
|
.toThrow('Not Found')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import { StreamedEmitter } from './streamed-emitter-browser'
|
||||||
|
|
||||||
|
describe('build/streamed-emitter-browser', () => {
|
||||||
|
it('should throw when try to constructing', () => {
|
||||||
|
expect(() => new StreamedEmitter()).toThrow(/streaming not supported/)
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Emitter } from './emitter'
|
import { Emitter } from '../emitters'
|
||||||
|
|
||||||
export class StreamedEmitter implements Emitter {
|
export class StreamedEmitter implements Emitter {
|
||||||
public buffer = '';
|
public buffer = '';
|
||||||
+26
-27
@@ -1,68 +1,67 @@
|
|||||||
import { expect } from 'chai'
|
import { LRU } from './lru'
|
||||||
import { LRU } from '../../../src/cache/lru'
|
|
||||||
|
|
||||||
describe('LRU', () => {
|
describe('LRU', () => {
|
||||||
it('should perform read()/write()', () => {
|
it('should perform read()/write()', () => {
|
||||||
const lru = new LRU(2)
|
const lru = new LRU(2)
|
||||||
expect(lru.limit).to.equal(2)
|
expect(lru.limit).toEqual(2)
|
||||||
|
|
||||||
lru.write('foo', 'FOO')
|
lru.write('foo', 'FOO')
|
||||||
lru.write('bar', 'BAR')
|
lru.write('bar', 'BAR')
|
||||||
expect(lru.read('foo')).to.equal('FOO')
|
expect(lru.read('foo')).toEqual('FOO')
|
||||||
expect(lru.read('bar')).to.equal('BAR')
|
expect(lru.read('bar')).toEqual('BAR')
|
||||||
})
|
})
|
||||||
it('should perform clear()', () => {
|
it('should perform clear()', () => {
|
||||||
const lru = new LRU(2)
|
const lru = new LRU(2)
|
||||||
lru.write('foo', 'FOO')
|
lru.write('foo', 'FOO')
|
||||||
lru.write('bar', 'BAR')
|
lru.write('bar', 'BAR')
|
||||||
expect(lru.size).to.equal(2)
|
expect(lru.size).toEqual(2)
|
||||||
lru.clear()
|
lru.clear()
|
||||||
expect(lru.size).to.equal(0)
|
expect(lru.size).toEqual(0)
|
||||||
expect(lru.read('foo')).to.be.undefined
|
expect(lru.read('foo')).toBe(undefined)
|
||||||
})
|
})
|
||||||
it('should remove lrc item when full(limit=-1)', () => {
|
it('should remove lrc item when full(limit=-1)', () => {
|
||||||
const lru = new LRU(-1)
|
const lru = new LRU(-1)
|
||||||
lru.write('foo', 'FOO')
|
lru.write('foo', 'FOO')
|
||||||
lru.write('bar', 'BAR')
|
lru.write('bar', 'BAR')
|
||||||
expect(lru.size).to.equal(0)
|
expect(lru.size).toEqual(0)
|
||||||
expect(lru.read('foo')).to.be.undefined
|
expect(lru.read('foo')).toBe(undefined)
|
||||||
expect(lru.read('bar')).to.be.undefined
|
expect(lru.read('bar')).toBe(undefined)
|
||||||
})
|
})
|
||||||
it('should remove lrc item when full(limit=0)', () => {
|
it('should remove lrc item when full(limit=0)', () => {
|
||||||
const lru = new LRU(0)
|
const lru = new LRU(0)
|
||||||
lru.write('foo', 'FOO')
|
lru.write('foo', 'FOO')
|
||||||
lru.write('bar', 'BAR')
|
lru.write('bar', 'BAR')
|
||||||
expect(lru.size).to.equal(0)
|
expect(lru.size).toEqual(0)
|
||||||
expect(lru.read('foo')).to.be.undefined
|
expect(lru.read('foo')).toBe(undefined)
|
||||||
expect(lru.read('bar')).to.be.undefined
|
expect(lru.read('bar')).toBe(undefined)
|
||||||
})
|
})
|
||||||
it('should remove lrc item when full(limit=1)', () => {
|
it('should remove lrc item when full(limit=1)', () => {
|
||||||
const lru = new LRU(1)
|
const lru = new LRU(1)
|
||||||
lru.write('foo', 'FOO')
|
lru.write('foo', 'FOO')
|
||||||
lru.write('bar', 'BAR')
|
lru.write('bar', 'BAR')
|
||||||
expect(lru.size).to.equal(1)
|
expect(lru.size).toEqual(1)
|
||||||
expect(lru.read('foo')).to.be.undefined
|
expect(lru.read('foo')).toBe(undefined)
|
||||||
expect(lru.read('bar')).to.equal('BAR')
|
expect(lru.read('bar')).toEqual('BAR')
|
||||||
})
|
})
|
||||||
it('should remove lrc item when full(limit=2)', () => {
|
it('should remove lrc item when full(limit=2)', () => {
|
||||||
const lru = new LRU(2)
|
const lru = new LRU(2)
|
||||||
expect(lru.size).to.equal(0)
|
expect(lru.size).toEqual(0)
|
||||||
lru.write('foo', 'FOO')
|
lru.write('foo', 'FOO')
|
||||||
expect(lru.size).to.equal(1)
|
expect(lru.size).toEqual(1)
|
||||||
lru.write('bar', 'BAR')
|
lru.write('bar', 'BAR')
|
||||||
expect(lru.size).to.equal(2)
|
expect(lru.size).toEqual(2)
|
||||||
lru.write('coo', 'COO')
|
lru.write('coo', 'COO')
|
||||||
expect(lru.size).to.equal(2)
|
expect(lru.size).toEqual(2)
|
||||||
expect(lru.read('foo')).to.be.undefined
|
expect(lru.read('foo')).toBe(undefined)
|
||||||
expect(lru.read('bar')).to.equal('BAR')
|
expect(lru.read('bar')).toEqual('BAR')
|
||||||
expect(lru.read('coo')).to.equal('COO')
|
expect(lru.read('coo')).toEqual('COO')
|
||||||
})
|
})
|
||||||
it('should overwrite item the with same key', () => {
|
it('should overwrite item the with same key', () => {
|
||||||
const lru = new LRU(2)
|
const lru = new LRU(2)
|
||||||
lru.write('foo', 'FOO')
|
lru.write('foo', 'FOO')
|
||||||
expect(lru.size).to.equal(1)
|
expect(lru.size).toEqual(1)
|
||||||
lru.write('foo', 'BAR')
|
lru.write('foo', 'BAR')
|
||||||
expect(lru.size).to.equal(1)
|
expect(lru.size).toEqual(1)
|
||||||
expect(lru.read('foo')).to.equal('BAR')
|
expect(lru.read('foo')).toEqual('BAR')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,8 +1,5 @@
|
|||||||
import * as chai from 'chai'
|
import { Context } from './context'
|
||||||
import { Context } from '../../../src/context/context'
|
import { Scope } from './scope'
|
||||||
import { Scope } from '../../../src/context/scope'
|
|
||||||
|
|
||||||
const expect = chai.expect
|
|
||||||
|
|
||||||
describe('Context', function () {
|
describe('Context', function () {
|
||||||
let ctx: any, scope: Scope
|
let ctx: any, scope: Scope
|
||||||
@@ -30,67 +27,68 @@ describe('Context', function () {
|
|||||||
|
|
||||||
describe('#get()', function () {
|
describe('#get()', function () {
|
||||||
it('should get direct property', async function () {
|
it('should get direct property', async function () {
|
||||||
expect(ctx.get(['foo'])).equal('zoo')
|
expect(ctx.get(['foo'])).toEqual('zoo')
|
||||||
})
|
})
|
||||||
it('should read nested property', async function () {
|
it('should read nested property', async function () {
|
||||||
expect(ctx.get(['obj', 'first'])).to.equal('f')
|
expect(ctx.get(['obj', 'first'])).toEqual('f')
|
||||||
expect(ctx.get(['obj', 'last'])).to.equal('l')
|
expect(ctx.get(['obj', 'last'])).toEqual('l')
|
||||||
expect(ctx.get(['obj', 'size'])).to.equal(2)
|
expect(ctx.get(['obj', 'size'])).toEqual(2)
|
||||||
})
|
})
|
||||||
it('undefined property should yield undefined', async function () {
|
it('undefined property should yield undefined', async function () {
|
||||||
expect(ctx.get(['notdefined'])).to.equal(undefined)
|
expect(ctx.get(['notdefined'])).toEqual(undefined)
|
||||||
expect(ctx.get([false as any])).to.equal(undefined)
|
expect(ctx.get([false as any])).toEqual(undefined)
|
||||||
})
|
})
|
||||||
it('should respect to toLiquid', async function () {
|
it('should respect to toLiquid', async function () {
|
||||||
const scope = new Context({ foo: {
|
const scope = new Context({ foo: {
|
||||||
toLiquid: () => ({ bar: 'BAR' }),
|
toLiquid: () => ({ bar: 'BAR' }),
|
||||||
bar: 'bar'
|
bar: 'bar'
|
||||||
} })
|
} })
|
||||||
expect(scope.get(['foo', 'bar'])).to.equal('BAR')
|
// eslint-disable-next-line deprecation/deprecation
|
||||||
|
expect(scope.get(['foo', 'bar'])).toEqual('BAR')
|
||||||
})
|
})
|
||||||
it('should return undefined when not exist', async function () {
|
it('should return undefined when not exist', async function () {
|
||||||
expect(ctx.get(['foo', 'foo', 'foo'])).to.be.undefined
|
expect(ctx.get(['foo', 'foo', 'foo'])).toBeUndefined()
|
||||||
})
|
})
|
||||||
it('should return string length as size', async function () {
|
it('should return string length as size', async function () {
|
||||||
expect(ctx.get(['foo', 'size'])).to.equal(3)
|
expect(ctx.get(['foo', 'size'])).toEqual(3)
|
||||||
})
|
})
|
||||||
it('should return array length as size', async function () {
|
it('should return array length as size', async function () {
|
||||||
expect(ctx.get(['bar', 'arr', 'size'])).to.equal(2)
|
expect(ctx.get(['bar', 'arr', 'size'])).toEqual(2)
|
||||||
})
|
})
|
||||||
it('should return map size as size', async function () {
|
it('should return map size as size', async function () {
|
||||||
expect(ctx.get(['map', 'size'])).to.equal(1)
|
expect(ctx.get(['map', 'size'])).toEqual(1)
|
||||||
})
|
})
|
||||||
it('should return undefined if not have a size', async function () {
|
it('should return undefined if not have a size', async function () {
|
||||||
expect(ctx.get(['one', 'size'])).to.equal(undefined)
|
expect(ctx.get(['one', 'size'])).toBeUndefined()
|
||||||
expect(ctx.get(['non-exist', 'size'])).to.equal(undefined)
|
expect(ctx.get(['non-exist', 'size'])).toBeUndefined()
|
||||||
})
|
})
|
||||||
it('should read .first of array', async function () {
|
it('should read .first of array', async function () {
|
||||||
expect(ctx.get(['bar', 'arr', 'first'])).to.equal('a')
|
expect(ctx.get(['bar', 'arr', 'first'])).toEqual('a')
|
||||||
})
|
})
|
||||||
it('should read .last of array', async function () {
|
it('should read .last of array', async function () {
|
||||||
expect(ctx.get(['bar', 'arr', 'last'])).to.equal('b')
|
expect(ctx.get(['bar', 'arr', 'last'])).toEqual('b')
|
||||||
})
|
})
|
||||||
it('should read element of array', async function () {
|
it('should read element of array', async function () {
|
||||||
expect(ctx.get(['arr', 1])).to.equal('b')
|
expect(ctx.get(['arr', 1])).toEqual('b')
|
||||||
})
|
})
|
||||||
it('should read element of array from end', async function () {
|
it('should read element of array from end', async function () {
|
||||||
expect(ctx.get(['arr', -2])).to.equal('c')
|
expect(ctx.get(['arr', -2])).toEqual('c')
|
||||||
})
|
})
|
||||||
it('should call function', async function () {
|
it('should call function', async function () {
|
||||||
expect(ctx.get(['func'])).to.equal('FUNC')
|
expect(ctx.get(['func'])).toEqual('FUNC')
|
||||||
})
|
})
|
||||||
it('should call function before read nested property', async function () {
|
it('should call function before read nested property', async function () {
|
||||||
expect(ctx.get(['objFunc', 'prop'])).to.equal('PROP')
|
expect(ctx.get(['objFunc', 'prop'])).toEqual('PROP')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('#getFromScope()', function () {
|
describe('#getFromScope()', function () {
|
||||||
it('should support string', () => {
|
it('should support string', () => {
|
||||||
expect(ctx.getFromScope({ obj: { foo: 'FOO' } }, 'obj.foo')).to.equal('FOO')
|
expect(ctx.getFromScope({ obj: { foo: 'FOO' } }, 'obj.foo')).toEqual('FOO')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('strictVariables', async function () {
|
describe('strictVariables', function () {
|
||||||
let ctx: Context
|
let ctx: Context
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
ctx = new Context(ctx, {
|
ctx = new Context(ctx, {
|
||||||
@@ -98,26 +96,26 @@ describe('Context', function () {
|
|||||||
} as any)
|
} as any)
|
||||||
})
|
})
|
||||||
it('should throw when variable not defined', function () {
|
it('should throw when variable not defined', function () {
|
||||||
return expect(() => ctx.get(['notdefined'])).to.throw(/undefined variable: notdefined/)
|
return expect(() => ctx.getSync(['notdefined'])).toThrow(/undefined variable: notdefined/)
|
||||||
})
|
})
|
||||||
it('should throw when deep variable not exist', async function () {
|
it('should throw when deep variable not exist', async function () {
|
||||||
ctx.push({ foo: 'FOO' })
|
ctx.push({ foo: 'FOO' })
|
||||||
return expect(() => ctx.get(['foo', 'bar', 'not', 'defined'])).to.throw(/undefined variable: foo.bar/)
|
return expect(() => ctx.getSync(['foo', 'bar', 'not', 'defined'])).toThrow(/undefined variable: foo.bar/)
|
||||||
})
|
})
|
||||||
it('should throw when itself not defined', async function () {
|
it('should throw when itself not defined', async function () {
|
||||||
ctx.push({ foo: 'FOO' })
|
ctx.push({ foo: 'FOO' })
|
||||||
return expect(() => ctx.get(['foo', 'BAR'])).to.throw(/undefined variable: foo.BAR/)
|
return expect(() => ctx.getSync(['foo', 'BAR'])).toThrow(/undefined variable: foo.BAR/)
|
||||||
})
|
})
|
||||||
it('should find variable in parent scope', async function () {
|
it('should find variable in parent scope', async function () {
|
||||||
ctx.push({ 'foo': 'foo' })
|
ctx.push({ 'foo': 'foo' })
|
||||||
ctx.push({
|
ctx.push({
|
||||||
'bar': 'bar'
|
'bar': 'bar'
|
||||||
})
|
})
|
||||||
expect(ctx.get(['foo'])).to.equal('foo')
|
expect(ctx.getSync(['foo'])).toEqual('foo')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('ownPropertyOnly', async function () {
|
describe('ownPropertyOnly', function () {
|
||||||
let ctx: Context
|
let ctx: Context
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
ctx = new Context(ctx, {
|
ctx = new Context(ctx, {
|
||||||
@@ -126,56 +124,56 @@ describe('Context', function () {
|
|||||||
})
|
})
|
||||||
it('should return undefined for prototype object property', function () {
|
it('should return undefined for prototype object property', function () {
|
||||||
ctx.push({ foo: Object.create({ bar: 'BAR' }) })
|
ctx.push({ foo: Object.create({ bar: 'BAR' }) })
|
||||||
return expect(ctx.get(['foo', 'bar'])).to.equal(undefined)
|
return expect(ctx.getSync(['foo', 'bar'])).toEqual(undefined)
|
||||||
})
|
})
|
||||||
it('should use prototype when ownPropertyOnly=false', function () {
|
it('should use prototype when ownPropertyOnly=false', function () {
|
||||||
ctx = new Context({ foo: Object.create({ bar: 'BAR' }) }, { ownPropertyOnly: false } as any)
|
ctx = new Context({ foo: Object.create({ bar: 'BAR' }) }, { ownPropertyOnly: false } as any)
|
||||||
return expect(ctx.get(['foo', 'bar'])).to.equal('BAR')
|
return expect(ctx.getSync(['foo', 'bar'])).toEqual('BAR')
|
||||||
})
|
})
|
||||||
it('renderOptions.ownPropertyOnly should override options.ownPropertyOnly', function () {
|
it('renderOptions.ownPropertyOnly should override options.ownPropertyOnly', function () {
|
||||||
ctx = new Context({ foo: Object.create({ bar: 'BAR' }) }, { ownPropertyOnly: false } as any, { ownPropertyOnly: true })
|
ctx = new Context({ foo: Object.create({ bar: 'BAR' }) }, { ownPropertyOnly: false } as any, { ownPropertyOnly: true })
|
||||||
return expect(ctx.get(['foo', 'bar'])).to.equal(undefined)
|
return expect(ctx.getSync(['foo', 'bar'])).toEqual(undefined)
|
||||||
})
|
})
|
||||||
it('should return undefined for Array.prototype.reduce', function () {
|
it('should return undefined for Array.prototype.reduce', function () {
|
||||||
ctx.push({ foo: [] })
|
ctx.push({ foo: [] })
|
||||||
return expect(ctx.get(['foo', 'reduce'])).to.equal(undefined)
|
return expect(ctx.getSync(['foo', 'reduce'])).toEqual(undefined)
|
||||||
})
|
})
|
||||||
it('should return undefined for function prototype property', function () {
|
it('should return undefined for function prototype property', function () {
|
||||||
function Foo () {}
|
function Foo () {}
|
||||||
Foo.prototype.bar = 'BAR'
|
Foo.prototype.bar = 'BAR'
|
||||||
ctx.push({ foo: new (Foo as any)() })
|
ctx.push({ foo: new (Foo as any)() })
|
||||||
return expect(ctx.get(['foo', 'bar'])).to.equal(undefined)
|
return expect(ctx.getSync(['foo', 'bar'])).toEqual(undefined)
|
||||||
})
|
})
|
||||||
it('should allow function constructor properties', function () {
|
it('should allow function constructor properties', function () {
|
||||||
function Foo (this: any) { this.bar = 'BAR' }
|
function Foo (this: any) { this.bar = 'BAR' }
|
||||||
ctx.push({ foo: new (Foo as any)() })
|
ctx.push({ foo: new (Foo as any)() })
|
||||||
return expect(ctx.get(['foo', 'bar'])).to.equal('BAR')
|
return expect(ctx.getSync(['foo', 'bar'])).toEqual('BAR')
|
||||||
})
|
})
|
||||||
it('should return undefined for class method', function () {
|
it('should return undefined for class method', function () {
|
||||||
class Foo { bar () {} }
|
class Foo { bar () {} }
|
||||||
ctx.push({ foo: new Foo() })
|
ctx.push({ foo: new Foo() })
|
||||||
return expect(ctx.get(['foo', 'bar'])).to.equal(undefined)
|
return expect(ctx.getSync(['foo', 'bar'])).toEqual(undefined)
|
||||||
})
|
})
|
||||||
it('should allow class property', function () {
|
it('should allow class property', function () {
|
||||||
class Foo { bar = 'BAR' }
|
class Foo { bar = 'BAR' }
|
||||||
ctx.push({ foo: new Foo() })
|
ctx.push({ foo: new Foo() })
|
||||||
return expect(ctx.get(['foo', 'bar'])).to.equal('BAR')
|
return expect(ctx.getSync(['foo', 'bar'])).toEqual('BAR')
|
||||||
})
|
})
|
||||||
it('should allow Array.prototype.length', function () {
|
it('should allow Array.prototype.length', function () {
|
||||||
ctx.push({ foo: [1, 2] })
|
ctx.push({ foo: [1, 2] })
|
||||||
return expect(ctx.get(['foo', 'length'])).to.equal(2)
|
return expect(ctx.getSync(['foo', 'length'])).toEqual(2)
|
||||||
})
|
})
|
||||||
it('should allow size to access Array.prototype.length', function () {
|
it('should allow size to access Array.prototype.length', function () {
|
||||||
ctx.push({ foo: [1, 2] })
|
ctx.push({ foo: [1, 2] })
|
||||||
return expect(ctx.get(['foo', 'size'])).to.equal(2)
|
return expect(ctx.getSync(['foo', 'size'])).toEqual(2)
|
||||||
})
|
})
|
||||||
it('should allow size to access Set.prototype.size', function () {
|
it('should allow size to access Set.prototype.size', function () {
|
||||||
ctx.push({ foo: new Set([1, 2]) })
|
ctx.push({ foo: new Set([1, 2]) })
|
||||||
return expect(ctx.get(['foo', 'size'])).to.equal(2)
|
return expect(ctx.getSync(['foo', 'size'])).toEqual(2)
|
||||||
})
|
})
|
||||||
it('should allow size to access Object key count', function () {
|
it('should allow size to access Object key count', function () {
|
||||||
ctx.push({ foo: { bar: 'BAR', coo: 'COO' } })
|
ctx.push({ foo: { bar: 'BAR', coo: 'COO' } })
|
||||||
return expect(ctx.get(['foo', 'size'])).to.equal(2)
|
return expect(ctx.getSync(['foo', 'size'])).toEqual(2)
|
||||||
})
|
})
|
||||||
it('should throw when property is hidden and strictVariables is true', function () {
|
it('should throw when property is hidden and strictVariables is true', function () {
|
||||||
ctx = new Context(ctx, {
|
ctx = new Context(ctx, {
|
||||||
@@ -183,13 +181,13 @@ describe('Context', function () {
|
|||||||
strictVariables: true
|
strictVariables: true
|
||||||
} as any)
|
} as any)
|
||||||
ctx.push({ foo: Object.create({ bar: 'BAR' }) })
|
ctx.push({ foo: Object.create({ bar: 'BAR' }) })
|
||||||
return expect(() => ctx.get(['foo', 'bar'])).to.throw(/undefined variable: foo.bar/)
|
return expect(() => ctx.getSync(['foo', 'bar'])).toThrow(/undefined variable: foo.bar/)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('.getAll()', function () {
|
describe('.getAll()', function () {
|
||||||
it('should get all properties when arguments empty', async function () {
|
it('should get all properties when arguments empty', async function () {
|
||||||
expect(ctx.getAll()).deep.equal(scope)
|
expect(ctx.getAll()).toEqual(scope)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -199,14 +197,14 @@ describe('Context', function () {
|
|||||||
ctx.push({
|
ctx.push({
|
||||||
foo: 'foo'
|
foo: 'foo'
|
||||||
})
|
})
|
||||||
expect(ctx.get(['foo'])).to.equal('foo')
|
expect(ctx.getSync(['foo'])).toEqual('foo')
|
||||||
expect(ctx.get(['bar'])).to.equal('bar')
|
expect(ctx.getSync(['bar'])).toEqual('bar')
|
||||||
})
|
})
|
||||||
it('should hide deep properties by push', async function () {
|
it('should hide deep properties by push', async function () {
|
||||||
ctx.push({ bar: { bar: 'bar' } })
|
ctx.push({ bar: { bar: 'bar' } })
|
||||||
ctx.push({ bar: { foo: 'foo' } })
|
ctx.push({ bar: { foo: 'foo' } })
|
||||||
expect(ctx.get(['bar', 'foo'])).to.equal('foo')
|
expect(ctx.getSync(['bar', 'foo'])).toEqual('foo')
|
||||||
expect(ctx.get(['bar', 'bar'])).to.equal(undefined)
|
expect(ctx.getSync(['bar', 'bar'])).toEqual(undefined)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('.pop()', function () {
|
describe('.pop()', function () {
|
||||||
@@ -215,7 +213,7 @@ describe('Context', function () {
|
|||||||
foo: 'foo'
|
foo: 'foo'
|
||||||
})
|
})
|
||||||
ctx.pop()
|
ctx.pop()
|
||||||
expect(ctx.get(['foo'])).to.equal('zoo')
|
expect(ctx.getSync(['foo'])).toEqual('zoo')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -58,9 +58,12 @@ export class Context {
|
|||||||
.reduce((ctx, val) => __assign(ctx, val), {})
|
.reduce((ctx, val) => __assign(ctx, val), {})
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @deprecated use `_get()` instead
|
* @deprecated use `_get()` or `getSync()` instead
|
||||||
*/
|
*/
|
||||||
public get (paths: PropertyKey[]): unknown {
|
public get (paths: PropertyKey[]): unknown {
|
||||||
|
return this.getSync(paths)
|
||||||
|
}
|
||||||
|
public getSync (paths: PropertyKey[]): unknown {
|
||||||
return toValueSync(this._get(paths))
|
return toValueSync(this._get(paths))
|
||||||
}
|
}
|
||||||
public * _get (paths: PropertyKey[]): IterableIterator<unknown> {
|
public * _get (paths: PropertyKey[]): IterableIterator<unknown> {
|
||||||
|
|||||||
@@ -1,57 +1,53 @@
|
|||||||
import * as fs from '../../../src/fs/node'
|
import * as fs from './fs-impl'
|
||||||
import * as path from 'path'
|
import * as path from 'path'
|
||||||
import { expect, use } from 'chai'
|
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
|
|
||||||
use(chaiAsPromised)
|
describe('fs-impl', function () {
|
||||||
|
|
||||||
describe('fs/node', function () {
|
|
||||||
describe('.resolve()', function () {
|
describe('.resolve()', function () {
|
||||||
it('should resolve based on root', async function () {
|
it('should resolve based on root', async function () {
|
||||||
const filepath = fs.resolve('/foo', 'bar.html', '.liquid')
|
const filepath = fs.resolve('/foo', 'bar.html', '.liquid')
|
||||||
const expected = path.resolve('/foo/bar.html')
|
const expected = path.resolve('/foo/bar.html')
|
||||||
return expect(filepath).to.equal(expected)
|
return expect(filepath).toBe(expected)
|
||||||
})
|
})
|
||||||
it('should add extension if it has no extension', async function () {
|
it('should add extension if it has no extension', async function () {
|
||||||
const filepath = fs.resolve('/foo', 'bar', '.liquid')
|
const filepath = fs.resolve('/foo', 'bar', '.liquid')
|
||||||
const expected = path.resolve('/foo/bar.liquid')
|
const expected = path.resolve('/foo/bar.liquid')
|
||||||
return expect(filepath).to.equal(expected)
|
return expect(filepath).toBe(expected)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('.existsSync', () => {
|
describe('.existsSync', () => {
|
||||||
it('should resolve as false if not exists', () => {
|
it('should resolve as false if not exists', () => {
|
||||||
expect(fs.existsSync('/foo/bar')).to.be.false
|
expect(fs.existsSync('/foo/bar')).toBeFalsy()
|
||||||
})
|
})
|
||||||
it('should resolve as true if exists', () => {
|
it('should resolve as true if exists', () => {
|
||||||
expect(fs.existsSync(__filename)).to.be.true
|
expect(fs.existsSync(__filename)).toBeTruthy()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('.exists', () => {
|
describe('.exists', () => {
|
||||||
it('should resolve as false if not exists', async () => {
|
it('should resolve as false if not exists', async () => {
|
||||||
const result = await fs.exists('/foo/bar')
|
const result = await fs.exists('/foo/bar')
|
||||||
expect(result).to.be.false
|
expect(result).toBeFalsy()
|
||||||
})
|
})
|
||||||
it('should resolve as true if exists', async () => {
|
it('should resolve as true if exists', async () => {
|
||||||
const result = await fs.exists(__filename)
|
const result = await fs.exists(__filename)
|
||||||
expect(result).to.be.true
|
expect(result).toBeTruthy()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('.readFileSync', function () {
|
describe('.readFileSync', function () {
|
||||||
it('should throw when not exist', function () {
|
it('should throw when not exist', function () {
|
||||||
return expect(() => fs.readFileSync('/foo/bar')).to.throw('ENOENT')
|
return expect(() => fs.readFileSync('/foo/bar')).toThrow('ENOENT')
|
||||||
})
|
})
|
||||||
it('should read content if exists', function () {
|
it('should read content if exists', function () {
|
||||||
const content = fs.readFileSync(__filename)
|
const content = fs.readFileSync(__filename)
|
||||||
expect(content).to.contain('should read content if exists')
|
expect(content).toContain('should read content if exists')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('.readFile', function () {
|
describe('.readFile', function () {
|
||||||
it('should throw when not exist', function () {
|
it('should throw when not exist', function () {
|
||||||
return expect(fs.readFile('/foo/bar')).to.rejectedWith('ENOENT')
|
return expect(fs.readFile('/foo/bar')).rejects.toHaveProperty('message', expect.stringMatching('ENOENT'))
|
||||||
})
|
})
|
||||||
it('should read content if exists', async function () {
|
it('should read content if exists', async function () {
|
||||||
const content = await fs.readFile(__filename)
|
const content = await fs.readFile(__filename)
|
||||||
expect(content).to.contain('should read content if exists')
|
expect(content).toContain('should read content if exists')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,26 +1,22 @@
|
|||||||
import { expect, use } from 'chai'
|
import * as fs from './fs-impl'
|
||||||
import * as fs from '../../../src/fs/node'
|
import { Loader } from './loader'
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
import { Loader } from '../../../src/fs/loader'
|
|
||||||
|
|
||||||
use(chaiAsPromised)
|
|
||||||
|
|
||||||
describe('fs/loader', function () {
|
describe('fs/loader', function () {
|
||||||
describe('.candidates()', function () {
|
describe('.candidates()', function () {
|
||||||
it('should resolve relatively', async function () {
|
it('should resolve relatively', async function () {
|
||||||
const loader = new Loader({ relativeReference: true, fs, extname: '' } as any)
|
const loader = new Loader({ relativeReference: true, fs, extname: '' } as any)
|
||||||
const candidates = [...loader.candidates('./foo/bar', ['/root', '/root/foo'], '/root/current', true)]
|
const candidates = [...loader.candidates('./foo/bar', ['/root', '/root/foo'], '/root/current', true)]
|
||||||
expect(candidates).to.contain('/root/foo/bar')
|
expect(candidates).toContain('/root/foo/bar')
|
||||||
})
|
})
|
||||||
it('should not include out of root candidates', async function () {
|
it('should not include out of root candidates', async function () {
|
||||||
const loader = new Loader({ relativeReference: true, fs, extname: '' } as any)
|
const loader = new Loader({ relativeReference: true, fs, extname: '' } as any)
|
||||||
const candidates = [...loader.candidates('../foo/bar', ['/root'], '/root/current', true)]
|
const candidates = [...loader.candidates('../foo/bar', ['/root'], '/root/current', true)]
|
||||||
expect(candidates).to.have.lengthOf(0)
|
expect(candidates).toHaveLength(0)
|
||||||
})
|
})
|
||||||
it('should treat root as a terminated path', async function () {
|
it('should treat root as a terminated path', async function () {
|
||||||
const loader = new Loader({ relativeReference: true, fs, extname: '' } as any)
|
const loader = new Loader({ relativeReference: true, fs, extname: '' } as any)
|
||||||
const candidates = [...loader.candidates('../root-dir/bar', ['/root'], '/root/current', true)]
|
const candidates = [...loader.candidates('../root-dir/bar', ['/root'], '/root/current', true)]
|
||||||
expect(candidates).to.have.lengthOf(0)
|
expect(candidates).toHaveLength(0)
|
||||||
})
|
})
|
||||||
it('should default `.contains()` to () => true', async function () {
|
it('should default `.contains()` to () => true', async function () {
|
||||||
const customFs = {
|
const customFs = {
|
||||||
@@ -29,7 +25,7 @@ describe('fs/loader', function () {
|
|||||||
}
|
}
|
||||||
const loader = new Loader({ relativeReference: true, fs: customFs, extname: '' } as any)
|
const loader = new Loader({ relativeReference: true, fs: customFs, extname: '' } as any)
|
||||||
const candidates = [...loader.candidates('../foo/bar', ['/root'], '/root/current', true)]
|
const candidates = [...loader.candidates('../foo/bar', ['/root'], '/root/current', true)]
|
||||||
expect(candidates).to.contain('/foo/bar')
|
expect(candidates).toContain('/foo/bar')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
import { normalize } from '../../src/liquid-options'
|
import { normalize } from './liquid-options'
|
||||||
import { expect } from 'chai'
|
|
||||||
|
|
||||||
describe('liquid-options', () => {
|
describe('liquid-options', () => {
|
||||||
describe('.normalize()', () => {
|
describe('.normalize()', () => {
|
||||||
it('should set cache to undefined if specified to falsy', () => {
|
it('should set cache to undefined if specified to falsy', () => {
|
||||||
const options = normalize({ cache: false })
|
const options = normalize({ cache: false })
|
||||||
expect(options.cache).to.equal(undefined)
|
expect(options.cache).toBeUndefined()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { assert, isArray, isString, isFunction } from './util'
|
import { assert, isArray, isString, isFunction } from './util'
|
||||||
import { LRU, LiquidCache } from './cache'
|
import { LRU, LiquidCache } from './cache'
|
||||||
import { FS, LookupType } from './fs'
|
import { FS, LookupType } from './fs'
|
||||||
import * as fs from './fs/node'
|
import * as fs from './fs/fs-impl'
|
||||||
import { defaultOperators, Operators } from './render'
|
import { defaultOperators, Operators } from './render'
|
||||||
import { json } from './filters/misc'
|
import { json } from './filters/misc'
|
||||||
import { escape } from './filters/html'
|
import { escape } from './filters/html'
|
||||||
@@ -180,8 +180,8 @@ export function normalize (options: LiquidOptions): NormalizedFullOptions {
|
|||||||
options.cache = cache
|
options.cache = cache
|
||||||
}
|
}
|
||||||
options = { ...defaultOptions, ...(options.jekyllInclude ? { dynamicPartials: false } : {}), ...options }
|
options = { ...defaultOptions, ...(options.jekyllInclude ? { dynamicPartials: false } : {}), ...options }
|
||||||
if (!options.fs!.dirname && options.relativeReference) {
|
if ((!options.fs!.dirname || !options.fs!.sep) && options.relativeReference) {
|
||||||
console.warn('[LiquidJS] `fs.dirname` is required for relativeReference, set relativeReference to `false` to suppress this warning, or provide implementation for `fs.dirname`')
|
console.warn('[LiquidJS] `fs.dirname` and `fs.sep` are required for relativeReference, set relativeReference to `false` to suppress this warning')
|
||||||
options.relativeReference = false
|
options.relativeReference = false
|
||||||
}
|
}
|
||||||
options.root = normalizeDirectoryList(options.root)
|
options.root = normalizeDirectoryList(options.root)
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import { matchOperator } from './match-operator'
|
||||||
|
import { defaultOperators } from '..'
|
||||||
|
import { createTrie } from '../util/operator-trie'
|
||||||
|
|
||||||
|
describe('parser/matchOperator()', function () {
|
||||||
|
const trie = createTrie(defaultOperators)
|
||||||
|
it('should match contains', () => {
|
||||||
|
expect(matchOperator('contains', 0, trie)).toBe(8)
|
||||||
|
})
|
||||||
|
it('should match comparision', () => {
|
||||||
|
expect(matchOperator('>', 0, trie)).toBe(1)
|
||||||
|
expect(matchOperator('>=', 0, trie)).toBe(2)
|
||||||
|
expect(matchOperator('<', 0, trie)).toBe(1)
|
||||||
|
expect(matchOperator('<=', 0, trie)).toBe(2)
|
||||||
|
})
|
||||||
|
it('should match binary logic', () => {
|
||||||
|
expect(matchOperator('and', 0, trie)).toBe(3)
|
||||||
|
expect(matchOperator('or', 0, trie)).toBe(2)
|
||||||
|
})
|
||||||
|
it('should not match if word not terminate', () => {
|
||||||
|
expect(matchOperator('true1', 0, trie)).toBe(-1)
|
||||||
|
expect(matchOperator('containsa', 0, trie)).toBe(-1)
|
||||||
|
})
|
||||||
|
it('should match if word boundary found', () => {
|
||||||
|
expect(matchOperator('>=1', 0, trie)).toBe(2)
|
||||||
|
expect(matchOperator('contains b', 0, trie)).toBe(8)
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -1,8 +1,5 @@
|
|||||||
import * as chai from 'chai'
|
import { ParseStream } from './parse-stream'
|
||||||
import { ParseStream } from '../../../src/parser'
|
import { Token } from '../tokens'
|
||||||
import { Token } from '../../../src/tokens'
|
|
||||||
|
|
||||||
const expect = chai.expect
|
|
||||||
|
|
||||||
describe('parseStream', () => {
|
describe('parseStream', () => {
|
||||||
it('should trigger "token" event', () => {
|
it('should trigger "token" event', () => {
|
||||||
@@ -10,6 +7,6 @@ describe('parseStream', () => {
|
|||||||
const ps = new ParseStream([token], (token) => ({ token } as any))
|
const ps = new ParseStream([token], (token) => ({ token } as any))
|
||||||
let got
|
let got
|
||||||
ps.on('token', token => { got = token }).start()
|
ps.on('token', token => { got = token }).start()
|
||||||
expect(got).to.equal(token)
|
expect(got).toEqual(token)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import { parseStringLiteral } from './parse-string-literal'
|
||||||
|
|
||||||
|
describe('parseStringLiteral()', function () {
|
||||||
|
it('should parse octal escape', () => {
|
||||||
|
expect(parseStringLiteral(String.raw`"\1010"`)).toBe('A0')
|
||||||
|
expect(parseStringLiteral(String.raw`"\12"`)).toBe('\n')
|
||||||
|
expect(parseStringLiteral(String.raw`"\01"`)).toBe('\u0001')
|
||||||
|
expect(parseStringLiteral(String.raw`"\0"`)).toBe('\0')
|
||||||
|
})
|
||||||
|
it('should skip invalid octal escape', () => {
|
||||||
|
expect(parseStringLiteral(String.raw`"\9"`)).toBe('9')
|
||||||
|
})
|
||||||
|
it('should parse \\n, \\t, \\r', () => {
|
||||||
|
expect(parseStringLiteral(String.raw`"fo\no"`)).toBe('fo\no')
|
||||||
|
expect(parseStringLiteral(String.raw`'fo\to'`)).toBe('fo\to')
|
||||||
|
expect(parseStringLiteral(String.raw`'fo\ro'`)).toBe('fo\ro')
|
||||||
|
})
|
||||||
|
it('should parse unicode(hex) escape', () => {
|
||||||
|
expect(parseStringLiteral('"\\u003C"')).toBe('<')
|
||||||
|
expect(parseStringLiteral('"\\u003cZ"')).toBe('<Z')
|
||||||
|
expect(parseStringLiteral('"\\u41"')).toBe('A')
|
||||||
|
})
|
||||||
|
it('should skip invalid unicode(hex) escape', () => {
|
||||||
|
expect(parseStringLiteral('"\\u41Z"')).toBe('AZ')
|
||||||
|
expect(parseStringLiteral('"\\uZ"')).toBe('\0Z')
|
||||||
|
})
|
||||||
|
it('should parse quote escape', () => {
|
||||||
|
expect(parseStringLiteral(String.raw`"fo\'o"`)).toBe("fo'o")
|
||||||
|
expect(parseStringLiteral(String.raw`'fo\"o'`)).toBe('fo"o')
|
||||||
|
})
|
||||||
|
it('should parse slash escape', () => {
|
||||||
|
expect(parseStringLiteral(String.raw`'fo\\o'`)).toBe('fo\\o')
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -0,0 +1,546 @@
|
|||||||
|
import { LiquidTagToken, HTMLToken, QuotedToken, OutputToken, TagToken, OperatorToken, RangeToken, PropertyAccessToken, NumberToken, IdentifierToken } from '../tokens'
|
||||||
|
import { Tokenizer } from './tokenizer'
|
||||||
|
|
||||||
|
describe('Tokenizer', function () {
|
||||||
|
it('should read quoted', () => {
|
||||||
|
expect(new Tokenizer('"foo" ff').readQuoted()!.getText()).toBe('"foo"')
|
||||||
|
expect(new Tokenizer(' "foo"ff').readQuoted()!.getText()).toBe('"foo"')
|
||||||
|
})
|
||||||
|
it('should read value', () => {
|
||||||
|
expect(new Tokenizer('a[ b][ "c d" ]').readValueOrThrow().getText()).toBe('a[ b][ "c d" ]')
|
||||||
|
expect(new Tokenizer('a.b[c[d.e]]').readValueOrThrow().getText()).toBe('a.b[c[d.e]]')
|
||||||
|
})
|
||||||
|
it('should read identifier', () => {
|
||||||
|
expect(new Tokenizer('foo bar').readIdentifier()).toHaveProperty('content', 'foo')
|
||||||
|
// eslint-disable-next-line deprecation/deprecation
|
||||||
|
expect(new Tokenizer('foo bar').readWord()).toHaveProperty('content', 'foo')
|
||||||
|
})
|
||||||
|
it('should read number value', () => {
|
||||||
|
const token: NumberToken = new Tokenizer('2.33.2').readValueOrThrow() as any
|
||||||
|
expect(token).toBeInstanceOf(NumberToken)
|
||||||
|
expect(token.whole.getText()).toBe('2')
|
||||||
|
expect(token.decimal!.getText()).toBe('33')
|
||||||
|
expect(token.getText()).toBe('2.33')
|
||||||
|
})
|
||||||
|
it('should read quoted value', () => {
|
||||||
|
const value = new Tokenizer('"foo"a').readValue()
|
||||||
|
expect(value).toBeInstanceOf(QuotedToken)
|
||||||
|
expect(value!.getText()).toBe('"foo"')
|
||||||
|
})
|
||||||
|
it('should read property access value', () => {
|
||||||
|
expect(new Tokenizer('a[b]["c d"]').readValueOrThrow().getText()).toBe('a[b]["c d"]')
|
||||||
|
})
|
||||||
|
it('should read quoted property access value', () => {
|
||||||
|
const value = new Tokenizer('["a prop"]').readValue()
|
||||||
|
expect(value).toBeInstanceOf(PropertyAccessToken)
|
||||||
|
expect((value as PropertyAccessToken).variable.getText()).toBe('"a prop"')
|
||||||
|
})
|
||||||
|
it('should throw for broken quoted property access', () => {
|
||||||
|
const tokenizer = new Tokenizer('[5]')
|
||||||
|
expect(() => tokenizer.readValueOrThrow()).toThrow()
|
||||||
|
})
|
||||||
|
it('should throw for incomplete quoted property access', () => {
|
||||||
|
const tokenizer = new Tokenizer('["a prop"')
|
||||||
|
expect(() => tokenizer.readValueOrThrow()).toThrow()
|
||||||
|
})
|
||||||
|
it('should read hash', () => {
|
||||||
|
const hash1 = new Tokenizer('foo: 3').readHash()
|
||||||
|
expect(hash1!.name.content).toBe('foo')
|
||||||
|
expect(hash1!.value!.getText()).toBe('3')
|
||||||
|
|
||||||
|
const hash2 = new Tokenizer(', foo: a[ "bar"]').readHash()
|
||||||
|
expect(hash2!.name.content).toBe('foo')
|
||||||
|
expect(hash2!.value!.getText()).toBe('a[ "bar"]')
|
||||||
|
})
|
||||||
|
it('should read multiple hashs', () => {
|
||||||
|
const hashes = new Tokenizer(', limit: 3 reverse offset:off').readHashes()
|
||||||
|
expect(hashes).toHaveLength(3)
|
||||||
|
const [limit, reverse, offset] = hashes
|
||||||
|
expect(limit.name.content).toBe('limit')
|
||||||
|
expect(limit.value!.getText()).toBe('3')
|
||||||
|
|
||||||
|
expect(reverse.name.content).toBe('reverse')
|
||||||
|
expect(reverse.value).toBeUndefined()
|
||||||
|
|
||||||
|
expect(offset.name.content).toBe('offset')
|
||||||
|
expect(offset.value!.getText()).toBe('off')
|
||||||
|
})
|
||||||
|
it('should read hash value with property access', () => {
|
||||||
|
const hashes = new Tokenizer('cols: 2, rows: data["rows"]').readHashes()
|
||||||
|
expect(hashes).toHaveLength(2)
|
||||||
|
const [cols, rols] = hashes
|
||||||
|
|
||||||
|
expect(cols.name.content).toBe('cols')
|
||||||
|
expect(cols.value!.getText()).toBe('2')
|
||||||
|
|
||||||
|
expect(rols.name.content).toBe('rows')
|
||||||
|
expect(rols.value!.getText()).toBe('data["rows"]')
|
||||||
|
})
|
||||||
|
describe('#readTopLevelTokens()', () => {
|
||||||
|
it('should read HTML token', function () {
|
||||||
|
const html = '<html><body><p>Lorem Ipsum</p></body></html>'
|
||||||
|
const tokenizer = new Tokenizer(html)
|
||||||
|
const tokens = tokenizer.readTopLevelTokens()
|
||||||
|
|
||||||
|
expect(tokens.length).toBe(1)
|
||||||
|
expect(tokens[0]).toBeInstanceOf(HTMLToken)
|
||||||
|
expect((tokens[0] as HTMLToken).getContent()).toBe(html)
|
||||||
|
})
|
||||||
|
it('should read tag token', function () {
|
||||||
|
const html = '<p>{% for p in a[1]%}</p>'
|
||||||
|
const tokenizer = new Tokenizer(html)
|
||||||
|
const tokens = tokenizer.readTopLevelTokens()
|
||||||
|
|
||||||
|
expect(tokens.length).toBe(3)
|
||||||
|
const tag = tokens[1] as TagToken
|
||||||
|
expect(tag).toBeInstanceOf(TagToken)
|
||||||
|
expect(tag.name).toBe('for')
|
||||||
|
expect(tag.args).toBe('p in a[1]')
|
||||||
|
})
|
||||||
|
it('should allow unclosed tag inside {% raw %}', function () {
|
||||||
|
const html = '{%raw%} {%if%} {%else {%endraw%}'
|
||||||
|
const tokenizer = new Tokenizer(html)
|
||||||
|
const tokens = tokenizer.readTopLevelTokens()
|
||||||
|
|
||||||
|
expect(tokens.length).toBe(3)
|
||||||
|
expect(tokens[0]).toHaveProperty('name', 'raw')
|
||||||
|
expect((tokens[1] as any).getContent()).toBe(' {%if%} {%else ')
|
||||||
|
})
|
||||||
|
it('should allow unclosed endraw tag inside {% raw %}', function () {
|
||||||
|
const html = '{%raw%} {%endraw {%raw%} {%endraw%}'
|
||||||
|
const tokenizer = new Tokenizer(html)
|
||||||
|
const tokens = tokenizer.readTopLevelTokens()
|
||||||
|
|
||||||
|
expect(tokens.length).toBe(3)
|
||||||
|
expect(tokens[0]).toHaveProperty('name', 'raw')
|
||||||
|
expect((tokens[1] as any).getContent()).toBe(' {%endraw {%raw%} ')
|
||||||
|
})
|
||||||
|
it('should throw when {% raw %} not closed', function () {
|
||||||
|
const html = '{%raw%} {%endraw {%raw%}'
|
||||||
|
const tokenizer = new Tokenizer(html)
|
||||||
|
expect(() => tokenizer.readTopLevelTokens()).toThrow('raw "{%raw%} {%end..." not closed, line:1, col:8')
|
||||||
|
})
|
||||||
|
it('should read output token', function () {
|
||||||
|
const html = '<p>{{foo | date: "%Y-%m-%d"}}</p>'
|
||||||
|
const tokenizer = new Tokenizer(html)
|
||||||
|
const tokens = tokenizer.readTopLevelTokens()
|
||||||
|
|
||||||
|
expect(tokens.length).toBe(3)
|
||||||
|
const output = tokens[1] as OutputToken
|
||||||
|
expect(output).toBeInstanceOf(OutputToken)
|
||||||
|
expect(output.content).toBe('foo | date: "%Y-%m-%d"')
|
||||||
|
})
|
||||||
|
it('should handle consecutive value and tags', function () {
|
||||||
|
const html = '{{foo}}{{bar}}{%foo%}{%bar%}'
|
||||||
|
const tokenizer = new Tokenizer(html)
|
||||||
|
const tokens = tokenizer.readTopLevelTokens()
|
||||||
|
|
||||||
|
expect(tokens.length).toBe(4)
|
||||||
|
const o1 = tokens[0] as OutputToken
|
||||||
|
const o2 = tokens[1] as OutputToken
|
||||||
|
const t1 = tokens[2] as TagToken
|
||||||
|
const t2 = tokens[3] as TagToken
|
||||||
|
expect(o1).toBeInstanceOf(OutputToken)
|
||||||
|
expect(o2).toBeInstanceOf(OutputToken)
|
||||||
|
expect(t1).toBeInstanceOf(TagToken)
|
||||||
|
expect(t2).toBeInstanceOf(TagToken)
|
||||||
|
|
||||||
|
expect(o1.content).toBe('foo')
|
||||||
|
expect(o2.content).toBe('bar')
|
||||||
|
expect(t1.name).toBe('foo')
|
||||||
|
expect(t1.args).toBe('')
|
||||||
|
expect(t2.name).toBe('bar')
|
||||||
|
expect(t2.args).toBe('')
|
||||||
|
})
|
||||||
|
it('should keep white spaces and newlines', function () {
|
||||||
|
const html = '{%foo%}\n{%bar %} \n {%alice%}'
|
||||||
|
const tokenizer = new Tokenizer(html)
|
||||||
|
const tokens = tokenizer.readTopLevelTokens()
|
||||||
|
expect(tokens.length).toBe(5)
|
||||||
|
expect(tokens[1]).toBeInstanceOf(HTMLToken)
|
||||||
|
expect(tokens[1].getText()).toBe('\n')
|
||||||
|
expect(tokens[3]).toBeInstanceOf(HTMLToken)
|
||||||
|
expect(tokens[3].getText()).toBe(' \n ')
|
||||||
|
})
|
||||||
|
it('should handle multiple lines tag', function () {
|
||||||
|
const html = '{%foo\na:a\nb:1.23\n%}'
|
||||||
|
const tokenizer = new Tokenizer(html)
|
||||||
|
const tokens = tokenizer.readTopLevelTokens()
|
||||||
|
expect(tokens.length).toBe(1)
|
||||||
|
expect(tokens[0]).toBeInstanceOf(TagToken)
|
||||||
|
expect((tokens[0] as TagToken).args).toBe('a:a\nb:1.23')
|
||||||
|
expect(tokens[0].getText()).toBe('{%foo\na:a\nb:1.23\n%}')
|
||||||
|
})
|
||||||
|
it('should handle multiple lines value', function () {
|
||||||
|
const html = '{{foo\n|date:\n"%Y-%m-%d"\n}}'
|
||||||
|
const tokenizer = new Tokenizer(html)
|
||||||
|
const tokens = tokenizer.readTopLevelTokens()
|
||||||
|
expect(tokens.length).toBe(1)
|
||||||
|
expect(tokens[0]).toBeInstanceOf(OutputToken)
|
||||||
|
expect(tokens[0].getText()).toBe('{{foo\n|date:\n"%Y-%m-%d"\n}}')
|
||||||
|
})
|
||||||
|
it('should handle complex object property access', function () {
|
||||||
|
const html = '{{ obj["my:property with anything"] }}'
|
||||||
|
const tokenizer = new Tokenizer(html)
|
||||||
|
const tokens = tokenizer.readTopLevelTokens()
|
||||||
|
expect(tokens.length).toBe(1)
|
||||||
|
const output = tokens[0] as OutputToken
|
||||||
|
expect(output).toBeInstanceOf(OutputToken)
|
||||||
|
expect(output.content).toBe('obj["my:property with anything"]')
|
||||||
|
})
|
||||||
|
it('should throw if tag not closed', function () {
|
||||||
|
const html = '{% assign foo = bar {{foo}}'
|
||||||
|
const tokenizer = new Tokenizer(html)
|
||||||
|
expect(() => tokenizer.readTopLevelTokens()).toThrow(/tag "{% assign foo..." not closed/)
|
||||||
|
})
|
||||||
|
it('should throw if output not closed', function () {
|
||||||
|
const tokenizer = new Tokenizer('{{name}')
|
||||||
|
expect(() => tokenizer.readTopLevelTokens()).toThrow(/output "{{name}" not closed/)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
describe('#readTagToken()', () => {
|
||||||
|
it('should skip quoted delimiters', function () {
|
||||||
|
const html = '{% assign a = "%} {% }} {{" %}'
|
||||||
|
const tokenizer = new Tokenizer(html)
|
||||||
|
const token = tokenizer.readTagToken()
|
||||||
|
|
||||||
|
expect(token).toBeInstanceOf(TagToken)
|
||||||
|
expect(token.name).toBe('assign')
|
||||||
|
expect(token.args).toBe('a = "%} {% }} {{"')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
describe('#readOutputToken()', () => {
|
||||||
|
it('should skip quoted delimiters', function () {
|
||||||
|
const html = '{{ "%} {%" | append: "}} {{" }}'
|
||||||
|
const tokenizer = new Tokenizer(html)
|
||||||
|
const token = tokenizer.readOutputToken()
|
||||||
|
|
||||||
|
expect(token).toBeInstanceOf(OutputToken)
|
||||||
|
expect(token.content).toBe('"%} {%" | append: "}} {{"')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
describe('#readRange()', () => {
|
||||||
|
it('should read `(1..3)`', () => {
|
||||||
|
const range = new Tokenizer('(1..3)').readRange()
|
||||||
|
expect(range).toBeInstanceOf(RangeToken)
|
||||||
|
expect(range!.getText()).toEqual('(1..3)')
|
||||||
|
const { lhs, rhs } = range!
|
||||||
|
expect(lhs).toBeInstanceOf(NumberToken)
|
||||||
|
expect(lhs.getText()).toBe('1')
|
||||||
|
expect(rhs).toBeInstanceOf(NumberToken)
|
||||||
|
expect(rhs.getText()).toBe('3')
|
||||||
|
})
|
||||||
|
it('should throw for `(..3)`', () => {
|
||||||
|
expect(() => new Tokenizer('(..3)').readRange()).toThrow('unexpected token "..3)", value expected')
|
||||||
|
})
|
||||||
|
it('should read `(a.b..c["..d"])`', () => {
|
||||||
|
const range = new Tokenizer('(a.b..c["..d"])').readRange()
|
||||||
|
expect(range).toBeInstanceOf(RangeToken)
|
||||||
|
expect(range!.getText()).toEqual('(a.b..c["..d"])')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
describe('#readFilter()', () => {
|
||||||
|
it('should read a simple filter', function () {
|
||||||
|
const tokenizer = new Tokenizer('| plus')
|
||||||
|
const token = tokenizer.readFilter()
|
||||||
|
expect(token).toHaveProperty('name', 'plus')
|
||||||
|
expect(token).toHaveProperty('args', [])
|
||||||
|
})
|
||||||
|
it('should read a filter with argument', function () {
|
||||||
|
const tokenizer = new Tokenizer(' | plus: 1')
|
||||||
|
const token = tokenizer.readFilter()
|
||||||
|
expect(token).toHaveProperty('name', 'plus')
|
||||||
|
expect(token!.args).toHaveLength(1)
|
||||||
|
|
||||||
|
const one: NumberToken = token!.args[0] as any
|
||||||
|
expect(one).toBeInstanceOf(NumberToken)
|
||||||
|
expect(one.getText()).toBe('1')
|
||||||
|
})
|
||||||
|
it('should read a filter with colon but no argument', function () {
|
||||||
|
const tokenizer = new Tokenizer('| plus:')
|
||||||
|
const token = tokenizer.readFilter()
|
||||||
|
expect(token).toHaveProperty('name', 'plus')
|
||||||
|
expect(token).toHaveProperty('args', [])
|
||||||
|
})
|
||||||
|
it('should read null if name not found', function () {
|
||||||
|
const tokenizer = new Tokenizer('|')
|
||||||
|
const token = tokenizer.readFilter()
|
||||||
|
expect(token).toBeNull()
|
||||||
|
})
|
||||||
|
it('should read a filter with k/v argument', function () {
|
||||||
|
const tokenizer = new Tokenizer(' | plus: a:1')
|
||||||
|
const token = tokenizer.readFilter()
|
||||||
|
expect(token).toHaveProperty('name', 'plus')
|
||||||
|
expect(token!.args).toHaveLength(1)
|
||||||
|
|
||||||
|
const [k, v]: [string, NumberToken] = token!.args[0] as any
|
||||||
|
expect(k).toBe('a')
|
||||||
|
expect(v).toBeInstanceOf(NumberToken)
|
||||||
|
expect(v.getText()).toBe('1')
|
||||||
|
})
|
||||||
|
it('should read a filter with "arr[0]" argument', function () {
|
||||||
|
const tokenizer = new Tokenizer('| plus: arr[0]')
|
||||||
|
const token = tokenizer.readFilter()
|
||||||
|
expect(token).toHaveProperty('name', 'plus')
|
||||||
|
expect(token!.args).toHaveLength(1)
|
||||||
|
|
||||||
|
const pa: PropertyAccessToken = token!.args[0] as any
|
||||||
|
expect(token!.args[0]).toBeInstanceOf(PropertyAccessToken)
|
||||||
|
expect((pa.variable as any).content).toBe('arr')
|
||||||
|
expect(pa.props).toHaveLength(1)
|
||||||
|
expect(pa.props[0]).toBeInstanceOf(NumberToken)
|
||||||
|
expect(pa.props[0].getText()).toBe('0')
|
||||||
|
})
|
||||||
|
it('should read a filter with obj.foo argument', function () {
|
||||||
|
const tokenizer = new Tokenizer('| plus: obj.foo')
|
||||||
|
const token = tokenizer.readFilter()
|
||||||
|
expect(token).toHaveProperty('name', 'plus')
|
||||||
|
expect(token!.args).toHaveLength(1)
|
||||||
|
|
||||||
|
const pa: PropertyAccessToken = token!.args[0] as any
|
||||||
|
expect(token!.args[0]).toBeInstanceOf(PropertyAccessToken)
|
||||||
|
expect((pa.variable as any).content).toBe('obj')
|
||||||
|
expect(pa.props).toHaveLength(1)
|
||||||
|
expect(pa.props[0]).toBeInstanceOf(IdentifierToken)
|
||||||
|
expect(pa.props[0].getText()).toBe('foo')
|
||||||
|
})
|
||||||
|
it('should read a filter with obj["foo"] argument', function () {
|
||||||
|
const tokenizer = new Tokenizer('| plus: obj["good luck"]')
|
||||||
|
const token = tokenizer.readFilter()
|
||||||
|
expect(token).toHaveProperty('name', 'plus')
|
||||||
|
expect(token!.args).toHaveLength(1)
|
||||||
|
|
||||||
|
const pa: PropertyAccessToken = token!.args[0] as any
|
||||||
|
expect(token!.args[0]).toBeInstanceOf(PropertyAccessToken)
|
||||||
|
expect(pa.getText()).toBe('obj["good luck"]')
|
||||||
|
expect((pa.variable as any).content).toBe('obj')
|
||||||
|
expect(pa.props[0].getText()).toBe('"good luck"')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
describe('#readFilters()', () => {
|
||||||
|
it('should read simple filters', function () {
|
||||||
|
const tokenizer = new Tokenizer('| plus: 3 | capitalize')
|
||||||
|
const tokens = tokenizer.readFilters()
|
||||||
|
|
||||||
|
expect(tokens).toHaveLength(2)
|
||||||
|
expect(tokens[0]).toHaveProperty('name', 'plus')
|
||||||
|
expect(tokens[0].args).toHaveLength(1)
|
||||||
|
expect(tokens[0].args[0]).toBeInstanceOf(NumberToken)
|
||||||
|
expect((tokens[0].args[0] as any).getText()).toBe('3')
|
||||||
|
|
||||||
|
expect(tokens[1]).toHaveProperty('name', 'capitalize')
|
||||||
|
expect(tokens[1].args).toHaveLength(0)
|
||||||
|
})
|
||||||
|
it('should read filters', function () {
|
||||||
|
const tokenizer = new Tokenizer('| plus: a:3 | capitalize | append: foo[a.b["c d"]]')
|
||||||
|
const tokens = tokenizer.readFilters()
|
||||||
|
|
||||||
|
expect(tokens).toHaveLength(3)
|
||||||
|
expect(tokens[0]).toHaveProperty('name', 'plus')
|
||||||
|
expect(tokens[0].args).toHaveLength(1)
|
||||||
|
const [k, v]: [string, NumberToken] = tokens[0].args[0] as any
|
||||||
|
expect(k).toBe('a')
|
||||||
|
expect(v).toBeInstanceOf(NumberToken)
|
||||||
|
expect(v.getText()).toBe('3')
|
||||||
|
|
||||||
|
expect(tokens[1]).toHaveProperty('name', 'capitalize')
|
||||||
|
expect(tokens[1].args).toHaveLength(0)
|
||||||
|
|
||||||
|
expect(tokens[2]).toHaveProperty('name', 'append')
|
||||||
|
expect(tokens[2].args).toHaveLength(1)
|
||||||
|
expect(tokens[2].args[0]).toBeInstanceOf(PropertyAccessToken)
|
||||||
|
expect((tokens[2].args[0] as any).getText()).toBe('foo[a.b["c d"]]')
|
||||||
|
expect((tokens[2].args[0] as any).props[0].getText()).toBe('a.b["c d"]')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
describe('#readExpression()', () => {
|
||||||
|
it('should read expression `a `', () => {
|
||||||
|
const exp = [...new Tokenizer('a ').readExpressionTokens()]
|
||||||
|
|
||||||
|
expect(exp).toHaveLength(1)
|
||||||
|
expect(exp[0]).toBeInstanceOf(PropertyAccessToken)
|
||||||
|
expect(exp[0].getText()).toEqual('a')
|
||||||
|
})
|
||||||
|
it('should read expression `a[][b]`', () => {
|
||||||
|
const exp = [...new Tokenizer('a[][b]').readExpressionTokens()]
|
||||||
|
|
||||||
|
expect(exp).toHaveLength(1)
|
||||||
|
const pa = exp[0] as PropertyAccessToken
|
||||||
|
expect(pa).toBeInstanceOf(PropertyAccessToken)
|
||||||
|
expect((pa.variable as any).content).toEqual('a')
|
||||||
|
expect(pa.props).toHaveLength(2)
|
||||||
|
|
||||||
|
const [p1, p2] = pa.props
|
||||||
|
expect(p1).toBeInstanceOf(IdentifierToken)
|
||||||
|
expect(p1.getText()).toBe('')
|
||||||
|
expect(p2).toBeInstanceOf(PropertyAccessToken)
|
||||||
|
expect(p2.getText()).toBe('b')
|
||||||
|
})
|
||||||
|
it('should read expression `a.`', () => {
|
||||||
|
const exp = [...new Tokenizer('a.').readExpressionTokens()]
|
||||||
|
|
||||||
|
expect(exp).toHaveLength(1)
|
||||||
|
const pa = exp[0] as PropertyAccessToken
|
||||||
|
expect(pa).toBeInstanceOf(PropertyAccessToken)
|
||||||
|
expect((pa.variable as any).content).toEqual('a')
|
||||||
|
expect(pa.props).toHaveLength(0)
|
||||||
|
})
|
||||||
|
it('should read expression `a ==`', () => {
|
||||||
|
const exp = [...new Tokenizer('a ==').readExpressionTokens()]
|
||||||
|
|
||||||
|
expect(exp).toHaveLength(2)
|
||||||
|
expect(exp[0]).toBeInstanceOf(PropertyAccessToken)
|
||||||
|
expect(exp[0].getText()).toEqual('a')
|
||||||
|
expect(exp[1]).toBeInstanceOf(OperatorToken)
|
||||||
|
expect(exp[1].getText()).toEqual('==')
|
||||||
|
})
|
||||||
|
it('should read expression `a==b`', () => {
|
||||||
|
const exp = new Tokenizer('a==b').readExpressionTokens()
|
||||||
|
const [a, equals, b] = exp
|
||||||
|
|
||||||
|
expect(a).toBeInstanceOf(PropertyAccessToken)
|
||||||
|
expect(a.getText()).toEqual('a')
|
||||||
|
|
||||||
|
expect(equals).toBeInstanceOf(OperatorToken)
|
||||||
|
expect(equals.getText()).toBe('==')
|
||||||
|
|
||||||
|
expect(b).toBeInstanceOf(PropertyAccessToken)
|
||||||
|
expect(b.getText()).toEqual('b')
|
||||||
|
})
|
||||||
|
it('should read expression `^`', () => {
|
||||||
|
const exp = new Tokenizer('^').readExpressionTokens()
|
||||||
|
expect([...exp]).toEqual([])
|
||||||
|
})
|
||||||
|
it('should read expression `a == b`', () => {
|
||||||
|
const exp = new Tokenizer('a == b').readExpressionTokens()
|
||||||
|
const [a, equals, b] = exp
|
||||||
|
|
||||||
|
expect(a).toBeInstanceOf(PropertyAccessToken)
|
||||||
|
expect(a.getText()).toEqual('a')
|
||||||
|
|
||||||
|
expect(equals).toBeInstanceOf(OperatorToken)
|
||||||
|
expect(equals.getText()).toBe('==')
|
||||||
|
|
||||||
|
expect(b).toBeInstanceOf(PropertyAccessToken)
|
||||||
|
expect(b.getText()).toEqual('b')
|
||||||
|
})
|
||||||
|
it('should read expression `(1..3) contains 3`', () => {
|
||||||
|
const exp = new Tokenizer('(1..3) contains 3').readExpressionTokens()
|
||||||
|
const [range, contains, rhs] = exp
|
||||||
|
|
||||||
|
expect(range).toBeInstanceOf(RangeToken)
|
||||||
|
expect(range.getText()).toEqual('(1..3)')
|
||||||
|
|
||||||
|
expect(contains).toBeInstanceOf(OperatorToken)
|
||||||
|
expect(contains.getText()).toBe('contains')
|
||||||
|
|
||||||
|
expect(rhs).toBeInstanceOf(NumberToken)
|
||||||
|
expect(rhs.getText()).toEqual('3')
|
||||||
|
})
|
||||||
|
it('should read expression `a[b] == c`', () => {
|
||||||
|
const exp = new Tokenizer('a[b] == c').readExpressionTokens()
|
||||||
|
const [lhs, contains, rhs] = exp
|
||||||
|
|
||||||
|
expect(lhs).toBeInstanceOf(PropertyAccessToken)
|
||||||
|
expect(lhs.getText()).toEqual('a[b]')
|
||||||
|
|
||||||
|
expect(contains).toBeInstanceOf(OperatorToken)
|
||||||
|
expect(contains.getText()).toBe('==')
|
||||||
|
|
||||||
|
expect(rhs).toBeInstanceOf(PropertyAccessToken)
|
||||||
|
expect(rhs.getText()).toEqual('c')
|
||||||
|
})
|
||||||
|
it('should read expression `c[a["b"]] >= c`', () => {
|
||||||
|
const exp = new Tokenizer('c[a["b"]] >= c').readExpressionTokens()
|
||||||
|
const [lhs, op, rhs] = exp
|
||||||
|
|
||||||
|
expect(lhs).toBeInstanceOf(PropertyAccessToken)
|
||||||
|
expect(lhs.getText()).toEqual('c[a["b"]]')
|
||||||
|
|
||||||
|
expect(op).toBeInstanceOf(OperatorToken)
|
||||||
|
expect(op.getText()).toBe('>=')
|
||||||
|
|
||||||
|
expect(rhs).toBeInstanceOf(PropertyAccessToken)
|
||||||
|
expect(rhs.getText()).toEqual('c')
|
||||||
|
})
|
||||||
|
it('should read expression `"][" == var`', () => {
|
||||||
|
const exp = new Tokenizer('"][" == var').readExpressionTokens()
|
||||||
|
const [lhs, equals, rhs] = exp
|
||||||
|
|
||||||
|
expect(lhs).toBeInstanceOf(QuotedToken)
|
||||||
|
expect(lhs.getText()).toEqual('"]["')
|
||||||
|
|
||||||
|
expect(equals).toBeInstanceOf(OperatorToken)
|
||||||
|
expect(equals.getText()).toBe('==')
|
||||||
|
|
||||||
|
expect(rhs).toBeInstanceOf(PropertyAccessToken)
|
||||||
|
expect(rhs.getText()).toEqual('var')
|
||||||
|
})
|
||||||
|
it('should read expression `"\\\'" == "\\""`', () => {
|
||||||
|
const exp = new Tokenizer('"\\\'" == "\\""').readExpressionTokens()
|
||||||
|
const [lhs, equals, rhs] = exp
|
||||||
|
|
||||||
|
expect(lhs).toBeInstanceOf(QuotedToken)
|
||||||
|
expect(lhs.getText()).toEqual('"\\\'"')
|
||||||
|
|
||||||
|
expect(equals).toBeInstanceOf(OperatorToken)
|
||||||
|
expect(equals.getText()).toBe('==')
|
||||||
|
|
||||||
|
expect(rhs).toBeInstanceOf(QuotedToken)
|
||||||
|
expect(rhs.getText()).toEqual('"\\""')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
describe('#readLiquidTagTokens', () => {
|
||||||
|
it('should read newline terminated tokens', () => {
|
||||||
|
const tokenizer = new Tokenizer('echo \'hello\'')
|
||||||
|
const tokens = tokenizer.readLiquidTagTokens()
|
||||||
|
expect(tokens.length).toBe(1)
|
||||||
|
const tag = tokens[0]
|
||||||
|
expect(tag).toBeInstanceOf(LiquidTagToken)
|
||||||
|
expect(tag.name).toBe('echo')
|
||||||
|
expect(tag.args).toBe('\'hello\'')
|
||||||
|
})
|
||||||
|
it('should gracefully handle empty lines', () => {
|
||||||
|
const tokenizer = new Tokenizer(`
|
||||||
|
echo 'hello'
|
||||||
|
|
||||||
|
decrement foo
|
||||||
|
`)
|
||||||
|
const tokens = tokenizer.readLiquidTagTokens()
|
||||||
|
expect(tokens.length).toBe(2)
|
||||||
|
})
|
||||||
|
it('should throw if line does not start with an identifier', () => {
|
||||||
|
const tokenizer = new Tokenizer('!')
|
||||||
|
expect(() => tokenizer.readLiquidTagTokens()).toThrow(/illegal liquid tag syntax/)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
describe('#read inline comment tags', () => {
|
||||||
|
it('should allow hash characters in tag names', () => {
|
||||||
|
const tokenizer = new Tokenizer('{% # some comment %}')
|
||||||
|
const tokens = tokenizer.readTopLevelTokens()
|
||||||
|
expect(tokens.length).toBe(1)
|
||||||
|
const tag = tokens[0] as TagToken
|
||||||
|
expect(tag).toBeInstanceOf(TagToken)
|
||||||
|
expect(tag.name).toBe('#')
|
||||||
|
expect(tag.args).toBe('some comment')
|
||||||
|
})
|
||||||
|
it('should handle leading whitespace', () => {
|
||||||
|
const tokenizer = new Tokenizer('{%\n # some comment %}')
|
||||||
|
const tokens = tokenizer.readTopLevelTokens()
|
||||||
|
expect(tokens.length).toBe(1)
|
||||||
|
const tag = tokens[0] as TagToken
|
||||||
|
expect(tag).toBeInstanceOf(TagToken)
|
||||||
|
expect(tag.name).toBe('#')
|
||||||
|
expect(tag.args).toBe('some comment')
|
||||||
|
})
|
||||||
|
it('should handle no trailing whitespace', () => {
|
||||||
|
const tokenizer = new Tokenizer('{%\n #some comment %}')
|
||||||
|
const tokens = tokenizer.readTopLevelTokens()
|
||||||
|
expect(tokens.length).toBe(1)
|
||||||
|
const tag = tokens[0] as TagToken
|
||||||
|
expect(tag).toBeInstanceOf(TagToken)
|
||||||
|
expect(tag.name).toBe('#')
|
||||||
|
expect(tag.args).toBe('some comment')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -199,10 +199,9 @@ export class Tokenizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated
|
* @deprecated use #readIdentifier instead
|
||||||
*/
|
*/
|
||||||
readWord () {
|
readWord () {
|
||||||
console.warn('Tokenizer#readWord() will be removed, use #readIdentifier instead')
|
|
||||||
return this.readIdentifier()
|
return this.readIdentifier()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,94 @@
|
|||||||
|
import { isTruthy, isFalsy } from './boolean'
|
||||||
|
import { Context } from '../context'
|
||||||
|
|
||||||
|
describe('boolean Shopify', function () {
|
||||||
|
describe('.isTruthy()', function () {
|
||||||
|
const ctx = {
|
||||||
|
opts: {
|
||||||
|
jsTruthy: false
|
||||||
|
}
|
||||||
|
} as unknown as Context
|
||||||
|
//
|
||||||
|
// Spec: https://shopify.github.io/liquid/basics/truthy-and-falsy/
|
||||||
|
it('true is truthy', function () {
|
||||||
|
expect(isTruthy(true, ctx)).toBeTruthy()
|
||||||
|
})
|
||||||
|
it('false is falsy', function () {
|
||||||
|
expect(isTruthy(false, ctx)).toBeFalsy()
|
||||||
|
})
|
||||||
|
it('null is falsy', function () {
|
||||||
|
expect(isTruthy(null, ctx)).toBeFalsy()
|
||||||
|
})
|
||||||
|
it('"foo" is truthy', function () {
|
||||||
|
expect(isTruthy('foo', ctx)).toBeTruthy()
|
||||||
|
})
|
||||||
|
it('"" is truthy', function () {
|
||||||
|
expect(isTruthy('', ctx)).toBeTruthy()
|
||||||
|
})
|
||||||
|
it('0 is truthy', function () {
|
||||||
|
expect(isTruthy(0, ctx)).toBeTruthy()
|
||||||
|
})
|
||||||
|
it('1 is truthy', function () {
|
||||||
|
expect(isTruthy(1, ctx)).toBeTruthy()
|
||||||
|
})
|
||||||
|
it('1.1 is truthy', function () {
|
||||||
|
expect(isTruthy(1.1, ctx)).toBeTruthy()
|
||||||
|
})
|
||||||
|
it('[1] is truthy', function () {
|
||||||
|
expect(isTruthy([1], ctx)).toBeTruthy()
|
||||||
|
})
|
||||||
|
it('[] is truthy', function () {
|
||||||
|
expect(isTruthy([], ctx)).toBeTruthy()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('boolean jsTruthy', function () {
|
||||||
|
const ctx = {
|
||||||
|
opts: {
|
||||||
|
jsTruthy: true
|
||||||
|
}
|
||||||
|
} as unknown as Context
|
||||||
|
|
||||||
|
describe('.isFalsy()', function () {
|
||||||
|
it('null is always falsy', function () {
|
||||||
|
expect(isFalsy(null, ctx)).toBeTruthy()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('.isTruthy()', function () {
|
||||||
|
it('true is truthy', function () {
|
||||||
|
expect(isTruthy(true, ctx)).toBeTruthy()
|
||||||
|
})
|
||||||
|
it('false is falsy', function () {
|
||||||
|
expect(isTruthy(false, ctx)).toBeFalsy()
|
||||||
|
})
|
||||||
|
it('null is always falsy', function () {
|
||||||
|
expect(isTruthy(null, ctx)).toBeFalsy()
|
||||||
|
})
|
||||||
|
it('null is always falsy', function () {
|
||||||
|
expect(isTruthy(null, ctx)).toBeFalsy()
|
||||||
|
})
|
||||||
|
it('"foo" is truthy', function () {
|
||||||
|
expect(isTruthy('foo', ctx)).toBeTruthy()
|
||||||
|
})
|
||||||
|
it('"" is falsy', function () {
|
||||||
|
expect(isTruthy('', ctx)).toBeFalsy()
|
||||||
|
})
|
||||||
|
it('0 is falsy', function () {
|
||||||
|
expect(isTruthy(0, ctx)).toBeFalsy()
|
||||||
|
})
|
||||||
|
it('1 is truthy', function () {
|
||||||
|
expect(isTruthy(1, ctx)).toBeTruthy()
|
||||||
|
})
|
||||||
|
it('1.1 is truthy', function () {
|
||||||
|
expect(isTruthy(1.1, ctx)).toBeTruthy()
|
||||||
|
})
|
||||||
|
it('[1] is truthy', function () {
|
||||||
|
expect(isTruthy([1], ctx)).toBeTruthy()
|
||||||
|
})
|
||||||
|
it('[] is truthy', function () {
|
||||||
|
expect(isTruthy([], ctx)).toBeTruthy()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
import { Tokenizer } from '../../../src/parser/tokenizer'
|
import { Tokenizer } from '../parser'
|
||||||
import { expect } from 'chai'
|
import { Drop } from '../drop'
|
||||||
import { Drop } from '../../../src/drop/drop'
|
import { Context } from '../context'
|
||||||
import { Context } from '../../../src/context/context'
|
import { toPromise, toValueSync } from '../util'
|
||||||
import { toPromise, toValueSync } from '../../../src/util/async'
|
|
||||||
|
|
||||||
describe('Expression', function () {
|
describe('Expression', function () {
|
||||||
const ctx = new Context({})
|
const ctx = new Context({})
|
||||||
@@ -12,26 +11,26 @@ describe('Expression', function () {
|
|||||||
toPromise(create('foo').evaluate(undefined!, false))
|
toPromise(create('foo').evaluate(undefined!, false))
|
||||||
.then(() => done(new Error('should not resolved')))
|
.then(() => done(new Error('should not resolved')))
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
expect(err.message).to.match(/context not defined/)
|
expect(err.message).toMatch(/context not defined/)
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('single value', function () {
|
describe('single value', function () {
|
||||||
it('should eval literal', async function () {
|
it('should eval literal', async function () {
|
||||||
expect(await toPromise(create('2.4').evaluate(ctx, false))).to.equal(2.4)
|
expect(await toPromise(create('2.4').evaluate(ctx, false))).toBe(2.4)
|
||||||
expect(await toPromise(create('"foo"').evaluate(ctx, false))).to.equal('foo')
|
expect(await toPromise(create('"foo"').evaluate(ctx, false))).toBe('foo')
|
||||||
expect(await toPromise(create('false').evaluate(ctx, false))).to.equal(false)
|
expect(await toPromise(create('false').evaluate(ctx, false))).toBe(false)
|
||||||
})
|
})
|
||||||
it('should eval range expression', async function () {
|
it('should eval range expression', async function () {
|
||||||
const ctx = new Context({ two: 2 })
|
const ctx = new Context({ two: 2 })
|
||||||
expect(await toPromise(create('(2..4)').evaluate(ctx, false))).to.deep.equal([2, 3, 4])
|
expect(await toPromise(create('(2..4)').evaluate(ctx, false))).toEqual([2, 3, 4])
|
||||||
expect(await toPromise(create('(two..4)').evaluate(ctx, false))).to.deep.equal([2, 3, 4])
|
expect(await toPromise(create('(two..4)').evaluate(ctx, false))).toEqual([2, 3, 4])
|
||||||
})
|
})
|
||||||
it('should eval literal', async function () {
|
it('should eval literal', async function () {
|
||||||
expect(await toPromise(create('2.4').evaluate(ctx, false))).to.equal(2.4)
|
expect(await toPromise(create('2.4').evaluate(ctx, false))).toBe(2.4)
|
||||||
expect(await toPromise(create('"foo"').evaluate(ctx, false))).to.equal('foo')
|
expect(await toPromise(create('"foo"').evaluate(ctx, false))).toBe('foo')
|
||||||
expect(await toPromise(create('false').evaluate(ctx, false))).to.equal(false)
|
expect(await toPromise(create('false').evaluate(ctx, false))).toBe(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should eval property access', async function () {
|
it('should eval property access', async function () {
|
||||||
@@ -40,18 +39,18 @@ describe('Expression', function () {
|
|||||||
coo: 'bar',
|
coo: 'bar',
|
||||||
doo: { foo: 'bar', bar: { foo: 'bar' } }
|
doo: { foo: 'bar', bar: { foo: 'bar' } }
|
||||||
})
|
})
|
||||||
expect(await toPromise(create('foo.bar').evaluate(ctx, false))).to.equal('BAR')
|
expect(await toPromise(create('foo.bar').evaluate(ctx, false))).toBe('BAR')
|
||||||
expect(await toPromise(create('foo["bar"]').evaluate(ctx, false))).to.equal('BAR')
|
expect(await toPromise(create('foo["bar"]').evaluate(ctx, false))).toBe('BAR')
|
||||||
expect(await toPromise(create('foo[coo]').evaluate(ctx, false))).to.equal('BAR')
|
expect(await toPromise(create('foo[coo]').evaluate(ctx, false))).toBe('BAR')
|
||||||
expect(await toPromise(create('foo[doo.foo]').evaluate(ctx, false))).to.equal('BAR')
|
expect(await toPromise(create('foo[doo.foo]').evaluate(ctx, false))).toBe('BAR')
|
||||||
expect(await toPromise(create('foo[doo["foo"]]').evaluate(ctx, false))).to.equal('BAR')
|
expect(await toPromise(create('foo[doo["foo"]]').evaluate(ctx, false))).toBe('BAR')
|
||||||
expect(await toPromise(create('doo[coo].foo').evaluate(ctx, false))).to.equal('bar')
|
expect(await toPromise(create('doo[coo].foo').evaluate(ctx, false))).toBe('bar')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('simple expression', function () {
|
describe('simple expression', function () {
|
||||||
it('should return false for "1==2"', async () => {
|
it('should return false for "1==2"', async () => {
|
||||||
expect(await toPromise(create('1==2').evaluate(ctx, false))).to.equal(false)
|
expect(await toPromise(create('1==2').evaluate(ctx, false))).toBe(false)
|
||||||
})
|
})
|
||||||
it('should apply deep equal for arrays', async () => {
|
it('should apply deep equal for arrays', async () => {
|
||||||
const ctx = new Context({
|
const ctx = new Context({
|
||||||
@@ -59,133 +58,133 @@ describe('Expression', function () {
|
|||||||
arr2: [1, 2],
|
arr2: [1, 2],
|
||||||
arr3: [1, 2, 3]
|
arr3: [1, 2, 3]
|
||||||
})
|
})
|
||||||
expect(await toPromise(create('arr1==arr2').evaluate(ctx, false))).to.equal(true)
|
expect(await toPromise(create('arr1==arr2').evaluate(ctx, false))).toBe(true)
|
||||||
expect(await toPromise(create('arr1==arr3').evaluate(ctx, false))).to.equal(false)
|
expect(await toPromise(create('arr1==arr3').evaluate(ctx, false))).toBe(false)
|
||||||
})
|
})
|
||||||
it('should return true for "1<2"', async () => {
|
it('should return true for "1<2"', async () => {
|
||||||
expect(await toPromise(create('1<2').evaluate(ctx, false))).to.equal(true)
|
expect(await toPromise(create('1<2').evaluate(ctx, false))).toBe(true)
|
||||||
})
|
})
|
||||||
it('should return true for "1 < 2"', async () => {
|
it('should return true for "1 < 2"', async () => {
|
||||||
expect(await toPromise(create('1 < 2').evaluate(ctx, false))).to.equal(true)
|
expect(await toPromise(create('1 < 2').evaluate(ctx, false))).toBe(true)
|
||||||
})
|
})
|
||||||
it('should return true for "1 < 2"', async () => {
|
it('should return true for "1 < 2"', async () => {
|
||||||
expect(await toPromise(create('1 < 2').evaluate(ctx, false))).to.equal(true)
|
expect(await toPromise(create('1 < 2').evaluate(ctx, false))).toBe(true)
|
||||||
})
|
})
|
||||||
it('should return true for "2 <= 2"', async () => {
|
it('should return true for "2 <= 2"', async () => {
|
||||||
expect(await toPromise(create('2 <= 2').evaluate(ctx, false))).to.equal(true)
|
expect(await toPromise(create('2 <= 2').evaluate(ctx, false))).toBe(true)
|
||||||
})
|
})
|
||||||
it('should return true for "one <= two"', async () => {
|
it('should return true for "one <= two"', async () => {
|
||||||
const ctx = new Context({ one: 1, two: 2 })
|
const ctx = new Context({ one: 1, two: 2 })
|
||||||
expect(await toPromise(create('one <= two').evaluate(ctx, false))).to.equal(true)
|
expect(await toPromise(create('one <= two').evaluate(ctx, false))).toBe(true)
|
||||||
})
|
})
|
||||||
it('should return false for "x contains "x""', async () => {
|
it('should return false for "x contains "x""', async () => {
|
||||||
const ctx = new Context({ x: 'XXX' })
|
const ctx = new Context({ x: 'XXX' })
|
||||||
expect(await toPromise(create('x contains "x"').evaluate(ctx, false))).to.equal(false)
|
expect(await toPromise(create('x contains "x"').evaluate(ctx, false))).toBe(false)
|
||||||
})
|
})
|
||||||
it('should return true for "x contains "X""', async () => {
|
it('should return true for "x contains "X""', async () => {
|
||||||
const ctx = new Context({ x: 'XXX' })
|
const ctx = new Context({ x: 'XXX' })
|
||||||
expect(await toPromise(create('x contains "X"').evaluate(ctx, false))).to.equal(true)
|
expect(await toPromise(create('x contains "X"').evaluate(ctx, false))).toBe(true)
|
||||||
})
|
})
|
||||||
it('should return false for "1 contains "x""', async () => {
|
it('should return false for "1 contains "x""', async () => {
|
||||||
const ctx = new Context({ x: 'XXX' })
|
const ctx = new Context({ x: 'XXX' })
|
||||||
expect(await toPromise(create('1 contains "x"').evaluate(ctx, false))).to.equal(false)
|
expect(await toPromise(create('1 contains "x"').evaluate(ctx, false))).toBe(false)
|
||||||
})
|
})
|
||||||
it('should return false for "y contains "x""', async () => {
|
it('should return false for "y contains "x""', async () => {
|
||||||
const ctx = new Context({ x: 'XXX' })
|
const ctx = new Context({ x: 'XXX' })
|
||||||
expect(await toPromise(create('y contains "x"').evaluate(ctx, false))).to.equal(false)
|
expect(await toPromise(create('y contains "x"').evaluate(ctx, false))).toBe(false)
|
||||||
})
|
})
|
||||||
it('should return false for "z contains "x""', async () => {
|
it('should return false for "z contains "x""', async () => {
|
||||||
const ctx = new Context({ x: 'XXX' })
|
const ctx = new Context({ x: 'XXX' })
|
||||||
expect(await toPromise(create('z contains "x"').evaluate(ctx, false))).to.equal(false)
|
expect(await toPromise(create('z contains "x"').evaluate(ctx, false))).toBe(false)
|
||||||
})
|
})
|
||||||
it('should return true for "(1..5) contains 3"', async () => {
|
it('should return true for "(1..5) contains 3"', async () => {
|
||||||
const ctx = new Context({ x: 'XXX' })
|
const ctx = new Context({ x: 'XXX' })
|
||||||
expect(await toPromise(create('(1..5) contains 3').evaluate(ctx, false))).to.equal(true)
|
expect(await toPromise(create('(1..5) contains 3').evaluate(ctx, false))).toBe(true)
|
||||||
})
|
})
|
||||||
it('should return false for "(1..5) contains 6"', async () => {
|
it('should return false for "(1..5) contains 6"', async () => {
|
||||||
const ctx = new Context({ x: 'XXX' })
|
const ctx = new Context({ x: 'XXX' })
|
||||||
expect(await toPromise(create('(1..5) contains 6').evaluate(ctx, false))).to.equal(false)
|
expect(await toPromise(create('(1..5) contains 6').evaluate(ctx, false))).toBe(false)
|
||||||
})
|
})
|
||||||
it('should return true for ""<=" == "<=""', async () => {
|
it('should return true for ""<=" == "<=""', async () => {
|
||||||
expect(await toPromise(create('"<=" == "<="').evaluate(ctx, false))).to.equal(true)
|
expect(await toPromise(create('"<=" == "<="').evaluate(ctx, false))).toBe(true)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should allow space in quoted value', async function () {
|
it('should allow space in quoted value', async function () {
|
||||||
const ctx = new Context({ space: ' ' })
|
const ctx = new Context({ space: ' ' })
|
||||||
expect(await toPromise(create('" " == space').evaluate(ctx, false))).to.equal(true)
|
expect(await toPromise(create('" " == space').evaluate(ctx, false))).toBe(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('escape', () => {
|
describe('escape', () => {
|
||||||
it('should escape quote', async function () {
|
it('should escape quote', async function () {
|
||||||
const ctx = new Context({ quote: '"' })
|
const ctx = new Context({ quote: '"' })
|
||||||
expect(await toPromise(create('"\\"" == quote').evaluate(ctx, false))).to.equal(true)
|
expect(await toPromise(create('"\\"" == quote').evaluate(ctx, false))).toBe(true)
|
||||||
})
|
})
|
||||||
it('should escape square bracket', async function () {
|
it('should escape square bracket', async function () {
|
||||||
const ctx = new Context({ obj: { ']': 'bracket' } })
|
const ctx = new Context({ obj: { ']': 'bracket' } })
|
||||||
expect(await toPromise(create('obj["]"] == "bracket"').evaluate(ctx, false))).to.equal(true)
|
expect(await toPromise(create('obj["]"] == "bracket"').evaluate(ctx, false))).toBe(true)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('complex expression', function () {
|
describe('complex expression', function () {
|
||||||
it('should support value or value', async function () {
|
it('should support value or value', async function () {
|
||||||
expect(await toPromise(create('false or true').evaluate(ctx, false))).to.equal(true)
|
expect(await toPromise(create('false or true').evaluate(ctx, false))).toBe(true)
|
||||||
})
|
})
|
||||||
it('should support < and contains', async function () {
|
it('should support < and contains', async function () {
|
||||||
expect(await toPromise(create('1 < 2 and x contains "x"').evaluate(ctx, false))).to.equal(false)
|
expect(await toPromise(create('1 < 2 and x contains "x"').evaluate(ctx, false))).toBe(false)
|
||||||
})
|
})
|
||||||
it('should support < or contains', async function () {
|
it('should support < or contains', async function () {
|
||||||
expect(await toPromise(create('1 < 2 or x contains "x"').evaluate(ctx, false))).to.equal(true)
|
expect(await toPromise(create('1 < 2 or x contains "x"').evaluate(ctx, false))).toBe(true)
|
||||||
})
|
})
|
||||||
it('should support Drops for "x contains "x""', async () => {
|
it('should support Drops for "x contains "x""', async () => {
|
||||||
class TemplateDrop extends Drop {
|
class TemplateDrop extends Drop {
|
||||||
valueOf () { return 'X' }
|
valueOf () { return 'X' }
|
||||||
}
|
}
|
||||||
const ctx = new Context({ x: 'XXX', X: new TemplateDrop() })
|
const ctx = new Context({ x: 'XXX', X: new TemplateDrop() })
|
||||||
expect(await toPromise(create('x contains X').evaluate(ctx, false))).to.equal(true)
|
expect(await toPromise(create('x contains X').evaluate(ctx, false))).toBe(true)
|
||||||
})
|
})
|
||||||
it('should support value and !=', async function () {
|
it('should support value and !=', async function () {
|
||||||
const ctx = new Context({ empty: '' })
|
const ctx = new Context({ empty: '' })
|
||||||
expect(await toPromise(create('empty and empty != ""').evaluate(ctx, false))).to.equal(false)
|
expect(await toPromise(create('empty and empty != ""').evaluate(ctx, false))).toBe(false)
|
||||||
})
|
})
|
||||||
it('should recognize quoted value', async function () {
|
it('should recognize quoted value', async function () {
|
||||||
expect(await toPromise(create('">"').evaluate(ctx, false))).to.equal('>')
|
expect(await toPromise(create('">"').evaluate(ctx, false))).toBe('>')
|
||||||
})
|
})
|
||||||
it('should evaluate from right to left', async function () {
|
it('should evaluate from right to left', async function () {
|
||||||
expect(await toPromise(create('true or false and false').evaluate(ctx, false))).to.equal(true)
|
expect(await toPromise(create('true or false and false').evaluate(ctx, false))).toBe(true)
|
||||||
expect(await toPromise(create('true and false and false or true').evaluate(ctx, false))).to.equal(false)
|
expect(await toPromise(create('true and false and false or true').evaluate(ctx, false))).toBe(false)
|
||||||
})
|
})
|
||||||
it('should recognize property access', async function () {
|
it('should recognize property access', async function () {
|
||||||
const ctx = new Context({ obj: { foo: true } })
|
const ctx = new Context({ obj: { foo: true } })
|
||||||
expect(await toPromise(create('obj["foo"] and true').evaluate(ctx, false))).to.equal(true)
|
expect(await toPromise(create('obj["foo"] and true').evaluate(ctx, false))).toBe(true)
|
||||||
})
|
})
|
||||||
it('should allow nested property access', async function () {
|
it('should allow nested property access', async function () {
|
||||||
const ctx = new Context({ obj: { foo: 'FOO' }, keys: { "what's this": 'foo' } })
|
const ctx = new Context({ obj: { foo: 'FOO' }, keys: { "what's this": 'foo' } })
|
||||||
expect(await toPromise(create('obj[keys["what\'s this"]]').evaluate(ctx, false))).to.equal('FOO')
|
expect(await toPromise(create('obj[keys["what\'s this"]]').evaluate(ctx, false))).toBe('FOO')
|
||||||
})
|
})
|
||||||
it('should support not', async function () {
|
it('should support not', async function () {
|
||||||
expect(await toPromise(create('not 1 < 2').evaluate(ctx))).to.equal(false)
|
expect(await toPromise(create('not 1 < 2').evaluate(ctx))).toBe(false)
|
||||||
})
|
})
|
||||||
it('not should have higher precedence than and/or', async function () {
|
it('not should have higher precedence than and/or', async function () {
|
||||||
expect(await toPromise(create('not 1 < 2 or not 1 > 2').evaluate(ctx))).to.equal(true)
|
expect(await toPromise(create('not 1 < 2 or not 1 > 2').evaluate(ctx))).toBe(true)
|
||||||
expect(await toPromise(create('not 1 < 2 and not 1 > 2').evaluate(ctx))).to.equal(false)
|
expect(await toPromise(create('not 1 < 2 and not 1 > 2').evaluate(ctx))).toBe(false)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('sync', function () {
|
describe('sync', function () {
|
||||||
it('should eval literal', function () {
|
it('should eval literal', function () {
|
||||||
expect(toValueSync(create('2.4').evaluate(ctx, false))).to.equal(2.4)
|
expect(toValueSync(create('2.4').evaluate(ctx, false))).toBe(2.4)
|
||||||
})
|
})
|
||||||
it('should return false for "1==2"', () => {
|
it('should return false for "1==2"', () => {
|
||||||
expect(toValueSync(create('1==2').evaluate(ctx, false))).to.equal(false)
|
expect(toValueSync(create('1==2').evaluate(ctx, false))).toBe(false)
|
||||||
})
|
})
|
||||||
it('should escape quote', function () {
|
it('should escape quote', function () {
|
||||||
const ctx = new Context({ quote: '"' })
|
const ctx = new Context({ quote: '"' })
|
||||||
expect(toValueSync(create('"\\"" == quote').evaluate(ctx, false))).to.equal(true)
|
expect(toValueSync(create('"\\"" == quote').evaluate(ctx, false))).toBe(true)
|
||||||
})
|
})
|
||||||
it('should allow nested property access', function () {
|
it('should allow nested property access', function () {
|
||||||
const ctx = new Context({ obj: { foo: 'FOO' }, keys: { "what's this": 'foo' } })
|
const ctx = new Context({ obj: { foo: 'FOO' }, keys: { "what's this": 'foo' } })
|
||||||
expect(toValueSync(create('obj[keys["what\'s this"]]').evaluate(ctx, false))).to.equal('FOO')
|
expect(toValueSync(create('obj[keys["what\'s this"]]').evaluate(ctx, false))).toBe('FOO')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,15 +1,13 @@
|
|||||||
import { expect } from 'chai'
|
import { Context } from '../context'
|
||||||
import { Context } from '../../../src/context/context'
|
import { HTMLToken, TagToken } from '../tokens'
|
||||||
import { HTMLToken, TagToken } from '../../../src/tokens'
|
import { Render } from './render'
|
||||||
import { Render } from '../../../src/render/render'
|
import { Tag, HTML } from '../template'
|
||||||
import { HTML } from '../../../src/template/html'
|
import { SimpleEmitter } from '../emitters'
|
||||||
import { SimpleEmitter } from '../../../src/emitters/simple-emitter'
|
import { toPromise } from '../util'
|
||||||
import { toPromise } from '../../../src/util/async'
|
|
||||||
import { Tag } from '../../../src/template/tag'
|
|
||||||
|
|
||||||
describe('render', function () {
|
describe('render', function () {
|
||||||
let render: Render
|
let render: Render
|
||||||
before(function () {
|
beforeEach(function () {
|
||||||
render = new Render()
|
render = new Render()
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -18,7 +16,7 @@ describe('render', function () {
|
|||||||
const scope = new Context()
|
const scope = new Context()
|
||||||
const token = { getContent: () => '<p>' } as HTMLToken
|
const token = { getContent: () => '<p>' } as HTMLToken
|
||||||
const html = await toPromise(render.renderTemplates([new HTML(token)], scope, new SimpleEmitter()))
|
const html = await toPromise(render.renderTemplates([new HTML(token)], scope, new SimpleEmitter()))
|
||||||
return expect(html).to.equal('<p>')
|
return expect(html).toBe('<p>')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -35,7 +33,7 @@ describe('render', function () {
|
|||||||
result += data
|
result += data
|
||||||
})
|
})
|
||||||
stream.on('end', () => {
|
stream.on('end', () => {
|
||||||
expect(result).to.equal('<p></p>')
|
expect(result).toBe('<p></p>')
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -59,7 +57,7 @@ describe('render', function () {
|
|||||||
result += data
|
result += data
|
||||||
})
|
})
|
||||||
stream.on('end', () => {
|
stream.on('end', () => {
|
||||||
expect(result).to.equal('<p>async tag</p>')
|
expect(result).toBe('<p>async tag</p>')
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,58 +1,55 @@
|
|||||||
import * as chai from 'chai'
|
import { Context } from '../context'
|
||||||
import * as sinon from 'sinon'
|
import { toPromise } from '../util'
|
||||||
import * as sinonChai from 'sinon-chai'
|
import { IdentifierToken, NumberToken, QuotedToken } from '../tokens'
|
||||||
import { Context } from '../../../../src/context'
|
import { Filter } from './filter'
|
||||||
import { toPromise } from '../../../../src/util'
|
|
||||||
import { IdentifierToken, NumberToken, QuotedToken } from '../../../../src/tokens'
|
|
||||||
import { Filter } from '../../../../src/template'
|
|
||||||
|
|
||||||
chai.use(sinonChai)
|
|
||||||
const expect = chai.expect
|
|
||||||
|
|
||||||
describe('filter', function () {
|
describe('filter', function () {
|
||||||
const ctx = new Context()
|
const ctx = new Context({ thirty: 30 })
|
||||||
const liquid = {} as any
|
const liquid = { testVersion: '1.0' } as any
|
||||||
it('should not change input if filter not registered', async function () {
|
it('should not change input if filter not registered', async function () {
|
||||||
const filter = new Filter('foo', undefined as any, [], liquid)
|
const filter = new Filter('foo', undefined as any, [], liquid)
|
||||||
expect(await toPromise(filter.render('value', ctx))).to.equal('value')
|
expect(await toPromise(filter.render('value', ctx))).toBe('value')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should call filter impl with correct arguments', async function () {
|
it('should call filter impl with correct arguments', async function () {
|
||||||
const spy = sinon.spy()
|
const spy = jest.fn()
|
||||||
const thirty = new NumberToken(new IdentifierToken('30', 0, 2), undefined)
|
const thirty = new NumberToken(new IdentifierToken('30', 0, 2), undefined)
|
||||||
const filter = new Filter('foo', spy, [thirty], liquid)
|
const filter = new Filter('foo', spy, [thirty], liquid)
|
||||||
await toPromise(filter.render('foo', ctx))
|
await toPromise(filter.render('foo', ctx))
|
||||||
expect(spy).to.have.been.calledWith('foo', 30)
|
expect(spy).toHaveBeenCalledWith('foo', 30)
|
||||||
})
|
})
|
||||||
it('should call filter impl with correct this', async function () {
|
it('should call filter impl with correct this', async function () {
|
||||||
const spy = sinon.spy()
|
const spy = jest.fn(function * (valStr, diff): Generator<string> {
|
||||||
const thirty = new NumberToken(new IdentifierToken('33', 0, 2), undefined)
|
const val = yield this.context._get([valStr])
|
||||||
await toPromise(new Filter('foo', spy, [thirty], liquid).render('foo', ctx))
|
return `${this.liquid.testVersion}: ${val + diff}`
|
||||||
expect(spy).to.have.been.calledOn(sinon.match.has('context', ctx))
|
})
|
||||||
expect(spy).to.have.been.calledOn(sinon.match.has('liquid', liquid))
|
const ten = new NumberToken(new IdentifierToken('10', 0, 2), undefined)
|
||||||
|
const filter = new Filter('add', spy, [ten], liquid)
|
||||||
|
const val = await toPromise(filter.render('thirty', ctx))
|
||||||
|
expect(val).toEqual('1.0: 40')
|
||||||
})
|
})
|
||||||
it('should render a simple filter', async function () {
|
it('should render a simple filter', async function () {
|
||||||
expect(await toPromise(new Filter('upcase', (x: string) => x.toUpperCase(), [], liquid).render('foo', ctx))).to.equal('FOO')
|
expect(await toPromise(new Filter('upcase', (x: string) => x.toUpperCase(), [], liquid).render('foo', ctx))).toBe('FOO')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should render filters with argument', async function () {
|
it('should render filters with argument', async function () {
|
||||||
const two = new NumberToken(new IdentifierToken('2', 0, 1), undefined)
|
const two = new NumberToken(new IdentifierToken('2', 0, 1), undefined)
|
||||||
expect(await toPromise(new Filter('add', (a: number, b: number) => a + b, [two], liquid).render(3, ctx))).to.equal(5)
|
expect(await toPromise(new Filter('add', (a: number, b: number) => a + b, [two], liquid).render(3, ctx))).toBe(5)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should render filters with multiple arguments', async function () {
|
it('should render filters with multiple arguments', async function () {
|
||||||
const two = new NumberToken(new IdentifierToken('2', 0, 1), undefined)
|
const two = new NumberToken(new IdentifierToken('2', 0, 1), undefined)
|
||||||
const c = new QuotedToken('"c"', 0, 3)
|
const c = new QuotedToken('"c"', 0, 3)
|
||||||
expect(await toPromise(new Filter('add', (a: number, b: number, c: number) => a + b + c, [two, c], liquid).render(3, ctx))).to.equal('5c')
|
expect(await toPromise(new Filter('add', (a: number, b: number, c: number) => a + b + c, [two, c], liquid).render(3, ctx))).toBe('5c')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should pass Objects/Drops as it is', async function () {
|
it('should pass Objects/Drops as it is', async function () {
|
||||||
class Foo {}
|
class Foo {}
|
||||||
expect(await toPromise(new Filter('name', (a: any) => a.constructor.name, [], liquid).render(new Foo(), ctx))).to.equal('Foo')
|
expect(await toPromise(new Filter('name', (a: any) => a.constructor.name, [], liquid).render(new Foo(), ctx))).toBe('Foo')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support key value pairs', async function () {
|
it('should support key value pairs', async function () {
|
||||||
const two = new NumberToken(new IdentifierToken('2', 0, 1), undefined)
|
const two = new NumberToken(new IdentifierToken('2', 0, 1), undefined)
|
||||||
expect(await toPromise(new Filter('add', (a: number, b: number[]) => b[0] + ':' + (a + b[1]), [['num', two]], liquid).render(3, ctx))).to.equal('num:5')
|
expect(await toPromise(new Filter('add', (a: number, b: number[]) => b[0] + ':' + (a + b[1]), [['num', two]], liquid).render(3, ctx))).toBe('num:5')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,41 +1,38 @@
|
|||||||
import * as chai from 'chai'
|
import { toPromise } from '../util'
|
||||||
import { toPromise } from '../../../src/util/async'
|
import { Hash } from './hash'
|
||||||
import { Hash } from '../../../src/template/hash'
|
import { Context } from '../context'
|
||||||
import { Context } from '../../../src/context/context'
|
|
||||||
|
|
||||||
const expect = chai.expect
|
|
||||||
|
|
||||||
describe('Hash', function () {
|
describe('Hash', function () {
|
||||||
it('should parse "reverse"', async function () {
|
it('should parse "reverse"', async function () {
|
||||||
const hash = await toPromise(new Hash('reverse').render(new Context({ foo: 3 })))
|
const hash = await toPromise(new Hash('reverse').render(new Context({ foo: 3 })))
|
||||||
expect(hash).to.haveOwnProperty('reverse')
|
expect(hash).toHaveProperty('reverse')
|
||||||
expect(hash.reverse).to.be.true
|
expect(hash.reverse).toBeTruthy()
|
||||||
})
|
})
|
||||||
it('should parse "num:foo"', async function () {
|
it('should parse "num:foo"', async function () {
|
||||||
const hash = await toPromise(new Hash('num:foo').render(new Context({ foo: 3 })))
|
const hash = await toPromise(new Hash('num:foo').render(new Context({ foo: 3 })))
|
||||||
expect(hash.num).to.equal(3)
|
expect(hash.num).toBe(3)
|
||||||
})
|
})
|
||||||
it('should parse "num:3"', async function () {
|
it('should parse "num:3"', async function () {
|
||||||
const hash = await toPromise(new Hash('num:3').render(new Context()))
|
const hash = await toPromise(new Hash('num:3').render(new Context()))
|
||||||
expect(hash.num).to.equal(3)
|
expect(hash.num).toBe(3)
|
||||||
})
|
})
|
||||||
it('should parse "num: arr[0]"', async function () {
|
it('should parse "num: arr[0]"', async function () {
|
||||||
const hash = await toPromise(new Hash('num:3').render(new Context({ arr: [3] })))
|
const hash = await toPromise(new Hash('num:3').render(new Context({ arr: [3] })))
|
||||||
expect(hash.num).to.equal(3)
|
expect(hash.num).toBe(3)
|
||||||
})
|
})
|
||||||
it('should parse "num: 2.3"', async function () {
|
it('should parse "num: 2.3"', async function () {
|
||||||
const hash = await toPromise(new Hash('num:2.3').render(new Context()))
|
const hash = await toPromise(new Hash('num:2.3').render(new Context()))
|
||||||
expect(hash.num).to.equal(2.3)
|
expect(hash.num).toBe(2.3)
|
||||||
})
|
})
|
||||||
it('should parse "num:bar.coo"', async function () {
|
it('should parse "num:bar.coo"', async function () {
|
||||||
const pending = new Hash('num:bar.coo').render(new Context({ bar: { coo: 3 } }))
|
const pending = new Hash('num:bar.coo').render(new Context({ bar: { coo: 3 } }))
|
||||||
const hash = await toPromise(pending)
|
const hash = await toPromise(pending)
|
||||||
expect(hash.num).to.equal(3)
|
expect(hash.num).toBe(3)
|
||||||
})
|
})
|
||||||
it('should parse "num1:2.3 reverse,num2:bar.coo\n num3: arr[0]"', async function () {
|
it('should parse "num1:2.3 reverse,num2:bar.coo\n num3: arr[0]"', async function () {
|
||||||
const ctx = new Context({ bar: { coo: 3 }, arr: [4] })
|
const ctx = new Context({ bar: { coo: 3 }, arr: [4] })
|
||||||
const hash = await toPromise(new Hash('num1:2.3 reverse,num2:bar.coo\n num3: arr[0]').render(ctx))
|
const hash = await toPromise(new Hash('num1:2.3 reverse,num2:bar.coo\n num3: arr[0]').render(ctx))
|
||||||
expect(hash).to.deep.equal({
|
expect(hash).toEqual({
|
||||||
num1: 2.3,
|
num1: 2.3,
|
||||||
reverse: true,
|
reverse: true,
|
||||||
num2: 3,
|
num2: 3,
|
||||||
@@ -1,11 +1,8 @@
|
|||||||
import * as chai from 'chai'
|
import { toPromise } from '../util'
|
||||||
import { toPromise } from '../../../src/util/async'
|
import { Context } from '../context'
|
||||||
import { Context } from '../../../src/context/context'
|
import { Output } from '../template'
|
||||||
import { Output } from '../../../src/template/output'
|
import { OutputToken } from '../tokens'
|
||||||
import { OutputToken } from '../../../src/tokens/output-token'
|
import { defaultOptions } from '../liquid-options'
|
||||||
import { defaultOptions } from '../../../src/liquid-options'
|
|
||||||
|
|
||||||
const expect = chai.expect
|
|
||||||
|
|
||||||
describe('Output', function () {
|
describe('Output', function () {
|
||||||
const emitter: any = { write: (html: string) => (emitter.html += html), html: '' }
|
const emitter: any = { write: (html: string) => (emitter.html += html), html: '' }
|
||||||
@@ -18,27 +15,27 @@ describe('Output', function () {
|
|||||||
})
|
})
|
||||||
const output = new Output({ content: 'foo' } as OutputToken, liquid)
|
const output = new Output({ content: 'foo' } as OutputToken, liquid)
|
||||||
await toPromise(output.render(scope, emitter))
|
await toPromise(output.render(scope, emitter))
|
||||||
return expect(emitter.html).to.equal('[object Object]')
|
return expect(emitter.html).toBe('[object Object]')
|
||||||
})
|
})
|
||||||
it('should skip function property', async function () {
|
it('should skip function property', async function () {
|
||||||
const scope = new Context({ obj: { foo: 'foo', bar: (x: any) => x } })
|
const scope = new Context({ obj: { foo: 'foo', bar: (x: any) => x } })
|
||||||
const output = new Output({ content: 'obj' } as OutputToken, liquid)
|
const output = new Output({ content: 'obj' } as OutputToken, liquid)
|
||||||
await toPromise(output.render(scope, emitter))
|
await toPromise(output.render(scope, emitter))
|
||||||
return expect(emitter.html).to.equal('[object Object]')
|
return expect(emitter.html).toBe('[object Object]')
|
||||||
})
|
})
|
||||||
it('should respect to .toString()', async () => {
|
it('should respect to .toString()', async () => {
|
||||||
const scope = new Context({ obj: { toString: () => 'FOO' } })
|
const scope = new Context({ obj: { toString: () => 'FOO' } })
|
||||||
const output = new Output({ content: 'obj' } as OutputToken, liquid)
|
const output = new Output({ content: 'obj' } as OutputToken, liquid)
|
||||||
await toPromise(output.render(scope, emitter))
|
await toPromise(output.render(scope, emitter))
|
||||||
return expect(emitter.html).to.equal('FOO')
|
return expect(emitter.html).toBe('FOO')
|
||||||
})
|
})
|
||||||
it('should respect to .toString()', async () => {
|
it('should respect to .toString()', async () => {
|
||||||
const scope = new Context({ obj: { toString: () => 'FOO' } })
|
const scope = new Context({ obj: { toString: () => 'FOO' } })
|
||||||
const output = new Output({ content: 'obj' } as OutputToken, liquid)
|
const output = new Output({ content: 'obj' } as OutputToken, liquid)
|
||||||
await toPromise(output.render(scope, emitter))
|
await toPromise(output.render(scope, emitter))
|
||||||
return expect(emitter.html).to.equal('FOO')
|
return expect(emitter.html).toBe('FOO')
|
||||||
})
|
})
|
||||||
context('when keepOutputType is enabled', () => {
|
describe('when keepOutputType is enabled', () => {
|
||||||
const emitter: any = {
|
const emitter: any = {
|
||||||
write: (html: any) => {
|
write: (html: any) => {
|
||||||
if (emitter.keepOutputType && typeof html !== 'string') {
|
if (emitter.keepOutputType && typeof html !== 'string') {
|
||||||
@@ -59,7 +56,7 @@ describe('Output', function () {
|
|||||||
}, { ...defaultOptions, keepOutputType: true })
|
}, { ...defaultOptions, keepOutputType: true })
|
||||||
const output = new Output({ content: 'foo' } as OutputToken, liquid)
|
const output = new Output({ content: 'foo' } as OutputToken, liquid)
|
||||||
await toPromise(output.render(scope, emitter))
|
await toPromise(output.render(scope, emitter))
|
||||||
return expect(emitter.html).to.equal(42)
|
return expect(emitter.html).toBe(42)
|
||||||
})
|
})
|
||||||
it('should respect output variable boolean type', async () => {
|
it('should respect output variable boolean type', async () => {
|
||||||
const scope = new Context({
|
const scope = new Context({
|
||||||
@@ -67,7 +64,7 @@ describe('Output', function () {
|
|||||||
}, { ...defaultOptions, keepOutputType: true })
|
}, { ...defaultOptions, keepOutputType: true })
|
||||||
const output = new Output({ content: 'foo' } as OutputToken, liquid)
|
const output = new Output({ content: 'foo' } as OutputToken, liquid)
|
||||||
await toPromise(output.render(scope, emitter))
|
await toPromise(output.render(scope, emitter))
|
||||||
return expect(emitter.html).to.equal(true)
|
return expect(emitter.html).toBe(true)
|
||||||
})
|
})
|
||||||
it('should respect output variable object type', async () => {
|
it('should respect output variable object type', async () => {
|
||||||
const scope = new Context({
|
const scope = new Context({
|
||||||
@@ -75,7 +72,7 @@ describe('Output', function () {
|
|||||||
}, { ...defaultOptions, keepOutputType: true })
|
}, { ...defaultOptions, keepOutputType: true })
|
||||||
const output = new Output({ content: 'foo' } as OutputToken, liquid)
|
const output = new Output({ content: 'foo' } as OutputToken, liquid)
|
||||||
await toPromise(output.render(scope, emitter))
|
await toPromise(output.render(scope, emitter))
|
||||||
return expect(emitter.html).to.equal('test')
|
return expect(emitter.html).toBe('test')
|
||||||
})
|
})
|
||||||
it('should respect output variable string type', async () => {
|
it('should respect output variable string type', async () => {
|
||||||
const scope = new Context({
|
const scope = new Context({
|
||||||
@@ -83,7 +80,7 @@ describe('Output', function () {
|
|||||||
}, { ...defaultOptions, keepOutputType: true })
|
}, { ...defaultOptions, keepOutputType: true })
|
||||||
const output = new Output({ content: 'foo' } as OutputToken, liquid)
|
const output = new Output({ content: 'foo' } as OutputToken, liquid)
|
||||||
await toPromise(output.render(scope, emitter))
|
await toPromise(output.render(scope, emitter))
|
||||||
return expect(emitter.html).to.deep.equal({ a: { b: 42 } })
|
return expect(emitter.html).toEqual({ a: { b: 42 } })
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
import { Liquid } from '../liquid'
|
||||||
|
import { QuotedToken } from '../tokens'
|
||||||
|
import { toPromise } from '../util'
|
||||||
|
import { Context } from '../context'
|
||||||
|
import { Value } from '../template'
|
||||||
|
|
||||||
|
describe('Value', function () {
|
||||||
|
const liquid = new Liquid()
|
||||||
|
|
||||||
|
describe('#constructor()', function () {
|
||||||
|
it('should parse filters in value content', function () {
|
||||||
|
const f = new Value('o | foo: a: "a"', liquid)
|
||||||
|
expect(f.filters[0].name).toBe('foo')
|
||||||
|
expect(f.filters[0].args).toHaveLength(1)
|
||||||
|
const [k, v] = f.filters[0].args[0] as any
|
||||||
|
expect(k).toBe('a')
|
||||||
|
expect(v).toBeInstanceOf(QuotedToken)
|
||||||
|
expect((v as QuotedToken).getText()).toBe('"a"')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('#value()', function () {
|
||||||
|
it('should call chained filters correctly', async function () {
|
||||||
|
const date = jest.fn(() => 'y')
|
||||||
|
const time = jest.fn()
|
||||||
|
liquid.registerFilter('date', date)
|
||||||
|
liquid.registerFilter('time', time)
|
||||||
|
const tpl = new Value('foo.bar | date: "b" | time:2', liquid)
|
||||||
|
const scope = new Context({
|
||||||
|
foo: { bar: 'bar' }
|
||||||
|
})
|
||||||
|
await toPromise(tpl.value(scope, false))
|
||||||
|
expect(date).toHaveBeenCalledWith('bar', 'b')
|
||||||
|
expect(time).toHaveBeenCalledWith('y', 2)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import { QuotedToken, PropertyAccessToken, IdentifierToken } from '.'
|
||||||
|
|
||||||
|
describe('PropertyAccessToken', function () {
|
||||||
|
describe('#propertyName', function () {
|
||||||
|
it('should return correct value for IdentifierToken', function () {
|
||||||
|
const token = new PropertyAccessToken(new IdentifierToken('foo', 0, 3), [], 3)
|
||||||
|
expect(token.propertyName).toBe('foo')
|
||||||
|
})
|
||||||
|
it('should return correct value for QuotedToken', function () {
|
||||||
|
const token = new PropertyAccessToken(new QuotedToken('"foo bar"', 0, 9), [], 9)
|
||||||
|
expect(token.propertyName).toBe('foo bar')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -1,19 +1,16 @@
|
|||||||
import * as chai from 'chai'
|
import { assert } from './assert'
|
||||||
import { assert } from '../../../src/util/assert'
|
|
||||||
|
|
||||||
const expect = chai.expect
|
|
||||||
|
|
||||||
describe('assert', function () {
|
describe('assert', function () {
|
||||||
it('should not throw if predicate is truthy', function () {
|
it('should not throw if predicate is truthy', function () {
|
||||||
const fn = () => assert('foo', () => 'bar')
|
const fn = () => assert('foo', () => 'bar')
|
||||||
expect(fn).to.not.throw()
|
expect(fn).not.toThrow()
|
||||||
})
|
})
|
||||||
it('should not throw if predicate is truthy', function () {
|
it('should not throw if predicate is truthy', function () {
|
||||||
const fn = () => assert('', () => 'bar')
|
const fn = () => assert('', () => 'bar')
|
||||||
expect(fn).to.throw(/bar/)
|
expect(fn).toThrow(/bar/)
|
||||||
})
|
})
|
||||||
it('should populate default message', function () {
|
it('should populate default message', function () {
|
||||||
const fn = () => assert(false)
|
const fn = () => assert(false)
|
||||||
expect(fn).to.throw(/expect false to be true/)
|
expect(fn).toThrow(/expect false to be true/)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,8 +1,4 @@
|
|||||||
import { toPromise, toValueSync } from '../../../src/util/async'
|
import { toPromise, toValueSync } from './async'
|
||||||
import { expect, use } from 'chai'
|
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
|
|
||||||
use(chaiAsPromised)
|
|
||||||
|
|
||||||
describe('utils/async', () => {
|
describe('utils/async', () => {
|
||||||
describe('#toPromise()', function () {
|
describe('#toPromise()', function () {
|
||||||
@@ -11,21 +7,21 @@ describe('utils/async', () => {
|
|||||||
return 'foo'
|
return 'foo'
|
||||||
}
|
}
|
||||||
const result = await toPromise(foo())
|
const result = await toPromise(foo())
|
||||||
expect(result).to.equal('foo')
|
expect(result).toBe('foo')
|
||||||
})
|
})
|
||||||
it('should support iterable with single return statement', async () => {
|
it('should support iterable with single return statement', async () => {
|
||||||
function * foo () {
|
function * foo () {
|
||||||
return 'foo'
|
return 'foo'
|
||||||
}
|
}
|
||||||
const result = await toPromise(foo())
|
const result = await toPromise(foo())
|
||||||
expect(result).to.equal('foo')
|
expect(result).toBe('foo')
|
||||||
})
|
})
|
||||||
it('should support promise', async () => {
|
it('should support promise', async () => {
|
||||||
function foo () {
|
function foo () {
|
||||||
return Promise.resolve('foo')
|
return Promise.resolve('foo')
|
||||||
}
|
}
|
||||||
const result = await toPromise(foo())
|
const result = await toPromise(foo())
|
||||||
expect(result).to.equal('foo')
|
expect(result).toBe('foo')
|
||||||
})
|
})
|
||||||
it('should resolve dependency', async () => {
|
it('should resolve dependency', async () => {
|
||||||
function * foo (): Generator<Generator<string>> {
|
function * foo (): Generator<Generator<string>> {
|
||||||
@@ -35,14 +31,14 @@ describe('utils/async', () => {
|
|||||||
return 'bar'
|
return 'bar'
|
||||||
}
|
}
|
||||||
const result = await toPromise(foo())
|
const result = await toPromise(foo())
|
||||||
expect(result).to.equal('bar')
|
expect(result).toBe('bar')
|
||||||
})
|
})
|
||||||
it('should support promise dependency', async () => {
|
it('should support promise dependency', async () => {
|
||||||
function * foo (): Generator<Promise<string>> {
|
function * foo (): Generator<Promise<string>> {
|
||||||
return yield Promise.resolve('foo')
|
return yield Promise.resolve('foo')
|
||||||
}
|
}
|
||||||
const result = await toPromise(foo())
|
const result = await toPromise(foo())
|
||||||
expect(result).to.equal('foo')
|
expect(result).toBe('foo')
|
||||||
})
|
})
|
||||||
it('should reject Promise if dependency throws syncly', done => {
|
it('should reject Promise if dependency throws syncly', done => {
|
||||||
function * foo (): Generator<Generator<never>> {
|
function * foo (): Generator<Generator<never>> {
|
||||||
@@ -52,7 +48,7 @@ describe('utils/async', () => {
|
|||||||
throw new Error('bar')
|
throw new Error('bar')
|
||||||
}
|
}
|
||||||
toPromise(foo()).catch(err => {
|
toPromise(foo()).catch(err => {
|
||||||
expect(err.message).to.equal('bar')
|
expect(err.message).toBe('bar')
|
||||||
done()
|
done()
|
||||||
return 0 as any
|
return 0 as any
|
||||||
})
|
})
|
||||||
@@ -72,7 +68,7 @@ describe('utils/async', () => {
|
|||||||
throw new Error('bar')
|
throw new Error('bar')
|
||||||
}
|
}
|
||||||
const ret = await toPromise(foo())
|
const ret = await toPromise(foo())
|
||||||
expect(ret).to.equal('barfoo')
|
expect(ret).toBe('barfoo')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('#toValueSync()', function () {
|
describe('#toValueSync()', function () {
|
||||||
@@ -83,7 +79,7 @@ describe('utils/async', () => {
|
|||||||
function * bar (): Generator<never> {
|
function * bar (): Generator<never> {
|
||||||
throw new Error('bar')
|
throw new Error('bar')
|
||||||
}
|
}
|
||||||
expect(() => toValueSync(foo())).to.throw('bar')
|
expect(() => toValueSync(foo())).toThrow('bar')
|
||||||
})
|
})
|
||||||
it('should resume yield after catch', () => {
|
it('should resume yield after catch', () => {
|
||||||
function * foo (): Generator<unknown, never, never> {
|
function * foo (): Generator<unknown, never, never> {
|
||||||
@@ -95,7 +91,7 @@ describe('utils/async', () => {
|
|||||||
function * bar (): Generator<never> {
|
function * bar (): Generator<never> {
|
||||||
throw new Error('bar')
|
throw new Error('bar')
|
||||||
}
|
}
|
||||||
expect(toValueSync(foo())).to.equal('foo')
|
expect(toValueSync(foo())).toBe('foo')
|
||||||
})
|
})
|
||||||
it('should resume return after catch', () => {
|
it('should resume return after catch', () => {
|
||||||
function * foo (): Generator<Generator<never>, string> {
|
function * foo (): Generator<Generator<never>, string> {
|
||||||
@@ -107,10 +103,10 @@ describe('utils/async', () => {
|
|||||||
function * bar (): Generator<never> {
|
function * bar (): Generator<never> {
|
||||||
throw new Error('bar')
|
throw new Error('bar')
|
||||||
}
|
}
|
||||||
expect(toValueSync(foo())).to.equal('foo')
|
expect(toValueSync(foo())).toBe('foo')
|
||||||
})
|
})
|
||||||
it('should return non iterator value as it is', () => {
|
it('should return non iterator value as it is', () => {
|
||||||
expect(toValueSync('foo')).to.equal('foo')
|
expect(toValueSync('foo')).toBe('foo')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
import * as chai from 'chai'
|
import { strftime as t } from './strftime'
|
||||||
import { strftime as t } from '../../../src/util/strftime'
|
import { DateWithTimezone } from '../../test/stub/date-with-timezone'
|
||||||
import { DateWithTimezone } from '../../stub/date-with-timezone'
|
|
||||||
const expect = chai.expect
|
|
||||||
|
|
||||||
describe('util/strftime', function () {
|
describe('util/strftime', function () {
|
||||||
const now = new Date('2016-01-04 13:15:23')
|
const now = new Date('2016-01-04 13:15:23')
|
||||||
@@ -9,112 +7,112 @@ describe('util/strftime', function () {
|
|||||||
|
|
||||||
describe('Date (Year, Month, Day)', () => {
|
describe('Date (Year, Month, Day)', () => {
|
||||||
it('should format %C as century', function () {
|
it('should format %C as century', function () {
|
||||||
expect(t(now, '%C')).to.equal('20')
|
expect(t(now, '%C')).toBe('20')
|
||||||
})
|
})
|
||||||
it('should format %B as month name', function () {
|
it('should format %B as month name', function () {
|
||||||
expect(t(now, '%B')).to.equal('January')
|
expect(t(now, '%B')).toBe('January')
|
||||||
})
|
})
|
||||||
it('should format %e as space padded date', function () {
|
it('should format %e as space padded date', function () {
|
||||||
expect(t(now, '%e')).to.equal(' 4')
|
expect(t(now, '%e')).toBe(' 4')
|
||||||
})
|
})
|
||||||
it('should format %y as 2-digit year', function () {
|
it('should format %y as 2-digit year', function () {
|
||||||
expect(t(now, '%y')).to.equal('16')
|
expect(t(now, '%y')).toBe('16')
|
||||||
})
|
})
|
||||||
describe('%j', function () {
|
describe('%j', function () {
|
||||||
it('should format %j as day of year', function () {
|
it('should format %j as day of year', function () {
|
||||||
expect(t(then, '%j')).to.equal('066')
|
expect(t(then, '%j')).toBe('066')
|
||||||
})
|
})
|
||||||
it('should take count of leap years', function () {
|
it('should take count of leap years', function () {
|
||||||
const date = new Date('2001 03 01')
|
const date = new Date('2001 03 01')
|
||||||
expect(t(date, '%j')).to.equal('060')
|
expect(t(date, '%j')).toBe('060')
|
||||||
})
|
})
|
||||||
it('should take count of leap years', function () {
|
it('should take count of leap years', function () {
|
||||||
const date = new Date('2000 03 01')
|
const date = new Date('2000 03 01')
|
||||||
expect(t(date, '%j')).to.equal('061')
|
expect(t(date, '%j')).toBe('061')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
it('should format %q as date suffix', function () {
|
it('should format %q as date suffix', function () {
|
||||||
const st = new Date('2016-03-01 03:05:03')
|
const st = new Date('2016-03-01 03:05:03')
|
||||||
const nd = new Date('2016-03-02 03:05:03')
|
const nd = new Date('2016-03-02 03:05:03')
|
||||||
const rd = new Date('2016-03-03 03:05:03')
|
const rd = new Date('2016-03-03 03:05:03')
|
||||||
expect(t(st, '%q')).to.equal('st')
|
expect(t(st, '%q')).toBe('st')
|
||||||
expect(t(nd, '%q')).to.equal('nd')
|
expect(t(nd, '%q')).toBe('nd')
|
||||||
expect(t(rd, '%q')).to.equal('rd')
|
expect(t(rd, '%q')).toBe('rd')
|
||||||
expect(t(now, '%q')).to.equal('th')
|
expect(t(now, '%q')).toBe('th')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('Time (Hour, Minute, Second, Subsecond)', function () {
|
describe('Time (Hour, Minute, Second, Subsecond)', function () {
|
||||||
it('should format %I as 0 padded hour12', function () {
|
it('should format %I as 0 padded hour12', function () {
|
||||||
expect(t(now, '%I')).to.equal('01')
|
expect(t(now, '%I')).toBe('01')
|
||||||
})
|
})
|
||||||
it('should format %I as 12 for 00:00', function () {
|
it('should format %I as 12 for 00:00', function () {
|
||||||
const date = new Date('2016-01-01 00:00:00')
|
const date = new Date('2016-01-01 00:00:00')
|
||||||
expect(t(date, '%I')).to.equal('12')
|
expect(t(date, '%I')).toBe('12')
|
||||||
})
|
})
|
||||||
it('should format %k as space padded hour', function () {
|
it('should format %k as space padded hour', function () {
|
||||||
expect(t(then, '%k')).to.equal(' 3')
|
expect(t(then, '%k')).toBe(' 3')
|
||||||
})
|
})
|
||||||
it('should format %l as space padded hour12', function () {
|
it('should format %l as space padded hour12', function () {
|
||||||
expect(t(now, '%l')).to.equal(' 1')
|
expect(t(now, '%l')).toBe(' 1')
|
||||||
})
|
})
|
||||||
it('should format %l as 12 for 00:00', function () {
|
it('should format %l as 12 for 00:00', function () {
|
||||||
const date = new Date('2016-01-01 00:00:00')
|
const date = new Date('2016-01-01 00:00:00')
|
||||||
expect(t(date, '%l')).to.equal('12')
|
expect(t(date, '%l')).toBe('12')
|
||||||
})
|
})
|
||||||
it('should format %L as 0 padded millisecond', function () {
|
it('should format %L as 0 padded millisecond', function () {
|
||||||
expect(t(then, '%L')).to.equal('000')
|
expect(t(then, '%L')).toBe('000')
|
||||||
})
|
})
|
||||||
it('should format %N as fractional seconds digits', function () {
|
it('should format %N as fractional seconds digits', function () {
|
||||||
const time = new Date('2019-12-15 01:21:00.129')
|
const time = new Date('2019-12-15 01:21:00.129')
|
||||||
expect(t(time, '%N')).to.equal('129000000')
|
expect(t(time, '%N')).toBe('129000000')
|
||||||
expect(t(time, '%2N')).to.equal('12')
|
expect(t(time, '%2N')).toBe('12')
|
||||||
expect(t(time, '%10N')).to.equal('1290000000')
|
expect(t(time, '%10N')).toBe('1290000000')
|
||||||
expect(t(time, '%0N')).to.equal('129000000')
|
expect(t(time, '%0N')).toBe('129000000')
|
||||||
})
|
})
|
||||||
it('should format %p as upper cased am/pm', function () {
|
it('should format %p as upper cased am/pm', function () {
|
||||||
expect(t(now, '%p')).to.equal('PM')
|
expect(t(now, '%p')).toBe('PM')
|
||||||
expect(t(then, '%p')).to.equal('AM')
|
expect(t(then, '%p')).toBe('AM')
|
||||||
})
|
})
|
||||||
it('should format %P as lower cased am/pm', function () {
|
it('should format %P as lower cased am/pm', function () {
|
||||||
expect(t(now, '%P')).to.equal('pm')
|
expect(t(now, '%P')).toBe('pm')
|
||||||
expect(t(now, '%^8P')).to.equal(' PM')
|
expect(t(now, '%^8P')).toBe(' PM')
|
||||||
expect(t(then, '%P')).to.equal('am')
|
expect(t(then, '%P')).toBe('am')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('Weekday', function () {
|
describe('Weekday', function () {
|
||||||
it('should format %A as Monday', function () {
|
it('should format %A as Monday', function () {
|
||||||
expect(t(now, '%A')).to.equal('Monday')
|
expect(t(now, '%A')).toBe('Monday')
|
||||||
expect(t(now, '%^A')).to.equal('MONDAY')
|
expect(t(now, '%^A')).toBe('MONDAY')
|
||||||
expect(t(now, '%#A')).to.equal('MONDAY')
|
expect(t(now, '%#A')).toBe('MONDAY')
|
||||||
})
|
})
|
||||||
it('should format %a as Mon', function () {
|
it('should format %a as Mon', function () {
|
||||||
expect(t(now, '%a')).to.equal('Mon')
|
expect(t(now, '%a')).toBe('Mon')
|
||||||
expect(t(now, '%^a')).to.equal('MON')
|
expect(t(now, '%^a')).toBe('MON')
|
||||||
})
|
})
|
||||||
it('should format %u as day of week(1-7)', function () {
|
it('should format %u as day of week(1-7)', function () {
|
||||||
expect(t(now, '%u')).to.be.equal('1')
|
expect(t(now, '%u')).toBe('1')
|
||||||
expect(t(then, '%u')).to.be.equal('7')
|
expect(t(then, '%u')).toBe('7')
|
||||||
})
|
})
|
||||||
it('should format %w as day of week(0-7)', function () {
|
it('should format %w as day of week(0-7)', function () {
|
||||||
expect(t(now, '%w')).to.be.equal('1')
|
expect(t(now, '%w')).toBe('1')
|
||||||
expect(t(then, '%w')).to.be.equal('0')
|
expect(t(then, '%w')).toBe('0')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('Seconds since the Unix Epoch', () => {
|
describe('Seconds since the Unix Epoch', () => {
|
||||||
it('should format %s as UNIX seconds', function () {
|
it('should format %s as UNIX seconds', function () {
|
||||||
expect(t(now, '%s')).to.be.match(/\d+/)
|
expect(t(now, '%s')).toMatch(/\d+/)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('Week number', () => {
|
describe('Week number', () => {
|
||||||
it('should format %U as week of year, starts with 0', function () {
|
it('should format %U as week of year, starts with 0', function () {
|
||||||
expect(t(now, '%U')).to.equal('01')
|
expect(t(now, '%U')).toBe('01')
|
||||||
})
|
})
|
||||||
it('should format %W as week of year, starts with 1', function () {
|
it('should format %W as week of year, starts with 1', function () {
|
||||||
expect(t(now, '%W')).to.be.equal('01')
|
expect(t(now, '%W')).toBe('01')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -122,98 +120,98 @@ describe('util/strftime', function () {
|
|||||||
it('should format %z as time zone', function () {
|
it('should format %z as time zone', function () {
|
||||||
// suppose we're in +8:00
|
// suppose we're in +8:00
|
||||||
const now = new DateWithTimezone('2016-01-04 13:15:23', -480)
|
const now = new DateWithTimezone('2016-01-04 13:15:23', -480)
|
||||||
expect(t(now, '%z')).to.equal('+0800')
|
expect(t(now, '%z')).toBe('+0800')
|
||||||
})
|
})
|
||||||
it('should format %z as negative time zone', function () {
|
it('should format %z as negative time zone', function () {
|
||||||
// suppose we're in -8:00
|
// suppose we're in -8:00
|
||||||
const date = new DateWithTimezone('2016-01-04T13:15:23.000Z', 480)
|
const date = new DateWithTimezone('2016-01-04T13:15:23.000Z', 480)
|
||||||
expect(t(date, '%z')).to.equal('-0800')
|
expect(t(date, '%z')).toBe('-0800')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('combination', () => {
|
describe('combination', () => {
|
||||||
it('should format %x as local date string', function () {
|
it('should format %x as local date string', function () {
|
||||||
expect(t(now, '%x')).to.equal(now.toLocaleDateString())
|
expect(t(now, '%x')).toBe(now.toLocaleDateString())
|
||||||
})
|
})
|
||||||
it('should format %X as local time string', function () {
|
it('should format %X as local time string', function () {
|
||||||
expect(t(now, '%X')).to.equal(now.toLocaleTimeString())
|
expect(t(now, '%X')).toBe(now.toLocaleTimeString())
|
||||||
})
|
})
|
||||||
it('should format detailed datetime', function () {
|
it('should format detailed datetime', function () {
|
||||||
expect(t(now, '%Y-%m-%d %H:%M:%S')).to.equal('2016-01-04 13:15:23')
|
expect(t(now, '%Y-%m-%d %H:%M:%S')).toBe('2016-01-04 13:15:23')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should format %c as local string', function () {
|
it('should format %c as local string', function () {
|
||||||
expect(t(now, '%c')).to.equal(now.toLocaleString())
|
expect(t(now, '%c')).toBe(now.toLocaleString())
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('literal strings', () => {
|
describe('literal strings', () => {
|
||||||
it('should escape %% as %', function () {
|
it('should escape %% as %', function () {
|
||||||
expect(t(now, '%%')).to.equal('%')
|
expect(t(now, '%%')).toBe('%')
|
||||||
})
|
})
|
||||||
it('should escape %n as \\n', function () {
|
it('should escape %n as \\n', function () {
|
||||||
expect(t(now, '%n')).to.equal('\n')
|
expect(t(now, '%n')).toBe('\n')
|
||||||
})
|
})
|
||||||
it('should escape %t as \\t', function () {
|
it('should escape %t as \\t', function () {
|
||||||
expect(t(now, '%t')).to.equal('\t')
|
expect(t(now, '%t')).toBe('\t')
|
||||||
})
|
})
|
||||||
it('should retain un-recognized formaters', function () {
|
it('should retain un-recognized formaters', function () {
|
||||||
expect(t(now, '%o')).to.equal('%o')
|
expect(t(now, '%o')).toBe('%o')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('width field', () => {
|
describe('width field', () => {
|
||||||
it('should support width field', () => {
|
it('should support width field', () => {
|
||||||
expect(t(now, '%8Y')).to.equal('00002016')
|
expect(t(now, '%8Y')).toBe('00002016')
|
||||||
})
|
})
|
||||||
it('should ignore invalid width', () => {
|
it('should ignore invalid width', () => {
|
||||||
expect(t(then, '%1Y')).to.equal('2016')
|
expect(t(then, '%1Y')).toBe('2016')
|
||||||
expect(t(then, '%1H')).to.equal('3')
|
expect(t(then, '%1H')).toBe('3')
|
||||||
})
|
})
|
||||||
it('should have higher priority than H', () => {
|
it('should have higher priority than H', () => {
|
||||||
expect(t(then, '%0H')).to.equal('03')
|
expect(t(then, '%0H')).toBe('03')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('modifier field', () => {
|
describe('modifier field', () => {
|
||||||
it('should ignore E modifier', () => {
|
it('should ignore E modifier', () => {
|
||||||
expect(t(now, '%EY')).to.equal('2016')
|
expect(t(now, '%EY')).toBe('2016')
|
||||||
})
|
})
|
||||||
it('should ignore O modifier', () => {
|
it('should ignore O modifier', () => {
|
||||||
expect(t(now, '%OY')).to.equal('2016')
|
expect(t(now, '%OY')).toBe('2016')
|
||||||
})
|
})
|
||||||
it('should support modifier with width field', () => {
|
it('should support modifier with width field', () => {
|
||||||
expect(t(now, '%8EY')).to.equal('00002016')
|
expect(t(now, '%8EY')).toBe('00002016')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('flags field', () => {
|
describe('flags field', () => {
|
||||||
it('should support - flag', () => {
|
it('should support - flag', () => {
|
||||||
expect(t(now, '%-m')).to.equal('1')
|
expect(t(now, '%-m')).toBe('1')
|
||||||
})
|
})
|
||||||
it('should support _ flag', () => {
|
it('should support _ flag', () => {
|
||||||
expect(t(now, '%_m')).to.equal(' 1')
|
expect(t(now, '%_m')).toBe(' 1')
|
||||||
})
|
})
|
||||||
it('should support 0 flag', () => {
|
it('should support 0 flag', () => {
|
||||||
expect(t(now, '%0m')).to.equal('01')
|
expect(t(now, '%0m')).toBe('01')
|
||||||
})
|
})
|
||||||
it('should support ^ flag', () => {
|
it('should support ^ flag', () => {
|
||||||
expect(t(now, '%^B')).to.equal('JANUARY')
|
expect(t(now, '%^B')).toBe('JANUARY')
|
||||||
})
|
})
|
||||||
it('should respect to specific conversion', () => {
|
it('should respect to specific conversion', () => {
|
||||||
expect(t(now, '%^P')).to.equal('PM')
|
expect(t(now, '%^P')).toBe('PM')
|
||||||
expect(t(now, '%P')).to.equal('pm')
|
expect(t(now, '%P')).toBe('pm')
|
||||||
})
|
})
|
||||||
it('should support # flag', () => {
|
it('should support # flag', () => {
|
||||||
expect(t(now, '%#B')).to.equal('JANUARY')
|
expect(t(now, '%#B')).toBe('JANUARY')
|
||||||
expect(t(now, '%#P')).to.equal('PM')
|
expect(t(now, '%#P')).toBe('PM')
|
||||||
})
|
})
|
||||||
it('should support : flag', () => {
|
it('should support : flag', () => {
|
||||||
// suppose we're in +8:00
|
// suppose we're in +8:00
|
||||||
const date = new DateWithTimezone('2016-01-04T13:15:23.000Z', -480)
|
const date = new DateWithTimezone('2016-01-04T13:15:23.000Z', -480)
|
||||||
expect(t(date, '%:z')).to.equal('+08:00')
|
expect(t(date, '%:z')).toBe('+08:00')
|
||||||
expect(t(date, '%z')).to.equal('+0800')
|
expect(t(date, '%z')).toBe('+0800')
|
||||||
})
|
})
|
||||||
it('should support multiple flags', () => {
|
it('should support multiple flags', () => {
|
||||||
expect(t(now, '%^08P')).to.equal('000000PM')
|
expect(t(now, '%^08P')).toBe('000000PM')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,38 +1,37 @@
|
|||||||
import { TimezoneDate } from '../../../src/util/timezone-date'
|
import { TimezoneDate } from './timezone-date'
|
||||||
import { expect } from 'chai'
|
|
||||||
|
|
||||||
describe('TimezoneDate', () => {
|
describe('TimezoneDate', () => {
|
||||||
it('should respect timezone set to 00:00', () => {
|
it('should respect timezone set to 00:00', () => {
|
||||||
const date = new TimezoneDate('2021-10-06T14:26:00.000+08:00', 0)
|
const date = new TimezoneDate('2021-10-06T14:26:00.000+08:00', 0)
|
||||||
expect(date.getTimezoneOffset()).to.equal(0)
|
expect(date.getTimezoneOffset()).toBe(0)
|
||||||
expect(date.getHours()).to.equal(6)
|
expect(date.getHours()).toBe(6)
|
||||||
expect(date.getMinutes()).to.equal(26)
|
expect(date.getMinutes()).toBe(26)
|
||||||
})
|
})
|
||||||
it('should respect timezone set to -06:00', () => {
|
it('should respect timezone set to -06:00', () => {
|
||||||
const date = new TimezoneDate('2021-10-06T14:26:00.000+08:00', -360)
|
const date = new TimezoneDate('2021-10-06T14:26:00.000+08:00', -360)
|
||||||
expect(date.getTimezoneOffset()).to.equal(-360)
|
expect(date.getTimezoneOffset()).toBe(-360)
|
||||||
expect(date.getMinutes()).to.equal(26)
|
expect(date.getMinutes()).toBe(26)
|
||||||
})
|
})
|
||||||
it('should support Date as argument', () => {
|
it('should support Date as argument', () => {
|
||||||
const date = new TimezoneDate(new Date('2021-10-06T14:26:00.000+08:00'), 0)
|
const date = new TimezoneDate(new Date('2021-10-06T14:26:00.000+08:00'), 0)
|
||||||
expect(date.getHours()).to.equal(6)
|
expect(date.getHours()).toBe(6)
|
||||||
})
|
})
|
||||||
it('should support .getMilliseconds()', () => {
|
it('should support .getMilliseconds()', () => {
|
||||||
const date = new TimezoneDate('2021-10-06T14:26:00.001+00:00', 0)
|
const date = new TimezoneDate('2021-10-06T14:26:00.001+00:00', 0)
|
||||||
expect(date.getMilliseconds()).to.equal(1)
|
expect(date.getMilliseconds()).toBe(1)
|
||||||
})
|
})
|
||||||
it('should support .getDay()', () => {
|
it('should support .getDay()', () => {
|
||||||
const date = new TimezoneDate('2021-12-07T00:00:00.001+08:00', -480)
|
const date = new TimezoneDate('2021-12-07T00:00:00.001+08:00', -480)
|
||||||
expect(date.getDay()).to.equal(2)
|
expect(date.getDay()).toBe(2)
|
||||||
})
|
})
|
||||||
it('should support .toLocaleTimeString()', () => {
|
it('should support .toLocaleTimeString()', () => {
|
||||||
const date = new TimezoneDate('2021-10-06T00:00:00.001+00:00', -480)
|
const date = new TimezoneDate('2021-10-06T00:00:00.001+00:00', -480)
|
||||||
expect(date.toLocaleTimeString('en-US')).to.equal('8:00:00 AM')
|
expect(date.toLocaleTimeString('en-US')).toBe('8:00:00 AM')
|
||||||
expect(() => date.toLocaleDateString()).to.not.throw()
|
expect(() => date.toLocaleDateString()).not.toThrow()
|
||||||
})
|
})
|
||||||
it('should support .toLocaleDateString()', () => {
|
it('should support .toLocaleDateString()', () => {
|
||||||
const date = new TimezoneDate('2021-10-06T22:00:00.001+00:00', -480)
|
const date = new TimezoneDate('2021-10-06T22:00:00.001+00:00', -480)
|
||||||
expect(date.toLocaleDateString('en-US')).to.equal('10/7/2021')
|
expect(date.toLocaleDateString('en-US')).toBe('10/7/2021')
|
||||||
expect(() => date.toLocaleDateString()).to.not.throw()
|
expect(() => date.toLocaleDateString()).not.toThrow()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,128 +1,122 @@
|
|||||||
import * as chai from 'chai'
|
import * as _ from './underscore'
|
||||||
import * as sinonChai from 'sinon-chai'
|
|
||||||
import * as sinon from 'sinon'
|
|
||||||
import * as _ from '../../../src/util/underscore'
|
|
||||||
|
|
||||||
const expect = chai.expect
|
|
||||||
chai.use(sinonChai)
|
|
||||||
|
|
||||||
describe('util/underscore', function () {
|
describe('util/underscore', function () {
|
||||||
describe('.isString()', function () {
|
describe('.isString()', function () {
|
||||||
it('should return true for literal string', function () {
|
it('should return true for literal string', function () {
|
||||||
expect(_.isString('foo')).to.be.true
|
expect(_.isString('foo')).toBeTruthy()
|
||||||
})
|
})
|
||||||
it('should return true String instance', function () {
|
it('should return true String instance', function () {
|
||||||
expect(_.isString(String('foo'))).to.be.true
|
expect(_.isString(String('foo'))).toBeTruthy()
|
||||||
})
|
})
|
||||||
it('should return false for 123 ', function () {
|
it('should return false for 123 ', function () {
|
||||||
expect(_.isString(123)).to.be.false
|
expect(_.isString(123)).toBeFalsy()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('.isNumber()', function () {
|
describe('.isNumber()', function () {
|
||||||
it('should return false for "foo"', function () {
|
it('should return false for "foo"', function () {
|
||||||
expect(_.isNumber('foo')).to.be.false
|
expect(_.isNumber('foo')).toBeFalsy()
|
||||||
})
|
})
|
||||||
it('should return true for 0', function () {
|
it('should return true for 0', function () {
|
||||||
expect(_.isNumber(0)).to.be.true
|
expect(_.isNumber(0)).toBeTruthy()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('.stringify()', function () {
|
describe('.stringify()', function () {
|
||||||
it('should return "" for null', function () {
|
it('should return "" for null', function () {
|
||||||
expect(_.stringify(null)).to.equal('')
|
expect(_.stringify(null)).toBe('')
|
||||||
})
|
})
|
||||||
it('should return "" for undefined', function () {
|
it('should return "" for undefined', function () {
|
||||||
expect(_.stringify(undefined)).to.equal('')
|
expect(_.stringify(undefined)).toBe('')
|
||||||
})
|
})
|
||||||
it('should return regex string for RegExp', function () {
|
it('should return regex string for RegExp', function () {
|
||||||
const reg = /foo/g
|
const reg = /foo/g
|
||||||
expect(_.stringify(reg)).to.equal('/foo/g')
|
expect(_.stringify(reg)).toBe('/foo/g')
|
||||||
})
|
})
|
||||||
it('should return locale string for date', function () {
|
it('should return locale string for date', function () {
|
||||||
const date = new Date('2018-10-01T14:51:00.000Z')
|
const date = new Date('2018-10-01T14:51:00.000Z')
|
||||||
// Mon Oct 01 2018 22:51:00 GMT+0800 (CST)
|
// Mon Oct 01 2018 22:51:00 GMT+0800 (CST)
|
||||||
expect(_.stringify(date)).to.equal(date.toString())
|
expect(_.stringify(date)).toBe(date.toString())
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('.forOwn()', function () {
|
describe('.forOwn()', function () {
|
||||||
it('should iterate all properties', function () {
|
it('should iterate all properties', function () {
|
||||||
const spy = sinon.spy()
|
const spy = jest.fn()
|
||||||
const obj = {
|
const obj = {
|
||||||
foo: 'bar'
|
foo: 'bar'
|
||||||
}
|
}
|
||||||
_.forOwn(obj, spy)
|
_.forOwn(obj, spy)
|
||||||
expect(spy).to.have.been.calledWith('bar', 'foo', obj)
|
expect(spy).toHaveBeenCalledWith('bar', 'foo', obj)
|
||||||
})
|
})
|
||||||
it('should default to empty object', function () {
|
it('should default to empty object', function () {
|
||||||
const spy = sinon.spy()
|
const spy = jest.fn()
|
||||||
_.forOwn(undefined, spy)
|
_.forOwn(undefined, spy)
|
||||||
expect(spy).to.have.not.been.called
|
expect(spy).not.toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
it('should not iterate over properties on prototype', function () {
|
it('should not iterate over properties on prototype', function () {
|
||||||
const spy = sinon.spy()
|
const spy = jest.fn()
|
||||||
const obj = Object.create({
|
const obj = Object.create({
|
||||||
bar: 'foo'
|
bar: 'foo'
|
||||||
})
|
})
|
||||||
obj.foo = 'bar'
|
obj.foo = 'bar'
|
||||||
_.forOwn(obj, spy)
|
_.forOwn(obj, spy)
|
||||||
expect(spy).to.have.been.calledOnce
|
expect(spy).toHaveBeenCalledTimes(1)
|
||||||
expect(spy).to.have.been.calledWith('bar', 'foo', obj)
|
expect(spy).toHaveBeenCalledWith('bar', 'foo', obj)
|
||||||
})
|
})
|
||||||
it('should break when returned false', function () {
|
it('should break when returned false', function () {
|
||||||
const spy = sinon.stub().returns(false)
|
const spy = jest.fn(() => false)
|
||||||
_.forOwn({
|
_.forOwn({
|
||||||
'foo': 'foo',
|
'foo': 'foo',
|
||||||
'bar': 'foo'
|
'bar': 'foo'
|
||||||
}, spy)
|
}, spy)
|
||||||
expect(spy).to.have.been.calledOnce
|
expect(spy).toHaveBeenCalledTimes(1)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('.range()', function () {
|
describe('.range()', function () {
|
||||||
it('should return a range of integers', function () {
|
it('should return a range of integers', function () {
|
||||||
expect(_.range(3, 5)).to.deep.equal([3, 4])
|
expect(_.range(3, 5)).toEqual([3, 4])
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('.isObject()', function () {
|
describe('.isObject()', function () {
|
||||||
it('should return true for function', function () {
|
it('should return true for function', function () {
|
||||||
expect(_.isObject((x: any) => x)).to.be.true
|
expect(_.isObject((x: any) => x)).toBeTruthy()
|
||||||
})
|
})
|
||||||
it('should return true for plain object', function () {
|
it('should return true for plain object', function () {
|
||||||
expect(_.isObject({})).to.be.true
|
expect(_.isObject({})).toBeTruthy()
|
||||||
})
|
})
|
||||||
it('should return false for null', function () {
|
it('should return false for null', function () {
|
||||||
expect(_.isObject(null)).to.be.false
|
expect(_.isObject(null)).toBeFalsy()
|
||||||
})
|
})
|
||||||
it('should return false for number', function () {
|
it('should return false for number', function () {
|
||||||
expect(_.isObject(2)).to.be.false
|
expect(_.isObject(2)).toBeFalsy()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('.padEnd()', function () {
|
describe('.padEnd()', function () {
|
||||||
it('should default ch to " "', () => {
|
it('should default ch to " "', () => {
|
||||||
expect(_.padEnd('foo', 5)).to.equal('foo ')
|
expect(_.padEnd('foo', 5)).toBe('foo ')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('.changeCase()', function () {
|
describe('.changeCase()', function () {
|
||||||
it('should to upper case if there is one lowercase', () => {
|
it('should to upper case if there is one lowercase', () => {
|
||||||
expect(_.changeCase('fooA')).to.equal('FOOA')
|
expect(_.changeCase('fooA')).toBe('FOOA')
|
||||||
})
|
})
|
||||||
it('should to lower case if all upper case', () => {
|
it('should to lower case if all upper case', () => {
|
||||||
expect(_.changeCase('FOOA')).to.equal('fooa')
|
expect(_.changeCase('FOOA')).toBe('fooa')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('.caseInsensitiveCompare()', function () {
|
describe('.caseInsensitiveCompare()', function () {
|
||||||
it('should "foo" > "bar"', () => {
|
it('should "foo" > "bar"', () => {
|
||||||
expect(_.caseInsensitiveCompare('foo', 'bar')).to.equal(1)
|
expect(_.caseInsensitiveCompare('foo', 'bar')).toBe(1)
|
||||||
})
|
})
|
||||||
it('should "foo" < null', () => {
|
it('should "foo" < null', () => {
|
||||||
expect(_.caseInsensitiveCompare('foo', null)).to.equal(-1)
|
expect(_.caseInsensitiveCompare('foo', null)).toBe(-1)
|
||||||
})
|
})
|
||||||
it('should null > "foo"', () => {
|
it('should null > "foo"', () => {
|
||||||
expect(_.caseInsensitiveCompare(null, 'foo')).to.equal(1)
|
expect(_.caseInsensitiveCompare(null, 'foo')).toBe(1)
|
||||||
})
|
})
|
||||||
it('should -1 < 0', () => {
|
it('should -1 < 0', () => {
|
||||||
expect(_.caseInsensitiveCompare(-1, 0)).to.equal(-1)
|
expect(_.caseInsensitiveCompare(-1, 0)).toBe(-1)
|
||||||
})
|
})
|
||||||
it('should 1 > 0', () => {
|
it('should 1 > 0', () => {
|
||||||
expect(_.caseInsensitiveCompare(1, 0)).to.equal(1)
|
expect(_.caseInsensitiveCompare(1, 0)).toBe(1)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,9 +1,5 @@
|
|||||||
import { Liquid } from '../../src/liquid'
|
import { Liquid } from '../../src/liquid'
|
||||||
import { Drop } from '../../src/drop/drop'
|
import { Drop } from '../../src/drop/drop'
|
||||||
import { expect, use } from 'chai'
|
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
|
|
||||||
use(chaiAsPromised)
|
|
||||||
|
|
||||||
class SettingsDrop extends Drop {
|
class SettingsDrop extends Drop {
|
||||||
private foo = 'FOO'
|
private foo = 'FOO'
|
||||||
@@ -24,7 +20,7 @@ describe('drop', function () {
|
|||||||
it('should support liquidMethodMissing', async function () {
|
it('should support liquidMethodMissing', async function () {
|
||||||
const src = `{{settings.foo}},{{settings.bar}},{{settings.coo}}`
|
const src = `{{settings.foo}},{{settings.bar}},{{settings.coo}}`
|
||||||
const html = await engine.parseAndRender(src, { settings })
|
const html = await engine.parseAndRender(src, { settings })
|
||||||
return expect(html).to.equal('FOO,BAR,COO')
|
return expect(html).toBe('FOO,BAR,COO')
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('BlandDrop', function () {
|
describe('BlandDrop', function () {
|
||||||
@@ -35,7 +31,7 @@ describe('drop', function () {
|
|||||||
{% endunless %}`
|
{% endunless %}`
|
||||||
var ctx = { settings: { fpHeading: '' } }
|
var ctx = { settings: { fpHeading: '' } }
|
||||||
const html = await engine.parseAndRender(src, ctx)
|
const html = await engine.parseAndRender(src, ctx)
|
||||||
return expect(html).to.match(/^\s+$/)
|
return expect(html).toMatch(/^\s+$/)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
import { expect } from 'chai'
|
|
||||||
import { Liquid } from '../..'
|
import { Liquid } from '../..'
|
||||||
|
|
||||||
describe('#evalValueSync()', function () {
|
describe('#evalValueSync()', function () {
|
||||||
@@ -6,6 +5,6 @@ describe('#evalValueSync()', function () {
|
|||||||
beforeEach(() => { engine = new Liquid() })
|
beforeEach(() => { engine = new Liquid() })
|
||||||
|
|
||||||
it('should eval value syncly', async function () {
|
it('should eval value syncly', async function () {
|
||||||
return expect(engine.evalValueSync('true', { opts: {} } as any)).to.equal(true)
|
return expect(engine.evalValueSync('true', { opts: {} } as any)).toBe(true)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
import { expect } from 'chai'
|
|
||||||
import { Liquid } from '../..'
|
import { Liquid } from '../..'
|
||||||
|
|
||||||
describe('#evalValue()', function () {
|
describe('#evalValue()', function () {
|
||||||
@@ -7,16 +6,16 @@ describe('#evalValue()', function () {
|
|||||||
|
|
||||||
it('should support boolean', async function () {
|
it('should support boolean', async function () {
|
||||||
const val = await engine.evalValue('true')
|
const val = await engine.evalValue('true')
|
||||||
expect(val).to.equal(true)
|
expect(val).toBe(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support binary expression with Context', async function () {
|
it('should support binary expression with Context', async function () {
|
||||||
const val = await engine.evalValue('a > b', { a: 1, b: 2 })
|
const val = await engine.evalValue('a > b', { a: 1, b: 2 })
|
||||||
expect(val).to.equal(false)
|
expect(val).toBe(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should inherit Liquid options', async function () {
|
it('should inherit Liquid options', async function () {
|
||||||
const val = await engine.evalValue('foo')
|
const val = await engine.evalValue('foo')
|
||||||
expect(val).to.equal('FOO')
|
expect(val).toBe('FOO')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
import { expect } from 'chai'
|
|
||||||
import * as request from 'supertest'
|
import * as request from 'supertest'
|
||||||
import * as express from 'express'
|
import * as express from 'express'
|
||||||
import { resolve } from 'path'
|
import { resolve } from 'path'
|
||||||
@@ -47,8 +46,8 @@ describe('express()', function () {
|
|||||||
const ctx = {}
|
const ctx = {}
|
||||||
engine.express().call(view, file, ctx, function (err: any) {
|
engine.express().call(view, file, ctx, function (err: any) {
|
||||||
try {
|
try {
|
||||||
expect(err.code).to.equal('ENOENT')
|
expect(err.code).toBe('ENOENT')
|
||||||
expect(err.message).to.match(/Failed to lookup/)
|
expect(err.message).toMatch(/Failed to lookup/)
|
||||||
done()
|
done()
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
done(e)
|
done(e)
|
||||||
@@ -1,18 +1,11 @@
|
|||||||
import { TopLevelToken, TagToken, Tokenizer, Context, Liquid, Drop, toValueSync } from '../..'
|
import { TopLevelToken, TagToken, Tokenizer, Context, Liquid, Drop, toValueSync } from '../..'
|
||||||
import { expect, use } from 'chai'
|
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
import * as sinon from 'sinon'
|
|
||||||
import * as sinonChai from 'sinon-chai'
|
|
||||||
const LiquidUMD = require('../../dist/liquid.browser.umd.js').Liquid
|
const LiquidUMD = require('../../dist/liquid.browser.umd.js').Liquid
|
||||||
|
|
||||||
use(chaiAsPromised)
|
|
||||||
use(sinonChai)
|
|
||||||
|
|
||||||
describe('Issues', function () {
|
describe('Issues', function () {
|
||||||
it('#221 unicode blanks are not properly treated', async () => {
|
it('#221 unicode blanks are not properly treated', async () => {
|
||||||
const engine = new Liquid({ strictVariables: true, strictFilters: true })
|
const engine = new Liquid({ strictVariables: true, strictFilters: true })
|
||||||
const html = engine.parseAndRenderSync('{{huh | truncate: 11}}', { huh: 'fdsafdsafdsafdsaaaaa' })
|
const html = engine.parseAndRenderSync('{{huh | truncate: 11}}', { huh: 'fdsafdsafdsafdsaaaaa' })
|
||||||
expect(html).to.equal('fdsafdsa...')
|
expect(html).toBe('fdsafdsa...')
|
||||||
})
|
})
|
||||||
it('#252 "Not valid identifier" error for a quotes-containing identifier', async () => {
|
it('#252 "Not valid identifier" error for a quotes-containing identifier', async () => {
|
||||||
const template = `{% capture "form_classes" -%}
|
const template = `{% capture "form_classes" -%}
|
||||||
@@ -20,12 +13,12 @@ describe('Issues', function () {
|
|||||||
{%- endcapture %}{{form_classes}}`
|
{%- endcapture %}{{form_classes}}`
|
||||||
const engine = new Liquid()
|
const engine = new Liquid()
|
||||||
const html = await engine.parseAndRender(template)
|
const html = await engine.parseAndRender(template)
|
||||||
expect(html).to.equal('foo')
|
expect(html).toBe('foo')
|
||||||
})
|
})
|
||||||
it('#259 complex property access with braces is not supported', async () => {
|
it('#259 complex property access with braces is not supported', async () => {
|
||||||
const engine = new Liquid()
|
const engine = new Liquid()
|
||||||
const html = engine.parseAndRenderSync('{{ ["complex key"] }}', { 'complex key': 'foo' })
|
const html = engine.parseAndRenderSync('{{ ["complex key"] }}', { 'complex key': 'foo' })
|
||||||
expect(html).to.equal('foo')
|
expect(html).toBe('foo')
|
||||||
})
|
})
|
||||||
it('#243 Potential for ReDoS through string replace function', async () => {
|
it('#243 Potential for ReDoS through string replace function', async () => {
|
||||||
const engine = new Liquid()
|
const engine = new Liquid()
|
||||||
@@ -38,13 +31,13 @@ describe('Issues', function () {
|
|||||||
const html = engine.parseAndRenderSync(template, parameters)
|
const html = engine.parseAndRenderSync(template, parameters)
|
||||||
|
|
||||||
// should stringify the regexp rather than execute it
|
// should stringify the regexp rather than execute it
|
||||||
expect(html).to.equal(INPUT)
|
expect(html).toBe(INPUT)
|
||||||
})
|
})
|
||||||
it('#263 raw/endraw block not ignoring {% characters', () => {
|
it('#263 raw/endraw block not ignoring {% characters', () => {
|
||||||
const template = `{% raw %}This is a code snippet showing how {% breaks the raw block.{% endraw %}`
|
const template = `{% raw %}This is a code snippet showing how {% breaks the raw block.{% endraw %}`
|
||||||
const engine = new Liquid()
|
const engine = new Liquid()
|
||||||
const html = engine.parseAndRenderSync(template)
|
const html = engine.parseAndRenderSync(template)
|
||||||
expect(html).to.equal('This is a code snippet showing how {% breaks the raw block.')
|
expect(html).toBe('This is a code snippet showing how {% breaks the raw block.')
|
||||||
})
|
})
|
||||||
it('#268 elsif is not supported for unless', () => {
|
it('#268 elsif is not supported for unless', () => {
|
||||||
const template = `{%- unless condition1 -%}
|
const template = `{%- unless condition1 -%}
|
||||||
@@ -56,7 +49,7 @@ describe('Issues', function () {
|
|||||||
{% endunless %}`
|
{% endunless %}`
|
||||||
const engine = new Liquid()
|
const engine = new Liquid()
|
||||||
const html = engine.parseAndRenderSync(template, { condition1: true, condition2: true })
|
const html = engine.parseAndRenderSync(template, { condition1: true, condition2: true })
|
||||||
expect(html).to.equal('<div>Y</div>')
|
expect(html).toBe('<div>Y</div>')
|
||||||
})
|
})
|
||||||
it('#277 Passing liquid in FilterImpl', () => {
|
it('#277 Passing liquid in FilterImpl', () => {
|
||||||
const engine = new Liquid()
|
const engine = new Liquid()
|
||||||
@@ -67,12 +60,12 @@ describe('Issues', function () {
|
|||||||
`{{ subtemplate | render: "foo" }}`,
|
`{{ subtemplate | render: "foo" }}`,
|
||||||
{ subtemplate: encodeURIComponent('hello {{ name }}') }
|
{ subtemplate: encodeURIComponent('hello {{ name }}') }
|
||||||
)
|
)
|
||||||
expect(html).to.equal('hello foo')
|
expect(html).toBe('hello foo')
|
||||||
})
|
})
|
||||||
it('#288 Unexpected behavior when string literals contain }}', async () => {
|
it('#288 Unexpected behavior when string literals contain }}', async () => {
|
||||||
const engine = new Liquid()
|
const engine = new Liquid()
|
||||||
const html = await engine.parseAndRender(`{{ '{{' }}{{ '}}' }}`)
|
const html = await engine.parseAndRender(`{{ '{{' }}{{ '}}' }}`)
|
||||||
expect(html).to.equal('{{}}')
|
expect(html).toBe('{{}}')
|
||||||
})
|
})
|
||||||
it('#222 Support function calls', async () => {
|
it('#222 Support function calls', async () => {
|
||||||
const engine = new Liquid()
|
const engine = new Liquid()
|
||||||
@@ -80,7 +73,7 @@ describe('Issues', function () {
|
|||||||
`{{ obj.property }}`,
|
`{{ obj.property }}`,
|
||||||
{ obj: { property: () => 'BAR' } }
|
{ obj: { property: () => 'BAR' } }
|
||||||
)
|
)
|
||||||
expect(html).to.equal('BAR')
|
expect(html).toBe('BAR')
|
||||||
})
|
})
|
||||||
it('#313 lenientIf not working as expected in umd', async () => {
|
it('#313 lenientIf not working as expected in umd', async () => {
|
||||||
const engine = new LiquidUMD({
|
const engine = new LiquidUMD({
|
||||||
@@ -88,7 +81,7 @@ describe('Issues', function () {
|
|||||||
lenientIf: true
|
lenientIf: true
|
||||||
})
|
})
|
||||||
const html = await engine.parseAndRender(`{{ name | default: "default name" }}`)
|
const html = await engine.parseAndRender(`{{ name | default: "default name" }}`)
|
||||||
expect(html).to.equal('default name')
|
expect(html).toBe('default name')
|
||||||
})
|
})
|
||||||
it('#321 comparison for empty/nil', async () => {
|
it('#321 comparison for empty/nil', async () => {
|
||||||
const engine = new Liquid()
|
const engine = new Liquid()
|
||||||
@@ -96,30 +89,31 @@ describe('Issues', function () {
|
|||||||
'{% if empty == nil %}true{%else%}false{%endif%}' +
|
'{% if empty == nil %}true{%else%}false{%endif%}' +
|
||||||
'{% if nil == empty %}true{%else%}false{%endif%}'
|
'{% if nil == empty %}true{%else%}false{%endif%}'
|
||||||
)
|
)
|
||||||
expect(html).to.equal('falsefalse')
|
expect(html).toBe('falsefalse')
|
||||||
})
|
})
|
||||||
it('#320 newline_to_br filter should output <br /> instead of <br/>', async () => {
|
it('#320 newline_to_br filter should output <br /> instead of <br/>', async () => {
|
||||||
const engine = new Liquid()
|
const engine = new Liquid()
|
||||||
const html = await engine.parseAndRender(
|
const html = await engine.parseAndRender(
|
||||||
`{{ 'a \n b \n c' | newline_to_br | split: '<br />' }}`
|
`{{ 'a \n b \n c' | newline_to_br | split: '<br />' }}`
|
||||||
)
|
)
|
||||||
expect(html).to.equal('a \n b \n c')
|
expect(html).toBe('a \n b \n c')
|
||||||
})
|
})
|
||||||
it('#342 New lines in logical operator', async () => {
|
it('#342 New lines in logical operator', async () => {
|
||||||
const engine = new Liquid()
|
const engine = new Liquid()
|
||||||
const tpl = `{%\r\nif\r\ntrue\r\nor\r\nfalse\r\n%}\r\ntrue\r\n{%\r\nendif\r\n%}`
|
const tpl = `{%\r\nif\r\ntrue\r\nor\r\nfalse\r\n%}\r\ntrue\r\n{%\r\nendif\r\n%}`
|
||||||
const html = await engine.parseAndRender(tpl)
|
const html = await engine.parseAndRender(tpl)
|
||||||
expect(html).to.equal('\r\ntrue\r\n')
|
expect(html).toBe('\r\ntrue\r\n')
|
||||||
})
|
})
|
||||||
it('#401 Timezone Offset Issue', async () => {
|
it('#401 Timezone Offset Issue', async () => {
|
||||||
const engine = new Liquid({ timezoneOffset: -600 })
|
const engine = new Liquid({ timezoneOffset: -600 })
|
||||||
const tpl = engine.parse('{{ date | date: "%Y-%m-%d %H:%M %p %z" }}')
|
const tpl = engine.parse('{{ date | date: "%Y-%m-%d %H:%M %p %z" }}')
|
||||||
const html = await engine.render(tpl, { date: '2021-10-06T15:31:00+08:00' })
|
const html = await engine.render(tpl, { date: '2021-10-06T15:31:00+08:00' })
|
||||||
expect(html).to.equal('2021-10-06 17:31 PM +1000')
|
expect(html).toBe('2021-10-06 17:31 PM +1000')
|
||||||
})
|
})
|
||||||
it('#412 Pass root as it is to `resolve`', async () => {
|
it('#412 Pass root as it is to `resolve`', async () => {
|
||||||
const engine = new Liquid({
|
const engine = new Liquid({
|
||||||
root: '/tmp',
|
root: '/tmp',
|
||||||
|
relativeReference: false,
|
||||||
fs: {
|
fs: {
|
||||||
readFileSync: (file: string) => file,
|
readFileSync: (file: string) => file,
|
||||||
async readFile (file: string) { return 'foo' },
|
async readFile (file: string) { return 'foo' },
|
||||||
@@ -130,15 +124,16 @@ describe('Issues', function () {
|
|||||||
})
|
})
|
||||||
const tpl = engine.parse('{% include "foo.liquid" %}')
|
const tpl = engine.parse('{% include "foo.liquid" %}')
|
||||||
const html = await engine.renderSync(tpl)
|
const html = await engine.renderSync(tpl)
|
||||||
expect(html).to.equal('/tmp/foo.liquid')
|
expect(html).toBe('/tmp/foo.liquid')
|
||||||
})
|
})
|
||||||
it('#416 Templates imported by {% render %} not cached for concurrent async render', async () => {
|
it('#416 Templates imported by {% render %} not cached for concurrent async render', async () => {
|
||||||
const readFile = sinon.spy(() => Promise.resolve('HELLO'))
|
const readFile = jest.fn(() => Promise.resolve('HELLO'))
|
||||||
const exists = sinon.spy(() => 'HELLO')
|
const exists = jest.fn(() => 'HELLO')
|
||||||
const engine = new Liquid({
|
const engine = new Liquid({
|
||||||
cache: true,
|
cache: true,
|
||||||
extname: '.liquid',
|
extname: '.liquid',
|
||||||
root: '~',
|
root: '~',
|
||||||
|
relativeReference: false,
|
||||||
fs: {
|
fs: {
|
||||||
exists,
|
exists,
|
||||||
resolve: (root: string, file: string, ext: string) => root + '#' + file + ext,
|
resolve: (root: string, file: string, ext: string) => root + '#' + file + ext,
|
||||||
@@ -150,20 +145,21 @@ describe('Issues', function () {
|
|||||||
await Promise.all(Array(5).fill(0).map(
|
await Promise.all(Array(5).fill(0).map(
|
||||||
x => engine.parseAndRender("{% render 'template' %}")
|
x => engine.parseAndRender("{% render 'template' %}")
|
||||||
))
|
))
|
||||||
expect(exists).to.be.calledOnce
|
expect(exists).toHaveBeenCalledTimes(1)
|
||||||
expect(readFile).to.be.calledOnce
|
expect(readFile).toHaveBeenCalledTimes(1)
|
||||||
})
|
})
|
||||||
it('#431 Error when using Date timezoneOffset in 9.28.5', async () => {
|
it('#431 Error when using Date timezoneOffset in 9.28.5', () => {
|
||||||
const engine = new Liquid({
|
const engine = new Liquid({
|
||||||
timezoneOffset: 0,
|
timezoneOffset: 0,
|
||||||
preserveTimezones: true
|
preserveTimezones: true
|
||||||
})
|
})
|
||||||
const tpl = engine.parse('Welcome to {{ now | date: "%Y-%m-%d" }}!')
|
const tpl = engine.parse('Welcome to {{ now | date: "%Y-%m-%d" }}')
|
||||||
expect(engine.render(tpl, { now: new Date('2019/02/01') })).to.eventually.equal('Welcome to 2019-02-01')
|
return expect(engine.render(tpl, { now: new Date('2019-02-01T00:00:00.000Z') })).resolves.toBe('Welcome to 2019-02-01')
|
||||||
})
|
})
|
||||||
it('#433 Support Jekyll-like includes', async () => {
|
it('#433 Support Jekyll-like includes', async () => {
|
||||||
const engine = new Liquid({
|
const engine = new Liquid({
|
||||||
dynamicPartials: false,
|
dynamicPartials: false,
|
||||||
|
relativeReference: false,
|
||||||
root: '/tmp',
|
root: '/tmp',
|
||||||
fs: {
|
fs: {
|
||||||
readFileSync: (file: string) => file,
|
readFileSync: (file: string) => file,
|
||||||
@@ -175,7 +171,7 @@ describe('Issues', function () {
|
|||||||
})
|
})
|
||||||
const tpl = engine.parse('{% include prefix/{{ my_variable | append: "-bar" }}/suffix %}')
|
const tpl = engine.parse('{% include prefix/{{ my_variable | append: "-bar" }}/suffix %}')
|
||||||
const html = await engine.render(tpl, { my_variable: 'foo' })
|
const html = await engine.render(tpl, { my_variable: 'foo' })
|
||||||
expect(html).to.equal('CONTENT for /tmp/prefix/foo-bar/suffix')
|
expect(html).toBe('CONTENT for /tmp/prefix/foo-bar/suffix')
|
||||||
})
|
})
|
||||||
it('#428 Implement liquid/echo tags', () => {
|
it('#428 Implement liquid/echo tags', () => {
|
||||||
const template = `{%- liquid
|
const template = `{%- liquid
|
||||||
@@ -192,17 +188,17 @@ describe('Issues', function () {
|
|||||||
-%}`
|
-%}`
|
||||||
const engine = new Liquid()
|
const engine = new Liquid()
|
||||||
const html = engine.parseAndRenderSync(template, { array: [1, 2, 3] })
|
const html = engine.parseAndRenderSync(template, { array: [1, 2, 3] })
|
||||||
expect(html).to.equal('4#8#12#6')
|
expect(html).toBe('4#8#12#6')
|
||||||
})
|
})
|
||||||
it('#454 leaking JS prototype getter functions in evaluation', async () => {
|
it('#454 leaking JS prototype getter functions in evaluation', async () => {
|
||||||
const engine = new Liquid({ ownPropertyOnly: true })
|
const engine = new Liquid({ ownPropertyOnly: true })
|
||||||
const html = engine.parseAndRenderSync('{{foo | size}}-{{bar.coo}}', { foo: 'foo', bar: Object.create({ coo: 'COO' }) })
|
const html = engine.parseAndRenderSync('{{foo | size}}-{{bar.coo}}', { foo: 'foo', bar: Object.create({ coo: 'COO' }) })
|
||||||
expect(html).to.equal('3-')
|
expect(html).toBe('3-')
|
||||||
})
|
})
|
||||||
it('#465 Liquidjs divided_by not compatible with Ruby/Shopify Liquid', () => {
|
it('#465 Liquidjs divided_by not compatible with Ruby/Shopify Liquid', () => {
|
||||||
const engine = new Liquid({ ownPropertyOnly: true })
|
const engine = new Liquid({ ownPropertyOnly: true })
|
||||||
const html = engine.parseAndRenderSync('{{ 5 | divided_by: 3, true }}')
|
const html = engine.parseAndRenderSync('{{ 5 | divided_by: 3, true }}')
|
||||||
expect(html).to.equal('1')
|
expect(html).toBe('1')
|
||||||
})
|
})
|
||||||
it('#479 url_encode throws on undefined value', async () => {
|
it('#479 url_encode throws on undefined value', async () => {
|
||||||
const engine = new Liquid({
|
const engine = new Liquid({
|
||||||
@@ -210,7 +206,7 @@ describe('Issues', function () {
|
|||||||
})
|
})
|
||||||
const tpl = engine.parse('{{ v | url_encode }}')
|
const tpl = engine.parse('{{ v | url_encode }}')
|
||||||
const html = await engine.render(tpl, { v: undefined })
|
const html = await engine.render(tpl, { v: undefined })
|
||||||
expect(html).to.equal('')
|
expect(html).toBe('')
|
||||||
})
|
})
|
||||||
it('#481 filters that should not throw', async () => {
|
it('#481 filters that should not throw', async () => {
|
||||||
const engine = new Liquid()
|
const engine = new Liquid()
|
||||||
@@ -225,17 +221,17 @@ describe('Issues', function () {
|
|||||||
{{ foo | concat | json }}
|
{{ foo | concat | json }}
|
||||||
`)
|
`)
|
||||||
const html = await engine.render(tpl, { foo: undefined })
|
const html = await engine.render(tpl, { foo: undefined })
|
||||||
expect(html.trim()).to.equal('[]')
|
expect(html.trim()).toBe('[]')
|
||||||
})
|
})
|
||||||
it('#481 concat should always return an array', async () => {
|
it('#481 concat should always return an array', async () => {
|
||||||
const engine = new Liquid()
|
const engine = new Liquid()
|
||||||
const html = await engine.parseAndRender(`{{ foo | concat | json }}`)
|
const html = await engine.parseAndRender(`{{ foo | concat | json }}`)
|
||||||
expect(html).to.equal('[]')
|
expect(html).toBe('[]')
|
||||||
})
|
})
|
||||||
it('#486 Access array items from the right with negative indexes', async () => {
|
it('#486 Access array items from the right with negative indexes', async () => {
|
||||||
const engine = new Liquid()
|
const engine = new Liquid()
|
||||||
const html = await engine.parseAndRender(`{% assign a = "x,y,z" | split: ',' -%}{{ a[-1] }} {{ a[-3] }} {{ a[-8] }}`)
|
const html = await engine.parseAndRender(`{% assign a = "x,y,z" | split: ',' -%}{{ a[-1] }} {{ a[-3] }} {{ a[-8] }}`)
|
||||||
expect(html).to.equal('z x ')
|
expect(html).toBe('z x ')
|
||||||
})
|
})
|
||||||
it('#492 contains operator does not support Drop', async () => {
|
it('#492 contains operator does not support Drop', async () => {
|
||||||
class TemplateDrop extends Drop {
|
class TemplateDrop extends Drop {
|
||||||
@@ -244,44 +240,44 @@ describe('Issues', function () {
|
|||||||
const engine = new Liquid()
|
const engine = new Liquid()
|
||||||
const ctx = { template: new TemplateDrop() }
|
const ctx = { template: new TemplateDrop() }
|
||||||
const html = await engine.parseAndRender(`{% if template contains "product" %}contains{%endif%}`, ctx)
|
const html = await engine.parseAndRender(`{% if template contains "product" %}contains{%endif%}`, ctx)
|
||||||
expect(html).to.equal('contains')
|
expect(html).toBe('contains')
|
||||||
})
|
})
|
||||||
it('#513 should support large number of templates [async]', async () => {
|
it('#513 should support large number of templates [async]', async () => {
|
||||||
const engine = new Liquid()
|
const engine = new Liquid()
|
||||||
const html = await engine.parseAndRender(`{% for i in (1..10000) %}{{ i }}{% endfor %}`)
|
const html = await engine.parseAndRender(`{% for i in (1..10000) %}{{ i }}{% endfor %}`)
|
||||||
expect(html).to.have.lengthOf(38894)
|
expect(html).toHaveLength(38894)
|
||||||
})
|
})
|
||||||
it('#513 should support large number of templates [sync]', () => {
|
it('#513 should support large number of templates [sync]', () => {
|
||||||
const engine = new Liquid()
|
const engine = new Liquid()
|
||||||
const html = engine.parseAndRenderSync(`{% for i in (1..10000) %}{{ i }}{% endfor %}`)
|
const html = engine.parseAndRenderSync(`{% for i in (1..10000) %}{{ i }}{% endfor %}`)
|
||||||
expect(html).to.have.lengthOf(38894)
|
expect(html).toHaveLength(38894)
|
||||||
})
|
})
|
||||||
it('#519 should throw parse error for invalid assign expression', () => {
|
it('#519 should throw parse error for invalid assign expression', () => {
|
||||||
const engine = new Liquid()
|
const engine = new Liquid()
|
||||||
expect(() => engine.parse('{% assign headshot = https://testurl.com/not_enclosed_in_quotes.jpg %}')).to.throw(/unexpected token at ":/)
|
expect(() => engine.parse('{% assign headshot = https://testurl.com/not_enclosed_in_quotes.jpg %}')).toThrow(/unexpected token at ":/)
|
||||||
})
|
})
|
||||||
it('#527 export Liquid Expression', () => {
|
it('#527 export Liquid Expression', () => {
|
||||||
const tokenizer = new Tokenizer('a > b')
|
const tokenizer = new Tokenizer('a > b')
|
||||||
const expression = tokenizer.readExpression()
|
const expression = tokenizer.readExpression()
|
||||||
const result = toValueSync(expression.evaluate(new Context({ a: 1, b: 2 })))
|
const result = toValueSync(expression.evaluate(new Context({ a: 1, b: 2 })))
|
||||||
expect(result).to.equal(false)
|
expect(result).toBe(false)
|
||||||
})
|
})
|
||||||
it('#527 export Liquid Expression (evalValue)', async () => {
|
it('#527 export Liquid Expression (evalValue)', async () => {
|
||||||
const liquid = new Liquid()
|
const liquid = new Liquid()
|
||||||
const result = await liquid.evalValue('a > b', { a: 1, b: 2 })
|
const result = await liquid.evalValue('a > b', { a: 1, b: 2 })
|
||||||
expect(result).to.equal(false)
|
expect(result).toBe(false)
|
||||||
})
|
})
|
||||||
it('#527 export Liquid Expression (evalValueSync)', async () => {
|
it('#527 export Liquid Expression (evalValueSync)', async () => {
|
||||||
const liquid = new Liquid()
|
const liquid = new Liquid()
|
||||||
const result = liquid.evalValueSync('a > b', { a: 1, b: 2 })
|
const result = liquid.evalValueSync('a > b', { a: 1, b: 2 })
|
||||||
expect(result).to.equal(false)
|
expect(result).toBe(false)
|
||||||
})
|
})
|
||||||
it('#276 Promise support in expressions', async () => {
|
it('#276 Promise support in expressions', async () => {
|
||||||
const liquid = new Liquid()
|
const liquid = new Liquid()
|
||||||
const tpl = '{%if name == "alice" %}true{%endif%}'
|
const tpl = '{%if name == "alice" %}true{%endif%}'
|
||||||
const ctx = { name: Promise.resolve('alice') }
|
const ctx = { name: Promise.resolve('alice') }
|
||||||
const html = await liquid.parseAndRender(tpl, ctx)
|
const html = await liquid.parseAndRender(tpl, ctx)
|
||||||
expect(html).to.equal('true')
|
expect(html).toBe('true')
|
||||||
})
|
})
|
||||||
it('#533 Nested Promise support for scope object', async () => {
|
it('#533 Nested Promise support for scope object', async () => {
|
||||||
const liquid = new Liquid()
|
const liquid = new Liquid()
|
||||||
@@ -308,26 +304,26 @@ describe('Issues', function () {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(await liquid.evalValue('a == 1', context)).to.equal(true)
|
expect(await liquid.evalValue('a == 1', context)).toBe(true)
|
||||||
expect(await liquid.evalValue('b == 1', context)).to.equal(true)
|
expect(await liquid.evalValue('b == 1', context)).toBe(true)
|
||||||
expect(await liquid.evalValue('c == 1', context)).to.equal(true)
|
expect(await liquid.evalValue('c == 1', context)).toBe(true)
|
||||||
expect(await liquid.evalValue('d.d == 1', context)).to.equal(true)
|
expect(await liquid.evalValue('d.d == 1', context)).toBe(true)
|
||||||
expect(await liquid.evalValue('e.e == 1', context)).to.equal(true)
|
expect(await liquid.evalValue('e.e == 1', context)).toBe(true)
|
||||||
expect(await liquid.evalValue('f.f == 1', context)).to.equal(true)
|
expect(await liquid.evalValue('f.f == 1', context)).toBe(true)
|
||||||
expect(await liquid.evalValue('g.g == 1', context)).to.equal(true)
|
expect(await liquid.evalValue('g.g == 1', context)).toBe(true)
|
||||||
expect(await liquid.evalValue('h.h == 1', context)).to.equal(true)
|
expect(await liquid.evalValue('h.h == 1', context)).toBe(true)
|
||||||
expect(await liquid.evalValue('i.i == 1', context)).to.equal(true)
|
expect(await liquid.evalValue('i.i == 1', context)).toBe(true)
|
||||||
expect(await liquid.evalValue('j.j == 1', context)).to.equal(true)
|
expect(await liquid.evalValue('j.j == 1', context)).toBe(true)
|
||||||
expect(await liquid.parseAndRender('{{a}}', context)).to.equal('1')
|
expect(await liquid.parseAndRender('{{a}}', context)).toBe('1')
|
||||||
expect(await liquid.parseAndRender('{{b}}', context)).to.equal('1')
|
expect(await liquid.parseAndRender('{{b}}', context)).toBe('1')
|
||||||
expect(await liquid.parseAndRender('{{c}}', context)).to.equal('1')
|
expect(await liquid.parseAndRender('{{c}}', context)).toBe('1')
|
||||||
expect(await liquid.parseAndRender('{{d.d}}', context)).to.equal('1')
|
expect(await liquid.parseAndRender('{{d.d}}', context)).toBe('1')
|
||||||
expect(await liquid.parseAndRender('{{e.e}}', context)).to.equal('1')
|
expect(await liquid.parseAndRender('{{e.e}}', context)).toBe('1')
|
||||||
expect(await liquid.parseAndRender('{{f.f}}', context)).to.equal('1')
|
expect(await liquid.parseAndRender('{{f.f}}', context)).toBe('1')
|
||||||
expect(await liquid.parseAndRender('{{g.g}}', context)).to.equal('1')
|
expect(await liquid.parseAndRender('{{g.g}}', context)).toBe('1')
|
||||||
expect(await liquid.parseAndRender('{{h.h}}', context)).to.equal('1')
|
expect(await liquid.parseAndRender('{{h.h}}', context)).toBe('1')
|
||||||
expect(await liquid.parseAndRender('{{i.i}}', context)).to.equal('1')
|
expect(await liquid.parseAndRender('{{i.i}}', context)).toBe('1')
|
||||||
expect(await liquid.parseAndRender('{{j.j}}', context)).to.equal('1')
|
expect(await liquid.parseAndRender('{{j.j}}', context)).toBe('1')
|
||||||
})
|
})
|
||||||
it('#559 Case/When should evaluate multiple When statements', async () => {
|
it('#559 Case/When should evaluate multiple When statements', async () => {
|
||||||
const liquid = new Liquid()
|
const liquid = new Liquid()
|
||||||
@@ -344,7 +340,7 @@ describe('Issues', function () {
|
|||||||
{% endcase %}
|
{% endcase %}
|
||||||
`
|
`
|
||||||
const html = await liquid.parseAndRender(tpl)
|
const html = await liquid.parseAndRender(tpl)
|
||||||
expect(html).to.match(/^\s*This is a love or luck potion.\s+This is a strength or health or love potion.\s*$/)
|
expect(html).toMatch(/^\s*This is a love or luck potion.\s+This is a strength or health or love potion.\s*$/)
|
||||||
})
|
})
|
||||||
it('#570 tag registration compatible to v9', async () => {
|
it('#570 tag registration compatible to v9', async () => {
|
||||||
const liquid = new Liquid()
|
const liquid = new Liquid()
|
||||||
@@ -360,7 +356,7 @@ describe('Issues', function () {
|
|||||||
const tpl = '{% metadata_file foo %}'
|
const tpl = '{% metadata_file foo %}'
|
||||||
const ctx = { foo: 'FOO' }
|
const ctx = { foo: 'FOO' }
|
||||||
const html = await liquid.parseAndRender(tpl, ctx)
|
const html = await liquid.parseAndRender(tpl, ctx)
|
||||||
expect(html).to.equal('FOO')
|
expect(html).toBe('FOO')
|
||||||
})
|
})
|
||||||
it('#573 date filter should return parsed input when no format is provided', async () => {
|
it('#573 date filter should return parsed input when no format is provided', async () => {
|
||||||
const liquid = new Liquid()
|
const liquid = new Liquid()
|
||||||
@@ -376,7 +372,7 @@ describe('Issues', function () {
|
|||||||
const tpl = `{{ 'now' | date }}`
|
const tpl = `{{ 'now' | date }}`
|
||||||
const html = await liquid.parseAndRender(tpl)
|
const html = await liquid.parseAndRender(tpl)
|
||||||
// sample: Thursday, February 2, 2023 at 6:25 pm +0000
|
// sample: Thursday, February 2, 2023 at 6:25 pm +0000
|
||||||
expect(html).to.match(/\w+, \w+ \d+, \d\d\d\d at \d+:\d\d [ap]m [-+]\d\d\d\d/)
|
expect(html).toMatch(/\w+, \w+ \d+, \d\d\d\d at \d+:\d\d [ap]m [-+]\d\d\d\d/)
|
||||||
})
|
})
|
||||||
it('#575 Add support for Not operator', async () => {
|
it('#575 Add support for Not operator', async () => {
|
||||||
const liquid = new Liquid()
|
const liquid = new Liquid()
|
||||||
@@ -388,7 +384,7 @@ describe('Issues', function () {
|
|||||||
{% endif %}`
|
{% endif %}`
|
||||||
const ctx = { link: 'https://example.com', button: false }
|
const ctx = { link: 'https://example.com', button: false }
|
||||||
const html = await liquid.parseAndRender(tpl, ctx)
|
const html = await liquid.parseAndRender(tpl, ctx)
|
||||||
expect(html.trim()).to.equal('<a href="https://example.com">Lot more code here</a>')
|
expect(html.trim()).toBe('<a href="https://example.com">Lot more code here</a>')
|
||||||
})
|
})
|
||||||
it('#70 strip multiline content of <style>', async () => {
|
it('#70 strip multiline content of <style>', async () => {
|
||||||
const str = `
|
const str = `
|
||||||
@@ -398,7 +394,7 @@ describe('Issues', function () {
|
|||||||
const engine = new Liquid()
|
const engine = new Liquid()
|
||||||
const template = '{{ str | strip_html }}'
|
const template = '{{ str | strip_html }}'
|
||||||
const html = await engine.parseAndRender(template, { str })
|
const html = await engine.parseAndRender(template, { str })
|
||||||
expect(html).to.match(/^\s*$/)
|
expect(html).toMatch(/^\s*$/)
|
||||||
})
|
})
|
||||||
it('#589 Arrays should compare values', async () => {
|
it('#589 Arrays should compare values', async () => {
|
||||||
const engine = new Liquid()
|
const engine = new Liquid()
|
||||||
@@ -408,6 +404,6 @@ describe('Issues', function () {
|
|||||||
{% if people1 == people2 %}true{%else%}false{% endif %}
|
{% if people1 == people2 %}true{%else%}false{% endif %}
|
||||||
`
|
`
|
||||||
const html = await engine.parseAndRender(template)
|
const html = await engine.parseAndRender(template)
|
||||||
expect(html).to.contain('true')
|
expect(html).toContain('true')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,8 +1,4 @@
|
|||||||
import { Liquid } from '../..'
|
import { Liquid } from '../..'
|
||||||
import { expect, use } from 'chai'
|
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
|
|
||||||
use(chaiAsPromised)
|
|
||||||
|
|
||||||
describe('.parseAndRender()', function () {
|
describe('.parseAndRender()', function () {
|
||||||
var engine: Liquid, strictEngine: Liquid
|
var engine: Liquid, strictEngine: Liquid
|
||||||
@@ -15,51 +11,50 @@ describe('.parseAndRender()', function () {
|
|||||||
it('should stringify array ', async function () {
|
it('should stringify array ', async function () {
|
||||||
var ctx = { arr: [-2, 'a'] }
|
var ctx = { arr: [-2, 'a'] }
|
||||||
const html = await engine.parseAndRender('{{arr}}', ctx)
|
const html = await engine.parseAndRender('{{arr}}', ctx)
|
||||||
return expect(html).to.equal('-2a')
|
return expect(html).toBe('-2a')
|
||||||
})
|
})
|
||||||
it('should render undefined as empty', async function () {
|
it('should render undefined as empty', async function () {
|
||||||
const html = await engine.parseAndRender('foo{{zzz}}bar', {})
|
const html = await engine.parseAndRender('foo{{zzz}}bar', {})
|
||||||
return expect(html).to.equal('foobar')
|
return expect(html).toBe('foobar')
|
||||||
})
|
})
|
||||||
it('should render as null when filter undefined', async function () {
|
it('should render as null when filter undefined', async function () {
|
||||||
const html = await engine.parseAndRender('{{"foo" | filter1}}', {})
|
const html = await engine.parseAndRender('{{"foo" | filter1}}', {})
|
||||||
return expect(html).to.equal('foo')
|
return expect(html).toBe('foo')
|
||||||
})
|
})
|
||||||
it('should throw upon undefined filter when strictFilters set', function () {
|
it('should throw upon undefined filter when strictFilters set', function () {
|
||||||
return expect(strictEngine.parseAndRender('{{"foo" | filter1}}', {})).to
|
return expect(strictEngine.parseAndRender('{{"foo" | filter1}}', {})).rejects.toThrow(/undefined filter: filter1/)
|
||||||
.be.rejectedWith(/undefined filter: filter1/)
|
|
||||||
})
|
})
|
||||||
it('should parse html', function () {
|
it('should parse html', function () {
|
||||||
expect(function () {
|
expect(function () {
|
||||||
engine.parse('{{obj}}')
|
engine.parse('{{obj}}')
|
||||||
}).to.not.throw()
|
}).not.toThrow()
|
||||||
expect(function () {
|
expect(function () {
|
||||||
engine.parse('<html><head>{{obj}}</head></html>')
|
engine.parse('<html><head>{{obj}}</head></html>')
|
||||||
}).to.not.throw()
|
}).not.toThrow()
|
||||||
})
|
})
|
||||||
it('template should be able to be rendered multiple times', async function () {
|
it('template should be able to be rendered multiple times', async function () {
|
||||||
const ctx = { obj: [1, 2] }
|
const ctx = { obj: [1, 2] }
|
||||||
const template = engine.parse('{{obj}}')
|
const template = engine.parse('{{obj}}')
|
||||||
const result = await engine.render(template, ctx)
|
const result = await engine.render(template, ctx)
|
||||||
expect(result).to.equal('12')
|
expect(result).toBe('12')
|
||||||
const result2 = await engine.render(template, ctx)
|
const result2 = await engine.render(template, ctx)
|
||||||
expect(result2).to.equal('12')
|
expect(result2).toBe('12')
|
||||||
})
|
})
|
||||||
it('should support the "join" filter', async function () {
|
it('should support the "join" filter', async function () {
|
||||||
var ctx = { names: ['alice', 'bob'] }
|
var ctx = { names: ['alice', 'bob'] }
|
||||||
var template = engine.parse('<p>{{names | join: ","}}</p>')
|
var template = engine.parse('<p>{{names | join: ","}}</p>')
|
||||||
const html = await engine.render(template, ctx)
|
const html = await engine.render(template, ctx)
|
||||||
return expect(html).to.equal('<p>alice,bob</p>')
|
return expect(html).toBe('<p>alice,bob</p>')
|
||||||
})
|
})
|
||||||
it('should support the "first" filter', async function () {
|
it('should support the "first" filter', async function () {
|
||||||
var src = '{% assign my_array = "apples, oranges, peaches, plums" | split: ", " %}' +
|
var src = '{% assign my_array = "apples, oranges, peaches, plums" | split: ", " %}' +
|
||||||
'{{ my_array | first }}'
|
'{{ my_array | first }}'
|
||||||
const html = await engine.parseAndRender(src)
|
const html = await engine.parseAndRender(src)
|
||||||
return expect(html).to.equal('apples')
|
return expect(html).toBe('apples')
|
||||||
})
|
})
|
||||||
it('should support nil(null, undefined) literal', async function () {
|
it('should support nil(null, undefined) literal', async function () {
|
||||||
const src = '{% if notexist == nil %}true{% endif %}'
|
const src = '{% if notexist == nil %}true{% endif %}'
|
||||||
const html = await engine.parseAndRender(src)
|
const html = await engine.parseAndRender(src)
|
||||||
expect(html).to.equal('true')
|
expect(html).toBe('true')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,10 +1,6 @@
|
|||||||
import { Liquid } from '../..'
|
import { Liquid } from '../..'
|
||||||
import { expect, use } from 'chai'
|
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
import { resolve } from 'path'
|
import { resolve } from 'path'
|
||||||
|
|
||||||
use(chaiAsPromised)
|
|
||||||
|
|
||||||
describe('#renderFile()', function () {
|
describe('#renderFile()', function () {
|
||||||
const root = resolve(__dirname, '../stub/root')
|
const root = resolve(__dirname, '../stub/root')
|
||||||
const views = resolve(__dirname, '../stub/views')
|
const views = resolve(__dirname, '../stub/views')
|
||||||
@@ -17,16 +13,16 @@ describe('#renderFile()', function () {
|
|||||||
})
|
})
|
||||||
it('should render file', async function () {
|
it('should render file', async function () {
|
||||||
const html = await engine.renderFile(resolve(root, 'foo.html'), {})
|
const html = await engine.renderFile(resolve(root, 'foo.html'), {})
|
||||||
return expect(html).to.equal('foo')
|
return expect(html).toBe('foo')
|
||||||
})
|
})
|
||||||
it('should find files without extname', async function () {
|
it('should find files without extname', async function () {
|
||||||
var engine = new Liquid({ root })
|
var engine = new Liquid({ root })
|
||||||
const html = await engine.renderFile(resolve(root, 'bar'), {})
|
const html = await engine.renderFile(resolve(root, 'bar'), {})
|
||||||
return expect(html).to.equal('bar')
|
return expect(html).toBe('bar')
|
||||||
})
|
})
|
||||||
it('should accept relative path', async function () {
|
it('should accept relative path', async function () {
|
||||||
const html = await engine.renderFile('foo.html')
|
const html = await engine.renderFile('foo.html')
|
||||||
return expect(html).to.equal('foo')
|
return expect(html).toBe('foo')
|
||||||
})
|
})
|
||||||
it('should traverse root array', async function () {
|
it('should traverse root array', async function () {
|
||||||
engine = new Liquid({
|
engine = new Liquid({
|
||||||
@@ -34,27 +30,26 @@ describe('#renderFile()', function () {
|
|||||||
extname: '.html'
|
extname: '.html'
|
||||||
})
|
})
|
||||||
const html = await engine.renderFile('foo.html')
|
const html = await engine.renderFile('foo.html')
|
||||||
return expect(html).to.equal('foo')
|
return expect(html).toBe('foo')
|
||||||
})
|
})
|
||||||
it('should default root to cwd', async function () {
|
it('should default root to cwd', async function () {
|
||||||
engine = new Liquid()
|
engine = new Liquid()
|
||||||
const html = await engine.renderFile('package.json')
|
const html = await engine.renderFile('package.json')
|
||||||
return expect(html).to.contain('"name": "liquidjs"')
|
return expect(html).toContain('"name": "liquidjs"')
|
||||||
})
|
})
|
||||||
it('should render file with context', async function () {
|
it('should render file with context', async function () {
|
||||||
const html = await engine.renderFile(resolve(views, 'name.html'), { name: 'harttle' })
|
const html = await engine.renderFile(resolve(views, 'name.html'), { name: 'harttle' })
|
||||||
return expect(html).to.equal('My name is harttle.')
|
return expect(html).toBe('My name is harttle.')
|
||||||
})
|
})
|
||||||
it('should use default extname', async function () {
|
it('should use default extname', async function () {
|
||||||
const html = await engine.renderFile(resolve(root, 'foo'))
|
const html = await engine.renderFile(resolve(root, 'foo'))
|
||||||
return expect(html).to.equal('foo')
|
return expect(html).toBe('foo')
|
||||||
})
|
})
|
||||||
it('should throw with lookup list when file not exist', function () {
|
it('should throw with lookup list when file not exist', function () {
|
||||||
engine = new Liquid({
|
engine = new Liquid({
|
||||||
root: ['/boo', '/root/'],
|
root: ['/boo', '/root/'],
|
||||||
extname: '.html'
|
extname: '.html'
|
||||||
})
|
})
|
||||||
return expect(engine.renderFile('/not/exist.html')).to
|
return expect(engine.renderFile('/not/exist.html')).rejects.toThrow(/Failed to lookup "\/not\/exist.html" in "\/boo,\/root\/"/)
|
||||||
.be.rejectedWith(/Failed to lookup "\/not\/exist.html" in "\/boo,\/root\/"/)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,10 +1,6 @@
|
|||||||
import { expect, use } from 'chai'
|
|
||||||
import { resolve } from 'path'
|
import { resolve } from 'path'
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
import { drainStream } from '../stub/stream'
|
import { drainStream } from '../stub/stream'
|
||||||
|
|
||||||
use(chaiAsPromised)
|
|
||||||
|
|
||||||
describe('.renderToNodeStream()', function () {
|
describe('.renderToNodeStream()', function () {
|
||||||
it('should render to stream in Node.js', done => {
|
it('should render to stream in Node.js', done => {
|
||||||
const cjs = require('../../dist/liquid.node.cjs')
|
const cjs = require('../../dist/liquid.node.cjs')
|
||||||
@@ -15,7 +11,7 @@ describe('.renderToNodeStream()', function () {
|
|||||||
stream.on('data', (data: string) => { html += data })
|
stream.on('data', (data: string) => { html += data })
|
||||||
stream.on('end', () => {
|
stream.on('end', () => {
|
||||||
try {
|
try {
|
||||||
expect(html).to.equal('foo')
|
expect(html).toBe('foo')
|
||||||
done()
|
done()
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
done(err)
|
done(err)
|
||||||
@@ -26,7 +22,7 @@ describe('.renderToNodeStream()', function () {
|
|||||||
const cjs = require('../../dist/liquid.browser.umd')
|
const cjs = require('../../dist/liquid.browser.umd')
|
||||||
const engine = new cjs.Liquid()
|
const engine = new cjs.Liquid()
|
||||||
const render = () => engine.renderToNodeStream('foo')
|
const render = () => engine.renderToNodeStream('foo')
|
||||||
return expect(render).to.throw('streaming not supported in browser')
|
return expect(render).toThrow('streaming not supported in browser')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -37,6 +33,6 @@ describe('.renderFileToNodeStream()', function () {
|
|||||||
root: resolve(__dirname, '../stub/root/')
|
root: resolve(__dirname, '../stub/root/')
|
||||||
})
|
})
|
||||||
const stream = await engine.renderFileToNodeStream('foo.html')
|
const stream = await engine.renderFileToNodeStream('foo.html')
|
||||||
expect(drainStream(stream)).to.eventually.equal('foo')
|
expect(drainStream(stream)).resolves.toBe('foo')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,10 +1,7 @@
|
|||||||
import { Liquid } from '../../dist/liquid.browser.umd.js'
|
|
||||||
import * as sinon from 'sinon'
|
import * as sinon from 'sinon'
|
||||||
import { expect, use } from 'chai'
|
|
||||||
import { JSDOM } from 'jsdom'
|
import { JSDOM } from 'jsdom'
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
import type { Liquid } from '../..'
|
||||||
|
const LiquidUMD = require('../../dist/liquid.browser.umd.js').Liquid
|
||||||
use(chaiAsPromised)
|
|
||||||
|
|
||||||
describe('xhr', () => {
|
describe('xhr', () => {
|
||||||
if (+(process.version.match(/^v(\d+)/) as RegExpMatchArray)[1] < 8) {
|
if (+(process.version.match(/^v(\d+)/) as RegExpMatchArray)[1] < 8) {
|
||||||
@@ -24,7 +21,7 @@ describe('xhr', () => {
|
|||||||
});
|
});
|
||||||
(global as any).XMLHttpRequest = sinon.FakeXMLHttpRequest;
|
(global as any).XMLHttpRequest = sinon.FakeXMLHttpRequest;
|
||||||
(global as any).document = dom.window.document
|
(global as any).document = dom.window.document
|
||||||
engine = new Liquid({
|
engine = new LiquidUMD({
|
||||||
root: 'https://example.com/views/',
|
root: 'https://example.com/views/',
|
||||||
extname: '.html'
|
extname: '.html'
|
||||||
})
|
})
|
||||||
@@ -37,21 +34,21 @@ describe('xhr', () => {
|
|||||||
describe('#renderFile()', () => {
|
describe('#renderFile()', () => {
|
||||||
it('should support without extname', async () => {
|
it('should support without extname', async () => {
|
||||||
const html = await engine.renderFile('hello', { name: 'alice1' })
|
const html = await engine.renderFile('hello', { name: 'alice1' })
|
||||||
return expect(html).to.equal('hello alice1')
|
return expect(html).toBe('hello alice1')
|
||||||
})
|
})
|
||||||
it('should support with extname', async () => {
|
it('should support with extname', async () => {
|
||||||
const html = await engine.renderFile('hello.html', { name: 'alice2' })
|
const html = await engine.renderFile('hello.html', { name: 'alice2' })
|
||||||
return expect(html).to.equal('hello alice2')
|
return expect(html).toBe('hello alice2')
|
||||||
})
|
})
|
||||||
it('should support with absolute path', async () => {
|
it('should support with absolute path', async () => {
|
||||||
server.respondWith('GET', 'https://example.com/foo.html',
|
server.respondWith('GET', 'https://example.com/foo.html',
|
||||||
[200, { 'Content-Type': 'text/plain' }, 'foo'])
|
[200, { 'Content-Type': 'text/plain' }, 'foo'])
|
||||||
const html = await engine.renderFile('/foo.html')
|
const html = await engine.renderFile('/foo.html')
|
||||||
return expect(html).to.equal('foo')
|
return expect(html).toBe('foo')
|
||||||
})
|
})
|
||||||
it('should support with url', async () => {
|
it('should support with url', async () => {
|
||||||
const html = await engine.renderFile('https://example.com/views/hello.html', { name: 'alice4' })
|
const html = await engine.renderFile('https://example.com/views/hello.html', { name: 'alice4' })
|
||||||
return expect(html).to.equal('hello alice4')
|
return expect(html).toBe('hello alice4')
|
||||||
})
|
})
|
||||||
it('should support include', async () => {
|
it('should support include', async () => {
|
||||||
server.respondWith('GET', 'https://example.com/views/hello.html',
|
server.respondWith('GET', 'https://example.com/views/hello.html',
|
||||||
@@ -59,15 +56,15 @@ describe('xhr', () => {
|
|||||||
server.respondWith('GET', 'https://example.com/views/name.html',
|
server.respondWith('GET', 'https://example.com/views/name.html',
|
||||||
[200, { 'Content-Type': 'text/plain' }, '{{name}}'])
|
[200, { 'Content-Type': 'text/plain' }, '{{name}}'])
|
||||||
const html = await engine.renderFile('hello.html', { name: 'alice5' })
|
const html = await engine.renderFile('hello.html', { name: 'alice5' })
|
||||||
return expect(html).to.equal('hello alice5')
|
return expect(html).toBe('hello alice5')
|
||||||
})
|
})
|
||||||
it('should throw 404', () => {
|
it('should throw 404', () => {
|
||||||
return expect(engine.renderFile('/not/exist.html'))
|
return expect(engine.renderFile('/not/exist.html'))
|
||||||
.to.be.rejectedWith('Not Found')
|
.rejects.toThrow('Not Found')
|
||||||
})
|
})
|
||||||
it('should throw error', function () {
|
it('should throw error', function () {
|
||||||
const result = expect(engine.renderFile('hello.html'))
|
const result = expect(engine.renderFile('hello.html'))
|
||||||
.to.be.rejectedWith('An error occurred whilst receiving the response.');
|
.rejects.toThrow('An error occurred whilst receiving the response.');
|
||||||
(global as any).XMLHttpRequest.onCreate = function (request: sinon.SinonFakeXMLHttpRequest) {
|
(global as any).XMLHttpRequest.onCreate = function (request: sinon.SinonFakeXMLHttpRequest) {
|
||||||
setTimeout(() => request.error())
|
setTimeout(() => request.error())
|
||||||
}
|
}
|
||||||
@@ -76,53 +73,53 @@ describe('xhr', () => {
|
|||||||
})
|
})
|
||||||
describe('#renderFile() with root specified', () => {
|
describe('#renderFile() with root specified', () => {
|
||||||
it('should support undefined root', async () => {
|
it('should support undefined root', async () => {
|
||||||
engine = new Liquid({
|
engine = new LiquidUMD({
|
||||||
extname: '.html'
|
extname: '.html'
|
||||||
})
|
})
|
||||||
server.respondWith('GET', 'https://example.com/foo/hello.html',
|
server.respondWith('GET', 'https://example.com/foo/hello.html',
|
||||||
[200, { 'Content-Type': 'text/plain' }, 'hello {{name}}'])
|
[200, { 'Content-Type': 'text/plain' }, 'hello {{name}}'])
|
||||||
const html = await engine.renderFile('hello.html', { name: 'alice5' })
|
const html = await engine.renderFile('hello.html', { name: 'alice5' })
|
||||||
return expect(html).to.equal('hello alice5')
|
return expect(html).toBe('hello alice5')
|
||||||
})
|
})
|
||||||
it('should support empty root', async () => {
|
it('should support empty root', async () => {
|
||||||
engine = new Liquid({
|
engine = new LiquidUMD({
|
||||||
root: '',
|
root: '',
|
||||||
extname: '.html'
|
extname: '.html'
|
||||||
})
|
})
|
||||||
server.respondWith('https://example.com/foo/hello.html',
|
server.respondWith('https://example.com/foo/hello.html',
|
||||||
[200, { 'Content-Type': 'text/plain' }, 'hello {{name}}'])
|
[200, { 'Content-Type': 'text/plain' }, 'hello {{name}}'])
|
||||||
const html = await engine.renderFile('hello.html', { name: 'alice5' })
|
const html = await engine.renderFile('hello.html', { name: 'alice5' })
|
||||||
return expect(html).to.equal('hello alice5')
|
return expect(html).toBe('hello alice5')
|
||||||
})
|
})
|
||||||
it('should support with relative path', async () => {
|
it('should support with relative path', async () => {
|
||||||
engine = new Liquid({
|
engine = new LiquidUMD({
|
||||||
root: './views/',
|
root: './views/',
|
||||||
extname: '.html'
|
extname: '.html'
|
||||||
})
|
})
|
||||||
server.respondWith('GET', 'https://example.com/foo/views/hello.html',
|
server.respondWith('GET', 'https://example.com/foo/views/hello.html',
|
||||||
[200, { 'Content-Type': 'text/plain' }, 'hello {{name}}'])
|
[200, { 'Content-Type': 'text/plain' }, 'hello {{name}}'])
|
||||||
const html = await engine.renderFile('hello.html', { name: 'alice5' })
|
const html = await engine.renderFile('hello.html', { name: 'alice5' })
|
||||||
return expect(html).to.equal('hello alice5')
|
return expect(html).toBe('hello alice5')
|
||||||
})
|
})
|
||||||
it('should support with absolute path', async () => {
|
it('should support with absolute path', async () => {
|
||||||
engine = new Liquid({
|
engine = new LiquidUMD({
|
||||||
root: '/views/',
|
root: '/views/',
|
||||||
extname: '.html'
|
extname: '.html'
|
||||||
})
|
})
|
||||||
server.respondWith('GET', 'https://example.com/views/hello.html',
|
server.respondWith('GET', 'https://example.com/views/hello.html',
|
||||||
[200, { 'Content-Type': 'text/plain' }, 'hello {{name}}'])
|
[200, { 'Content-Type': 'text/plain' }, 'hello {{name}}'])
|
||||||
const html = await engine.renderFile('hello.html', { name: 'alice5' })
|
const html = await engine.renderFile('hello.html', { name: 'alice5' })
|
||||||
return expect(html).to.equal('hello alice5')
|
return expect(html).toBe('hello alice5')
|
||||||
})
|
})
|
||||||
it('should support with url', async () => {
|
it('should support with url', async () => {
|
||||||
engine = new Liquid({
|
engine = new LiquidUMD({
|
||||||
root: 'https://foo.com/bar/',
|
root: 'https://foo.com/bar/',
|
||||||
extname: '.html'
|
extname: '.html'
|
||||||
})
|
})
|
||||||
server.respondWith('GET', 'https://foo.com/bar/hello.html',
|
server.respondWith('GET', 'https://foo.com/bar/hello.html',
|
||||||
[200, { 'Content-Type': 'text/plain' }, 'hello {{name}}'])
|
[200, { 'Content-Type': 'text/plain' }, 'hello {{name}}'])
|
||||||
const html = await engine.renderFile('hello.html', { name: 'alice5' })
|
const html = await engine.renderFile('hello.html', { name: 'alice5' })
|
||||||
return expect(html).to.equal('hello alice5')
|
return expect(html).toBe('hello alice5')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('cache options', () => {
|
describe('cache options', () => {
|
||||||
@@ -131,15 +128,15 @@ describe('xhr', () => {
|
|||||||
[200, { 'Content-Type': 'text/plain' }, 'foo1'])
|
[200, { 'Content-Type': 'text/plain' }, 'foo1'])
|
||||||
return engine.renderFile('foo.html')
|
return engine.renderFile('foo.html')
|
||||||
.then((html: string) => {
|
.then((html: string) => {
|
||||||
expect(html).to.equal('foo1')
|
expect(html).toBe('foo1')
|
||||||
server.respondWith('GET', 'https://example.com/views/foo.html',
|
server.respondWith('GET', 'https://example.com/views/foo.html',
|
||||||
[200, { 'Content-Type': 'text/plain' }, 'foo2'])
|
[200, { 'Content-Type': 'text/plain' }, 'foo2'])
|
||||||
return engine.renderFile('foo.html')
|
return engine.renderFile('foo.html')
|
||||||
})
|
})
|
||||||
.then((html: string) => expect(html).to.equal('foo2'))
|
.then((html: string) => expect(html).toBe('foo2'))
|
||||||
})
|
})
|
||||||
it('should respect cache=true option', () => {
|
it('should respect cache=true option', () => {
|
||||||
engine = new Liquid({
|
engine = new LiquidUMD({
|
||||||
root: '/views/',
|
root: '/views/',
|
||||||
extname: '.html',
|
extname: '.html',
|
||||||
cache: true
|
cache: true
|
||||||
@@ -148,12 +145,12 @@ describe('xhr', () => {
|
|||||||
[200, { 'Content-Type': 'text/plain' }, 'foo1'])
|
[200, { 'Content-Type': 'text/plain' }, 'foo1'])
|
||||||
return engine.renderFile('foo.html')
|
return engine.renderFile('foo.html')
|
||||||
.then((html: string) => {
|
.then((html: string) => {
|
||||||
expect(html).to.equal('foo1')
|
expect(html).toBe('foo1')
|
||||||
server.respondWith('GET', 'https://example.com/views/foo.html',
|
server.respondWith('GET', 'https://example.com/views/foo.html',
|
||||||
[200, { 'Content-Type': 'text/plain' }, 'foo2'])
|
[200, { 'Content-Type': 'text/plain' }, 'foo2'])
|
||||||
return engine.renderFile('foo.html')
|
return engine.renderFile('foo.html')
|
||||||
})
|
})
|
||||||
.then((html: string) => expect(html).to.equal('foo1'))
|
.then((html: string) => expect(html).toBe('foo1'))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,52 +1,51 @@
|
|||||||
import { expect } from 'chai'
|
|
||||||
import { Liquid } from '../../../src/liquid'
|
import { Liquid } from '../../../src/liquid'
|
||||||
|
|
||||||
describe('drop/blank-drop', function () {
|
describe('drop/blank-drop', function () {
|
||||||
let liquid: Liquid
|
let liquid: Liquid
|
||||||
before(() => (liquid = new Liquid()))
|
beforeEach(() => (liquid = new Liquid()))
|
||||||
|
|
||||||
it('render blank drop as blank string', async function () {
|
it('render blank drop as blank string', async function () {
|
||||||
const html = await liquid.parseAndRender('{{blank}}')
|
const html = await liquid.parseAndRender('{{blank}}')
|
||||||
expect(html).to.equal('')
|
expect(html).toBe('')
|
||||||
})
|
})
|
||||||
it('blank equals nil', async function () {
|
it('blank equals nil', async function () {
|
||||||
const src = '{%if blank == nil %}blank == nil{%else%}blank != nil{% endif %}'
|
const src = '{%if blank == nil %}blank == nil{%else%}blank != nil{% endif %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
expect(html).to.equal('blank == nil')
|
expect(html).toBe('blank == nil')
|
||||||
})
|
})
|
||||||
it('false is blank', async function () {
|
it('false is blank', async function () {
|
||||||
const src = '{%if false == blank %}false == blank{%else%}false != blank{% endif %}'
|
const src = '{%if false == blank %}false == blank{%else%}false != blank{% endif %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
expect(html).to.equal('false == blank')
|
expect(html).toBe('false == blank')
|
||||||
})
|
})
|
||||||
it('"" is blank', async function () {
|
it('"" is blank', async function () {
|
||||||
const src = '{%if "" == blank %}"" == blank{%else%}"" != blank{% endif %}'
|
const src = '{%if "" == blank %}"" == blank{%else%}"" != blank{% endif %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
expect(html).to.equal('"" == blank')
|
expect(html).toBe('"" == blank')
|
||||||
})
|
})
|
||||||
it('" " is blank', async function () {
|
it('" " is blank', async function () {
|
||||||
const src = '{%if " " == blank %}" " == blank{%else%}" " != blank{% endif %}'
|
const src = '{%if " " == blank %}" " == blank{%else%}" " != blank{% endif %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
expect(html).to.equal('" " == blank')
|
expect(html).toBe('" " == blank')
|
||||||
})
|
})
|
||||||
it('{} is blank', async function () {
|
it('{} is blank', async function () {
|
||||||
const src = '{%if obj == blank %}{} == blank{%else%}{} != blank{% endif %}'
|
const src = '{%if obj == blank %}{} == blank{%else%}{} != blank{% endif %}'
|
||||||
const html = await liquid.parseAndRender(src, { obj: {} })
|
const html = await liquid.parseAndRender(src, { obj: {} })
|
||||||
expect(html).to.equal('{} == blank')
|
expect(html).toBe('{} == blank')
|
||||||
})
|
})
|
||||||
it('{foo: 1} is not blank', async function () {
|
it('{foo: 1} is not blank', async function () {
|
||||||
const src = '{%if obj == blank %}{foo: 1} == blank{%else%}{foo: 1} != blank{% endif %}'
|
const src = '{%if obj == blank %}{foo: 1} == blank{%else%}{foo: 1} != blank{% endif %}'
|
||||||
const html = await liquid.parseAndRender(src, { obj: { foo: 1 } })
|
const html = await liquid.parseAndRender(src, { obj: { foo: 1 } })
|
||||||
expect(html).to.equal('{foo: 1} != blank')
|
expect(html).toBe('{foo: 1} != blank')
|
||||||
})
|
})
|
||||||
it('[] is blank', async function () {
|
it('[] is blank', async function () {
|
||||||
const src = '{%if arr == blank %}[] == blank{%else%}[] != blank{% endif %}'
|
const src = '{%if arr == blank %}[] == blank{%else%}[] != blank{% endif %}'
|
||||||
const html = await liquid.parseAndRender(src, { arr: [] })
|
const html = await liquid.parseAndRender(src, { arr: [] })
|
||||||
expect(html).to.equal('[] == blank')
|
expect(html).toBe('[] == blank')
|
||||||
})
|
})
|
||||||
it('[1] is not blank', async function () {
|
it('[1] is not blank', async function () {
|
||||||
const src = '{%if arr == blank %}[1] == blank{%else%}[1] != blank{% endif %}'
|
const src = '{%if arr == blank %}[1] == blank{%else%}[1] != blank{% endif %}'
|
||||||
const html = await liquid.parseAndRender(src, { arr: [1] })
|
const html = await liquid.parseAndRender(src, { arr: [1] })
|
||||||
expect(html).to.equal('[1] != blank')
|
expect(html).toBe('[1] != blank')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
import { expect } from 'chai'
|
|
||||||
import { Liquid, Drop } from '../../../src'
|
import { Liquid, Drop } from '../../../src'
|
||||||
|
|
||||||
describe('drop/drop', function () {
|
describe('drop/drop', function () {
|
||||||
let liquid: Liquid
|
let liquid: Liquid
|
||||||
before(() => (liquid = new Liquid()))
|
beforeEach(() => (liquid = new Liquid()))
|
||||||
|
|
||||||
class CustomDrop extends Drop {
|
class CustomDrop extends Drop {
|
||||||
private name = 'NAME'
|
private name = 'NAME'
|
||||||
@@ -27,39 +26,39 @@ describe('drop/drop', function () {
|
|||||||
}
|
}
|
||||||
it('should call corresponding method when output', async function () {
|
it('should call corresponding method when output', async function () {
|
||||||
const html = await liquid.parseAndRender(`{{obj.getName}}`, { obj: new CustomDrop() })
|
const html = await liquid.parseAndRender(`{{obj.getName}}`, { obj: new CustomDrop() })
|
||||||
expect(html).to.equal('GET NAME')
|
expect(html).toBe('GET NAME')
|
||||||
})
|
})
|
||||||
it('should call corresponding method when expression evaluates', async function () {
|
it('should call corresponding method when expression evaluates', async function () {
|
||||||
const html = await liquid.parseAndRender(`{% if obj.getName == "GET NAME" %}true{% endif %}`, { obj: new CustomDrop() })
|
const html = await liquid.parseAndRender(`{% if obj.getName == "GET NAME" %}true{% endif %}`, { obj: new CustomDrop() })
|
||||||
expect(html).to.equal('true')
|
expect(html).toBe('true')
|
||||||
})
|
})
|
||||||
it('should read corresponding property', async function () {
|
it('should read corresponding property', async function () {
|
||||||
const html = await liquid.parseAndRender(`{{obj.name}}`, { obj: new CustomDrop() })
|
const html = await liquid.parseAndRender(`{{obj.name}}`, { obj: new CustomDrop() })
|
||||||
expect(html).to.equal('NAME')
|
expect(html).toBe('NAME')
|
||||||
})
|
})
|
||||||
it('should output empty string if not exist', async function () {
|
it('should output empty string if not exist', async function () {
|
||||||
const html = await liquid.parseAndRender(`{{obj.foo}}`, { obj: new CustomDrop() })
|
const html = await liquid.parseAndRender(`{{obj.foo}}`, { obj: new CustomDrop() })
|
||||||
expect(html).to.equal('')
|
expect(html).toBe('')
|
||||||
})
|
})
|
||||||
it('should respect liquidMethodMissing', async function () {
|
it('should respect liquidMethodMissing', async function () {
|
||||||
const html = await liquid.parseAndRender(`{{obj.foo}}`, { obj: new CustomDropWithMethodMissing() })
|
const html = await liquid.parseAndRender(`{{obj.foo}}`, { obj: new CustomDropWithMethodMissing() })
|
||||||
expect(html).to.equal('FOO')
|
expect(html).toBe('FOO')
|
||||||
})
|
})
|
||||||
it('should call corresponding promise method', async function () {
|
it('should call corresponding promise method', async function () {
|
||||||
const html = await liquid.parseAndRender(`{{obj.getName}}`, { obj: new PromiseDrop() })
|
const html = await liquid.parseAndRender(`{{obj.getName}}`, { obj: new PromiseDrop() })
|
||||||
expect(html).to.equal('GET NAME')
|
expect(html).toBe('GET NAME')
|
||||||
})
|
})
|
||||||
it('should read corresponding promise property', async function () {
|
it('should read corresponding promise property', async function () {
|
||||||
const html = await liquid.parseAndRender(`{{obj.name}}`, { obj: new PromiseDrop() })
|
const html = await liquid.parseAndRender(`{{obj.name}}`, { obj: new PromiseDrop() })
|
||||||
expect(html).to.equal('NAME')
|
expect(html).toBe('NAME')
|
||||||
})
|
})
|
||||||
it('should resolve before calling filters', async function () {
|
it('should resolve before calling filters', async function () {
|
||||||
const html = await liquid.parseAndRender(`{{obj.name | downcase}}`, { obj: new PromiseDrop() })
|
const html = await liquid.parseAndRender(`{{obj.name | downcase}}`, { obj: new PromiseDrop() })
|
||||||
expect(html).to.equal('name')
|
expect(html).toBe('name')
|
||||||
})
|
})
|
||||||
it('should support promise returned by liquidMethodMissing', async function () {
|
it('should support promise returned by liquidMethodMissing', async function () {
|
||||||
const html = await liquid.parseAndRender(`{{obj.foo}}`, { obj: new PromiseDrop() })
|
const html = await liquid.parseAndRender(`{{obj.foo}}`, { obj: new PromiseDrop() })
|
||||||
expect(html).to.equal('FOO')
|
expect(html).toBe('FOO')
|
||||||
})
|
})
|
||||||
it('should respect valueOf', async () => {
|
it('should respect valueOf', async () => {
|
||||||
class CustomDrop extends Drop {
|
class CustomDrop extends Drop {
|
||||||
@@ -70,7 +69,7 @@ describe('drop/drop', function () {
|
|||||||
}
|
}
|
||||||
const tpl = '{{drop}}: {% for field in drop %}{{ field }};{% endfor %}'
|
const tpl = '{{drop}}: {% for field in drop %}{{ field }};{% endfor %}'
|
||||||
const html = await liquid.parseAndRender(tpl, { drop: new CustomDrop() })
|
const html = await liquid.parseAndRender(tpl, { drop: new CustomDrop() })
|
||||||
expect(html).to.equal('foobar: foo;bar;')
|
expect(html).toBe('foobar: foo;bar;')
|
||||||
})
|
})
|
||||||
it('should support valueOf in == expression', async () => {
|
it('should support valueOf in == expression', async () => {
|
||||||
class AddressDrop extends Drop {
|
class AddressDrop extends Drop {
|
||||||
@@ -82,6 +81,6 @@ describe('drop/drop', function () {
|
|||||||
const customer = { default_address: new AddressDrop() }
|
const customer = { default_address: new AddressDrop() }
|
||||||
const tpl = `{% if address == customer.default_address %}{{address}}{% endif %}`
|
const tpl = `{% if address == customer.default_address %}{{address}}{% endif %}`
|
||||||
const html = await liquid.parseAndRender(tpl, { address, customer })
|
const html = await liquid.parseAndRender(tpl, { address, customer })
|
||||||
expect(html).to.equal('test')
|
expect(html).toBe('test')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,92 +1,91 @@
|
|||||||
import { expect } from 'chai'
|
|
||||||
import { Liquid } from '../../../src/liquid'
|
import { Liquid } from '../../../src/liquid'
|
||||||
|
|
||||||
describe('drop/empty-drop', function () {
|
describe('drop/empty-drop', function () {
|
||||||
let liquid: Liquid
|
let liquid: Liquid
|
||||||
before(() => (liquid = new Liquid()))
|
beforeEach(() => (liquid = new Liquid()))
|
||||||
|
|
||||||
it('render empty drop as empty string', async function () {
|
it('render empty drop as empty string', async function () {
|
||||||
const html = await liquid.parseAndRender('{{empty}}')
|
const html = await liquid.parseAndRender('{{empty}}')
|
||||||
expect(html).to.equal('')
|
expect(html).toBe('')
|
||||||
})
|
})
|
||||||
it('nil is not empty', async function () {
|
it('nil is not empty', async function () {
|
||||||
const src = '{%if nil == empty %}nil == empty{%else%}nil != empty{% endif %}'
|
const src = '{%if nil == empty %}nil == empty{%else%}nil != empty{% endif %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
expect(html).to.equal('nil != empty')
|
expect(html).toBe('nil != empty')
|
||||||
})
|
})
|
||||||
it('false is not empty', async function () {
|
it('false is not empty', async function () {
|
||||||
const src = '{%if false == empty %}false == empty{%else%}false != empty{% endif %}'
|
const src = '{%if false == empty %}false == empty{%else%}false != empty{% endif %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
expect(html).to.equal('false != empty')
|
expect(html).toBe('false != empty')
|
||||||
})
|
})
|
||||||
it('"" is empty', async function () {
|
it('"" is empty', async function () {
|
||||||
const src = '{%if "" == empty %}"" == empty{%else%}"" != empty{% endif %}'
|
const src = '{%if "" == empty %}"" == empty{%else%}"" != empty{% endif %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
expect(html).to.equal('"" == empty')
|
expect(html).toBe('"" == empty')
|
||||||
})
|
})
|
||||||
it('" " is not empty', async function () {
|
it('" " is not empty', async function () {
|
||||||
const src = '{%if " " == empty %}" " == empty{%else%}" " != empty{% endif %}'
|
const src = '{%if " " == empty %}" " == empty{%else%}" " != empty{% endif %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
expect(html).to.equal('" " != empty')
|
expect(html).toBe('" " != empty')
|
||||||
})
|
})
|
||||||
it('{} is empty', async function () {
|
it('{} is empty', async function () {
|
||||||
const src = '{%if obj == empty %}{} == empty{%else%}{} != empty{% endif %}'
|
const src = '{%if obj == empty %}{} == empty{%else%}{} != empty{% endif %}'
|
||||||
const html = await liquid.parseAndRender(src, { obj: {} })
|
const html = await liquid.parseAndRender(src, { obj: {} })
|
||||||
expect(html).to.equal('{} == empty')
|
expect(html).toBe('{} == empty')
|
||||||
})
|
})
|
||||||
it('{foo: 1} is not empty', async function () {
|
it('{foo: 1} is not empty', async function () {
|
||||||
const src = '{%if obj == empty %}{foo: 1} == empty{%else%}{foo: 1} != empty{% endif %}'
|
const src = '{%if obj == empty %}{foo: 1} == empty{%else%}{foo: 1} != empty{% endif %}'
|
||||||
const html = await liquid.parseAndRender(src, { obj: { foo: 1 } })
|
const html = await liquid.parseAndRender(src, { obj: { foo: 1 } })
|
||||||
expect(html).to.equal('{foo: 1} != empty')
|
expect(html).toBe('{foo: 1} != empty')
|
||||||
})
|
})
|
||||||
it('[] is empty', async function () {
|
it('[] is empty', async function () {
|
||||||
const src = '{%if arr == empty %}[] == empty{%else%}[] != empty{% endif %}'
|
const src = '{%if arr == empty %}[] == empty{%else%}[] != empty{% endif %}'
|
||||||
const html = await liquid.parseAndRender(src, { arr: [] })
|
const html = await liquid.parseAndRender(src, { arr: [] })
|
||||||
expect(html).to.equal('[] == empty')
|
expect(html).toBe('[] == empty')
|
||||||
})
|
})
|
||||||
it('[1] is not empty', async function () {
|
it('[1] is not empty', async function () {
|
||||||
const src = '{%if arr == empty %}[1] == empty{%else%}[1] != empty{% endif %}'
|
const src = '{%if arr == empty %}[1] == empty{%else%}[1] != empty{% endif %}'
|
||||||
const html = await liquid.parseAndRender(src, { arr: [1] })
|
const html = await liquid.parseAndRender(src, { arr: [1] })
|
||||||
expect(html).to.equal('[1] != empty')
|
expect(html).toBe('[1] != empty')
|
||||||
})
|
})
|
||||||
it('1 < empty should be false', async function () {
|
it('1 < empty should be false', async function () {
|
||||||
const src = '{%if 1 < empty %}true{%else%}false{% endif %}'
|
const src = '{%if 1 < empty %}true{%else%}false{% endif %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
expect(html).to.equal('false')
|
expect(html).toBe('false')
|
||||||
})
|
})
|
||||||
it('1 <= empty should be false', async function () {
|
it('1 <= empty should be false', async function () {
|
||||||
const src = '{%if 1 <= empty %}true{%else%}false{% endif %}'
|
const src = '{%if 1 <= empty %}true{%else%}false{% endif %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
expect(html).to.equal('false')
|
expect(html).toBe('false')
|
||||||
})
|
})
|
||||||
it('1 > empty should be false', async function () {
|
it('1 > empty should be false', async function () {
|
||||||
const src = '{%if 1 > empty %}true{%else%}false{% endif %}'
|
const src = '{%if 1 > empty %}true{%else%}false{% endif %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
expect(html).to.equal('false')
|
expect(html).toBe('false')
|
||||||
})
|
})
|
||||||
it('1 >= empty should be false', async function () {
|
it('1 >= empty should be false', async function () {
|
||||||
const src = '{%if 1 >= empty %}true{%else%}false{% endif %}'
|
const src = '{%if 1 >= empty %}true{%else%}false{% endif %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
expect(html).to.equal('false')
|
expect(html).toBe('false')
|
||||||
})
|
})
|
||||||
it('1 == empty should be false', async function () {
|
it('1 == empty should be false', async function () {
|
||||||
const src = '{%if 1 == empty %}true{%else%}false{% endif %}'
|
const src = '{%if 1 == empty %}true{%else%}false{% endif %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
expect(html).to.equal('false')
|
expect(html).toBe('false')
|
||||||
})
|
})
|
||||||
it('1 != empty should be true', async function () {
|
it('1 != empty should be true', async function () {
|
||||||
const src = '{%if 1 != empty %}true{%else%}false{% endif %}'
|
const src = '{%if 1 != empty %}true{%else%}false{% endif %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
expect(html).to.equal('true')
|
expect(html).toBe('true')
|
||||||
})
|
})
|
||||||
it('empty != empty', async function () {
|
it('empty != empty', async function () {
|
||||||
const src = '{%if empty == empty %}true{%else%}false{% endif %}'
|
const src = '{%if empty == empty %}true{%else%}false{% endif %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
expect(html).to.equal('false')
|
expect(html).toBe('false')
|
||||||
})
|
})
|
||||||
it('empty != nil', async function () {
|
it('empty != nil', async function () {
|
||||||
const src = '{%if empty == nil %}true{%else%}false{% endif %}'
|
const src = '{%if empty == nil %}true{%else%}false{% endif %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
expect(html).to.equal('false')
|
expect(html).toBe('false')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,41 +1,40 @@
|
|||||||
import { expect } from 'chai'
|
|
||||||
import { Liquid } from '../../../src/liquid'
|
import { Liquid } from '../../../src/liquid'
|
||||||
|
|
||||||
describe('drop/null-drop', function () {
|
describe('drop/null-drop', function () {
|
||||||
let liquid: Liquid
|
let liquid: Liquid
|
||||||
before(() => (liquid = new Liquid()))
|
beforeEach(() => (liquid = new Liquid()))
|
||||||
|
|
||||||
it('render nil as empty string', async function () {
|
it('render nil as empty string', async function () {
|
||||||
const html = await liquid.parseAndRender('{{nil}}')
|
const html = await liquid.parseAndRender('{{nil}}')
|
||||||
expect(html).to.equal('')
|
expect(html).toBe('')
|
||||||
})
|
})
|
||||||
it('render null as empty string', async function () {
|
it('render null as empty string', async function () {
|
||||||
const html = await liquid.parseAndRender('{{null}}')
|
const html = await liquid.parseAndRender('{{null}}')
|
||||||
expect(html).to.equal('')
|
expect(html).toBe('')
|
||||||
})
|
})
|
||||||
it('undefined == null', async function () {
|
it('undefined == null', async function () {
|
||||||
const src = '{%if foo == nil %}foo == nil{%else%}foo != nil{% endif %}'
|
const src = '{%if foo == nil %}foo == nil{%else%}foo != nil{% endif %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
expect(html).to.equal('foo == nil')
|
expect(html).toBe('foo == nil')
|
||||||
})
|
})
|
||||||
it('nil != blank', async function () {
|
it('nil != blank', async function () {
|
||||||
const src = '{%if nil == blank %}eq{%else%}neq{% endif %}'
|
const src = '{%if nil == blank %}eq{%else%}neq{% endif %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
expect(html).to.equal('neq')
|
expect(html).toBe('neq')
|
||||||
})
|
})
|
||||||
it('nil != empty', async function () {
|
it('nil != empty', async function () {
|
||||||
const src = '{%if nil == empty %}eq{%else%}neq{% endif %}'
|
const src = '{%if nil == empty %}eq{%else%}neq{% endif %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
expect(html).to.equal('neq')
|
expect(html).toBe('neq')
|
||||||
})
|
})
|
||||||
it('0 != null', async function () {
|
it('0 != null', async function () {
|
||||||
const src = '{%if 0 == null %}0 == null{%else%}0 != null{% endif %}'
|
const src = '{%if 0 == null %}0 == null{%else%}0 != null{% endif %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
expect(html).to.equal('0 != null')
|
expect(html).toBe('0 != null')
|
||||||
})
|
})
|
||||||
it('nil == null', async function () {
|
it('nil == null', async function () {
|
||||||
const src = '{%if nil == null %}nil == null{%else%}nil != null{% endif %}'
|
const src = '{%if nil == null %}nil == null{%else%}nil != null{% endif %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
expect(html).to.equal('nil == null')
|
expect(html).toBe('nil == null')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,7 +1,4 @@
|
|||||||
import { test, render } from '../../stub/render'
|
import { test, render } from '../../stub/render'
|
||||||
import { expect, use } from 'chai'
|
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
use(chaiAsPromised)
|
|
||||||
|
|
||||||
describe('filters/array', function () {
|
describe('filters/array', function () {
|
||||||
describe('index', function () {
|
describe('index', function () {
|
||||||
@@ -25,7 +22,7 @@ describe('filters/array', function () {
|
|||||||
it('should throw when comma missing', async () => {
|
it('should throw when comma missing', async () => {
|
||||||
const src = '{% assign beatles = "John, Paul, George, Ringo" | split: ", " %}' +
|
const src = '{% assign beatles = "John, Paul, George, Ringo" | split: ", " %}' +
|
||||||
'{{ beatles | join " and " }}'
|
'{{ beatles | join " and " }}'
|
||||||
return expect(render(src)).to.be.rejectedWith('unexpected token at "\\" and \\"", line:1, col:65')
|
return expect(render(src)).rejects.toThrow('unexpected token at "\\" and \\"", line:1, col:65')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('last', () => {
|
describe('last', () => {
|
||||||
@@ -104,7 +101,7 @@ describe('filters/array', function () {
|
|||||||
const scope = { arr: ['a', 'b', 'c'] }
|
const scope = { arr: ['a', 'b', 'c'] }
|
||||||
await render('{{ arr | reverse | join: "" }}', scope)
|
await render('{{ arr | reverse | join: "" }}', scope)
|
||||||
const html = await render('{{ arr | join: "" }}', scope)
|
const html = await render('{{ arr | join: "" }}', scope)
|
||||||
expect(html).to.equal('abc')
|
expect(html).toBe('abc')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('size', function () {
|
describe('size', function () {
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
import { test } from '../../stub/render'
|
import { test } from '../../stub/render'
|
||||||
import { expect } from 'chai'
|
|
||||||
import { Liquid } from '../../../src/liquid'
|
import { Liquid } from '../../../src/liquid'
|
||||||
|
|
||||||
describe('filters/html', function () {
|
describe('filters/html', function () {
|
||||||
@@ -50,24 +49,24 @@ describe('filters/html', function () {
|
|||||||
'Ulysses?')
|
'Ulysses?')
|
||||||
})
|
})
|
||||||
it('should strip multiline comments', function () {
|
it('should strip multiline comments', function () {
|
||||||
expect(liquid.parseAndRenderSync('{{"<!--foo\r\nbar \ncoo\t \r\n -->"|strip_html}}')).to.equal('')
|
expect(liquid.parseAndRenderSync('{{"<!--foo\r\nbar \ncoo\t \r\n -->"|strip_html}}')).toBe('')
|
||||||
})
|
})
|
||||||
it('should strip all style tags and their contents', function () {
|
it('should strip all style tags and their contents', function () {
|
||||||
return test('{{ "<style>cite { font-style: italic; }</style><cite>Ulysses<cite>?" | strip_html }}',
|
return test('{{ "<style>cite { font-style: italic; }</style><cite>Ulysses<cite>?" | strip_html }}',
|
||||||
'Ulysses?')
|
'Ulysses?')
|
||||||
})
|
})
|
||||||
it('should strip multiline styles', function () {
|
it('should strip multiline styles', function () {
|
||||||
expect(liquid.parseAndRenderSync('{{"<style> \n.header {\r\n color: black;\r\n}\n</style>" | strip_html}}')).to.equal('')
|
expect(liquid.parseAndRenderSync('{{"<style> \n.header {\r\n color: black;\r\n}\n</style>" | strip_html}}')).toBe('')
|
||||||
})
|
})
|
||||||
it('should strip all scripts tags and their contents', function () {
|
it('should strip all scripts tags and their contents', function () {
|
||||||
return test('{{ "<script async>console.log(\'hello world\')</script><cite>Ulysses<cite>?" | strip_html }}',
|
return test('{{ "<script async>console.log(\'hello world\')</script><cite>Ulysses<cite>?" | strip_html }}',
|
||||||
'Ulysses?')
|
'Ulysses?')
|
||||||
})
|
})
|
||||||
it('should strip multiline scripts', function () {
|
it('should strip multiline scripts', function () {
|
||||||
expect(liquid.parseAndRenderSync('{{ "<script> \nfoo\r\nbar\n</script>" | strip_html }}')).to.equal('')
|
expect(liquid.parseAndRenderSync('{{ "<script> \nfoo\r\nbar\n</script>" | strip_html }}')).toBe('')
|
||||||
})
|
})
|
||||||
it('should not strip non-matched <script>', function () {
|
it('should not strip non-matched <script>', function () {
|
||||||
expect(liquid.parseAndRenderSync('{{ "<script></script>text<script></script>" | strip_html }}')).to.equal('text')
|
expect(liquid.parseAndRenderSync('{{ "<script></script>text<script></script>" | strip_html }}')).toBe('text')
|
||||||
})
|
})
|
||||||
it('should strip until empty', function () {
|
it('should strip until empty', function () {
|
||||||
return test('{{"<br/><br />< p ></p></ p >" | strip_html }}', '')
|
return test('{{"<br/><br />< p ></p></ p >" | strip_html }}', '')
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
import { expect } from 'chai'
|
|
||||||
import { test, liquid } from '../../stub/render'
|
import { test, liquid } from '../../stub/render'
|
||||||
|
|
||||||
describe('filters/math', function () {
|
describe('filters/math', function () {
|
||||||
@@ -48,7 +47,7 @@ describe('filters/math', function () {
|
|||||||
it('should return "3" for 24,7', () => test('{{ 24 | modulo: 7 }}', '3'))
|
it('should return "3" for 24,7', () => test('{{ 24 | modulo: 7 }}', '3'))
|
||||||
it('should return "3.357" for 183.357,12', async () => {
|
it('should return "3.357" for 183.357,12', async () => {
|
||||||
const html = await liquid.parseAndRender('{{ 183.357 | modulo: 12 }}')
|
const html = await liquid.parseAndRender('{{ 183.357 | modulo: 12 }}')
|
||||||
expect(Number(html)).to.be.closeTo(3.357, 0.001)
|
expect(Number(html)).toBeCloseTo(3.357, 3)
|
||||||
})
|
})
|
||||||
it('should convert string', () => test('{{ "24" | modulo: "7" }}', '3'))
|
it('should convert string', () => test('{{ "24" | modulo: "7" }}', '3'))
|
||||||
})
|
})
|
||||||
@@ -1,32 +1,28 @@
|
|||||||
import { Liquid } from '../../../src/liquid'
|
import { Liquid } from '../../../src/liquid'
|
||||||
import { expect, use } from 'chai'
|
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
|
|
||||||
use(chaiAsPromised)
|
|
||||||
|
|
||||||
describe('filters/object', function () {
|
describe('filters/object', function () {
|
||||||
const liquid = new Liquid()
|
const liquid = new Liquid()
|
||||||
describe('default', function () {
|
describe('default', function () {
|
||||||
it('false should use default', async () => expect(await liquid.parseAndRender('{{false | default: "a"}}')).to.equal('a'))
|
it('false should use default', async () => expect(await liquid.parseAndRender('{{false | default: "a"}}')).toBe('a'))
|
||||||
it('empty string should use default', async () => expect(await liquid.parseAndRender('{{"" | default: "a"}}')).to.equal('a'))
|
it('empty string should use default', async () => expect(await liquid.parseAndRender('{{"" | default: "a"}}')).toBe('a'))
|
||||||
it('empty array should use default', async () => expect(await liquid.parseAndRender('{{arr | default: "a"}}', { arr: [] })).to.equal('a'))
|
it('empty array should use default', async () => expect(await liquid.parseAndRender('{{arr | default: "a"}}', { arr: [] })).toBe('a'))
|
||||||
it('non-empty string should not use default', async () => expect(await liquid.parseAndRender('{{" " | default: "a"}}')).to.equal(' '))
|
it('non-empty string should not use default', async () => expect(await liquid.parseAndRender('{{" " | default: "a"}}')).toBe(' '))
|
||||||
it('nil should use default', async () => expect(await liquid.parseAndRender('{{nil | default: "a"}}')).to.equal('a'))
|
it('nil should use default', async () => expect(await liquid.parseAndRender('{{nil | default: "a"}}')).toBe('a'))
|
||||||
it('undefined should use default', async () => expect(await liquid.parseAndRender('{{not_defined | default: "a"}}')).to.equal('a'))
|
it('undefined should use default', async () => expect(await liquid.parseAndRender('{{not_defined | default: "a"}}')).toBe('a'))
|
||||||
it('true should not use default', async () => expect(await liquid.parseAndRender('{{true | default: "a"}}')).to.equal('true'))
|
it('true should not use default', async () => expect(await liquid.parseAndRender('{{true | default: "a"}}')).toBe('true'))
|
||||||
it('0 should not use default', async () => expect(await liquid.parseAndRender('{{0 | default: "a"}}')).to.equal('0'))
|
it('0 should not use default', async () => expect(await liquid.parseAndRender('{{0 | default: "a"}}')).toBe('0'))
|
||||||
it('should output false when allow_false=true', async () => expect(await liquid.parseAndRender('{{false | default: true, allow_false: true}}')).to.equal('false'))
|
it('should output false when allow_false=true', async () => expect(await liquid.parseAndRender('{{false | default: true, allow_false: true}}')).toBe('false'))
|
||||||
it('should output default without allow_false', async () => expect(await liquid.parseAndRender('{{false | default: true}}')).to.equal('true'))
|
it('should output default without allow_false', async () => expect(await liquid.parseAndRender('{{false | default: true}}')).toBe('true'))
|
||||||
it('should output default when allow_false=false', async () => expect(await liquid.parseAndRender('{{false | default: true, allow_false: false}}')).to.equal('true'))
|
it('should output default when allow_false=false', async () => expect(await liquid.parseAndRender('{{false | default: true, allow_false: false}}')).toBe('true'))
|
||||||
it('should throw for additional args', () => {
|
it('should throw for additional args', () => {
|
||||||
const src = `{{ age | default: 'now' date: '%d'}}` // missing `|` before `date`
|
const src = `{{ age | default: 'now' date: '%d'}}` // missing `|` before `date`
|
||||||
return expect(liquid.parseAndRender(src)).to.be.rejectedWith(/unexpected character "date: '%d'"/)
|
return expect(liquid.parseAndRender(src)).rejects.toThrow(/unexpected character "date: '%d'"/)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('json', function () {
|
describe('json', function () {
|
||||||
it('should stringify string', async () => expect(await liquid.parseAndRender('{{"foo" | json}}')).to.equal('"foo"'))
|
it('should stringify string', async () => expect(await liquid.parseAndRender('{{"foo" | json}}')).toBe('"foo"'))
|
||||||
it('should stringify number', async () => expect(await liquid.parseAndRender('{{2 | json}}')).to.equal('2'))
|
it('should stringify number', async () => expect(await liquid.parseAndRender('{{2 | json}}')).toBe('2'))
|
||||||
it('should stringify object', async () => expect(await liquid.parseAndRender('{{obj | json}}', { obj: { foo: 'bar' } })).to.equal('{"foo":"bar"}'))
|
it('should stringify object', async () => expect(await liquid.parseAndRender('{{obj | json}}', { obj: { foo: 'bar' } })).toBe('{"foo":"bar"}'))
|
||||||
it('should stringify array', async () => expect(await liquid.parseAndRender('{{arr | json}}', { arr: [-2, 'a'] })).to.equal('[-2,"a"]'))
|
it('should stringify array', async () => expect(await liquid.parseAndRender('{{arr | json}}', { arr: [-2, 'a'] })).toBe('[-2,"a"]'))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,8 +1,4 @@
|
|||||||
import { test } from '../../stub/render'
|
import { test } from '../../stub/render'
|
||||||
import { expect, use } from 'chai'
|
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
|
|
||||||
use(chaiAsPromised)
|
|
||||||
|
|
||||||
describe('filters/string', function () {
|
describe('filters/string', function () {
|
||||||
describe('append', function () {
|
describe('append', function () {
|
||||||
@@ -10,7 +6,7 @@ describe('filters/string', function () {
|
|||||||
() => test('{{ -3 | append: "abc" }}', '-3abc'))
|
() => test('{{ -3 | append: "abc" }}', '-3abc'))
|
||||||
it('should return "abar" for "a", foo', () => test('{{ "a" | append: foo }}', { foo: 'bar' }, 'abar'))
|
it('should return "abar" for "a", foo', () => test('{{ "a" | append: foo }}', { foo: 'bar' }, 'abar'))
|
||||||
it('should throw if second argument not set', () => {
|
it('should throw if second argument not set', () => {
|
||||||
return expect(test('{{ "abc" | append }}', 'abc')).to.be.rejectedWith(/2 arguments/)
|
return expect(test('{{ "abc" | append }}', 'abc')).rejects.toThrow(/2 arguments/)
|
||||||
})
|
})
|
||||||
it('should return "abcfalse" for "abc", false', () => test('{{ "abc" | append: false }}', 'abcfalse'))
|
it('should return "abcfalse" for "abc", false', () => test('{{ "abc" | append: false }}', 'abcfalse'))
|
||||||
})
|
})
|
||||||
@@ -19,7 +15,7 @@ describe('filters/string', function () {
|
|||||||
() => test('{{ -3 | prepend: "abc" }}', 'abc-3'))
|
() => test('{{ -3 | prepend: "abc" }}', 'abc-3'))
|
||||||
it('should return "abar" for "a", foo', () => test('{{ "a" | prepend: foo }}', { foo: 'bar' }, 'bara'))
|
it('should return "abar" for "a", foo', () => test('{{ "a" | prepend: foo }}', { foo: 'bar' }, 'bara'))
|
||||||
it('should throw if second argument not set', () => {
|
it('should throw if second argument not set', () => {
|
||||||
return expect(test('{{ "abc" | prepend }}', 'abc')).to.be.rejectedWith(/2 arguments/)
|
return expect(test('{{ "abc" | prepend }}', 'abc')).rejects.toThrow(/2 arguments/)
|
||||||
})
|
})
|
||||||
it('should return "falseabc" for "abc", false', () => test('{{ "abc" | prepend: false }}', 'falseabc'))
|
it('should return "falseabc" for "abc", false', () => test('{{ "abc" | prepend: false }}', 'falseabc'))
|
||||||
})
|
})
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { expect } from 'chai'
|
import { Liquid } from '../../../src/liquid'
|
||||||
import { Liquid, Template } from '../../../src/liquid'
|
|
||||||
import { mock, restore } from '../../stub/mockfs'
|
import { mock, restore } from '../../stub/mockfs'
|
||||||
|
import { Template } from '../../../src/template'
|
||||||
|
|
||||||
describe('LiquidOptions#cache', function () {
|
describe('LiquidOptions#cache', function () {
|
||||||
afterEach(restore)
|
afterEach(restore)
|
||||||
@@ -13,10 +13,10 @@ describe('LiquidOptions#cache', function () {
|
|||||||
})
|
})
|
||||||
mock({ '/root/files/foo.html': 'foo' })
|
mock({ '/root/files/foo.html': 'foo' })
|
||||||
const x = await engine.renderFile('files/foo')
|
const x = await engine.renderFile('files/foo')
|
||||||
expect(x).to.equal('foo')
|
expect(x).toBe('foo')
|
||||||
mock({ '/root/files/foo.html': 'bar' })
|
mock({ '/root/files/foo.html': 'bar' })
|
||||||
const y = await engine.renderFile('files/foo')
|
const y = await engine.renderFile('files/foo')
|
||||||
expect(y).to.equal('bar')
|
expect(y).toBe('bar')
|
||||||
})
|
})
|
||||||
it('should be disabled when cache <= 0', async function () {
|
it('should be disabled when cache <= 0', async function () {
|
||||||
const engine = new Liquid({
|
const engine = new Liquid({
|
||||||
@@ -26,10 +26,10 @@ describe('LiquidOptions#cache', function () {
|
|||||||
})
|
})
|
||||||
mock({ '/root/files/foo.html': 'foo' })
|
mock({ '/root/files/foo.html': 'foo' })
|
||||||
const x = await engine.renderFile('files/foo')
|
const x = await engine.renderFile('files/foo')
|
||||||
expect(x).to.equal('foo')
|
expect(x).toBe('foo')
|
||||||
mock({ '/root/files/foo.html': 'bar' })
|
mock({ '/root/files/foo.html': 'bar' })
|
||||||
const y = await engine.renderFile('files/foo')
|
const y = await engine.renderFile('files/foo')
|
||||||
expect(y).to.equal('bar')
|
expect(y).toBe('bar')
|
||||||
})
|
})
|
||||||
it('should respect cache=true option', async function () {
|
it('should respect cache=true option', async function () {
|
||||||
const engine = new Liquid({
|
const engine = new Liquid({
|
||||||
@@ -39,10 +39,10 @@ describe('LiquidOptions#cache', function () {
|
|||||||
})
|
})
|
||||||
mock({ '/root/files/foo.html': 'foo' })
|
mock({ '/root/files/foo.html': 'foo' })
|
||||||
const x = await engine.renderFile('files/foo')
|
const x = await engine.renderFile('files/foo')
|
||||||
expect(x).to.equal('foo')
|
expect(x).toBe('foo')
|
||||||
mock({ '/root/files/foo.html': 'bar' })
|
mock({ '/root/files/foo.html': 'bar' })
|
||||||
const y = await engine.renderFile('files/foo')
|
const y = await engine.renderFile('files/foo')
|
||||||
expect(y).to.equal('foo')
|
expect(y).toBe('foo')
|
||||||
})
|
})
|
||||||
it('should respect cache=2 option', async function () {
|
it('should respect cache=2 option', async function () {
|
||||||
const engine = new Liquid({
|
const engine = new Liquid({
|
||||||
@@ -57,12 +57,12 @@ describe('LiquidOptions#cache', function () {
|
|||||||
mock({ '/root/files/foo.html': 'FOO' })
|
mock({ '/root/files/foo.html': 'FOO' })
|
||||||
await engine.renderFile('files/bar')
|
await engine.renderFile('files/bar')
|
||||||
const x = await engine.renderFile('files/foo')
|
const x = await engine.renderFile('files/foo')
|
||||||
expect(x).to.equal('foo')
|
expect(x).toBe('foo')
|
||||||
|
|
||||||
await engine.renderFile('files/bar')
|
await engine.renderFile('files/bar')
|
||||||
await engine.renderFile('files/coo')
|
await engine.renderFile('files/coo')
|
||||||
const y = await engine.renderFile('files/foo')
|
const y = await engine.renderFile('files/foo')
|
||||||
expect(y).to.equal('FOO')
|
expect(y).toBe('FOO')
|
||||||
})
|
})
|
||||||
it('should respect cache={read, write} option', async function () {
|
it('should respect cache={read, write} option', async function () {
|
||||||
let last: Template[] | undefined
|
let last: Template[] | undefined
|
||||||
@@ -70,6 +70,7 @@ describe('LiquidOptions#cache', function () {
|
|||||||
root: '/root/',
|
root: '/root/',
|
||||||
extname: '.html',
|
extname: '.html',
|
||||||
cache: {
|
cache: {
|
||||||
|
remove: () => void (0),
|
||||||
read: (): Template[] | undefined => last,
|
read: (): Template[] | undefined => last,
|
||||||
write: (key: string, value: Template[]) => { last = value }
|
write: (key: string, value: Template[]) => { last = value }
|
||||||
}
|
}
|
||||||
@@ -77,9 +78,9 @@ describe('LiquidOptions#cache', function () {
|
|||||||
mock({ '/root/files/foo.html': 'foo' })
|
mock({ '/root/files/foo.html': 'foo' })
|
||||||
mock({ '/root/files/bar.html': 'bar' })
|
mock({ '/root/files/bar.html': 'bar' })
|
||||||
mock({ '/root/files/coo.html': 'coo' })
|
mock({ '/root/files/coo.html': 'coo' })
|
||||||
expect(await engine.renderFile('files/foo')).to.equal('foo')
|
expect(await engine.renderFile('files/foo')).toBe('foo')
|
||||||
expect(await engine.renderFile('files/bar')).to.equal('foo')
|
expect(await engine.renderFile('files/bar')).toBe('foo')
|
||||||
expect(await engine.renderFile('files/coo')).to.equal('foo')
|
expect(await engine.renderFile('files/coo')).toBe('foo')
|
||||||
})
|
})
|
||||||
it('should respect cache={ async read, async write } option', async function () {
|
it('should respect cache={ async read, async write } option', async function () {
|
||||||
const cached: { [key: string]: Template[] | undefined } = {}
|
const cached: { [key: string]: Template[] | undefined } = {}
|
||||||
@@ -87,6 +88,7 @@ describe('LiquidOptions#cache', function () {
|
|||||||
root: '/root/',
|
root: '/root/',
|
||||||
extname: '.html',
|
extname: '.html',
|
||||||
cache: {
|
cache: {
|
||||||
|
remove: (key: string) => { delete cached[key] },
|
||||||
read: (key: string) => Promise.resolve(cached[key]),
|
read: (key: string) => Promise.resolve(cached[key]),
|
||||||
write: (key: string, value: Template[]) => { cached[key] = value; Promise.resolve() }
|
write: (key: string, value: Template[]) => { cached[key] = value; Promise.resolve() }
|
||||||
}
|
}
|
||||||
@@ -94,11 +96,11 @@ describe('LiquidOptions#cache', function () {
|
|||||||
mock({ '/root/files/foo.html': 'foo' })
|
mock({ '/root/files/foo.html': 'foo' })
|
||||||
mock({ '/root/files/bar.html': 'bar' })
|
mock({ '/root/files/bar.html': 'bar' })
|
||||||
mock({ '/root/files/coo.html': 'coo' })
|
mock({ '/root/files/coo.html': 'coo' })
|
||||||
expect(await engine.renderFile('files/foo')).to.equal('foo')
|
expect(await engine.renderFile('files/foo')).toBe('foo')
|
||||||
expect(await engine.renderFile('files/bar')).to.equal('bar')
|
expect(await engine.renderFile('files/bar')).toBe('bar')
|
||||||
expect(await engine.renderFile('files/coo')).to.equal('coo')
|
expect(await engine.renderFile('files/coo')).toBe('coo')
|
||||||
mock({ '/root/files/coo.html': 'COO' })
|
mock({ '/root/files/coo.html': 'COO' })
|
||||||
expect(await engine.renderFile('files/coo')).to.equal('coo')
|
expect(await engine.renderFile('files/coo')).toBe('coo')
|
||||||
})
|
})
|
||||||
it('should handle concurrent cache read/write', async function () {
|
it('should handle concurrent cache read/write', async function () {
|
||||||
const engine = new Liquid({
|
const engine = new Liquid({
|
||||||
@@ -115,10 +117,10 @@ describe('LiquidOptions#cache', function () {
|
|||||||
engine.renderFile('files/bar'),
|
engine.renderFile('files/bar'),
|
||||||
engine.renderFile('files/coo')
|
engine.renderFile('files/coo')
|
||||||
])
|
])
|
||||||
expect(foo1).to.equal('foo')
|
expect(foo1).toBe('foo')
|
||||||
expect(foo2).to.equal('foo')
|
expect(foo2).toBe('foo')
|
||||||
expect(bar).to.equal('bar')
|
expect(bar).toBe('bar')
|
||||||
expect(coo).to.equal('coo')
|
expect(coo).toBe('coo')
|
||||||
})
|
})
|
||||||
it('should not cache not exist file', async function () {
|
it('should not cache not exist file', async function () {
|
||||||
const engine = new Liquid({
|
const engine = new Liquid({
|
||||||
@@ -132,7 +134,7 @@ describe('LiquidOptions#cache', function () {
|
|||||||
|
|
||||||
mock({ '/root/foo.html': 'foo' })
|
mock({ '/root/foo.html': 'foo' })
|
||||||
const html = await engine.renderFile('foo')
|
const html = await engine.renderFile('foo')
|
||||||
expect(html).to.equal('foo')
|
expect(html).toBe('foo')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -144,11 +146,11 @@ describe('LiquidOptions#cache', function () {
|
|||||||
})
|
})
|
||||||
mock({ '/root/foo.html': 'foo' })
|
mock({ '/root/foo.html': 'foo' })
|
||||||
const x = engine.renderFileSync('foo')
|
const x = engine.renderFileSync('foo')
|
||||||
expect(x).to.equal('foo')
|
expect(x).toBe('foo')
|
||||||
|
|
||||||
mock({ '/root/foo.html': 'bar' })
|
mock({ '/root/foo.html': 'bar' })
|
||||||
const y = engine.renderFileSync('foo')
|
const y = engine.renderFileSync('foo')
|
||||||
expect(y).to.equal('bar')
|
expect(y).toBe('bar')
|
||||||
})
|
})
|
||||||
it('should respect cache=true option', function () {
|
it('should respect cache=true option', function () {
|
||||||
const engine = new Liquid({
|
const engine = new Liquid({
|
||||||
@@ -157,9 +159,9 @@ describe('LiquidOptions#cache', function () {
|
|||||||
cache: true
|
cache: true
|
||||||
})
|
})
|
||||||
mock({ '/root/foo.html': 'foo' })
|
mock({ '/root/foo.html': 'foo' })
|
||||||
expect(engine.renderFileSync('foo')).to.equal('foo')
|
expect(engine.renderFileSync('foo')).toBe('foo')
|
||||||
mock({ '/root/foo.html': 'bar' })
|
mock({ '/root/foo.html': 'bar' })
|
||||||
expect(engine.renderFileSync('foo')).to.equal('foo')
|
expect(engine.renderFileSync('foo')).toBe('foo')
|
||||||
})
|
})
|
||||||
it('should not cache not exist file', async function () {
|
it('should not cache not exist file', async function () {
|
||||||
const engine = new Liquid({
|
const engine = new Liquid({
|
||||||
@@ -171,7 +173,7 @@ describe('LiquidOptions#cache', function () {
|
|||||||
|
|
||||||
mock({ '/root/foo.html': 'foo' })
|
mock({ '/root/foo.html': 'foo' })
|
||||||
const y = await engine.renderFile('foo')
|
const y = await engine.renderFile('foo')
|
||||||
expect(y).to.equal('foo')
|
expect(y).toBe('foo')
|
||||||
})
|
})
|
||||||
it('should cache relative referenced files properly', async function () {
|
it('should cache relative referenced files properly', async function () {
|
||||||
const engine = new Liquid({
|
const engine = new Liquid({
|
||||||
@@ -186,10 +188,10 @@ describe('LiquidOptions#cache', function () {
|
|||||||
'/root/another/bar.html': 'bar2'
|
'/root/another/bar.html': 'bar2'
|
||||||
})
|
})
|
||||||
const foo1 = await engine.renderFile('foo')
|
const foo1 = await engine.renderFile('foo')
|
||||||
expect(foo1).to.equal('bar1')
|
expect(foo1).toBe('bar1')
|
||||||
|
|
||||||
const foo2 = await engine.renderFile('another/foo')
|
const foo2 = await engine.renderFile('another/foo')
|
||||||
expect(foo2).to.equal('bar2')
|
expect(foo2).toBe('bar2')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
import { expect } from 'chai'
|
|
||||||
import { Liquid } from '../../../src/liquid'
|
import { Liquid } from '../../../src/liquid'
|
||||||
|
|
||||||
describe('LiquidOptions#*_delimiter_*', function () {
|
describe('LiquidOptions#*_delimiter_*', function () {
|
||||||
@@ -8,7 +7,7 @@ describe('LiquidOptions#*_delimiter_*', function () {
|
|||||||
tagDelimiterRight: '%>'
|
tagDelimiterRight: '%>'
|
||||||
})
|
})
|
||||||
const html = await engine.parseAndRender('<%=if true%>foo<%=endif%> ')
|
const html = await engine.parseAndRender('<%=if true%>foo<%=endif%> ')
|
||||||
return expect(html).to.equal('foo ')
|
return expect(html).toBe('foo ')
|
||||||
})
|
})
|
||||||
it('should respect output_delimiter_*', async function () {
|
it('should respect output_delimiter_*', async function () {
|
||||||
const engine = new Liquid({
|
const engine = new Liquid({
|
||||||
@@ -16,7 +15,7 @@ describe('LiquidOptions#*_delimiter_*', function () {
|
|||||||
outputDelimiterRight: '>>'
|
outputDelimiterRight: '>>'
|
||||||
})
|
})
|
||||||
const html = await engine.parseAndRender('<< "liquid" | capitalize >>')
|
const html = await engine.parseAndRender('<< "liquid" | capitalize >>')
|
||||||
return expect(html).to.equal('Liquid')
|
return expect(html).toBe('Liquid')
|
||||||
})
|
})
|
||||||
it('should support trimming with tag_delimiter_* set', async function () {
|
it('should support trimming with tag_delimiter_* set', async function () {
|
||||||
const engine = new Liquid({
|
const engine = new Liquid({
|
||||||
@@ -26,6 +25,6 @@ describe('LiquidOptions#*_delimiter_*', function () {
|
|||||||
trimTagRight: true
|
trimTagRight: true
|
||||||
})
|
})
|
||||||
const html = await engine.parseAndRender(' <%=if true%> \tfoo\t <%=endif%> ')
|
const html = await engine.parseAndRender(' <%=if true%> \tfoo\t <%=endif%> ')
|
||||||
return expect(html).to.equal('foo')
|
return expect(html).toBe('foo')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
import { expect, use } from 'chai'
|
|
||||||
import { Liquid } from '../../../src/liquid'
|
import { Liquid } from '../../../src/liquid'
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
use(chaiAsPromised)
|
|
||||||
|
|
||||||
describe('LiquidOptions#fs', function () {
|
describe('LiquidOptions#fs', function () {
|
||||||
let engine: Liquid
|
let engine: Liquid
|
||||||
const fs = {
|
const fs = {
|
||||||
|
sep: '/',
|
||||||
|
dirname: (x: string) => x.split('/').slice(0, -1).join('/'),
|
||||||
exists: (x: string) => Promise.resolve(!x.match(/not-exist/)),
|
exists: (x: string) => Promise.resolve(!x.match(/not-exist/)),
|
||||||
existsSync: (x: string) => !x.match(/not-exist/),
|
existsSync: (x: string) => !x.match(/not-exist/),
|
||||||
readFile: (x: string) => Promise.resolve(`content for ${x}`),
|
readFile: (x: string) => Promise.resolve(`content for ${x}`),
|
||||||
@@ -21,17 +20,17 @@ describe('LiquidOptions#fs', function () {
|
|||||||
})
|
})
|
||||||
it('should be used to read templates', async function () {
|
it('should be used to read templates', async function () {
|
||||||
const html = await engine.renderFile('files/foo')
|
const html = await engine.renderFile('files/foo')
|
||||||
expect(html).to.equal('content for /root/files/foo')
|
expect(html).toBe('content for /root/files/foo')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support fallback', async function () {
|
it('should support fallback', async function () {
|
||||||
const html = await engine.renderFile('not-exist/foo')
|
const html = await engine.renderFile('not-exist/foo')
|
||||||
expect(html).to.equal('content for /root/files/fallback')
|
expect(html).toBe('content for /root/files/fallback')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support renderSync', function () {
|
it('should support renderSync', function () {
|
||||||
const html = engine.renderFileSync('not-exist/foo')
|
const html = engine.renderFileSync('not-exist/foo')
|
||||||
expect(html).to.equal('content for /root/files/fallback')
|
expect(html).toBe('content for /root/files/fallback')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should throw lookup failure if fallback not specified', function () {
|
it('should throw lookup failure if fallback not specified', function () {
|
||||||
@@ -40,6 +39,14 @@ describe('LiquidOptions#fs', function () {
|
|||||||
fs: { ...fs, fallback: undefined }
|
fs: { ...fs, fallback: undefined }
|
||||||
} as any)
|
} as any)
|
||||||
return expect(engine.renderFile('not-exist/foo'))
|
return expect(engine.renderFile('not-exist/foo'))
|
||||||
.to.be.rejectedWith('Failed to lookup')
|
.rejects.toThrow('Failed to lookup')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should disable relativeReference if `sep` and `dirname` not specified', function () {
|
||||||
|
const engine = new Liquid({
|
||||||
|
root: '/root/',
|
||||||
|
fs: { ...fs, sep: undefined, dirname: undefined }
|
||||||
|
} as any)
|
||||||
|
expect(engine.options.relativeReference).toBe(false)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
+8
-9
@@ -1,4 +1,3 @@
|
|||||||
import { expect } from 'chai'
|
|
||||||
import { Liquid } from '../../../src/liquid'
|
import { Liquid } from '../../../src/liquid'
|
||||||
|
|
||||||
describe('LiquidOptions#*keepOutputType*', function () {
|
describe('LiquidOptions#*keepOutputType*', function () {
|
||||||
@@ -12,13 +11,13 @@ describe('LiquidOptions#*keepOutputType*', function () {
|
|||||||
'my-string': 'test'
|
'my-string': 'test'
|
||||||
}
|
}
|
||||||
const booleanHtml = await engine.parseAndRender('{{my-boolean}}', context)
|
const booleanHtml = await engine.parseAndRender('{{my-boolean}}', context)
|
||||||
expect(booleanHtml).to.equal(true)
|
expect(booleanHtml).toBe(true)
|
||||||
const numberHtml = await engine.parseAndRender('{{my-number}}', context)
|
const numberHtml = await engine.parseAndRender('{{my-number}}', context)
|
||||||
expect(numberHtml).to.equal(42)
|
expect(numberHtml).toBe(42)
|
||||||
const html = await engine.parseAndRender('{{my-string}}', context)
|
const html = await engine.parseAndRender('{{my-string}}', context)
|
||||||
expect(html).to.equal('test')
|
expect(html).toBe('test')
|
||||||
const composedHtml = await engine.parseAndRender('{{my-string}}:{{my-number}}', context)
|
const composedHtml = await engine.parseAndRender('{{my-string}}:{{my-number}}', context)
|
||||||
expect(composedHtml).to.equal('test:42')
|
expect(composedHtml).toBe('test:42')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should respect keepOutputType = false as default', async function () {
|
it('should respect keepOutputType = false as default', async function () {
|
||||||
@@ -29,12 +28,12 @@ describe('LiquidOptions#*keepOutputType*', function () {
|
|||||||
'my-string': 'test'
|
'my-string': 'test'
|
||||||
}
|
}
|
||||||
const booleanHtml = await engine.parseAndRender('{{my-boolean}}', context)
|
const booleanHtml = await engine.parseAndRender('{{my-boolean}}', context)
|
||||||
expect(booleanHtml).to.equal('true')
|
expect(booleanHtml).toBe('true')
|
||||||
const numberHtml = await engine.parseAndRender('{{my-number}}', context)
|
const numberHtml = await engine.parseAndRender('{{my-number}}', context)
|
||||||
expect(numberHtml).to.equal('42')
|
expect(numberHtml).toBe('42')
|
||||||
const html = await engine.parseAndRender('{{my-string}}', context)
|
const html = await engine.parseAndRender('{{my-string}}', context)
|
||||||
expect(html).to.equal('test')
|
expect(html).toBe('test')
|
||||||
const composedHtml = await engine.parseAndRender('{{my-string}}:{{my-number}}', context)
|
const composedHtml = await engine.parseAndRender('{{my-string}}:{{my-number}}', context)
|
||||||
expect(composedHtml).to.equal('test:42')
|
expect(composedHtml).toBe('test:42')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,12 +1,7 @@
|
|||||||
import * as chai from 'chai'
|
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
import { Liquid, Context, isFalsy } from '../../../src'
|
import { Liquid, Context, isFalsy } from '../../../src'
|
||||||
import { mock, restore } from '../../stub/mockfs'
|
import { mock, restore } from '../../stub/mockfs'
|
||||||
import { drainStream } from '../../stub/stream'
|
import { drainStream } from '../../stub/stream'
|
||||||
|
|
||||||
const expect = chai.expect
|
|
||||||
chai.use(chaiAsPromised)
|
|
||||||
|
|
||||||
describe('Liquid', function () {
|
describe('Liquid', function () {
|
||||||
describe('#plugin()', function () {
|
describe('#plugin()', function () {
|
||||||
it('should call plugin on the instance', async function () {
|
it('should call plugin on the instance', async function () {
|
||||||
@@ -15,7 +10,7 @@ describe('Liquid', function () {
|
|||||||
this.registerFilter('foo', x => `foo${x}foo`)
|
this.registerFilter('foo', x => `foo${x}foo`)
|
||||||
})
|
})
|
||||||
const html = await engine.parseAndRender('{{"bar"|foo}}')
|
const html = await engine.parseAndRender('{{"bar"|foo}}')
|
||||||
expect(html).to.equal('foobarfoo')
|
expect(html).toBe('foobarfoo')
|
||||||
})
|
})
|
||||||
it('should call plugin with Liquid', async function () {
|
it('should call plugin with Liquid', async function () {
|
||||||
const engine = new Liquid()
|
const engine = new Liquid()
|
||||||
@@ -23,92 +18,92 @@ describe('Liquid', function () {
|
|||||||
this.registerFilter('t', function (v) { return isFalsy(v, this.context) })
|
this.registerFilter('t', function (v) { return isFalsy(v, this.context) })
|
||||||
})
|
})
|
||||||
const html = await engine.parseAndRender('{{false|t}}')
|
const html = await engine.parseAndRender('{{false|t}}')
|
||||||
expect(html).to.equal('true')
|
expect(html).toBe('true')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('#parseAndRender', function () {
|
describe('#parseAndRender', function () {
|
||||||
const engine = new Liquid()
|
const engine = new Liquid()
|
||||||
it('should parse and render variable output', async function () {
|
it('should parse and render variable output', async function () {
|
||||||
const html = await engine.parseAndRender('{{"foo"}}')
|
const html = await engine.parseAndRender('{{"foo"}}')
|
||||||
expect(html).to.equal('foo')
|
expect(html).toBe('foo')
|
||||||
})
|
})
|
||||||
it('should parse and render complex output', async function () {
|
it('should parse and render complex output', async function () {
|
||||||
const tpl = '{{ "Welcome|to]Liquid" | split: "|" | join: "("}}'
|
const tpl = '{{ "Welcome|to]Liquid" | split: "|" | join: "("}}'
|
||||||
const html = await engine.parseAndRender(tpl)
|
const html = await engine.parseAndRender(tpl)
|
||||||
expect(html).to.equal('Welcome(to]Liquid')
|
expect(html).toBe('Welcome(to]Liquid')
|
||||||
})
|
})
|
||||||
it('should support for-in with variable', async function () {
|
it('should support for-in with variable', async function () {
|
||||||
const src = '{% assign total = 3 | minus: 1 %}' +
|
const src = '{% assign total = 3 | minus: 1 %}' +
|
||||||
'{% for i in (1..total) %}{{ i }}{% endfor %}'
|
'{% for i in (1..total) %}{{ i }}{% endfor %}'
|
||||||
const html = await engine.parseAndRender(src, {})
|
const html = await engine.parseAndRender(src, {})
|
||||||
return expect(html).to.equal('12')
|
return expect(html).toBe('12')
|
||||||
})
|
})
|
||||||
it('should support `globals` render option', async function () {
|
it('should support `globals` render option', async function () {
|
||||||
const src = '{{ foo }}'
|
const src = '{{ foo }}'
|
||||||
const html = await engine.parseAndRender(src, {}, { globals: { foo: 'FOO' } })
|
const html = await engine.parseAndRender(src, {}, { globals: { foo: 'FOO' } })
|
||||||
return expect(html).to.equal('FOO')
|
return expect(html).toBe('FOO')
|
||||||
})
|
})
|
||||||
it('should support `strictVariables` render option', function () {
|
it('should support `strictVariables` render option', function () {
|
||||||
const src = '{{ foo }}'
|
const src = '{{ foo }}'
|
||||||
return expect(engine.parseAndRender(src, {}, { strictVariables: true })).rejectedWith(/undefined variable/)
|
return expect(engine.parseAndRender(src, {}, { strictVariables: true })).rejects.toThrow(/undefined variable/)
|
||||||
})
|
})
|
||||||
it('should support async variables in output', async () => {
|
it('should support async variables in output', async () => {
|
||||||
const src = '{{ foo }}'
|
const src = '{{ foo }}'
|
||||||
const html = await engine.parseAndRender(src, { foo: Promise.resolve('FOO') })
|
const html = await engine.parseAndRender(src, { foo: Promise.resolve('FOO') })
|
||||||
expect(html).to.equal('FOO')
|
expect(html).toBe('FOO')
|
||||||
})
|
})
|
||||||
it('should parse and render with Context', async function () {
|
it('should parse and render with Context', async function () {
|
||||||
const html = await engine.parseAndRender('{{foo}}', new Context({ foo: 'FOO' }))
|
const html = await engine.parseAndRender('{{foo}}', new Context({ foo: 'FOO' }))
|
||||||
expect(html).to.equal('FOO')
|
expect(html).toBe('FOO')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('#parseAndRenderSync', function () {
|
describe('#parseAndRenderSync', function () {
|
||||||
const engine = new Liquid()
|
const engine = new Liquid()
|
||||||
it('should parse and render variable output', function () {
|
it('should parse and render variable output', function () {
|
||||||
const html = engine.parseAndRenderSync('{{"foo"}}')
|
const html = engine.parseAndRenderSync('{{"foo"}}')
|
||||||
expect(html).to.equal('foo')
|
expect(html).toBe('foo')
|
||||||
})
|
})
|
||||||
it('should parse and render complex output', function () {
|
it('should parse and render complex output', function () {
|
||||||
const tpl = '{{ "Welcome|to]Liquid" | split: "|" | join: "("}}'
|
const tpl = '{{ "Welcome|to]Liquid" | split: "|" | join: "("}}'
|
||||||
const html = engine.parseAndRenderSync(tpl)
|
const html = engine.parseAndRenderSync(tpl)
|
||||||
expect(html).to.equal('Welcome(to]Liquid')
|
expect(html).toBe('Welcome(to]Liquid')
|
||||||
})
|
})
|
||||||
it('should support for-in with variable', function () {
|
it('should support for-in with variable', function () {
|
||||||
const src = '{% assign total = 3 | minus: 1 %}' +
|
const src = '{% assign total = 3 | minus: 1 %}' +
|
||||||
'{% for i in (1..total) %}{{ i }}{% endfor %}'
|
'{% for i in (1..total) %}{{ i }}{% endfor %}'
|
||||||
const html = engine.parseAndRenderSync(src, {})
|
const html = engine.parseAndRenderSync(src, {})
|
||||||
return expect(html).to.equal('12')
|
return expect(html).toBe('12')
|
||||||
})
|
})
|
||||||
it('should support `globals` render option', function () {
|
it('should support `globals` render option', function () {
|
||||||
const src = '{{ foo }}'
|
const src = '{{ foo }}'
|
||||||
const html = engine.parseAndRenderSync(src, {}, { globals: { foo: 'FOO' } })
|
const html = engine.parseAndRenderSync(src, {}, { globals: { foo: 'FOO' } })
|
||||||
return expect(html).to.equal('FOO')
|
return expect(html).toBe('FOO')
|
||||||
})
|
})
|
||||||
it('should support `strictVariables` render option', function () {
|
it('should support `strictVariables` render option', function () {
|
||||||
const src = '{{ foo }}'
|
const src = '{{ foo }}'
|
||||||
return expect(() => engine.parseAndRenderSync(src, {}, { strictVariables: true })).throw(/undefined variable/)
|
return expect(() => engine.parseAndRenderSync(src, {}, { strictVariables: true })).toThrow(/undefined variable/)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('#express()', function () {
|
describe('#express()', function () {
|
||||||
const liquid = new Liquid({ root: '/root' })
|
const liquid = new Liquid({ root: '/root' })
|
||||||
const render = liquid.express()
|
const render = liquid.express()
|
||||||
before(function () {
|
beforeEach(function () {
|
||||||
mock({
|
mock({
|
||||||
'/root/foo': 'foo'
|
'/root/foo': 'foo'
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
after(restore)
|
afterEach(restore)
|
||||||
it('should render single template', function (done) {
|
it('should render single template', function (done) {
|
||||||
render.call({ root: '/root' }, 'foo', null as any, (err: Error | null, result: string | undefined) => {
|
render.call({ root: '/root' }, 'foo', null as any, (err: Error | null, result: string | undefined) => {
|
||||||
if (err) return done(err)
|
if (err) return done(err)
|
||||||
expect(result).to.equal('foo')
|
expect(result).toBe('foo')
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
it('should render single template with Array-typed root', function (done) {
|
it('should render single template with Array-typed root', function (done) {
|
||||||
render.call({ root: ['/root'] }, 'foo', null as any, (err: Error | null, result: string | undefined) => {
|
render.call({ root: ['/root'] }, 'foo', null as any, (err: Error | null, result: string | undefined) => {
|
||||||
if (err) return done(err)
|
if (err) return done(err)
|
||||||
expect(result).to.equal('foo')
|
expect(result).toBe('foo')
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -119,8 +114,7 @@ describe('Liquid', function () {
|
|||||||
root: ['/boo', '/root/'],
|
root: ['/boo', '/root/'],
|
||||||
extname: '.html'
|
extname: '.html'
|
||||||
})
|
})
|
||||||
return expect(engine.renderFile('/not/exist.html')).to
|
return expect(engine.renderFile('/not/exist.html')).rejects.toThrow(/Failed to lookup "\/not\/exist.html" in "\/boo,\/root\/"/)
|
||||||
.be.rejectedWith(/Failed to lookup "\/not\/exist.html" in "\/boo,\/root\/"/)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('#parseFile', function () {
|
describe('#parseFile', function () {
|
||||||
@@ -129,17 +123,16 @@ describe('Liquid', function () {
|
|||||||
root: ['/boo', '/root/'],
|
root: ['/boo', '/root/'],
|
||||||
extname: '.html'
|
extname: '.html'
|
||||||
})
|
})
|
||||||
return expect(engine.parseFile('/not/exist.html')).to
|
return expect(engine.parseFile('/not/exist.html')).rejects.toThrow(/Failed to lookup "\/not\/exist.html" in "\/boo,\/root\/"/)
|
||||||
.be.rejectedWith(/Failed to lookup "\/not\/exist.html" in "\/boo,\/root\/"/)
|
|
||||||
})
|
})
|
||||||
it('should fallback to require.resolve in Node.js', async function () {
|
it('should fallback to require.resolve in Node.js', async function () {
|
||||||
const engine = new Liquid({
|
const engine = new Liquid({
|
||||||
root: ['/root/'],
|
root: ['/root/'],
|
||||||
extname: '.html'
|
extname: '.html'
|
||||||
})
|
})
|
||||||
const tpls = await engine.parseFileSync('mocha')
|
const tpls = await engine.parseFileSync('jest')
|
||||||
expect(tpls.length).to.gte(1)
|
expect(tpls.length).toBeGreaterThanOrEqual(1)
|
||||||
expect(tpls[0].token.getText()).to.contain('module.exports')
|
expect(tpls[0].token.getText()).toContain('use strict')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('#evalValue', function () {
|
describe('#evalValue', function () {
|
||||||
@@ -147,12 +140,12 @@ describe('Liquid', function () {
|
|||||||
const engine = new Liquid()
|
const engine = new Liquid()
|
||||||
const ctx = new Context()
|
const ctx = new Context()
|
||||||
const str = await engine.evalValue('"foo"', ctx)
|
const str = await engine.evalValue('"foo"', ctx)
|
||||||
expect(str).to.equal('foo')
|
expect(str).toBe('foo')
|
||||||
})
|
})
|
||||||
it('should support plain scope', async function () {
|
it('should support plain scope', async function () {
|
||||||
const engine = new Liquid()
|
const engine = new Liquid()
|
||||||
const str = await engine.evalValue('foo', { foo: 'FOO' })
|
const str = await engine.evalValue('foo', { foo: 'FOO' })
|
||||||
expect(str).to.equal('FOO')
|
expect(str).toBe('FOO')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('#evalValueSync', function () {
|
describe('#evalValueSync', function () {
|
||||||
@@ -160,7 +153,7 @@ describe('Liquid', function () {
|
|||||||
const engine = new Liquid()
|
const engine = new Liquid()
|
||||||
const ctx = new Context()
|
const ctx = new Context()
|
||||||
const str = engine.evalValueSync('"foo"', ctx)
|
const str = engine.evalValueSync('"foo"', ctx)
|
||||||
expect(str).to.equal('foo')
|
expect(str).toBe('foo')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('#parse', function () {
|
describe('#parse', function () {
|
||||||
@@ -173,7 +166,7 @@ describe('Liquid', function () {
|
|||||||
'/root/partial.html': 'foo'
|
'/root/partial.html': 'foo'
|
||||||
})
|
})
|
||||||
const tpls = engine.parse('{% render "./partial.html" %}', '/root/index.html')
|
const tpls = engine.parse('{% render "./partial.html" %}', '/root/index.html')
|
||||||
return expect(engine.renderSync(tpls)).to.equal('foo')
|
return expect(engine.renderSync(tpls)).toBe('foo')
|
||||||
})
|
})
|
||||||
it('should resolve against pwd for relative filepath', function () {
|
it('should resolve against pwd for relative filepath', function () {
|
||||||
const engine = new Liquid({
|
const engine = new Liquid({
|
||||||
@@ -184,7 +177,7 @@ describe('Liquid', function () {
|
|||||||
[`${process.cwd()}/partial.html`]: 'foo'
|
[`${process.cwd()}/partial.html`]: 'foo'
|
||||||
})
|
})
|
||||||
const tpls = engine.parse('{% render "./partial.html" %}', './index.html')
|
const tpls = engine.parse('{% render "./partial.html" %}', './index.html')
|
||||||
return expect(engine.renderSync(tpls)).to.equal('foo')
|
return expect(engine.renderSync(tpls)).toBe('foo')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('#parseFileSync', function () {
|
describe('#parseFileSync', function () {
|
||||||
@@ -194,7 +187,7 @@ describe('Liquid', function () {
|
|||||||
extname: '.html'
|
extname: '.html'
|
||||||
})
|
})
|
||||||
return expect(() => engine.parseFileSync('/not/exist.html'))
|
return expect(() => engine.parseFileSync('/not/exist.html'))
|
||||||
.to.throw(/Failed to lookup "\/not\/exist.html" in "\/boo,\/root\/"/)
|
.toThrow(/Failed to lookup "\/not\/exist.html" in "\/boo,\/root\/"/)
|
||||||
})
|
})
|
||||||
it('should throw with lookup list when file not exist', function () {
|
it('should throw with lookup list when file not exist', function () {
|
||||||
const engine = new Liquid({
|
const engine = new Liquid({
|
||||||
@@ -202,19 +195,19 @@ describe('Liquid', function () {
|
|||||||
extname: '.html'
|
extname: '.html'
|
||||||
})
|
})
|
||||||
return expect(() => engine.parseFileSync('/not/exist.html'))
|
return expect(() => engine.parseFileSync('/not/exist.html'))
|
||||||
.to.throw(/Failed to lookup "\/not\/exist.html" in "\/boo,\/root\/"/)
|
.toThrow(/Failed to lookup "\/not\/exist.html" in "\/boo,\/root\/"/)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('#enderToNodeStream', function () {
|
describe('#enderToNodeStream', function () {
|
||||||
const engine = new Liquid()
|
const engine = new Liquid()
|
||||||
it('should render a simple value', async () => {
|
it('should render a simple value', async () => {
|
||||||
const stream = engine.renderToNodeStream(engine.parse('{{"foo"}}'))
|
const stream = engine.renderToNodeStream(engine.parse('{{"foo"}}'))
|
||||||
expect(drainStream(stream)).to.eventually.equal('foo')
|
expect(drainStream(stream)).resolves.toBe('foo')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('#enderFileToNodeStream', function () {
|
describe('#enderFileToNodeStream', function () {
|
||||||
let engine: Liquid
|
let engine: Liquid
|
||||||
before(function () {
|
beforeEach(function () {
|
||||||
mock({
|
mock({
|
||||||
'/root/foo.html': 'foo',
|
'/root/foo.html': 'foo',
|
||||||
'/root/error.html': 'A{%throwingTag%}B'
|
'/root/error.html': 'A{%throwingTag%}B'
|
||||||
@@ -226,14 +219,14 @@ describe('Liquid', function () {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
after(restore)
|
afterEach(restore)
|
||||||
it('should render a simple value', async () => {
|
it('should render a simple value', async () => {
|
||||||
const stream = await engine.renderFileToNodeStream('foo.html')
|
const stream = await engine.renderFileToNodeStream('foo.html')
|
||||||
expect(drainStream(stream)).to.be.eventually.equal('foo')
|
expect(drainStream(stream)).resolves.toBe('foo')
|
||||||
})
|
})
|
||||||
it('should throw RenderError when tag throws', async () => {
|
it('should throw RenderError when tag throws', async () => {
|
||||||
const stream = await engine.renderFileToNodeStream('error.html')
|
const stream = await engine.renderFileToNodeStream('error.html')
|
||||||
expect(drainStream(stream)).to.be.rejectedWith(/intended render error/)
|
expect(drainStream(stream)).rejects.toThrow(/intended render error/)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
+6
-7
@@ -1,4 +1,3 @@
|
|||||||
import { expect } from 'chai'
|
|
||||||
import { Liquid, defaultOperators } from '../../../src'
|
import { Liquid, defaultOperators } from '../../../src'
|
||||||
|
|
||||||
describe('LiquidOptions#operators', function () {
|
describe('LiquidOptions#operators', function () {
|
||||||
@@ -8,27 +7,27 @@ describe('LiquidOptions#operators', function () {
|
|||||||
engine = new Liquid({
|
engine = new Liquid({
|
||||||
operators: {
|
operators: {
|
||||||
...defaultOperators,
|
...defaultOperators,
|
||||||
isFooBar: (l, r) => l === 'foo' && r === 'bar'
|
isFooBar: (l: string, r: string) => l === 'foo' && r === 'bar'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should evaluate the default operators', async function () {
|
it('should evaluate the default operators', async function () {
|
||||||
const result = await engine.parseAndRender('{% if "foo" == "foo" %}True{% endif %}')
|
const result = await engine.parseAndRender('{% if "foo" == "foo" %}True{% endif %}')
|
||||||
expect(result).to.equal('True')
|
expect(result).toBe('True')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should evaluate a custom operator', async function () {
|
it('should evaluate a custom operator', async function () {
|
||||||
const first = await engine.parseAndRender('{% if "foo" isFooBar "bar" %}True{% else %}False{% endif %}')
|
const first = await engine.parseAndRender('{% if "foo" isFooBar "bar" %}True{% else %}False{% endif %}')
|
||||||
expect(first).to.equal('True')
|
expect(first).toBe('True')
|
||||||
const second = await engine.parseAndRender('{% if "foo" isFooBar "foo" %}True{% else %}False{% endif %}')
|
const second = await engine.parseAndRender('{% if "foo" isFooBar "foo" %}True{% else %}False{% endif %}')
|
||||||
expect(second).to.equal('False')
|
expect(second).toBe('False')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should evaluate a custom operator with the correct precedence', async function () {
|
it('should evaluate a custom operator with the correct precedence', async function () {
|
||||||
const first = await engine.parseAndRender('{% if "foo" isFooBar "bar" or "foo" == "bar" %}True{% else %}False{% endif %}')
|
const first = await engine.parseAndRender('{% if "foo" isFooBar "bar" or "foo" == "bar" %}True{% else %}False{% endif %}')
|
||||||
expect(first).to.equal('True')
|
expect(first).toBe('True')
|
||||||
const second = await engine.parseAndRender('{% if "foo" isFooBar "foo" or "foo" == "bar" %}True{% else %}False{% endif %}')
|
const second = await engine.parseAndRender('{% if "foo" isFooBar "foo" or "foo" == "bar" %}True{% else %}False{% endif %}')
|
||||||
expect(second).to.equal('False')
|
expect(second).toBe('False')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
+5
-6
@@ -1,11 +1,10 @@
|
|||||||
import { expect } from 'chai'
|
|
||||||
import { Liquid } from '../../../src/liquid'
|
import { Liquid } from '../../../src/liquid'
|
||||||
|
|
||||||
describe('LiquidOptions#*outputEscape*', function () {
|
describe('LiquidOptions#*outputEscape*', function () {
|
||||||
it('when outputEscape is not set', async function () {
|
it('when outputEscape is not set', async function () {
|
||||||
const engine = new Liquid()
|
const engine = new Liquid()
|
||||||
const html = await engine.parseAndRender('{{"<"}}')
|
const html = await engine.parseAndRender('{{"<"}}')
|
||||||
expect(html).to.equal('<')
|
expect(html).toBe('<')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should escape when outputEscape="escape"', async function () {
|
it('should escape when outputEscape="escape"', async function () {
|
||||||
@@ -13,7 +12,7 @@ describe('LiquidOptions#*outputEscape*', function () {
|
|||||||
outputEscape: 'escape'
|
outputEscape: 'escape'
|
||||||
})
|
})
|
||||||
const html = await engine.parseAndRender('{{"<"}}')
|
const html = await engine.parseAndRender('{{"<"}}')
|
||||||
expect(html).to.equal('<')
|
expect(html).toBe('<')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should json stringify when outputEscape="json"', async function () {
|
it('should json stringify when outputEscape="json"', async function () {
|
||||||
@@ -21,7 +20,7 @@ describe('LiquidOptions#*outputEscape*', function () {
|
|||||||
outputEscape: 'json'
|
outputEscape: 'json'
|
||||||
})
|
})
|
||||||
const html = await engine.parseAndRender('{{"<"}}')
|
const html = await engine.parseAndRender('{{"<"}}')
|
||||||
expect(html).to.equal('"<"')
|
expect(html).toBe('"<"')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support outputEscape=Function', async function () {
|
it('should support outputEscape=Function', async function () {
|
||||||
@@ -29,7 +28,7 @@ describe('LiquidOptions#*outputEscape*', function () {
|
|||||||
outputEscape: (v: any) => `{${v}}`
|
outputEscape: (v: any) => `{${v}}`
|
||||||
})
|
})
|
||||||
const html = await engine.parseAndRender('{{"<"}}')
|
const html = await engine.parseAndRender('{{"<"}}')
|
||||||
expect(html).to.equal('{<}')
|
expect(html).toBe('{<}')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should skip escape for output with filter "| raw"', async function () {
|
it('should skip escape for output with filter "| raw"', async function () {
|
||||||
@@ -37,6 +36,6 @@ describe('LiquidOptions#*outputEscape*', function () {
|
|||||||
outputEscape: 'escape'
|
outputEscape: 'escape'
|
||||||
})
|
})
|
||||||
const html = await engine.parseAndRender('{{"<" | raw}}')
|
const html = await engine.parseAndRender('{{"<" | raw}}')
|
||||||
expect(html).to.equal('<')
|
expect(html).toBe('<')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
+5
-6
@@ -1,4 +1,3 @@
|
|||||||
import { expect } from 'chai'
|
|
||||||
import { Liquid } from '../../../src/liquid'
|
import { Liquid } from '../../../src/liquid'
|
||||||
|
|
||||||
describe('liquid#registerFilter()', function () {
|
describe('liquid#registerFilter()', function () {
|
||||||
@@ -15,13 +14,13 @@ describe('liquid#registerFilter()', function () {
|
|||||||
const src = `{{ "a" | obj_test: k1: "v1", k2: foo }}`
|
const src = `{{ "a" | obj_test: k1: "v1", k2: foo }}`
|
||||||
const dst = '["a",["k1","v1"],["k2","bar"]]'
|
const dst = '["a",["k1","v1"],["k2","bar"]]'
|
||||||
const html = await liquid.parseAndRender(src, { foo: 'bar' })
|
const html = await liquid.parseAndRender(src, { foo: 'bar' })
|
||||||
return expect(html).to.equal(dst)
|
return expect(html).toBe(dst)
|
||||||
})
|
})
|
||||||
it('should support mixed arguments', async () => {
|
it('should support mixed arguments', async () => {
|
||||||
const src = `{{ "a" | obj_test: "something", k1: "v1", k2: foo }}`
|
const src = `{{ "a" | obj_test: "something", k1: "v1", k2: foo }}`
|
||||||
const dst = '["a","something",["k1","v1"],["k2","bar"]]'
|
const dst = '["a","something",["k1","v1"],["k2","bar"]]'
|
||||||
const html = await liquid.parseAndRender(src, { foo: 'bar' })
|
const html = await liquid.parseAndRender(src, { foo: 'bar' })
|
||||||
return expect(html).to.equal(dst)
|
return expect(html).toBe(dst)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -33,7 +32,7 @@ describe('liquid#registerFilter()', function () {
|
|||||||
const src = `{{ userId | get_user_data | json }}`
|
const src = `{{ userId | get_user_data | json }}`
|
||||||
const dst = '{"userId":"alice","userName":"ALICE"}'
|
const dst = '{"userId":"alice","userName":"ALICE"}'
|
||||||
const html = await liquid.parseAndRender(src, { userId: 'alice' })
|
const html = await liquid.parseAndRender(src, { userId: 'alice' })
|
||||||
return expect(html).to.equal(dst)
|
return expect(html).toBe(dst)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -48,7 +47,7 @@ describe('liquid#registerFilter()', function () {
|
|||||||
const src = `{{ "a\nb" | break }}`
|
const src = `{{ "a\nb" | break }}`
|
||||||
const dst = 'a<br/>b'
|
const dst = 'a<br/>b'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal(dst)
|
return expect(html).toBe(dst)
|
||||||
})
|
})
|
||||||
it('should not escape filter output when registered as "raw"', async () => {
|
it('should not escape filter output when registered as "raw"', async () => {
|
||||||
liquid.registerFilter('break', {
|
liquid.registerFilter('break', {
|
||||||
@@ -58,7 +57,7 @@ describe('liquid#registerFilter()', function () {
|
|||||||
const src = `{{ "a\nb" | break }}`
|
const src = `{{ "a\nb" | break }}`
|
||||||
const dst = 'a<br/>b'
|
const dst = 'a<br/>b'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal(dst)
|
return expect(html).toBe(dst)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
+4
-5
@@ -1,4 +1,3 @@
|
|||||||
import { expect } from 'chai'
|
|
||||||
import { Liquid } from '../../../src/liquid'
|
import { Liquid } from '../../../src/liquid'
|
||||||
|
|
||||||
describe('liquid#registerTag()', function () {
|
describe('liquid#registerTag()', function () {
|
||||||
@@ -8,7 +7,7 @@ describe('liquid#registerTag()', function () {
|
|||||||
render: () => 'B'
|
render: () => 'B'
|
||||||
})
|
})
|
||||||
const html = await liquid.parseAndRender(`A{% simple-string %}C`)
|
const html = await liquid.parseAndRender(`A{% simple-string %}C`)
|
||||||
return expect(html).to.equal('ABC')
|
return expect(html).toBe('ABC')
|
||||||
})
|
})
|
||||||
it('should support async tag render', async () => {
|
it('should support async tag render', async () => {
|
||||||
const liquid = new Liquid()
|
const liquid = new Liquid()
|
||||||
@@ -16,7 +15,7 @@ describe('liquid#registerTag()', function () {
|
|||||||
render: async () => 'B'
|
render: async () => 'B'
|
||||||
})
|
})
|
||||||
const html = await liquid.parseAndRender(`A{% async-string %}C`)
|
const html = await liquid.parseAndRender(`A{% async-string %}C`)
|
||||||
return expect(html).to.equal('ABC')
|
return expect(html).toBe('ABC')
|
||||||
})
|
})
|
||||||
it('should have access to ctx in render()', async () => {
|
it('should have access to ctx in render()', async () => {
|
||||||
const liquid = new Liquid()
|
const liquid = new Liquid()
|
||||||
@@ -26,7 +25,7 @@ describe('liquid#registerTag()', function () {
|
|||||||
const html = await liquid.parseAndRender(`A{% dynamic-string %}C`, {
|
const html = await liquid.parseAndRender(`A{% dynamic-string %}C`, {
|
||||||
c: 'B'
|
c: 'B'
|
||||||
})
|
})
|
||||||
return expect(html).to.equal('ABC')
|
return expect(html).toBe('ABC')
|
||||||
})
|
})
|
||||||
it('should have access to tag arguments', async () => {
|
it('should have access to tag arguments', async () => {
|
||||||
const liquid = new Liquid()
|
const liquid = new Liquid()
|
||||||
@@ -37,6 +36,6 @@ describe('liquid#registerTag()', function () {
|
|||||||
const html = await liquid.parseAndRender(`A{% argument-reflector variable=c %}C`, {
|
const html = await liquid.parseAndRender(`A{% argument-reflector variable=c %}C`, {
|
||||||
c: 'B'
|
c: 'B'
|
||||||
})
|
})
|
||||||
return expect(html).to.equal('ABC')
|
return expect(html).toBe('ABC')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,15 +1,14 @@
|
|||||||
import { normalize } from '../../../src/liquid-options'
|
import { normalize } from '../../../src/liquid-options'
|
||||||
import { expect } from 'chai'
|
|
||||||
|
|
||||||
describe('LiquidOptions#root', function () {
|
describe('LiquidOptions#root', function () {
|
||||||
describe('#normalize ()', function () {
|
describe('#normalize ()', function () {
|
||||||
it('should normalize string typed root array', function () {
|
it('should normalize string typed root array', function () {
|
||||||
const options = normalize({ root: 'foo' })
|
const options = normalize({ root: 'foo' })
|
||||||
expect(options.root).to.eql(['foo'])
|
expect(options.root).toEqual(['foo'])
|
||||||
})
|
})
|
||||||
it('should normalize null typed root as empty array', function () {
|
it('should normalize null typed root as empty array', function () {
|
||||||
const options = normalize({ root: null } as any)
|
const options = normalize({ root: null } as any)
|
||||||
expect(options.root).to.eql([])
|
expect(options.root).toEqual([])
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,9 +1,4 @@
|
|||||||
import { Liquid } from '../../../src/liquid'
|
import { Liquid } from '../../../src/liquid'
|
||||||
import * as chai from 'chai'
|
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
|
|
||||||
chai.use(chaiAsPromised)
|
|
||||||
const expect = chai.expect
|
|
||||||
|
|
||||||
describe('LiquidOptions#strict*', function () {
|
describe('LiquidOptions#strict*', function () {
|
||||||
let engine: Liquid
|
let engine: Liquid
|
||||||
@@ -16,7 +11,7 @@ describe('LiquidOptions#strict*', function () {
|
|||||||
})
|
})
|
||||||
it('should not throw when strictVariables false (default)', async function () {
|
it('should not throw when strictVariables false (default)', async function () {
|
||||||
const html = await engine.parseAndRender('before{{notdefined}}after', ctx)
|
const html = await engine.parseAndRender('before{{notdefined}}after', ctx)
|
||||||
return expect(html).to.equal('beforeafter')
|
return expect(html).toBe('beforeafter')
|
||||||
})
|
})
|
||||||
it('should throw when strictVariables true', function () {
|
it('should throw when strictVariables true', function () {
|
||||||
const tpl = engine.parse('before{{notdefined}}after')
|
const tpl = engine.parse('before{{notdefined}}after')
|
||||||
@@ -25,8 +20,7 @@ describe('LiquidOptions#strict*', function () {
|
|||||||
extname: '.html',
|
extname: '.html',
|
||||||
strictVariables: true
|
strictVariables: true
|
||||||
})
|
})
|
||||||
return expect(engine.render(tpl, ctx)).to
|
return expect(engine.render(tpl, ctx)).rejects.toThrow(/undefined variable: notdefined/)
|
||||||
.be.rejectedWith(/undefined variable: notdefined/)
|
|
||||||
})
|
})
|
||||||
it('should pass strictVariables to render by parseAndRender', function () {
|
it('should pass strictVariables to render by parseAndRender', function () {
|
||||||
const html = 'before{{notdefined}}after'
|
const html = 'before{{notdefined}}after'
|
||||||
@@ -35,8 +29,7 @@ describe('LiquidOptions#strict*', function () {
|
|||||||
extname: '.html',
|
extname: '.html',
|
||||||
strictVariables: true
|
strictVariables: true
|
||||||
})
|
})
|
||||||
return expect(engine.parseAndRender(html, ctx)).to
|
return expect(engine.parseAndRender(html, ctx)).rejects.toThrow(/undefined variable: notdefined/)
|
||||||
.be.rejectedWith(/undefined variable: notdefined/)
|
|
||||||
})
|
})
|
||||||
describe('with strictVariables and lenientIf', function () {
|
describe('with strictVariables and lenientIf', function () {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@@ -50,31 +43,31 @@ describe('LiquidOptions#strict*', function () {
|
|||||||
it('should not throw in `if` with a single variable', async function () {
|
it('should not throw in `if` with a single variable', async function () {
|
||||||
const tpl = engine.parse('before{% if notdefined %}{{notdefined}}{% endif %}after')
|
const tpl = engine.parse('before{% if notdefined %}{{notdefined}}{% endif %}after')
|
||||||
const html = await engine.render(tpl, ctx)
|
const html = await engine.render(tpl, ctx)
|
||||||
return expect(html).to.equal('beforeafter')
|
return expect(html).toBe('beforeafter')
|
||||||
})
|
})
|
||||||
it('should support elsif with undefined variables', async function () {
|
it('should support elsif with undefined variables', async function () {
|
||||||
const tpl = engine.parse('{% if notdefined1 %}a{% elsif notdefined2 %}b{% elsif defined3 %}{{defined3}}{% else %}d{% endif %}')
|
const tpl = engine.parse('{% if notdefined1 %}a{% elsif notdefined2 %}b{% elsif defined3 %}{{defined3}}{% else %}d{% endif %}')
|
||||||
const html = await engine.render(tpl, { 'defined3': 'bla' })
|
const html = await engine.render(tpl, { 'defined3': 'bla' })
|
||||||
return expect(html).to.equal('bla')
|
return expect(html).toBe('bla')
|
||||||
})
|
})
|
||||||
it('should not throw in `unless` with a single variable', async function () {
|
it('should not throw in `unless` with a single variable', async function () {
|
||||||
const tpl = engine.parse('before{% unless notdefined %}X{% else %}{{notdefined}}{% endunless %}after')
|
const tpl = engine.parse('before{% unless notdefined %}X{% else %}{{notdefined}}{% endunless %}after')
|
||||||
const html = await engine.render(tpl, ctx)
|
const html = await engine.render(tpl, ctx)
|
||||||
return expect(html).to.equal('beforeXafter')
|
return expect(html).toBe('beforeXafter')
|
||||||
})
|
})
|
||||||
it('should still throw with an undefined variable in a compound `if` expression', function () {
|
it('should still throw with an undefined variable in a compound `if` expression', function () {
|
||||||
const tpl = engine.parse('{% if notdefined == 15 %}a{% endif %}')
|
const tpl = engine.parse('{% if notdefined == 15 %}a{% endif %}')
|
||||||
const fhtml = engine.render(tpl, ctx)
|
const fhtml = engine.render(tpl, ctx)
|
||||||
return expect(fhtml).to.be.rejectedWith(/undefined variable: notdefined/)
|
return expect(fhtml).rejects.toThrow(/undefined variable: notdefined/)
|
||||||
})
|
})
|
||||||
it('should allow an undefined variable when before the `default` filter', async function () {
|
it('should allow an undefined variable when before the `default` filter', async function () {
|
||||||
const tpl = engine.parse('{{notdefined | default: "a" | tolower}}')
|
const tpl = engine.parse('{{notdefined | default: "a" | tolower}}')
|
||||||
const html = await engine.render(tpl, ctx)
|
const html = await engine.render(tpl, ctx)
|
||||||
return expect(html).to.equal('a')
|
return expect(html).toBe('a')
|
||||||
})
|
})
|
||||||
it('should not allow undefined variable even if `lenientIf` set', async function () {
|
it('should not allow undefined variable even if `lenientIf` set', async function () {
|
||||||
const tpl = engine.parse('{{notdefined | tolower}}')
|
const tpl = engine.parse('{{notdefined | tolower}}')
|
||||||
return expect(() => engine.renderSync(tpl, ctx)).to.throw('undefined variable: notdefined')
|
return expect(() => engine.renderSync(tpl, ctx)).toThrow('undefined variable: notdefined')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
import { expect } from 'chai'
|
|
||||||
import { Liquid } from '../../../src/liquid'
|
import { Liquid } from '../../../src/liquid'
|
||||||
|
|
||||||
describe('LiquidOptions#trimming', function () {
|
describe('LiquidOptions#trimming', function () {
|
||||||
@@ -8,34 +7,34 @@ describe('LiquidOptions#trimming', function () {
|
|||||||
it('should respect trimTagLeft', async function () {
|
it('should respect trimTagLeft', async function () {
|
||||||
const engine = new Liquid({ trimTagLeft: true })
|
const engine = new Liquid({ trimTagLeft: true })
|
||||||
const html = await engine.parseAndRender(' \n \t{%if true%}foo{%endif%} ')
|
const html = await engine.parseAndRender(' \n \t{%if true%}foo{%endif%} ')
|
||||||
return expect(html).to.equal('foo ')
|
return expect(html).toBe('foo ')
|
||||||
})
|
})
|
||||||
it('should respect trimTagRight', async function () {
|
it('should respect trimTagRight', async function () {
|
||||||
const engine = new Liquid({ trimTagRight: true } as any)
|
const engine = new Liquid({ trimTagRight: true } as any)
|
||||||
const html = await engine.parseAndRender('\t{%if true%}foo{%endif%} \n')
|
const html = await engine.parseAndRender('\t{%if true%}foo{%endif%} \n')
|
||||||
return expect(html).to.equal('\tfoo')
|
return expect(html).toBe('\tfoo')
|
||||||
})
|
})
|
||||||
it('should not trim value', async function () {
|
it('should not trim value', async function () {
|
||||||
const engine = new Liquid({ trimTagLeft: true, trimTagRight: true } as any)
|
const engine = new Liquid({ trimTagLeft: true, trimTagRight: true } as any)
|
||||||
const html = await engine.parseAndRender('{%if true%}a {{name}} b{%endif%}', ctx)
|
const html = await engine.parseAndRender('{%if true%}a {{name}} b{%endif%}', ctx)
|
||||||
return expect(html).to.equal('a harttle b')
|
return expect(html).toBe('a harttle b')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('value trimming', function () {
|
describe('value trimming', function () {
|
||||||
it('should respect trimOutputLeft', async function () {
|
it('should respect trimOutputLeft', async function () {
|
||||||
const engine = new Liquid({ trimOutputLeft: true } as any)
|
const engine = new Liquid({ trimOutputLeft: true } as any)
|
||||||
const html = await engine.parseAndRender(' \n \t{{name}} ', ctx)
|
const html = await engine.parseAndRender(' \n \t{{name}} ', ctx)
|
||||||
return expect(html).to.equal('harttle ')
|
return expect(html).toBe('harttle ')
|
||||||
})
|
})
|
||||||
it('should respect trimOutputRight', async function () {
|
it('should respect trimOutputRight', async function () {
|
||||||
const engine = new Liquid({ trimOutputRight: true } as any)
|
const engine = new Liquid({ trimOutputRight: true } as any)
|
||||||
const html = await engine.parseAndRender(' \n \t{{name}} ', ctx)
|
const html = await engine.parseAndRender(' \n \t{{name}} ', ctx)
|
||||||
return expect(html).to.equal(' \n \tharttle')
|
return expect(html).toBe(' \n \tharttle')
|
||||||
})
|
})
|
||||||
it('should respect not trim tag', async function () {
|
it('should respect not trim tag', async function () {
|
||||||
const engine = new Liquid({ trimOutputLeft: true, trimOutputRight: true } as any)
|
const engine = new Liquid({ trimOutputLeft: true, trimOutputRight: true } as any)
|
||||||
const html = await engine.parseAndRender('\t{% if true %} aha {%endif%}\t')
|
const html = await engine.parseAndRender('\t{% if true %} aha {%endif%}\t')
|
||||||
return expect(html).to.equal('\t aha \t')
|
return expect(html).toBe('\t aha \t')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('greedy', function () {
|
describe('greedy', function () {
|
||||||
@@ -43,12 +42,12 @@ describe('LiquidOptions#trimming', function () {
|
|||||||
it('should enable greedy by default', async function () {
|
it('should enable greedy by default', async function () {
|
||||||
const engine = new Liquid()
|
const engine = new Liquid()
|
||||||
const html = await engine.parseAndRender(src, ctx)
|
const html = await engine.parseAndRender(src, ctx)
|
||||||
return expect(html).to.equal('aharttle')
|
return expect(html).toBe('aharttle')
|
||||||
})
|
})
|
||||||
it('should allow greedy:false', async function () {
|
it('should allow greedy:false', async function () {
|
||||||
const engine = new Liquid({ greedy: false } as any)
|
const engine = new Liquid({ greedy: false } as any)
|
||||||
const html = await engine.parseAndRender(src, ctx)
|
const html = await engine.parseAndRender(src, ctx)
|
||||||
return expect(html).to.equal('\n a \nharttle ')
|
return expect(html).toBe('\n a \nharttle ')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('markup', function () {
|
describe('markup', function () {
|
||||||
@@ -64,7 +63,7 @@ describe('LiquidOptions#trimming', function () {
|
|||||||
].join('\n')
|
].join('\n')
|
||||||
const dst = 'Wow, John G. Chalmers-Smith, you have a long name!'
|
const dst = 'Wow, John G. Chalmers-Smith, you have a long name!'
|
||||||
const html = await engine.parseAndRender(src)
|
const html = await engine.parseAndRender(src)
|
||||||
return expect(html).to.equal(dst)
|
return expect(html).toBe(dst)
|
||||||
})
|
})
|
||||||
it('should not trim when not specified', async function () {
|
it('should not trim when not specified', async function () {
|
||||||
const engine = new Liquid()
|
const engine = new Liquid()
|
||||||
@@ -78,7 +77,7 @@ describe('LiquidOptions#trimming', function () {
|
|||||||
].join('\n')
|
].join('\n')
|
||||||
const dst = '\n\n Wow, John G. Chalmers-Smith, you have a long name!\n'
|
const dst = '\n\n Wow, John G. Chalmers-Smith, you have a long name!\n'
|
||||||
const html = await engine.parseAndRender(src)
|
const html = await engine.parseAndRender(src)
|
||||||
return expect(html).to.equal(dst)
|
return expect(html).toBe(dst)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
+1
-2
@@ -1,4 +1,3 @@
|
|||||||
import { expect } from 'chai'
|
|
||||||
import { Liquid } from '../../../src/liquid'
|
import { Liquid } from '../../../src/liquid'
|
||||||
|
|
||||||
const liquid = new Liquid()
|
const liquid = new Liquid()
|
||||||
@@ -444,7 +443,7 @@ describe('Whitespace Control', function () {
|
|||||||
item.text,
|
item.text,
|
||||||
async () => {
|
async () => {
|
||||||
const html = await liquid.parseAndRender(item.text)
|
const html = await liquid.parseAndRender(item.text)
|
||||||
expect(html).to.equal(item.expected)
|
expect(html).toBe(item.expected)
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
@@ -1,41 +1,37 @@
|
|||||||
import { Liquid } from '../../../src/liquid'
|
import { Liquid } from '../../../src/liquid'
|
||||||
import { ParseError } from '../../../src'
|
import { ParseError } from '../../../src'
|
||||||
import { expect, use } from 'chai'
|
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
|
|
||||||
use(chaiAsPromised)
|
|
||||||
|
|
||||||
describe('tags/assign', function () {
|
describe('tags/assign', function () {
|
||||||
const liquid = new Liquid()
|
const liquid = new Liquid()
|
||||||
it('should throw when variable name illegal', function () {
|
it('should throw when variable name illegal', function () {
|
||||||
const src = '{% assign / %}'
|
const src = '{% assign / %}'
|
||||||
const ctx = {}
|
const ctx = {}
|
||||||
return expect(liquid.parseAndRender(src, ctx)).to.be.rejectedWith(/illegal/)
|
return expect(liquid.parseAndRender(src, ctx)).rejects.toThrow(/illegal/)
|
||||||
})
|
})
|
||||||
it('should support assign to a string', async function () {
|
it('should support assign to a string', async function () {
|
||||||
const src = '{% assign foo="bar" %}{{foo}}'
|
const src = '{% assign foo="bar" %}{{foo}}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('bar')
|
return expect(html).toBe('bar')
|
||||||
})
|
})
|
||||||
it('should throw when variable value illegal', function () {
|
it('should throw when variable value illegal', function () {
|
||||||
const src = '{% assign foo = “bar” %}'
|
const src = '{% assign foo = “bar” %}'
|
||||||
expect(() => liquid.parse(src)).to.throw(/unexpected token at "“bar”"/)
|
expect(() => liquid.parse(src)).toThrow(/unexpected token at "“bar”"/)
|
||||||
expect(() => liquid.parse(src)).to.throw(ParseError)
|
expect(() => liquid.parse(src)).toThrow(ParseError)
|
||||||
})
|
})
|
||||||
it('should support assign to a number', async function () {
|
it('should support assign to a number', async function () {
|
||||||
const src = '{% assign foo=10086 %}{{foo}}'
|
const src = '{% assign foo=10086 %}{{foo}}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('10086')
|
return expect(html).toBe('10086')
|
||||||
})
|
})
|
||||||
it('should assign as array', async function () {
|
it('should assign as array', async function () {
|
||||||
const src = '{% assign foo=(1..3) %}{{foo}}'
|
const src = '{% assign foo=(1..3) %}{{foo}}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('123')
|
return expect(html).toBe('123')
|
||||||
})
|
})
|
||||||
it('should assign as filter result', async function () {
|
it('should assign as filter result', async function () {
|
||||||
const src = '{% assign foo="a b" | capitalize | split: " " | first %}{{foo}}'
|
const src = '{% assign foo="a b" | capitalize | split: " " | first %}{{foo}}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('A')
|
return expect(html).toBe('A')
|
||||||
})
|
})
|
||||||
it('should assign as filter across multiple lines as result', async function () {
|
it('should assign as filter across multiple lines as result', async function () {
|
||||||
const src = `{% assign foo="a b"
|
const src = `{% assign foo="a b"
|
||||||
@@ -43,64 +39,64 @@ describe('tags/assign', function () {
|
|||||||
| split: " "
|
| split: " "
|
||||||
| first %}{{foo}}`
|
| first %}{{foo}}`
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('A')
|
return expect(html).toBe('A')
|
||||||
})
|
})
|
||||||
it('should assign var-1', async function () {
|
it('should assign var-1', async function () {
|
||||||
const src = '{% assign var-1 = 5 %}{{ var-1 }}'
|
const src = '{% assign var-1 = 5 %}{{ var-1 }}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('5')
|
return expect(html).toBe('5')
|
||||||
})
|
})
|
||||||
it('should assign var-', async function () {
|
it('should assign var-', async function () {
|
||||||
const src = '{% assign var- = 5 %}{{ var- }}'
|
const src = '{% assign var- = 5 %}{{ var- }}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('5')
|
return expect(html).toBe('5')
|
||||||
})
|
})
|
||||||
it('should assign -var', async function () {
|
it('should assign -var', async function () {
|
||||||
const src = '{% assign -let = 5 %}{{ -let }}'
|
const src = '{% assign -let = 5 %}{{ -let }}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('5')
|
return expect(html).toBe('5')
|
||||||
})
|
})
|
||||||
it('should assign -5-5', async function () {
|
it('should assign -5-5', async function () {
|
||||||
const src = '{% assign -5-5 = 5 %}{{ -5-5 }}'
|
const src = '{% assign -5-5 = 5 %}{{ -5-5 }}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('5')
|
return expect(html).toBe('5')
|
||||||
})
|
})
|
||||||
it('should assign 4-3', async function () {
|
it('should assign 4-3', async function () {
|
||||||
const src = '{% assign 4-3 = 5 %}{{ 4-3 }}'
|
const src = '{% assign 4-3 = 5 %}{{ 4-3 }}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('5')
|
return expect(html).toBe('5')
|
||||||
})
|
})
|
||||||
it('should not assign -6', async function () {
|
it('should not assign -6', async function () {
|
||||||
const src = '{% assign -6 = 5 %}{{ -6 }}'
|
const src = '{% assign -6 = 5 %}{{ -6 }}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('-6')
|
return expect(html).toBe('-6')
|
||||||
})
|
})
|
||||||
it('should allow reassignment', async function () {
|
it('should allow reassignment', async function () {
|
||||||
const src = '{% assign var = 1 %}{% assign var = 2 %}{{ var }}'
|
const src = '{% assign var = 1 %}{% assign var = 2 %}{{ var }}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('2')
|
return expect(html).toBe('2')
|
||||||
})
|
})
|
||||||
describe('scope', function () {
|
describe('scope', function () {
|
||||||
it('should read from parent scope', async function () {
|
it('should read from parent scope', async function () {
|
||||||
const src = '{%for a in (1..2)%}{{num}}{%endfor%}'
|
const src = '{%for a in (1..2)%}{{num}}{%endfor%}'
|
||||||
const html = await liquid.parseAndRender(src, { num: 1 })
|
const html = await liquid.parseAndRender(src, { num: 1 })
|
||||||
return expect(html).to.equal('11')
|
return expect(html).toBe('11')
|
||||||
})
|
})
|
||||||
it('should write to the root scope', async function () {
|
it('should write to the root scope', async function () {
|
||||||
const src = '{%for a in (1..2)%}{%assign num = a%}{{a}}{%endfor%}'
|
const src = '{%for a in (1..2)%}{%assign num = a%}{{a}}{%endfor%}'
|
||||||
const html = await liquid.parseAndRender(src, { num: 1 })
|
const html = await liquid.parseAndRender(src, { num: 1 })
|
||||||
return expect(html).to.equal('12')
|
return expect(html).toBe('12')
|
||||||
})
|
})
|
||||||
it('should not change input scope', async function () {
|
it('should not change input scope', async function () {
|
||||||
const src = '{%for a in (1..2)%}{%assign num = a%}{{a}}{%endfor%} {{num}}'
|
const src = '{%for a in (1..2)%}{%assign num = a%}{{a}}{%endfor%} {{num}}'
|
||||||
const ctx = { num: 1 }
|
const ctx = { num: 1 }
|
||||||
await liquid.parseAndRender(src, ctx)
|
await liquid.parseAndRender(src, ctx)
|
||||||
return expect(ctx.num).to.equal(1)
|
return expect(ctx.num).toBe(1)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
it('should support sync', function () {
|
it('should support sync', function () {
|
||||||
const src = '{% assign foo="bar" %}{{foo}}'
|
const src = '{% assign foo="bar" %}{{foo}}'
|
||||||
const html = liquid.parseAndRenderSync(src)
|
const html = liquid.parseAndRenderSync(src)
|
||||||
return expect(html).to.equal('bar')
|
return expect(html).toBe('bar')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,8 +1,4 @@
|
|||||||
import { Liquid } from '../../../src/liquid'
|
import { Liquid } from '../../../src/liquid'
|
||||||
import { expect, use } from 'chai'
|
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
|
|
||||||
use(chaiAsPromised)
|
|
||||||
|
|
||||||
describe('tags/capture', function () {
|
describe('tags/capture', function () {
|
||||||
const liquid = new Liquid()
|
const liquid = new Liquid()
|
||||||
@@ -10,37 +6,37 @@ describe('tags/capture', function () {
|
|||||||
it('should support capture', async function () {
|
it('should support capture', async function () {
|
||||||
const src = '{% capture f %}{{"a" | capitalize}}{%endcapture%}{{f}}'
|
const src = '{% capture f %}{{"a" | capitalize}}{%endcapture%}{{f}}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('A')
|
return expect(html).toBe('A')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support quoted variable name', async function () {
|
it('should support quoted variable name', async function () {
|
||||||
const src = '{% capture "f" %}{{"a" | capitalize}}{%endcapture%}{{f}}'
|
const src = '{% capture "f" %}{{"a" | capitalize}}{%endcapture%}{{f}}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('A')
|
return expect(html).toBe('A')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should not change root scope', async function () {
|
it('should not change root scope', async function () {
|
||||||
const src = '{% capture var %}10{% endcapture %}{{var}}'
|
const src = '{% capture var %}10{% endcapture %}{{var}}'
|
||||||
const ctx = { 'var': 20 }
|
const ctx = { 'var': 20 }
|
||||||
const html = await liquid.parseAndRender(src, ctx)
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
expect(html).to.equal('10')
|
expect(html).toBe('10')
|
||||||
expect(ctx.var).to.equal(20)
|
expect(ctx.var).toBe(20)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should throw on invalid identifier', function () {
|
it('should throw on invalid identifier', function () {
|
||||||
const src = '{% capture = %}{%endcapture%}'
|
const src = '{% capture = %}{%endcapture%}'
|
||||||
return expect(liquid.parseAndRender(src))
|
return expect(liquid.parseAndRender(src))
|
||||||
.to.be.rejectedWith(/= not valid identifier/)
|
.rejects.toThrow(/= not valid identifier/)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should throw when capture not closed', function () {
|
it('should throw when capture not closed', function () {
|
||||||
const src = '{%capture c%}{{c}}'
|
const src = '{%capture c%}{{c}}'
|
||||||
return expect(liquid.parseAndRender(src))
|
return expect(liquid.parseAndRender(src))
|
||||||
.to.be.rejectedWith(/tag .* not closed/)
|
.rejects.toThrow(/tag .* not closed/)
|
||||||
})
|
})
|
||||||
it('should support sync', function () {
|
it('should support sync', function () {
|
||||||
const src = '{% capture f %}{{"a" | capitalize}}{%endcapture%}{{f}}'
|
const src = '{% capture f %}{{"a" | capitalize}}{%endcapture%}{{f}}'
|
||||||
const html = liquid.parseAndRenderSync(src)
|
const html = liquid.parseAndRenderSync(src)
|
||||||
return expect(html).to.equal('A')
|
return expect(html).toBe('A')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,8 +1,4 @@
|
|||||||
import { Liquid } from '../../../src/liquid'
|
import { Liquid } from '../../../src/liquid'
|
||||||
import { expect, use } from 'chai'
|
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
|
|
||||||
use(chaiAsPromised)
|
|
||||||
|
|
||||||
describe('tags/case', function () {
|
describe('tags/case', function () {
|
||||||
const liquid = new Liquid()
|
const liquid = new Liquid()
|
||||||
@@ -10,43 +6,43 @@ describe('tags/case', function () {
|
|||||||
it('should reject if not closed', function () {
|
it('should reject if not closed', function () {
|
||||||
const src = '{% case "foo"%}'
|
const src = '{% case "foo"%}'
|
||||||
return expect(liquid.parseAndRender(src))
|
return expect(liquid.parseAndRender(src))
|
||||||
.to.be.rejectedWith(/{% case "foo"%} not closed/)
|
.rejects.toThrow(/{% case "foo"%} not closed/)
|
||||||
})
|
})
|
||||||
it('should hit the specified case', async function () {
|
it('should hit the specified case', async function () {
|
||||||
const src = '{% case "foo"%}' +
|
const src = '{% case "foo"%}' +
|
||||||
'{% when "foo" %}foo{% when "bar"%}bar' +
|
'{% when "foo" %}foo{% when "bar"%}bar' +
|
||||||
'{%endcase%}'
|
'{%endcase%}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('foo')
|
return expect(html).toBe('foo')
|
||||||
})
|
})
|
||||||
it('should resolve blank as empty string', async function () {
|
it('should resolve blank as empty string', async function () {
|
||||||
const src = '{% case blank %}{% when ""%}bar{%endcase%}'
|
const src = '{% case blank %}{% when ""%}bar{%endcase%}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('bar')
|
return expect(html).toBe('bar')
|
||||||
})
|
})
|
||||||
it('should resolve empty as empty string', async function () {
|
it('should resolve empty as empty string', async function () {
|
||||||
const src = '{% case empty %}{% when ""%}bar{%endcase%}'
|
const src = '{% case empty %}{% when ""%}bar{%endcase%}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('bar')
|
return expect(html).toBe('bar')
|
||||||
})
|
})
|
||||||
it('should accept empty string as branch name', async function () {
|
it('should accept empty string as branch name', async function () {
|
||||||
const src = '{% case "" %}{% when ""%}bar{%endcase%}'
|
const src = '{% case "" %}{% when ""%}bar{%endcase%}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('bar')
|
return expect(html).toBe('bar')
|
||||||
})
|
})
|
||||||
it('should support boolean case', async function () {
|
it('should support boolean case', async function () {
|
||||||
const src = '{% case false %}' +
|
const src = '{% case false %}' +
|
||||||
'{% when "foo" %}foo{% when false%}bar' +
|
'{% when "foo" %}foo{% when false%}bar' +
|
||||||
'{%endcase%}'
|
'{%endcase%}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('bar')
|
return expect(html).toBe('bar')
|
||||||
})
|
})
|
||||||
it('should support else branch', async function () {
|
it('should support else branch', async function () {
|
||||||
const src = '{% case "a" %}' +
|
const src = '{% case "a" %}' +
|
||||||
'{% when "b" %}b{% when "c"%}c{%else %}d' +
|
'{% when "b" %}b{% when "c"%}c{%else %}d' +
|
||||||
'{%endcase%}'
|
'{%endcase%}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('d')
|
return expect(html).toBe('d')
|
||||||
})
|
})
|
||||||
describe('sync support', function () {
|
describe('sync support', function () {
|
||||||
it('should hit the specified case', function () {
|
it('should hit the specified case', function () {
|
||||||
@@ -54,14 +50,14 @@ describe('tags/case', function () {
|
|||||||
'{% when "foo" %}foo{% when "bar"%}bar' +
|
'{% when "foo" %}foo{% when "bar"%}bar' +
|
||||||
'{%endcase%}'
|
'{%endcase%}'
|
||||||
const html = liquid.parseAndRenderSync(src)
|
const html = liquid.parseAndRenderSync(src)
|
||||||
return expect(html).to.equal('foo')
|
return expect(html).toBe('foo')
|
||||||
})
|
})
|
||||||
it('should support else branch', function () {
|
it('should support else branch', function () {
|
||||||
const src = '{% case "a" %}' +
|
const src = '{% case "a" %}' +
|
||||||
'{% when "b" %}b{% when "c"%}c{%else %}d' +
|
'{% when "b" %}b{% when "c"%}c{%else %}d' +
|
||||||
'{%endcase%}'
|
'{%endcase%}'
|
||||||
const html = liquid.parseAndRenderSync(src)
|
const html = liquid.parseAndRenderSync(src)
|
||||||
return expect(html).to.equal('d')
|
return expect(html).toBe('d')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
it('should support case with multiple values', async function () {
|
it('should support case with multiple values', async function () {
|
||||||
@@ -69,7 +65,7 @@ describe('tags/case', function () {
|
|||||||
'{% when "a", "b" %}foo' +
|
'{% when "a", "b" %}foo' +
|
||||||
'{%endcase%}'
|
'{%endcase%}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('foo')
|
return expect(html).toBe('foo')
|
||||||
})
|
})
|
||||||
it('should render multiple matching branches', async function () {
|
it('should render multiple matching branches', async function () {
|
||||||
const src = '{% case "b" %}' +
|
const src = '{% case "b" %}' +
|
||||||
@@ -77,6 +73,6 @@ describe('tags/case', function () {
|
|||||||
'{% when "b" %}second' +
|
'{% when "b" %}second' +
|
||||||
'{%endcase%}'
|
'{%endcase%}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('firstsecond')
|
return expect(html).toBe('firstsecond')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,41 +1,37 @@
|
|||||||
import { Liquid } from '../../../src/liquid'
|
import { Liquid } from '../../../src/liquid'
|
||||||
import { expect, use } from 'chai'
|
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
|
|
||||||
use(chaiAsPromised)
|
|
||||||
|
|
||||||
describe('tags/comment', function () {
|
describe('tags/comment', function () {
|
||||||
const liquid = new Liquid()
|
const liquid = new Liquid()
|
||||||
it('should support empty content', function () {
|
it('should support empty content', function () {
|
||||||
const src = '{% comment %}{% raw%}'
|
const src = '{% comment %}{% raw%}'
|
||||||
return expect(liquid.parseAndRender(src))
|
return expect(liquid.parseAndRender(src))
|
||||||
.to.be.rejectedWith(/{% comment %} not closed/)
|
.rejects.toThrow(/{% comment %} not closed/)
|
||||||
})
|
})
|
||||||
it('should ignore plain string', async function () {
|
it('should ignore plain string', async function () {
|
||||||
const src = 'My name is {% comment %}super{% endcomment %} Shopify.'
|
const src = 'My name is {% comment %}super{% endcomment %} Shopify.'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('My name is Shopify.')
|
return expect(html).toBe('My name is Shopify.')
|
||||||
})
|
})
|
||||||
it('should ignore output tokens', async function () {
|
it('should ignore output tokens', async function () {
|
||||||
const src = '{% comment %}\n{{ foo}} \n{% endcomment %}'
|
const src = '{% comment %}\n{{ foo}} \n{% endcomment %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('')
|
return expect(html).toBe('')
|
||||||
})
|
})
|
||||||
it('should ignore tag tokens', async function () {
|
it('should ignore tag tokens', async function () {
|
||||||
const src = '{% comment %}{%if true%}true{%else%}false{%endif%}{% endcomment %}'
|
const src = '{% comment %}{%if true%}true{%else%}false{%endif%}{% endcomment %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('')
|
return expect(html).toBe('')
|
||||||
})
|
})
|
||||||
it('should ignore un-balenced tag tokens', async function () {
|
it('should ignore un-balenced tag tokens', async function () {
|
||||||
const src = '{% comment %}{%if true%}true{%else%}false{% endcomment %}'
|
const src = '{% comment %}{%if true%}true{%else%}false{% endcomment %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('')
|
return expect(html).toBe('')
|
||||||
})
|
})
|
||||||
describe('sync support', function () {
|
describe('sync support', function () {
|
||||||
it('should ignore plain string', function () {
|
it('should ignore plain string', function () {
|
||||||
const src = 'My name is {% comment %}super{% endcomment %} Shopify.'
|
const src = 'My name is {% comment %}super{% endcomment %} Shopify.'
|
||||||
const html = liquid.parseAndRenderSync(src)
|
const html = liquid.parseAndRenderSync(src)
|
||||||
return expect(html).to.equal('My name is Shopify.')
|
return expect(html).toBe('My name is Shopify.')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,8 +1,4 @@
|
|||||||
import { Liquid } from '../../../src/liquid'
|
import { Liquid } from '../../../src/liquid'
|
||||||
import { expect, use } from 'chai'
|
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
|
|
||||||
use(chaiAsPromised)
|
|
||||||
|
|
||||||
describe('tags/cycle', function () {
|
describe('tags/cycle', function () {
|
||||||
const liquid = new Liquid()
|
const liquid = new Liquid()
|
||||||
@@ -10,12 +6,12 @@ describe('tags/cycle', function () {
|
|||||||
it('should support cycle', async function () {
|
it('should support cycle', async function () {
|
||||||
const src = "{% cycle '1', '2', '3' %}"
|
const src = "{% cycle '1', '2', '3' %}"
|
||||||
const html = await liquid.parseAndRender(src + src + src + src)
|
const html = await liquid.parseAndRender(src + src + src + src)
|
||||||
return expect(html).to.equal('1231')
|
return expect(html).toBe('1231')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should throw when cycle candidates empty', function () {
|
it('should throw when cycle candidates empty', function () {
|
||||||
return expect(liquid.parseAndRender('{%cycle%}'))
|
return expect(liquid.parseAndRender('{%cycle%}'))
|
||||||
.to.be.rejectedWith(/empty candidates/)
|
.rejects.toThrow(/empty candidates/)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support cycle in for block', async function () {
|
it('should support cycle in for block', async function () {
|
||||||
@@ -24,7 +20,7 @@ describe('tags/cycle', function () {
|
|||||||
one: 1
|
one: 1
|
||||||
}
|
}
|
||||||
const html = await liquid.parseAndRender(src, ctx)
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
return expect(html).to.equal('1e1e1')
|
return expect(html).toBe('1e1e1')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should considered different groups for different arguments', async function () {
|
it('should considered different groups for different arguments', async function () {
|
||||||
@@ -32,7 +28,7 @@ describe('tags/cycle', function () {
|
|||||||
"{% cycle '1', '2'%}" +
|
"{% cycle '1', '2'%}" +
|
||||||
"{% cycle '1', '2', '3'%}"
|
"{% cycle '1', '2', '3'%}"
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('112')
|
return expect(html).toBe('112')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support cycle group', async function () {
|
it('should support cycle group', async function () {
|
||||||
@@ -41,11 +37,11 @@ describe('tags/cycle', function () {
|
|||||||
"{% cycle 2: '1', '2', '3'%}"
|
"{% cycle 2: '1', '2', '3'%}"
|
||||||
const ctx = { one: 1 }
|
const ctx = { one: 1 }
|
||||||
const html = await liquid.parseAndRender(src, ctx)
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
return expect(html).to.equal('121')
|
return expect(html).toBe('121')
|
||||||
})
|
})
|
||||||
it('should support sync', function () {
|
it('should support sync', function () {
|
||||||
const src = "{% cycle '1', '2', '3' %}"
|
const src = "{% cycle '1', '2', '3' %}"
|
||||||
const html = liquid.parseAndRenderSync(src + src + src + src)
|
const html = liquid.parseAndRenderSync(src + src + src + src)
|
||||||
return expect(html).to.equal('1231')
|
return expect(html).toBe('1231')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,8 +1,4 @@
|
|||||||
import { Liquid } from '../../../src/liquid'
|
import { Liquid } from '../../../src/liquid'
|
||||||
import { expect, use } from 'chai'
|
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
|
|
||||||
use(chaiAsPromised)
|
|
||||||
|
|
||||||
describe('tags/decrement', function () {
|
describe('tags/decrement', function () {
|
||||||
const liquid = new Liquid()
|
const liquid = new Liquid()
|
||||||
@@ -10,44 +6,44 @@ describe('tags/decrement', function () {
|
|||||||
it('should decrement undefined variable', async function () {
|
it('should decrement undefined variable', async function () {
|
||||||
const src = '{% decrement var %}{% decrement var %}{% decrement var %}'
|
const src = '{% decrement var %}{% decrement var %}{% decrement var %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('-1-2-3')
|
return expect(html).toBe('-1-2-3')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should decrement defined variable', async function () {
|
it('should decrement defined variable', async function () {
|
||||||
const src = '{% decrement var %}{% decrement var %}{% decrement var %}'
|
const src = '{% decrement var %}{% decrement var %}{% decrement var %}'
|
||||||
const ctx = { 'var': 10 }
|
const ctx = { 'var': 10 }
|
||||||
const html = await liquid.parseAndRender(src, ctx)
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
expect(html).to.equal('987')
|
expect(html).toBe('987')
|
||||||
expect(ctx.var).to.equal(7)
|
expect(ctx.var).toBe(7)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should be independent from assign', async function () {
|
it('should be independent from assign', async function () {
|
||||||
const src = '{% assign var=10 %}{% decrement var %}{% decrement var %}{% decrement var %}'
|
const src = '{% assign var=10 %}{% decrement var %}{% decrement var %}{% decrement var %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('-1-2-3')
|
return expect(html).toBe('-1-2-3')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should be independent from capture', async function () {
|
it('should be independent from capture', async function () {
|
||||||
const src = '{% capture var %}10{% endcapture %}{% decrement var %}{% decrement var %}{% decrement var %}'
|
const src = '{% capture var %}10{% endcapture %}{% decrement var %}{% decrement var %}{% decrement var %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('-1-2-3')
|
return expect(html).toBe('-1-2-3')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should not shading assign', async function () {
|
it('should not shading assign', async function () {
|
||||||
const src = '{% assign var=10 %}{% decrement var %}{% decrement var %}{% decrement var %} {{var}}'
|
const src = '{% assign var=10 %}{% decrement var %}{% decrement var %}{% decrement var %} {{var}}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('-1-2-3 10')
|
return expect(html).toBe('-1-2-3 10')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should not shading capture', async function () {
|
it('should not shading capture', async function () {
|
||||||
const src = '{% capture var %}10{% endcapture %}{% decrement var %}{% decrement var %}{% decrement var %} {{var}}'
|
const src = '{% capture var %}10{% endcapture %}{% decrement var %}{% decrement var %}{% decrement var %} {{var}}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('-1-2-3 10')
|
return expect(html).toBe('-1-2-3 10')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should share the same variable with increment', async function () {
|
it('should share the same variable with increment', async function () {
|
||||||
const src = '{%increment var%}{%increment var%}{%decrement var%}{%decrement var%}{%increment var%}'
|
const src = '{%increment var%}{%increment var%}{%decrement var%}{%decrement var%}{%increment var%}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('01100')
|
return expect(html).toBe('01100')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,8 +1,4 @@
|
|||||||
import { Liquid } from '../../../src/liquid'
|
import { Liquid } from '../../../src/liquid'
|
||||||
import { expect, use } from 'chai'
|
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
|
|
||||||
use(chaiAsPromised)
|
|
||||||
|
|
||||||
describe('tags/echo', function () {
|
describe('tags/echo', function () {
|
||||||
const liquid = new Liquid()
|
const liquid = new Liquid()
|
||||||
@@ -10,25 +6,25 @@ describe('tags/echo', function () {
|
|||||||
it('should output literals', async function () {
|
it('should output literals', async function () {
|
||||||
const src = '{% echo 1 %} {% echo "1" %} {% echo 1.1 %}'
|
const src = '{% echo 1 %} {% echo "1" %} {% echo 1.1 %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('1 1 1.1')
|
return expect(html).toBe('1 1 1.1')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should output variables', async function () {
|
it('should output variables', async function () {
|
||||||
const src = '{% echo people.users[0].name %}'
|
const src = '{% echo people.users[0].name %}'
|
||||||
const html = await liquid.parseAndRender(src, { people: { users: [ { name: 'Sally' } ] } })
|
const html = await liquid.parseAndRender(src, { people: { users: [ { name: 'Sally' } ] } })
|
||||||
return expect(html).to.equal('Sally')
|
return expect(html).toBe('Sally')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should apply filters before output', async function () {
|
it('should apply filters before output', async function () {
|
||||||
const src = '{% echo user.name | upcase | prepend: "Hello, " | append: "!" %}'
|
const src = '{% echo user.name | upcase | prepend: "Hello, " | append: "!" %}'
|
||||||
const html = await liquid.parseAndRender(src, { user: { name: 'Sally' } })
|
const html = await liquid.parseAndRender(src, { user: { name: 'Sally' } })
|
||||||
return expect(html).to.equal('Hello, SALLY!')
|
return expect(html).toBe('Hello, SALLY!')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should handle empty tag', async function () {
|
it('should handle empty tag', async function () {
|
||||||
const src = '{% echo %}'
|
const src = '{% echo %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('')
|
return expect(html).toBe('')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should handle extra whitespace', async function () {
|
it('should handle extra whitespace', async function () {
|
||||||
@@ -38,6 +34,6 @@ describe('tags/echo', function () {
|
|||||||
"Hello, " | append: "!"
|
"Hello, " | append: "!"
|
||||||
%}`
|
%}`
|
||||||
const html = await liquid.parseAndRender(src, { user: { name: 'Sally' } })
|
const html = await liquid.parseAndRender(src, { user: { name: 'Sally' } })
|
||||||
return expect(html).to.equal('Hello, SALLY!')
|
return expect(html).toBe('Hello, SALLY!')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,14 +1,10 @@
|
|||||||
import { expect, use } from 'chai'
|
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
import { Liquid } from '../../../src/liquid'
|
import { Liquid } from '../../../src/liquid'
|
||||||
import { Drop } from '../../../src/drop/drop'
|
import { Drop } from '../../../src/drop/drop'
|
||||||
import { Scope } from '../../../src/context/scope'
|
import { Scope } from '../../../src/context/scope'
|
||||||
|
|
||||||
use(chaiAsPromised)
|
|
||||||
|
|
||||||
describe('tags/for', function () {
|
describe('tags/for', function () {
|
||||||
let liquid: Liquid, scope: Scope
|
let liquid: Liquid, scope: Scope
|
||||||
before(function () {
|
beforeEach(function () {
|
||||||
liquid = new Liquid()
|
liquid = new Liquid()
|
||||||
liquid.registerTag('throwingTag', {
|
liquid.registerTag('throwingTag', {
|
||||||
render: function () { throw new Error('intended render error') }
|
render: function () { throw new Error('intended render error') }
|
||||||
@@ -29,57 +25,57 @@ describe('tags/for', function () {
|
|||||||
it('should support array', async function () {
|
it('should support array', async function () {
|
||||||
const src = '{%for c in alpha%}{{c}}{%endfor%}'
|
const src = '{%for c in alpha%}{{c}}{%endfor%}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('abc')
|
return expect(html).toBe('abc')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support promise of array', async function () {
|
it('should support promise of array', async function () {
|
||||||
const src = '{%for c in promiseArray%}{{c}}{%endfor%}'
|
const src = '{%for c in promiseArray%}{{c}}{%endfor%}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('abc')
|
return expect(html).toBe('abc')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support object', async function () {
|
it('should support object', async function () {
|
||||||
const src = '{%for item in obj%}{{item[0]}},{{item[1]}}-{%else%}b{%endfor%}'
|
const src = '{%for item in obj%}{{item[0]}},{{item[1]}}-{%else%}b{%endfor%}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('foo,bar-coo,haa-')
|
return expect(html).toBe('foo,bar-coo,haa-')
|
||||||
})
|
})
|
||||||
it('should output forloop', async function () {
|
it('should output forloop', async function () {
|
||||||
const src = '{%for i in (1..1)%}{{forloop}}{%endfor%}'
|
const src = '{%for i in (1..1)%}{{forloop}}{%endfor%}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('{"i":0,"length":1,"name":"i-(1..1)"}')
|
return expect(html).toBe('{"i":0,"length":1,"name":"i-(1..1)"}')
|
||||||
})
|
})
|
||||||
it('should output forloop collection name', async function () {
|
it('should output forloop collection name', async function () {
|
||||||
const src = '{%for c in alpha%}{{forloop.name}}-{{c}}{%endfor%}'
|
const src = '{%for c in alpha%}{{forloop.name}}-{{c}}{%endfor%}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('c-alpha-ac-alpha-bc-alpha-c')
|
return expect(html).toBe('c-alpha-ac-alpha-bc-alpha-c')
|
||||||
})
|
})
|
||||||
it('should output forloop property accessor name', async function () {
|
it('should output forloop property accessor name', async function () {
|
||||||
const src = '{%for c in obj.foo%}{{forloop.name}}-{{c}}{%endfor%}'
|
const src = '{%for c in obj.foo%}{{forloop.name}}-{{c}}{%endfor%}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('c-obj.foo-bar')
|
return expect(html).toBe('c-obj.foo-bar')
|
||||||
})
|
})
|
||||||
it('should output forloop quoted name', async function () {
|
it('should output forloop quoted name', async function () {
|
||||||
const src = '{%for str in "string"%}{{forloop.name}}-{{str}}{%endfor%}'
|
const src = '{%for str in "string"%}{{forloop.name}}-{{str}}{%endfor%}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('str-"string"-string')
|
return expect(html).toBe('str-"string"-string')
|
||||||
})
|
})
|
||||||
describe('illegal', function () {
|
describe('illegal', function () {
|
||||||
it('should reject when for not closed', function () {
|
it('should reject when for not closed', function () {
|
||||||
const src = '{%for c in alpha%}{{c}}'
|
const src = '{%for c in alpha%}{{c}}'
|
||||||
return expect(liquid.parseAndRender(src, scope))
|
return expect(liquid.parseAndRender(src, scope))
|
||||||
.to.be.rejectedWith(/tag .* not closed/)
|
.rejects.toThrow(/tag .* not closed/)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should reject when for in not found', function () {
|
it('should reject when for in not found', function () {
|
||||||
const src = '{%for c alpha%}{{c}}'
|
const src = '{%for c alpha%}{{c}}'
|
||||||
return expect(liquid.parseAndRender(src, scope))
|
return expect(liquid.parseAndRender(src, scope))
|
||||||
.to.be.rejectedWith('illegal tag: {%for c alpha%}, line:1, col:1')
|
.rejects.toThrow('illegal tag: {%for c alpha%}, line:1, col:1')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should reject when inner templates rejected', function () {
|
it('should reject when inner templates rejected', function () {
|
||||||
const src = '{%for c in alpha%}{%throwingTag%}{%endfor%}'
|
const src = '{%for c in alpha%}{%throwingTag%}{%endfor%}'
|
||||||
return expect(liquid.parseAndRender(src, scope))
|
return expect(liquid.parseAndRender(src, scope))
|
||||||
.to.be.rejectedWith(/intended render error/)
|
.rejects.toThrow(/intended render error/)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -87,38 +83,38 @@ describe('tags/for', function () {
|
|||||||
it('should goto else for empty array', async function () {
|
it('should goto else for empty array', async function () {
|
||||||
const src = '{%for c in emptyArray%}a{%else%}b{%endfor%}'
|
const src = '{%for c in emptyArray%}a{%else%}b{%endfor%}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('b')
|
return expect(html).toBe('b')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should treat non-empty string as one single element', async function () {
|
it('should treat non-empty string as one single element', async function () {
|
||||||
const src = '{%for c in "abc"%}x{{c}}{%else%}y{%endfor%}'
|
const src = '{%for c in "abc"%}x{{c}}{%else%}y{%endfor%}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('xabc')
|
return expect(html).toBe('xabc')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should goto else for empty string', async function () {
|
it('should goto else for empty string', async function () {
|
||||||
const src = '{%for c in ""%}a{%else%}b{%endfor%}'
|
const src = '{%for c in ""%}a{%else%}b{%endfor%}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('b')
|
return expect(html).toBe('b')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should goto else for empty string object', async function () {
|
it('should goto else for empty string object', async function () {
|
||||||
// it should be false although `new String` is none-conform
|
// it should be false although `new String` is none-conform
|
||||||
const src = '{%for c in strObj%}a{%else%}b{%endfor%}'
|
const src = '{%for c in strObj%}a{%else%}b{%endfor%}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('b')
|
return expect(html).toBe('b')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should goto else for empty object', async function () {
|
it('should goto else for empty object', async function () {
|
||||||
const src = '{%for c in emptyObj%}a{%else%}b{%endfor%}'
|
const src = '{%for c in emptyObj%}a{%else%}b{%endfor%}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('b')
|
return expect(html).toBe('b')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should goto else for null-prototyped object', async function () {
|
it('should goto else for null-prototyped object', async function () {
|
||||||
const src = '{%for c in nullProtoObj%}a{%else%}b{%endfor%}'
|
const src = '{%for c in nullProtoObj%}a{%else%}b{%endfor%}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('b')
|
return expect(html).toBe('b')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -133,7 +129,7 @@ describe('tags/for', function () {
|
|||||||
'false.2.1.false.3.2.1b\n' +
|
'false.2.1.false.3.2.1b\n' +
|
||||||
'false.3.2.true.3.1.0c\n'
|
'false.3.2.true.3.1.0c\n'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal(dst)
|
return expect(html).toBe(dst)
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('continue', function () {
|
describe('continue', function () {
|
||||||
@@ -142,7 +138,7 @@ describe('tags/for', function () {
|
|||||||
'{% if i == 4 %}continue{% continue %}{% endif %}{{i}}' +
|
'{% if i == 4 %}continue{% continue %}{% endif %}{{i}}' +
|
||||||
'{% endfor %}'
|
'{% endfor %}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('123continue5')
|
return expect(html).toBe('123continue5')
|
||||||
})
|
})
|
||||||
it('should output contents before continue', async function () {
|
it('should output contents before continue', async function () {
|
||||||
const src = '{% for i in (1..5) %}' +
|
const src = '{% for i in (1..5) %}' +
|
||||||
@@ -150,7 +146,7 @@ describe('tags/for', function () {
|
|||||||
'{{ i }}' +
|
'{{ i }}' +
|
||||||
'{% endfor %}'
|
'{% endfor %}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('123continue5')
|
return expect(html).toBe('123continue5')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('break', function () {
|
describe('break', function () {
|
||||||
@@ -160,7 +156,7 @@ describe('tags/for', function () {
|
|||||||
'{{ i }}' +
|
'{{ i }}' +
|
||||||
'{% endfor %}'
|
'{% endfor %}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('123')
|
return expect(html).toBe('123')
|
||||||
})
|
})
|
||||||
it('should output contents before break', async function () {
|
it('should output contents before break', async function () {
|
||||||
const src = '{% for i in (1..5) %}' +
|
const src = '{% for i in (1..5) %}' +
|
||||||
@@ -168,7 +164,7 @@ describe('tags/for', function () {
|
|||||||
'{{ i }}' +
|
'{{ i }}' +
|
||||||
'{% endfor %}'
|
'{% endfor %}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('123breaking')
|
return expect(html).toBe('123breaking')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -176,22 +172,22 @@ describe('tags/for', function () {
|
|||||||
it('should support for with limit', async function () {
|
it('should support for with limit', async function () {
|
||||||
const src = '{% for i in (1..5) limit:2 %}{{ i }}{% endfor %}'
|
const src = '{% for i in (1..5) limit:2 %}{{ i }}{% endfor %}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('12')
|
return expect(html).toBe('12')
|
||||||
})
|
})
|
||||||
it('should set forloop.last properly', async function () {
|
it('should set forloop.last properly', async function () {
|
||||||
const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.last}} {%endfor%}'
|
const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.last}} {%endfor%}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('false true ')
|
return expect(html).toBe('false true ')
|
||||||
})
|
})
|
||||||
it('should set forloop.first properly', async function () {
|
it('should set forloop.first properly', async function () {
|
||||||
const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.first}} {%endfor%}'
|
const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.first}} {%endfor%}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('true false ')
|
return expect(html).toBe('true false ')
|
||||||
})
|
})
|
||||||
it('should set forloop.length properly', function () {
|
it('should set forloop.length properly', function () {
|
||||||
const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.length}} {%endfor%}'
|
const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.length}} {%endfor%}'
|
||||||
return expect(liquid.parseAndRender(src, scope))
|
return expect(liquid.parseAndRender(src, scope))
|
||||||
.to.eventually.equal('2 2 ')
|
.resolves.toBe('2 2 ')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -199,48 +195,48 @@ describe('tags/for', function () {
|
|||||||
it('should support offset with limit', async function () {
|
it('should support offset with limit', async function () {
|
||||||
const src = '{% for i in (1..10) limit:2 offset:5%}{{ i }}{% endfor %}'
|
const src = '{% for i in (1..10) limit:2 offset:5%}{{ i }}{% endfor %}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('67')
|
return expect(html).toBe('67')
|
||||||
})
|
})
|
||||||
it('should set index properly', async function () {
|
it('should set index properly', async function () {
|
||||||
const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.index}} {%endfor%}'
|
const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.index}} {%endfor%}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('1 2 ')
|
return expect(html).toBe('1 2 ')
|
||||||
})
|
})
|
||||||
it('should set index0 properly', async function () {
|
it('should set index0 properly', async function () {
|
||||||
const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.index0}} {%endfor%}'
|
const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.index0}} {%endfor%}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('0 1 ')
|
return expect(html).toBe('0 1 ')
|
||||||
})
|
})
|
||||||
it('should set rindex properly', async function () {
|
it('should set rindex properly', async function () {
|
||||||
const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.rindex}} {%endfor%}'
|
const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.rindex}} {%endfor%}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('2 1 ')
|
return expect(html).toBe('2 1 ')
|
||||||
})
|
})
|
||||||
it('should set rindex0 properly', async function () {
|
it('should set rindex0 properly', async function () {
|
||||||
const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.rindex0}} {%endfor%}'
|
const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.rindex0}} {%endfor%}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('1 0 ')
|
return expect(html).toBe('1 0 ')
|
||||||
})
|
})
|
||||||
it('should continue from limit-ed loop', async function () {
|
it('should continue from limit-ed loop', async function () {
|
||||||
const src = '{%for i in arr limit:2%}{{i}}{%endfor%}-{%for i in arr offset:continue%}{{i}}{%endfor%}'
|
const src = '{%for i in arr limit:2%}{{i}}{%endfor%}-{%for i in arr offset:continue%}{{i}}{%endfor%}'
|
||||||
const html = await liquid.parseAndRender(src, { arr: [1, 2, 3, 4, 5] })
|
const html = await liquid.parseAndRender(src, { arr: [1, 2, 3, 4, 5] })
|
||||||
return expect(html).to.equal('12-345')
|
return expect(html).toBe('12-345')
|
||||||
})
|
})
|
||||||
it('should continue nothing for fully iterated loop', async function () {
|
it('should continue nothing for fully iterated loop', async function () {
|
||||||
const src = '{%for i in arr%}{{i}}{%endfor%}-{%for i in arr offset:continue%}{{i}}{%endfor%}'
|
const src = '{%for i in arr%}{{i}}{%endfor%}-{%for i in arr offset:continue%}{{i}}{%endfor%}'
|
||||||
const html = await liquid.parseAndRender(src, { arr: [1, 2, 3, 4, 5] })
|
const html = await liquid.parseAndRender(src, { arr: [1, 2, 3, 4, 5] })
|
||||||
return expect(html).to.equal('12345-')
|
return expect(html).toBe('12345-')
|
||||||
})
|
})
|
||||||
it('should treat different variable names as different forloop', async function () {
|
it('should treat different variable names as different forloop', async function () {
|
||||||
const src = '{%for i in (1..5)%}{{i}}{%endfor%}-{%for j in (1..5) offset:continue%}{{j}}{%endfor%}'
|
const src = '{%for i in (1..5)%}{{i}}{%endfor%}-{%for j in (1..5) offset:continue%}{{j}}{%endfor%}'
|
||||||
const html = await liquid.parseAndRender(src, {})
|
const html = await liquid.parseAndRender(src, {})
|
||||||
return expect(html).to.equal('12345-12345')
|
return expect(html).toBe('12345-12345')
|
||||||
})
|
})
|
||||||
it('should treat different collection names as different forloop', async function () {
|
it('should treat different collection names as different forloop', async function () {
|
||||||
const src = '{%for i in arr1%}{{i}}{%endfor%}-{%for i in arr2 offset:continue%}{{i}}{%endfor%}'
|
const src = '{%for i in arr1%}{{i}}{%endfor%}-{%for i in arr2 offset:continue%}{{i}}{%endfor%}'
|
||||||
const arr = [1, 2, 3, 4, 5]
|
const arr = [1, 2, 3, 4, 5]
|
||||||
const html = await liquid.parseAndRender(src, { arr1: arr, arr2: arr })
|
const html = await liquid.parseAndRender(src, { arr1: arr, arr2: arr })
|
||||||
return expect(html).to.equal('12345-12345')
|
return expect(html).toBe('12345-12345')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -248,33 +244,33 @@ describe('tags/for', function () {
|
|||||||
it('should support for reversed in the last position', async function () {
|
it('should support for reversed in the last position', async function () {
|
||||||
const src = '{% for i in (1..8) limit:2 reversed %}{{ i }}{% endfor %}'
|
const src = '{% for i in (1..8) limit:2 reversed %}{{ i }}{% endfor %}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('21')
|
return expect(html).toBe('21')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support for reversed in the first position', async function () {
|
it('should support for reversed in the first position', async function () {
|
||||||
const src = '{% for i in (1..8) reversed limit:2 %}{{ i }}{% endfor %}'
|
const src = '{% for i in (1..8) reversed limit:2 %}{{ i }}{% endfor %}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('21')
|
return expect(html).toBe('21')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support for reversed in the first position with orderedFilterParameters=true', async function () {
|
it('should support for reversed in the first position with orderedFilterParameters=true', async function () {
|
||||||
const liquid = new Liquid({ orderedFilterParameters: true })
|
const liquid = new Liquid({ orderedFilterParameters: true })
|
||||||
const src = '{% for i in (1..8) reversed limit:2 %}{{ i }}{% endfor %}'
|
const src = '{% for i in (1..8) reversed limit:2 %}{{ i }}{% endfor %}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('87')
|
return expect(html).toBe('87')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support for reversed in the middle position', async function () {
|
it('should support for reversed in the middle position', async function () {
|
||||||
const src = '{% for i in (1..8) offset:2 reversed limit:3 %}{{ i }}{% endfor %}'
|
const src = '{% for i in (1..8) offset:2 reversed limit:3 %}{{ i }}{% endfor %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('543')
|
return expect(html).toBe('543')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support for reversed in the middle position with orderedFilterParameters=true', async function () {
|
it('should support for reversed in the middle position with orderedFilterParameters=true', async function () {
|
||||||
const liquid = new Liquid({ orderedFilterParameters: true })
|
const liquid = new Liquid({ orderedFilterParameters: true })
|
||||||
const src = '{% for i in (1..8) offset:2 reversed limit:3 %}{{ i }}{% endfor %}'
|
const src = '{% for i in (1..8) offset:2 reversed limit:3 %}{{ i }}{% endfor %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('876')
|
return expect(html).toBe('876')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -282,7 +278,7 @@ describe('tags/for', function () {
|
|||||||
it('should support sync', function () {
|
it('should support sync', function () {
|
||||||
const src = '{% for i in (1..5) %}{{i}}{%endfor%}'
|
const src = '{% for i in (1..5) %}{{i}}{%endfor%}'
|
||||||
const html = liquid.parseAndRenderSync(src)
|
const html = liquid.parseAndRenderSync(src)
|
||||||
return expect(html).to.equal('12345')
|
return expect(html).toBe('12345')
|
||||||
})
|
})
|
||||||
it('should output contents before break', function () {
|
it('should output contents before break', function () {
|
||||||
const src = '{% for i in (1..5) %}' +
|
const src = '{% for i in (1..5) %}' +
|
||||||
@@ -290,19 +286,19 @@ describe('tags/for', function () {
|
|||||||
'{{ i }}' +
|
'{{ i }}' +
|
||||||
'{% endfor %}'
|
'{% endfor %}'
|
||||||
const html = liquid.parseAndRenderSync(src, scope)
|
const html = liquid.parseAndRenderSync(src, scope)
|
||||||
return expect(html).to.equal('123breaking')
|
return expect(html).toBe('123breaking')
|
||||||
})
|
})
|
||||||
it('should support for with continue', function () {
|
it('should support for with continue', function () {
|
||||||
const src = '{% for i in (1..5) %}' +
|
const src = '{% for i in (1..5) %}' +
|
||||||
'{% if i == 4 %}continue{% continue %}{% endif %}{{i}}' +
|
'{% if i == 4 %}continue{% continue %}{% endif %}{{i}}' +
|
||||||
'{% endfor %}'
|
'{% endfor %}'
|
||||||
const html = liquid.parseAndRenderSync(src, scope)
|
const html = liquid.parseAndRenderSync(src, scope)
|
||||||
return expect(html).to.equal('123continue5')
|
return expect(html).toBe('123continue5')
|
||||||
})
|
})
|
||||||
it('should goto else for empty array', async function () {
|
it('should goto else for empty array', async function () {
|
||||||
const src = '{%for c in emptyArray%}a{%else%}b{%endfor%}'
|
const src = '{%for c in emptyArray%}a{%else%}b{%endfor%}'
|
||||||
const html = await liquid.parseAndRenderSync(src, scope)
|
const html = await liquid.parseAndRenderSync(src, scope)
|
||||||
return expect(html).to.equal('b')
|
return expect(html).toBe('b')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -333,37 +329,37 @@ describe('tags/for', function () {
|
|||||||
it('should loop over iterable objects', function () {
|
it('should loop over iterable objects', function () {
|
||||||
const src = '{% for i in someIterable %}{{i}}{%endfor%}'
|
const src = '{% for i in someIterable %}{{i}}{%endfor%}'
|
||||||
const html = liquid.parseAndRenderSync(src, { someIterable: new MockIterable() })
|
const html = liquid.parseAndRenderSync(src, { someIterable: new MockIterable() })
|
||||||
return expect(html).to.equal('abc')
|
return expect(html).toBe('abc')
|
||||||
})
|
})
|
||||||
it('should loop over iterable drops', function () {
|
it('should loop over iterable drops', function () {
|
||||||
const src = '{{ someDrop }}: {% for i in someDrop %}{{i}}{%endfor%}'
|
const src = '{{ someDrop }}: {% for i in someDrop %}{{i}}{%endfor%}'
|
||||||
const html = liquid.parseAndRenderSync(src, { someDrop: new MockIterableDrop() })
|
const html = liquid.parseAndRenderSync(src, { someDrop: new MockIterableDrop() })
|
||||||
return expect(html).to.equal('MockIterableDrop: abc')
|
return expect(html).toBe('MockIterableDrop: abc')
|
||||||
})
|
})
|
||||||
it('should loop over iterable objects with a limit', function () {
|
it('should loop over iterable objects with a limit', function () {
|
||||||
const src = '{% for i in someIterable limit:2 %}{{i}}{%endfor%}'
|
const src = '{% for i in someIterable limit:2 %}{{i}}{%endfor%}'
|
||||||
const html = liquid.parseAndRenderSync(src, { someIterable: new MockIterable() })
|
const html = liquid.parseAndRenderSync(src, { someIterable: new MockIterable() })
|
||||||
return expect(html).to.equal('ab')
|
return expect(html).toBe('ab')
|
||||||
})
|
})
|
||||||
it('should loop over iterable objects with an offset', function () {
|
it('should loop over iterable objects with an offset', function () {
|
||||||
const src = '{% for i in someIterable offset:1 %}{{i}}{%endfor%}'
|
const src = '{% for i in someIterable offset:1 %}{{i}}{%endfor%}'
|
||||||
const html = liquid.parseAndRenderSync(src, { someIterable: new MockIterable() })
|
const html = liquid.parseAndRenderSync(src, { someIterable: new MockIterable() })
|
||||||
return expect(html).to.equal('bc')
|
return expect(html).toBe('bc')
|
||||||
})
|
})
|
||||||
it('should loop over iterable objects in reverse', function () {
|
it('should loop over iterable objects in reverse', function () {
|
||||||
const src = '{% for i in someIterable reversed %}{{i}}{%endfor%}'
|
const src = '{% for i in someIterable reversed %}{{i}}{%endfor%}'
|
||||||
const html = liquid.parseAndRenderSync(src, { someIterable: new MockIterable() })
|
const html = liquid.parseAndRenderSync(src, { someIterable: new MockIterable() })
|
||||||
return expect(html).to.equal('cba')
|
return expect(html).toBe('cba')
|
||||||
})
|
})
|
||||||
it('should go to else for an empty iterable', function () {
|
it('should go to else for an empty iterable', function () {
|
||||||
const src = '{% for i in emptyIterable reversed %}{{i}}{%else%}EMPTY{%endfor%}'
|
const src = '{% for i in emptyIterable reversed %}{{i}}{%else%}EMPTY{%endfor%}'
|
||||||
const html = liquid.parseAndRenderSync(src, { emptyIterable: new MockEmptyIterable() })
|
const html = liquid.parseAndRenderSync(src, { emptyIterable: new MockEmptyIterable() })
|
||||||
return expect(html).to.equal('EMPTY')
|
return expect(html).toBe('EMPTY')
|
||||||
})
|
})
|
||||||
it('should support iterable names', function () {
|
it('should support iterable names', function () {
|
||||||
const src = '{% for i in someDrop %}{{forloop.name}} {%else%}EMPTY{%endfor%}'
|
const src = '{% for i in someDrop %}{{forloop.name}} {%else%}EMPTY{%endfor%}'
|
||||||
const html = liquid.parseAndRenderSync(src, { someDrop: new MockIterableDrop() })
|
const html = liquid.parseAndRenderSync(src, { someDrop: new MockIterableDrop() })
|
||||||
return expect(html).to.equal('i-someDrop i-someDrop i-someDrop ')
|
return expect(html).toBe('i-someDrop i-someDrop i-someDrop ')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,9 +1,4 @@
|
|||||||
import { Liquid } from '../../../src/liquid'
|
import { Liquid } from '../../../src/liquid'
|
||||||
import * as chai from 'chai'
|
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
|
|
||||||
const expect = chai.expect
|
|
||||||
chai.use(chaiAsPromised)
|
|
||||||
|
|
||||||
describe('tags/if', function () {
|
describe('tags/if', function () {
|
||||||
const liquid = new Liquid()
|
const liquid = new Liquid()
|
||||||
@@ -17,67 +12,67 @@ describe('tags/if', function () {
|
|||||||
it('should throw if not closed', function () {
|
it('should throw if not closed', function () {
|
||||||
const src = '{% if false%}yes'
|
const src = '{% if false%}yes'
|
||||||
return expect(liquid.parseAndRender(src, scope))
|
return expect(liquid.parseAndRender(src, scope))
|
||||||
.to.be.rejectedWith(/tag {% if false%} not closed/)
|
.rejects.toThrow(/tag {% if false%} not closed/)
|
||||||
})
|
})
|
||||||
it('should support nested', async function () {
|
it('should support nested', async function () {
|
||||||
const src = '{%if false%}{%if true%}{%else%}a{%endif%}{%endif%}'
|
const src = '{%if false%}{%if true%}{%else%}a{%endif%}{%endif%}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('')
|
return expect(html).toBe('')
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('single value as condition', function () {
|
describe('single value as condition', function () {
|
||||||
it('should support boolean', async function () {
|
it('should support boolean', async function () {
|
||||||
const src = '{% if false %}1{%elsif true%}2{%else%}3{%endif%}'
|
const src = '{% if false %}1{%elsif true%}2{%else%}3{%endif%}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('2')
|
return expect(html).toBe('2')
|
||||||
})
|
})
|
||||||
it('should treat Array truthy', async function () {
|
it('should treat Array truthy', async function () {
|
||||||
const src = '{%if emptyArray%}a{%endif%}'
|
const src = '{%if emptyArray%}a{%endif%}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('a')
|
return expect(html).toBe('a')
|
||||||
})
|
})
|
||||||
it('should return true if empty string', async function () {
|
it('should return true if empty string', async function () {
|
||||||
const src = '{%if emptyString%}a{%endif%}'
|
const src = '{%if emptyString%}a{%endif%}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('a')
|
return expect(html).toBe('a')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('expression as condition', function () {
|
describe('expression as condition', function () {
|
||||||
it('should support ==', async function () {
|
it('should support ==', async function () {
|
||||||
const src = '{% if 2 == 3 %}yes{%else%}no{%endif%}'
|
const src = '{% if 2 == 3 %}yes{%else%}no{%endif%}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('no')
|
return expect(html).toBe('no')
|
||||||
})
|
})
|
||||||
it('should support >=', async function () {
|
it('should support >=', async function () {
|
||||||
const src = '{% if 1 >= 2 and one<two %}a{%endif%}'
|
const src = '{% if 1 >= 2 and one<two %}a{%endif%}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('')
|
return expect(html).toBe('')
|
||||||
})
|
})
|
||||||
it('should support !=', async function () {
|
it('should support !=', async function () {
|
||||||
const src = '{% if one != two %}yes{%else%}no{%endif%}'
|
const src = '{% if one != two %}yes{%else%}no{%endif%}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('yes')
|
return expect(html).toBe('yes')
|
||||||
})
|
})
|
||||||
it('should support value and expression', async function () {
|
it('should support value and expression', async function () {
|
||||||
const src = `X{%if version and version != '' %}x{{version}}y{%endif%}Y`
|
const src = `X{%if version and version != '' %}x{{version}}y{%endif%}Y`
|
||||||
const scope = { 'version': '' }
|
const scope = { 'version': '' }
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('XY')
|
return expect(html).toBe('XY')
|
||||||
})
|
})
|
||||||
it('should evaluate right to left', async function () {
|
it('should evaluate right to left', async function () {
|
||||||
const src = `{% if false and false or true %}true{%endif%}`
|
const src = `{% if false and false or true %}true{%endif%}`
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('')
|
return expect(html).toBe('')
|
||||||
})
|
})
|
||||||
it('should allow no spaces around operator for literal', async function () {
|
it('should allow no spaces around operator for literal', async function () {
|
||||||
const src = `{% if true==true %}success{%else%}fail{% endif %}`
|
const src = `{% if true==true %}success{%else%}fail{% endif %}`
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('success')
|
return expect(html).toBe('success')
|
||||||
})
|
})
|
||||||
it('should allow no spaces around operator for variables', async function () {
|
it('should allow no spaces around operator for variables', async function () {
|
||||||
const src = `{%assign var = 1%}{%if var ==1%}success{%else%}fail{%endif%}`
|
const src = `{%assign var = 1%}{%if var ==1%}success{%else%}fail{%endif%}`
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('success')
|
return expect(html).toBe('success')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('filters as condition', function () {
|
describe('filters as condition', function () {
|
||||||
@@ -85,67 +80,67 @@ describe('tags/if', function () {
|
|||||||
liquid.registerFilter('negate', (val) => !val)
|
liquid.registerFilter('negate', (val) => !val)
|
||||||
const src = '{% if 2 == 3 | negate %}yes{%else%}no{%endif%}'
|
const src = '{% if 2 == 3 | negate %}yes{%else%}no{%endif%}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('yes')
|
return expect(html).toBe('yes')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('compare to null', function () {
|
describe('compare to null', function () {
|
||||||
it('should evaluate false for null < 10', async function () {
|
it('should evaluate false for null < 10', async function () {
|
||||||
const src = '{% if null < 10 %}yes{% else %}no{% endif %}'
|
const src = '{% if null < 10 %}yes{% else %}no{% endif %}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('no')
|
return expect(html).toBe('no')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should evaluate false for null > 10', async function () {
|
it('should evaluate false for null > 10', async function () {
|
||||||
const src = '{% if null > 10 %}yes{% else %}no{% endif %}'
|
const src = '{% if null > 10 %}yes{% else %}no{% endif %}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('no')
|
return expect(html).toBe('no')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should evaluate false for null <= 10', async function () {
|
it('should evaluate false for null <= 10', async function () {
|
||||||
const src = '{% if null <= 10 %}yes{% else %}no{% endif %}'
|
const src = '{% if null <= 10 %}yes{% else %}no{% endif %}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('no')
|
return expect(html).toBe('no')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should evaluate false for null >= 10', async function () {
|
it('should evaluate false for null >= 10', async function () {
|
||||||
const src = '{% if null >= 10 %}yes{% else %}no{% endif %}'
|
const src = '{% if null >= 10 %}yes{% else %}no{% endif %}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('no')
|
return expect(html).toBe('no')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should evaluate false for 10 < null', async function () {
|
it('should evaluate false for 10 < null', async function () {
|
||||||
const src = '{% if 10 < null %}yes{% else %}no{% endif %}'
|
const src = '{% if 10 < null %}yes{% else %}no{% endif %}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('no')
|
return expect(html).toBe('no')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should evaluate false for 10 > null', async function () {
|
it('should evaluate false for 10 > null', async function () {
|
||||||
const src = '{% if 10 > null %}yes{% else %}no{% endif %}'
|
const src = '{% if 10 > null %}yes{% else %}no{% endif %}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('no')
|
return expect(html).toBe('no')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should evaluate false for 10 <= null', async function () {
|
it('should evaluate false for 10 <= null', async function () {
|
||||||
const src = '{% if 10 <= null %}yes{% else %}no{% endif %}'
|
const src = '{% if 10 <= null %}yes{% else %}no{% endif %}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('no')
|
return expect(html).toBe('no')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should evaluate false for 10 >= null', async function () {
|
it('should evaluate false for 10 >= null', async function () {
|
||||||
const src = '{% if 10 >= null %}yes{% else %}no{% endif %}'
|
const src = '{% if 10 >= null %}yes{% else %}no{% endif %}'
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('no')
|
return expect(html).toBe('no')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
it('should support sync', function () {
|
it('should support sync', function () {
|
||||||
const src = '{%if true%}true{%else%}false{%endif%}'
|
const src = '{%if true%}true{%else%}false{%endif%}'
|
||||||
const html = liquid.parseAndRenderSync(src, scope)
|
const html = liquid.parseAndRenderSync(src, scope)
|
||||||
return expect(html).to.equal('true')
|
return expect(html).toBe('true')
|
||||||
})
|
})
|
||||||
it('should support async variables', async () => {
|
it('should support async variables', async () => {
|
||||||
const src = `{%if var == 'var' %}success{%endif%}`
|
const src = `{%if var == 'var' %}success{%endif%}`
|
||||||
const scope = { 'var': Promise.resolve('var') }
|
const scope = { 'var': Promise.resolve('var') }
|
||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).to.equal('success')
|
return expect(html).toBe('success')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
import { Liquid } from '../../../src/liquid'
|
import { Liquid } from '../../../src/liquid'
|
||||||
import { Drop } from '../../../src/drop/drop'
|
import { Drop } from '../../../src/drop/drop'
|
||||||
import { expect } from 'chai'
|
|
||||||
import { mock, restore } from '../../stub/mockfs'
|
import { mock, restore } from '../../stub/mockfs'
|
||||||
|
|
||||||
describe('tags/include', function () {
|
describe('tags/include', function () {
|
||||||
let liquid: Liquid
|
let liquid: Liquid
|
||||||
before(function () {
|
beforeEach(function () {
|
||||||
liquid = new Liquid({
|
liquid = new Liquid({
|
||||||
root: '/',
|
root: '/',
|
||||||
extname: '.html'
|
extname: '.html'
|
||||||
@@ -18,7 +17,7 @@ describe('tags/include', function () {
|
|||||||
'/bar/foo.html': 'foo'
|
'/bar/foo.html': 'foo'
|
||||||
})
|
})
|
||||||
const html = await liquid.renderFile('/current.html')
|
const html = await liquid.renderFile('/current.html')
|
||||||
return expect(html).to.equal('barfoobar')
|
return expect(html).toBe('barfoobar')
|
||||||
})
|
})
|
||||||
it('should support relative reference', async function () {
|
it('should support relative reference', async function () {
|
||||||
mock({
|
mock({
|
||||||
@@ -26,7 +25,7 @@ describe('tags/include', function () {
|
|||||||
'/foo/coo/foo.html': 'foo'
|
'/foo/coo/foo.html': 'foo'
|
||||||
})
|
})
|
||||||
const html = await liquid.renderFile('/foo/bar/current.html')
|
const html = await liquid.renderFile('/foo/bar/current.html')
|
||||||
return expect(html).to.equal('barfoobar')
|
return expect(html).toBe('barfoobar')
|
||||||
})
|
})
|
||||||
it('should support template string', async function () {
|
it('should support template string', async function () {
|
||||||
mock({
|
mock({
|
||||||
@@ -34,7 +33,7 @@ describe('tags/include', function () {
|
|||||||
'/bar/foo.html': 'foo'
|
'/bar/foo.html': 'foo'
|
||||||
})
|
})
|
||||||
const html = await liquid.renderFile('/current.html', { name: 'foo.html' })
|
const html = await liquid.renderFile('/current.html', { name: 'foo.html' })
|
||||||
return expect(html).to.equal('barfoobar')
|
return expect(html).toBe('barfoobar')
|
||||||
})
|
})
|
||||||
it('should allow escape in template string', async function () {
|
it('should allow escape in template string', async function () {
|
||||||
mock({
|
mock({
|
||||||
@@ -42,7 +41,7 @@ describe('tags/include', function () {
|
|||||||
'/bar/foo.html': 'foo'
|
'/bar/foo.html': 'foo'
|
||||||
})
|
})
|
||||||
const html = await liquid.renderFile('/current.html', { name: 'foo' })
|
const html = await liquid.renderFile('/current.html', { name: 'foo' })
|
||||||
return expect(html).to.equal('barfoobar')
|
return expect(html).toBe('barfoobar')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should throw when not specified', function () {
|
it('should throw when not specified', function () {
|
||||||
@@ -50,8 +49,8 @@ describe('tags/include', function () {
|
|||||||
'/parent.html': '{%include , %}'
|
'/parent.html': '{%include , %}'
|
||||||
})
|
})
|
||||||
return liquid.renderFile('/parent.html').catch(function (e) {
|
return liquid.renderFile('/parent.html').catch(function (e) {
|
||||||
expect(e.name).to.equal('ParseError')
|
expect(e.name).toBe('ParseError')
|
||||||
expect(e.message).to.match(/illegal argument ","/)
|
expect(e.message).toMatch(/illegal argument ","/)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -60,8 +59,8 @@ describe('tags/include', function () {
|
|||||||
'/parent.html': '{%include not-exist%}'
|
'/parent.html': '{%include not-exist%}'
|
||||||
})
|
})
|
||||||
return liquid.renderFile('/parent.html').catch(function (e) {
|
return liquid.renderFile('/parent.html').catch(function (e) {
|
||||||
expect(e.name).to.equal('RenderError')
|
expect(e.name).toBe('RenderError')
|
||||||
expect(e.message).to.match(/illegal filename "undefined"/)
|
expect(e.message).toMatch(/illegal filename "undefined"/)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -71,7 +70,7 @@ describe('tags/include', function () {
|
|||||||
'/foo/relative.html': 'bar{% include "../bar/foo.html" %}bar'
|
'/foo/relative.html': 'bar{% include "../bar/foo.html" %}bar'
|
||||||
})
|
})
|
||||||
const html = await liquid.renderFile('foo/relative.html')
|
const html = await liquid.renderFile('foo/relative.html')
|
||||||
return expect(html).to.equal('barfoobar')
|
return expect(html).toBe('barfoobar')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support include: hash list', async function () {
|
it('should support include: hash list', async function () {
|
||||||
@@ -80,7 +79,7 @@ describe('tags/include', function () {
|
|||||||
'/user.html': '{{name}} : {{role}} : {{alias}}'
|
'/user.html': '{{name}} : {{role}} : {{alias}}'
|
||||||
})
|
})
|
||||||
const html = await liquid.renderFile('hash.html')
|
const html = await liquid.renderFile('hash.html')
|
||||||
return expect(html).to.equal('harttle : admin : harttle')
|
return expect(html).toBe('harttle : admin : harttle')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support include: parent scope', async function () {
|
it('should support include: parent scope', async function () {
|
||||||
@@ -89,7 +88,7 @@ describe('tags/include', function () {
|
|||||||
'/color.html': 'color:{{color}}, shape:{{shape}}'
|
'/color.html': 'color:{{color}}, shape:{{shape}}'
|
||||||
})
|
})
|
||||||
const html = await liquid.renderFile('scope.html')
|
const html = await liquid.renderFile('scope.html')
|
||||||
return expect(html).to.equal('color:yellow, shape:triangle')
|
return expect(html).toBe('color:yellow, shape:triangle')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support include: with', async function () {
|
it('should support include: with', async function () {
|
||||||
@@ -98,7 +97,7 @@ describe('tags/include', function () {
|
|||||||
'/color.html': 'color:{{color}}, shape:{{shape}}'
|
'/color.html': 'color:{{color}}, shape:{{shape}}'
|
||||||
})
|
})
|
||||||
const html = await liquid.renderFile('with.html')
|
const html = await liquid.renderFile('with.html')
|
||||||
return expect(html).to.equal('color:red, shape:rect')
|
return expect(html).toBe('color:red, shape:rect')
|
||||||
})
|
})
|
||||||
it('should ignore if with value not specified', async function () {
|
it('should ignore if with value not specified', async function () {
|
||||||
mock({
|
mock({
|
||||||
@@ -106,7 +105,7 @@ describe('tags/include', function () {
|
|||||||
'/color.html': 'color:{{color}}, shape:{{shape}}'
|
'/color.html': 'color:{{color}}, shape:{{shape}}'
|
||||||
})
|
})
|
||||||
const html = await liquid.renderFile('with.html')
|
const html = await liquid.renderFile('with.html')
|
||||||
return expect(html).to.equal('color:, shape:rect')
|
return expect(html).toBe('color:, shape:rect')
|
||||||
})
|
})
|
||||||
it('should treat with as a valid key', async function () {
|
it('should treat with as a valid key', async function () {
|
||||||
mock({
|
mock({
|
||||||
@@ -114,7 +113,7 @@ describe('tags/include', function () {
|
|||||||
'/color.html': 'with:{{with}}'
|
'/color.html': 'with:{{with}}'
|
||||||
})
|
})
|
||||||
const html = await liquid.renderFile('with.html')
|
const html = await liquid.renderFile('with.html')
|
||||||
return expect(html).to.equal('with:foo')
|
return expect(html).toBe('with:foo')
|
||||||
})
|
})
|
||||||
it('should support include: with as Drop', async function () {
|
it('should support include: with as Drop', async function () {
|
||||||
class ColorDrop extends Drop {
|
class ColorDrop extends Drop {
|
||||||
@@ -127,7 +126,7 @@ describe('tags/include', function () {
|
|||||||
'/color.html': 'color:{{color}}'
|
'/color.html': 'color:{{color}}'
|
||||||
})
|
})
|
||||||
const html = await liquid.renderFile('with.html', { color: new ColorDrop() })
|
const html = await liquid.renderFile('with.html', { color: new ColorDrop() })
|
||||||
expect(html).to.equal('color:red!')
|
expect(html).toBe('color:red!')
|
||||||
})
|
})
|
||||||
it('should support include: with passed as Drop', async function () {
|
it('should support include: with passed as Drop', async function () {
|
||||||
class ColorDrop extends Drop {
|
class ColorDrop extends Drop {
|
||||||
@@ -141,7 +140,7 @@ describe('tags/include', function () {
|
|||||||
'/color.html': '{{color | name}}'
|
'/color.html': '{{color | name}}'
|
||||||
})
|
})
|
||||||
const html = await liquid.renderFile('with.html', { color: new ColorDrop() })
|
const html = await liquid.renderFile('with.html', { color: new ColorDrop() })
|
||||||
expect(html).to.equal('ColorDrop')
|
expect(html).toBe('ColorDrop')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support nested includes', async function () {
|
it('should support nested includes', async function () {
|
||||||
@@ -160,7 +159,7 @@ describe('tags/include', function () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const html = await liquid.renderFile('personInfo.html', ctx)
|
const html = await liquid.renderFile('personInfo.html', ctx)
|
||||||
return expect(html).to.equal('This is a person <p>Joe Shmoe<br/>City: Dallas</p>')
|
return expect(html).toBe('This is a person <p>Joe Shmoe<br/>City: Dallas</p>')
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('static partial', function () {
|
describe('static partial', function () {
|
||||||
@@ -171,7 +170,7 @@ describe('tags/include', function () {
|
|||||||
})
|
})
|
||||||
const staticLiquid = new Liquid({ dynamicPartials: false, root: '/' })
|
const staticLiquid = new Liquid({ dynamicPartials: false, root: '/' })
|
||||||
const html = await staticLiquid.renderFile('parent.html')
|
const html = await staticLiquid.renderFile('parent.html')
|
||||||
return expect(html).to.equal('Xchild with redY')
|
return expect(html).toBe('Xchild with redY')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support parent paths', async function () {
|
it('should support parent paths', async function () {
|
||||||
@@ -181,7 +180,7 @@ describe('tags/include', function () {
|
|||||||
})
|
})
|
||||||
const staticLiquid = new Liquid({ dynamicPartials: false, root: '/' })
|
const staticLiquid = new Liquid({ dynamicPartials: false, root: '/' })
|
||||||
const html = await staticLiquid.renderFile('parent.html')
|
const html = await staticLiquid.renderFile('parent.html')
|
||||||
return expect(html).to.equal('XchildY')
|
return expect(html).toBe('XchildY')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support subpaths', async function () {
|
it('should support subpaths', async function () {
|
||||||
@@ -191,7 +190,7 @@ describe('tags/include', function () {
|
|||||||
})
|
})
|
||||||
const staticLiquid = new Liquid({ dynamicPartials: false, root: '/' })
|
const staticLiquid = new Liquid({ dynamicPartials: false, root: '/' })
|
||||||
const html = await staticLiquid.renderFile('parent.html')
|
const html = await staticLiquid.renderFile('parent.html')
|
||||||
return expect(html).to.equal('XchildY')
|
return expect(html).toBe('XchildY')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support comma separated arguments', async function () {
|
it('should support comma separated arguments', async function () {
|
||||||
@@ -201,7 +200,7 @@ describe('tags/include', function () {
|
|||||||
})
|
})
|
||||||
const staticLiquid = new Liquid({ dynamicPartials: false, root: '/' })
|
const staticLiquid = new Liquid({ dynamicPartials: false, root: '/' })
|
||||||
const html = await staticLiquid.renderFile('parent.html')
|
const html = await staticLiquid.renderFile('parent.html')
|
||||||
return expect(html).to.equal('Xchild with redY')
|
return expect(html).toBe('Xchild with redY')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support single liquid output', async function () {
|
it('should support single liquid output', async function () {
|
||||||
@@ -211,7 +210,7 @@ describe('tags/include', function () {
|
|||||||
})
|
})
|
||||||
const staticLiquid = new Liquid({ dynamicPartials: false, root: '/' })
|
const staticLiquid = new Liquid({ dynamicPartials: false, root: '/' })
|
||||||
const html = await staticLiquid.renderFile('parent.html', { child: 'child.html' })
|
const html = await staticLiquid.renderFile('parent.html', { child: 'child.html' })
|
||||||
return expect(html).to.equal('Xchild with redY')
|
return expect(html).toBe('Xchild with redY')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('sync support', function () {
|
describe('sync support', function () {
|
||||||
@@ -221,7 +220,7 @@ describe('tags/include', function () {
|
|||||||
'/bar/foo.html': 'foo'
|
'/bar/foo.html': 'foo'
|
||||||
})
|
})
|
||||||
const html = liquid.renderFileSync('/current.html')
|
const html = liquid.renderFileSync('/current.html')
|
||||||
return expect(html).to.equal('barfoobar')
|
return expect(html).toBe('barfoobar')
|
||||||
})
|
})
|
||||||
it('should support variable', function () {
|
it('should support variable', function () {
|
||||||
mock({
|
mock({
|
||||||
@@ -229,7 +228,7 @@ describe('tags/include', function () {
|
|||||||
'/bar/foo.html': 'foo'
|
'/bar/foo.html': 'foo'
|
||||||
})
|
})
|
||||||
const html = liquid.renderFileSync('/current.html', { name: '/bar/foo.html' })
|
const html = liquid.renderFileSync('/current.html', { name: '/bar/foo.html' })
|
||||||
return expect(html).to.equal('barfoobar')
|
return expect(html).toBe('barfoobar')
|
||||||
})
|
})
|
||||||
it('should support include: with', function () {
|
it('should support include: with', function () {
|
||||||
mock({
|
mock({
|
||||||
@@ -237,7 +236,7 @@ describe('tags/include', function () {
|
|||||||
'/color.html': 'color:{{color}}, shape:{{shape}}'
|
'/color.html': 'color:{{color}}, shape:{{shape}}'
|
||||||
})
|
})
|
||||||
const html = liquid.renderFileSync('with.html')
|
const html = liquid.renderFileSync('with.html')
|
||||||
return expect(html).to.equal('color:red, shape:rect')
|
return expect(html).toBe('color:red, shape:rect')
|
||||||
})
|
})
|
||||||
it('should support filename with extension', function () {
|
it('should support filename with extension', function () {
|
||||||
mock({
|
mock({
|
||||||
@@ -246,12 +245,12 @@ describe('tags/include', function () {
|
|||||||
})
|
})
|
||||||
const staticLiquid = new Liquid({ dynamicPartials: false, root: '/' })
|
const staticLiquid = new Liquid({ dynamicPartials: false, root: '/' })
|
||||||
const html = staticLiquid.renderFileSync('parent.html')
|
const html = staticLiquid.renderFileSync('parent.html')
|
||||||
return expect(html).to.equal('Xchild with redY')
|
return expect(html).toBe('Xchild with redY')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('Jekyll include', function () {
|
describe('Jekyll include', function () {
|
||||||
before(function () {
|
beforeEach(function () {
|
||||||
liquid = new Liquid({
|
liquid = new Liquid({
|
||||||
root: '/',
|
root: '/',
|
||||||
extname: '.html',
|
extname: '.html',
|
||||||
@@ -264,7 +263,7 @@ describe('tags/include', function () {
|
|||||||
'/bar/foo.html': '{{include.content}}-{{content}}'
|
'/bar/foo.html': '{{include.content}}-{{content}}'
|
||||||
})
|
})
|
||||||
const html = liquid.renderFileSync('/current.html')
|
const html = liquid.renderFileSync('/current.html')
|
||||||
return expect(html).to.equal('FOO-')
|
return expect(html).toBe('FOO-')
|
||||||
})
|
})
|
||||||
it('should support multiple parameters', function () {
|
it('should support multiple parameters', function () {
|
||||||
mock({
|
mock({
|
||||||
@@ -272,7 +271,7 @@ describe('tags/include', function () {
|
|||||||
'/bar/foo.html': '<h2>{{include.header}}</h2>{{include.content}}'
|
'/bar/foo.html': '<h2>{{include.header}}</h2>{{include.content}}'
|
||||||
})
|
})
|
||||||
const html = liquid.renderFileSync('/current.html')
|
const html = liquid.renderFileSync('/current.html')
|
||||||
return expect(html).to.equal('<h2>HEADER</h2>CONTENT')
|
return expect(html).toBe('<h2>HEADER</h2>CONTENT')
|
||||||
})
|
})
|
||||||
it('should support dynamicPartials=true', function () {
|
it('should support dynamicPartials=true', function () {
|
||||||
mock({
|
mock({
|
||||||
@@ -286,7 +285,7 @@ describe('tags/include', function () {
|
|||||||
dynamicPartials: true
|
dynamicPartials: true
|
||||||
})
|
})
|
||||||
const html = liquid.renderFileSync('/current.html')
|
const html = liquid.renderFileSync('/current.html')
|
||||||
return expect(html).to.equal('FOO-')
|
return expect(html).toBe('FOO-')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,8 +1,4 @@
|
|||||||
import { Liquid } from '../../../src/liquid'
|
import { Liquid } from '../../../src/liquid'
|
||||||
import { expect, use } from 'chai'
|
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
|
|
||||||
use(chaiAsPromised)
|
|
||||||
|
|
||||||
describe('tags/increment', function () {
|
describe('tags/increment', function () {
|
||||||
const liquid = new Liquid()
|
const liquid = new Liquid()
|
||||||
@@ -10,38 +6,38 @@ describe('tags/increment', function () {
|
|||||||
it('should increment undefined variable', async function () {
|
it('should increment undefined variable', async function () {
|
||||||
const src = '{% increment one %}{% increment one %}{% increment one %}'
|
const src = '{% increment one %}{% increment one %}{% increment one %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('012')
|
return expect(html).toBe('012')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should increment defined variable', async function () {
|
it('should increment defined variable', async function () {
|
||||||
const src = '{% increment one %}{% increment one %}{% increment one %}'
|
const src = '{% increment one %}{% increment one %}{% increment one %}'
|
||||||
const ctx = { one: 7 }
|
const ctx = { one: 7 }
|
||||||
const html = await liquid.parseAndRender(src, ctx)
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
expect(html).to.equal('789')
|
expect(html).toBe('789')
|
||||||
expect(ctx.one).to.equal(10)
|
expect(ctx.one).toBe(10)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should be independent from assign', async function () {
|
it('should be independent from assign', async function () {
|
||||||
const src = '{% assign var=10 %}{% increment var %}{% increment var %}{% increment var %}'
|
const src = '{% assign var=10 %}{% increment var %}{% increment var %}{% increment var %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('012')
|
return expect(html).toBe('012')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should be independent from capture', async function () {
|
it('should be independent from capture', async function () {
|
||||||
const src = '{% capture var %}10{% endcapture %}{% increment var %}{% increment var %}{% increment var %}'
|
const src = '{% capture var %}10{% endcapture %}{% increment var %}{% increment var %}{% increment var %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('012')
|
return expect(html).toBe('012')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should not shading assign', async function () {
|
it('should not shading assign', async function () {
|
||||||
const src = '{% assign var=10 %}{% increment var %}{% increment var %}{% increment var %} {{var}}'
|
const src = '{% assign var=10 %}{% increment var %}{% increment var %}{% increment var %} {{var}}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('012 10')
|
return expect(html).toBe('012 10')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should not hide capture', async function () {
|
it('should not hide capture', async function () {
|
||||||
const src = '{% capture var %}10{% endcapture %}{% increment var %}{% increment var %}{% increment var %} {{var}}'
|
const src = '{% capture var %}10{% endcapture %}{% increment var %}{% increment var %}{% increment var %} {{var}}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('012 10')
|
return expect(html).toBe('012 10')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
+11
-15
@@ -1,40 +1,36 @@
|
|||||||
import { Liquid } from '../../../src/liquid'
|
import { Liquid } from '../../../src/liquid'
|
||||||
import { expect, use } from 'chai'
|
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
|
|
||||||
use(chaiAsPromised)
|
|
||||||
|
|
||||||
describe('tags/inline-comment', function () {
|
describe('tags/inline-comment', function () {
|
||||||
const liquid = new Liquid()
|
const liquid = new Liquid()
|
||||||
it('should ignore plain string', async function () {
|
it('should ignore plain string', async function () {
|
||||||
const src = 'My name is {% # super %} Shopify.'
|
const src = 'My name is {% # super %} Shopify.'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('My name is Shopify.')
|
return expect(html).toBe('My name is Shopify.')
|
||||||
})
|
})
|
||||||
it('should ignore output tokens', async function () {
|
it('should ignore output tokens', async function () {
|
||||||
const src = '{% #\n{{ foo}} \n %}'
|
const src = '{% #\n{{ foo}} \n %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('')
|
return expect(html).toBe('')
|
||||||
})
|
})
|
||||||
it('should support whitespace control', async function () {
|
it('should support whitespace control', async function () {
|
||||||
const src = '{%- # some comment \n -%}\nfoo'
|
const src = '{%- # some comment \n -%}\nfoo'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('foo')
|
return expect(html).toBe('foo')
|
||||||
})
|
})
|
||||||
it('should handle hash without trailing whitespace', async function () {
|
it('should handle hash without trailing whitespace', async function () {
|
||||||
const src = '{% #some comment %}'
|
const src = '{% #some comment %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('')
|
return expect(html).toBe('')
|
||||||
})
|
})
|
||||||
it('should handle hash without leading whitespace', async function () {
|
it('should handle hash without leading whitespace', async function () {
|
||||||
const src = '{%#some comment %}'
|
const src = '{%#some comment %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('')
|
return expect(html).toBe('')
|
||||||
})
|
})
|
||||||
it('should handle empty comment', async function () {
|
it('should handle empty comment', async function () {
|
||||||
const src = '{%#%}'
|
const src = '{%#%}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('')
|
return expect(html).toBe('')
|
||||||
})
|
})
|
||||||
it('should support multiple lines', async function () {
|
it('should support multiple lines', async function () {
|
||||||
const src = [
|
const src = [
|
||||||
@@ -44,7 +40,7 @@ describe('tags/inline-comment', function () {
|
|||||||
'-%}'
|
'-%}'
|
||||||
].join('\n')
|
].join('\n')
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('')
|
return expect(html).toBe('')
|
||||||
})
|
})
|
||||||
it('should enforce leading hashes', async function () {
|
it('should enforce leading hashes', async function () {
|
||||||
const src = [
|
const src = [
|
||||||
@@ -54,13 +50,13 @@ describe('tags/inline-comment', function () {
|
|||||||
'-%}'
|
'-%}'
|
||||||
].join('\n')
|
].join('\n')
|
||||||
return expect(liquid.parseAndRender(src))
|
return expect(liquid.parseAndRender(src))
|
||||||
.to.be.rejectedWith(/every line of an inline comment must start with a '#' character/)
|
.rejects.toThrow(/every line of an inline comment must start with a '#' character/)
|
||||||
})
|
})
|
||||||
describe('sync support', function () {
|
describe('sync support', function () {
|
||||||
it('should ignore plain string', function () {
|
it('should ignore plain string', function () {
|
||||||
const src = 'My name is {% # super %} Shopify.'
|
const src = 'My name is {% # super %} Shopify.'
|
||||||
const html = liquid.parseAndRenderSync(src)
|
const html = liquid.parseAndRenderSync(src)
|
||||||
return expect(html).to.equal('My name is Shopify.')
|
return expect(html).toBe('My name is Shopify.')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('liquid tag', function () {
|
describe('liquid tag', function () {
|
||||||
@@ -78,7 +74,7 @@ describe('tags/inline-comment', function () {
|
|||||||
'-%}'
|
'-%}'
|
||||||
].join('\n')
|
].join('\n')
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('Hello goodbye')
|
return expect(html).toBe('Hello goodbye')
|
||||||
})
|
})
|
||||||
it('should handle lots of hashes', async function () {
|
it('should handle lots of hashes', async function () {
|
||||||
const src = [
|
const src = [
|
||||||
@@ -89,7 +85,7 @@ describe('tags/inline-comment', function () {
|
|||||||
'-%}'
|
'-%}'
|
||||||
].join('\n')
|
].join('\n')
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('')
|
return expect(html).toBe('')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,13 +1,9 @@
|
|||||||
import { expect, use } from 'chai'
|
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
import { Liquid } from '../../../src/liquid'
|
import { Liquid } from '../../../src/liquid'
|
||||||
import { mock, restore } from '../../stub/mockfs'
|
import { mock, restore } from '../../stub/mockfs'
|
||||||
|
|
||||||
use(chaiAsPromised)
|
|
||||||
|
|
||||||
describe('tags/layout', function () {
|
describe('tags/layout', function () {
|
||||||
let liquid: Liquid
|
let liquid: Liquid
|
||||||
before(function () {
|
beforeEach(function () {
|
||||||
liquid = new Liquid({
|
liquid = new Liquid({
|
||||||
root: '/',
|
root: '/',
|
||||||
extname: '.html'
|
extname: '.html'
|
||||||
@@ -20,16 +16,15 @@ describe('tags/layout', function () {
|
|||||||
'/parent.html': 'parent'
|
'/parent.html': 'parent'
|
||||||
})
|
})
|
||||||
const src = '{% layout "parent" %}{%block%}A'
|
const src = '{% layout "parent" %}{%block%}A'
|
||||||
return expect(liquid.parseAndRender(src)).to
|
return expect(liquid.parseAndRender(src)).rejects.toThrow(/tag {%block%} not closed/)
|
||||||
.be.rejectedWith(/tag {%block%} not closed/)
|
|
||||||
})
|
})
|
||||||
it('should throw when filename not specified', function () {
|
it('should throw when filename not specified', function () {
|
||||||
mock({
|
mock({
|
||||||
'/parent.html': '{%layout%}'
|
'/parent.html': '{%layout%}'
|
||||||
})
|
})
|
||||||
return liquid.renderFile('/parent.html').catch(function (e) {
|
return liquid.renderFile('/parent.html').catch(function (e) {
|
||||||
expect(e.name).to.equal('ParseError')
|
expect(e.name).toBe('ParseError')
|
||||||
expect(e.message).to.match(/illegal argument ""/)
|
expect(e.message).toMatch(/illegal argument ""/)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
it('should throw when filename resolved to falsy', function () {
|
it('should throw when filename resolved to falsy', function () {
|
||||||
@@ -37,8 +32,8 @@ describe('tags/layout', function () {
|
|||||||
'/parent.html': '{%layout foo%}'
|
'/parent.html': '{%layout foo%}'
|
||||||
})
|
})
|
||||||
return liquid.renderFile('/parent.html').catch(function (e) {
|
return liquid.renderFile('/parent.html').catch(function (e) {
|
||||||
expect(e.name).to.equal('RenderError')
|
expect(e.name).toBe('RenderError')
|
||||||
expect(e.message).to.contain('illegal filename "undefined"')
|
expect(e.message).toContain('illegal filename "undefined"')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
it('should handle layout none', async function () {
|
it('should handle layout none', async function () {
|
||||||
@@ -46,7 +41,7 @@ describe('tags/layout', function () {
|
|||||||
'{%block a%}A{%endblock%}' +
|
'{%block a%}A{%endblock%}' +
|
||||||
'B'
|
'B'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('AB')
|
return expect(html).toBe('AB')
|
||||||
})
|
})
|
||||||
describe('anonymous block', function () {
|
describe('anonymous block', function () {
|
||||||
it('should handle anonymous block', async function () {
|
it('should handle anonymous block', async function () {
|
||||||
@@ -55,7 +50,7 @@ describe('tags/layout', function () {
|
|||||||
})
|
})
|
||||||
const src = '{% layout "parent.html" %}{%block%}A{%endblock%}'
|
const src = '{% layout "parent.html" %}{%block%}A{%endblock%}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('XAY')
|
return expect(html).toBe('XAY')
|
||||||
})
|
})
|
||||||
it('should handle top level contents as anonymous block', async function () {
|
it('should handle top level contents as anonymous block', async function () {
|
||||||
mock({
|
mock({
|
||||||
@@ -63,7 +58,7 @@ describe('tags/layout', function () {
|
|||||||
})
|
})
|
||||||
const src = '{% layout "parent.html" %}A'
|
const src = '{% layout "parent.html" %}A'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('XAY')
|
return expect(html).toBe('XAY')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
it('should handle named blocks', async function () {
|
it('should handle named blocks', async function () {
|
||||||
@@ -74,7 +69,7 @@ describe('tags/layout', function () {
|
|||||||
'{%block a%}A{%endblock%}' +
|
'{%block a%}A{%endblock%}' +
|
||||||
'{%block b%}B{%endblock%}'
|
'{%block b%}B{%endblock%}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('XAYBZ')
|
return expect(html).toBe('XAYBZ')
|
||||||
})
|
})
|
||||||
it('should support `options.layouts`', async () => {
|
it('should support `options.layouts`', async () => {
|
||||||
mock({
|
mock({
|
||||||
@@ -83,7 +78,7 @@ describe('tags/layout', function () {
|
|||||||
const src = '{% layout "parent.html" %}{%block a%}A{%endblock%}'
|
const src = '{% layout "parent.html" %}{%block a%}A{%endblock%}'
|
||||||
const liquid = new Liquid({ layouts: '/layouts' })
|
const liquid = new Liquid({ layouts: '/layouts' })
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('XAY')
|
return expect(html).toBe('XAY')
|
||||||
})
|
})
|
||||||
it('should use `layouts` if specified', async function () {
|
it('should use `layouts` if specified', async function () {
|
||||||
mock({
|
mock({
|
||||||
@@ -93,7 +88,7 @@ describe('tags/layout', function () {
|
|||||||
})
|
})
|
||||||
const staticLiquid = new Liquid({ root: '/root', layouts: '/layouts', dynamicPartials: false })
|
const staticLiquid = new Liquid({ root: '/root', layouts: '/layouts', dynamicPartials: false })
|
||||||
const html = await staticLiquid.renderFile('main.html')
|
const html = await staticLiquid.renderFile('main.html')
|
||||||
return expect(html).to.equal('LAYOUTS A')
|
return expect(html).toBe('LAYOUTS A')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support block.super', async function () {
|
it('should support block.super', async function () {
|
||||||
@@ -104,7 +99,7 @@ describe('tags/layout', function () {
|
|||||||
'{%block css%}{{block.super}}<link href="extra.css" rel="stylesheet">{%endblock%}'
|
'{%block css%}{{block.super}}<link href="extra.css" rel="stylesheet">{%endblock%}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
const output = '<link href="base.css" rel="stylesheet"><link href="extra.css" rel="stylesheet">'
|
const output = '<link href="base.css" rel="stylesheet"><link href="extra.css" rel="stylesheet">'
|
||||||
return expect(html).to.equal(output)
|
return expect(html).toBe(output)
|
||||||
})
|
})
|
||||||
it('should render block.super to empty if no parent exists', async function () {
|
it('should render block.super to empty if no parent exists', async function () {
|
||||||
mock({
|
mock({
|
||||||
@@ -114,7 +109,7 @@ describe('tags/layout', function () {
|
|||||||
'{%block css%}{{block.super}}<link href="extra.css" rel="stylesheet">{%endblock%}'
|
'{%block css%}{{block.super}}<link href="extra.css" rel="stylesheet">{%endblock%}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
const output = '<link href="base.css" rel="stylesheet"><link href="extra.css" rel="stylesheet">'
|
const output = '<link href="base.css" rel="stylesheet"><link href="extra.css" rel="stylesheet">'
|
||||||
return expect(html).to.equal(output)
|
return expect(html).toBe(output)
|
||||||
})
|
})
|
||||||
it('should support nested block.super', async function () {
|
it('should support nested block.super', async function () {
|
||||||
mock({
|
mock({
|
||||||
@@ -124,7 +119,7 @@ describe('tags/layout', function () {
|
|||||||
const src = '{% layout "parent.html" %}{%block css%}{{block.super}}<link href="extra.css" rel="stylesheet">{%endblock%}'
|
const src = '{% layout "parent.html" %}{%block css%}{{block.super}}<link href="extra.css" rel="stylesheet">{%endblock%}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
const output = '<link href="root.css" rel="stylesheet"><link href="parent.css" rel="stylesheet"><link href="extra.css" rel="stylesheet">'
|
const output = '<link href="root.css" rel="stylesheet"><link href="parent.css" rel="stylesheet"><link href="extra.css" rel="stylesheet">'
|
||||||
return expect(html).to.equal(output)
|
return expect(html).toBe(output)
|
||||||
})
|
})
|
||||||
it('should support variable as layout name', async function () {
|
it('should support variable as layout name', async function () {
|
||||||
mock({
|
mock({
|
||||||
@@ -132,7 +127,7 @@ describe('tags/layout', function () {
|
|||||||
})
|
})
|
||||||
const src = '{% layout parent %}{%block a%}A{%endblock%}'
|
const src = '{% layout parent %}{%block a%}A{%endblock%}'
|
||||||
const html = await liquid.parseAndRender(src, { parent: 'parent.html' })
|
const html = await liquid.parseAndRender(src, { parent: 'parent.html' })
|
||||||
return expect(html).to.equal('XAY')
|
return expect(html).toBe('XAY')
|
||||||
})
|
})
|
||||||
it('should support default block content', async function () {
|
it('should support default block content', async function () {
|
||||||
mock({
|
mock({
|
||||||
@@ -140,7 +135,7 @@ describe('tags/layout', function () {
|
|||||||
})
|
})
|
||||||
const src = '{% layout "parent.html" %}{%block a%}a{%endblock%}'
|
const src = '{% layout "parent.html" %}{%block a%}a{%endblock%}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('XaYBZ')
|
return expect(html).toBe('XaYBZ')
|
||||||
})
|
})
|
||||||
it('should handle nested block', async function () {
|
it('should handle nested block', async function () {
|
||||||
mock({
|
mock({
|
||||||
@@ -149,7 +144,7 @@ describe('tags/layout', function () {
|
|||||||
'/main.html': '{%layout "parent"%}{%block a%}A{%endblock%}'
|
'/main.html': '{%layout "parent"%}{%block a%}A{%endblock%}'
|
||||||
})
|
})
|
||||||
const html = await liquid.renderFile('/main.html')
|
const html = await liquid.renderFile('/main.html')
|
||||||
return expect(html).to.equal('XAY')
|
return expect(html).toBe('XAY')
|
||||||
})
|
})
|
||||||
it('should not bleed scope into `include` layout', async function () {
|
it('should not bleed scope into `include` layout', async function () {
|
||||||
mock({
|
mock({
|
||||||
@@ -160,7 +155,7 @@ describe('tags/layout', function () {
|
|||||||
'/included.html': '{%layout "parent"%}{%block a%}a{%endblock%}'
|
'/included.html': '{%layout "parent"%}{%block a%}a{%endblock%}'
|
||||||
})
|
})
|
||||||
const html = await liquid.renderFile('main')
|
const html = await liquid.renderFile('main')
|
||||||
return expect(html).to.equal('XAYIXaYZJZ')
|
return expect(html).toBe('XAYIXaYZJZ')
|
||||||
})
|
})
|
||||||
it('should not bleed scope into `render` layout', async function () {
|
it('should not bleed scope into `render` layout', async function () {
|
||||||
mock({
|
mock({
|
||||||
@@ -171,7 +166,7 @@ describe('tags/layout', function () {
|
|||||||
'/included.html': '{%layout "parent"%}{%block a%}a{%endblock%}'
|
'/included.html': '{%layout "parent"%}{%block a%}a{%endblock%}'
|
||||||
})
|
})
|
||||||
const html = await liquid.renderFile('main')
|
const html = await liquid.renderFile('main')
|
||||||
return expect(html).to.equal('XAYIXaYZJZ')
|
return expect(html).toBe('XAYIXaYZJZ')
|
||||||
})
|
})
|
||||||
it('should support hash list', async function () {
|
it('should support hash list', async function () {
|
||||||
mock({
|
mock({
|
||||||
@@ -179,7 +174,7 @@ describe('tags/layout', function () {
|
|||||||
'/main.html': '{% layout "parent.html" color:"black"%}{%block%}A{%endblock%}'
|
'/main.html': '{% layout "parent.html" color:"black"%}{%block%}A{%endblock%}'
|
||||||
})
|
})
|
||||||
const html = await liquid.renderFile('/main.html')
|
const html = await liquid.renderFile('/main.html')
|
||||||
return expect(html).to.equal('blackA')
|
return expect(html).toBe('blackA')
|
||||||
})
|
})
|
||||||
it('should support multiple hash', async function () {
|
it('should support multiple hash', async function () {
|
||||||
mock({
|
mock({
|
||||||
@@ -187,7 +182,7 @@ describe('tags/layout', function () {
|
|||||||
'/main.html': '{% layout "parent.html" color:"black", bg:"red"%}{%block%}A{%endblock%}'
|
'/main.html': '{% layout "parent.html" color:"black", bg:"red"%}{%block%}A{%endblock%}'
|
||||||
})
|
})
|
||||||
const html = await liquid.renderFile('/main.html')
|
const html = await liquid.renderFile('/main.html')
|
||||||
return expect(html).to.equal('blackredA')
|
return expect(html).toBe('blackredA')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support relative reference', async function () {
|
it('should support relative reference', async function () {
|
||||||
@@ -197,7 +192,7 @@ describe('tags/layout', function () {
|
|||||||
})
|
})
|
||||||
const staticLiquid = new Liquid({ root: '/', dynamicPartials: false })
|
const staticLiquid = new Liquid({ root: '/', dynamicPartials: false })
|
||||||
const html = await staticLiquid.renderFile('/foo/bar/main.html')
|
const html = await staticLiquid.renderFile('/foo/bar/main.html')
|
||||||
return expect(html).to.equal('blackA')
|
return expect(html).toBe('blackA')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support relative root', async function () {
|
it('should support relative root', async function () {
|
||||||
@@ -207,7 +202,7 @@ describe('tags/layout', function () {
|
|||||||
})
|
})
|
||||||
const staticLiquid = new Liquid({ root: './foo', dynamicPartials: false })
|
const staticLiquid = new Liquid({ root: './foo', dynamicPartials: false })
|
||||||
const html = await staticLiquid.renderFile('bar/main.html')
|
const html = await staticLiquid.renderFile('bar/main.html')
|
||||||
return expect(html).to.equal('blackA')
|
return expect(html).toBe('blackA')
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('static partial', function () {
|
describe('static partial', function () {
|
||||||
@@ -218,7 +213,7 @@ describe('tags/layout', function () {
|
|||||||
})
|
})
|
||||||
const staticLiquid = new Liquid({ root: '/', dynamicPartials: false })
|
const staticLiquid = new Liquid({ root: '/', dynamicPartials: false })
|
||||||
const html = await staticLiquid.renderFile('/main.html')
|
const html = await staticLiquid.renderFile('/main.html')
|
||||||
return expect(html).to.equal('blackA')
|
return expect(html).toBe('blackA')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support parent paths', async function () {
|
it('should support parent paths', async function () {
|
||||||
@@ -228,7 +223,7 @@ describe('tags/layout', function () {
|
|||||||
})
|
})
|
||||||
const staticLiquid = new Liquid({ root: '/', dynamicPartials: false })
|
const staticLiquid = new Liquid({ root: '/', dynamicPartials: false })
|
||||||
const html = await staticLiquid.renderFile('/main.html')
|
const html = await staticLiquid.renderFile('/main.html')
|
||||||
return expect(html).to.equal('blackA')
|
return expect(html).toBe('blackA')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support none', async function () {
|
it('should support none', async function () {
|
||||||
@@ -237,7 +232,7 @@ describe('tags/layout', function () {
|
|||||||
})
|
})
|
||||||
const staticLiquid = new Liquid({ root: '/', dynamicPartials: false })
|
const staticLiquid = new Liquid({ root: '/', dynamicPartials: false })
|
||||||
const html = await staticLiquid.renderFile('/main.html')
|
const html = await staticLiquid.renderFile('/main.html')
|
||||||
return expect(html).to.equal('foo')
|
return expect(html).toBe('foo')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support subpaths', async function () {
|
it('should support subpaths', async function () {
|
||||||
@@ -247,7 +242,7 @@ describe('tags/layout', function () {
|
|||||||
})
|
})
|
||||||
const staticLiquid = new Liquid({ root: '/', dynamicPartials: false })
|
const staticLiquid = new Liquid({ root: '/', dynamicPartials: false })
|
||||||
const html = await staticLiquid.renderFile('/main.html')
|
const html = await staticLiquid.renderFile('/main.html')
|
||||||
return expect(html).to.equal('blackA')
|
return expect(html).toBe('blackA')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
it('should support sync', function () {
|
it('should support sync', function () {
|
||||||
@@ -257,6 +252,6 @@ describe('tags/layout', function () {
|
|||||||
'/main.html': '{%layout "parent"%}{%block a%}A{%endblock%}'
|
'/main.html': '{%layout "parent"%}{%block a%}A{%endblock%}'
|
||||||
})
|
})
|
||||||
const html = liquid.renderFileSync('/main.html')
|
const html = liquid.renderFileSync('/main.html')
|
||||||
return expect(html).to.equal('XAY')
|
return expect(html).toBe('XAY')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,9 +1,5 @@
|
|||||||
import { expect, use } from 'chai'
|
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
import { Liquid } from '../../../src/liquid'
|
import { Liquid } from '../../../src/liquid'
|
||||||
|
|
||||||
use(chaiAsPromised)
|
|
||||||
|
|
||||||
describe('tags/liquid', function () {
|
describe('tags/liquid', function () {
|
||||||
const liquid = new Liquid()
|
const liquid = new Liquid()
|
||||||
|
|
||||||
@@ -19,7 +15,7 @@ describe('tags/liquid', function () {
|
|||||||
-%}
|
-%}
|
||||||
`
|
`
|
||||||
const html = await liquid.parseAndRender(src, { array: [1, 2, 3] })
|
const html = await liquid.parseAndRender(src, { array: [1, 2, 3] })
|
||||||
return expect(html).to.equal('1#2#3')
|
return expect(html).toBe('1#2#3')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support shorthand syntax with assignments and filters', async function () {
|
it('should support shorthand syntax with assignments and filters', async function () {
|
||||||
@@ -38,13 +34,13 @@ describe('tags/liquid', function () {
|
|||||||
-%}
|
-%}
|
||||||
`
|
`
|
||||||
const html = await liquid.parseAndRender(src, { array: [1, 2, 3] })
|
const html = await liquid.parseAndRender(src, { array: [1, 2, 3] })
|
||||||
return expect(html).to.equal('4#8#12#6')
|
return expect(html).toBe('4#8#12#6')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should handle empty tag', async function () {
|
it('should handle empty tag', async function () {
|
||||||
const src = '{% liquid %}'
|
const src = '{% liquid %}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('')
|
return expect(html).toBe('')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should handle lines containing only whitespace', async function () {
|
it('should handle lines containing only whitespace', async function () {
|
||||||
@@ -56,7 +52,7 @@ describe('tags/liquid', function () {
|
|||||||
echo 'goodbye'
|
echo 'goodbye'
|
||||||
%}`
|
%}`
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('hello goodbye')
|
return expect(html).toBe('hello goodbye')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should fail with carriage return terminated tags', async function () {
|
it('should fail with carriage return terminated tags', async function () {
|
||||||
@@ -71,6 +67,6 @@ describe('tags/liquid', function () {
|
|||||||
'-%}'
|
'-%}'
|
||||||
].join('\r')
|
].join('\r')
|
||||||
return expect(liquid.parseAndRender(src))
|
return expect(liquid.parseAndRender(src))
|
||||||
.to.be.rejectedWith(/not closed/)
|
.rejects.toThrow(/not closed/)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,30 +1,25 @@
|
|||||||
import * as chai from 'chai'
|
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
import { Liquid } from '../../../src/liquid'
|
import { Liquid } from '../../../src/liquid'
|
||||||
|
|
||||||
const expect = chai.expect
|
|
||||||
chai.use(chaiAsPromised)
|
|
||||||
|
|
||||||
describe('tags/raw', function () {
|
describe('tags/raw', function () {
|
||||||
const liquid = new Liquid()
|
const liquid = new Liquid()
|
||||||
it('should throw when not closed', async function () {
|
it('should throw when not closed', async function () {
|
||||||
const p = liquid.parseAndRender('{% raw %}')
|
const p = liquid.parseAndRender('{% raw %}')
|
||||||
return expect(p).be.rejectedWith(/{% raw %} not closed/)
|
return expect(p).rejects.toThrow(/{% raw %} not closed/)
|
||||||
})
|
})
|
||||||
it('should output filters as it is', async function () {
|
it('should output filters as it is', async function () {
|
||||||
const src = '{% raw %}{{ 5 | plus: 6 }}{% endraw %} is equal to 11.'
|
const src = '{% raw %}{{ 5 | plus: 6 }}{% endraw %} is equal to 11.'
|
||||||
const dst = '{{ 5 | plus: 6 }} is equal to 11.'
|
const dst = '{{ 5 | plus: 6 }} is equal to 11.'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal(dst)
|
return expect(html).toBe(dst)
|
||||||
})
|
})
|
||||||
it('should preserve blank characters', async function () {
|
it('should preserve blank characters', async function () {
|
||||||
const src = '{% raw %}\n{{ foo}} \n{% endraw %}'
|
const src = '{% raw %}\n{{ foo}} \n{% endraw %}'
|
||||||
const dst = '\n{{ foo}} \n'
|
const dst = '\n{{ foo}} \n'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal(dst)
|
return expect(html).toBe(dst)
|
||||||
})
|
})
|
||||||
it('should support sync', function () {
|
it('should support sync', function () {
|
||||||
const html = liquid.parseAndRenderSync('{% raw %}{{foo}}{% endraw %}')
|
const html = liquid.parseAndRenderSync('{% raw %}{{foo}}{% endraw %}')
|
||||||
return expect(html).to.equal('{{foo}}')
|
return expect(html).toBe('{{foo}}')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,13 +1,10 @@
|
|||||||
import { expect, use } from 'chai'
|
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
import { Liquid } from '../../../src/liquid'
|
import { Liquid } from '../../../src/liquid'
|
||||||
import { Drop } from '../../../src/drop/drop'
|
import { Drop } from '../../../src/drop/drop'
|
||||||
import { mock, restore } from '../../stub/mockfs'
|
import { mock, restore } from '../../stub/mockfs'
|
||||||
use(chaiAsPromised)
|
|
||||||
|
|
||||||
describe('tags/render', function () {
|
describe('tags/render', function () {
|
||||||
let liquid: Liquid
|
let liquid: Liquid
|
||||||
before(function () {
|
beforeEach(function () {
|
||||||
liquid = new Liquid({
|
liquid = new Liquid({
|
||||||
root: '/',
|
root: '/',
|
||||||
extname: '.html'
|
extname: '.html'
|
||||||
@@ -20,7 +17,7 @@ describe('tags/render', function () {
|
|||||||
'/bar/foo.html': 'foo'
|
'/bar/foo.html': 'foo'
|
||||||
})
|
})
|
||||||
const html = await liquid.renderFile('/current.html')
|
const html = await liquid.renderFile('/current.html')
|
||||||
expect(html).to.equal('barfoobar')
|
expect(html).toBe('barfoobar')
|
||||||
})
|
})
|
||||||
it('should support render', async function () {
|
it('should support render', async function () {
|
||||||
mock({
|
mock({
|
||||||
@@ -29,7 +26,7 @@ describe('tags/render', function () {
|
|||||||
})
|
})
|
||||||
const liquid = new Liquid({ partials: '/partials', root: '/' })
|
const liquid = new Liquid({ partials: '/partials', root: '/' })
|
||||||
const html = await liquid.renderFile('/current.html')
|
const html = await liquid.renderFile('/current.html')
|
||||||
expect(html).to.equal('barfoobar')
|
expect(html).toBe('barfoobar')
|
||||||
})
|
})
|
||||||
it('should support template string', async function () {
|
it('should support template string', async function () {
|
||||||
mock({
|
mock({
|
||||||
@@ -37,7 +34,7 @@ describe('tags/render', function () {
|
|||||||
'/bar/foo.html': 'foo'
|
'/bar/foo.html': 'foo'
|
||||||
})
|
})
|
||||||
const html = await liquid.renderFile('/current.html', { name: 'foo.html' })
|
const html = await liquid.renderFile('/current.html', { name: 'foo.html' })
|
||||||
expect(html).to.equal('barfoobar')
|
expect(html).toBe('barfoobar')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should throw when not specified', function () {
|
it('should throw when not specified', function () {
|
||||||
@@ -45,8 +42,8 @@ describe('tags/render', function () {
|
|||||||
'/parent.html': '{%render%}'
|
'/parent.html': '{%render%}'
|
||||||
})
|
})
|
||||||
return liquid.renderFile('/parent.html').catch(function (e) {
|
return liquid.renderFile('/parent.html').catch(function (e) {
|
||||||
expect(e.name).to.equal('ParseError')
|
expect(e.name).toBe('ParseError')
|
||||||
expect(e.message).to.match(/illegal argument ""/)
|
expect(e.message).toMatch(/illegal argument ""/)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -55,8 +52,8 @@ describe('tags/render', function () {
|
|||||||
'/parent.html': '{%render not-exist%}'
|
'/parent.html': '{%render not-exist%}'
|
||||||
})
|
})
|
||||||
return liquid.renderFile('/parent.html').catch(function (e) {
|
return liquid.renderFile('/parent.html').catch(function (e) {
|
||||||
expect(e.name).to.equal('RenderError')
|
expect(e.name).toBe('RenderError')
|
||||||
expect(e.message).to.match(/illegal filename "undefined"/)
|
expect(e.message).toMatch(/illegal filename "undefined"/)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -66,7 +63,7 @@ describe('tags/render', function () {
|
|||||||
'/foo/relative.html': 'bar{% render "../bar/foo.html" %}bar'
|
'/foo/relative.html': 'bar{% render "../bar/foo.html" %}bar'
|
||||||
})
|
})
|
||||||
const html = await liquid.renderFile('foo/relative.html')
|
const html = await liquid.renderFile('foo/relative.html')
|
||||||
expect(html).to.equal('barfoobar')
|
expect(html).toBe('barfoobar')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support render: hash list', async function () {
|
it('should support render: hash list', async function () {
|
||||||
@@ -75,7 +72,7 @@ describe('tags/render', function () {
|
|||||||
'/user.html': '{{role}} : {{alias}}'
|
'/user.html': '{{role}} : {{alias}}'
|
||||||
})
|
})
|
||||||
const html = await liquid.renderFile('hash.html')
|
const html = await liquid.renderFile('hash.html')
|
||||||
expect(html).to.equal('admin : harttle')
|
expect(html).toBe('admin : harttle')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should not bleed into child template', async function () {
|
it('should not bleed into child template', async function () {
|
||||||
@@ -84,7 +81,7 @@ describe('tags/render', function () {
|
|||||||
'/user.html': 'InChild: {{name}}'
|
'/user.html': 'InChild: {{name}}'
|
||||||
})
|
})
|
||||||
const html = await liquid.renderFile('hash.html')
|
const html = await liquid.renderFile('hash.html')
|
||||||
expect(html).to.equal('InParent: harttle InChild: ')
|
expect(html).toBe('InParent: harttle InChild: ')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should allow argument reassignment', async function () {
|
it('should allow argument reassignment', async function () {
|
||||||
@@ -94,7 +91,7 @@ describe('tags/render', function () {
|
|||||||
})
|
})
|
||||||
const staticLiquid = new Liquid({ dynamicPartials: false, root: '/' })
|
const staticLiquid = new Liquid({ dynamicPartials: false, root: '/' })
|
||||||
const html = await staticLiquid.renderFile('parent.html')
|
const html = await staticLiquid.renderFile('parent.html')
|
||||||
return expect(html).to.equal('green')
|
return expect(html).toBe('green')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should be able to access globals', async function () {
|
it('should be able to access globals', async function () {
|
||||||
@@ -104,7 +101,7 @@ describe('tags/render', function () {
|
|||||||
'/user.html': 'InChild: {{name}}'
|
'/user.html': 'InChild: {{name}}'
|
||||||
})
|
})
|
||||||
const html = await liquid.renderFile('hash', { name: 'harttle' })
|
const html = await liquid.renderFile('hash', { name: 'harttle' })
|
||||||
expect(html).to.equal('InParent: harttle InChild: Harttle')
|
expect(html).toBe('InParent: harttle InChild: Harttle')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support with', async function () {
|
it('should support with', async function () {
|
||||||
@@ -113,7 +110,7 @@ describe('tags/render', function () {
|
|||||||
'/color.html': 'color:{{color}}, shape:{{shape}}'
|
'/color.html': 'color:{{color}}, shape:{{shape}}'
|
||||||
})
|
})
|
||||||
const html = await liquid.renderFile('with.html')
|
const html = await liquid.renderFile('with.html')
|
||||||
expect(html).to.equal('color:red, shape:rect')
|
expect(html).toBe('color:red, shape:rect')
|
||||||
})
|
})
|
||||||
it('should treat as normal key/value if followed by ":"', async () => {
|
it('should treat as normal key/value if followed by ":"', async () => {
|
||||||
mock({
|
mock({
|
||||||
@@ -121,7 +118,7 @@ describe('tags/render', function () {
|
|||||||
'/color.html': 'color:{{color}}, with:{{with}}'
|
'/color.html': 'color:{{color}}, with:{{with}}'
|
||||||
})
|
})
|
||||||
const html = await liquid.renderFile('with.html')
|
const html = await liquid.renderFile('with.html')
|
||||||
expect(html).to.equal('color:, with:foo')
|
expect(html).toBe('color:, with:foo')
|
||||||
})
|
})
|
||||||
it('should treat as normal key if with value not specified', async () => {
|
it('should treat as normal key if with value not specified', async () => {
|
||||||
mock({
|
mock({
|
||||||
@@ -129,7 +126,7 @@ describe('tags/render', function () {
|
|||||||
'/color.html': 'color:{{color}}, with:{{with}}, shape:{{shape}}'
|
'/color.html': 'color:{{color}}, with:{{with}}, shape:{{shape}}'
|
||||||
})
|
})
|
||||||
const html = await liquid.renderFile('with.html')
|
const html = await liquid.renderFile('with.html')
|
||||||
expect(html).to.equal('color:, with:true, shape:rect')
|
expect(html).toBe('color:, with:true, shape:rect')
|
||||||
})
|
})
|
||||||
it('should support with...as', async function () {
|
it('should support with...as', async function () {
|
||||||
mock({
|
mock({
|
||||||
@@ -137,7 +134,7 @@ describe('tags/render', function () {
|
|||||||
'/color.html': 'color:{{c}}'
|
'/color.html': 'color:{{c}}'
|
||||||
})
|
})
|
||||||
const html = await liquid.renderFile('with.html', { color: 'red' })
|
const html = await liquid.renderFile('with.html', { color: 'red' })
|
||||||
expect(html).to.equal('color:red')
|
expect(html).toBe('color:red')
|
||||||
})
|
})
|
||||||
it('should support with...as and other parameters', async function () {
|
it('should support with...as and other parameters', async function () {
|
||||||
mock({
|
mock({
|
||||||
@@ -146,7 +143,7 @@ describe('tags/render', function () {
|
|||||||
})
|
})
|
||||||
const scope = { color: 'red', shape: 'rect' }
|
const scope = { color: 'red', shape: 'rect' }
|
||||||
const html = await liquid.renderFile('index.html', scope)
|
const html = await liquid.renderFile('index.html', scope)
|
||||||
expect(html).to.equal('color:red, shape:rect')
|
expect(html).toBe('color:red, shape:rect')
|
||||||
})
|
})
|
||||||
it('should support for...as', async function () {
|
it('should support for...as', async function () {
|
||||||
mock({
|
mock({
|
||||||
@@ -154,7 +151,7 @@ describe('tags/render', function () {
|
|||||||
'/item.html': '{{forloop.index}}: {{color}}\n'
|
'/item.html': '{{forloop.index}}: {{color}}\n'
|
||||||
})
|
})
|
||||||
const html = await liquid.renderFile('index.html', { colors: ['red', 'green'] })
|
const html = await liquid.renderFile('index.html', { colors: ['red', 'green'] })
|
||||||
expect(html).to.equal('1: red\n2: green\n')
|
expect(html).toBe('1: red\n2: green\n')
|
||||||
})
|
})
|
||||||
it('should support for <iterable> as', async function () {
|
it('should support for <iterable> as', async function () {
|
||||||
class MockIterable {
|
class MockIterable {
|
||||||
@@ -168,7 +165,7 @@ describe('tags/render', function () {
|
|||||||
'/item.html': '{{forloop.index}}: {{color}}\n'
|
'/item.html': '{{forloop.index}}: {{color}}\n'
|
||||||
})
|
})
|
||||||
const html = await liquid.renderFile('index.html', { colors: new MockIterable() })
|
const html = await liquid.renderFile('index.html', { colors: new MockIterable() })
|
||||||
expect(html).to.equal('1: red\n2: green\n')
|
expect(html).toBe('1: red\n2: green\n')
|
||||||
})
|
})
|
||||||
it('should support for <non-array> as', async function () {
|
it('should support for <non-array> as', async function () {
|
||||||
mock({
|
mock({
|
||||||
@@ -176,7 +173,7 @@ describe('tags/render', function () {
|
|||||||
'/item.html': '{{forloop.index}}: {{color}}\n'
|
'/item.html': '{{forloop.index}}: {{color}}\n'
|
||||||
})
|
})
|
||||||
const html = await liquid.renderFile('index.html')
|
const html = await liquid.renderFile('index.html')
|
||||||
expect(html).to.equal('1: green\n')
|
expect(html).toBe('1: green\n')
|
||||||
})
|
})
|
||||||
it('should support for without as', async function () {
|
it('should support for without as', async function () {
|
||||||
mock({
|
mock({
|
||||||
@@ -184,7 +181,7 @@ describe('tags/render', function () {
|
|||||||
'/item.html': '{{forloop.index}}: {{color}}\n'
|
'/item.html': '{{forloop.index}}: {{color}}\n'
|
||||||
})
|
})
|
||||||
const html = await liquid.renderFile('index.html', { colors: ['red', 'green'] })
|
const html = await liquid.renderFile('index.html', { colors: ['red', 'green'] })
|
||||||
expect(html).to.equal('1: \n2: \n')
|
expect(html).toBe('1: \n2: \n')
|
||||||
})
|
})
|
||||||
it('should support for...as with other parameters', async function () {
|
it('should support for...as with other parameters', async function () {
|
||||||
mock({
|
mock({
|
||||||
@@ -192,7 +189,7 @@ describe('tags/render', function () {
|
|||||||
'/item.html': '{{forloop.index}}{{sep}}{{color}}{{tail}}'
|
'/item.html': '{{forloop.index}}{{sep}}{{color}}{{tail}}'
|
||||||
})
|
})
|
||||||
const html = await liquid.renderFile('index.html', { colors: ['red', 'green'] })
|
const html = await liquid.renderFile('index.html', { colors: ['red', 'green'] })
|
||||||
expect(html).to.equal('1. red.\n2. green.\n')
|
expect(html).toBe('1. red.\n2. green.\n')
|
||||||
})
|
})
|
||||||
it('should support for...as with other parameters (comma separated)', async function () {
|
it('should support for...as with other parameters (comma separated)', async function () {
|
||||||
mock({
|
mock({
|
||||||
@@ -200,7 +197,7 @@ describe('tags/render', function () {
|
|||||||
'/item.html': '{{forloop.index}}{{sep}}{{color}}{{tail}}'
|
'/item.html': '{{forloop.index}}{{sep}}{{color}}{{tail}}'
|
||||||
})
|
})
|
||||||
const html = await liquid.renderFile('index.html', { colors: ['red', 'green'] })
|
const html = await liquid.renderFile('index.html', { colors: ['red', 'green'] })
|
||||||
expect(html).to.equal('1. red.\n2. green.\n')
|
expect(html).toBe('1. red.\n2. green.\n')
|
||||||
})
|
})
|
||||||
it('should support render: with as Drop', async function () {
|
it('should support render: with as Drop', async function () {
|
||||||
class ColorDrop extends Drop {
|
class ColorDrop extends Drop {
|
||||||
@@ -213,7 +210,7 @@ describe('tags/render', function () {
|
|||||||
'/color.html': 'color:{{color}}'
|
'/color.html': 'color:{{color}}'
|
||||||
})
|
})
|
||||||
const html = await liquid.renderFile('with.html', { color: new ColorDrop() })
|
const html = await liquid.renderFile('with.html', { color: new ColorDrop() })
|
||||||
expect(html).to.equal('color:red!')
|
expect(html).toBe('color:red!')
|
||||||
})
|
})
|
||||||
it('should support render: with passed as Drop', async function () {
|
it('should support render: with passed as Drop', async function () {
|
||||||
class ColorDrop extends Drop {
|
class ColorDrop extends Drop {
|
||||||
@@ -227,7 +224,7 @@ describe('tags/render', function () {
|
|||||||
'/color.html': '{{color | name}}'
|
'/color.html': '{{color | name}}'
|
||||||
})
|
})
|
||||||
const html = await liquid.renderFile('with.html', { color: new ColorDrop() })
|
const html = await liquid.renderFile('with.html', { color: new ColorDrop() })
|
||||||
expect(html).to.equal('ColorDrop')
|
expect(html).toBe('ColorDrop')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support nested renders', async function () {
|
it('should support nested renders', async function () {
|
||||||
@@ -246,7 +243,7 @@ describe('tags/render', function () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const html = await liquid.renderFile('personInfo.html', ctx)
|
const html = await liquid.renderFile('personInfo.html', ctx)
|
||||||
expect(html).to.equal('This is a person <p>Joe Shmoe<br/>City: Dallas</p>')
|
expect(html).toBe('This is a person <p>Joe Shmoe<br/>City: Dallas</p>')
|
||||||
})
|
})
|
||||||
it('should support relative reference', async function () {
|
it('should support relative reference', async function () {
|
||||||
mock({
|
mock({
|
||||||
@@ -255,7 +252,7 @@ describe('tags/render', function () {
|
|||||||
})
|
})
|
||||||
const staticLiquid = new Liquid({ dynamicPartials: false, root: '/foo' })
|
const staticLiquid = new Liquid({ dynamicPartials: false, root: '/foo' })
|
||||||
const html = await staticLiquid.renderFile('coo/parent.html')
|
const html = await staticLiquid.renderFile('coo/parent.html')
|
||||||
expect(html).to.equal('Xchild with redY')
|
expect(html).toBe('Xchild with redY')
|
||||||
})
|
})
|
||||||
it('should disable relative reference if specified', () => {
|
it('should disable relative reference if specified', () => {
|
||||||
mock({
|
mock({
|
||||||
@@ -263,7 +260,7 @@ describe('tags/render', function () {
|
|||||||
'/foo/bar/child.html': 'child with {{color}}'
|
'/foo/bar/child.html': 'child with {{color}}'
|
||||||
})
|
})
|
||||||
const staticLiquid = new Liquid({ dynamicPartials: false, root: '/foo', relativeReference: false })
|
const staticLiquid = new Liquid({ dynamicPartials: false, root: '/foo', relativeReference: false })
|
||||||
return expect(staticLiquid.renderFile('coo/parent.html')).to.be.rejectedWith(/Failed to lookup/)
|
return expect(staticLiquid.renderFile('coo/parent.html')).rejects.toThrow(/Failed to lookup/)
|
||||||
})
|
})
|
||||||
it('should throw not found if relative reference out of root', () => {
|
it('should throw not found if relative reference out of root', () => {
|
||||||
mock({
|
mock({
|
||||||
@@ -271,7 +268,7 @@ describe('tags/render', function () {
|
|||||||
'/bar/child.html': 'child with {{color}}'
|
'/bar/child.html': 'child with {{color}}'
|
||||||
})
|
})
|
||||||
const staticLiquid = new Liquid({ dynamicPartials: false, root: '/foo', partials: '/foo' })
|
const staticLiquid = new Liquid({ dynamicPartials: false, root: '/foo', partials: '/foo' })
|
||||||
return expect(staticLiquid.renderFile('parent.html')).to.be.rejectedWith(/Failed to lookup "..\/bar\/child.html"/)
|
return expect(staticLiquid.renderFile('parent.html')).rejects.toThrow(/Failed to lookup "..\/bar\/child.html"/)
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('static partial', function () {
|
describe('static partial', function () {
|
||||||
@@ -285,7 +282,7 @@ describe('tags/render', function () {
|
|||||||
'/child.html': 'child with {{color}}'
|
'/child.html': 'child with {{color}}'
|
||||||
})
|
})
|
||||||
const html = await staticLiquid.renderFile('parent.html')
|
const html = await staticLiquid.renderFile('parent.html')
|
||||||
expect(html).to.equal('Xchild with redY')
|
expect(html).toBe('Xchild with redY')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support parent paths', async function () {
|
it('should support parent paths', async function () {
|
||||||
@@ -294,7 +291,7 @@ describe('tags/render', function () {
|
|||||||
'/foo/child.html': 'child'
|
'/foo/child.html': 'child'
|
||||||
})
|
})
|
||||||
const html = await staticLiquid.renderFile('parent.html')
|
const html = await staticLiquid.renderFile('parent.html')
|
||||||
expect(html).to.equal('XchildY')
|
expect(html).toBe('XchildY')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support subpaths', async function () {
|
it('should support subpaths', async function () {
|
||||||
@@ -303,7 +300,7 @@ describe('tags/render', function () {
|
|||||||
'/foo/child.html': 'child'
|
'/foo/child.html': 'child'
|
||||||
})
|
})
|
||||||
const html = await staticLiquid.renderFile('parent.html')
|
const html = await staticLiquid.renderFile('parent.html')
|
||||||
expect(html).to.equal('XchildY')
|
expect(html).toBe('XchildY')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support comma separated arguments', async function () {
|
it('should support comma separated arguments', async function () {
|
||||||
@@ -312,7 +309,7 @@ describe('tags/render', function () {
|
|||||||
'/child.html': 'child with {{color}}'
|
'/child.html': 'child with {{color}}'
|
||||||
})
|
})
|
||||||
const html = await staticLiquid.renderFile('parent.html')
|
const html = await staticLiquid.renderFile('parent.html')
|
||||||
expect(html).to.equal('Xchild with redY')
|
expect(html).toBe('Xchild with redY')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support template string', async function () {
|
it('should support template string', async function () {
|
||||||
@@ -321,7 +318,7 @@ describe('tags/render', function () {
|
|||||||
'/bar/foo.html': 'foo'
|
'/bar/foo.html': 'foo'
|
||||||
})
|
})
|
||||||
const html = await staticLiquid.renderFile('/current.html', { name: 'foo.html' })
|
const html = await staticLiquid.renderFile('/current.html', { name: 'foo.html' })
|
||||||
expect(html).to.equal('barfoobar')
|
expect(html).toBe('barfoobar')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support filters in template string', async function () {
|
it('should support filters in template string', async function () {
|
||||||
@@ -330,7 +327,7 @@ describe('tags/render', function () {
|
|||||||
'/bar/foo.html': 'foo'
|
'/bar/foo.html': 'foo'
|
||||||
})
|
})
|
||||||
const html = await staticLiquid.renderFile('/current.html', { name: 'foo' })
|
const html = await staticLiquid.renderFile('/current.html', { name: 'foo' })
|
||||||
expect(html).to.equal('barfoobar')
|
expect(html).toBe('barfoobar')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('sync support', function () {
|
describe('sync support', function () {
|
||||||
@@ -340,7 +337,7 @@ describe('tags/render', function () {
|
|||||||
'/bar/foo.html': 'foo'
|
'/bar/foo.html': 'foo'
|
||||||
})
|
})
|
||||||
const html = liquid.renderFileSync('/current.html')
|
const html = liquid.renderFileSync('/current.html')
|
||||||
expect(html).to.equal('barfoobar')
|
expect(html).toBe('barfoobar')
|
||||||
})
|
})
|
||||||
it('should support value string', function () {
|
it('should support value string', function () {
|
||||||
mock({
|
mock({
|
||||||
@@ -348,7 +345,7 @@ describe('tags/render', function () {
|
|||||||
'/bar/foo.html': 'foo'
|
'/bar/foo.html': 'foo'
|
||||||
})
|
})
|
||||||
const html = liquid.renderFileSync('/current.html', { name: '/bar/foo.html' })
|
const html = liquid.renderFileSync('/current.html', { name: '/bar/foo.html' })
|
||||||
expect(html).to.equal('barfoobar')
|
expect(html).toBe('barfoobar')
|
||||||
})
|
})
|
||||||
it('should support template string', function () {
|
it('should support template string', function () {
|
||||||
mock({
|
mock({
|
||||||
@@ -356,7 +353,7 @@ describe('tags/render', function () {
|
|||||||
'/bar/foo.html': 'foo'
|
'/bar/foo.html': 'foo'
|
||||||
})
|
})
|
||||||
const html = liquid.renderFileSync('/current.html', { name: '/foo.html' })
|
const html = liquid.renderFileSync('/current.html', { name: '/foo.html' })
|
||||||
expect(html).to.equal('barfoobar')
|
expect(html).toBe('barfoobar')
|
||||||
})
|
})
|
||||||
it('should support with', function () {
|
it('should support with', function () {
|
||||||
mock({
|
mock({
|
||||||
@@ -364,7 +361,7 @@ describe('tags/render', function () {
|
|||||||
'/color.html': 'color:{{color}}, shape:{{shape}}'
|
'/color.html': 'color:{{color}}, shape:{{shape}}'
|
||||||
})
|
})
|
||||||
const html = liquid.renderFileSync('with.html')
|
const html = liquid.renderFileSync('with.html')
|
||||||
expect(html).to.equal('color:red, shape:rect')
|
expect(html).toBe('color:red, shape:rect')
|
||||||
})
|
})
|
||||||
it('should support filename with extension', function () {
|
it('should support filename with extension', function () {
|
||||||
mock({
|
mock({
|
||||||
@@ -373,7 +370,7 @@ describe('tags/render', function () {
|
|||||||
})
|
})
|
||||||
const staticLiquid = new Liquid({ dynamicPartials: false, root: '/' })
|
const staticLiquid = new Liquid({ dynamicPartials: false, root: '/' })
|
||||||
const html = staticLiquid.renderFileSync('parent.html')
|
const html = staticLiquid.renderFileSync('parent.html')
|
||||||
expect(html).to.equal('Xchild with redY')
|
expect(html).toBe('Xchild with redY')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,9 +1,5 @@
|
|||||||
import { expect, use } from 'chai'
|
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
import { Liquid } from '../../../src/liquid'
|
import { Liquid } from '../../../src/liquid'
|
||||||
|
|
||||||
use(chaiAsPromised)
|
|
||||||
|
|
||||||
describe('tags/tablerow', function () {
|
describe('tags/tablerow', function () {
|
||||||
const liquid = new Liquid()
|
const liquid = new Liquid()
|
||||||
|
|
||||||
@@ -11,7 +7,7 @@ describe('tags/tablerow', function () {
|
|||||||
const src = '{% tablerow i in (1..3)%}{{ i }}{% endtablerow %}'
|
const src = '{% tablerow i in (1..3)%}{{ i }}{% endtablerow %}'
|
||||||
const dst = '<tr class="row1"><td class="col1">1</td><td class="col2">2</td><td class="col3">3</td></tr>'
|
const dst = '<tr class="row1"><td class="col1">1</td><td class="col2">2</td><td class="col3">3</td></tr>'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal(dst)
|
return expect(html).toBe(dst)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support promises', async function () {
|
it('should support promises', async function () {
|
||||||
@@ -21,7 +17,7 @@ describe('tags/tablerow', function () {
|
|||||||
}
|
}
|
||||||
const dst = '<tr class="row1"><td class="col1">1</td><td class="col2">2</td><td class="col3">3</td></tr>'
|
const dst = '<tr class="row1"><td class="col1">1</td><td class="col2">2</td><td class="col3">3</td></tr>'
|
||||||
const html = await liquid.parseAndRender(src, ctx)
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
return expect(html).to.equal(dst)
|
return expect(html).toBe(dst)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support iterables', async function () {
|
it('should support iterables', async function () {
|
||||||
@@ -38,7 +34,7 @@ describe('tags/tablerow', function () {
|
|||||||
}
|
}
|
||||||
const dst = '<tr class="row1"><td class="col1">1</td><td class="col2">2</td><td class="col3">3</td></tr>'
|
const dst = '<tr class="row1"><td class="col1">1</td><td class="col2">2</td><td class="col3">3</td></tr>'
|
||||||
const html = await liquid.parseAndRender(src, ctx)
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
return expect(html).to.equal(dst)
|
return expect(html).toBe(dst)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support cols', async function () {
|
it('should support cols', async function () {
|
||||||
@@ -50,40 +46,40 @@ describe('tags/tablerow', function () {
|
|||||||
'<tr class="row1"><td class="col1">a</td><td class="col2">b</td></tr>' +
|
'<tr class="row1"><td class="col1">a</td><td class="col2">b</td></tr>' +
|
||||||
'<tr class="row2"><td class="col1">c</td></tr>'
|
'<tr class="row2"><td class="col1">c</td></tr>'
|
||||||
const html = await liquid.parseAndRender(src, ctx)
|
const html = await liquid.parseAndRender(src, ctx)
|
||||||
return expect(html).to.equal(dst)
|
return expect(html).toBe(dst)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support cols set to 0', async function () {
|
it('should support cols set to 0', async function () {
|
||||||
const src = '{% tablerow i in (1..3) cols:0 %}{{ i }}{% endtablerow %}'
|
const src = '{% tablerow i in (1..3) cols:0 %}{{ i }}{% endtablerow %}'
|
||||||
const dst = '<tr class="row1"><td class="col1">1</td><td class="col2">2</td><td class="col3">3</td></tr>'
|
const dst = '<tr class="row1"><td class="col1">1</td><td class="col2">2</td><td class="col3">3</td></tr>'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal(dst)
|
return expect(html).toBe(dst)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support empty tablerow', async function () {
|
it('should support empty tablerow', async function () {
|
||||||
const src = '{% tablerow i in (1..0) cols:2 %}{{ i }}{% endtablerow %}'
|
const src = '{% tablerow i in (1..0) cols:2 %}{{ i }}{% endtablerow %}'
|
||||||
const dst = ''
|
const dst = ''
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal(dst)
|
return expect(html).toBe(dst)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support empty array', async function () {
|
it('should support empty array', async function () {
|
||||||
const src = '{% tablerow i in alpha.z cols:2 %}{{ i }}{% endtablerow %}'
|
const src = '{% tablerow i in alpha.z cols:2 %}{{ i }}{% endtablerow %}'
|
||||||
const dst = ''
|
const dst = ''
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal(dst)
|
return expect(html).toBe(dst)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should throw when tablerow not closed', function () {
|
it('should throw when tablerow not closed', function () {
|
||||||
const src = '{% tablerow i in (1..0) cols:2 %}{{ i }}'
|
const src = '{% tablerow i in (1..0) cols:2 %}{{ i }}'
|
||||||
return expect(liquid.parseAndRender(src))
|
return expect(liquid.parseAndRender(src))
|
||||||
.to.be.rejectedWith(/tag .* not closed/)
|
.rejects.toThrow(/tag .* not closed/)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should throw when x in y not found', function () {
|
it('should throw when x in y not found', function () {
|
||||||
const src = '{% tablerow i (1..3) %}{{ i }}'
|
const src = '{% tablerow i (1..3) %}{{ i }}'
|
||||||
return expect(liquid.parseAndRender(src))
|
return expect(liquid.parseAndRender(src))
|
||||||
.to.be.rejectedWith('illegal tag: {% tablerow i (1..3) %}, line:1, col:1')
|
.rejects.toThrow('illegal tag: {% tablerow i (1..3) %}, line:1, col:1')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support tablerow with range', async function () {
|
it('should support tablerow with range', async function () {
|
||||||
@@ -93,7 +89,7 @@ describe('tags/tablerow', function () {
|
|||||||
'<tr class="row2"><td class="col1">3</td><td class="col2">4</td></tr>' +
|
'<tr class="row2"><td class="col1">3</td><td class="col2">4</td></tr>' +
|
||||||
'<tr class="row3"><td class="col1">5</td></tr>'
|
'<tr class="row3"><td class="col1">5</td></tr>'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal(dst)
|
return expect(html).toBe(dst)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support tablerow with limit', async function () {
|
it('should support tablerow with limit', async function () {
|
||||||
@@ -102,45 +98,45 @@ describe('tags/tablerow', function () {
|
|||||||
'<tr class="row1"><td class="col1">1</td><td class="col2">2</td></tr>' +
|
'<tr class="row1"><td class="col1">1</td><td class="col2">2</td></tr>' +
|
||||||
'<tr class="row2"><td class="col1">3</td></tr>'
|
'<tr class="row2"><td class="col1">3</td></tr>'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal(dst)
|
return expect(html).toBe(dst)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should support index0, index, rindex0, rindex', async function () {
|
it('should support index0, index, rindex0, rindex', async function () {
|
||||||
const src = '{% tablerow i in (1..3)%}{{tablerowloop.index0}}{{tablerowloop.index}}{{tablerowloop.rindex0}}{{tablerowloop.rindex}}{% endtablerow %}'
|
const src = '{% tablerow i in (1..3)%}{{tablerowloop.index0}}{{tablerowloop.index}}{{tablerowloop.rindex0}}{{tablerowloop.rindex}}{% endtablerow %}'
|
||||||
const dst = '<tr class="row1"><td class="col1">0123</td><td class="col2">1212</td><td class="col3">2301</td></tr>'
|
const dst = '<tr class="row1"><td class="col1">0123</td><td class="col2">1212</td><td class="col3">2301</td></tr>'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal(dst)
|
return expect(html).toBe(dst)
|
||||||
})
|
})
|
||||||
it('should support first, last, length', async function () {
|
it('should support first, last, length', async function () {
|
||||||
const src = '{% tablerow i in (1..3)%}{{tablerowloop.first}} {{tablerowloop.last}} {{tablerowloop.length}}{% endtablerow %}'
|
const src = '{% tablerow i in (1..3)%}{{tablerowloop.first}} {{tablerowloop.last}} {{tablerowloop.length}}{% endtablerow %}'
|
||||||
const dst = '<tr class="row1"><td class="col1">true false 3</td><td class="col2">false false 3</td><td class="col3">false true 3</td></tr>'
|
const dst = '<tr class="row1"><td class="col1">true false 3</td><td class="col2">false false 3</td><td class="col3">false true 3</td></tr>'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal(dst)
|
return expect(html).toBe(dst)
|
||||||
})
|
})
|
||||||
it('should support col, row, col0, col_first, col_last', async function () {
|
it('should support col, row, col0, col_first, col_last', async function () {
|
||||||
const src = '{% tablerow i in (1..3)%}{{tablerowloop.col}} {{tablerowloop.col0}} {{tablerowloop.col_first}} {{tablerowloop.col_last}}{% endtablerow %}'
|
const src = '{% tablerow i in (1..3)%}{{tablerowloop.col}} {{tablerowloop.col0}} {{tablerowloop.col_first}} {{tablerowloop.col_last}}{% endtablerow %}'
|
||||||
const dst = '<tr class="row1"><td class="col1">1 0 true false</td><td class="col2">2 1 false false</td><td class="col3">3 2 false true</td></tr>'
|
const dst = '<tr class="row1"><td class="col1">1 0 true false</td><td class="col2">2 1 false false</td><td class="col3">3 2 false true</td></tr>'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal(dst)
|
return expect(html).toBe(dst)
|
||||||
})
|
})
|
||||||
describe('offset', function () {
|
describe('offset', function () {
|
||||||
it('should support tablerow with offset', async function () {
|
it('should support tablerow with offset', async function () {
|
||||||
const src = '{% tablerow i in (1..5) cols:2 offset:3 %}{{ i }}{% endtablerow %}'
|
const src = '{% tablerow i in (1..5) cols:2 offset:3 %}{{ i }}{% endtablerow %}'
|
||||||
const dst = '<tr class="row1"><td class="col1">4</td><td class="col2">5</td></tr>'
|
const dst = '<tr class="row1"><td class="col1">4</td><td class="col2">5</td></tr>'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal(dst)
|
return expect(html).toBe(dst)
|
||||||
})
|
})
|
||||||
it('index should also start at 1', async function () {
|
it('index should also start at 1', async function () {
|
||||||
const src = '{% tablerow i in (1..4) cols:2 offset:2 %}{{tablerowloop.index}}{% endtablerow %}'
|
const src = '{% tablerow i in (1..4) cols:2 offset:2 %}{{tablerowloop.index}}{% endtablerow %}'
|
||||||
const dst = '<tr class="row1"><td class="col1">1</td><td class="col2">2</td></tr>'
|
const dst = '<tr class="row1"><td class="col1">1</td><td class="col2">2</td></tr>'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal(dst)
|
return expect(html).toBe(dst)
|
||||||
})
|
})
|
||||||
it('col should also start at 1', async function () {
|
it('col should also start at 1', async function () {
|
||||||
const src = '{% tablerow i in (1..4) cols:2 offset:3 %}{{tablerowloop.col}}{% endtablerow %}'
|
const src = '{% tablerow i in (1..4) cols:2 offset:3 %}{{tablerowloop.col}}{% endtablerow %}'
|
||||||
const dst = '<tr class="row1"><td class="col1">1</td></tr>'
|
const dst = '<tr class="row1"><td class="col1">1</td></tr>'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal(dst)
|
return expect(html).toBe(dst)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('sync support', function () {
|
describe('sync support', function () {
|
||||||
@@ -148,13 +144,13 @@ describe('tags/tablerow', function () {
|
|||||||
const src = '{% tablerow i in (1..3)%}{{ i }}{% endtablerow %}'
|
const src = '{% tablerow i in (1..3)%}{{ i }}{% endtablerow %}'
|
||||||
const dst = '<tr class="row1"><td class="col1">1</td><td class="col2">2</td><td class="col3">3</td></tr>'
|
const dst = '<tr class="row1"><td class="col1">1</td><td class="col2">2</td><td class="col3">3</td></tr>'
|
||||||
const html = liquid.parseAndRenderSync(src)
|
const html = liquid.parseAndRenderSync(src)
|
||||||
expect(html).to.equal(dst)
|
expect(html).toBe(dst)
|
||||||
})
|
})
|
||||||
it('should support empty tablerow', function () {
|
it('should support empty tablerow', function () {
|
||||||
const src = '{% tablerow i in "" cols:2 %}{{ i }}{% endtablerow %}'
|
const src = '{% tablerow i in "" cols:2 %}{{ i }}{% endtablerow %}'
|
||||||
const dst = ''
|
const dst = ''
|
||||||
const html = liquid.parseAndRenderSync(src)
|
const html = liquid.parseAndRenderSync(src)
|
||||||
return expect(html).to.equal(dst)
|
return expect(html).toBe(dst)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,43 +1,39 @@
|
|||||||
import { expect, use } from 'chai'
|
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
import { Liquid } from '../../../src/liquid'
|
import { Liquid } from '../../../src/liquid'
|
||||||
|
|
||||||
use(chaiAsPromised)
|
|
||||||
|
|
||||||
describe('tags/unless', function () {
|
describe('tags/unless', function () {
|
||||||
let liquid: Liquid
|
let liquid: Liquid
|
||||||
before(() => { liquid = new Liquid() })
|
beforeEach(() => { liquid = new Liquid() })
|
||||||
|
|
||||||
it('should render else when predicate yields true', async function () {
|
it('should render else when predicate yields true', async function () {
|
||||||
// 0 is truthy
|
// 0 is truthy
|
||||||
const src = '{% unless 0 %}yes{%else%}no{%endunless%}'
|
const src = '{% unless 0 %}yes{%else%}no{%endunless%}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('no')
|
return expect(html).toBe('no')
|
||||||
})
|
})
|
||||||
it('should support elsif', async function () {
|
it('should support elsif', async function () {
|
||||||
const src = '{% unless true %}1{%elsif true%}2{%else%}3{%endunless%}'
|
const src = '{% unless true %}1{%elsif true%}2{%else%}3{%endunless%}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('2')
|
return expect(html).toBe('2')
|
||||||
})
|
})
|
||||||
it('should render unless when predicate yields false', async function () {
|
it('should render unless when predicate yields false', async function () {
|
||||||
const src = '{% unless false %}yes{%else%}no{%endunless%}'
|
const src = '{% unless false %}yes{%else%}no{%endunless%}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('yes')
|
return expect(html).toBe('yes')
|
||||||
})
|
})
|
||||||
it('should reject when tag not closed', function () {
|
it('should reject when tag not closed', function () {
|
||||||
const src = '{% unless 1 > 2 %}yes'
|
const src = '{% unless 1 > 2 %}yes'
|
||||||
return expect(liquid.parseAndRender(src))
|
return expect(liquid.parseAndRender(src))
|
||||||
.to.be.rejectedWith(/tag {% unless 1 > 2 %} not closed/)
|
.rejects.toThrow(/tag {% unless 1 > 2 %} not closed/)
|
||||||
})
|
})
|
||||||
it('should render unless when predicate yields false and else undefined', async function () {
|
it('should render unless when predicate yields false and else undefined', async function () {
|
||||||
const src = '{% unless 1 > 2 %}yes{%endunless%}'
|
const src = '{% unless 1 > 2 %}yes{%endunless%}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('yes')
|
return expect(html).toBe('yes')
|
||||||
})
|
})
|
||||||
it('should render "" when predicate yields false and else undefined', async function () {
|
it('should render "" when predicate yields false and else undefined', async function () {
|
||||||
const src = '{% unless 1 < 2 %}yes{%endunless%}'
|
const src = '{% unless 1 < 2 %}yes{%endunless%}'
|
||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).to.equal('')
|
return expect(html).toBe('')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should output unless contents in order', async function () {
|
it('should output unless contents in order', async function () {
|
||||||
@@ -46,7 +42,7 @@ describe('tags/unless', function () {
|
|||||||
{% unless false %}Inside {{ location }}{% endunless %}
|
{% unless false %}Inside {{ location }}{% endunless %}
|
||||||
After {{ location }}`
|
After {{ location }}`
|
||||||
const html = await liquid.parseAndRender(src, { location: 'wonderland' })
|
const html = await liquid.parseAndRender(src, { location: 'wonderland' })
|
||||||
expect(html).to.equal(`
|
expect(html).toBe(`
|
||||||
Before wonderland
|
Before wonderland
|
||||||
Inside wonderland
|
Inside wonderland
|
||||||
After wonderland`)
|
After wonderland`)
|
||||||
@@ -56,12 +52,12 @@ describe('tags/unless', function () {
|
|||||||
it('should render else when predicate yields true', function () {
|
it('should render else when predicate yields true', function () {
|
||||||
const src = '{% unless 0 %}yes{%else%}no{%endunless%}'
|
const src = '{% unless 0 %}yes{%else%}no{%endunless%}'
|
||||||
const html = liquid.parseAndRenderSync(src)
|
const html = liquid.parseAndRenderSync(src)
|
||||||
expect(html).to.equal('no')
|
expect(html).toBe('no')
|
||||||
})
|
})
|
||||||
it('should render unless when predicate yields false', function () {
|
it('should render unless when predicate yields false', function () {
|
||||||
const src = '{% unless false %}yes{%else%}no{%endunless%}'
|
const src = '{% unless false %}yes{%else%}no{%endunless%}'
|
||||||
const html = liquid.parseAndRenderSync(src)
|
const html = liquid.parseAndRenderSync(src)
|
||||||
expect(html).to.equal('yes')
|
expect(html).toBe('yes')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1,11 +1,7 @@
|
|||||||
import { expect, use } from 'chai'
|
|
||||||
import { RenderError } from '../../../src/util/error'
|
import { RenderError } from '../../../src/util/error'
|
||||||
import { Liquid } from '../../../src/liquid'
|
import { Liquid } from '../../../src/liquid'
|
||||||
import * as path from 'path'
|
import * as path from 'path'
|
||||||
import { mock, restore } from '../../stub/mockfs'
|
import { mock, restore } from '../../stub/mockfs'
|
||||||
import * as chaiAsPromised from 'chai-as-promised'
|
|
||||||
|
|
||||||
use(chaiAsPromised)
|
|
||||||
|
|
||||||
let engine = new Liquid()
|
let engine = new Liquid()
|
||||||
const strictEngine = new Liquid({
|
const strictEngine = new Liquid({
|
||||||
@@ -18,9 +14,10 @@ describe('error', function () {
|
|||||||
|
|
||||||
describe('TokenizationError', function () {
|
describe('TokenizationError', function () {
|
||||||
it('should throw TokenizationError when tag illegal', async function () {
|
it('should throw TokenizationError when tag illegal', async function () {
|
||||||
const err = await expect(engine.parseAndRender('{% . a %}', {})).be.rejected
|
await expect(engine.parseAndRender('{% . a %}', {})).rejects.toMatchObject({
|
||||||
expect(err.name).to.equal('TokenizationError')
|
name: 'TokenizationError',
|
||||||
expect(err.message).to.contain('illegal tag syntax')
|
message: expect.stringContaining('illegal tag syntax')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
it('should contain template content in err.message', async function () {
|
it('should contain template content in err.message', async function () {
|
||||||
const html = ['1st', '2nd', 'X{% . a %} Y', '4th']
|
const html = ['1st', '2nd', 'X{% . a %} Y', '4th']
|
||||||
@@ -31,33 +28,41 @@ describe('error', function () {
|
|||||||
' 4| 4th',
|
' 4| 4th',
|
||||||
'TokenizationError'
|
'TokenizationError'
|
||||||
]
|
]
|
||||||
const err = await expect(engine.parseAndRender(html.join('\n'))).be.rejected
|
await expect(engine.parseAndRender(html.join('\n'))).rejects.toMatchObject({
|
||||||
expect(err.message).to.equal('illegal tag syntax, line:3, col:2')
|
message: 'illegal tag syntax, line:3, col:2',
|
||||||
expect(err.stack).to.contain(message.join('\n'))
|
stack: expect.stringContaining(message.join('\n')),
|
||||||
expect(err.name).to.equal('TokenizationError')
|
name: 'TokenizationError'
|
||||||
|
})
|
||||||
})
|
})
|
||||||
it('should contain the whole template content in err.token.input', async function () {
|
it('should contain the whole template content in err.token.input', async function () {
|
||||||
const html = 'bar\nfoo{% . a %}\nfoo'
|
const html = 'bar\nfoo{% . a %}\nfoo'
|
||||||
const err = await expect(engine.parseAndRender(html)).be.rejected
|
await expect(engine.parseAndRender(html)).rejects.toMatchObject({
|
||||||
expect(err.token.input).to.equal(html)
|
token: expect.objectContaining({
|
||||||
|
input: html
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
it('should contain stack in err.stack', async function () {
|
it('should contain stack in err.stack', async function () {
|
||||||
const err = await expect(engine.parseAndRender('{% . a %}')).be.rejected
|
await expect(engine.parseAndRender('{% . a %}')).rejects.toMatchObject({
|
||||||
expect(err.message).to.contain('illegal tag syntax')
|
message: expect.stringContaining('illegal tag syntax'),
|
||||||
expect(err.stack).to.contain('at Liquid.parse')
|
stack: expect.stringContaining('at Liquid.parse')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
describe('captureStackTrace compatibility', function () {
|
describe('captureStackTrace compatibility', function () {
|
||||||
it('should be empty when captureStackTrace undefined', async function () {
|
it('should be empty when captureStackTrace undefined', async function () {
|
||||||
const err = await expect(engine.parseAndRender('{% . a %}')).be.rejected
|
await expect(engine.parseAndRender('{% . a %}')).rejects.toMatchObject({
|
||||||
expect(err.stack).to.contain('illegal tag syntax')
|
stack: expect.stringContaining('illegal tag syntax')
|
||||||
expect(err.stack).to.not.contain('at Object.parse')
|
})
|
||||||
|
await expect(engine.parseAndRender('{% . a %}')).rejects.toMatchObject({
|
||||||
|
stack: expect.not.stringContaining('at Object.parse')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
it('should throw error with [line, col] if tag unmatched', async function () {
|
it('should throw error with [line, col] if tag unmatched', async function () {
|
||||||
const err = await expect(engine.parseAndRender('1\n2\nfoo{% assign a = 4 }\n4')).be.rejected
|
await expect(engine.parseAndRender('1\n2\nfoo{% assign a = 4 }\n4')).rejects.toMatchObject({
|
||||||
console.log(err.stack)
|
name: 'TokenizationError',
|
||||||
expect(err.name).to.equal('TokenizationError')
|
message: 'tag "{% assign a =..." not closed, line:3, col:4'
|
||||||
expect(err.message).to.equal('tag "{% assign a =..." not closed, line:3, col:4')
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -82,30 +87,34 @@ describe('error', function () {
|
|||||||
})
|
})
|
||||||
it('should throw RenderError when tag throws', async function () {
|
it('should throw RenderError when tag throws', async function () {
|
||||||
const src = '{%throwingTag%}'
|
const src = '{%throwingTag%}'
|
||||||
const err = await expect(engine.parseAndRender(src)).be.rejected
|
await expect(engine.parseAndRender(src)).rejects.toMatchObject({
|
||||||
expect(err.name).to.equal('RenderError')
|
name: 'RenderError',
|
||||||
expect(err.message).to.contain('intended render error')
|
message: expect.stringContaining('intended render error')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
it('should throw RenderError when tag rejects', async function () {
|
it('should throw RenderError when tag rejects', async function () {
|
||||||
const src = '{%rejectingTag%}'
|
const src = '{%rejectingTag%}'
|
||||||
const err = await expect(engine.parseAndRender(src)).be.rejected
|
await expect(engine.parseAndRender(src)).rejects.toMatchObject({
|
||||||
expect(err.name).to.equal('RenderError')
|
name: 'RenderError',
|
||||||
expect(err.message).to.contain('intended render reject')
|
message: expect.stringContaining('intended render reject')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
it('should throw RenderError when filter throws', async function () {
|
it('should throw RenderError when filter throws', async function () {
|
||||||
const src = '{{1|throwingFilter}}'
|
const src = '{{1|throwingFilter}}'
|
||||||
const err = await expect(engine.parseAndRender(src)).be.rejected
|
await expect(engine.parseAndRender(src)).rejects.toMatchObject({
|
||||||
expect(err.name).to.equal('RenderError')
|
name: 'RenderError',
|
||||||
expect(err.message).to.contain('throwed by filter')
|
message: expect.stringContaining('throwed by filter')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
it('should not throw when variable undefined by default', async function () {
|
it('should not throw when variable undefined by default', async function () {
|
||||||
const html = await engine.parseAndRender('X{{a}}Y')
|
const html = await engine.parseAndRender('X{{a}}Y')
|
||||||
return expect(html).to.equal('XY')
|
return expect(html).toBe('XY')
|
||||||
})
|
})
|
||||||
it('should throw RenderError when variable not defined', async function () {
|
it('should throw RenderError when variable not defined', async function () {
|
||||||
const err = await expect(strictEngine.parseAndRender('{{a}}')).be.rejected
|
await expect(strictEngine.parseAndRender('{{a}}')).rejects.toMatchObject({
|
||||||
expect(err).to.have.property('name', 'RenderError')
|
name: 'RenderError',
|
||||||
expect(err.message).to.contain('undefined variable: a')
|
message: expect.stringContaining('undefined variable: a')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
it('should contain template context in err.stack', async function () {
|
it('should contain template context in err.stack', async function () {
|
||||||
const html = ['1st', '2nd', '3rd', 'X{%throwingTag%} Y', '5th', '6th', '7th']
|
const html = ['1st', '2nd', '3rd', 'X{%throwingTag%} Y', '5th', '6th', '7th']
|
||||||
@@ -118,10 +127,11 @@ describe('error', function () {
|
|||||||
' 7| 7th',
|
' 7| 7th',
|
||||||
'RenderError'
|
'RenderError'
|
||||||
]
|
]
|
||||||
const err = await expect(engine.parseAndRender(html.join('\n'))).be.rejected
|
await expect(engine.parseAndRender(html.join('\n'))).rejects.toMatchObject({
|
||||||
expect(err.message).to.equal('intended render error, line:4, col:2')
|
name: 'RenderError',
|
||||||
expect(err.stack).to.contain(message.join('\n'))
|
message: 'intended render error, line:4, col:2',
|
||||||
expect(err.name).to.equal('RenderError')
|
stack: expect.stringContaining(message.join('\n'))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
it('should contain original error info for {% layout %}', async function () {
|
it('should contain original error info for {% layout %}', async function () {
|
||||||
mock({
|
mock({
|
||||||
@@ -145,10 +155,11 @@ describe('error', function () {
|
|||||||
' 7| 7th',
|
' 7| 7th',
|
||||||
'RenderError'
|
'RenderError'
|
||||||
]
|
]
|
||||||
const err = await expect(engine.parseAndRender(html)).be.rejected
|
await expect(engine.parseAndRender(html)).rejects.toMatchObject({
|
||||||
expect(err.message).to.equal(`intended render error, file:${path.resolve('/throwing-tag.html')}, line:4, col:2`)
|
name: 'RenderError',
|
||||||
expect(err.stack).to.contain(message.join('\n'))
|
message: `intended render error, file:${path.resolve('/throwing-tag.html')}, line:4, col:2`,
|
||||||
expect(err.name).to.equal('RenderError')
|
stack: expect.stringContaining(message.join('\n'))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
it('should contain original error info for {% include %}', async function () {
|
it('should contain original error info for {% include %}', async function () {
|
||||||
const origin = ['1st', '2nd', '3rd', 'X{%throwingTag%} Y', '5th', '6th', '7th']
|
const origin = ['1st', '2nd', '3rd', 'X{%throwingTag%} Y', '5th', '6th', '7th']
|
||||||
@@ -165,15 +176,17 @@ describe('error', function () {
|
|||||||
' 7| 7th',
|
' 7| 7th',
|
||||||
'RenderError'
|
'RenderError'
|
||||||
]
|
]
|
||||||
const err = await expect(engine.parseAndRender(html)).be.rejected
|
await expect(engine.parseAndRender(html)).rejects.toMatchObject({
|
||||||
expect(err.message).to.equal(`intended render error, file:${path.resolve('/throwing-tag.html')}, line:4, col:2`)
|
name: 'RenderError',
|
||||||
expect(err.stack).to.contain(message.join('\n'))
|
message: `intended render error, file:${path.resolve('/throwing-tag.html')}, line:4, col:2`,
|
||||||
expect(err.name).to.equal('RenderError')
|
stack: expect.stringContaining(message.join('\n'))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
it('should contain stack in err.stack', async function () {
|
it('should contain stack in err.stack', async function () {
|
||||||
const err = await expect(engine.parseAndRender('{%rejectingTag%}')).be.rejected
|
await expect(engine.parseAndRender('{%rejectingTag%}')).rejects.toMatchObject({
|
||||||
expect(err.message).to.contain('intended render reject')
|
message: expect.stringContaining('intended render reject'),
|
||||||
expect(err.stack).to.match(/at .*:\d+:\d+/)
|
stack: expect.stringMatching(/at .*:\d+:\d+/)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -188,30 +201,35 @@ describe('error', function () {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
it('should throw ParseError when filter not defined', async function () {
|
it('should throw ParseError when filter not defined', async function () {
|
||||||
const err = await expect(strictEngine.parseAndRender('{{1 | a}}')).be.rejected
|
await expect(strictEngine.parseAndRender('{{1 | a}}')).rejects.toMatchObject({
|
||||||
expect(err).to.have.property('name', 'ParseError')
|
name: 'ParseError',
|
||||||
expect(err.message).to.contain('undefined filter: a')
|
message: expect.stringContaining('undefined filter: a')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
it('should throw ParseError when tag not closed', async function () {
|
it('should throw ParseError when tag not closed', async function () {
|
||||||
const err = await expect(engine.parseAndRender('{% if %}')).be.rejected
|
await expect(engine.parseAndRender('{% if %}')).rejects.toMatchObject({
|
||||||
expect(err.name).to.equal('ParseError')
|
name: 'ParseError',
|
||||||
expect(err.message).to.contain('tag {% if %} not closed')
|
message: expect.stringContaining('tag {% if %} not closed')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
it('should throw ParseError when tag parse throws', async function () {
|
it('should throw ParseError when tag parse throws', async function () {
|
||||||
const err = await expect(engine.parseAndRender('{%throwsOnParse%}')).be.rejected
|
await expect(engine.parseAndRender('{%throwsOnParse%}')).rejects.toMatchObject({
|
||||||
expect(err.name).to.equal('ParseError')
|
name: 'ParseError',
|
||||||
expect(err.message).to.contain('intended parse error')
|
message: expect.stringContaining('intended parse error')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
it('should throw ParseError when tag not found', async function () {
|
it('should throw ParseError when tag not found', async function () {
|
||||||
const src = '{%if true%}\naaa{%endif%}\n{% -a %}\n3'
|
const src = '{%if true%}\naaa{%endif%}\n{% -a %}\n3'
|
||||||
const err = await expect(engine.parseAndRender(src)).be.rejected
|
await expect(engine.parseAndRender(src)).rejects.toMatchObject({
|
||||||
expect(err.name).to.equal('ParseError')
|
name: 'ParseError',
|
||||||
expect(err.message).to.contain('tag "-a" not found')
|
message: expect.stringContaining('tag "-a" not found')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
it('should throw ParseError when tag not exist', async function () {
|
it('should throw ParseError when tag not exist', async function () {
|
||||||
const err = await expect(engine.parseAndRender('{% a %}')).be.rejected
|
await expect(engine.parseAndRender('{% a %}')).rejects.toMatchObject({
|
||||||
expect(err.name).to.equal('ParseError')
|
name: 'ParseError',
|
||||||
expect(err.message).to.contain('tag "a" not found')
|
message: expect.stringContaining('tag "a" not found')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should contain template context in err.stack', async function () {
|
it('should contain template context in err.stack', async function () {
|
||||||
@@ -225,10 +243,11 @@ describe('error', function () {
|
|||||||
' 7| 7th',
|
' 7| 7th',
|
||||||
'ParseError: tag "a" not found'
|
'ParseError: tag "a" not found'
|
||||||
]
|
]
|
||||||
const err = await expect(engine.parseAndRender(html.join('\n'))).be.rejected
|
await expect(engine.parseAndRender(html.join('\n'))).rejects.toMatchObject({
|
||||||
expect(err.message).to.equal('tag "a" not found, line:4, col:2')
|
name: 'ParseError',
|
||||||
expect(err.stack).to.contain(message.join('\n'))
|
message: 'tag "a" not found, line:4, col:2',
|
||||||
expect(err.name).to.equal('ParseError')
|
stack: expect.stringContaining(message.join('\n'))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should handle err.message when context not enough', async function () {
|
it('should handle err.message when context not enough', async function () {
|
||||||
@@ -240,15 +259,19 @@ describe('error', function () {
|
|||||||
' 4| 4th',
|
' 4| 4th',
|
||||||
'ParseError: tag "a" not found'
|
'ParseError: tag "a" not found'
|
||||||
]
|
]
|
||||||
const err = await expect(engine.parseAndRender(html.join('\n'))).be.rejected
|
await expect(engine.parseAndRender(html.join('\n'))).rejects.toMatchObject({
|
||||||
expect(err.message).to.equal('tag "a" not found, line:2, col:2')
|
message: 'tag "a" not found, line:2, col:2',
|
||||||
expect(err.stack).to.contain(message.join('\n'))
|
stack: expect.stringContaining(message.join('\n'))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should contain stack in err.stack', async function () {
|
it('should contain stack in err.stack', async function () {
|
||||||
const err = await expect(engine.parseAndRender('{% -a %}')).be.rejected
|
await expect(engine.parseAndRender('{% -a %}')).rejects.toMatchObject({
|
||||||
expect(err.stack).to.contain('ParseError: tag "-a" not found')
|
stack: expect.stringContaining('ParseError: tag "-a" not found')
|
||||||
expect(err.stack).to.match(/at .*:\d+:\d+\)/)
|
})
|
||||||
|
await expect(engine.parseAndRender('{% -a %}')).rejects.toMatchObject({
|
||||||
|
stack: expect.stringMatching(/at .*:\d+:\d+\)/)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('sync support', function () {
|
describe('sync support', function () {
|
||||||
@@ -265,8 +288,8 @@ describe('error', function () {
|
|||||||
})
|
})
|
||||||
it('should throw RenderError when tag throws', function () {
|
it('should throw RenderError when tag throws', function () {
|
||||||
const src = '{%throwingTag%}'
|
const src = '{%throwingTag%}'
|
||||||
expect(() => engine.parseAndRenderSync(src))
|
expect(() => engine.parseAndRenderSync(src)).toThrow(RenderError)
|
||||||
.to.throw(RenderError, /intended render error/)
|
expect(() => engine.parseAndRenderSync(src)).toThrow(/intended render error/)
|
||||||
})
|
})
|
||||||
it('should contain original error info for {% include %}', function () {
|
it('should contain original error info for {% include %}', function () {
|
||||||
mock({
|
mock({
|
||||||
@@ -286,9 +309,9 @@ describe('error', function () {
|
|||||||
engine.parseAndRenderSync(html)
|
engine.parseAndRenderSync(html)
|
||||||
throw new Error('expected throw')
|
throw new Error('expected throw')
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
expect(err.message).to.equal(`intended render error, file:${path.resolve('/throwing-tag.html')}, line:4, col:2`)
|
expect(err).toHaveProperty('name', 'RenderError')
|
||||||
expect(err.stack).to.contain(message.join('\n'))
|
expect(err).toHaveProperty('message', `intended render error, file:${path.resolve('/throwing-tag.html')}, line:4, col:2`)
|
||||||
expect(err.name).to.equal('RenderError')
|
expect(err).toHaveProperty('stack', expect.stringContaining(message.join('\n')))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
import { isString, forOwn } from '../../src/util/underscore'
|
import { isString, forOwn } from '../../src/util/underscore'
|
||||||
import * as fs from '../../src/fs/node'
|
import * as fs from '../../src/fs/fs-impl'
|
||||||
import { resolve } from 'path'
|
import { resolve } from 'path'
|
||||||
|
|
||||||
interface FileDescriptor {
|
interface FileDescriptor {
|
||||||
|
|||||||
+2
-3
@@ -1,6 +1,5 @@
|
|||||||
import { Liquid } from '../../src/liquid'
|
import { Liquid } from '../../src/liquid'
|
||||||
import { LiquidOptions } from '../../src/liquid-options'
|
import { LiquidOptions } from '../../src/liquid-options'
|
||||||
import { expect } from 'chai'
|
|
||||||
|
|
||||||
export const liquid = new Liquid()
|
export const liquid = new Liquid()
|
||||||
|
|
||||||
@@ -15,6 +14,6 @@ export async function test (src: string, ctx: object | string, expected?: string
|
|||||||
}
|
}
|
||||||
const engine = opts ? new Liquid(opts) : liquid
|
const engine = opts ? new Liquid(opts) : liquid
|
||||||
const result = await engine.parseAndRender(src, ctx as object)
|
const result = await engine.parseAndRender(src, ctx as object)
|
||||||
if (expected instanceof RegExp) return expect(result).to.match(expected)
|
if (expected instanceof RegExp) return expect(result).toMatch(expected)
|
||||||
return expect(result).to.equal(expected)
|
return expect(result).toBe(expected)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
import { expect } from 'chai'
|
|
||||||
import { StreamedEmitter } from '../../../src/emitters/streamed-emitter-browser'
|
|
||||||
|
|
||||||
describe('emitters/streamed-emitter-browser', () => {
|
|
||||||
it('should throw when try to constructing', () => {
|
|
||||||
expect(() => new StreamedEmitter()).to.throw(/streaming not supported/)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
import { expect } from 'chai'
|
|
||||||
import { matchOperator } from '../../../src/parser/match-operator'
|
|
||||||
import { defaultOperators } from '../../../src'
|
|
||||||
import { createTrie } from '../../../src/util/operator-trie'
|
|
||||||
|
|
||||||
describe('parser/matchOperator()', function () {
|
|
||||||
const trie = createTrie(defaultOperators)
|
|
||||||
it('should match contains', () => {
|
|
||||||
expect(matchOperator('contains', 0, trie)).to.equal(8)
|
|
||||||
})
|
|
||||||
it('should match comparision', () => {
|
|
||||||
expect(matchOperator('>', 0, trie)).to.equal(1)
|
|
||||||
expect(matchOperator('>=', 0, trie)).to.equal(2)
|
|
||||||
expect(matchOperator('<', 0, trie)).to.equal(1)
|
|
||||||
expect(matchOperator('<=', 0, trie)).to.equal(2)
|
|
||||||
})
|
|
||||||
it('should match binary logic', () => {
|
|
||||||
expect(matchOperator('and', 0, trie)).to.equal(3)
|
|
||||||
expect(matchOperator('or', 0, trie)).to.equal(2)
|
|
||||||
})
|
|
||||||
it('should not match if word not terminate', () => {
|
|
||||||
expect(matchOperator('true1', 0, trie)).to.equal(-1)
|
|
||||||
expect(matchOperator('containsa', 0, trie)).to.equal(-1)
|
|
||||||
})
|
|
||||||
it('should match if word boundary found', () => {
|
|
||||||
expect(matchOperator('>=1', 0, trie)).to.equal(2)
|
|
||||||
expect(matchOperator('contains b', 0, trie)).to.equal(8)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
import { expect } from 'chai'
|
|
||||||
import { parseStringLiteral } from '../../../src/parser/parse-string-literal'
|
|
||||||
|
|
||||||
describe('parseStringLiteral()', function () {
|
|
||||||
it('should parse octal escape', () => {
|
|
||||||
expect(parseStringLiteral(String.raw`"\1010"`)).to.equal('A0')
|
|
||||||
expect(parseStringLiteral(String.raw`"\12"`)).to.equal('\n')
|
|
||||||
expect(parseStringLiteral(String.raw`"\01"`)).to.equal('\u0001')
|
|
||||||
expect(parseStringLiteral(String.raw`"\0"`)).to.equal('\0')
|
|
||||||
})
|
|
||||||
it('should skip invalid octal escape', () => {
|
|
||||||
expect(parseStringLiteral(String.raw`"\9"`)).to.equal('9')
|
|
||||||
})
|
|
||||||
it('should parse \\n, \\t, \\r', () => {
|
|
||||||
expect(parseStringLiteral(String.raw`"fo\no"`)).to.equal('fo\no')
|
|
||||||
expect(parseStringLiteral(String.raw`'fo\to'`)).to.equal('fo\to')
|
|
||||||
expect(parseStringLiteral(String.raw`'fo\ro'`)).to.equal('fo\ro')
|
|
||||||
})
|
|
||||||
it('should parse unicode(hex) escape', () => {
|
|
||||||
expect(parseStringLiteral('"\\u003C"')).to.equal('<')
|
|
||||||
expect(parseStringLiteral('"\\u003cZ"')).to.equal('<Z')
|
|
||||||
expect(parseStringLiteral('"\\u41"')).to.equal('A')
|
|
||||||
})
|
|
||||||
it('should skip invalid unicode(hex) escape', () => {
|
|
||||||
expect(parseStringLiteral('"\\u41Z"')).to.equal('AZ')
|
|
||||||
expect(parseStringLiteral('"\\uZ"')).to.equal('\0Z')
|
|
||||||
})
|
|
||||||
it('should parse quote escape', () => {
|
|
||||||
expect(parseStringLiteral(String.raw`"fo\'o"`)).to.equal("fo'o")
|
|
||||||
expect(parseStringLiteral(String.raw`'fo\"o'`)).to.equal('fo"o')
|
|
||||||
})
|
|
||||||
it('should parse slash escape', () => {
|
|
||||||
expect(parseStringLiteral(String.raw`'fo\\o'`)).to.equal('fo\\o')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
@@ -1,555 +0,0 @@
|
|||||||
import { expect } from 'chai'
|
|
||||||
import { IdentifierToken } from '../../../src/tokens/identifier-token'
|
|
||||||
import { NumberToken } from '../../../src/tokens/number-token'
|
|
||||||
import { PropertyAccessToken } from '../../../src/tokens/property-access-token'
|
|
||||||
import { RangeToken } from '../../../src/tokens/range-token'
|
|
||||||
import { OperatorToken } from '../../../src/tokens/operator-token'
|
|
||||||
import { Tokenizer } from '../../../src/parser/tokenizer'
|
|
||||||
import { TagToken } from '../../../src/tokens/tag-token'
|
|
||||||
import { QuotedToken } from '../../../src/tokens/quoted-token'
|
|
||||||
import { OutputToken } from '../../../src/tokens/output-token'
|
|
||||||
import { HTMLToken } from '../../../src/tokens/html-token'
|
|
||||||
import { LiquidTagToken } from '../../../src/tokens/liquid-tag-token'
|
|
||||||
|
|
||||||
describe('Tokenizer', function () {
|
|
||||||
it('should read quoted', () => {
|
|
||||||
expect(new Tokenizer('"foo" ff').readQuoted()!.getText()).to.equal('"foo"')
|
|
||||||
expect(new Tokenizer(' "foo"ff').readQuoted()!.getText()).to.equal('"foo"')
|
|
||||||
})
|
|
||||||
it('should read value', () => {
|
|
||||||
expect(new Tokenizer('a[ b][ "c d" ]').readValueOrThrow().getText()).to.equal('a[ b][ "c d" ]')
|
|
||||||
expect(new Tokenizer('a.b[c[d.e]]').readValueOrThrow().getText()).to.equal('a.b[c[d.e]]')
|
|
||||||
})
|
|
||||||
it('should read identifier', () => {
|
|
||||||
expect(new Tokenizer('foo bar').readIdentifier()).to.haveOwnProperty('content', 'foo')
|
|
||||||
expect(new Tokenizer('foo bar').readWord()).to.haveOwnProperty('content', 'foo')
|
|
||||||
})
|
|
||||||
it('should read number value', () => {
|
|
||||||
const token: NumberToken = new Tokenizer('2.33.2').readValueOrThrow() as any
|
|
||||||
expect(token).to.be.instanceOf(NumberToken)
|
|
||||||
expect(token.whole.getText()).to.equal('2')
|
|
||||||
expect(token.decimal!.getText()).to.equal('33')
|
|
||||||
expect(token.getText()).to.equal('2.33')
|
|
||||||
})
|
|
||||||
it('should read quoted value', () => {
|
|
||||||
const value = new Tokenizer('"foo"a').readValue()
|
|
||||||
expect(value).to.be.instanceOf(QuotedToken)
|
|
||||||
expect(value!.getText()).to.equal('"foo"')
|
|
||||||
})
|
|
||||||
it('should read property access value', () => {
|
|
||||||
expect(new Tokenizer('a[b]["c d"]').readValueOrThrow().getText()).to.equal('a[b]["c d"]')
|
|
||||||
})
|
|
||||||
it('should read quoted property access value', () => {
|
|
||||||
const value = new Tokenizer('["a prop"]').readValue()
|
|
||||||
expect(value).to.be.instanceOf(PropertyAccessToken)
|
|
||||||
expect((value as PropertyAccessToken).variable.getText()).to.equal('"a prop"')
|
|
||||||
})
|
|
||||||
it('should throw for broken quoted property access', () => {
|
|
||||||
const tokenizer = new Tokenizer('[5]')
|
|
||||||
expect(() => tokenizer.readValueOrThrow()).to.throw()
|
|
||||||
})
|
|
||||||
it('should throw for incomplete quoted property access', () => {
|
|
||||||
const tokenizer = new Tokenizer('["a prop"')
|
|
||||||
expect(() => tokenizer.readValueOrThrow()).to.throw()
|
|
||||||
})
|
|
||||||
it('should read hash', () => {
|
|
||||||
const hash1 = new Tokenizer('foo: 3').readHash()
|
|
||||||
expect(hash1!.name.content).to.equal('foo')
|
|
||||||
expect(hash1!.value!.getText()).to.equal('3')
|
|
||||||
|
|
||||||
const hash2 = new Tokenizer(', foo: a[ "bar"]').readHash()
|
|
||||||
expect(hash2!.name.content).to.equal('foo')
|
|
||||||
expect(hash2!.value!.getText()).to.equal('a[ "bar"]')
|
|
||||||
})
|
|
||||||
it('should read multiple hashs', () => {
|
|
||||||
const hashes = new Tokenizer(', limit: 3 reverse offset:off').readHashes()
|
|
||||||
expect(hashes).to.have.lengthOf(3)
|
|
||||||
const [limit, reverse, offset] = hashes
|
|
||||||
expect(limit.name.content).to.equal('limit')
|
|
||||||
expect(limit.value!.getText()).to.equal('3')
|
|
||||||
|
|
||||||
expect(reverse.name.content).to.equal('reverse')
|
|
||||||
expect(reverse.value).to.be.undefined
|
|
||||||
|
|
||||||
expect(offset.name.content).to.equal('offset')
|
|
||||||
expect(offset.value!.getText()).to.equal('off')
|
|
||||||
})
|
|
||||||
it('should read hash value with property access', () => {
|
|
||||||
const hashes = new Tokenizer('cols: 2, rows: data["rows"]').readHashes()
|
|
||||||
expect(hashes).to.have.lengthOf(2)
|
|
||||||
const [cols, rols] = hashes
|
|
||||||
|
|
||||||
expect(cols.name.content).to.equal('cols')
|
|
||||||
expect(cols.value!.getText()).to.equal('2')
|
|
||||||
|
|
||||||
expect(rols.name.content).to.equal('rows')
|
|
||||||
expect(rols.value!.getText()).to.equal('data["rows"]')
|
|
||||||
})
|
|
||||||
describe('#readTopLevelTokens()', () => {
|
|
||||||
it('should read HTML token', function () {
|
|
||||||
const html = '<html><body><p>Lorem Ipsum</p></body></html>'
|
|
||||||
const tokenizer = new Tokenizer(html)
|
|
||||||
const tokens = tokenizer.readTopLevelTokens()
|
|
||||||
|
|
||||||
expect(tokens.length).to.equal(1)
|
|
||||||
expect(tokens[0]).instanceOf(HTMLToken)
|
|
||||||
expect((tokens[0] as HTMLToken).getContent()).to.equal(html)
|
|
||||||
})
|
|
||||||
it('should read tag token', function () {
|
|
||||||
const html = '<p>{% for p in a[1]%}</p>'
|
|
||||||
const tokenizer = new Tokenizer(html)
|
|
||||||
const tokens = tokenizer.readTopLevelTokens()
|
|
||||||
|
|
||||||
expect(tokens.length).to.equal(3)
|
|
||||||
const tag = tokens[1] as TagToken
|
|
||||||
expect(tag).instanceOf(TagToken)
|
|
||||||
expect(tag.name).to.equal('for')
|
|
||||||
expect(tag.args).to.equal('p in a[1]')
|
|
||||||
})
|
|
||||||
it('should allow unclosed tag inside {% raw %}', function () {
|
|
||||||
const html = '{%raw%} {%if%} {%else {%endraw%}'
|
|
||||||
const tokenizer = new Tokenizer(html)
|
|
||||||
const tokens = tokenizer.readTopLevelTokens()
|
|
||||||
|
|
||||||
expect(tokens.length).to.equal(3)
|
|
||||||
expect(tokens[0]).to.haveOwnProperty('name', 'raw')
|
|
||||||
expect((tokens[1] as any).getContent()).to.equal(' {%if%} {%else ')
|
|
||||||
})
|
|
||||||
it('should allow unclosed endraw tag inside {% raw %}', function () {
|
|
||||||
const html = '{%raw%} {%endraw {%raw%} {%endraw%}'
|
|
||||||
const tokenizer = new Tokenizer(html)
|
|
||||||
const tokens = tokenizer.readTopLevelTokens()
|
|
||||||
|
|
||||||
expect(tokens.length).to.equal(3)
|
|
||||||
expect(tokens[0]).to.haveOwnProperty('name', 'raw')
|
|
||||||
expect((tokens[1] as any).getContent()).to.equal(' {%endraw {%raw%} ')
|
|
||||||
})
|
|
||||||
it('should throw when {% raw %} not closed', function () {
|
|
||||||
const html = '{%raw%} {%endraw {%raw%}'
|
|
||||||
const tokenizer = new Tokenizer(html)
|
|
||||||
expect(() => tokenizer.readTopLevelTokens()).to.throw('raw "{%raw%} {%end..." not closed, line:1, col:8')
|
|
||||||
})
|
|
||||||
it('should read output token', function () {
|
|
||||||
const html = '<p>{{foo | date: "%Y-%m-%d"}}</p>'
|
|
||||||
const tokenizer = new Tokenizer(html)
|
|
||||||
const tokens = tokenizer.readTopLevelTokens()
|
|
||||||
|
|
||||||
expect(tokens.length).to.equal(3)
|
|
||||||
const output = tokens[1] as OutputToken
|
|
||||||
expect(output).instanceOf(OutputToken)
|
|
||||||
expect(output.content).to.equal('foo | date: "%Y-%m-%d"')
|
|
||||||
})
|
|
||||||
it('should handle consecutive value and tags', function () {
|
|
||||||
const html = '{{foo}}{{bar}}{%foo%}{%bar%}'
|
|
||||||
const tokenizer = new Tokenizer(html)
|
|
||||||
const tokens = tokenizer.readTopLevelTokens()
|
|
||||||
|
|
||||||
expect(tokens.length).to.equal(4)
|
|
||||||
const o1 = tokens[0] as OutputToken
|
|
||||||
const o2 = tokens[1] as OutputToken
|
|
||||||
const t1 = tokens[2] as TagToken
|
|
||||||
const t2 = tokens[3] as TagToken
|
|
||||||
expect(o1).instanceOf(OutputToken)
|
|
||||||
expect(o2).instanceOf(OutputToken)
|
|
||||||
expect(t1).instanceOf(TagToken)
|
|
||||||
expect(t2).instanceOf(TagToken)
|
|
||||||
|
|
||||||
expect(o1.content).to.equal('foo')
|
|
||||||
expect(o2.content).to.equal('bar')
|
|
||||||
expect(t1.name).to.equal('foo')
|
|
||||||
expect(t1.args).to.equal('')
|
|
||||||
expect(t2.name).to.equal('bar')
|
|
||||||
expect(t2.args).to.equal('')
|
|
||||||
})
|
|
||||||
it('should keep white spaces and newlines', function () {
|
|
||||||
const html = '{%foo%}\n{%bar %} \n {%alice%}'
|
|
||||||
const tokenizer = new Tokenizer(html)
|
|
||||||
const tokens = tokenizer.readTopLevelTokens()
|
|
||||||
expect(tokens.length).to.equal(5)
|
|
||||||
expect(tokens[1]).instanceOf(HTMLToken)
|
|
||||||
expect(tokens[1].getText()).to.equal('\n')
|
|
||||||
expect(tokens[3]).instanceOf(HTMLToken)
|
|
||||||
expect(tokens[3].getText()).to.equal(' \n ')
|
|
||||||
})
|
|
||||||
it('should handle multiple lines tag', function () {
|
|
||||||
const html = '{%foo\na:a\nb:1.23\n%}'
|
|
||||||
const tokenizer = new Tokenizer(html)
|
|
||||||
const tokens = tokenizer.readTopLevelTokens()
|
|
||||||
expect(tokens.length).to.equal(1)
|
|
||||||
expect(tokens[0]).instanceOf(TagToken)
|
|
||||||
expect((tokens[0] as TagToken).args).to.equal('a:a\nb:1.23')
|
|
||||||
expect(tokens[0].getText()).to.equal('{%foo\na:a\nb:1.23\n%}')
|
|
||||||
})
|
|
||||||
it('should handle multiple lines value', function () {
|
|
||||||
const html = '{{foo\n|date:\n"%Y-%m-%d"\n}}'
|
|
||||||
const tokenizer = new Tokenizer(html)
|
|
||||||
const tokens = tokenizer.readTopLevelTokens()
|
|
||||||
expect(tokens.length).to.equal(1)
|
|
||||||
expect(tokens[0]).instanceOf(OutputToken)
|
|
||||||
expect(tokens[0].getText()).to.equal('{{foo\n|date:\n"%Y-%m-%d"\n}}')
|
|
||||||
})
|
|
||||||
it('should handle complex object property access', function () {
|
|
||||||
const html = '{{ obj["my:property with anything"] }}'
|
|
||||||
const tokenizer = new Tokenizer(html)
|
|
||||||
const tokens = tokenizer.readTopLevelTokens()
|
|
||||||
expect(tokens.length).to.equal(1)
|
|
||||||
const output = tokens[0] as OutputToken
|
|
||||||
expect(output).instanceOf(OutputToken)
|
|
||||||
expect(output.content).to.equal('obj["my:property with anything"]')
|
|
||||||
})
|
|
||||||
it('should throw if tag not closed', function () {
|
|
||||||
const html = '{% assign foo = bar {{foo}}'
|
|
||||||
const tokenizer = new Tokenizer(html)
|
|
||||||
expect(() => tokenizer.readTopLevelTokens()).to.throw(/tag "{% assign foo..." not closed/)
|
|
||||||
})
|
|
||||||
it('should throw if output not closed', function () {
|
|
||||||
const tokenizer = new Tokenizer('{{name}')
|
|
||||||
expect(() => tokenizer.readTopLevelTokens()).to.throw(/output "{{name}" not closed/)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
describe('#readTagToken()', () => {
|
|
||||||
it('should skip quoted delimiters', function () {
|
|
||||||
const html = '{% assign a = "%} {% }} {{" %}'
|
|
||||||
const tokenizer = new Tokenizer(html)
|
|
||||||
const token = tokenizer.readTagToken()
|
|
||||||
|
|
||||||
expect(token).instanceOf(TagToken)
|
|
||||||
expect(token.name).to.equal('assign')
|
|
||||||
expect(token.args).to.equal('a = "%} {% }} {{"')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
describe('#readOutputToken()', () => {
|
|
||||||
it('should skip quoted delimiters', function () {
|
|
||||||
const html = '{{ "%} {%" | append: "}} {{" }}'
|
|
||||||
const tokenizer = new Tokenizer(html)
|
|
||||||
const token = tokenizer.readOutputToken()
|
|
||||||
|
|
||||||
expect(token).instanceOf(OutputToken)
|
|
||||||
expect(token.content).to.equal('"%} {%" | append: "}} {{"')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
describe('#readRange()', () => {
|
|
||||||
it('should read `(1..3)`', () => {
|
|
||||||
const range = new Tokenizer('(1..3)').readRange()
|
|
||||||
expect(range).to.be.instanceOf(RangeToken)
|
|
||||||
expect(range!.getText()).to.deep.equal('(1..3)')
|
|
||||||
const { lhs, rhs } = range!
|
|
||||||
expect(lhs).to.be.instanceOf(NumberToken)
|
|
||||||
expect(lhs.getText()).to.equal('1')
|
|
||||||
expect(rhs).to.be.instanceOf(NumberToken)
|
|
||||||
expect(rhs.getText()).to.equal('3')
|
|
||||||
})
|
|
||||||
it('should throw for `(..3)`', () => {
|
|
||||||
expect(() => new Tokenizer('(..3)').readRange()).to.throw('unexpected token "..3)", value expected')
|
|
||||||
})
|
|
||||||
it('should read `(a.b..c["..d"])`', () => {
|
|
||||||
const range = new Tokenizer('(a.b..c["..d"])').readRange()
|
|
||||||
expect(range).to.be.instanceOf(RangeToken)
|
|
||||||
expect(range!.getText()).to.deep.equal('(a.b..c["..d"])')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
describe('#readFilter()', () => {
|
|
||||||
it('should read a simple filter', function () {
|
|
||||||
const tokenizer = new Tokenizer('| plus')
|
|
||||||
const token = tokenizer.readFilter()
|
|
||||||
expect(token).to.have.property('name', 'plus')
|
|
||||||
expect(token).to.have.property('args').to.deep.equal([])
|
|
||||||
})
|
|
||||||
it('should read a filter with argument', function () {
|
|
||||||
const tokenizer = new Tokenizer(' | plus: 1')
|
|
||||||
const token = tokenizer.readFilter()
|
|
||||||
expect(token).to.have.property('name', 'plus')
|
|
||||||
expect(token!.args).to.have.lengthOf(1)
|
|
||||||
|
|
||||||
const one: NumberToken = token!.args[0] as any
|
|
||||||
expect(one).to.be.instanceOf(NumberToken)
|
|
||||||
expect(one.getText()).to.equal('1')
|
|
||||||
})
|
|
||||||
it('should read a filter with colon but no argument', function () {
|
|
||||||
const tokenizer = new Tokenizer('| plus:')
|
|
||||||
const token = tokenizer.readFilter()
|
|
||||||
expect(token).to.have.property('name', 'plus')
|
|
||||||
expect(token).to.have.property('args').to.deep.equal([])
|
|
||||||
})
|
|
||||||
it('should read null if name not found', function () {
|
|
||||||
const tokenizer = new Tokenizer('|')
|
|
||||||
const token = tokenizer.readFilter()
|
|
||||||
expect(token).to.be.null
|
|
||||||
})
|
|
||||||
it('should read a filter with k/v argument', function () {
|
|
||||||
const tokenizer = new Tokenizer(' | plus: a:1')
|
|
||||||
const token = tokenizer.readFilter()
|
|
||||||
expect(token).to.have.property('name', 'plus')
|
|
||||||
expect(token!.args).to.have.lengthOf(1)
|
|
||||||
|
|
||||||
const [k, v]: [string, NumberToken] = token!.args[0] as any
|
|
||||||
expect(k).to.equal('a')
|
|
||||||
expect(v).to.be.instanceOf(NumberToken)
|
|
||||||
expect(v.getText()).to.equal('1')
|
|
||||||
})
|
|
||||||
it('should read a filter with "arr[0]" argument', function () {
|
|
||||||
const tokenizer = new Tokenizer('| plus: arr[0]')
|
|
||||||
const token = tokenizer.readFilter()
|
|
||||||
expect(token).to.have.property('name', 'plus')
|
|
||||||
expect(token!.args).to.have.lengthOf(1)
|
|
||||||
|
|
||||||
const pa: PropertyAccessToken = token!.args[0] as any
|
|
||||||
expect(token!.args[0]).to.be.instanceOf(PropertyAccessToken)
|
|
||||||
expect((pa.variable as any).content).to.equal('arr')
|
|
||||||
expect(pa.props).to.have.lengthOf(1)
|
|
||||||
expect(pa.props[0]).to.be.instanceOf(NumberToken)
|
|
||||||
expect(pa.props[0].getText()).to.equal('0')
|
|
||||||
})
|
|
||||||
it('should read a filter with obj.foo argument', function () {
|
|
||||||
const tokenizer = new Tokenizer('| plus: obj.foo')
|
|
||||||
const token = tokenizer.readFilter()
|
|
||||||
expect(token).to.have.property('name', 'plus')
|
|
||||||
expect(token!.args).to.have.lengthOf(1)
|
|
||||||
|
|
||||||
const pa: PropertyAccessToken = token!.args[0] as any
|
|
||||||
expect(token!.args[0]).to.be.instanceOf(PropertyAccessToken)
|
|
||||||
expect((pa.variable as any).content).to.equal('obj')
|
|
||||||
expect(pa.props).to.have.lengthOf(1)
|
|
||||||
expect(pa.props[0]).to.be.instanceOf(IdentifierToken)
|
|
||||||
expect(pa.props[0].getText()).to.equal('foo')
|
|
||||||
})
|
|
||||||
it('should read a filter with obj["foo"] argument', function () {
|
|
||||||
const tokenizer = new Tokenizer('| plus: obj["good luck"]')
|
|
||||||
const token = tokenizer.readFilter()
|
|
||||||
expect(token).to.have.property('name', 'plus')
|
|
||||||
expect(token!.args).to.have.lengthOf(1)
|
|
||||||
|
|
||||||
const pa: PropertyAccessToken = token!.args[0] as any
|
|
||||||
expect(token!.args[0]).to.be.instanceOf(PropertyAccessToken)
|
|
||||||
expect(pa.getText()).to.equal('obj["good luck"]')
|
|
||||||
expect((pa.variable as any).content).to.equal('obj')
|
|
||||||
expect(pa.props[0].getText()).to.equal('"good luck"')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
describe('#readFilters()', () => {
|
|
||||||
it('should read simple filters', function () {
|
|
||||||
const tokenizer = new Tokenizer('| plus: 3 | capitalize')
|
|
||||||
const tokens = tokenizer.readFilters()
|
|
||||||
|
|
||||||
expect(tokens).to.have.lengthOf(2)
|
|
||||||
expect(tokens[0]).to.have.property('name', 'plus')
|
|
||||||
expect(tokens[0].args).to.have.lengthOf(1)
|
|
||||||
expect(tokens[0].args[0]).to.be.instanceOf(NumberToken)
|
|
||||||
expect((tokens[0].args[0] as any).getText()).to.equal('3')
|
|
||||||
|
|
||||||
expect(tokens[1]).to.have.property('name', 'capitalize')
|
|
||||||
expect(tokens[1].args).to.have.lengthOf(0)
|
|
||||||
})
|
|
||||||
it('should read filters', function () {
|
|
||||||
const tokenizer = new Tokenizer('| plus: a:3 | capitalize | append: foo[a.b["c d"]]')
|
|
||||||
const tokens = tokenizer.readFilters()
|
|
||||||
|
|
||||||
expect(tokens).to.have.lengthOf(3)
|
|
||||||
expect(tokens[0]).to.have.property('name', 'plus')
|
|
||||||
expect(tokens[0].args).to.have.lengthOf(1)
|
|
||||||
const [k, v]: [string, NumberToken] = tokens[0].args[0] as any
|
|
||||||
expect(k).to.equal('a')
|
|
||||||
expect(v).to.be.instanceOf(NumberToken)
|
|
||||||
expect(v.getText()).to.equal('3')
|
|
||||||
|
|
||||||
expect(tokens[1]).to.have.property('name', 'capitalize')
|
|
||||||
expect(tokens[1].args).to.have.lengthOf(0)
|
|
||||||
|
|
||||||
expect(tokens[2]).to.have.property('name', 'append')
|
|
||||||
expect(tokens[2].args).to.have.lengthOf(1)
|
|
||||||
expect(tokens[2].args[0]).to.be.instanceOf(PropertyAccessToken)
|
|
||||||
expect((tokens[2].args[0] as any).getText()).to.equal('foo[a.b["c d"]]')
|
|
||||||
expect((tokens[2].args[0] as any).props[0].getText()).to.equal('a.b["c d"]')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
describe('#readExpression()', () => {
|
|
||||||
it('should read expression `a `', () => {
|
|
||||||
const exp = [...new Tokenizer('a ').readExpressionTokens()]
|
|
||||||
|
|
||||||
expect(exp).to.have.lengthOf(1)
|
|
||||||
expect(exp[0]).to.be.instanceOf(PropertyAccessToken)
|
|
||||||
expect(exp[0].getText()).to.deep.equal('a')
|
|
||||||
})
|
|
||||||
it('should read expression `a[][b]`', () => {
|
|
||||||
const exp = [...new Tokenizer('a[][b]').readExpressionTokens()]
|
|
||||||
|
|
||||||
expect(exp).to.have.lengthOf(1)
|
|
||||||
const pa = exp[0] as PropertyAccessToken
|
|
||||||
expect(pa).to.be.instanceOf(PropertyAccessToken)
|
|
||||||
expect((pa.variable as any).content).to.deep.equal('a')
|
|
||||||
expect(pa.props).to.have.lengthOf(2)
|
|
||||||
|
|
||||||
const [p1, p2] = pa.props
|
|
||||||
expect(p1).to.be.instanceOf(IdentifierToken)
|
|
||||||
expect(p1.getText()).to.equal('')
|
|
||||||
expect(p2).to.be.instanceOf(PropertyAccessToken)
|
|
||||||
expect(p2.getText()).to.equal('b')
|
|
||||||
})
|
|
||||||
it('should read expression `a.`', () => {
|
|
||||||
const exp = [...new Tokenizer('a.').readExpressionTokens()]
|
|
||||||
|
|
||||||
expect(exp).to.have.lengthOf(1)
|
|
||||||
const pa = exp[0] as PropertyAccessToken
|
|
||||||
expect(pa).to.be.instanceOf(PropertyAccessToken)
|
|
||||||
expect((pa.variable as any).content).to.deep.equal('a')
|
|
||||||
expect(pa.props).to.have.lengthOf(0)
|
|
||||||
})
|
|
||||||
it('should read expression `a ==`', () => {
|
|
||||||
const exp = [...new Tokenizer('a ==').readExpressionTokens()]
|
|
||||||
|
|
||||||
expect(exp).to.have.lengthOf(2)
|
|
||||||
expect(exp[0]).to.be.instanceOf(PropertyAccessToken)
|
|
||||||
expect(exp[0].getText()).to.deep.equal('a')
|
|
||||||
expect(exp[1]).to.be.instanceOf(OperatorToken)
|
|
||||||
expect(exp[1].getText()).to.deep.equal('==')
|
|
||||||
})
|
|
||||||
it('should read expression `a==b`', () => {
|
|
||||||
const exp = new Tokenizer('a==b').readExpressionTokens()
|
|
||||||
const [a, equals, b] = exp
|
|
||||||
|
|
||||||
expect(a).to.be.instanceOf(PropertyAccessToken)
|
|
||||||
expect(a.getText()).to.deep.equal('a')
|
|
||||||
|
|
||||||
expect(equals).to.be.instanceOf(OperatorToken)
|
|
||||||
expect(equals.getText()).to.equal('==')
|
|
||||||
|
|
||||||
expect(b).to.be.instanceOf(PropertyAccessToken)
|
|
||||||
expect(b.getText()).to.deep.equal('b')
|
|
||||||
})
|
|
||||||
it('should read expression `^`', () => {
|
|
||||||
const exp = new Tokenizer('^').readExpressionTokens()
|
|
||||||
expect([...exp]).to.deep.equal([])
|
|
||||||
})
|
|
||||||
it('should read expression `a == b`', () => {
|
|
||||||
const exp = new Tokenizer('a == b').readExpressionTokens()
|
|
||||||
const [a, equals, b] = exp
|
|
||||||
|
|
||||||
expect(a).to.be.instanceOf(PropertyAccessToken)
|
|
||||||
expect(a.getText()).to.deep.equal('a')
|
|
||||||
|
|
||||||
expect(equals).to.be.instanceOf(OperatorToken)
|
|
||||||
expect(equals.getText()).to.equal('==')
|
|
||||||
|
|
||||||
expect(b).to.be.instanceOf(PropertyAccessToken)
|
|
||||||
expect(b.getText()).to.deep.equal('b')
|
|
||||||
})
|
|
||||||
it('should read expression `(1..3) contains 3`', () => {
|
|
||||||
const exp = new Tokenizer('(1..3) contains 3').readExpressionTokens()
|
|
||||||
const [range, contains, rhs] = exp
|
|
||||||
|
|
||||||
expect(range).to.be.instanceOf(RangeToken)
|
|
||||||
expect(range.getText()).to.deep.equal('(1..3)')
|
|
||||||
|
|
||||||
expect(contains).to.be.instanceOf(OperatorToken)
|
|
||||||
expect(contains.getText()).to.equal('contains')
|
|
||||||
|
|
||||||
expect(rhs).to.be.instanceOf(NumberToken)
|
|
||||||
expect(rhs.getText()).to.deep.equal('3')
|
|
||||||
})
|
|
||||||
it('should read expression `a[b] == c`', () => {
|
|
||||||
const exp = new Tokenizer('a[b] == c').readExpressionTokens()
|
|
||||||
const [lhs, contains, rhs] = exp
|
|
||||||
|
|
||||||
expect(lhs).to.be.instanceOf(PropertyAccessToken)
|
|
||||||
expect(lhs.getText()).to.deep.equal('a[b]')
|
|
||||||
|
|
||||||
expect(contains).to.be.instanceOf(OperatorToken)
|
|
||||||
expect(contains.getText()).to.equal('==')
|
|
||||||
|
|
||||||
expect(rhs).to.be.instanceOf(PropertyAccessToken)
|
|
||||||
expect(rhs.getText()).to.deep.equal('c')
|
|
||||||
})
|
|
||||||
it('should read expression `c[a["b"]] >= c`', () => {
|
|
||||||
const exp = new Tokenizer('c[a["b"]] >= c').readExpressionTokens()
|
|
||||||
const [lhs, op, rhs] = exp
|
|
||||||
|
|
||||||
expect(lhs).to.be.instanceOf(PropertyAccessToken)
|
|
||||||
expect(lhs.getText()).to.deep.equal('c[a["b"]]')
|
|
||||||
|
|
||||||
expect(op).to.be.instanceOf(OperatorToken)
|
|
||||||
expect(op.getText()).to.equal('>=')
|
|
||||||
|
|
||||||
expect(rhs).to.be.instanceOf(PropertyAccessToken)
|
|
||||||
expect(rhs.getText()).to.deep.equal('c')
|
|
||||||
})
|
|
||||||
it('should read expression `"][" == var`', () => {
|
|
||||||
const exp = new Tokenizer('"][" == var').readExpressionTokens()
|
|
||||||
const [lhs, equals, rhs] = exp
|
|
||||||
|
|
||||||
expect(lhs).to.be.instanceOf(QuotedToken)
|
|
||||||
expect(lhs.getText()).to.deep.equal('"]["')
|
|
||||||
|
|
||||||
expect(equals).to.be.instanceOf(OperatorToken)
|
|
||||||
expect(equals.getText()).to.equal('==')
|
|
||||||
|
|
||||||
expect(rhs).to.be.instanceOf(PropertyAccessToken)
|
|
||||||
expect(rhs.getText()).to.deep.equal('var')
|
|
||||||
})
|
|
||||||
it('should read expression `"\\\'" == "\\""`', () => {
|
|
||||||
const exp = new Tokenizer('"\\\'" == "\\""').readExpressionTokens()
|
|
||||||
const [lhs, equals, rhs] = exp
|
|
||||||
|
|
||||||
expect(lhs).to.be.instanceOf(QuotedToken)
|
|
||||||
expect(lhs.getText()).to.deep.equal('"\\\'"')
|
|
||||||
|
|
||||||
expect(equals).to.be.instanceOf(OperatorToken)
|
|
||||||
expect(equals.getText()).to.equal('==')
|
|
||||||
|
|
||||||
expect(rhs).to.be.instanceOf(QuotedToken)
|
|
||||||
expect(rhs.getText()).to.deep.equal('"\\""')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
describe('#readLiquidTagTokens', () => {
|
|
||||||
it('should read newline terminated tokens', () => {
|
|
||||||
const tokenizer = new Tokenizer('echo \'hello\'')
|
|
||||||
const tokens = tokenizer.readLiquidTagTokens()
|
|
||||||
expect(tokens.length).to.equal(1)
|
|
||||||
const tag = tokens[0]
|
|
||||||
expect(tag).instanceOf(LiquidTagToken)
|
|
||||||
expect(tag.name).to.equal('echo')
|
|
||||||
expect(tag.args).to.equal('\'hello\'')
|
|
||||||
})
|
|
||||||
it('should gracefully handle empty lines', () => {
|
|
||||||
const tokenizer = new Tokenizer(`
|
|
||||||
echo 'hello'
|
|
||||||
|
|
||||||
decrement foo
|
|
||||||
`)
|
|
||||||
const tokens = tokenizer.readLiquidTagTokens()
|
|
||||||
expect(tokens.length).to.equal(2)
|
|
||||||
})
|
|
||||||
it('should throw if line does not start with an identifier', () => {
|
|
||||||
const tokenizer = new Tokenizer('!')
|
|
||||||
expect(() => tokenizer.readLiquidTagTokens()).to.throw(/illegal liquid tag syntax/)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
describe('#read inline comment tags', () => {
|
|
||||||
it('should allow hash characters in tag names', () => {
|
|
||||||
const tokenizer = new Tokenizer('{% # some comment %}')
|
|
||||||
const tokens = tokenizer.readTopLevelTokens()
|
|
||||||
expect(tokens.length).to.equal(1)
|
|
||||||
const tag = tokens[0] as TagToken
|
|
||||||
expect(tag).instanceOf(TagToken)
|
|
||||||
expect(tag.name).to.equal('#')
|
|
||||||
expect(tag.args).to.equal('some comment')
|
|
||||||
})
|
|
||||||
it('should handle leading whitespace', () => {
|
|
||||||
const tokenizer = new Tokenizer('{%\n # some comment %}')
|
|
||||||
const tokens = tokenizer.readTopLevelTokens()
|
|
||||||
expect(tokens.length).to.equal(1)
|
|
||||||
const tag = tokens[0] as TagToken
|
|
||||||
expect(tag).instanceOf(TagToken)
|
|
||||||
expect(tag.name).to.equal('#')
|
|
||||||
expect(tag.args).to.equal('some comment')
|
|
||||||
})
|
|
||||||
it('should handle no trailing whitespace', () => {
|
|
||||||
const tokenizer = new Tokenizer('{%\n #some comment %}')
|
|
||||||
const tokens = tokenizer.readTopLevelTokens()
|
|
||||||
expect(tokens.length).to.equal(1)
|
|
||||||
const tag = tokens[0] as TagToken
|
|
||||||
expect(tag).instanceOf(TagToken)
|
|
||||||
expect(tag.name).to.equal('#')
|
|
||||||
expect(tag.args).to.equal('some comment')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
import { isTruthy, isFalsy } from '../../../src/render/boolean'
|
|
||||||
import { Context } from '../../../src/context/context'
|
|
||||||
import { expect } from 'chai'
|
|
||||||
|
|
||||||
describe('boolean Shopify', async function () {
|
|
||||||
describe('.isTruthy()', async function () {
|
|
||||||
const ctx = {
|
|
||||||
opts: {
|
|
||||||
jsTruthy: false
|
|
||||||
}
|
|
||||||
} as unknown as Context
|
|
||||||
//
|
|
||||||
// Spec: https://shopify.github.io/liquid/basics/truthy-and-falsy/
|
|
||||||
it('true is truthy', function () {
|
|
||||||
expect(isTruthy(true, ctx)).to.be.true
|
|
||||||
})
|
|
||||||
it('false is falsy', function () {
|
|
||||||
expect(isTruthy(false, ctx)).to.be.false
|
|
||||||
})
|
|
||||||
it('null is falsy', function () {
|
|
||||||
expect(isTruthy(null, ctx)).to.be.false
|
|
||||||
})
|
|
||||||
it('"foo" is truthy', function () {
|
|
||||||
expect(isTruthy('foo', ctx)).to.be.true
|
|
||||||
})
|
|
||||||
it('"" is truthy', function () {
|
|
||||||
expect(isTruthy('', ctx)).to.be.true
|
|
||||||
})
|
|
||||||
it('0 is truthy', function () {
|
|
||||||
expect(isTruthy(0, ctx)).to.be.true
|
|
||||||
})
|
|
||||||
it('1 is truthy', function () {
|
|
||||||
expect(isTruthy(1, ctx)).to.be.true
|
|
||||||
})
|
|
||||||
it('1.1 is truthy', function () {
|
|
||||||
expect(isTruthy(1.1, ctx)).to.be.true
|
|
||||||
})
|
|
||||||
it('[1] is truthy', function () {
|
|
||||||
expect(isTruthy([1], ctx)).to.be.true
|
|
||||||
})
|
|
||||||
it('[] is truthy', function () {
|
|
||||||
expect(isTruthy([], ctx)).to.be.true
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('boolean jsTruthy', async function () {
|
|
||||||
const ctx = {
|
|
||||||
opts: {
|
|
||||||
jsTruthy: true
|
|
||||||
}
|
|
||||||
} as unknown as Context
|
|
||||||
|
|
||||||
describe('.isFalsy()', async function () {
|
|
||||||
it('null is always falsy', function () {
|
|
||||||
expect(isFalsy(null, ctx)).to.be.true
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('.isTruthy()', async function () {
|
|
||||||
it('true is truthy', function () {
|
|
||||||
expect(isTruthy(true, ctx)).to.be.true
|
|
||||||
})
|
|
||||||
it('false is falsy', function () {
|
|
||||||
expect(isTruthy(false, ctx)).to.be.false
|
|
||||||
})
|
|
||||||
it('null is always falsy', function () {
|
|
||||||
expect(isTruthy(null, ctx)).to.be.false
|
|
||||||
})
|
|
||||||
it('null is always falsy', function () {
|
|
||||||
expect(isTruthy(null, ctx)).to.be.false
|
|
||||||
})
|
|
||||||
it('"foo" is truthy', function () {
|
|
||||||
expect(isTruthy('foo', ctx)).to.be.true
|
|
||||||
})
|
|
||||||
it('"" is falsy', function () {
|
|
||||||
expect(isTruthy('', ctx)).to.be.false
|
|
||||||
})
|
|
||||||
it('0 is falsy', function () {
|
|
||||||
expect(isTruthy(0, ctx)).to.be.false
|
|
||||||
})
|
|
||||||
it('1 is truthy', function () {
|
|
||||||
expect(isTruthy(1, ctx)).to.be.true
|
|
||||||
})
|
|
||||||
it('1.1 is truthy', function () {
|
|
||||||
expect(isTruthy(1.1, ctx)).to.be.true
|
|
||||||
})
|
|
||||||
it('[1] is truthy', function () {
|
|
||||||
expect(isTruthy([1], ctx)).to.be.true
|
|
||||||
})
|
|
||||||
it('[] is truthy', function () {
|
|
||||||
expect(isTruthy([], ctx)).to.be.true
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
import * as chai from 'chai'
|
|
||||||
import { Liquid } from '../../../src/liquid'
|
|
||||||
import { QuotedToken } from '../../../src/tokens/quoted-token'
|
|
||||||
import { toPromise } from '../../../src/util/async'
|
|
||||||
import * as sinonChai from 'sinon-chai'
|
|
||||||
import * as sinon from 'sinon'
|
|
||||||
import { Context } from '../../../src/context/context'
|
|
||||||
import { Value } from '../../../src/template/value'
|
|
||||||
|
|
||||||
chai.use(sinonChai)
|
|
||||||
|
|
||||||
const expect = chai.expect
|
|
||||||
|
|
||||||
describe('Value', function () {
|
|
||||||
const liquid = new Liquid()
|
|
||||||
|
|
||||||
describe('#constructor()', function () {
|
|
||||||
it('should parse filters in value content', function () {
|
|
||||||
const f = new Value('o | foo: a: "a"', liquid)
|
|
||||||
expect(f.filters[0].name).to.equal('foo')
|
|
||||||
expect(f.filters[0].args).to.have.lengthOf(1)
|
|
||||||
const [k, v] = f.filters[0].args[0] as any
|
|
||||||
expect(k).to.equal('a')
|
|
||||||
expect(v).to.be.instanceOf(QuotedToken)
|
|
||||||
expect((v as QuotedToken).getText()).to.equal('"a"')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('#value()', function () {
|
|
||||||
it('should call chained filters correctly', async function () {
|
|
||||||
const date = sinon.stub().returns('y')
|
|
||||||
const time = sinon.spy()
|
|
||||||
liquid.registerFilter('date', date)
|
|
||||||
liquid.registerFilter('time', time)
|
|
||||||
const tpl = new Value('foo.bar | date: "b" | time:2', liquid)
|
|
||||||
const scope = new Context({
|
|
||||||
foo: { bar: 'bar' }
|
|
||||||
})
|
|
||||||
await toPromise(tpl.value(scope, false))
|
|
||||||
expect(date).to.have.been.calledWith('bar', 'b')
|
|
||||||
expect(time).to.have.been.calledWith('y', 2)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
import * as chai from 'chai'
|
|
||||||
import * as sinonChai from 'sinon-chai'
|
|
||||||
import { PropertyAccessToken } from '../../../src/tokens/property-access-token'
|
|
||||||
import { QuotedToken } from '../../../src/tokens/quoted-token'
|
|
||||||
import { IdentifierToken } from '../../../src/tokens/identifier-token'
|
|
||||||
|
|
||||||
chai.use(sinonChai)
|
|
||||||
const expect = chai.expect
|
|
||||||
|
|
||||||
describe('PropertyAccessToken', function () {
|
|
||||||
describe('#propertyName', function () {
|
|
||||||
it('should return correct value for IdentifierToken', function () {
|
|
||||||
const token = new PropertyAccessToken(new IdentifierToken('foo', 0, 3), [], 3)
|
|
||||||
expect(token.propertyName).to.equal('foo')
|
|
||||||
})
|
|
||||||
it('should return correct value for QuotedToken', function () {
|
|
||||||
const token = new PropertyAccessToken(new QuotedToken('"foo bar"', 0, 9), [], 9)
|
|
||||||
expect(token.propertyName).to.equal('foo bar')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
Reference in New Issue
Block a user