UNPKG

skg

Version:
383 lines (376 loc) 18.9 kB
var assert = require('assert'); const { Graph, literal, label, serialize, deserialize } = require('../graph.js'); function assertContains(collection, triple) { const expected = Object.entries(triple).toString(); const actual = []; Array.from(collection).forEach((element) => { actual.push(Object.entries(triple).toString()); }); assert(actual.includes(expected), `expected ${ JSON.stringify(triple) }`); } describe('Graph', function() { describe('assert', function() { it('should assert triple', function() { const g = new Graph(); g.assert('s0', 'p0', 'o0'); const triples = Array.from(g.getTriples()); assert(triples.length === 1, 'expected 1 triple'); assertContains(g.getTriples(), { s: 's0', p: 'p0', o: 'o0' }); }); it('should assert multiple triples', function() { const g = new Graph(); g.assert('s0', 'p0', 'o0'); g.assert('s0', 'p0', 'o1'); g.assert('s0', 'p1', 'o0'); g.assert('s0', 'p1', 'o1'); g.assert('s1', 'p0', 'o0'); g.assert('s1', 'p0', 'o1'); g.assert('s1', 'p1', 'o0'); g.assert('s1', 'p1', 'o1'); assert(Array.from(g.getTriples()).length === 8, 'expected 8 triples'); assertContains(g.getTriples(), { s: 's0', p: 'p0', o: 'o0' }); assertContains(g.getTriples(), { s: 's0', p: 'p0', o: 'o1' }); assertContains(g.getTriples(), { s: 's0', p: 'p1', o: 'o0' }); assertContains(g.getTriples(), { s: 's0', p: 'p1', o: 'o1' }); assertContains(g.getTriples(), { s: 's1', p: 'p0', o: 'o0' }); assertContains(g.getTriples(), { s: 's1', p: 'p0', o: 'o1' }); assertContains(g.getTriples(), { s: 's1', p: 'p1', o: 'o0' }); assertContains(g.getTriples(), { s: 's1', p: 'p1', o: 'o1' }); }); it('should ignore duplicate asserts', function() { const g = new Graph(); assert(g.assert('s0', 'p0', 'o0')); assert(g.assert('s0', 'p0', 'o1')); assert(g.assert('s0', 'p1', 'o0')); assert(g.assert('s0', 'p1', 'o1')); assert(g.assert('s1', 'p0', 'o0')); assert(g.assert('s1', 'p0', 'o1')); assert(g.assert('s1', 'p1', 'o0')); assert(g.assert('s1', 'p1', 'o1')); assert(!g.assert('s0', 'p0', 'o0')); assert(!g.assert('s0', 'p0', 'o1')); assert(!g.assert('s0', 'p1', 'o0')); assert(!g.assert('s0', 'p1', 'o1')); assert(!g.assert('s1', 'p0', 'o0')); assert(!g.assert('s1', 'p0', 'o1')); assert(!g.assert('s1', 'p1', 'o0')); assert(!g.assert('s1', 'p1', 'o1')); assert(Array.from(g.getTriples()).length === 8, 'expected 8 triples'); }); }); describe('retract', function() { it('should retract triple', function() { const g = new Graph(); g.assert('s0', 'p0', 'o0'); g.retract('s0', 'p0', 'o0'); const triples = Array.from(g.getTriples()); assert(triples.length === 0, 'expected empty'); }); it('should retract multiple triples', function() { const g = new Graph(); g.assert('s0', 'p0', 'o0'); g.assert('s0', 'p0', 'o1'); g.assert('s0', 'p1', 'o0'); g.assert('s0', 'p1', 'o1'); g.assert('s1', 'p0', 'o0'); g.assert('s1', 'p0', 'o1'); g.assert('s1', 'p1', 'o0'); g.assert('s1', 'p1', 'o1'); g.retract('s0', 'p0', 'o0'); g.retract('s0', 'p1', 'o0'); g.retract('s1', 'p1', 'o0'); g.retract('s1', 'p1', 'o1'); g.assert('s0', 'p0', 'o0'); // re-assert g.assert('s1', 'p1', 'o0'); // re-assert assert(Array.from(g.getTriples()).length === 6, 'expected 6 triples'); assertContains(g.getTriples(), { s: 's0', p: 'p0', o: 'o0' }); assertContains(g.getTriples(), { s: 's0', p: 'p0', o: 'o1' }); assertContains(g.getTriples(), { s: 's0', p: 'p1', o: 'o1' }); assertContains(g.getTriples(), { s: 's1', p: 'p0', o: 'o0' }); assertContains(g.getTriples(), { s: 's1', p: 'p0', o: 'o1' }); assertContains(g.getTriples(), { s: 's1', p: 'p1', o: 'o0' }); }); it('should ignore duplicate retracts', function() { const g = new Graph(); assert(g.assert('s0', 'p0', 'o0')); assert(g.assert('s0', 'p0', 'o1')); assert(g.assert('s0', 'p1', 'o0')); assert(g.assert('s0', 'p1', 'o1')); assert(g.assert('s1', 'p0', 'o0')); assert(g.assert('s1', 'p0', 'o1')); assert(g.assert('s1', 'p1', 'o0')); assert(g.assert('s1', 'p1', 'o1')); assert(!g.assert('s0', 'p0', 'o0')); assert(!g.assert('s0', 'p0', 'o1')); assert(!g.assert('s0', 'p1', 'o0')); assert(!g.assert('s0', 'p1', 'o1')); assert(!g.assert('s1', 'p0', 'o0')); assert(!g.assert('s1', 'p0', 'o1')); assert(!g.assert('s1', 'p1', 'o0')); assert(!g.assert('s1', 'p1', 'o1')); assert(g.retract('s0', 'p0', 'o0')); assert(g.retract('s0', 'p1', 'o0')); assert(g.retract('s1', 'p1', 'o0')); assert(g.retract('s1', 'p1', 'o1')); assert(!g.retract('s0', 'p1', 'o0')); assert(!g.retract('s1', 'p1', 'o0')); assert(Array.from(g.getTriples()).length === 4, 'expected 4 triples'); }); }); describe('merge', function() { it('should merge', function() { const g = new Graph(); assert(g.assert('s0', 'p0', 'o0')); assert(g.assert('s1', 'p0', 'o0')); assert(g.assert('s1', 'p0', 'o1')); assert(g.assert('s1', 'p1', 'o1')); const d = new Graph(); assert(d.assert('s0', 'p0', 'o0')); assert(d.assert('s0', 'p0', 'o1')); assert(d.assert('s1', 'p0', 'o1')); g.merge(d); assert(Array.from(g.getTriples()).length === 5, 'expected 5 results'); assertContains(g.getTriples(), { s: 's0', p: 'p0', o: 'o0' }); assertContains(g.getTriples(), { s: 's0', p: 'p0', o: 'o1' }); assertContains(g.getTriples(), { s: 's1', p: 'p0', o: 'o0' }); assertContains(g.getTriples(), { s: 's1', p: 'p0', o: 'o1' }); assertContains(g.getTriples(), { s: 's1', p: 'p1', o: 'o1' }); }); }); describe('minus', function() { it('should minus', function() { const g = new Graph(); assert(g.assert('s0', 'p0', 'o0')); assert(g.assert('s1', 'p0', 'o0')); assert(g.assert('s1', 'p0', 'o1')); assert(g.assert('s1', 'p1', 'o1')); const d = new Graph(); assert(d.assert('s0', 'p0', 'o0')); assert(d.assert('s1', 'p0', 'o1')); assert(d.assert('s1', 'p1', 'o0')); g.minus(d); assert(Array.from(g.getTriples()).length === 2, 'expected 2 results'); assertContains(g.getTriples(), { s: 's1', p: 'p0', o: 'o0' }); assertContains(g.getTriples(), { s: 's1', p: 'p1', o: 'o1' }); }); }); describe('getBySubject', function() { it('should getBySubject', function() { const g = new Graph(); g.assert('s0', 'p0', 'o0'); g.assert('s0', 'p0', 'o1'); g.assert('s0', 'p1', 'o0'); g.assert('s0', 'p1', 'o1'); g.assert('s1', 'p0', 'o0'); g.assert('s1', 'p0', 'o1'); g.assert('s1', 'p1', 'o0'); g.assert('s1', 'p1', 'o1'); assert(Array.from(g.getBySubject('s1')).length === 4, 'expected 4 results'); assertContains(g.getTriples(), { s: 's1', p: 'p0', o: 'o0' }); assertContains(g.getTriples(), { s: 's1', p: 'p0', o: 'o1' }); assertContains(g.getTriples(), { s: 's1', p: 'p1', o: 'o0' }); assertContains(g.getTriples(), { s: 's1', p: 'p1', o: 'o1' }); }); }); describe('getByPredicate', function() { it('should getByPredicate', function() { const g = new Graph(); g.assert('s0', 'p0', 'o0'); g.assert('s0', 'p0', 'o1'); g.assert('s0', 'p1', 'o0'); g.assert('s0', 'p1', 'o1'); g.assert('s1', 'p0', 'o0'); g.assert('s1', 'p0', 'o1'); g.assert('s1', 'p1', 'o0'); g.assert('s1', 'p1', 'o1'); assert(Array.from(g.getByPredicate('p0')).length === 4, 'expected 4 results'); assertContains(g.getByPredicate('p0'), { s: 's1', p: 'p0', o: 'o0' }); assertContains(g.getByPredicate('p0'), { s: 's1', p: 'p0', o: 'o1' }); assertContains(g.getByPredicate('p0'), { s: 's0', p: 'p0', o: 'o0' }); assertContains(g.getByPredicate('p0'), { s: 's0', p: 'p0', o: 'o1' }); }); }); describe('getByObject', function() { it('should getByObject', function() { const g = new Graph(); g.assert('s0', 'p0', 'o0'); g.assert('s0', 'p0', 'o1'); g.assert('s0', 'p1', 'o0'); g.assert('s0', 'p1', 'o1'); g.assert('s1', 'p0', 'o0'); g.assert('s1', 'p0', 'o1'); g.assert('s1', 'p1', 'o0'); g.assert('s1', 'p1', 'o1'); assert(Array.from(g.getByObject('o0')).length === 4, 'expected 4 results'); assertContains(g.getByObject('o0'), { s: 's1', p: 'p0', o: 'o0' }); assertContains(g.getByObject('o0'), { s: 's1', p: 'p1', o: 'o0' }); assertContains(g.getByObject('o0'), { s: 's0', p: 'p0', o: 'o0' }); assertContains(g.getByObject('o0'), { s: 's0', p: 'p1', o: 'o0' }); }); it('should getByObject (literal)', function() { const g = new Graph(); g.assert('s0', 'p0', literal('o0', 'string')); g.assert('s0', 'p0', literal('o1', 'string')); g.assert('s0', 'p1', literal('o0', 'string')); g.assert('s0', 'p1', literal('o1', 'string')); g.assert('s1', 'p0', literal('o0', 'string')); g.assert('s1', 'p0', literal('o1', 'string')); g.assert('s1', 'p1', literal('o0', 'string')); g.assert('s1', 'p1', literal('o1', 'string')); assert(Array.from(g.getByObject(literal('o0', 'string'))).length === 4, 'expected 4 results'); assertContains(g.getByObject(literal('o0', 'string')), { s: 's1', p: 'p0', o: { value: 'o0', type: 'string' }}); assertContains(g.getByObject(literal('o0', 'string')), { s: 's1', p: 'p1', o: { value: 'o0', type: 'string' }}); assertContains(g.getByObject(literal('o0', 'string')), { s: 's0', p: 'p0', o: { value: 'o0', type: 'string' }}); assertContains(g.getByObject(literal('o0', 'string')), { s: 's0', p: 'p1', o: { value: 'o0', type: 'string' }}); }); }); describe('getBySubjectPredicate', function() { it('should getBySubjectPredicate', function() { const g = new Graph(); g.assert('s0', 'p0', 'o0'); g.assert('s0', 'p0', 'o1'); g.assert('s0', 'p1', 'o0'); g.assert('s0', 'p1', 'o1'); g.assert('s1', 'p0', 'o0'); g.assert('s1', 'p0', 'o1'); g.assert('s1', 'p1', 'o0'); g.assert('s1', 'p1', 'o1'); assert(Array.from(g.getBySubjectPredicate('s1', 'p1')).length === 2, 'expected 2 results'); assertContains(g.getBySubjectPredicate('s1', 'p1'), { s: 's1', p: 'p1', o: 'o0' }); assertContains(g.getBySubjectPredicate('s1', 'p1'), { s: 's1', p: 'p1', o: 'o1' }); }); }); describe('getByPredicateObject', function() { it('should getByPredicateObject', function() { const g = new Graph(); g.assert('s0', 'p0', 'o0'); g.assert('s0', 'p0', 'o1'); g.assert('s0', 'p1', 'o0'); g.assert('s0', 'p1', 'o1'); g.assert('s1', 'p0', 'o0'); g.assert('s1', 'p0', 'o1'); g.assert('s1', 'p1', 'o0'); g.assert('s1', 'p1', 'o1'); assert(Array.from(g.getByPredicateObject('p1', 'o0')).length === 2, 'expected 2 results'); assertContains(g.getByPredicateObject('p1', 'o0'), { s: 's0', p: 'p1', o: 'o0' }); assertContains(g.getByPredicateObject('p1', 'o0'), { s: 's1', p: 'p1', o: 'o0' }); }); }); describe('getByObjectSubject', function() { it('should getByObjectSubject', function() { const g = new Graph(); g.assert('s0', 'p0', 'o0'); g.assert('s0', 'p0', 'o1'); g.assert('s0', 'p1', 'o0'); g.assert('s0', 'p1', 'o1'); g.assert('s1', 'p0', 'o0'); g.assert('s1', 'p0', 'o1'); g.assert('s1', 'p1', 'o0'); g.assert('s1', 'p1', 'o1'); assert(Array.from(g.getByObjectSubject('o1', 's1')).length === 2, 'expected 2 results'); assertContains(g.getByObjectSubject('o1', 's1'), { s: 's1', p: 'p0', o: 'o1' }); assertContains(g.getByObjectSubject('o1', 's1'), { s: 's1', p: 'p1', o: 'o1' }); }); }); describe('count', function() { it('should keep count of number of distinct triples', function() { const g = new Graph(); assert(g.assert('s0', 'p0', 'o0')); assert(g.assert('s0', 'p0', 'o1')); assert(g.assert('s0', 'p1', 'o0')); assert(g.assert('s0', 'p1', 'o1')); assert(g.assert('s1', 'p0', 'o0')); assert(g.assert('s1', 'p0', 'o1')); assert(g.assert('s1', 'p1', 'o0')); assert(g.assert('s1', 'p1', 'o1')); assert(!g.assert('s0', 'p0', 'o0')); assert(!g.assert('s0', 'p0', 'o1')); assert(!g.assert('s0', 'p1', 'o0')); assert(!g.assert('s0', 'p1', 'o1')); assert(!g.assert('s1', 'p0', 'o0')); assert(!g.assert('s1', 'p0', 'o1')); assert(!g.assert('s1', 'p1', 'o0')); assert(!g.assert('s1', 'p1', 'o1')); assert(g.retract('s0', 'p0', 'o0')); assert(g.retract('s0', 'p1', 'o0')); assert(g.retract('s1', 'p1', 'o0')); assert(g.retract('s1', 'p1', 'o1')); assert(!g.retract('s0', 'p1', 'o0')); assert(!g.retract('s1', 'p1', 'o0')); assert(g.assert('s2', 'p1', 'o0')); assert(g.assert('s2', 'p1', 'o1')); assert(Array.from(g.getTriples()).length === g.count, 'expected count to equal getTriples length'); }); }); describe('label', function() { it('should assert rdfs label', function() { const g = new Graph(); g.assert('s0', 'p0', 'o0'); label(g, 's0', 'subject0'); label(g, 'p0', 'predicate0'); assert(Array.from(g.getByPredicate('rdfs:label')).length === 2, 'expected 2 results'); assertContains(g.getByPredicate('rdfs:label'), { s: 's0', p: 'rdfs:label', o: { value: 'subject0', type: 'string' }}); assertContains(g.getByPredicate('rdfs:label'), { s: 'p0', p: 'rdfs:label', o: { value: 'predicate0', type: 'string' }}); }); }); describe('iteration', function() { it('should support iteration', function() { const g = new Graph(); g.assert('s0', 'p0', 'o0'); g.assert('s0', 'p0', 'o1'); g.assert('s0', 'p1', 'o0'); g.assert('s0', 'p1', 'o1'); g.assert('s1', 'p0', 'o0'); g.assert('s1', 'p0', 'o1'); g.assert('s1', 'p1', 'o0'); g.assert('s1', 'p1', 'o1'); const result = []; for (const s of g.getSubjects()) { for (const p of s.getPredicates()) { for (const o of p.getObjects()) { result.push({ s: s, p: p, s: o }); } } } assertContains(result, { s: 's0', p: 'p0', o: 'o0' }); assertContains(result, { s: 's0', p: 'p0', o: 'o1' }); assertContains(result, { s: 's0', p: 'p1', o: 'o0' }); assertContains(result, { s: 's0', p: 'p1', o: 'o1' }); assertContains(result, { s: 's1', p: 'p0', o: 'o0' }); assertContains(result, { s: 's1', p: 'p0', o: 'o1' }); assertContains(result, { s: 's1', p: 'p1', o: 'o0' }); assertContains(result, { s: 's1', p: 'p1', o: 'o1' }); }); }); describe('serialization', function() { it('should support roundtrip serialization', function() { const g = new Graph(); g.assert('s0', 'p0', 'o0'); g.assert('s0', 'p0', 'o1'); g.assert('s0', 'p1', 'o0'); g.assert('s0', 'p1', 'o1'); g.assert('s1', 'p0', 'o0'); g.assert('s1', 'p0', 'o1'); g.assert('s1', 'p1', 'o0'); g.assert('s1', 'p1', 'o1'); const result = deserialize(JSON.parse(JSON.stringify(serialize(g)))); assertContains(result.getTriples(), { s: 's0', p: 'p0', o: 'o0' }); assertContains(result.getTriples(), { s: 's0', p: 'p0', o: 'o1' }); assertContains(result.getTriples(), { s: 's0', p: 'p1', o: 'o0' }); assertContains(result.getTriples(), { s: 's0', p: 'p1', o: 'o1' }); assertContains(result.getTriples(), { s: 's1', p: 'p0', o: 'o0' }); assertContains(result.getTriples(), { s: 's1', p: 'p0', o: 'o1' }); assertContains(result.getTriples(), { s: 's1', p: 'p1', o: 'o0' }); assertContains(result.getTriples(), { s: 's1', p: 'p1', o: 'o1' }); }); }); describe('toString', function() { it('should support toString', function() { const g = new Graph(); g.assert('s0', 'p0', 'o1'); g.assert('s1', 'p0', 'o1'); const s = g.toString(); assert('s0 p0 o1 .\ns1 p0 o1\n', s); }); }); });