n3 0.4.5 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.travis.yml CHANGED
@@ -1,10 +1,7 @@
1
1
  language: node_js
2
2
  node_js:
3
- - "0.10"
4
-
5
- branches:
6
- except:
7
- - browser
8
- - earl
3
+ - "4"
4
+ - "6"
5
+ - "node"
9
6
 
10
7
  sudo: false
package/lib/N3Store.js CHANGED
@@ -11,22 +11,25 @@ function N3Store(triples, options) {
11
11
  this._size = 0;
12
12
  // `_graphs` contains subject, predicate, and object indexes per graph.
13
13
  this._graphs = Object.create(null);
14
- // `_entities` maps entities such as `http://xmlns.com/foaf/0.1/name` to numbers.
15
- // This saves memory, since only the numbers have to be stored in `_graphs`.
16
- this._entities = Object.create(null);
17
- this._entities['><'] = 0; // Dummy entry, so the first actual key is non-zero
18
- this._entityCount = 0;
19
- // `_blankNodeIndex` is the index of the last created blank node that was automatically named
14
+ // `_ids` maps entities such as `http://xmlns.com/foaf/0.1/name` to numbers,
15
+ // saving memory by using only numbers as keys in `_graphs`.
16
+ this._id = 0;
17
+ this._ids = Object.create(null);
18
+ this._ids['><'] = 0; // dummy entry, so the first actual key is non-zero
19
+ this._entities = Object.create(null); // inverse of `_ids`
20
+ // `_blankNodeIndex` is the index of the last automatically named blank node
20
21
  this._blankNodeIndex = 0;
21
22
 
22
23
  // Shift parameters if `triples` is not given
23
24
  if (!options && triples && !triples[0])
24
25
  options = triples, triples = null;
26
+ options = options || {};
25
27
 
26
28
  // Add triples and prefixes if passed
27
29
  this._prefixes = Object.create(null);
28
- if (options && options.prefixes)
30
+ if (options.prefixes)
29
31
  this.addPrefixes(options.prefixes);
32
+ this.defaultGraph = options.defaultGraph || 'http://example.org/#defaultGraph';
30
33
  if (triples)
31
34
  this.addTriples(triples);
32
35
  }
