perf: introduce AST to avoid reparse

This commit is contained in:
harttle
2020-03-15 02:51:25 +08:00
committed by Jun Yang
parent 3b58f1c3f6
commit d2d6a38235
96 changed files with 1553 additions and 1168 deletions
@@ -6,11 +6,6 @@ use(chaiAsPromised)
describe('tags/decrement', function () {
const liquid = new Liquid()
it('should throw when variable expression illegal', function () {
const src = '{% decrement / %}{{var}}'
const ctx = {}
return expect(liquid.parseAndRender(src, ctx)).to.be.rejectedWith(/illegal/)
})
it('should decrement undefined variable', async function () {
const src = '{% decrement var %}{% decrement var %}{% decrement var %}'
+6
View File
@@ -46,6 +46,12 @@ describe('tags/for', function () {
.to.be.rejectedWith(/tag .* not closed/)
})
it('should reject when for in not found', function () {
const src = '{%for c alpha%}{{c}}'
return expect(liquid.parseAndRender(src, scope))
.to.be.rejectedWith('illegal tag: {%for c alpha%}, line:1, col:1')
})
it('should reject when inner templates rejected', function () {
const src = '{%for c in alpha%}{%throwingTag%}{%endfor%}'
return expect(liquid.parseAndRender(src, scope))
+16
View File
@@ -83,6 +83,22 @@ describe('tags/include', function () {
const html = await liquid.renderFile('with.html')
return expect(html).to.equal('color:red, shape:rect')
})
it('should ignore if with value not specified', async function () {
mock({
'/with.html': '{% include "color" with, shape: "rect" %}',
'/color.html': 'color:{{color}}, shape:{{shape}}'
})
const html = await liquid.renderFile('with.html')
return expect(html).to.equal('color:, shape:rect')
})
it('should treat with as a valid key', async function () {
mock({
'/with.html': '{% include "color" with: "foo" %}',
'/color.html': 'with:{{with}}'
})
const html = await liquid.renderFile('with.html')
return expect(html).to.equal('with:foo')
})
it('should support include: with as Drop', async function () {
class ColorDrop extends Drop {
public valueOf (): string {
+13 -1
View File
@@ -1,6 +1,9 @@
import { Liquid } from '../../../../src/liquid'
import { expect } from 'chai'
import { expect, use } from 'chai'
import { mock, restore } from '../../../stub/mockfs'
import * as chaiAsPromised from 'chai-as-promised'
use(chaiAsPromised)
describe('tags/layout', function () {
let liquid: Liquid
@@ -29,6 +32,15 @@ describe('tags/layout', function () {
expect(e.message).to.match(/illegal argument ""/)
})
})
it('should throw when filename resolved to falsy', function () {
mock({
'/parent.html': '{%layout foo%}'
})
return liquid.renderFile('/parent.html').catch(function (e) {
expect(e.name).to.equal('RenderError')
expect(e.message).to.match(/illegal filename "foo":"undefined"/)
})
})
describe('anonymous block', function () {
it('should handle anonymous block', async function () {
mock({
+25 -1
View File
@@ -121,9 +121,33 @@ describe('tags/render', function () {
const html = await liquid.renderFile('index.html', { colors: ['red', 'green'] })
expect(html).to.equal('1: red\n2: green\n')
})
it('should support for <non-array> as', async function () {
mock({
'/index.html': '{% render "item" for "green" as color %}',
'/item.html': '{{forloop.index}}: {{color}}\n'
})
const html = await liquid.renderFile('index.html')
expect(html).to.equal('1: green\n')
})
it('should support for without as', async function () {
mock({
'/index.html': '{% render "item" for colors %}',
'/item.html': '{{forloop.index}}: {{color}}\n'
})
const html = await liquid.renderFile('index.html', { colors: ['red', 'green'] })
expect(html).to.equal('1: \n2: \n')
})
it('should support for...as with other parameters', async function () {
mock({
'/index.html': '{% render "item" for colors as color with ".\n" as tail, sep: ". "%}',
'/index.html': '{% render "item" for colors as color with ".\n" as tail sep: ". "%}',
'/item.html': '{{forloop.index}}{{sep}}{{color}}{{tail}}'
})
const html = await liquid.renderFile('index.html', { colors: ['red', 'green'] })
expect(html).to.equal('1. red.\n2. green.\n')
})
it('should support for...as with other parameters (comma separated)', async function () {
mock({
'/index.html': '{% render "item" for colors as color, with ".\n" as tail, sep: ". "%}',
'/item.html': '{{forloop.index}}{{sep}}{{color}}{{tail}}'
})
const html = await liquid.renderFile('index.html', { colors: ['red', 'green'] })
+10 -1
View File
@@ -1,5 +1,8 @@
import { Liquid } from '../../../../src/liquid'
import { expect } from 'chai'
import { expect, use } from 'chai'
import * as chaiAsPromised from 'chai-as-promised'
use(chaiAsPromised)
describe('tags/tablerow', function () {
const liquid = new Liquid()
@@ -50,6 +53,12 @@ describe('tags/tablerow', function () {
.to.be.rejectedWith(/tag .* not closed/)
})
it('should throw when x in y not found', function () {
const src = '{% tablerow i (1..3) %}{{ i }}'
return expect(liquid.parseAndRender(src))
.to.be.rejectedWith('illegal tag: {% tablerow i (1..3) %}, line:1, col:1')
})
it('should support tablerow with range', async function () {
const src = '{% tablerow i in (1..5) cols:2 %}{{ i }}{% endtablerow %}'
const dst =