Comparing version 0.4.5 to 0.5.0
@@ -14,8 +14,9 @@ // **N3Store** objects store N3 triples by graph in memory. | ||
this._graphs = Object.create(null); | ||
// `_entities` maps entities such as `http://xmlns.com/foaf/0.1/name` to numbers. | ||
// This saves memory, since only the numbers have to be stored in `_graphs`. | ||
this._entities = Object.create(null); | ||
this._entities['><'] = 0; // Dummy entry, so the first actual key is non-zero | ||
this._entityCount = 0; | ||
// `_blankNodeIndex` is the index of the last created blank node that was automatically named | ||
// `_ids` maps entities such as `http://xmlns.com/foaf/0.1/name` to numbers, | ||
// saving memory by using only numbers as keys in `_graphs`. | ||
this._id = 0; | ||
this._ids = Object.create(null); | ||
this._ids['><'] = 0; // dummy entry, so the first actual key is non-zero | ||
this._entities = Object.create(null); // inverse of `_ids` | ||
// `_blankNodeIndex` is the index of the last automatically named blank node | ||
this._blankNodeIndex = 0; | ||
@@ -26,7 +27,9 @@ | ||
options = triples, triples = null; | ||
options = options || {}; | ||
// Add triples and prefixes if passed | ||
this._prefixes = Object.create(null); | ||
if (options && options.prefixes) | ||
if (options.prefixes) | ||
this.addPrefixes(options.prefixes); | ||
this.defaultGraph = options.defaultGraph || 'http://example.org/#defaultGraph'; | ||
if (triples) | ||
@@ -58,2 +61,3 @@ this.addTriples(triples); | ||
// ### `_addToIndex` adds a triple to a three-layered index. | ||
// Returns if the index has changed, if the entry did not already exist. | ||
_addToIndex: function (index0, key0, key1, key2) { | ||
@@ -63,4 +67,7 @@ // Create layers as necessary. | ||
var index2 = index1[key1] || (index1[key1] = {}); | ||
// Setting the key to _any_ value signalizes the presence of the triple. | ||
index2[key2] = null; | ||
// Setting the key to _any_ value signals the presence of the triple. | ||
var existed = key2 in index2; | ||
if (!existed) | ||
index2[key2] = null; | ||
return !existed; | ||
}, | ||
@@ -89,3 +96,5 @@ | ||
_findInIndex: function (index0, key0, key1, key2, name0, name1, name2, graph) { | ||
var results = [], entityKeys = Object.keys(this._entities), tmp, index1, index2; | ||
var results = [], tmp, index1, index2, varCount = !key0 + !key1 + !key2, | ||
// depending on the number of variables, keys or reverse index are faster | ||
entityKeys = varCount > 1 ? Object.keys(this._ids) : this._entities; | ||
@@ -149,2 +158,3 @@ // If a key is specified, use only that part of index 0. | ||
// ### `addTriple` adds a new N3 triple to the store. | ||
// Returns if the triple index has changed, if the triple did not already exist. | ||
addTriple: function (subject, predicate, object, graph) { | ||
@@ -157,3 +167,3 @@ // Shift arguments if a triple object is given instead of components | ||
// Find the graph that will contain the triple. | ||
graph = graph || ''; | ||
graph = graph || this.defaultGraph; | ||
var graphItem = this._graphs[graph]; | ||
@@ -171,8 +181,9 @@ // Create the graph if it doesn't exist yet. | ||
// which are then used as keys in the other indexes. | ||
var ids = this._ids; | ||
var entities = this._entities; | ||
subject = entities[subject] || (entities[subject] = ++this._entityCount); | ||
predicate = entities[predicate] || (entities[predicate] = ++this._entityCount); | ||
object = entities[object] || (entities[object] = ++this._entityCount); | ||
subject = ids[subject] || (ids[entities[++this._id] = subject] = this._id); | ||
predicate = ids[predicate] || (ids[entities[++this._id] = predicate] = this._id); | ||
object = ids[object] || (ids[entities[++this._id] = object] = this._id); | ||
this._addToIndex(graphItem.subjects, subject, predicate, object); | ||
var changed = this._addToIndex(graphItem.subjects, subject, predicate, object); | ||
this._addToIndex(graphItem.predicates, predicate, object, subject); | ||
@@ -183,2 +194,3 @@ this._addToIndex(graphItem.objects, object, subject, predicate); | ||
this._size = null; | ||
return changed; | ||
}, | ||
@@ -209,16 +221,16 @@ | ||
predicate = subject.predicate, subject = subject.subject; | ||
graph = graph || ''; | ||
graph = graph || this.defaultGraph; | ||
// Find internal identifiers for all components. | ||
var graphItem, entities = this._entities, graphs = this._graphs; | ||
if (!(subject = entities[subject])) return; | ||
if (!(predicate = entities[predicate])) return; | ||
if (!(object = entities[object])) return; | ||
if (!(graphItem = graphs[graph])) return; | ||
var graphItem, ids = this._ids, graphs = this._graphs; | ||
if (!(subject = ids[subject])) return false; | ||
if (!(predicate = ids[predicate])) return false; | ||
if (!(object = ids[object])) return false; | ||
if (!(graphItem = graphs[graph])) return false; | ||
// Verify that the triple exists. | ||
var subjects, predicates; | ||
if (!(subjects = graphItem.subjects[subject])) return; | ||
if (!(predicates = subjects[predicate])) return; | ||
if (!(object in predicates)) return; | ||
if (!(subjects = graphItem.subjects[subject])) return false; | ||
if (!(predicates = subjects[predicate])) return false; | ||
if (!(object in predicates)) return false; | ||
@@ -232,4 +244,5 @@ // Remove it from all indexes. | ||
// Remove the graph if it is empty. | ||
for (subject in graphItem.subjects) return; | ||
for (subject in graphItem.subjects) return true; | ||
delete graphs[graph]; | ||
return true; | ||
}, | ||
@@ -244,4 +257,3 @@ | ||
// ### `find` finds a set of triples matching a pattern, expanding prefixes as necessary. | ||
// Setting `subject`, `predicate`, or `object` to `null` means an _anything_ wildcard. | ||
// Setting `graph` to `null` means the default graph. | ||
// Setting `subject`, `predicate`, `object` or `graph` to a falsy value means an _anything_ wildcard. | ||
find: function (subject, predicate, object, graph) { | ||
@@ -258,40 +270,47 @@ var prefixes = this._prefixes; | ||
// ### `findByIRI` finds a set of triples matching a pattern. | ||
// Setting `subject`, `predicate`, or `object` to a falsy value means an _anything_ wildcard. | ||
// Setting `graph` to a falsy value means the default graph. | ||
// Setting `subject`, `predicate`, `object` or `graph` to a falsy value means an _anything_ wildcard. | ||
findByIRI: function (subject, predicate, object, graph) { | ||
graph = graph || ''; | ||
var graphItem = this._graphs[graph], entities = this._entities; | ||
var quads = [], graphs = {}, graphContents, | ||
ids = this._ids, subjectId, predicateId, objectId; | ||
// Either loop over all graphs, or over just one selected graph. | ||
if (!graph) | ||
graphs = this._graphs; | ||
else | ||
graphs[graph] = this._graphs[graph]; | ||
// If the specified graph contain no triples, there are no results. | ||
if (!graphItem) return []; | ||
for (var graphId in graphs) { | ||
// Only if the specified graph contains triples, there can be results | ||
if (graphContents = graphs[graphId]) { | ||
// Translate IRIs to internal index keys. | ||
// Optimization: if the entity doesn't exist, no triples with it exist. | ||
if (subject && !(subjectId = ids[subject])) return quads; | ||
if (predicate && !(predicateId = ids[predicate])) return quads; | ||
if (object && !(objectId = ids[object])) return quads; | ||
// Translate IRIs to internal index keys. | ||
// Optimization: if the entity doesn't exist, no triples with it exist. | ||
if (subject && !(subject = entities[subject])) return []; | ||
if (predicate && !(predicate = entities[predicate])) return []; | ||
if (object && !(object = entities[object])) return []; | ||
// Choose the optimal index, based on what fields are present | ||
if (subject) { | ||
if (object) | ||
// If subject and object are given, the object index will be the fastest. | ||
return this._findInIndex(graphItem.objects, object, subject, predicate, | ||
'object', 'subject', 'predicate', graph); | ||
else | ||
// If only subject and possibly predicate are given, the subject index will be the fastest. | ||
return this._findInIndex(graphItem.subjects, subject, predicate, null, | ||
'subject', 'predicate', 'object', graph); | ||
// Choose the optimal index, based on what fields are present | ||
if (subjectId) { | ||
if (objectId) | ||
// If subject and object are given, the object index will be the fastest. | ||
quads.push(this._findInIndex(graphContents.objects, objectId, subjectId, predicateId, | ||
'object', 'subject', 'predicate', graphId)); | ||
else | ||
// If only subject and possibly predicate are given, the subject index will be the fastest. | ||
quads.push(this._findInIndex(graphContents.subjects, subjectId, predicateId, null, | ||
'subject', 'predicate', 'object', graphId)); | ||
} | ||
else if (predicateId) | ||
// If only predicate and possibly object are given, the predicate index will be the fastest. | ||
quads.push(this._findInIndex(graphContents.predicates, predicateId, objectId, null, | ||
'predicate', 'object', 'subject', graphId)); | ||
else if (objectId) | ||
// If only object is given, the object index will be the fastest. | ||
quads.push(this._findInIndex(graphContents.objects, objectId, null, null, | ||
'object', 'subject', 'predicate', graphId)); | ||
else | ||
// If nothing is given, iterate subjects and predicates first | ||
quads.push(this._findInIndex(graphContents.subjects, null, null, null, | ||
'subject', 'predicate', 'object', graphId)); | ||
} | ||
} | ||
else if (predicate) | ||
// If only predicate and possibly object are given, the predicate index will be the fastest. | ||
return this._findInIndex(graphItem.predicates, predicate, object, null, | ||
'predicate', 'object', 'subject', graph); | ||
else if (object) | ||
// If only object is given, the object index will be the fastest. | ||
return this._findInIndex(graphItem.objects, object, null, null, | ||
'object', 'subject', 'predicate', graph); | ||
else | ||
// If nothing is given, iterate subjects and predicates first | ||
return this._findInIndex(graphItem.subjects, null, null, null, | ||
'subject', 'predicate', 'object', graph); | ||
return quads.length === 1 ? quads[0] : quads.concat.apply([], quads); | ||
}, | ||
@@ -316,4 +335,4 @@ | ||
countByIRI: function (subject, predicate, object, graph) { | ||
graph = graph || ''; | ||
var graphItem = this._graphs[graph], entities = this._entities; | ||
graph = graph || this.defaultGraph; | ||
var graphItem = this._graphs[graph], ids = this._ids; | ||
@@ -325,5 +344,5 @@ // If the specified graph contain no triples, there are no results. | ||
// Optimization: if the entity doesn't exist, no triples with it exist. | ||
if (subject && !(subject = entities[subject])) return 0; | ||
if (predicate && !(predicate = entities[predicate])) return 0; | ||
if (object && !(object = entities[object])) return 0; | ||
if (subject && !(subject = ids[subject])) return 0; | ||
if (predicate && !(predicate = ids[predicate])) return 0; | ||
if (object && !(object = ids[object])) return 0; | ||
@@ -355,3 +374,3 @@ // Choose the optimal index, based on what fields are present | ||
name = suggestedName = '_:' + suggestedName, index = 1; | ||
while (this._entities[name]) | ||
while (this._ids[name]) | ||
name = suggestedName + index++; | ||
@@ -362,6 +381,6 @@ } | ||
do { name = '_:b' + this._blankNodeIndex++; } | ||
while (this._entities[name]); | ||
while (this._ids[name]); | ||
} | ||
// Add the blank node to the entities, avoiding the generation of duplicates | ||
this._entities[name] = ++this._entityCount; | ||
this._ids[name] = ++this._id; | ||
return name; | ||
@@ -368,0 +387,0 @@ }, |
@@ -97,2 +97,31 @@ // **N3Util** provides N3 utility functions | ||
}, | ||
// Creates a function that prepends the given IRI to a local name | ||
prefix: function (iri) { | ||
return N3Util.prefixes({ '': iri })(''); | ||
}, | ||
// Creates a function that allows registering and expanding prefixes | ||
prefixes: function (defaultPrefixes) { | ||
// Add all of the default prefixes | ||
var prefixes = Object.create(null); | ||
for (var prefix in defaultPrefixes) | ||
processPrefix(prefix, defaultPrefixes[prefix]); | ||
// Registers a new prefix (if an IRI was specified) | ||
// or retrieves a function that expands an existing prefix (if no IRI was specified) | ||
function processPrefix(prefix, iri) { | ||
// Create a new prefix if an IRI is specified or the prefix doesn't exist | ||
if (iri || !(prefix in prefixes)) { | ||
var cache = Object.create(null); | ||
iri = iri || ''; | ||
// Create a function that expands the prefix | ||
prefixes[prefix] = function (localName) { | ||
return cache[localName] || (cache[localName] = iri + localName); | ||
}; | ||
} | ||
return prefixes[prefix]; | ||
} | ||
return processPrefix; | ||
}, | ||
}; | ||
@@ -99,0 +128,0 @@ |
{ | ||
"name": "n3", | ||
"version": "0.4.5", | ||
"version": "0.5.0", | ||
"description": "Lightning fast, asynchronous, streaming Turtle / N3 / RDF library.", | ||
@@ -5,0 +5,0 @@ "author": "Ruben Verborgh <ruben.verborgh@gmail.com>", |
@@ -7,13 +7,14 @@ #!/usr/bin/env node | ||
var TEST; | ||
var dim = parseInt(process.argv[2], 10) || 256; | ||
var dimSquared = dim * dim; | ||
var dimCubed = dimSquared * dim; | ||
var prefix = 'http://example.org/#'; | ||
var TEST, dim, dimSquared, dimCubed, dimQuads, store; | ||
var store = new N3.Store(); | ||
/* Test triples */ | ||
dim = parseInt(process.argv[2], 10) || 256; | ||
dimSquared = dim * dim; | ||
dimCubed = dimSquared * dim; | ||
TEST = '- Adding ' + dimCubed + ' triples'; | ||
store = new N3.Store(); | ||
TEST = '- Adding ' + dimCubed + ' triples in the default graph'; | ||
console.time(TEST); | ||
var i, j, k; | ||
var i, j, k, l; | ||
for (i = 0; i < dim; i++) | ||
@@ -25,7 +26,28 @@ for (j = 0; j < dim; j++) | ||
console.log('* Memory usage: ' + Math.round(process.memoryUsage().rss / 1024 / 1024) + 'MB'); | ||
console.log('* Memory usage for triples: ' + Math.round(process.memoryUsage().rss / 1024 / 1024) + 'MB'); | ||
TEST = '- Finding all ' + dimCubed + ' triples ' + dimSquared * 3 + ' times'; | ||
TEST = '- Finding all ' + dimCubed + ' triples to the default graph ' + dimSquared * 1 + ' times (0 variables)'; | ||
console.time(TEST); | ||
for (i = 0; i < dim; i++) | ||
for (j = 0; j < dim; j++) | ||
for (k = 0; k < dim; k++) | ||
assert.equal(store.find(prefix + i, prefix + j, prefix + k).length, 1); | ||
console.timeEnd(TEST); | ||
TEST = '- Finding all ' + dimCubed + ' triples to the default graph ' + dimSquared * 2 + ' times (1 variable)'; | ||
console.time(TEST); | ||
for (i = 0; i < dim; i++) | ||
for (j = 0; j < dim; j++) | ||
assert.equal(store.find(prefix + i, prefix + j, null).length, dim); | ||
for (i = 0; i < dim; i++) | ||
for (j = 0; j < dim; j++) | ||
assert.equal(store.find(prefix + i, null, prefix + j).length, dim); | ||
for (i = 0; i < dim; i++) | ||
for (j = 0; j < dim; j++) | ||
assert.equal(store.find(null, prefix + i, prefix + j).length, dim); | ||
console.timeEnd(TEST); | ||
TEST = '- Finding all ' + dimCubed + ' triples to the default graph ' + dimSquared * 3 + ' times (2 variables)'; | ||
console.time(TEST); | ||
for (i = 0; i < dim; i++) | ||
assert.equal(store.find(prefix + i, null, null).length, dimSquared); | ||
@@ -37,1 +59,33 @@ for (j = 0; j < dim; j++) | ||
console.timeEnd(TEST); | ||
console.log(); | ||
/* Test quads */ | ||
dim /= 4, | ||
dimSquared = dim * dim; | ||
dimCubed = dimSquared * dim; | ||
dimQuads = dimCubed * dim; | ||
store = new N3.Store(); | ||
TEST = '- Adding ' + dimQuads + ' quads'; | ||
console.time(TEST); | ||
for (i = 0; i < dim; i++) | ||
for (j = 0; j < dim; j++) | ||
for (k = 0; k < dim; k++) | ||
for (l = 0; l < dim; l++) | ||
store.addTriple(prefix + i, prefix + j, prefix + k, prefix + l); | ||
console.timeEnd(TEST); | ||
console.log('* Memory usage for quads: ' + Math.round(process.memoryUsage().rss / 1024 / 1024) + 'MB'); | ||
TEST = '- Finding all ' + dimQuads + ' quads ' + dimCubed * 4 + ' times'; | ||
console.time(TEST); | ||
for (i = 0; i < dim; i++) | ||
assert.equal(store.find(prefix + i, null, null, null).length, dimCubed); | ||
for (j = 0; j < dim; j++) | ||
assert.equal(store.find(null, prefix + j, null, null).length, dimCubed); | ||
for (k = 0; k < dim; k++) | ||
assert.equal(store.find(null, null, prefix + k, null).length, dimCubed); | ||
for (l = 0; l < dim; l++) | ||
assert.equal(store.find(null, null, null, prefix + l).length, dimCubed); | ||
console.timeEnd(TEST); |
@@ -37,3 +37,3 @@ var N3Store = require('../N3').Store; | ||
store.addTriple('_:b0', '_:b1', '_:b2'); | ||
store.addTriple('_:b0', '_:b1', '_:b2').should.be.true; | ||
store.createBlankNode().should.eql('_:b3'); | ||
@@ -49,3 +49,3 @@ }); | ||
it('should be able to store triples with generated blank nodes', function () { | ||
store.addTriple(store.createBlankNode('x'), 'b', 'c'); | ||
store.addTriple(store.createBlankNode('x'), 'b', 'c').should.be.true; | ||
shouldIncludeAll(store.find(null, 'b'), ['_:x1', 'b', 'd']); | ||
@@ -55,2 +55,19 @@ }); | ||
describe('An N3Store without a configured default graph', function () { | ||
var store = new N3Store(); | ||
it('should have a dummy default graph', function () { | ||
store.defaultGraph.should.eql('http://example.org/#defaultGraph'); | ||
}); | ||
}); | ||
describe('An N3Store with a configured default graph', function () { | ||
var dg = 'http://example.org/#defaultGraph'; | ||
var store = new N3Store({ defaultGraph: dg }); | ||
it('should return that configured default graph', function () { | ||
store.defaultGraph.should.eql(dg); | ||
}); | ||
}); | ||
describe('An N3Store with initialized with 3 elements', function () { | ||
@@ -66,8 +83,48 @@ var store = new N3Store([ | ||
}); | ||
describe('adding a triple that already exists', function () { | ||
it('should return false', function () { | ||
store.addTriple('s1', 'p1', 'o1').should.be.false; | ||
}); | ||
it('should not increase the size', function () { | ||
store.size.should.eql(3); | ||
}); | ||
}); | ||
describe('adding a triple that did not exist yet', function () { | ||
it('should return true', function () { | ||
store.addTriple('s1', 'p1', 'o4').should.be.true; | ||
}); | ||
it('should increase the size', function () { | ||
store.size.should.eql(4); | ||
}); | ||
}); | ||
describe('removing an existing triple', function () { | ||
it('should return true', function () { | ||
store.removeTriple('s1', 'p1', 'o4').should.be.true; | ||
}); | ||
it('should decrease the size', function () { | ||
store.size.should.eql(3); | ||
}); | ||
}); | ||
describe('removing a non-existing triple', function () { | ||
it('should return false', function () { | ||
store.removeTriple('s1', 'p1', 'o5').should.be.false; | ||
}); | ||
it('should not decrease the size', function () { | ||
store.size.should.eql(3); | ||
}); | ||
}); | ||
}); | ||
describe('An N3Store with 5 elements', function () { | ||
var store = new N3Store(); | ||
store.addTriple('s1', 'p1', 'o1'); | ||
store.addTriple({ subject: 's1', predicate: 'p1', object: 'o2' }); | ||
var store = new N3Store({ defaultGraph: 'http://example.org/#defaultGraph' }); | ||
store.addTriple('s1', 'p1', 'o1').should.be.true; | ||
store.addTriple({ subject: 's1', predicate: 'p1', object: 'o2' }).should.be.true; | ||
store.addTriples([ | ||
@@ -77,3 +134,3 @@ { subject: 's1', predicate: 'p2', object: 'o2' }, | ||
]); | ||
store.addTriple('s1', 'p2', 'o3', 'c4'); | ||
store.addTriple('s1', 'p2', 'o3', 'c4').should.be.true; | ||
@@ -85,11 +142,18 @@ it('should have size 5', function () { | ||
describe('when searched without parameters', function () { | ||
it('should return all items in the default graph', | ||
it('should return all items', | ||
shouldIncludeAll(store.find(), | ||
['s1', 'p1', 'o1'], ['s1', 'p1', 'o2'], ['s1', 'p2', 'o2'], ['s2', 'p1', 'o1'])); | ||
['s1', 'p1', 'o1', store.defaultGraph], | ||
['s1', 'p1', 'o2', store.defaultGraph], | ||
['s1', 'p2', 'o2', store.defaultGraph], | ||
['s2', 'p1', 'o1', store.defaultGraph], | ||
['s1', 'p2', 'o3', 'c4'])); | ||
}); | ||
describe('when searched with an existing subject parameter', function () { | ||
it('should return all items with this subject in the default graph', | ||
it('should return all items with this subject in all graphs', | ||
shouldIncludeAll(store.find('s1', null, null), | ||
['s1', 'p1', 'o1'], ['s1', 'p1', 'o2'], ['s1', 'p2', 'o2'])); | ||
['s1', 'p1', 'o1', store.defaultGraph], | ||
['s1', 'p1', 'o2', store.defaultGraph], | ||
['s1', 'p2', 'o2', store.defaultGraph], | ||
['s1', 'p2', 'o3', 'c4'])); | ||
}); | ||
@@ -108,3 +172,5 @@ | ||
shouldIncludeAll(store.find(null, 'p1', null), | ||
['s1', 'p1', 'o1'], ['s1', 'p1', 'o2'], ['s2', 'p1', 'o1'])); | ||
['s1', 'p1', 'o1', store.defaultGraph], | ||
['s1', 'p1', 'o2', store.defaultGraph], | ||
['s2', 'p1', 'o1', store.defaultGraph])); | ||
}); | ||
@@ -118,3 +184,5 @@ | ||
it('should return all items with this object in the default graph', | ||
shouldIncludeAll(store.find(null, null, 'o1'), ['s1', 'p1', 'o1'], ['s2', 'p1', 'o1'])); | ||
shouldIncludeAll(store.find(null, null, 'o1'), | ||
['s1', 'p1', 'o1', store.defaultGraph], | ||
['s2', 'p1', 'o1', store.defaultGraph])); | ||
}); | ||
@@ -128,3 +196,5 @@ | ||
it('should return all items with this subject and predicate in the default graph', | ||
shouldIncludeAll(store.find('s1', 'p1', null), ['s1', 'p1', 'o1'], ['s1', 'p1', 'o2'])); | ||
shouldIncludeAll(store.find('s1', 'p1', null), | ||
['s1', 'p1', 'o1', store.defaultGraph], | ||
['s1', 'p1', 'o2', store.defaultGraph])); | ||
}); | ||
@@ -138,3 +208,5 @@ | ||
it('should return all items with this subject and object in the default graph', | ||
shouldIncludeAll(store.find('s1', null, 'o2'), ['s1', 'p1', 'o2'], ['s1', 'p2', 'o2'])); | ||
shouldIncludeAll(store.find('s1', null, 'o2'), | ||
['s1', 'p1', 'o2', store.defaultGraph], | ||
['s1', 'p2', 'o2', store.defaultGraph])); | ||
}); | ||
@@ -148,7 +220,9 @@ | ||
it('should return all items with this predicate and object in the default graph', | ||
shouldIncludeAll(store.find(null, 'p1', 'o1'), ['s1', 'p1', 'o1'], ['s2', 'p1', 'o1'])); | ||
shouldIncludeAll(store.find(null, 'p1', 'o1'), | ||
['s1', 'p1', 'o1', store.defaultGraph], | ||
['s2', 'p1', 'o1', store.defaultGraph])); | ||
}); | ||
describe('when searched with non-existing predicate and object parameters', function () { | ||
itShouldBeEmpty(store.find(null, 'p2', 'o3')); | ||
describe('when searched with non-existing predicate and object parameters in the default graph', function () { | ||
itShouldBeEmpty(store.find(null, 'p2', 'o3', store.defaultGraph)); | ||
}); | ||
@@ -158,3 +232,3 @@ | ||
it('should return all items with this subject, predicate, and object in the default graph', | ||
shouldIncludeAll(store.find('s1', 'p1', 'o1'), ['s1', 'p1', 'o1'])); | ||
shouldIncludeAll(store.find('s1', 'p1', 'o1'), ['s1', 'p1', 'o1', store.defaultGraph])); | ||
}); | ||
@@ -168,4 +242,7 @@ | ||
it('should return all items in the default graph', | ||
shouldIncludeAll(store.find(), | ||
['s1', 'p1', 'o1'], ['s1', 'p1', 'o2'], ['s1', 'p2', 'o2'], ['s2', 'p1', 'o1'])); | ||
shouldIncludeAll(store.find(null, null, null, store.defaultGraph), | ||
['s1', 'p1', 'o1', store.defaultGraph], | ||
['s1', 'p1', 'o2', store.defaultGraph], | ||
['s1', 'p2', 'o2', store.defaultGraph], | ||
['s2', 'p1', 'o1', store.defaultGraph])); | ||
}); | ||
@@ -297,3 +374,3 @@ | ||
describe('when trying to remove a triple with a non-existing subject', function () { | ||
before(function () { store.removeTriple('s0', 'p1', 'o1'); }); | ||
before(function () { store.removeTriple('s0', 'p1', 'o1').should.be.false; }); | ||
it('should still have size 5', function () { store.size.should.eql(5); }); | ||
@@ -303,3 +380,3 @@ }); | ||
describe('when trying to remove a triple with a non-existing predicate', function () { | ||
before(function () { store.removeTriple('s1', 'p0', 'o1'); }); | ||
before(function () { store.removeTriple('s1', 'p0', 'o1').should.be.false; }); | ||
it('should still have size 5', function () { store.size.should.eql(5); }); | ||
@@ -309,3 +386,3 @@ }); | ||
describe('when trying to remove a triple with a non-existing object', function () { | ||
before(function () { store.removeTriple('s1', 'p1', 'o0'); }); | ||
before(function () { store.removeTriple('s1', 'p1', 'o0').should.be.false; }); | ||
it('should still have size 5', function () { store.size.should.eql(5); }); | ||
@@ -315,3 +392,3 @@ }); | ||
describe('when trying to remove a triple for which no subjects exist', function () { | ||
before(function () { store.removeTriple('o1', 'p1', 'o1'); }); | ||
before(function () { store.removeTriple('o1', 'p1', 'o1').should.be.false; }); | ||
it('should still have size 5', function () { store.size.should.eql(5); }); | ||
@@ -321,3 +398,3 @@ }); | ||
describe('when trying to remove a triple for which no predicates exist', function () { | ||
before(function () { store.removeTriple('s1', 's1', 'o1'); }); | ||
before(function () { store.removeTriple('s1', 's1', 'o1').should.be.false; }); | ||
it('should still have size 5', function () { store.size.should.eql(5); }); | ||
@@ -327,3 +404,3 @@ }); | ||
describe('when trying to remove a triple for which no objects exist', function () { | ||
before(function () { store.removeTriple('s1', 'p1', 's1'); }); | ||
before(function () { store.removeTriple('s1', 'p1', 's1').should.be.false; }); | ||
it('should still have size 5', function () { store.size.should.eql(5); }); | ||
@@ -333,3 +410,3 @@ }); | ||
describe('when trying to remove a triple that does not exist', function () { | ||
before(function () { store.removeTriple('s1', 'p2', 'o1'); }); | ||
before(function () { store.removeTriple('s1', 'p2', 'o1').should.be.false; }); | ||
it('should still have size 5', function () { store.size.should.eql(5); }); | ||
@@ -339,3 +416,3 @@ }); | ||
describe('when trying to remove an incomplete triple', function () { | ||
before(function () { store.removeTriple('s1', null, null); }); | ||
before(function () { store.removeTriple('s1', null, null).should.be.false; }); | ||
it('should still have size 5', function () { store.size.should.eql(5); }); | ||
@@ -345,3 +422,3 @@ }); | ||
describe('when trying to remove a triple with a non-existing graph', function () { | ||
before(function () { store.removeTriple('s1', 'p1', 'o1', 'c0'); }); | ||
before(function () { store.removeTriple('s1', 'p1', 'o1', 'c0').should.be.false; }); | ||
it('should still have size 5', function () { store.size.should.eql(5); }); | ||
@@ -351,3 +428,3 @@ }); | ||
describe('when removing an existing triple', function () { | ||
before(function () { store.removeTriple('s1', 'p1', 'o1'); }); | ||
before(function () { store.removeTriple('s1', 'p1', 'o1').should.be.true; }); | ||
@@ -358,7 +435,10 @@ it('should have size 4', function () { store.size.should.eql(4); }); | ||
shouldIncludeAll(function () { return store.find(); }, | ||
['s1', 'p1', 'o2'], ['s1', 'p2', 'o2'], ['s2', 'p1', 'o1'])); | ||
['s1', 'p1', 'o2', store.defaultGraph], | ||
['s1', 'p2', 'o2', store.defaultGraph], | ||
['s2', 'p1', 'o1', store.defaultGraph], | ||
['s1', 'p2', 'o3', 'c4', store.defaultGraph])); | ||
}); | ||
describe('when removing an existing triple from a non-default graph', function () { | ||
before(function () { store.removeTriple('s1', 'p2', 'o3', 'c4'); }); | ||
before(function () { store.removeTriple('s1', 'p2', 'o3', 'c4').should.be.true; }); | ||
@@ -382,3 +462,3 @@ it('should have size 3', function () { store.size.should.eql(3); }); | ||
shouldIncludeAll(function () { return store.find(); }, | ||
['s1', 'p1', 'o2'])); | ||
['s1', 'p1', 'o2', store.defaultGraph])); | ||
}); | ||
@@ -388,4 +468,4 @@ | ||
before(function () { | ||
store.addTriple('a', 'b', 'c'); | ||
store.removeTriple('a', 'b', 'c'); | ||
store.addTriple('a', 'b', 'c').should.be.true; | ||
store.removeTriple('a', 'b', 'c').should.be.true; | ||
}); | ||
@@ -409,12 +489,21 @@ | ||
it('should return all triples with that subject', | ||
shouldIncludeAll(store.find('a:s1', null, null), | ||
['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1'], | ||
['http://foo.org/#s1', 'http://bar.org/p2', 'http://foo.org/#o1'])); | ||
shouldIncludeAll(store.find('a:s1', null, null), | ||
['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', store.defaultGraph], | ||
['http://foo.org/#s1', 'http://bar.org/p2', 'http://foo.org/#o1', store.defaultGraph], | ||
['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', 'http://graphs.org/#g1'])); | ||
}); | ||
describe('should allow to query subjects with prefixes', function () { | ||
it('should return all triples with that subject in the default graph', | ||
shouldIncludeAll(store.find('a:s1', null, null, store.defaultGraph), | ||
['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', store.defaultGraph], | ||
['http://foo.org/#s1', 'http://bar.org/p2', 'http://foo.org/#o1', store.defaultGraph])); | ||
}); | ||
describe('should allow to query predicates with prefixes', function () { | ||
it('should return all triples with that predicate', | ||
shouldIncludeAll(store.find(null, 'b:p1', null), | ||
['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1'], | ||
['http://foo.org/#s2', 'http://bar.org/p1', 'http://foo.org/#o2'])); | ||
['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', store.defaultGraph], | ||
['http://foo.org/#s2', 'http://bar.org/p1', 'http://foo.org/#o2', store.defaultGraph], | ||
['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', 'http://graphs.org/#g1'])); | ||
}); | ||
@@ -425,4 +514,5 @@ | ||
shouldIncludeAll(store.find(null, null, 'a:o1'), | ||
['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1'], | ||
['http://foo.org/#s1', 'http://bar.org/p2', 'http://foo.org/#o1'])); | ||
['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', store.defaultGraph], | ||
['http://foo.org/#s1', 'http://bar.org/p2', 'http://foo.org/#o1', store.defaultGraph], | ||
['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', 'http://graphs.org/#g1'])); | ||
}); | ||
@@ -433,3 +523,3 @@ | ||
shouldIncludeAll(store.find(null, null, null, 'http://graphs.org/#g1'), | ||
['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', 'http://graphs.org/#g1'])); | ||
['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', 'http://graphs.org/#g1', store.defaultGraph])); | ||
}); | ||
@@ -450,20 +540,44 @@ }); | ||
describe('should allow to query subjects with prefixes', function () { | ||
it('should return all triples with that subject in the default graph', | ||
shouldIncludeAll(store.find('a:s1', null, null, store.defaultGraph), | ||
['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', store.defaultGraph], | ||
['http://foo.org/#s1', 'http://bar.org/p2', 'http://foo.org/#o1', store.defaultGraph])); | ||
}); | ||
describe('should allow to query subjects with prefixes', function () { | ||
it('should return all triples with that subject', | ||
shouldIncludeAll(store.find('a:s1', null, null), | ||
['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1'], | ||
['http://foo.org/#s1', 'http://bar.org/p2', 'http://foo.org/#o1'])); | ||
shouldIncludeAll(store.find('a:s1', null, null), | ||
['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', store.defaultGraph], | ||
['http://foo.org/#s1', 'http://bar.org/p2', 'http://foo.org/#o1', store.defaultGraph], | ||
['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', 'http://graphs.org/#g1'])); | ||
}); | ||
describe('should allow to query predicates with prefixes', function () { | ||
it('should return all triples with that predicate in the default graph', | ||
shouldIncludeAll(store.find(null, 'b:p1', null, store.defaultGraph), | ||
['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', store.defaultGraph], | ||
['http://foo.org/#s2', 'http://bar.org/p1', 'http://foo.org/#o2', store.defaultGraph])); | ||
}); | ||
describe('should allow to query predicates with prefixes', function () { | ||
it('should return all triples with that predicate', | ||
shouldIncludeAll(store.find(null, 'b:p1', null), | ||
['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1'], | ||
['http://foo.org/#s2', 'http://bar.org/p1', 'http://foo.org/#o2'])); | ||
shouldIncludeAll(store.find(null, 'b:p1', null), | ||
['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', store.defaultGraph], | ||
['http://foo.org/#s2', 'http://bar.org/p1', 'http://foo.org/#o2', store.defaultGraph], | ||
['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', 'http://graphs.org/#g1'])); | ||
}); | ||
describe('should allow to query objects with prefixes', function () { | ||
it('should return all triples with that object in the default graph', | ||
shouldIncludeAll(store.find(null, null, 'a:o1', store.defaultGraph), | ||
['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', store.defaultGraph], | ||
['http://foo.org/#s1', 'http://bar.org/p2', 'http://foo.org/#o1', store.defaultGraph])); | ||
}); | ||
describe('should allow to query objects with prefixes', function () { | ||
it('should return all triples with that object', | ||
shouldIncludeAll(store.find(null, null, 'a:o1'), | ||
['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1'], | ||
['http://foo.org/#s1', 'http://bar.org/p2', 'http://foo.org/#o1'])); | ||
['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', store.defaultGraph], | ||
['http://foo.org/#s1', 'http://bar.org/p2', 'http://foo.org/#o1', store.defaultGraph], | ||
['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', 'http://graphs.org/#g1'])); | ||
}); | ||
@@ -489,4 +603,4 @@ | ||
shouldIncludeAll(store.find('http://foo.org/#s1', null, null), | ||
['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1'], | ||
['http://foo.org/#s1', 'http://bar.org/p2', 'http://foo.org/#o1'])); | ||
['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', store.defaultGraph], | ||
['http://foo.org/#s1', 'http://bar.org/p2', 'http://foo.org/#o1', store.defaultGraph])); | ||
}); | ||
@@ -497,3 +611,3 @@ }); | ||
var store = new N3Store({ prefixes: { http: 'http://www.w3.org/2006/http#' } }); | ||
store.addTriple('a', 'http://www.w3.org/2006/http#b', 'c'); | ||
store.addTriple('a', 'http://www.w3.org/2006/http#b', 'c').should.be.true; | ||
@@ -503,3 +617,3 @@ describe('should allow to query predicates with prefixes', function () { | ||
shouldIncludeAll(store.find(null, 'http:b', null), | ||
['a', 'http://www.w3.org/2006/http#b', 'c'])); | ||
['a', 'http://www.w3.org/2006/http#b', 'c', store.defaultGraph])); | ||
}); | ||
@@ -514,3 +628,3 @@ }); | ||
it('should be able to contain entities with JavaScript object property names', function () { | ||
store.addTriple('toString', 'valueOf', 'toLocaleString', 'hasOwnProperty'); | ||
store.addTriple('toString', 'valueOf', 'toLocaleString', 'hasOwnProperty').should.be.true; | ||
shouldIncludeAll(store.find(null, null, null, 'hasOwnProperty'), | ||
@@ -521,3 +635,3 @@ ['toString', 'valueOf', 'toLocaleString', 'hasOwnProperty'])(); | ||
it('should be able to contain entities named "null"', function () { | ||
store.addTriple('null', 'null', 'null', 'null'); | ||
store.addTriple('null', 'null', 'null', 'null').should.be.true; | ||
shouldIncludeAll(store.find(null, null, null, 'null'), ['null', 'null', 'null', 'null'])(); | ||
@@ -524,0 +638,0 @@ }); |
@@ -343,2 +343,68 @@ var N3Util = require('../N3').Util; | ||
}); | ||
describe('prefix', function () { | ||
var baz = N3Util.prefix('http://ex.org/baz#'); | ||
it('should return a function', function () { | ||
expect(baz).to.be.an.instanceof(Function); | ||
}); | ||
describe('the function', function () { | ||
it('should expand the prefix', function () { | ||
expect(baz('bar')).to.equal('http://ex.org/baz#bar'); | ||
}); | ||
}); | ||
}); | ||
describe('prefixes', function () { | ||
describe('called without arguments', function () { | ||
var prefixes = N3Util.prefixes(); | ||
it('should return a function', function () { | ||
expect(prefixes).to.be.an.instanceof(Function); | ||
}); | ||
describe('the function', function () { | ||
it('should not expand non-registered prefixes', function () { | ||
expect(prefixes('baz')('bar')).to.equal('bar'); | ||
}); | ||
it('should allow registering prefixes', function () { | ||
var p = prefixes('baz', 'http://ex.org/baz#'); | ||
expect(p).to.exist; | ||
expect(p).to.equal(prefixes('baz')); | ||
}); | ||
it('should expand the newly registered prefix', function () { | ||
expect(prefixes('baz')('bar')).to.equal('http://ex.org/baz#bar'); | ||
}); | ||
}); | ||
}); | ||
describe('called with a hash of prefixes', function () { | ||
var prefixes = N3Util.prefixes({ foo: 'http://ex.org/foo#', bar: 'http://ex.org/bar#' }); | ||
it('should return a function', function () { | ||
expect(prefixes).to.be.an.instanceof(Function); | ||
}); | ||
describe('the function', function () { | ||
it('should expand registered prefixes', function () { | ||
expect(prefixes('foo')('bar')).to.equal('http://ex.org/foo#bar'); | ||
expect(prefixes('bar')('bar')).to.equal('http://ex.org/bar#bar'); | ||
}); | ||
it('should not expand non-registered prefixes', function () { | ||
expect(prefixes('baz')('bar')).to.equal('bar'); | ||
}); | ||
it('should allow registering prefixes', function () { | ||
var p = prefixes('baz', 'http://ex.org/baz#'); | ||
expect(p).to.exist; | ||
expect(p).to.equal(prefixes('baz')); | ||
}); | ||
it('should expand the newly registered prefix', function () { | ||
expect(prefixes('baz')('bar')).to.equal('http://ex.org/baz#bar'); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 2 instances in 1 package
310684
36
5602
2
80