mirror of
https://github.com/harttle/liquidjs.git
synced 2026-09-18 05:50:43 -07:00
test: coverage to 100%
This commit is contained in:
@@ -16,13 +16,10 @@ export default {
|
||||
|
||||
while (!tokenizer.end()) {
|
||||
const value = tokenizer.readValue()
|
||||
if (value) {
|
||||
this.cases.push({
|
||||
val: value,
|
||||
templates: p
|
||||
})
|
||||
}
|
||||
|
||||
this.cases.push({
|
||||
val: value,
|
||||
templates: p
|
||||
})
|
||||
tokenizer.readTo(',')
|
||||
}
|
||||
})
|
||||
|
||||
+14
-19
@@ -1,4 +1,4 @@
|
||||
import { Value, Emitter, isTruthy, TagToken, TopLevelToken, Context, Template, TagImplOptions, ParseStream } from '../../types'
|
||||
import { Value, Emitter, isTruthy, TagToken, TopLevelToken, Context, Template, TagImplOptions } from '../../types'
|
||||
|
||||
export default {
|
||||
parse: function (tagToken: TagToken, remainTokens: TopLevelToken[]) {
|
||||
@@ -6,34 +6,29 @@ export default {
|
||||
this.elseTemplates = []
|
||||
|
||||
let p
|
||||
const stream: ParseStream = this.liquid.parser.parseStream(remainTokens)
|
||||
this.liquid.parser.parseStream(remainTokens)
|
||||
.on('start', () => this.branches.push({
|
||||
cond: new Value(tagToken.args, this.liquid),
|
||||
predicate: new Value(tagToken.args, this.liquid),
|
||||
templates: (p = [])
|
||||
}))
|
||||
.on('tag:elsif', (token: TagToken) => this.branches.push({
|
||||
predicate: new Value(token.args, this.liquid),
|
||||
templates: (p = [])
|
||||
}))
|
||||
.on('tag:elsif', (token: TagToken) => {
|
||||
this.branches.push({
|
||||
cond: new Value(token.args, this.liquid),
|
||||
templates: p = []
|
||||
})
|
||||
})
|
||||
.on('tag:else', () => (p = this.elseTemplates))
|
||||
.on('tag:endif', () => stream.stop())
|
||||
.on('tag:endif', function () { this.stop() })
|
||||
.on('template', (tpl: Template) => p.push(tpl))
|
||||
.on('end', () => {
|
||||
throw new Error(`tag ${tagToken.getText()} not closed`)
|
||||
})
|
||||
|
||||
stream.start()
|
||||
.on('end', () => { throw new Error(`tag ${tagToken.getText()} not closed`) })
|
||||
.start()
|
||||
},
|
||||
|
||||
render: function * (ctx: Context, emitter: Emitter) {
|
||||
const r = this.liquid.renderer
|
||||
|
||||
for (const branch of this.branches) {
|
||||
const cond = yield branch.cond.value(ctx, ctx.opts.lenientIf)
|
||||
if (isTruthy(cond, ctx)) {
|
||||
yield r.renderTemplates(branch.templates, ctx, emitter)
|
||||
for (const { predicate, templates } of this.branches) {
|
||||
const value = yield predicate.value(ctx, ctx.opts.lenientIf)
|
||||
if (isTruthy(value, ctx)) {
|
||||
yield r.renderTemplates(templates, ctx, emitter)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,10 @@ export default {
|
||||
const keyword = tokenizer.readIdentifier()
|
||||
if (keyword.content === 'with' || keyword.content === 'for') {
|
||||
tokenizer.skipBlank()
|
||||
// can be normal key/value pair, like "with: true"
|
||||
if (tokenizer.peek() !== ':') {
|
||||
const value = tokenizer.readValue()
|
||||
// can be normal key, like "with,"
|
||||
if (value) {
|
||||
const beforeAs = tokenizer.p
|
||||
const asStr = tokenizer.readIdentifier()
|
||||
@@ -30,10 +32,14 @@ export default {
|
||||
this[keyword.content] = { value, alias: alias && alias.content }
|
||||
tokenizer.skipBlank()
|
||||
if (tokenizer.peek() === ',') tokenizer.advance()
|
||||
// matched!
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* restore cursor if with/for not matched
|
||||
*/
|
||||
tokenizer.p = begin
|
||||
break
|
||||
}
|
||||
@@ -83,14 +89,11 @@ export function parseFilePath (tokenizer: Tokenizer, liquid: Liquid): ParsedFile
|
||||
const file = tokenizer.readValue()
|
||||
if (file === undefined) throw new TypeError(`illegal argument "${tokenizer.input}"`)
|
||||
if (file.getText() === 'none') return null
|
||||
// for filenames like "files/{{file}}", eval as liquid template
|
||||
if (TypeGuards.isQuotedToken(file)) {
|
||||
// for filenames like "files/{{file}}", eval as liquid template
|
||||
const tpls = liquid.parse(evalQuotedToken(file))
|
||||
// for filenames like "files/file.liquid", extract the string directly
|
||||
if (tpls.length === 1) {
|
||||
const first = tpls[0]
|
||||
if (TypeGuards.isHTMLToken(first)) return first.getText()
|
||||
}
|
||||
if (tpls.length === 1 && TypeGuards.isHTMLToken(tpls[0].token)) return tpls[0].token.getContent()
|
||||
return tpls
|
||||
}
|
||||
return file
|
||||
|
||||
+19
-29
@@ -1,45 +1,35 @@
|
||||
import { Value, TopLevelToken, Template, Emitter, isTruthy, isFalsy, ParseStream, Context, TagImplOptions, TagToken } from '../../types'
|
||||
import { Value, TopLevelToken, Template, Emitter, isTruthy, isFalsy, Context, TagImplOptions, TagToken } from '../../types'
|
||||
|
||||
export default {
|
||||
parse: function (tagToken: TagToken, remainTokens: TopLevelToken[]) {
|
||||
this.templates = []
|
||||
this.branches = []
|
||||
this.elseTemplates = []
|
||||
let p
|
||||
const stream: ParseStream = this.liquid.parser.parseStream(remainTokens)
|
||||
.on('start', () => {
|
||||
p = this.templates
|
||||
this.cond = new Value(tagToken.args, this.liquid)
|
||||
})
|
||||
.on('tag:elsif', (token: TagToken) => {
|
||||
this.branches.push({
|
||||
cond: new Value(token.args, this.liquid),
|
||||
templates: p = []
|
||||
})
|
||||
})
|
||||
this.liquid.parser.parseStream(remainTokens)
|
||||
.on('start', () => this.branches.push({
|
||||
predicate: new Value(tagToken.args, this.liquid),
|
||||
test: isFalsy,
|
||||
templates: (p = [])
|
||||
}))
|
||||
.on('tag:elsif', (token: TagToken) => this.branches.push({
|
||||
predicate: new Value(token.args, this.liquid),
|
||||
test: isTruthy,
|
||||
templates: (p = [])
|
||||
}))
|
||||
.on('tag:else', () => (p = this.elseTemplates))
|
||||
.on('tag:endunless', () => stream.stop())
|
||||
.on('tag:endunless', function () { this.stop() })
|
||||
.on('template', (tpl: Template) => p.push(tpl))
|
||||
.on('end', () => {
|
||||
throw new Error(`tag ${tagToken.getText()} not closed`)
|
||||
})
|
||||
|
||||
stream.start()
|
||||
.on('end', () => { throw new Error(`tag ${tagToken.getText()} not closed`) })
|
||||
.start()
|
||||
},
|
||||
|
||||
render: function * (ctx: Context, emitter: Emitter) {
|
||||
const r = this.liquid.renderer
|
||||
const cond = yield this.cond.value(ctx, ctx.opts.lenientIf)
|
||||
|
||||
if (isFalsy(cond, ctx)) {
|
||||
yield r.renderTemplates(this.templates, ctx, emitter)
|
||||
return
|
||||
}
|
||||
|
||||
for (const branch of this.branches) {
|
||||
const cond = yield branch.cond.value(ctx, ctx.opts.lenientIf)
|
||||
if (isTruthy(cond, ctx)) {
|
||||
yield r.renderTemplates(branch.templates, ctx, emitter)
|
||||
for (const { predicate, test, templates } of this.branches) {
|
||||
const value = yield predicate.value(ctx, ctx.opts.lenientIf)
|
||||
if (test(value, ctx)) {
|
||||
yield r.renderTemplates(templates, ctx, emitter)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,13 +15,13 @@ export class ParseStream<T extends Token = TopLevelToken> {
|
||||
this.tokens = tokens
|
||||
this.parseToken = parseToken
|
||||
}
|
||||
public on<T2 extends Template | T | undefined> (name: string, cb: (arg: T2) => void): ParseStream<T> {
|
||||
public on<T2 extends Template | T | undefined> (name: string, cb: (this: ParseStream, arg: T2) => void): ParseStream<T> {
|
||||
this.handlers[name] = cb
|
||||
return this
|
||||
}
|
||||
private trigger <T extends Token | Template> (event: string, arg?: T) {
|
||||
const h = this.handlers[event]
|
||||
return h ? (h(arg), true) : false
|
||||
return h ? (h.call(this, arg), true) : false
|
||||
}
|
||||
public start () {
|
||||
this.trigger('start')
|
||||
|
||||
Reference in New Issue
Block a user