Skip to content

Commit d233bf3

Browse files
alexdimaeamodio
authored andcommitted
- Add tests
- RHS of `in` expression is not a value, so don't deserialize it like a value - avoid unnecessary undefined check - use `hasOwnProperty` for object case - keys() should include the RHS of `in` expression
1 parent 2057d8a commit d233bf3

2 files changed

Lines changed: 21 additions & 4 deletions

File tree

src/vs/platform/contextkey/common/contextkey.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ STATIC_VALUES.set('isWindows', isWindows);
1717
STATIC_VALUES.set('isWeb', isWeb);
1818
STATIC_VALUES.set('isMacNative', isMacintosh && !isWeb);
1919

20+
const hasOwnProperty = Object.prototype.hasOwnProperty;
21+
2022
export const enum ContextKeyExprType {
2123
False = 0,
2224
True = 1,
@@ -138,7 +140,7 @@ export abstract class ContextKeyExpr {
138140

139141
if (serializedOne.indexOf(' in ') >= 0) {
140142
let pieces = serializedOne.split(' in ');
141-
return ContextKeyInExpr.create(pieces[0].trim(), this._deserializeValue(pieces[1], strict));
143+
return ContextKeyInExpr.create(pieces[0].trim(), pieces[1].trim());
142144
}
143145

144146
if (/^\!\s*/.test(serializedOne)) {
@@ -451,8 +453,8 @@ export class ContextKeyInExpr implements IContextKeyExpression {
451453
return (source.indexOf(item) >= 0);
452454
}
453455

454-
if (typeof item === 'string' && typeof source === 'object' && source !== undefined && source !== null) {
455-
return item in source;
456+
if (typeof item === 'string' && typeof source === 'object' && source !== null) {
457+
return hasOwnProperty.call(source, item);
456458
}
457459
return false;
458460
}
@@ -462,7 +464,7 @@ export class ContextKeyInExpr implements IContextKeyExpression {
462464
}
463465

464466
public keys(): string[] {
465-
return [this.key];
467+
return [this.key, this.valueKey];
466468
}
467469

468470
public map(mapFnc: IContextKeyExprMapper): ContextKeyInExpr {

src/vs/platform/contextkey/test/common/contextkey.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,4 +150,19 @@ suite('ContextKeyExpr', () => {
150150
t('a || b', 'c && d', 'a && c && d || b && c && d');
151151
t('a || b', 'c && d || e', 'a && e || b && e || a && c && d || b && c && d');
152152
});
153+
154+
test('ContextKeyInExpr', () => {
155+
const ainb = ContextKeyExpr.deserialize('a in b')!;
156+
assert.equal(ainb.evaluate(createContext({ 'a': 3, 'b': [3, 2, 1] })), true);
157+
assert.equal(ainb.evaluate(createContext({ 'a': 3, 'b': [1, 2, 3] })), true);
158+
assert.equal(ainb.evaluate(createContext({ 'a': 3, 'b': [1, 2] })), false);
159+
assert.equal(ainb.evaluate(createContext({ 'a': 3 })), false);
160+
assert.equal(ainb.evaluate(createContext({ 'a': 3, 'b': null })), false);
161+
assert.equal(ainb.evaluate(createContext({ 'a': 'x', 'b': ['x'] })), true);
162+
assert.equal(ainb.evaluate(createContext({ 'a': 'x', 'b': ['y'] })), false);
163+
assert.equal(ainb.evaluate(createContext({ 'a': 'x', 'b': {} })), false);
164+
assert.equal(ainb.evaluate(createContext({ 'a': 'x', 'b': { 'x': false } })), true);
165+
assert.equal(ainb.evaluate(createContext({ 'a': 'x', 'b': { 'x': true } })), true);
166+
assert.equal(ainb.evaluate(createContext({ 'a': 'prototype', 'b': {} })), false);
167+
});
153168
});

0 commit comments

Comments
 (0)