diff --git a/src/path/expression.ts b/src/path/expression.ts index 7f2a499..d214fcb 100644 --- a/src/path/expression.ts +++ b/src/path/expression.ts @@ -118,6 +118,8 @@ export class PrefixExpression extends FilterExpression { } export class InfixExpression extends FilterExpression { + readonly logical: boolean; + constructor( readonly token: Token, readonly left: FilterExpression, @@ -125,15 +127,16 @@ export class InfixExpression extends FilterExpression { readonly right: FilterExpression, ) { super(token); + this.logical = operator === "&&" || operator === "||"; } public evaluate(context: FilterContext): boolean { let left = this.left.evaluate(context); - if (left instanceof JSONPathNodeList && left.nodes.length === 1) + if (!this.logical && left instanceof JSONPathNodeList && left.nodes.length === 1) left = left.nodes[0].value; let right = this.right.evaluate(context); - if (right instanceof JSONPathNodeList && right.nodes.length === 1) + if (!this.logical && right instanceof JSONPathNodeList && right.nodes.length === 1) right = right.nodes[0].value; if (this.operator === "&&") { @@ -148,7 +151,7 @@ export class InfixExpression extends FilterExpression { } public toString(): string { - if (this.operator === "&&" || this.operator === "||") { + if (this.logical) { return `(${this.left.toString()} ${ this.operator } ${this.right.toString()})`; diff --git a/tests/path/query.test.ts b/tests/path/query.test.ts new file mode 100644 index 0000000..8c8e62d --- /dev/null +++ b/tests/path/query.test.ts @@ -0,0 +1,10 @@ +import { query } from "../../src/path"; + +describe("JSONPath query", () => { + test("logical expression, existence tests", () => { + const path = "$[?@.a && @.b]"; + const data = [{"a": false, "b": false}]; + expect(query(path, data).values()).toStrictEqual([{"a": false, "b": false}]); + }); + } +); \ No newline at end of file