@@ -53,12 +56,16 @@ N3Store.prototype = {
53
56
  // ## Private methods
54
57
 
55
58
  // ### `_addToIndex` adds a triple to a three-layered index.
59
+ // Returns if the index has changed, if the entry did not already exist.
56
60
  _addToIndex: function (index0, key0, key1, key2) {
57
61
  // Create layers as necessary.
58
62
  var index1 = index0[key0] || (index0[key0] = {});
59
63
  var index2 = index1[key1] || (index1[key1] = {});
60
- // Setting the key to _any_ value signalizes the presence of the triple.
61
- index2[key2] = null;
64
+ // Setting the key to _any_ value signals the presence of the triple.
65
+ var existed = key2 in index2;
66
+ if (!existed)
67
+ index2[key2] = null;
68
+ return !existed;
62
69
  },
63
70
 
64
71
  // ### `_removeFromIndex` removes a triple from a three-layered index.
@@ -82,7 +89,9 @@ N3Store.prototype = {
82
89
  // (for instance: _subject_, _predicate_, and _object_).
83
90
  // Finally, `graph` will be the graph of the created triples.
84
91
  _findInIndex: function (index0, key0, key1, key2, name0, name1, name2, graph) {
85
- var results = [], entityKeys = Object.keys(this._entities), tmp, index1, index2;
92
+ var results = [], tmp, index1, index2, varCount = !key0 + !key1 + !key2,
93
+ // depending on the number of variables, keys or reverse index are faster
94
+ entityKeys = varCount > 1 ? Object.keys(this._ids) : this._entities;
86
95
 
87
96
  // If a key is specified, use only that part of index 0.
88
97
  if (key0) (tmp = index0, index0 = {})[key0] = tmp[key0];
@@ -141,6 +150,7 @@ N3Store.prototype = {
141
150
  // ## Public methods
142
151
 
143
152
  // ### `addTriple` adds a new N3 triple to the store.
153
+ // Returns if the triple index has changed, if the triple did not already exist.
144
154
  addTriple: function (subject, predicate, object, graph) {
145
155
  // Shift arguments if a triple object is given instead of components
146
156
  if (!predicate)
@@ -148,7 +158,7 @@ N3Store.prototype = {
148
158
  predicate = subject.predicate, subject = subject.subject;
149
159
 
150
160
  // Find the graph that will contain the triple.
151
- graph = graph || '';
161
+ graph = graph || this.defaultGraph;
152
162
  var graphItem = this._graphs[graph];
153
163
  // Create the graph if it doesn't exist yet.
154
164
  if (!graphItem) {
@@ -161,17 +171,19 @@ N3Store.prototype = {
161
171
  // Since entities can often be long IRIs, we avoid storing them in every index.
162
172
  // Instead, we have a separate index that maps entities to numbers,
163
173
  // which are then used as keys in the other indexes.
174
+ var ids = this._ids;
164
175
  var entities = this._entities;
165
- subject = entities[subject] || (entities[subject] = ++this._entityCount);
166
- predicate = entities[predicate] || (entities[predicate] = ++this._entityCount);
167
- object = entities[object] || (entities[object] = ++this._entityCount);
176
+ subject = ids[subject] || (ids[entities[++this._id] = subject] = this._id);
177
+ predicate = ids[predicate] || (ids[entities[++this._id] = predicate] = this._id);
178
+ object = ids[object] || (ids[entities[++this._id] = object] = this._id);
168
179
 
169
- this._addToIndex(graphItem.subjects, subject, predicate, object);
180
+ var changed = this._addToIndex(graphItem.subjects, subject, predicate, object);
170
181
  this._addToIndex(graphItem.predicates, predicate, object, subject);
171
182
  this._addToIndex(graphItem.objects, object, subject, predicate);
172
183
 
173
184
  // The cached triple count is now invalid.
174
185
  this._size = null;
186
+ return changed;
175
187
  },
176
188
 
177
189
  // ### `addTriples` adds multiple N3 triples to the store.
@@ -197,20 +209,20 @@ N3Store.prototype = {
197
209
  if (!predicate)
198
210
  graph = subject.graph, object = subject.object,
199
211
  predicate = subject.predicate, subject = subject.subject;
200
- graph = graph || '';
212
+ graph = graph || this.defaultGraph;
201
213
 
202
214
  // Find internal identifiers for all components.
203
- var graphItem, entities = this._entities, graphs = this._graphs;
204
- if (!(subject = entities[subject])) return;
205
- if (!(predicate = entities[predicate])) return;
206
- if (!(object = entities[object])) return;
207
- if (!(graphItem = graphs[graph])) return;
215
+ var graphItem, ids = this._ids, graphs = this._graphs;
216
+ if (!(subject = ids[subject])) return false;
217
+ if (!(predicate = ids[predicate])) return false;
218
+ if (!(object = ids[object])) return false;
219
+ if (!(graphItem = graphs[graph])) return false;
208
220
 
209
221
  // Verify that the triple exists.
210
222
  var subjects, predicates;
211
- if (!(subjects = graphItem.subjects[subject])) return;
212
- if (!(predicates = subjects[predicate])) return;
213
- if (!(object in predicates)) return;
223
+ if (!(subjects = graphItem.subjects[subject])) return false;
224
+ if (!(predicates = subjects[predicate])) return false;
225
+ if (!(object in predicates)) return false;
214
226
 
215
227
  // Remove it from all indexes.
216
228
  this._removeFromIndex(graphItem.subjects, subject, predicate, object);
@@ -219,8 +231,9 @@ N3Store.prototype = {
219
231
  if (this._size !== null) this._size--;
220
232
 
221
233
  // Remove the graph if it is empty.
222
- for (subject in graphItem.subjects) return;
234
+ for (subject in graphItem.subjects) return true;
223
235
  delete graphs[graph];
236
+ return true;
224
237
  },
225
238
 
226
239
  // ### `removeTriples` removes multiple N3 triples from the store.
@@ -230,8 +243,7 @@ N3Store.prototype = {
230
243
  },
231
244
 
232
245
  // ### `find` finds a set of triples matching a pattern, expanding prefixes as necessary.
233
- // Setting `subject`, `predicate`, or `object` to `null` means an _anything_ wildcard.
234
- // Setting `graph` to `null` means the default graph.
246
+ // Setting `subject`, `predicate`, `object` or `graph` to a falsy value means an _anything_ wildcard.
235
247
  find: function (subject, predicate, object, graph) {
236
248
  var prefixes = this._prefixes;
237
249
  return this.findByIRI(
@@ -243,44 +255,51 @@ N3Store.prototype = {
243
255
  },
244
256
 
245
257
  // ### `findByIRI` finds a set of triples matching a pattern.
246
- // Setting `subject`, `predicate`, or `object` to a falsy value means an _anything_ wildcard.
247
- // Setting `graph` to a falsy value means the default graph.
258
+ // Setting `subject`, `predicate`, `object` or `graph` to a falsy value means an _anything_ wildcard.
248
259
  findByIRI: function (subject, predicate, object, graph) {
249
- graph = graph || '';
250
- var graphItem = this._graphs[graph], entities = this._entities;
251
-
252
- // If the specified graph contain no triples, there are no results.
253
- if (!graphItem) return [];
254
-
255
- // Translate IRIs to internal index keys.
256
- // Optimization: if the entity doesn't exist, no triples with it exist.
257
- if (subject && !(subject = entities[subject])) return [];
258
- if (predicate && !(predicate = entities[predicate])) return [];
259
- if (object && !(object = entities[object])) return [];
260
-
261
- // Choose the optimal index, based on what fields are present
262
- if (subject) {
263
- if (object)
264
- // If subject and object are given, the object index will be the fastest.
265
- return this._findInIndex(graphItem.objects, object, subject, predicate,
266
- 'object', 'subject', 'predicate', graph);
267
- else
268
- // If only subject and possibly predicate are given, the subject index will be the fastest.
269
- return this._findInIndex(graphItem.subjects, subject, predicate, null,
270
- 'subject', 'predicate', 'object', graph);
271
- }
272
- else if (predicate)
273
- // If only predicate and possibly object are given, the predicate index will be the fastest.
274
- return this._findInIndex(graphItem.predicates, predicate, object, null,
275
- 'predicate', 'object', 'subject', graph);
276
- else if (object)
277
- // If only object is given, the object index will be the fastest.
278
- return this._findInIndex(graphItem.objects, object, null, null,
279
- 'object', 'subject', 'predicate', graph);
260
+ var quads = [], graphs = {}, graphContents,
261
+ ids = this._ids, subjectId, predicateId, objectId;
262
+ // Either loop over all graphs, or over just one selected graph.
263
+ if (!graph)
264
+ graphs = this._graphs;
280
265
  else
281
- // If nothing is given, iterate subjects and predicates first
282
- return this._findInIndex(graphItem.subjects, null, null, null,
283
- 'subject', 'predicate', 'object', graph);
266
+ graphs[graph] = this._graphs[graph];
267
+
268
+ for (var graphId in graphs) {
269
+ // Only if the specified graph contains triples, there can be results
270
+ if (graphContents = graphs[graphId]) {
271
+ // Translate IRIs to internal index keys.
272
+ // Optimization: if the entity doesn't exist, no triples with it exist.
273
+ if (subject && !(subjectId = ids[subject])) return quads;
274
+ if (predicate && !(predicateId = ids[predicate])) return quads;
275
+ if (object && !(objectId = ids[object])) return quads;
276
+
277
+ // Choose the optimal index, based on what fields are present
278
+ if (subjectId) {
279
+ if (objectId)
280
+ // If subject and object are given, the object index will be the fastest.
281
+ quads.push(this._findInIndex(graphContents.objects, objectId, subjectId, predicateId,
282
+ 'object', 'subject', 'predicate', graphId));
283
+ else
284
+ // If only subject and possibly predicate are given, the subject index will be the fastest.
285
+ quads.push(this._findInIndex(graphContents.subjects, subjectId, predicateId, null,
286
+ 'subject', 'predicate', 'object', graphId));
287
+ }
288
+ else if (predicateId)
289
+ // If only predicate and possibly object are given, the predicate index will be the fastest.
290
+ quads.push(this._findInIndex(graphContents.predicates, predicateId, objectId, null,
291
+ 'predicate', 'object', 'subject', graphId));
292
+ else if (objectId)
293
+ // If only object is given, the object index will be the fastest.
294
+ quads.push(this._findInIndex(graphContents.objects, objectId, null, null,
295
+ 'object', 'subject', 'predicate', graphId));
296
+ else
297
+ // If nothing is given, iterate subjects and predicates first
298
+ quads.push(this._findInIndex(graphContents.subjects, null, null, null,
299
+ 'subject', 'predicate', 'object', graphId));
300
+ }
301
+ }
302
+ return quads.length === 1 ? quads[0] : quads.concat.apply([], quads);
284
303
  },
285
304
 
286
305
  // ### `count` returns the number of triples matching a pattern, expanding prefixes as necessary.
@@ -300,17 +319,17 @@ N3Store.prototype = {
300
319
  // Setting `subject`, `predicate`, or `object` to `null` means an _anything_ wildcard.
301
320
  // Setting `graph` to `null` means the default graph.
302
321
  countByIRI: function (subject, predicate, object, graph) {
303
- graph = graph || '';
304
- var graphItem = this._graphs[graph], entities = this._entities;
322
+ graph = graph || this.defaultGraph;
323
+ var graphItem = this._graphs[graph], ids = this._ids;
305
324
 
306
325
  // If the specified graph contain no triples, there are no results.
307
326
  if (!graphItem) return 0;
308
327
 
309
328
  // Translate IRIs to internal index keys.
310
329
  // Optimization: if the entity doesn't exist, no triples with it exist.
311
- if (subject && !(subject = entities[subject])) return 0;
312
- if (predicate && !(predicate = entities[predicate])) return 0;
313
- if (object && !(object = entities[object])) return 0;
330
+ if (subject && !(subject = ids[subject])) return 0;
331
+ if (predicate && !(predicate = ids[predicate])) return 0;
332
+ if (object && !(object = ids[object])) return 0;
314
333
 
315
334
  // Choose the optimal index, based on what fields are present
316
335
  if (subject) {
@@ -337,16 +356,16 @@ N3Store.prototype = {
337
356
  // Generate a name based on the suggested name
338
357
  if (suggestedName) {
339
358
  name = suggestedName = '_:' + suggestedName, index = 1;
340
- while (this._entities[name])
359
+ while (this._ids[name])
341
360
  name = suggestedName + index++;
342
361
  }
343
362
  // Generate a generic blank node name
344
363
  else {
345
364
  do { name = '_:b' + this._blankNodeIndex++; }
346
- while (this._entities[name]);
365
+ while (this._ids[name]);
347
366
  }
348
367
  // Add the blank node to the entities, avoiding the generation of duplicates
349
- this._entities[name] = ++this._entityCount;
368
+ this._ids[name] = ++this._id;
350
369
  return name;
351
370
  },
352
371
  };
package/lib/N3Util.js CHANGED
@@ -94,6 +94,35 @@ var N3Util = {
94
94
  (/^[a-z]+(-[a-z0-9]+)*$/i.test(modifier) ? '"@' + modifier.toLowerCase()
95
95
  : '"^^' + modifier);
96
96
  },
97
+
98
+ // Creates a function that prepends the given IRI to a local name
99
+ prefix: function (iri) {
100
+ return N3Util.prefixes({ '': iri })('');
101
+ },
102
+
103
+ // Creates a function that allows registering and expanding prefixes
104
+ prefixes: function (defaultPrefixes) {
105
+ // Add all of the default prefixes
106
+ var prefixes = Object.create(null);
107
+ for (var prefix in defaultPrefixes)
108
+ processPrefix(prefix, defaultPrefixes[prefix]);
109
+
110
+ // Registers a new prefix (if an IRI was specified)
111
+ // or retrieves a function that expands an existing prefix (if no IRI was specified)
112
+ function processPrefix(prefix, iri) {
113
+ // Create a new prefix if an IRI is specified or the prefix doesn't exist
114
+ if (iri || !(prefix in prefixes)) {
115
+ var cache = Object.create(null);
116
+ iri = iri || '';
117
+ // Create a function that expands the prefix
118
+ prefixes[prefix] = function (localName) {
119
+ return cache[localName] || (cache[localName] = iri + localName);
120
+ };
121
+ }
122
+ return prefixes[prefix];
123
+ }
124
+ return processPrefix;
125
+ },
97
126
  };
98
127
 
99
128
  // Add the N3Util functions to the given object or its prototype
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n3",
3
- "version": "0.4.5",
3
+ "version": "0.5.0",
4
4
  "description": "Lightning fast, asynchronous, streaming Turtle / N3 / RDF library.",
5
5
  "author": "Ruben Verborgh <ruben.verborgh@gmail.com>",
6
6
  "keywords": [
@@ -4,26 +4,48 @@ var assert = require('assert');
4
4
 
5
5
  console.log('N3Store performance test');
6
6
 
7
- var TEST;
8
- var dim = parseInt(process.argv[2], 10) || 256;
9
- var dimSquared = dim * dim;
10
- var dimCubed = dimSquared * dim;
11
7
  var prefix = 'http://example.org/#';
8
+ var TEST, dim, dimSquared, dimCubed, dimQuads, store;
12
9
 
13
- var store = new N3.Store();
10
+ /* Test triples */
11
+ dim = parseInt(process.argv[2], 10) || 256;
12
+ dimSquared = dim * dim;
13
+ dimCubed = dimSquared * dim;
14
14
 
15
- TEST = '- Adding ' + dimCubed + ' triples';
15
+ store = new N3.Store();
16
+ TEST = '- Adding ' + dimCubed + ' triples in the default graph';
16
17
  console.time(TEST);
17
- var i, j, k;
18
+ var i, j, k, l;
18
19
  for (i = 0; i < dim; i++)
19
20
  for (j = 0; j < dim; j++)
20
21
  for (k = 0; k < dim; k++)
21
22
  store.addTriple(prefix + i, prefix + j, prefix + k);
22
23
  console.timeEnd(TEST);
23
24
 
24
- console.log('* Memory usage: ' + Math.round(process.memoryUsage().rss / 1024 / 1024) + 'MB');
25
+ console.log('* Memory usage for triples: ' + Math.round(process.memoryUsage().rss / 1024 / 1024) + 'MB');
25
26
 
26
- TEST = '- Finding all ' + dimCubed + ' triples ' + dimSquared * 3 + ' times';
27
+ TEST = '- Finding all ' + dimCubed + ' triples to the default graph ' + dimSquared * 1 + ' times (0 variables)';
28
+ console.time(TEST);
29
+ for (i = 0; i < dim; i++)
30
+ for (j = 0; j < dim; j++)
31
+ for (k = 0; k < dim; k++)
32
+ assert.equal(store.find(prefix + i, prefix + j, prefix + k).length, 1);
33
+ console.timeEnd(TEST);
34
+
35
+ TEST = '- Finding all ' + dimCubed + ' triples to the default graph ' + dimSquared * 2 + ' times (1 variable)';
36
+ console.time(TEST);
37
+ for (i = 0; i < dim; i++)
38
+ for (j = 0; j < dim; j++)
39
+ assert.equal(store.find(prefix + i, prefix + j, null).length, dim);
40
+ for (i = 0; i < dim; i++)
41
+ for (j = 0; j < dim; j++)
42
+ assert.equal(store.find(prefix + i, null, prefix + j).length, dim);
43
+ for (i = 0; i < dim; i++)
44
+ for (j = 0; j < dim; j++)
45
+ assert.equal(store.find(null, prefix + i, prefix + j).length, dim);
46
+ console.timeEnd(TEST);
47
+
48
+ TEST = '- Finding all ' + dimCubed + ' triples to the default graph ' + dimSquared * 3 + ' times (2 variables)';
27
49
  console.time(TEST);
28
50
  for (i = 0; i < dim; i++)
29
51
  assert.equal(store.find(prefix + i, null, null).length, dimSquared);
@@ -32,3 +54,35 @@ for (j = 0; j < dim; j++)
32
54
  for (k = 0; k < dim; k++)
33
55
  assert.equal(store.find(null, null, prefix + k).length, dimSquared);
34
56
  console.timeEnd(TEST);
57
+
58
+ console.log();
59
+
60
+ /* Test quads */
61
+ dim /= 4,
62
+ dimSquared = dim * dim;
63
+ dimCubed = dimSquared * dim;
64
+ dimQuads = dimCubed * dim;
65
+
66
+ store = new N3.Store();
67
+ TEST = '- Adding ' + dimQuads + ' quads';
68
+ console.time(TEST);
69
+ for (i = 0; i < dim; i++)
70
+ for (j = 0; j < dim; j++)
71
+ for (k = 0; k < dim; k++)
72
+ for (l = 0; l < dim; l++)
73
+ store.addTriple(prefix + i, prefix + j, prefix + k, prefix + l);
74
+ console.timeEnd(TEST);
75
+
76
+ console.log('* Memory usage for quads: ' + Math.round(process.memoryUsage().rss / 1024 / 1024) + 'MB');
77
+
78
+ TEST = '- Finding all ' + dimQuads + ' quads ' + dimCubed * 4 + ' times';
79
+ console.time(TEST);
80
+ for (i = 0; i < dim; i++)
81
+ assert.equal(store.find(prefix + i, null, null, null).length, dimCubed);
82
+ for (j = 0; j < dim; j++)
83
+ assert.equal(store.find(null, prefix + j, null, null).length, dimCubed);
84
+ for (k = 0; k < dim; k++)
85
+ assert.equal(store.find(null, null, prefix + k, null).length, dimCubed);
86
+ for (l = 0; l < dim; l++)
87
+ assert.equal(store.find(null, null, null, prefix + l).length, dimCubed);
88
+ console.timeEnd(TEST);
@@ -0,0 +1,48 @@
1
+ Summary
2
+ =======
3
+
4
+ Distributed under both the W3C Test Suite License[1] and the W3C 3-clause BSD License[2]. To contribute to a W3C Test Suite, see the policies and contribution forms [3]
5
+
6
+ 1. http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
7
+ 2. http://www.w3.org/Consortium/Legal/2008/03-bsd-license
8
+ 3. http://www.w3.org/2004/10/27-testcases
9
+
10
+ DISCLAIMER
11
+
12
+ UNDER BOTH MUTUALLY EXCLUSIVE LICENSES, THIS DOCUMENT AND ALL DOCUMENTS, TESTS AND SOFTWARE THAT LINK THIS STATEMENT ARE PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, OR TITLE; THAT THE CONTENTS OF THE DOCUMENT ARE SUITABLE FOR ANY PURPOSE; NOR THAT THE IMPLEMENTATION OF SUCH CONTENTS WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
13
+ COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE DOCUMENT OR THE PERFORMANCE OR IMPLEMENTATION OF THE CONTENTS THEREOF.
14
+
15
+
16
+ W3C Test Suite License
17
+ ======================
18
+
19
+ This document, Test Suites and other documents that link to this statement are provided by the copyright holders under the following license: By using and/or copying this document, or the W3C document from which this statement is linked, you (the licensee) agree that you have read, understood, and will comply with the following terms and conditions:
20
+
21
+ Permission to copy, and distribute the contents of this document, or the W3C document from which this statement is linked, in any medium for any purpose and without fee or royalty is hereby granted, provided that you include the following on ALL copies of the document, or portions thereof, that you use:
22
+
23
+ A link or URL to the original W3C document.
24
+ The pre-existing copyright notice of the original author, or if it doesn't exist, a notice (hypertext is preferred, but a textual representation is permitted) of the form: "Copyright © [$date-of-document] World Wide Web Consortium, (Massachusetts Institute of Technology, European Research Consortium for Informatics and Mathematics, Keio University) and others. All Rights Reserved. http://www.w3.org/Consortium/Legal/2008/04-testsuite-copyright.html"
25
+ If it exists, the STATUS of the W3C document.
26
+ When space permits, inclusion of the full text of this NOTICE should be provided. We request that authorship attribution be provided in any software, documents, or other items or products that you create pursuant to the implementation of the contents of this document, or any portion thereof.
27
+
28
+ No right to create modifications or derivatives of W3C documents is granted pursuant to this license. However, if additional requirements (documented in the Copyright FAQ) are satisfied, the right to create modifications or derivatives is sometimes granted by the W3C to individuals complying with those requirements.
29
+
30
+ If a Test Suite distinguishes the test harness (or, framework for navigation) and the actual tests, permission is given to remove or alter the harness or navigation if the Test Suite in question allows to do so. The tests themselves shall NOT be changed in any way.
31
+
32
+ The name and trademarks of W3C and other copyright holders may NOT be used in advertising or publicity pertaining to this document or other documents that link to this statement without specific, written prior permission. Title to copyright in this document will at all times remain with copyright holders. Permission is given to use the trademarked string W3C within claims of performance concerning W3C Specifications or features described therein, and there only, if the test suite so authorizes.
33
+
34
+ THIS WORK IS PROVIDED BY W3C, MIT, ERCIM, KEIO UNIVERSITY, THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL W3C, MIT, ERCIM, KEIO UNIVERSITY, THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35
+
36
+
37
+ W3C 3-clause BSD License
38
+ ========================
39
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
40
+
41
+ Redistributions of works must retain the original copyright notice, this list of conditions and the following disclaimer.
42
+
43
+ Redistributions in binary form must reproduce the original copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
44
+
45
+ Neither the name of the W3C nor the names of its contributors may be used to endorse or promote products derived from this work without specific prior written permission.
46
+
47
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48
+
@@ -0,0 +1,117 @@
1
+ Summary
2
+ =======
3
+
4
+ Distributed under both the W3C Test Suite License[1] and the W3C 3-clause BSD
5
+ License[2]. To contribute to a W3C Test Suite, see the policies and contribution
6
+ forms [3]
7
+
8
+ 1. http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
9
+ 2. http://www.w3.org/Consortium/Legal/2008/03-bsd-license
10
+ 3. http://www.w3.org/2004/10/27-testcases
11
+
12
+ DISCLAIMER
13
+
14
+ UNDER BOTH MUTUALLY EXCLUSIVE LICENSES, THIS DOCUMENT AND ALL DOCUMENTS, TESTS
15
+ AND SOFTWARE THAT LINK THIS STATEMENT ARE PROVIDED "AS IS," AND COPYRIGHT
16
+ HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING,
17
+ BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
18
+ PURPOSE, NON-INFRINGEMENT, OR TITLE; THAT THE CONTENTS OF THE DOCUMENT ARE
19
+ SUITABLE FOR ANY PURPOSE; NOR THAT THE IMPLEMENTATION OF SUCH CONTENTS WILL NOT
20
+ INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
21
+ COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR
22
+ CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE DOCUMENT OR THE PERFORMANCE
23
+ OR IMPLEMENTATION OF THE CONTENTS THEREOF.
24
+
25
+
26
+ W3C Test Suite License
27
+ ======================
28
+
29
+ This document, Test Suites and other documents that link to this statement are
30
+ provided by the copyright holders under the following license: By using and/or
31
+ copying this document, or the W3C document from which this statement is linked,
32
+ you (the licensee) agree that you have read, understood, and will comply with
33
+ the following terms and conditions:
34
+
35
+ Permission to copy, and distribute the contents of this document, or the W3C
36
+ document from which this statement is linked, in any medium for any purpose and
37
+ without fee or royalty is hereby granted, provided that you include the
38
+ following on ALL copies of the document, or portions thereof, that you use:
39
+
40
+ 1 A link or URL to the original W3C document.
41
+
42
+ 2 The pre-existing copyright notice of the original author, or if it doesn't
43
+ exist, a notice (hypertext is preferred, but a textual representation is
44
+ permitted) of the form: "Copyright © [$date-of-document] World Wide Web
45
+ Consortium, (Massachusetts Institute of Technology, European Research
46
+ Consortium for Informatics and Mathematics, Keio University) and others. All
47
+ Rights
48
+ Reserved. http://www.w3.org/Consortium/Legal/2008/04-testsuite-copyright.html"
49
+
50
+ 3 If it exists, the STATUS of the W3C document.
51
+
52
+ 4 When space permits, inclusion of the full text of this NOTICE should be
53
+ provided. We request that authorship attribution be provided in any software,
54
+ documents, or other items or products that you create pursuant to the
55
+ implementation of the contents of this document, or any portion thereof.
56
+
57
+
58
+ No right to create modifications or derivatives of W3C documents is granted
59
+ pursuant to this license. However, if additional requirements (documented in the
60
+ Copyright FAQ) are satisfied, the right to create modifications or derivatives
61
+ is sometimes granted by the W3C to individuals complying with those
62
+ requirements.
63
+
64
+ If a Test Suite distinguishes the test harness (or, framework for navigation)
65
+ and the actual tests, permission is given to remove or alter the harness or
66
+ navigation if the Test Suite in question allows to do so. The tests themselves
67
+ shall NOT be changed in any way.
68
+
69
+ The name and trademarks of W3C and other copyright holders may NOT be used in
70
+ advertising or publicity pertaining to this document or other documents that
71
+ link to this statement without specific, written prior permission. Title to
72
+ copyright in this document will at all times remain with copyright
73
+ holders. Permission is given to use the trademarked string W3C within claims of
74
+ performance concerning W3C Specifications or features described therein, and
75
+ there only, if the test suite so authorizes.
76
+
77
+ THIS WORK IS PROVIDED BY W3C, MIT, ERCIM, KEIO UNIVERSITY, THE COPYRIGHT HOLDERS
78
+ AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
79
+ NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
80
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL W3C, MIT, ERCIM, KEIO
81
+ UNIVERSITY, THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
82
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
83
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
84
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
85
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
86
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
87
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88
+
89
+
90
+ W3C 3-clause BSD License
91
+ ========================
92
+
93
+ Redistribution and use in source and binary forms, with or without modification,
94
+ are permitted provided that the following conditions are met:
95
+
96
+ 1 Redistributions of works must retain the original copyright notice, this list
97
+ of conditions and the following disclaimer.
98
+
99
+ 2 Redistributions in binary form must reproduce the original copyright notice,
100
+ this list of conditions and the following disclaimer in the documentation
101
+ and/or other materials provided with the distribution.
102
+
103
+ 3 Neither the name of the W3C nor the names of its contributors may be used to
104
+ endorse or promote products derived from this work without specific prior
105
+ written permission.
106
+
107
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
108
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
109
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
110
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
111
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
112
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
113
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
114
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
115
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
116
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
117
+
@@ -34,7 +34,7 @@ describe('N3Store', function () {
34
34
  store.createBlankNode().should.eql('_:b0');
35
35
  store.createBlankNode().should.eql('_:b1');
36
36
 
37
- store.addTriple('_:b0', '_:b1', '_:b2');
37
+ store.addTriple('_:b0', '_:b1', '_:b2').should.be.true;
38
38
  store.createBlankNode().should.eql('_:b3');
39
39
  });
40
40
 
@@ -45,11 +45,28 @@ describe('N3Store', function () {
45
45
  });
46
46
 
47
47
  it('should be able to store triples with generated blank nodes', function () {
48
- store.addTriple(store.createBlankNode('x'), 'b', 'c');
48
+ store.addTriple(store.createBlankNode('x'), 'b', 'c').should.be.true;
49
49
  shouldIncludeAll(store.find(null, 'b'), ['_:x1', 'b', 'd']);
50
50
  });
51
51
  });
52
52
 
53
+ describe('An N3Store without a configured default graph', function () {
54
+ var store = new N3Store();
55
+
56
+ it('should have a dummy default graph', function () {
57
+ store.defaultGraph.should.eql('http://example.org/#defaultGraph');
58
+ });
59
+ });
60
+
61
+ describe('An N3Store with a configured default graph', function () {
62
+ var dg = 'http://example.org/#defaultGraph';
63
+ var store = new N3Store({ defaultGraph: dg });
64
+
65
+ it('should return that configured default graph', function () {
66
+ store.defaultGraph.should.eql(dg);
67
+ });
68
+ });
69
+
53
70
  describe('An N3Store with initialized with 3 elements', function () {
54
71
  var store = new N3Store([
55
72
  { subject: 's1', predicate: 'p1', object: 'o1' },
@@ -60,32 +77,79 @@ describe('N3Store', function () {
60
77
  it('should have size 3', function () {
61
78
  store.size.should.eql(3);
62
79
  });
80
+
81
+ describe('adding a triple that already exists', function () {
82
+ it('should return false', function () {
83
+ store.addTriple('s1', 'p1', 'o1').should.be.false;
84
+ });
85
+
86
+ it('should not increase the size', function () {
87
+ store.size.should.eql(3);
88
+ });
89
+ });
90
+
91
+ describe('adding a triple that did not exist yet', function () {
92
+ it('should return true', function () {
93
+ store.addTriple('s1', 'p1', 'o4').should.be.true;
94
+ });
95
+
96
+ it('should increase the size', function () {
97
+ store.size.should.eql(4);
98
+ });
99
+ });
100
+
101
+ describe('removing an existing triple', function () {
102
+ it('should return true', function () {
103
+ store.removeTriple('s1', 'p1', 'o4').should.be.true;
104
+ });
105
+
106
+ it('should decrease the size', function () {
107
+ store.size.should.eql(3);
108
+ });
109
+ });
110
+
111
+ describe('removing a non-existing triple', function () {
112
+ it('should return false', function () {
113
+ store.removeTriple('s1', 'p1', 'o5').should.be.false;
114
+ });
115
+
116
+ it('should not decrease the size', function () {
117
+ store.size.should.eql(3);
118
+ });
119
+ });
63
120
  });
64
121
 
65
122
  describe('An N3Store with 5 elements', function () {
66
- var store = new N3Store();
67
- store.addTriple('s1', 'p1', 'o1');
68
- store.addTriple({ subject: 's1', predicate: 'p1', object: 'o2' });
123
+ var store = new N3Store({ defaultGraph: 'http://example.org/#defaultGraph' });
124
+ store.addTriple('s1', 'p1', 'o1').should.be.true;
125
+ store.addTriple({ subject: 's1', predicate: 'p1', object: 'o2' }).should.be.true;
69
126
  store.addTriples([
70
127
  { subject: 's1', predicate: 'p2', object: 'o2' },
71
128
  { subject: 's2', predicate: 'p1', object: 'o1' },
72
129
  ]);
73
- store.addTriple('s1', 'p2', 'o3', 'c4');
130
+ store.addTriple('s1', 'p2', 'o3', 'c4').should.be.true;
74
131
 
75
132
  it('should have size 5', function () {
76
133
  store.size.should.eql(5);
77
134
  });
78
135
 
79
136
  describe('when searched without parameters', function () {
80
- it('should return all items in the default graph',
137
+ it('should return all items',
81
138
  shouldIncludeAll(store.find(),
82
- ['s1', 'p1', 'o1'], ['s1', 'p1', 'o2'], ['s1', 'p2', 'o2'], ['s2', 'p1', 'o1']));
139
+ ['s1', 'p1', 'o1', store.defaultGraph],
140
+ ['s1', 'p1', 'o2', store.defaultGraph],
141
+ ['s1', 'p2', 'o2', store.defaultGraph],
142
+ ['s2', 'p1', 'o1', store.defaultGraph],
143
+ ['s1', 'p2', 'o3', 'c4']));
83
144
  });
84
145
 
85
146
  describe('when searched with an existing subject parameter', function () {
86
- it('should return all items with this subject in the default graph',
147
+ it('should return all items with this subject in all graphs',
87
148
  shouldIncludeAll(store.find('s1', null, null),
88
- ['s1', 'p1', 'o1'], ['s1', 'p1', 'o2'], ['s1', 'p2', 'o2']));
149
+ ['s1', 'p1', 'o1', store.defaultGraph],
150
+ ['s1', 'p1', 'o2', store.defaultGraph],
151
+ ['s1', 'p2', 'o2', store.defaultGraph],
152
+ ['s1', 'p2', 'o3', 'c4']));
89
153
  });
90
154
 
91
155
  describe('when searched with a non-existing subject parameter', function () {
@@ -99,7 +163,9 @@ describe('N3Store', function () {
99
163
  describe('when searched with an existing predicate parameter', function () {
100
164
  it('should return all items with this predicate in the default graph',
101
165
  shouldIncludeAll(store.find(null, 'p1', null),
102
- ['s1', 'p1', 'o1'], ['s1', 'p1', 'o2'], ['s2', 'p1', 'o1']));
166
+ ['s1', 'p1', 'o1', store.defaultGraph],
167
+ ['s1', 'p1', 'o2', store.defaultGraph],
168
+ ['s2', 'p1', 'o1', store.defaultGraph]));
103
169
  });
104
170
 
105
171
  describe('when searched with a non-existing predicate parameter', function () {
@@ -108,7 +174,9 @@ describe('N3Store', function () {
108
174
 
109
175
  describe('when searched with an existing object parameter', function () {
110
176
  it('should return all items with this object in the default graph',
111
- shouldIncludeAll(store.find(null, null, 'o1'), ['s1', 'p1', 'o1'], ['s2', 'p1', 'o1']));
177
+ shouldIncludeAll(store.find(null, null, 'o1'),
178
+ ['s1', 'p1', 'o1', store.defaultGraph],
179
+ ['s2', 'p1', 'o1', store.defaultGraph]));
112
180
  });
113
181
 
114
182
  describe('when searched with a non-existing object parameter', function () {
@@ -117,7 +185,9 @@ describe('N3Store', function () {
117
185
 
118
186
  describe('when searched with existing subject and predicate parameters', function () {
119
187
  it('should return all items with this subject and predicate in the default graph',
120
- shouldIncludeAll(store.find('s1', 'p1', null), ['s1', 'p1', 'o1'], ['s1', 'p1', 'o2']));
188
+ shouldIncludeAll(store.find('s1', 'p1', null),
189
+ ['s1', 'p1', 'o1', store.defaultGraph],
190
+ ['s1', 'p1', 'o2', store.defaultGraph]));
121
191
  });
122
192
 
123
193
  describe('when searched with non-existing subject and predicate parameters', function () {
@@ -126,7 +196,9 @@ describe('N3Store', function () {
126
196
 
127
197
  describe('when searched with existing subject and object parameters', function () {
128
198
  it('should return all items with this subject and object in the default graph',
129
- shouldIncludeAll(store.find('s1', null, 'o2'), ['s1', 'p1', 'o2'], ['s1', 'p2', 'o2']));
199
+ shouldIncludeAll(store.find('s1', null, 'o2'),
200
+ ['s1', 'p1', 'o2', store.defaultGraph],
201
+ ['s1', 'p2', 'o2', store.defaultGraph]));
130
202
  });
131
203
 
132
204
  describe('when searched with non-existing subject and object parameters', function () {
@@ -135,16 +207,18 @@ describe('N3Store', function () {
135
207
 
136
208
  describe('when searched with existing predicate and object parameters', function () {
137
209
  it('should return all items with this predicate and object in the default graph',
138
- shouldIncludeAll(store.find(null, 'p1', 'o1'), ['s1', 'p1', 'o1'], ['s2', 'p1', 'o1']));
210
+ shouldIncludeAll(store.find(null, 'p1', 'o1'),
211
+ ['s1', 'p1', 'o1', store.defaultGraph],
212
+ ['s2', 'p1', 'o1', store.defaultGraph]));
139
213
  });
140
214
 
141
- describe('when searched with non-existing predicate and object parameters', function () {
142
- itShouldBeEmpty(store.find(null, 'p2', 'o3'));
215
+ describe('when searched with non-existing predicate and object parameters in the default graph', function () {
216
+ itShouldBeEmpty(store.find(null, 'p2', 'o3', store.defaultGraph));
143
217
  });
144
218
 
145
219
  describe('when searched with existing subject, predicate, and object parameters', function () {
146
220
  it('should return all items with this subject, predicate, and object in the default graph',
147
- shouldIncludeAll(store.find('s1', 'p1', 'o1'), ['s1', 'p1', 'o1']));
221
+ shouldIncludeAll(store.find('s1', 'p1', 'o1'), ['s1', 'p1', 'o1', store.defaultGraph]));
148
222
  });
149
223
 
150
224
  describe('when searched with a non-existing triple', function () {
@@ -153,8 +227,11 @@ describe('N3Store', function () {
153
227
 
154
228
  describe('when searched with the default graph parameter', function () {
155
229
  it('should return all items in the default graph',
156
- shouldIncludeAll(store.find(),
157
- ['s1', 'p1', 'o1'], ['s1', 'p1', 'o2'], ['s1', 'p2', 'o2'], ['s2', 'p1', 'o1']));
230
+ shouldIncludeAll(store.find(null, null, null, store.defaultGraph),
231
+ ['s1', 'p1', 'o1', store.defaultGraph],
232
+ ['s1', 'p1', 'o2', store.defaultGraph],
233
+ ['s1', 'p2', 'o2', store.defaultGraph],
234
+ ['s2', 'p1', 'o1', store.defaultGraph]));
158
235
  });
159
236
 
160
237
  describe('when searched with an existing non-default graph parameter', function () {
@@ -281,62 +358,65 @@ describe('N3Store', function () {
281
358
  });
282
359
 
283
360
  describe('when trying to remove a triple with a non-existing subject', function () {
284
- before(function () { store.removeTriple('s0', 'p1', 'o1'); });
361
+ before(function () { store.removeTriple('s0', 'p1', 'o1').should.be.false; });
285
362
  it('should still have size 5', function () { store.size.should.eql(5); });
286
363
  });
287
364
 
288
365
  describe('when trying to remove a triple with a non-existing predicate', function () {
289
- before(function () { store.removeTriple('s1', 'p0', 'o1'); });
366
+ before(function () { store.removeTriple('s1', 'p0', 'o1').should.be.false; });
290
367
  it('should still have size 5', function () { store.size.should.eql(5); });
291
368
  });
292
369
 
293
370
  describe('when trying to remove a triple with a non-existing object', function () {
294
- before(function () { store.removeTriple('s1', 'p1', 'o0'); });
371
+ before(function () { store.removeTriple('s1', 'p1', 'o0').should.be.false; });
295
372
  it('should still have size 5', function () { store.size.should.eql(5); });
296
373
  });
297
374
 
298
375
  describe('when trying to remove a triple for which no subjects exist', function () {
299
- before(function () { store.removeTriple('o1', 'p1', 'o1'); });
376
+ before(function () { store.removeTriple('o1', 'p1', 'o1').should.be.false; });
300
377
  it('should still have size 5', function () { store.size.should.eql(5); });
301
378
  });
302
379
 
303
380
  describe('when trying to remove a triple for which no predicates exist', function () {
304
- before(function () { store.removeTriple('s1', 's1', 'o1'); });
381
+ before(function () { store.removeTriple('s1', 's1', 'o1').should.be.false; });
305
382
  it('should still have size 5', function () { store.size.should.eql(5); });
306
383
  });
307
384
 
308
385
  describe('when trying to remove a triple for which no objects exist', function () {
309
- before(function () { store.removeTriple('s1', 'p1', 's1'); });
386
+ before(function () { store.removeTriple('s1', 'p1', 's1').should.be.false; });
310
387
  it('should still have size 5', function () { store.size.should.eql(5); });
311
388
  });
312
389
 
313
390
  describe('when trying to remove a triple that does not exist', function () {
314
- before(function () { store.removeTriple('s1', 'p2', 'o1'); });
391
+ before(function () { store.removeTriple('s1', 'p2', 'o1').should.be.false; });
315
392
  it('should still have size 5', function () { store.size.should.eql(5); });
316
393
  });
317
394
 
318
395
  describe('when trying to remove an incomplete triple', function () {
319
- before(function () { store.removeTriple('s1', null, null); });
396
+ before(function () { store.removeTriple('s1', null, null).should.be.false; });
320
397
  it('should still have size 5', function () { store.size.should.eql(5); });
321
398
  });
322
399
 
323
400
  describe('when trying to remove a triple with a non-existing graph', function () {
324
- before(function () { store.removeTriple('s1', 'p1', 'o1', 'c0'); });
401
+ before(function () { store.removeTriple('s1', 'p1', 'o1', 'c0').should.be.false; });
325
402
  it('should still have size 5', function () { store.size.should.eql(5); });
326
403
  });
327
404
 
328
405
  describe('when removing an existing triple', function () {
329
- before(function () { store.removeTriple('s1', 'p1', 'o1'); });
406
+ before(function () { store.removeTriple('s1', 'p1', 'o1').should.be.true; });
330
407
 
331
408
  it('should have size 4', function () { store.size.should.eql(4); });
332
409
 
333
410
  it('should not contain that triple anymore',
334
411
  shouldIncludeAll(function () { return store.find(); },
335
- ['s1', 'p1', 'o2'], ['s1', 'p2', 'o2'], ['s2', 'p1', 'o1']));
412
+ ['s1', 'p1', 'o2', store.defaultGraph],
413
+ ['s1', 'p2', 'o2', store.defaultGraph],
414
+ ['s2', 'p1', 'o1', store.defaultGraph],
415
+ ['s1', 'p2', 'o3', 'c4', store.defaultGraph]));
336
416
  });
337
417
 
338
418
  describe('when removing an existing triple from a non-default graph', function () {
339
- before(function () { store.removeTriple('s1', 'p2', 'o3', 'c4'); });
419
+ before(function () { store.removeTriple('s1', 'p2', 'o3', 'c4').should.be.true; });
340
420
 
341
421
  it('should have size 3', function () { store.size.should.eql(3); });
342
422
 
@@ -355,13 +435,13 @@ describe('N3Store', function () {
355
435
 
356
436
  it('should not contain those triples anymore',
357
437
  shouldIncludeAll(function () { return store.find(); },
358
- ['s1', 'p1', 'o2']));
438
+ ['s1', 'p1', 'o2', store.defaultGraph]));
359
439
  });
360
440
 
361
441
  describe('when adding and removing a triple', function () {
362
442
  before(function () {
363
- store.addTriple('a', 'b', 'c');
364
- store.removeTriple('a', 'b', 'c');
443
+ store.addTriple('a', 'b', 'c').should.be.true;
444
+ store.removeTriple('a', 'b', 'c').should.be.true;
365
445
  });
366
446
 
367
447
  it('should have an unchanged size', function () { store.size.should.eql(1); });
@@ -380,29 +460,39 @@ describe('N3Store', function () {
380
460
 
381
461
  describe('should allow to query subjects with prefixes', function () {
382
462
  it('should return all triples with that subject',
383
- shouldIncludeAll(store.find('a:s1', null, null),
384
- ['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1'],
385
- ['http://foo.org/#s1', 'http://bar.org/p2', 'http://foo.org/#o1']));
463
+ shouldIncludeAll(store.find('a:s1', null, null),
464
+ ['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', store.defaultGraph],
465
+ ['http://foo.org/#s1', 'http://bar.org/p2', 'http://foo.org/#o1', store.defaultGraph],
466
+ ['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', 'http://graphs.org/#g1']));
467
+ });
468
+
469
+ describe('should allow to query subjects with prefixes', function () {
470
+ it('should return all triples with that subject in the default graph',
471
+ shouldIncludeAll(store.find('a:s1', null, null, store.defaultGraph),
472
+ ['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', store.defaultGraph],
473
+ ['http://foo.org/#s1', 'http://bar.org/p2', 'http://foo.org/#o1', store.defaultGraph]));
386
474
  });
387
475
 
388
476
  describe('should allow to query predicates with prefixes', function () {
389
477
  it('should return all triples with that predicate',
390
478
  shouldIncludeAll(store.find(null, 'b:p1', null),
391
- ['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1'],
392
- ['http://foo.org/#s2', 'http://bar.org/p1', 'http://foo.org/#o2']));
479
+ ['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', store.defaultGraph],
480
+ ['http://foo.org/#s2', 'http://bar.org/p1', 'http://foo.org/#o2', store.defaultGraph],
481
+ ['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', 'http://graphs.org/#g1']));
393
482
  });
394
483
 
395
484
  describe('should allow to query objects with prefixes', function () {
396
485
  it('should return all triples with that object',
397
486
  shouldIncludeAll(store.find(null, null, 'a:o1'),
398
- ['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1'],
399
- ['http://foo.org/#s1', 'http://bar.org/p2', 'http://foo.org/#o1']));
487
+ ['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', store.defaultGraph],
488
+ ['http://foo.org/#s1', 'http://bar.org/p2', 'http://foo.org/#o1', store.defaultGraph],
489
+ ['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', 'http://graphs.org/#g1']));
400
490
  });
401
491
 
402
492
  describe('should allow to query graphs with prefixes', function () {
403
493
  it('should return all triples with that graph',
404
494
  shouldIncludeAll(store.find(null, null, null, 'http://graphs.org/#g1'),
405
- ['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', 'http://graphs.org/#g1']));
495
+ ['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', 'http://graphs.org/#g1', store.defaultGraph]));
406
496
  });
407
497
  });
408
498
 
@@ -417,25 +507,49 @@ describe('N3Store', function () {
417
507
  store.addPrefix('a', 'http://foo.org/#');
418
508
  store.addPrefixes({ b: 'http://bar.org/', g: 'http://graphs.org/#' });
419
509
 
510
+ describe('should allow to query subjects with prefixes', function () {
511
+ it('should return all triples with that subject in the default graph',
512
+ shouldIncludeAll(store.find('a:s1', null, null, store.defaultGraph),
513
+ ['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', store.defaultGraph],
514
+ ['http://foo.org/#s1', 'http://bar.org/p2', 'http://foo.org/#o1', store.defaultGraph]));
515
+ });
516
+
420
517
  describe('should allow to query subjects with prefixes', function () {
421
518
  it('should return all triples with that subject',
422
- shouldIncludeAll(store.find('a:s1', null, null),
423
- ['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1'],
424
- ['http://foo.org/#s1', 'http://bar.org/p2', 'http://foo.org/#o1']));
519
+ shouldIncludeAll(store.find('a:s1', null, null),
520
+ ['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', store.defaultGraph],
521
+ ['http://foo.org/#s1', 'http://bar.org/p2', 'http://foo.org/#o1', store.defaultGraph],
522
+ ['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', 'http://graphs.org/#g1']));
523
+ });
524
+
525
+ describe('should allow to query predicates with prefixes', function () {
526
+ it('should return all triples with that predicate in the default graph',
527
+ shouldIncludeAll(store.find(null, 'b:p1', null, store.defaultGraph),
528
+ ['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', store.defaultGraph],
529
+ ['http://foo.org/#s2', 'http://bar.org/p1', 'http://foo.org/#o2', store.defaultGraph]));
425
530
  });
426
531
 
427
532
  describe('should allow to query predicates with prefixes', function () {
428
533
  it('should return all triples with that predicate',
429
- shouldIncludeAll(store.find(null, 'b:p1', null),
430
- ['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1'],
431
- ['http://foo.org/#s2', 'http://bar.org/p1', 'http://foo.org/#o2']));
534
+ shouldIncludeAll(store.find(null, 'b:p1', null),
535
+ ['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', store.defaultGraph],
536
+ ['http://foo.org/#s2', 'http://bar.org/p1', 'http://foo.org/#o2', store.defaultGraph],
537
+ ['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', 'http://graphs.org/#g1']));
538
+ });
539
+
540
+ describe('should allow to query objects with prefixes', function () {
541
+ it('should return all triples with that object in the default graph',
542
+ shouldIncludeAll(store.find(null, null, 'a:o1', store.defaultGraph),
543
+ ['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', store.defaultGraph],
544
+ ['http://foo.org/#s1', 'http://bar.org/p2', 'http://foo.org/#o1', store.defaultGraph]));
432
545
  });
433
546
 
434
547
  describe('should allow to query objects with prefixes', function () {
435
548
  it('should return all triples with that object',
436
549
  shouldIncludeAll(store.find(null, null, 'a:o1'),
437
- ['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1'],
438
- ['http://foo.org/#s1', 'http://bar.org/p2', 'http://foo.org/#o1']));
550
+ ['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', store.defaultGraph],
551
+ ['http://foo.org/#s1', 'http://bar.org/p2', 'http://foo.org/#o1', store.defaultGraph],
552
+ ['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', 'http://graphs.org/#g1']));
439
553
  });
440
554
 
441
555
  describe('should allow to query graphs with prefixes', function () {
@@ -456,19 +570,19 @@ describe('N3Store', function () {
456
570
  describe('should allow to query subjects without prefixes', function () {
457
571
  it('should return all triples with that subject',
458
572
  shouldIncludeAll(store.find('http://foo.org/#s1', null, null),
459
- ['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1'],
460
- ['http://foo.org/#s1', 'http://bar.org/p2', 'http://foo.org/#o1']));
573
+ ['http://foo.org/#s1', 'http://bar.org/p1', 'http://foo.org/#o1', store.defaultGraph],
574
+ ['http://foo.org/#s1', 'http://bar.org/p2', 'http://foo.org/#o1', store.defaultGraph]));
461
575
  });
462
576
  });
463
577
 
464
578
  describe('An N3Store created without triples but with prefixes', function () {
465
579
  var store = new N3Store({ prefixes: { http: 'http://www.w3.org/2006/http#' } });
466
- store.addTriple('a', 'http://www.w3.org/2006/http#b', 'c');
580
+ store.addTriple('a', 'http://www.w3.org/2006/http#b', 'c').should.be.true;
467
581
 
468
582
  describe('should allow to query predicates with prefixes', function () {
469
583
  it('should return all triples with that predicate',
470
584
  shouldIncludeAll(store.find(null, 'http:b', null),
471
- ['a', 'http://www.w3.org/2006/http#b', 'c']));
585
+ ['a', 'http://www.w3.org/2006/http#b', 'c', store.defaultGraph]));
472
586
  });
473
587
  });
474
588
 
@@ -478,13 +592,13 @@ describe('N3Store', function () {
478
592
  // Test inspired by http://www.devthought.com/2012/01/18/an-object-is-not-a-hash/.
479
593
  // The value `__proto__` is not supported however – fixing it introduces too much overhead.
480
594
  it('should be able to contain entities with JavaScript object property names', function () {
481
- store.addTriple('toString', 'valueOf', 'toLocaleString', 'hasOwnProperty');
595
+ store.addTriple('toString', 'valueOf', 'toLocaleString', 'hasOwnProperty').should.be.true;
482
596
  shouldIncludeAll(store.find(null, null, null, 'hasOwnProperty'),
483
597
  ['toString', 'valueOf', 'toLocaleString', 'hasOwnProperty'])();
484
598
  });
485
599
 
486
600
  it('should be able to contain entities named "null"', function () {
487
- store.addTriple('null', 'null', 'null', 'null');
601
+ store.addTriple('null', 'null', 'null', 'null').should.be.true;
488
602
  shouldIncludeAll(store.find(null, null, null, 'null'), ['null', 'null', 'null', 'null'])();
489
603
  });
490
604
  });
@@ -340,4 +340,70 @@ describe('N3Util', function () {
340
340
  N3Util.createLiteral(true).should.equal('"true"^^http://www.w3.org/2001/XMLSchema#boolean');
341
341
  });
342
342
  });
343
+
344
+ describe('prefix', function () {
345
+ var baz = N3Util.prefix('http://ex.org/baz#');
346
+ it('should return a function', function () {
347
+ expect(baz).to.be.an.instanceof(Function);
348
+ });
349
+
350
+ describe('the function', function () {
351
+ it('should expand the prefix', function () {
352
+ expect(baz('bar')).to.equal('http://ex.org/baz#bar');
353
+ });
354
+ });
355
+ });
356
+
357
+ describe('prefixes', function () {
358
+ describe('called without arguments', function () {
359
+ var prefixes = N3Util.prefixes();
360
+ it('should return a function', function () {
361
+ expect(prefixes).to.be.an.instanceof(Function);
362
+ });
363
+
364
+ describe('the function', function () {
365
+ it('should not expand non-registered prefixes', function () {
366
+ expect(prefixes('baz')('bar')).to.equal('bar');
367
+ });
368
+
369
+ it('should allow registering prefixes', function () {
370
+ var p = prefixes('baz', 'http://ex.org/baz#');
371
+ expect(p).to.exist;
372
+ expect(p).to.equal(prefixes('baz'));
373
+ });
374
+
375
+ it('should expand the newly registered prefix', function () {
376
+ expect(prefixes('baz')('bar')).to.equal('http://ex.org/baz#bar');
377
+ });
378
+ });
379
+ });
380
+
381
+ describe('called with a hash of prefixes', function () {
382
+ var prefixes = N3Util.prefixes({ foo: 'http://ex.org/foo#', bar: 'http://ex.org/bar#' });
383
+ it('should return a function', function () {
384
+ expect(prefixes).to.be.an.instanceof(Function);
385
+ });
386
+
387
+ describe('the function', function () {
388
+ it('should expand registered prefixes', function () {
389
+ expect(prefixes('foo')('bar')).to.equal('http://ex.org/foo#bar');
390
+ expect(prefixes('bar')('bar')).to.equal('http://ex.org/bar#bar');
391
+ });
392
+
393
+ it('should not expand non-registered prefixes', function () {
394
+ expect(prefixes('baz')('bar')).to.equal('bar');
395
+ });
396
+
397
+ it('should allow registering prefixes', function () {
398
+ var p = prefixes('baz', 'http://ex.org/baz#');
399
+ expect(p).to.exist;
400
+ expect(p).to.equal(prefixes('baz'));
401
+ });
402
+
403
+ it('should expand the newly registered prefix', function () {
404
+ expect(prefixes('baz')('bar')).to.equal('http://ex.org/baz#bar');
405
+ });
406
+ });
407
+ });
408
+ });
343
409
  });