graph-ecs/tests/query-parser/where.test.js

107 lines
No EOL
4 KiB
JavaScript

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(new Identifier('max'))),
new Literal(500),
GreaterThan,
new ObjectPath(new Identifier('h'), new Property(new Identifier('current'))),
new Literal(250),
LesserThan,
new ObjectPath(new Identifier('a'), new Property(new Identifier('value'))),
new Literal(10),
Equal,
Or,
And,
new ObjectPath(new Identifier('a'), new Property(new Identifier('value'))),
new Literal(2),
LesserThanEqual,
Or,
]
assert.deepEqual(actual.values, expected)
})
})
})