fix: comparison for empty/nil, fixes #321

This commit is contained in:
Jun Yang
2021-03-13 17:14:08 +08:00
parent aff9976042
commit 99d14e76d7
6 changed files with 36 additions and 11 deletions
+3 -1
View File
@@ -1,9 +1,11 @@
import { Drop } from './drop' import { Drop } from './drop'
import { Comparable } from './comparable' import { Comparable } from './comparable'
import { isObject, isString, isArray } from '../util/underscore' import { isObject, isString, isArray, toValue } from '../util/underscore'
export class EmptyDrop extends Drop implements Comparable { export class EmptyDrop extends Drop implements Comparable {
public equals (value: any) { public equals (value: any) {
if (value instanceof EmptyDrop) return false
value = toValue(value)
if (isString(value) || isArray(value)) return value.length === 0 if (isString(value) || isArray(value)) return value.length === 0
if (isObject(value)) return Object.keys(value).length === 0 if (isObject(value)) return Object.keys(value).length === 0
return false return false
+1 -2
View File
@@ -1,11 +1,10 @@
import { Drop } from './drop' import { Drop } from './drop'
import { Comparable } from './comparable' import { Comparable } from './comparable'
import { isNil, toValue } from '../util/underscore' import { isNil, toValue } from '../util/underscore'
import { BlankDrop } from '../drop/blank-drop'
export class NullDrop extends Drop implements Comparable { export class NullDrop extends Drop implements Comparable {
public equals (value: any) { public equals (value: any) {
return isNil(toValue(value)) || value instanceof BlankDrop return isNil(toValue(value))
} }
public gt () { public gt () {
return false return false
+3 -2
View File
@@ -2,11 +2,12 @@ import { NullDrop } from '../drop/null-drop'
import { EmptyDrop } from '../drop/empty-drop' import { EmptyDrop } from '../drop/empty-drop'
import { BlankDrop } from '../drop/blank-drop' import { BlankDrop } from '../drop/blank-drop'
const nil = new NullDrop()
export const literalValues = { export const literalValues = {
'true': true, 'true': true,
'false': false, 'false': false,
'nil': new NullDrop(), 'nil': nil,
'null': new NullDrop(), 'null': nil,
'empty': new EmptyDrop(), 'empty': new EmptyDrop(),
'blank': new BlankDrop() 'blank': new BlankDrop()
} }
+8
View File
@@ -87,4 +87,12 @@ describe('Issues', function () {
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).to.equal('default name')
}) })
it('#321 comparison for empty/nil', async () => {
const engine = new Liquid()
const html = await engine.parseAndRender(
'{% if empty == nil %}true{%else%}false{%endif%}' +
'{% if nil == empty %}true{%else%}false{%endif%}'
)
expect(html).to.equal('falsefalse')
})
}) })
+10
View File
@@ -79,4 +79,14 @@ describe('drop/empty-drop', function () {
const html = await liquid.parseAndRender(src) const html = await liquid.parseAndRender(src)
expect(html).to.equal('true') expect(html).to.equal('true')
}) })
it('empty != empty', async function () {
const src = '{%if empty == empty %}true{%else%}false{% endif %}'
const html = await liquid.parseAndRender(src)
expect(html).to.equal('false')
})
it('empty != nil', async function () {
const src = '{%if empty == nil %}true{%else%}false{% endif %}'
const html = await liquid.parseAndRender(src)
expect(html).to.equal('false')
})
}) })
+11 -6
View File
@@ -13,22 +13,27 @@ describe('drop/null-drop', function () {
const html = await liquid.parseAndRender('{{null}}') const html = await liquid.parseAndRender('{{null}}')
expect(html).to.equal('') expect(html).to.equal('')
}) })
it('undefined variable should equal to 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).to.equal('foo == nil')
}) })
it('nil equals blank', async function () { it('nil != blank', async function () {
const src = '{%if nil == blank %}nil == blank{%else%}nil != blank{% 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('nil == blank') expect(html).to.equal('neq')
}) })
it('0 should not equal to null', async function () { it('nil != empty', async function () {
const src = '{%if nil == empty %}eq{%else%}neq{% endif %}'
const html = await liquid.parseAndRender(src)
expect(html).to.equal('neq')
})
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).to.equal('0 != null')
}) })
it('nil should equal to 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).to.equal('nil == null')