import { describe, it } from 'node:test' import assert from '../assert.js' import { and, eq, expr, gt, gte, lt, lte, not, or, params, whereClause, xor } from '../../src/query-parser/where.js' import { And, Equal, Filter, GreaterThan, GreaterThanEqual, Identifier, LesserThan, LesserThanEqual, Literal, ObjectPath, Or, Property } from '../../src/query-parser/types.js' import { parse } from '../../src/parser.js' const l = x => new Literal(x) describe('where operators', () => { it('or', () => { assert.parseOk(or, 'OR', ([actual]) => { assert.strictEqual(actual.apply([true, true]), true) assert.strictEqual(actual.apply([false, true]), true) assert.strictEqual(actual.apply([true, false]), true) assert.strictEqual(actual.apply([false, false]), false) }) }) it('and', () => { assert.parseOk(and, 'AND', ([actual]) => { assert.strictEqual(actual.apply([true, true]), true) assert.strictEqual(actual.apply([false, true]), false) assert.strictEqual(actual.apply([true, false]), false) assert.strictEqual(actual.apply([false, false]), false) }) }) it('xor', () => { assert.parseOk(xor, 'XOR', ([actual]) => { assert.strictEqual(actual.apply([true, true]), false) assert.strictEqual(actual.apply([false, true]), true) assert.strictEqual(actual.apply([true, false]), true) assert.strictEqual(actual.apply([false, false]), false) }) }) it('not', () => { assert.parseOk(not, 'NOT', ([actual]) => { assert.strictEqual(actual.apply([true]), false) assert.strictEqual(actual.apply([false]), true) }) }) it('gt', () => { assert.parseOk(gt, '>', ([actual]) => { assert.strictEqual(actual.apply([1, 2]), false) assert.strictEqual(actual.apply([2, 1]), true) assert.strictEqual(actual.apply([1, 1]), false) }) }) it('gte', () => { assert.parseOk(gte, '>=', ([actual]) => { assert.strictEqual(actual.apply([1, 2]), false) assert.strictEqual(actual.apply([2, 1]), true) assert.strictEqual(actual.apply([1, 1]), true) }) }) it('lt', () => { assert.parseOk(lt, '<', ([actual]) => { assert.strictEqual(actual.apply([1, 2]), true) assert.strictEqual(actual.apply([2, 1]), false) assert.strictEqual(actual.apply([1, 1]), false) }) }) it('lte', () => { assert.parseOk(lte, '<=', ([actual]) => { assert.strictEqual(actual.apply([1, 2]), true) assert.strictEqual(actual.apply([2, 1]), false) assert.strictEqual(actual.apply([1, 1]), true) }) }) it('eq', () => { assert.parseOk(eq, '=', ([actual]) => { assert.strictEqual(actual.apply([1, 2]), false) assert.strictEqual(actual.apply([2, 1]), false) assert.strictEqual(actual.apply([1, 1]), true) }) }) }) describe('WHERE keyword', () => { it('handles complex filters', () => { assert.parseOk(whereClause, 'WHERE h.max > 500 AND (h.current < 250 OR a.value = 10) OR a.value <= 2', ([actual]) => { const expected = [ new ObjectPath(new Identifier('h'), new Property('max')), new Literal(500), GreaterThan, new ObjectPath(new Identifier('h'), new Property('current')), new Literal(250), LesserThan, new ObjectPath(new Identifier('a'), new Property('value')), Or, new Literal(10), Equal, And, new ObjectPath(new Identifier('a'), new Property('value')), Or, new Literal(2), LesserThanEqual ] assert.deepEqual(actual.values, expected) }) }) })