Skip to content

Commit 1937aa1

Browse files
santialboharttle
andauthored
fix: Rely on equal for computing contains (#668)
* fix: rely on equal for computing contains This change allows contains to be computed using the toValue of the items in the array. Before this change if I had an array of "Drop" `contains` would not match against the value. * Apply suggestions from code review Co-authored-by: Jun Yang <[email protected]> --------- Co-authored-by: Jun Yang <[email protected]>
1 parent 4518a19 commit 1937aa1

File tree

2 files changed

+19
-4
lines changed

2 files changed

+19
-4
lines changed

src/render/expression.spec.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,20 @@ describe('Expression', function () {
147147
const ctx = new Context({ x: 'XXX', X: new TemplateDrop() })
148148
expect(await toPromise(create('x contains X').evaluate(ctx, false))).toBe(true)
149149
})
150+
it('should support Drops for "x contains "x"" when x is an array', async () => {
151+
class TemplateDrop extends Drop {
152+
valueOf () { return 'X' }
153+
}
154+
const ctx = new Context({ x: [new TemplateDrop()], X: 'X' })
155+
expect(await toPromise(create('x contains X').evaluate(ctx, false))).toBe(true)
156+
})
157+
it('should support Drops for "x contains "x"" when x is an array on both operands', async () => {
158+
class TemplateDrop extends Drop {
159+
valueOf () { return 'X' }
160+
}
161+
const ctx = new Context({ x: [new TemplateDrop()], X: new TemplateDrop() })
162+
expect(await toPromise(create('x contains X').evaluate(ctx, false))).toBe(true)
163+
})
150164
it('should support value and !=', async function () {
151165
const ctx = new Context({ empty: '' })
152166
expect(await toPromise(create('empty and empty != ""').evaluate(ctx, false))).toBe(false)

src/render/operator.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { isComparable } from '../drop/comparable'
22
import { Context } from '../context'
3-
import { isFunction, toValue } from '../util'
3+
import { toValue } from '../util'
44
import { isFalsy, isTruthy } from '../render/boolean'
5-
import { isArray } from '../util/underscore'
5+
import { isArray, isString } from '../util/underscore'
66

77
export type UnaryOperatorHandler = (operand: any, ctx: Context) => boolean;
88
export type BinaryOperatorHandler = (lhs: any, rhs: any, ctx: Context) => boolean;
@@ -34,8 +34,9 @@ export const defaultOperators: Operators = {
3434
},
3535
'contains': (l: any, r: any) => {
3636
l = toValue(l)
37-
r = toValue(r)
38-
return l && isFunction(l.indexOf) ? l.indexOf(r) > -1 : false
37+
if (isArray(l)) return l.some((i) => equal(i, r))
38+
if (isString(l)) return l.indexOf(toValue(r)) > -1
39+
return false
3940
},
4041
'not': (v: any, ctx: Context) => isFalsy(toValue(v), ctx),
4142
'and': (l: any, r: any, ctx: Context) => isTruthy(toValue(l), ctx) && isTruthy(toValue(r), ctx),

0 commit comments

Comments
 (0)