git » hoplite.git » master » tree

[master] / tests.mjs

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"
    );
  });
});