refactor: Tag class support in registerTag()

This commit is contained in:
Jun Yang
2022-11-27 14:04:01 +08:00
parent 1f6ce7c822
commit 92992689cd
145 changed files with 694 additions and 768 deletions
+16 -39
View File
@@ -1,81 +1,58 @@
import * as chai from 'chai'
import * as sinon from 'sinon'
import * as sinonChai from 'sinon-chai'
import { Context } from '../../../../src/context/context'
import { toPromise } from '../../../../src/util/async'
import { NumberToken } from '../../../../src/tokens/number-token'
import { QuotedToken } from '../../../../src/tokens/quoted-token'
import { IdentifierToken } from '../../../../src/tokens/identifier-token'
import { FilterMap } from '../../../../src/template/filter/filter-map'
import { Context } from '../../../../src/context'
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 () {
let ctx: Context
let filters: FilterMap
const ctx = new Context()
const liquid = {} as any
beforeEach(function () {
filters = new FilterMap(false, liquid)
ctx = new Context()
})
it('should create default filter if not registered', async function () {
const result = filters.create('foo', []) as any
expect(result.name).to.equal('foo')
})
it('should render input if filter not registered', async function () {
expect(await toPromise(filters.create('undefined', []).render('foo', ctx))).to.equal('foo')
it('should not change input if filter not registered', async function () {
const filter = new Filter('foo', undefined as any, [], liquid)
expect(await toPromise(filter.render('value', ctx))).to.equal('value')
})
it('should call filter impl with correct arguments', async function () {
const spy = sinon.spy()
filters.set('foo', spy)
const thirty = new NumberToken(new IdentifierToken('30', 0, 2), undefined)
await toPromise(filters.create('foo', [thirty]).render('foo', ctx))
const filter = new Filter('foo', spy, [thirty], liquid)
await toPromise(filter.render('foo', ctx))
expect(spy).to.have.been.calledWith('foo', 30)
})
it('should call filter impl with correct this', async function () {
const spy = sinon.spy()
filters.set('foo', spy)
const thirty = new NumberToken(new IdentifierToken('33', 0, 2), undefined)
await toPromise(filters.create('foo', [thirty]).render('foo', ctx))
await toPromise(new Filter('foo', spy, [thirty], liquid).render('foo', ctx))
expect(spy).to.have.been.calledOn(sinon.match.has('context', ctx))
expect(spy).to.have.been.calledOn(sinon.match.has('liquid', liquid))
})
it('should render a simple filter', async function () {
filters.set('upcase', x => x.toUpperCase())
expect(await toPromise(filters.create('upcase', []).render('foo', ctx))).to.equal('FOO')
expect(await toPromise(new Filter('upcase', (x: string) => x.toUpperCase(), [], liquid).render('foo', ctx))).to.equal('FOO')
})
it('should render filters with argument', async function () {
filters.set('add', (a, b) => a + b)
const two = new NumberToken(new IdentifierToken('2', 0, 1), undefined)
expect(await toPromise(filters.create('add', [two]).render(3, ctx))).to.equal(5)
expect(await toPromise(new Filter('add', (a: number, b: number) => a + b, [two], liquid).render(3, ctx))).to.equal(5)
})
it('should render filters with multiple arguments', async function () {
filters.set('add', (a, b, c) => a + b + c)
const two = new NumberToken(new IdentifierToken('2', 0, 1), undefined)
const c = new QuotedToken('"c"', 0, 3)
expect(await toPromise(filters.create('add', [two, c]).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))).to.equal('5c')
})
it('should pass Objects/Drops as it is', async function () {
filters.set('name', a => a.constructor.name)
class Foo {}
expect(await toPromise(filters.create('name', []).render(new Foo(), ctx))).to.equal('Foo')
})
it('should not throw when filter name illegal', function () {
expect(function () {
filters.create('/', [])
}).to.not.throw()
expect(await toPromise(new Filter('name', (a: any) => a.constructor.name, [], liquid).render(new Foo(), ctx))).to.equal('Foo')
})
it('should support key value pairs', async function () {
filters.set('add', (a, b) => b[0] + ':' + (a + b[1]))
const two = new NumberToken(new IdentifierToken('2', 0, 1), undefined)
expect(await toPromise(filters.create('add', [['num', two]]).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))).to.equal('num:5')
})
})
+1 -1
View File
@@ -1,6 +1,6 @@
import * as chai from 'chai'
import { toPromise } from '../../../src/util/async'
import { Hash } from '../../../src/template/tag/hash'
import { Hash } from '../../../src/template/hash'
import { Context } from '../../../src/context/context'
const expect = chai.expect
+1 -5
View File
@@ -4,16 +4,12 @@ import { Context } from '../../../src/context/context'
import { Output } from '../../../src/template/output'
import { OutputToken } from '../../../src/tokens/output-token'
import { defaultOptions } from '../../../src/liquid-options'
import { createTrie } from '../../../src/util/operator-trie'
import { defaultOperators } from '../../../src/types'
const expect = chai.expect
describe('Output', function () {
const emitter: any = { write: (html: string) => (emitter.html += html), html: '' }
const liquid = {
options: { operatorsTrie: createTrie(defaultOperators) }
} as any
const liquid = { options: {} } as any
beforeEach(() => { emitter.html = '' })
it('should stringify objects', async function () {
-16
View File
@@ -1,16 +0,0 @@
import { expect } from 'chai'
import { TagMap } from '../../../src/template/tag/tag-map'
describe('TagMap', function () {
it('should throw when not exist', function () {
const map = new TagMap()
expect(() => map.get('not-exist'))
.to.throw(/tag "not-exist" not found/)
})
it('should get previously set value', function () {
const map = new TagMap()
const impl = { render: () => 'foo' }
map.set('foo', impl)
expect(map.get('foo')).to.equal(impl)
})
})
-30
View File
@@ -1,30 +0,0 @@
import * as chai from 'chai'
import { Tag } from '../../../src/template/tag/tag'
import { Context } from '../../../src/context/context'
import * as sinon from 'sinon'
import * as sinonChai from 'sinon-chai'
import { TagToken } from '../../../src/tokens/tag-token'
import { toPromise } from '../../../src/util/async'
chai.use(sinonChai)
const expect = chai.expect
describe('Tag', function () {
const ctx = new Context()
const emitter: any = { write: (html: string) => (emitter.html += html), html: '' }
it('should call tag.render', async function () {
const spy = sinon.spy()
const token = {
content: 'foo',
args: '',
name: 'foo'
} as TagToken
await toPromise(new Tag(token, [], {
tags: {
get: () => ({ render: spy })
}
} as any).render(ctx, emitter))
expect(spy).to.have.been.called
})
})