diff --git a/src/drop/drop.ts b/src/drop/drop.ts index b4a2c98ad..f9ea60890 100644 --- a/src/drop/drop.ts +++ b/src/drop/drop.ts @@ -1,8 +1,4 @@ export abstract class Drop { - public valueOf (): any { - return undefined - } - public liquidMethodMissing (key: string | number): Promise | string | undefined { return undefined } diff --git a/src/util/collection.ts b/src/util/collection.ts index 677095e21..b43b7ad36 100644 --- a/src/util/collection.ts +++ b/src/util/collection.ts @@ -1,6 +1,7 @@ -import { isNil, isString, isObject, isArray, isIterable } from './underscore' +import { isNil, isString, isObject, isArray, isIterable, toValue } from './underscore' export function toEnumerable (val: any) { + val = toValue(val) if (isArray(val)) return val if (isString(val) && val.length > 0) return [val] if (isIterable(val)) return Array.from(val) diff --git a/src/util/underscore.ts b/src/util/underscore.ts index 15143f155..64107321b 100644 --- a/src/util/underscore.ts +++ b/src/util/underscore.ts @@ -39,7 +39,7 @@ export function stringify (value: any): string { } export function toValue (value: any): any { - return value instanceof Drop ? value.valueOf() : value + return (value instanceof Drop && isFunction(value.valueOf)) ? value.valueOf() : value } export function isNumber (value: any): value is number { diff --git a/test/integration/builtin/tags/for.ts b/test/integration/builtin/tags/for.ts index dc40c40a3..632d5c98e 100644 --- a/test/integration/builtin/tags/for.ts +++ b/test/integration/builtin/tags/for.ts @@ -324,8 +324,7 @@ describe('tags/for', function () { yield 'b' yield 'c' } - - public valueOf (): string { + toString () { return 'MockIterableDrop' } } diff --git a/test/integration/drop/drop.ts b/test/integration/drop/drop.ts index 768796c2f..b9a5bf78d 100644 --- a/test/integration/drop/drop.ts +++ b/test/integration/drop/drop.ts @@ -61,4 +61,15 @@ describe('drop/drop', function () { const html = await liquid.parseAndRender(`{{obj.foo}}`, { obj: new PromiseDrop() }) expect(html).to.equal('FOO') }) + it('should respect valueOf', async () => { + class CustomDrop extends Drop { + prop = 'not enumerable' + valueOf () { + return ['foo', 'bar'] + } + } + const tpl = '{{drop}}: {% for field in drop %}{{ field }};{% endfor %}' + const html = await liquid.parseAndRender(tpl, { drop: new CustomDrop() }) + expect(html).to.equal('foobar: foo;bar;') + }) }) diff --git a/test/unit/drop/drop.ts b/test/unit/drop/drop.ts deleted file mode 100644 index c31285082..000000000 --- a/test/unit/drop/drop.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { expect } from 'chai' -import { Drop } from '../../../src/drop/drop' - -describe('drop/drop', function () { - class CustomDrop extends Drop { } - - it('.valueOf() should return undefined by default', async function () { - expect(new CustomDrop().valueOf()).to.be.undefined - }) -})