import { _, query, StupidTupleSet, ANY } from './datalog.mjs';
const { module, test } = QUnit;
QUnit.assert.setEqual = function(actual, expected, message = "okay") {
expected = new StupidTupleSet(expected);
this.pushResult({
result: actual.equals(expected),
actual: [...actual],
expected: [...expected],
message: message
});
}
module('datalog', () => {
let db1 = new StupidTupleSet([
["sally", "age", 21],
["fred", "age", 42],
["ethel", "age", 42],
["fred", "likes", "pizza"],
["sally", "likes", "opera"],
["ethel", "likes", "sushi"]
]);
let db2 = new StupidTupleSet([
["ethel", "sex", "female"],
["fred", "sex", "male"],
["sally", "sex", "female"]
]);
test('basic query', assert => {
assert.setEqual(
query({find: [_.e], where: [[_.e, "age", 42]]}, db1),
[["fred"], ["ethel"]],
"implicit database"
);
assert.setEqual(
query({find: [_.e], use: [[_.db]], where: [[_.db, _.e, "age", 42]]}, db1),
[["fred"], ["ethel"]],
"explicit database"
);
assert.setEqual(
query({
find: [_.sex],
use: [[_.db1, _.db2], _.age],
where: [
[_.db1, _.e, "age", _.age],
[_.db2, _.e, "sex", _.sex]
]
}, db1, db2, 21),
[["female"]],
"multiple databases with variable"
);
assert.setEqual(
query({find: [_.e], where: [[_.e]]}, db2),
[["ethel"], ["fred"], ["sally"]],
"partial tuple match"
);
});
test('predicates', assert => {
assert.setEqual(
query({
find: [_.e],
where: [
[_.e, "age", _.age],
[['<', _.age, 30]]
]
}, db1),
[["sally"]],
"no variable"
);
assert.setEqual(
query({
find: [_.e],
use: [_.maxAge],
where: [
[_.e, "age", _.age],
[['<', _.age, _.maxAge]]
]
}, db1, ANY.VALUE),
[["sally"], ["fred"], ["ethel"]],
"ANY.VALUE variable"
);
assert.setEqual(
query({
find: [_.e],
use: [_.minAge, _.maxAge],
where: [
[_.e, "age", _.age],
[['>', _.age, _.minAge]],
[['<=', _.age, _.maxAge]]
]
}, db1, 30, 50),
[["fred"], ["ethel"]],
"multiple variable"
);
});
test.skip('aggregation', assert => {
let monsters = new StupidTupleSet([
["Cerberus", 3],
["Medusa", 1],
["Cyclops", 1],
["Chimera", 1]
]);
assert.setEqual(
query({
find: [['min', _.heads]],
where: [[_._, _.heads]]
}, monsters),
[[1]],
"min"
);
});
});