├── .editorconfig
├── .eslintrc.js
├── .gitignore
├── Makefile
├── README.ipynb
├── README.md
├── UNLICENSE
├── bin
├── node_modules
│ └── rdf.js
├── turtle-equal.js
└── turtle-nt.js
├── index.js
├── lib
├── BlankNodeMap.js
├── Builtins.js
├── DataFactory.js
├── Dataset.js
├── Graph.js
├── GraphEquals.js
├── GraphSimplyEntails.js
├── Profile.js
├── RDFEnvironment.js
├── RDFNode.js
├── ResultSet.js
├── TurtleParser.js
├── encodeString.js
├── environment.js
├── ns.js
├── prefixes.js
└── space.js
├── package.json
└── test
├── .eslintrc.js
├── BlankNode.test.js
├── BlankNodeMap.test.js
├── DataFactory.test.js
├── Dataset.test.js
├── DefaultGraph.test.js
├── Graph.test.js
├── Literal.test.js
├── NamedNode.test.js
├── PrefixMap.test.js
├── Profile.test.js
├── Quad.test.js
├── RDF-MT.test.js
├── RDFEnvironment.test.js
├── RDFNode.test.js
├── ResultSet.test.js
├── TermMap.test.js
├── Triple.test.js
├── TriplePattern.test.js
├── TurtleParser.test.js
├── Variable.test.js
├── builtins-Number.test.js
├── builtins-Object.test.js
├── builtins-String.test.js
├── environment.test.js
├── ns.test.js
└── parse.test.js
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://EditorConfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = tab
7 | indent_size = 3
8 | end_of_line = lf
9 | insert_final_newline = true
10 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | module.exports = {
3 | "env": {
4 | "node": true,
5 | "es6": true,
6 | },
7 | "extends": "eslint:recommended",
8 | "parserOptions": {
9 | "ecmaVersion": 6,
10 | },
11 | "rules": {
12 | "indent": [ "error", "tab", { SwitchCase: 1 } ],
13 | "strict": ["error", "global"],
14 | "no-unused-vars": [ "warn", { "args": "none" } ],
15 | "no-unreachable": [ "error" ],
16 | "linebreak-style": [ "error", "unix" ],
17 | "semi": [ "error", "always" ],
18 | "comma-dangle": [ "error", "always-multiline" ],
19 | "no-console": [ "error" ],
20 | },
21 | };
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules/
2 | /test/TurtleTests/
3 | /test/rdf-mt-tests/
4 | /.ipynb_checkpoints
5 | /.nyc_output
6 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | # You could also set to "wget -o -"
2 | GET="curl"
3 | MOCHA=./node_modules/.bin/mocha
4 | ISTANBUL=./node_modules/.bin/nyc
5 |
6 | all: README.md
7 |
8 | test: test/TurtleTests/manifest.ttl test/rdf-mt-tests/manifest.ttl
9 | $(MOCHA)
10 |
11 | coverage: test/TurtleTests/manifest.ttl
12 | $(ISTANBUL) --reporter=html $(MOCHA)
13 |
14 | test/TurtleTests/manifest.ttl: | test/TurtleTests
15 |
16 | test/TurtleTests:
17 | $(GET) 'https://www.w3.org/2013/TurtleTests/TESTS.tar.gz' | tar -zx -C test -f -
18 |
19 | test/rdf-mt-tests/manifest.ttl: | test/rdf-mt-tests
20 |
21 | test/rdf-mt-tests:
22 | mkdir $@
23 | $(GET) 'https://www.w3.org/2013/rdf-mt-tests/TESTS.tar.gz' | tar -zx -C test/rdf-mt-tests -f -
24 |
25 | # Edit with:
26 | # $ ijsnotebook README.ipynb
27 | # `cat -s` collapses multiple newlines into a single newline
28 | README.md: README.ipynb
29 | jupyter-nbconvert $< --to markdown --stdout | sed 's/^var /const /' | cat -s > $@
30 |
31 | clean:
32 | rm -rf README.md coverage
33 |
34 | .PHONY: test clean
35 |
--------------------------------------------------------------------------------
/UNLICENSE:
--------------------------------------------------------------------------------
1 | This is free and unencumbered software released into the public domain.
2 |
3 | Anyone is free to copy, modify, publish, use, compile, sell, or
4 | distribute this software, either in source code form or as a compiled
5 | binary, for any purpose, commercial or non-commercial, and by any
6 | means.
7 |
8 | In jurisdictions that recognize copyright laws, the author or authors
9 | of this software dedicate any and all copyright interest in the
10 | software to the public domain. We make this dedication for the benefit
11 | of the public at large and to the detriment of our heirs and
12 | successors. We intend this dedication to be an overt act of
13 | relinquishment in perpetuity of all present and future rights to this
14 | software under copyright law.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 | OTHER DEALINGS IN THE SOFTWARE.
23 |
24 | For more information, please refer to
25 |
--------------------------------------------------------------------------------
/bin/node_modules/rdf.js:
--------------------------------------------------------------------------------
1 | module.exports = require('../../index.js');
2 |
--------------------------------------------------------------------------------
/bin/turtle-equal.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | var fs = require('fs');
4 |
5 | var parse = require('./../index.js').parse;
6 | var TurtleParser = require('rdf').TurtleParser;
7 | var rdfenv = require('rdf').environment;
8 |
9 | var files = process.argv.slice(2);
10 | var baseURI = 'http://example.com/';
11 |
12 | var graphii = files.map(function(filepath){
13 | try {
14 | //console.error(filepath);
15 | var inputContents = fs.readFileSync(filepath, 'UTF-8');
16 | var turtleParser = TurtleParser.parse(inputContents, baseURI);
17 | var outputGraph = turtleParser.graph;
18 | console.log(outputGraph.toArray().map(function(t){ return t.toString()+'\n'; }).join(''));
19 | return outputGraph;
20 | }catch(err){
21 | console.error(err.stack);
22 | }
23 | });
24 |
25 | var match = graphii[0].equals(graphii[1]);
26 | if(match){
27 | console.log(match);
28 | }else{
29 | console.error('No match');
30 | process.exit(1);
31 | }
32 |
--------------------------------------------------------------------------------
/bin/turtle-nt.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | var fs = require('fs');
4 |
5 | var TurtleParser = require('rdf').TurtleParser;
6 | var rdfenv = require('rdf').environment;
7 |
8 | var files = process.argv.slice(2);
9 | var baseURI = 'http://example.com/';
10 |
11 | files.forEach(function(filepath){
12 | try {
13 | //console.error(filepath);
14 | var inputContents = fs.readFileSync(filepath, 'UTF-8');
15 | var turtleParser = TurtleParser.parse(inputContents, baseURI);
16 | var outputGraph = turtleParser.graph;
17 | console.log(outputGraph.toArray().map(function(t){ return t.toString()+'\n'; }).join(''));
18 | }catch(err){
19 | console.error(err.stack);
20 | }
21 | });
22 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | /**
4 | * RDF
5 | *
6 | * Implement a mash-up of the RDF Interfaces API, the RDF API, and first and foremost whatever makes sense for Node.js
7 | */
8 |
9 | var api = exports;
10 |
11 | api.RDFNode = require('./lib/RDFNode.js').RDFNode;
12 | api.Term = api.RDFNode;
13 | api.NamedNode = require('./lib/RDFNode.js').NamedNode;
14 | api.BlankNode = require('./lib/RDFNode.js').BlankNode;
15 | api.Literal = require('./lib/RDFNode.js').Literal;
16 | api.Variable = require('./lib/RDFNode.js').Variable;
17 |
18 | api.Profile = require('./lib/Profile.js').Profile;
19 | api.TermMap = require('./lib/Profile.js').TermMap;
20 | api.PrefixMap = require('./lib/Profile.js').PrefixMap;
21 | api.RDFEnvironment = require('./lib/RDFEnvironment.js').RDFEnvironment;
22 | api.BlankNodeMap = require('./lib/BlankNodeMap.js').BlankNodeMap;
23 |
24 | api.TurtleParser = require('./lib/TurtleParser.js').Turtle;
25 |
26 | api.Graph = require('./lib/Graph.js').Graph;
27 | api.Triple = require('./lib/RDFNode.js').Triple;
28 | api.TriplePattern = require('./lib/RDFNode.js').TriplePattern;
29 | api.ResultSet = require("./lib/ResultSet.js").ResultSet;
30 |
31 | api.DefaultGraph = require('./lib/RDFNode.js').DefaultGraph;
32 | api.Dataset = require('./lib/Dataset.js').Dataset;
33 | api.Quad = require('./lib/RDFNode.js').Quad;
34 |
35 | // DataFactory support
36 | api.DataFactory = require('./lib/DataFactory.js').DataFactory;
37 | api.factory = require('./lib/environment').factory;
38 | // api.namedNode = require('./lib/DataFactory.js').namedNode;
39 | // api.blankNode = require('./lib/DataFactory.js').blankNode;
40 | // api.literal = require('./lib/DataFactory.js').literal;
41 | // api.variable = require('./lib/DataFactory.js').variable;
42 | // api.defaultGraph = require('./lib/DataFactory.js').defaultGraph;
43 | // api.triple = require('./lib/DataFactory.js').triple;
44 | // api.quad = require('./lib/DataFactory.js').quad;
45 |
46 | api.environment = require('./lib/environment').environment;
47 | api.setBuiltins = require('./lib/Builtins').setBuiltins;
48 | api.unsetBuiltins = require('./lib/Builtins').unsetBuiltins;
49 | api.builtins = require('./lib/Builtins');
50 | api.parse = function(o, id){
51 | return api.builtins.ref.call(o, id);
52 | };
53 |
54 | api.ns = require('./lib/ns.js').ns;
55 | api.rdfns = require('./lib/ns.js').rdfns;
56 | api.rdfsns = require('./lib/ns.js').rdfsns;
57 | api.xsdns = require('./lib/ns.js').xsdns;
58 |
--------------------------------------------------------------------------------
/lib/BlankNodeMap.js:
--------------------------------------------------------------------------------
1 |
2 | "use strict";
3 |
4 | var BlankNode = require('./RDFNode.js').BlankNode;
5 | var Triple = require('./RDFNode.js').Triple;
6 | var Quad = require('./RDFNode.js').Quad;
7 |
8 | // Declare or generate a mapping of Variables or BlankNodes to BlankNodes, Terms, or Literals
9 |
10 | module.exports.BlankNodeMap = BlankNodeMap;
11 | function BlankNodeMap(){
12 | if(!(this instanceof BlankNodeMap)) return new BlankNodeMap();
13 | this.mapping = {};
14 | this.start = 0;
15 | this.labelPrefix = 'bn';
16 | }
17 |
18 | BlankNodeMap.prototype.get = function get(bnode){
19 | return this.mapping[bnode];
20 | };
21 |
22 | BlankNodeMap.prototype.process = function process(bnode){
23 | if(bnode instanceof Triple){
24 | return new Triple(this.process(bnode.subject), bnode.predicate, this.process(bnode.object));
25 | }
26 | if(bnode instanceof Quad){
27 | return new Quad(this.process(bnode.subject), bnode.predicate, this.process(bnode.object), bnode.graph);
28 | }
29 | if(typeof bnode=='string' && bnode.substring(0,2)!=='_:'){
30 | bnode = '_:' + bnode;
31 | }
32 | if(this.mapping[bnode]) return this.mapping[bnode];
33 | if(this.labelPrefix) this.mapping[bnode] = new BlankNode(this.labelPrefix+this.start);
34 | else this.mapping[bnode] = new BlankNode(bnode.toString());
35 | this.start++;
36 | return this.mapping[bnode];
37 | };
38 |
39 | BlankNodeMap.prototype.equals = function equals(bnode, target){
40 | if(this.mapping[bnode]) return this.mapping[bnode]===target;
41 | this.mapping[bnode] = target;
42 | return true;
43 | };
44 |
--------------------------------------------------------------------------------
/lib/DataFactory.js:
--------------------------------------------------------------------------------
1 | // RDF Representation - DataFactory support
2 |
3 | "use strict";
4 |
5 | var RDFNode = require('./RDFNode.js');
6 | var Dataset = require('./Dataset.js').Dataset;
7 |
8 | module.exports.DataFactory = DataFactory;
9 | function DataFactory(){
10 | // At a future date, have rdf.Environment use DataFactory for its Environment#createFoo methods
11 | // this.blankNodeId = 0;
12 | // this.blankNodeMap = {};
13 | this.DefaultGraphInstance = new RDFNode.DefaultGraph();
14 | }
15 |
16 | DataFactory.prototype.namedNode = function namedNode(uri){
17 | return new RDFNode.NamedNode(uri);
18 | };
19 | DataFactory.prototype.blankNode = function blankNode(label){
20 | // If a label is specified, possibly re-use an existing blankNode
21 | return new RDFNode.BlankNode(label);
22 | };
23 | DataFactory.prototype.literal = function literal(value, dt){
24 | return new RDFNode.Literal(value, dt);
25 | };
26 | DataFactory.prototype.variable = function variable(name){
27 | return new RDFNode.Variable(name);
28 | };
29 | DataFactory.prototype.defaultGraph = function defaultGraph(){
30 | return this.DefaultGraphInstance;
31 | };
32 | DataFactory.prototype.triple = function triple(subject, predicate, object){
33 | return new RDFNode.Triple(subject, predicate, object);
34 | };
35 | DataFactory.prototype.quad = function quad(subject, predicate, object, graph){
36 | return new RDFNode.Quad(subject, predicate, object, graph || this.DefaultGraphInstance);
37 | };
38 | DataFactory.prototype.dataset = function dataset(src){
39 | return new Dataset(src);
40 | };
41 | DataFactory.prototype.fromTerm = function fromTerm(node){
42 | if(typeof node!=='object') throw new Error('Expected an object `node`');
43 | if(node instanceof RDFNode.RDFNode) return node;
44 | switch(node.termType){
45 | case 'NamedNode': return new RDFNode.NamedNode(node.value);
46 | case 'BlankNode': return new RDFNode.BlankNode(node.value);
47 | case 'Literal': return new RDFNode.Literal(node.value, node.language ? node.language : this.fromTerm(node.datatype)); // FIXME
48 | case 'Variable': return new RDFNode.Variable(node.value);
49 | case 'DefaultGraph': return this.DefaultGraphInstance;
50 | }
51 | throw new Error('Unrecognised Term#termType');
52 | };
53 | DataFactory.prototype.fromQuad = function fromQuad(quad){
54 | if(typeof quad!=='object') throw new Error('Expected an object `quad`');
55 | if(quad instanceof RDFNode.Quad) return quad;
56 | return new RDFNode.Quad(this.fromTerm(quad.subject), this.fromTerm(quad.predicate), this.fromTerm(quad.object), this.fromTerm(quad.graph));
57 | };
58 | DataFactory.prototype.fromTriple = function fromTriple(stmt){
59 | if(typeof stmt!=='object') throw new Error('Expected an object `quad`');
60 | if(stmt instanceof RDFNode.Triple) return stmt;
61 | return new RDFNode.Triple(this.fromTerm(stmt.subject), this.fromTerm(stmt.predicate), this.fromTerm(stmt.object));
62 | };
63 |
--------------------------------------------------------------------------------
/lib/Dataset.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var RDFNode = require('./RDFNode.js');
4 | var Graph = require('./Graph.js').Graph;
5 |
6 | /**
7 | * Read an RDF Collection and return it as an Array
8 | */
9 | var rdfnil = new RDFNode.NamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#nil');
10 | var rdffirst = new RDFNode.NamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#first');
11 | var rdfrest = new RDFNode.NamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#rest');
12 |
13 | function isIndex(i, a, b, c, d, t){
14 | if(!i[a]) return false;
15 | if(!i[a][b]) return false;
16 | if(!i[a][b][c]) return false;
17 | return i[a][b][c][d] ? i[a][b][c][d].equals(t) : false ;
18 | }
19 |
20 | function insertIndex(i, a, b, c, d, t){
21 | if(!i[a]) i[a] = {};
22 | if(!i[a][b]) i[a][b] = {};
23 | if(!i[a][b][c]) i[a][b][c] = {};
24 | i[a][b][c][d] = t;
25 | }
26 |
27 | function deleteIndex(i, a, b, c, d, t){
28 | if(i[a] && i[a][b] && i[a][b][c] && i[a][b][c][d]){
29 | if(!i[a][b][c][d].equals(t)) throw new Error('assertion fail: deleted quad mismatch');
30 | delete(i[a][b][c][d]);
31 | if(!Object.keys(i[a][b][c]).length) delete(i[a][b][c]);
32 | if(!Object.keys(i[a][b]).length) delete(i[a][b]);
33 | if(!Object.keys(i[a]).length) delete(i[a]);
34 | }
35 | }
36 |
37 | exports.Dataset = Dataset;
38 | function Dataset(init){
39 | this.clear();
40 | //this._actions = [];
41 | Object.defineProperty(this, 'size', {get: function(){return self.length;}});
42 | var self = this;
43 | if(init && init.forEach){
44 | init.forEach(function(t){ self.add(t); });
45 | }
46 | }
47 | Dataset.prototype.length = null;
48 | Dataset.prototype.graph = null;
49 |
50 | // TODO remove this? What is this doing?
51 | Dataset.prototype.importArray = function(a) { while( a.length > 0) { this.add(a.pop()); } };
52 |
53 | Dataset.prototype.insertIndex = insertIndex;
54 | Dataset.prototype.deleteIndex = deleteIndex;
55 | Dataset.prototype.add = function(quad) {
56 | if(!(quad instanceof RDFNode.Quad)) throw new TypeError('Expected a Quad for argument[0] `quad`');
57 | var st=quad.subject.toNT(), pt=quad.predicate.toNT(), ot=quad.object.toNT(), gt=quad.graph.toNT();
58 | if(isIndex(this.indexSPOG, st, pt, ot, gt, quad)) return;
59 | insertIndex(this.indexSPOG, st, pt, ot, gt, quad);
60 | insertIndex(this.indexPOGS, pt, ot, gt, st, quad);
61 | insertIndex(this.indexOGSP, ot, gt, st, pt, quad);
62 | insertIndex(this.indexGSPO, gt, st, pt, ot, quad);
63 | insertIndex(this.indexGPOS, gt, pt, ot, st, quad);
64 | insertIndex(this.indexOSGP, ot, st, gt, pt, quad);
65 | this.length++;
66 | //this.actions.forEach(function(fn){ fn(quad); });
67 | };
68 | Dataset.prototype.addAll = function(g){
69 | var g2 = this;
70 | g.forEach(function(s){ g2.add(s); });
71 | };
72 | Dataset.prototype.union = function union(){
73 | var gx = new Graph;
74 | this.forEach(function(q){
75 | gx.add(new RDFNode.Triple(q.subject, q.predicate, q.object));
76 | });
77 | return gx;
78 | };
79 | Dataset.prototype.remove = function(quad) {
80 | var st=quad.subject.toNT(), pt=quad.predicate.toNT(), ot=quad.object.toNT(), gt=quad.graph.toNT();
81 | if(!isIndex(this.indexSPOG, st, pt, ot, gt, quad)) return;
82 | deleteIndex(this.indexSPOG, st, pt, ot, gt, quad);
83 | deleteIndex(this.indexPOGS, pt, ot, gt, st, quad);
84 | deleteIndex(this.indexOGSP, ot, gt, st, pt, quad);
85 | deleteIndex(this.indexGSPO, gt, st, pt, ot, quad);
86 | deleteIndex(this.indexGPOS, gt, pt, ot, st, quad);
87 | deleteIndex(this.indexOSGP, ot, st, gt, pt, quad);
88 | this.length--;
89 | };
90 | Dataset.prototype.delete = Dataset.prototype.remove;
91 | Dataset.prototype.has = function(quad) {
92 | if(!(quad instanceof RDFNode.Quad)) throw new TypeError('Expected a Quad for argument[0] `quad`');
93 | var st=quad.subject.toNT(), pt=quad.predicate.toNT(), ot=quad.object.toNT(), gt=quad.graph.toNT();
94 | return isIndex(this.indexSPOG, st, pt, ot, gt, quad);
95 | };
96 | Dataset.prototype.removeMatches = function(s, p, o, g) {
97 | var self = this;
98 | this.match(s, p, o, g).forEach(function(t) {
99 | self.remove(t);
100 | });
101 | };
102 | Dataset.prototype.deleteMatches = Dataset.prototype.removeMatches;
103 | Dataset.prototype.clear = function(){
104 | this.indexSPOG = {};
105 | this.indexPOGS = {};
106 | this.indexOGSP = {};
107 | this.indexGSPO = {};
108 | this.indexGPOS = {};
109 | this.indexOSGP = {};
110 | this.length = 0;
111 | };
112 | Dataset.prototype.import = function(s) {
113 | var _g1 = 0, _g = s.length;
114 | while(_g1 < _g) {
115 | var i = _g1++;
116 | this.add(s.get(i));
117 | }
118 | };
119 | Dataset.prototype.every = function every(filter) { return this.toArray().every(filter); };
120 | Dataset.prototype.some = function some(filter) { return this.toArray().some(filter); };
121 | Dataset.prototype.forEach = function forEach(callbck) { this.toArray().forEach(callbck); };
122 | Dataset.prototype.toArray = function toArray() {
123 | var quads = [];
124 | var data = this.indexSPOG;
125 | if(!data) return [];
126 | (function go(data, c){
127 | if(c) Object.keys(data).forEach(function(t){go(data[t], c-1);});
128 | else quads.push(data);
129 | })(data, 4);
130 | return quads;
131 | };
132 | Dataset.prototype.filter = function filter(cb){
133 | var result = new Dataset;
134 | this.forEach(function(quad){
135 | if(cb(quad)) result.add(quad);
136 | });
137 | return result;
138 | };
139 | Dataset.prototype.getCollection = function getCollection(subject){
140 | var collection=[], seen=[];
141 | var first, rest=subject;
142 | while(rest && !rest.equals(rdfnil)){
143 | var g = this.match(rest, rdffirst, null);
144 | if(g.length===0) throw new Error('Collection <'+rest+'> is incomplete');
145 | first = g.toArray().map(function(v){return v.object;})[0];
146 | if(seen.indexOf(rest.toString())!==-1) throw new Error('Collection <'+rest+'> is circular');
147 | seen.push(rest.toString());
148 | collection.push(first);
149 | rest = this.match(rest, rdfrest, null).toArray().map(function(v){return v.object;})[0];
150 | }
151 | return collection;
152 | };
153 | // FIXME ensure that the RDFNode#equals semantics are met
154 |
155 | Dataset.prototype.match = function match(subject, predicate, object, graph){
156 | // if the String prototype has a nodeType/toNT function, builtins is enabled,
157 | if(typeof subject=="string" && typeof subject.toNT!='function') subject = new RDFNode.NamedNode(subject);
158 | if(subject!==null && !RDFNode.RDFNode.is(subject)) throw new Error('match subject is not an RDFNode');
159 | if(subject!==null && subject.termType!=='NamedNode' && subject.termType!=='BlankNode') throw new Error('match subject must be a NamedNode/BlankNode');
160 | if(typeof predicate=="string" && typeof predicate.toNT!='function') predicate = new RDFNode.NamedNode(predicate);
161 | if(predicate!==null && !RDFNode.RDFNode.is(predicate)) throw new Error('match predicate is not an RDFNode');
162 | if(predicate!==null && predicate.termType!=='NamedNode') throw new Error('match predicate must be a NamedNode');
163 | if(typeof object=="string" && typeof object.toNT!='function') object = new RDFNode.NamedNode(object);
164 | if(object!==null && !RDFNode.RDFNode.is(object)) throw new Error('match object is not an RDFNode');
165 | if(object!==null && object.termType!=='NamedNode' && object.termType!=='BlankNode' && object.termType!=='Literal') throw new Error('match object must be a NamedNode/BlankNode/Literal');
166 | if(typeof graph=="string" && typeof graph.toNT!='function') graph = new RDFNode.NamedNode(graph);
167 | if(graph!==null && !RDFNode.RDFNode.is(graph)) throw new Error('match graph is not an RDFNode');
168 | if(graph!==null && graph.termType!=='NamedNode') throw new Error('match graph must be a NamedNode');
169 | var result = new Dataset;
170 | var pattern = {s:subject&&subject.toNT(), p:predicate&&predicate.toNT(), o:object&&object.toNT(), g:graph&&graph.toNT()};
171 | var patternIndexMap = [
172 | {index:this.indexSPOG, constants:["s", "p", "o", "g"], variables:[]},
173 | {index:this.indexSPOG, constants:["s", "p", "o"], variables:["g"]},
174 | {index:this.indexGSPO, constants:["s", "p", "g"], variables:["o"]},
175 | {index:this.indexSPOG, constants:["s", "p"], variables:["o", "g"]},
176 | {index:this.indexOSGP, constants:["s", "o", "g"], variables:["p"]},
177 | {index:this.indexOSGP, constants:["s", "o"], variables:["p", "g"]},
178 | {index:this.indexGSPO, constants:["s", "g"], variables:["p", "o"]},
179 | {index:this.indexSPOG, constants:["s"], variables:["p", "o", "g"]},
180 | {index:this.indexPOGS, constants:["p", "o", "g"], variables:["s"]},
181 | {index:this.indexPOGS, constants:["p", "o"], variables:["s", "g"]},
182 | {index:this.indexGPOS, constants:["p", "g"], variables:["s", "o"]},
183 | {index:this.indexPOGS, constants:["p"], variables:["s", "o", "g"]},
184 | {index:this.indexOGSP, constants:["o", "g"], variables:["s", "p"]},
185 | {index:this.indexOGSP, constants:["o"], variables:["s", "p", "g"]},
186 | {index:this.indexGSPO, constants:["g"], variables:["s", "p", "o"]},
187 | {index:this.indexSPOG, constants:[], variables:["s", "p", "o", "g"]},
188 | ];
189 | var patternType = 0;
190 | if(!pattern.s) patternType |= 8;
191 | if(!pattern.p) patternType |= 4;
192 | if(!pattern.o) patternType |= 2;
193 | if(!pattern.g) patternType |= 1;
194 | var index = patternIndexMap[patternType];
195 | var data = index.index;
196 | index.constants.forEach(function(v){if(data) data=data[pattern[v]];});
197 | if(!data) return result;
198 | (function go(data, c){
199 | if(c) return void Object.keys(data).forEach(function(t){go(data[t], c-1);});
200 | if(subject && !data.subject.equals(subject)) throw new Error('assertion fail: subject');
201 | if(predicate && !data.predicate.equals(predicate)) throw new Error('assertion fail: predicate');
202 | if(object && !data.object.equals(object)) throw new Error('assertion fail: object');
203 | if(graph && !data.graph.equals(graph)) throw new Error('assertion fail: graph');
204 | result.add(data);
205 | })(data, index.variables.length);
206 | return result;
207 | };
208 |
209 | // Gets a reference to a particular subject
210 | // Graph.prototype.reference = function reference(subject){
211 | // return new ResultSet.ResultSet(this, subject);
212 | // };
213 |
--------------------------------------------------------------------------------
/lib/Graph.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var RDFNode = require('./RDFNode.js');
4 | var ResultSet = require('./ResultSet.js');
5 |
6 | /**
7 | * The very fastest graph for heavy read operations, but uses three indexes
8 | * Graph (fast, triple indexed) implements DataStore
9 |
10 | [NoInterfaceObject]
11 | interface Graph {
12 | readonly attribute unsigned long length;
13 | Graph add (in Triple triple);
14 | Graph remove (in Triple triple);
15 | Graph removeMatches (in any? subject, in any? predicate, in any? object);
16 | sequence toArray ();
17 | boolean some (in TripleFilter callback);
18 | boolean every (in TripleFilter callback);
19 | Graph filter (in TripleFilter filter);
20 | void forEach (in TripleCallback callback);
21 | Graph match (in any? subject, in any? predicate, in any? object, in optional unsigned long limit);
22 | Graph merge (in Graph graph);
23 | Graph addAll (in Graph graph);
24 | readonly attribute sequence actions;
25 | Graph addAction (in TripleAction action, in optional boolean run);
26 | };
27 |
28 | */
29 |
30 | /**
31 | * Read an RDF Collection and return it as an Array
32 | */
33 | var rdfnil = new RDFNode.NamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#nil');
34 | var rdffirst = new RDFNode.NamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#first');
35 | var rdfrest = new RDFNode.NamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#rest');
36 |
37 | function getKey(node){
38 | if(!node) return node;
39 | switch(node.termType){
40 | case 'Literal': return node.datatype + node.language + ' ' + node.value;
41 | }
42 | return node.value;
43 | }
44 |
45 | function isIndex(i, a, b, c, t){
46 | if(!i[a]) return false;
47 | if(!i[a][b]) return false;
48 | return i[a][b][c] ? i[a][b][c].equals(t) : false ;
49 | }
50 |
51 | function insertIndex(i, a, b, c, t){
52 | if(!i[a]) i[a] = {};
53 | if(!i[a][b]) i[a][b] = {};
54 | i[a][b][c] = t;
55 | }
56 |
57 | function deleteIndex(i, a, b, c, t){
58 | if(i[a]&&i[a][b]&&i[a][b][c]){
59 | if(!i[a][b][c].equals(t)) throw new Error('assertion fail: deleted triple mismatch');
60 | delete(i[a][b][c]);
61 | if(!Object.keys(i[a][b]).length) delete(i[a][b]);
62 | if(!Object.keys(i[a]).length) delete(i[a]);
63 | }
64 | }
65 |
66 | exports.Graph = Graph;
67 | function Graph(init){
68 | this.clear();
69 | //this._actions = [];
70 | Object.defineProperty(this, 'size', {get: function(){return self.length;}});
71 | var self = this;
72 | if(init && init.forEach){
73 | init.forEach(function(t){ self.add(t); });
74 | }
75 | }
76 | Graph.prototype.length = null;
77 | Graph.prototype.graph = null;
78 |
79 | Graph.prototype.importArray = function(a) { while( a.length > 0) { this.add(a.pop()); } };
80 |
81 | Graph.prototype.insertIndex = insertIndex;
82 | Graph.prototype.deleteIndex = deleteIndex;
83 | Graph.prototype.add = function(triple) {
84 | if(!(triple instanceof RDFNode.Triple)) throw new TypeError('Expected a Triple for argument[0] `triple`');
85 | var st=getKey(triple.subject), pt=getKey(triple.predicate), ot=getKey(triple.object);
86 | if(isIndex(this.indexSOP, st, ot, pt, triple)) return;
87 | insertIndex(this.indexOPS, ot, pt, st, triple);
88 | insertIndex(this.indexPSO, pt, st, ot, triple);
89 | insertIndex(this.indexSOP, st, ot, pt, triple);
90 | this.length++;
91 | //this.actions.forEach(function(fn){ fn(triple); });
92 | };
93 | Graph.prototype.addAll = function(g){
94 | var g2 = this;
95 | g.forEach(function(s){ g2.add(s); });
96 | };
97 | Graph.prototype.union = function union(g){
98 | var gx = new Graph;
99 | gx.addAll(this);
100 | gx.addAll(g);
101 | return gx;
102 | };
103 | Graph.prototype.merge = Graph.prototype.union;
104 | Graph.prototype.remove = function(triple) {
105 | var st=getKey(triple.subject), pt=getKey(triple.predicate), ot=getKey(triple.object);
106 | if(!isIndex(this.indexSOP, st, ot, pt, triple)) return;
107 | deleteIndex(this.indexOPS, ot, pt, st, triple);
108 | deleteIndex(this.indexPSO, pt, st, ot, triple);
109 | deleteIndex(this.indexSOP, st, ot, pt, triple);
110 | this.length--;
111 | };
112 | Graph.prototype.delete = Graph.prototype.remove;
113 | Graph.prototype.has = function(triple) {
114 | var st=getKey(triple.subject), pt=getKey(triple.predicate), ot=getKey(triple.object);
115 | return isIndex(this.indexSOP, st, ot, pt, triple);
116 | };
117 | Graph.prototype.removeMatches = function(s, p, o) {
118 | var graph = this;
119 | this.match(s, p, o).forEach(function(t) {
120 | graph.remove(t);
121 | });
122 | };
123 | Graph.prototype.deleteMatches = Graph.prototype.removeMatches;
124 | Graph.prototype.clear = function(){
125 | this.indexSOP = {};
126 | this.indexPSO = {};
127 | this.indexOPS = {};
128 | this.length = 0;
129 | };
130 | Graph.prototype.import = function(s) {
131 | var _g1 = 0, _g = s.length;
132 | while(_g1 < _g) {
133 | var i = _g1++;
134 | this.add(s.get(i));
135 | }
136 | };
137 | Graph.prototype.every = function every(filter) { return this.toArray().every(filter); };
138 | Graph.prototype.some = function some(filter) { return this.toArray().some(filter); };
139 | Graph.prototype.forEach = function forEach(callbck) { this.toArray().forEach(callbck); };
140 | Graph.prototype.toArray = function toArray() {
141 | var triples = [];
142 | var data = this.indexPSO;
143 | if(!data) return [];
144 | (function go(data, c){
145 | if(c) Object.keys(data).forEach(function(t){go(data[t], c-1);});
146 | else triples.push(data);
147 | })(data, 3);
148 | return triples;
149 | };
150 | Graph.prototype.filter = function filter(cb){
151 | var result = new Graph;
152 | this.forEach(function(triple){
153 | if(cb(triple)) result.add(triple);
154 | });
155 | return result;
156 | };
157 | Graph.prototype.getCollection = function getCollection(subject){
158 | var collection=[], seen=[];
159 | var first, rest=subject;
160 | while(rest && !rest.equals(rdfnil)){
161 | var g = this.match(rest, rdffirst, null);
162 | if(g.length===0) throw new Error('Collection <'+rest+'> is incomplete');
163 | first = g.toArray().map(function(v){return v.object;})[0];
164 | if(seen.indexOf(rest.toString())!==-1) throw new Error('Collection <'+rest+'> is circular');
165 | seen.push(rest.toString());
166 | collection.push(first);
167 | rest = this.match(rest, rdfrest, null).toArray().map(function(v){return v.object;})[0];
168 | }
169 | return collection;
170 | };
171 | // FIXME this should return a Graph, not an Array
172 | // FIXME ensure that the RDFNode#equals semantics are met
173 | Graph.prototype.match = function match(subject, predicate, object){
174 | if(typeof subject=="string") subject = new RDFNode.NamedNode(subject);
175 | if(subject!==null && !RDFNode.RDFNode.is(subject)) throw new Error('match subject is not an RDFNode');
176 | if(subject!==null && subject.termType!=='NamedNode' && subject.termType!=='BlankNode') throw new Error('match subject must be a NamedNode/BlankNode');
177 | if(typeof predicate=="string") predicate = new RDFNode.NamedNode(predicate);
178 | if(predicate!==null && !RDFNode.RDFNode.is(predicate)) throw new Error('match predicate is not an RDFNode');
179 | if(predicate!==null && predicate.termType!=='NamedNode') throw new Error('match predicate must be a NamedNode');
180 | if(typeof object=="string") object = new RDFNode.NamedNode(object);
181 | if(object!==null && !RDFNode.RDFNode.is(object)) throw new Error('match object is not an RDFNode');
182 | if(object!==null && object.termType!=='NamedNode' && object.termType!=='BlankNode' && object.termType!=='Literal') throw new Error('match object must be a NamedNode/BlankNode/Literal');
183 | var triples = new Graph;
184 | var pattern = {s:subject&&getKey(subject), p:predicate&&getKey(predicate), o:getKey(object)};
185 | var patternIndexMap = [
186 | {index:this.indexOPS, constants:["o", "p", "s"], variables:[]},
187 | {index:this.indexPSO, constants:["p", "s"], variables:["o"]},
188 | {index:this.indexSOP, constants:["s", "o"], variables:["p"]},
189 | {index:this.indexSOP, constants:["s"], variables:["o", "p"]},
190 | {index:this.indexOPS, constants:["o", "p"], variables:["s"]},
191 | {index:this.indexPSO, constants:["p"], variables:["s", "o"]},
192 | {index:this.indexOPS, constants:["o"], variables:["p", "s"]},
193 | {index:this.indexPSO, constants:[], variables:["p", "s", "o"]},
194 | ];
195 | var patternType = 0;
196 | if(!pattern.s) patternType |= 4;
197 | if(!pattern.p) patternType |= 2;
198 | if(!pattern.o) patternType |= 1;
199 | var index = patternIndexMap[patternType];
200 | var data = index.index;
201 | index.constants.forEach(function(v){if(data) data=data[pattern[v]];});
202 | if(!data) return triples;
203 | (function go(data, c){
204 | if(c) return void Object.keys(data).forEach(function(t){go(data[t], c-1);});
205 | if(subject && !data.subject.equals(subject)) throw new Error('assertion fail: subject');
206 | if(predicate && !data.predicate.equals(predicate)) throw new Error('assertion fail: predicate');
207 | if(object && !data.object.equals(object)) throw new Error('assertion fail: object');
208 | triples.add(data);
209 | })(data, index.variables.length);
210 | return triples;
211 | };
212 |
213 | var GraphEquals = require('./GraphEquals.js');
214 | Graph.prototype.isomorphic = function isomorphic(b){
215 | return GraphEquals(this, b);
216 | };
217 | Graph.prototype.equals = function equals(b){
218 | return GraphEquals(this, b);
219 | };
220 | var GraphSimplyEntails = require('./GraphSimplyEntails.js');
221 | Graph.prototype.simplyEntails = function simplyEntails(subset){
222 | var reference = this;
223 | return GraphSimplyEntails(reference, subset);
224 | };
225 |
226 | //Graph.prototype.addAction = function(action, run){
227 | // this._actions.push(action);
228 | // if(run){
229 | // this.forEach(action);
230 | // }
231 | //}
232 | //
233 | //Object.defineProperty(Graph.prototype, 'actions', { get: function(){ return this._actions; } });
234 |
235 | // Gets a reference to a particular subject
236 | Graph.prototype.reference = function reference(subject){
237 | return new ResultSet.ResultSet(this, subject);
238 | };
239 |
--------------------------------------------------------------------------------
/lib/GraphEquals.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | module.exports = GraphEquals;
4 | function GraphEquals(a, b, depth){
5 | if(typeof a.length!='number') throw new Error('Expected an RDFGraph for argument `a`');
6 | if(typeof b.length!='number') throw new Error('Expected an RDFGraph for argument `b`');
7 | if(a.length!==b.length) return false;
8 | if(a.length<=0) throw new Error('Expected a nonempty RDFGraph');
9 | var al = a.toArray();
10 | var bl = b.toArray();
11 | //if(!a.every(function(s))) return false;
12 | var stack = [ {i:0, depth:0, bindings:{}} ];
13 | // Iterate through each statement in `a`
14 | // test that named nodes/literals/bound bnodes have a match in the other document
15 | // For each bnode encountered in the statement that's unbound, determine every possible binding and recurse
16 | while(stack.length){
17 | // If `depth` starts as 0 this will never be hit
18 | if(--depth===0) throw new Error('Hit search limit');
19 | var state = stack.pop();
20 | if(state.i===al.length) return state.bindings;
21 | var stmt = al[state.i];
22 | // If it's a bnode, then map it. If it's not mapped, use `null` to search for any values.
23 | // in theory the predicate will never be a bnode, but the additional test shouldn't hurt anything
24 | var stmtsubject = stmt.subject.nodeType()==='BlankNode' ? (state.bindings[stmt.subject] || null) : stmt.subject ;
25 | var stmtpredicate = stmt.predicate.nodeType()==='BlankNode' ? (state.bindings[stmt.predicate] || null) : stmt.predicate ;
26 | var stmtobject = stmt.object.nodeType()==='BlankNode' ? (state.bindings[stmt.object] || null) : stmt.object ;
27 | var matches = b.match(stmtsubject, stmtpredicate, stmtobject).filter(function(m){
28 | // wildcards must only match bnodes
29 | // The predicate should never be a bnode, so skip over that code path for now
30 | if(stmtsubject===null && m.subject.nodeType()!=='BlankNode') return false;
31 | //if(stmtpredicate===null && m.predicate.nodeType()!=='BlankNode') return false;
32 | if(stmtobject===null && m.object.nodeType()!=='BlankNode') return false;
33 | return true;
34 | });
35 | if(stmtsubject && stmtpredicate && stmtobject){
36 | if(matches.length===1){
37 | // if there's a single match where all nodes match exactly, push the comparison for the next item
38 | stack.push({ i:state.i+1, depth:state.depth, bindings:state.bindings });
39 | }else if(matches.length===0){
40 | continue;
41 | }else{
42 | throw new Error('Multiple matches, expected exactly one or zero match');
43 | }
44 | }else{
45 | // otherwise there's an unbound bnode, get the possible mappings and push those onto the stack
46 | matches.forEach(function(match){
47 | var b2 = {};
48 | var depth = state.depth;
49 | for(var n in state.bindings) b2[n] = state.bindings[n];
50 | if(stmtsubject===null){
51 | if(b2[stmt.subject]===undefined){
52 | for(var n in b2) if(b2[n]===match.subject) return;
53 | b2[stmt.subject] = match.subject;
54 | depth++;
55 | }else{
56 | throw new Error('bnode already mapped');
57 | }
58 | }
59 | // if(stmtpredicate===null && b2[stmt.predicate]===undefined){
60 | // if(b2[stmt.predicate]===undefined){
61 | // for(var n in b2) if(b2[n]===match.predicate) return;
62 | // b2[stmt.predicate] = match.predicate;
63 | // depth++;
64 | // }else{
65 | // throw new Error('bnode already mapped');
66 | // }
67 | // }
68 | if(stmtobject===null){
69 | if(b2[stmt.object]===undefined){
70 | for(var n in b2) if(b2[n]===match.object) return;
71 | b2[stmt.object] = match.object;
72 | depth++;
73 | }else{
74 | throw new Error('bnode already mapped');
75 | }
76 | }
77 | stack.push({ i:state.i, depth:depth, bindings:b2 });
78 | });
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/lib/GraphSimplyEntails.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | // Verify that `ref` simply entails `tst`
4 | // According to RDF 1.1 Semantics, this is true iff a subgraph of `ref` is an instance of `tst`
5 | // Go through every triple in `tst` and map bnodes to nodes in `ref`
6 |
7 | module.exports = GraphSimplyEntails;
8 | function GraphSimplyEntails(ref, tst, depth){
9 | if(typeof ref.length!='number') throw new Error('Expected an RDFGraph for argument `ref`');
10 | if(typeof tst.length!='number') throw new Error('Expected an RDFGraph for argument `tst`');
11 | if(tst.length > ref.length) return false;
12 | var tstl = tst.toArray();
13 | //if(!a.every(function(s))) return false;
14 | var stack = [ {i:0, depth:0, bindings:{}} ];
15 | // Iterate through each statement in `a`
16 | // test that named nodes/literals/bound bnodes have a match in the other document
17 | // For each bnode encountered in the statement that's unbound, determine every possible binding and recurse
18 | while(stack.length){
19 | // If `depth` starts as 0 this will never be hit
20 | if(--depth===0) throw new Error('Hit search limit');
21 | var state = stack.pop();
22 | if(state.i===tstl.length) return state.bindings;
23 | var stmt = tstl[state.i];
24 | // If it's a bnode, then map it. If it's not mapped, use `null` to search for any values.
25 | // in theory the predicate will never be a bnode, but the additional test shouldn't hurt anything
26 | var stmtsubject = stmt.subject.termType==='BlankNode' ? (state.bindings[stmt.subject] || null) : stmt.subject ;
27 | var stmtpredicate = stmt.predicate.termType==='BlankNode' ? (state.bindings[stmt.predicate] || null) : stmt.predicate ;
28 | var stmtobject = stmt.object.termType==='BlankNode' ? (state.bindings[stmt.object] || null) : stmt.object ;
29 | var matches = ref.match(stmtsubject, stmtpredicate, stmtobject).filter(function(m){
30 | // wildcards must only match bnodes
31 | // The predicate should never be a bnode, so skip over that code path for now
32 | // if(stmtsubject===null && (m.subject.termType!=='BlankNode' && m.subject.termType!=='NamedNode')) return false;
33 | //if(stmtpredicate===null && (m.predicate.termType!=='BlankNode' && m.predicate.termType!=='NamedNode')) return false;
34 | // if(stmtobject===null && (m.object.termType!=='BlankNode' && m.object.termType!=='NamedNode' && m.object.termType!=='Literal')) return false;
35 | return true;
36 | });
37 | if(stmtsubject && stmtpredicate && stmtobject){
38 | if(matches.length===1){
39 | // if there's a single match where all nodes match exactly, push the comparison for the next item
40 | stack.push({ i:state.i+1, depth:state.depth, bindings:state.bindings });
41 | }else if(matches.length===0){
42 | continue;
43 | }else{
44 | throw new Error('Multiple matches, expected exactly one or zero match');
45 | }
46 | }else{
47 | // otherwise there's an unbound bnode, get the possible mappings and push those onto the stack
48 | matches.forEach(function(match){
49 | var b2 = {};
50 | var depth = state.depth;
51 | for(var n in state.bindings) b2[n] = state.bindings[n];
52 | if(stmtsubject===null){
53 | if(b2[stmt.subject]===undefined){
54 | for(var n in b2) if(b2[n]===match.subject) return;
55 | b2[stmt.subject] = match.subject;
56 | depth++;
57 | }else{
58 | throw new Error('bnode already mapped');
59 | }
60 | }
61 | // if(stmtpredicate===null && b2[stmt.predicate]===undefined){
62 | // if(b2[stmt.predicate]===undefined){
63 | // for(var n in b2) if(b2[n]===match.predicate) return;
64 | // b2[stmt.predicate] = match.predicate;
65 | // depth++;
66 | // }else{
67 | // throw new Error('bnode already mapped');
68 | // }
69 | // }
70 | if(stmtobject===null){
71 | if(b2[stmt.object]===undefined){
72 | for(var n in b2) if(b2[n]===match.object) return;
73 | b2[stmt.object] = match.object;
74 | depth++;
75 | }else{
76 | throw new Error('bnode already mapped');
77 | }
78 | }
79 | stack.push({ i:state.i, depth:depth, bindings:b2 });
80 | });
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/lib/Profile.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | /** Implements interfaces from http://www.w3.org/TR/2011/WD-rdf-interfaces-20110510/ */
4 |
5 | var api = exports;
6 |
7 | var NamedNode = require("./RDFNode.js").NamedNode;
8 |
9 | api.SCHEME_MATCH = new RegExp("^[a-z0-9-.+]+:", "i");
10 |
11 | // This is the same as the XML NCName
12 | // Note how [\uD800-\uDBFF][\uDC00-\uDFFF] is a surrogate pair that encodes #x10000-#xEFFFF
13 | api.CURIE_PREFIX = new RegExp("^([A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]|[\uD800-\uDBFF][\uDC00-\uDFFF])([A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD.0-9\u00B7\u0300-\u036F\u203F-\u2040\\-]|[\uD800-\uDBFF][\uDC00-\uDFFF])*$", "i");
14 |
15 |
16 | // For implementations that don't have Map defined...???
17 | function GoodEnoughMap(){
18 | this.map = {};
19 | }
20 | GoodEnoughMap.prototype.has = function has(key){
21 | return Object.hasOwnProperty.call(this.map, key+':');
22 | };
23 | GoodEnoughMap.prototype.get = function get(key){
24 | return Object.hasOwnProperty.call(this.map, key+':') ? this.map[key+':'] : undefined;
25 | };
26 | GoodEnoughMap.prototype.set = function set(key, value){
27 | // Store with some suffix to avoid certain magic keywords
28 | this.map[key+':'] = value;
29 | };
30 | GoodEnoughMap.prototype.delete = function del(key){
31 | delete this.map[key+':'];
32 | };
33 | GoodEnoughMap.prototype.forEach = function forEach(it){
34 | var map = this.map;
35 | Object.keys(this.map).forEach(function(k){
36 | it(map[k], k.substring(0, k.length-1));
37 | });
38 | };
39 | var StringMap = (typeof Map=='function') ? Map : GoodEnoughMap ;
40 |
41 | /**
42 | * Implements PrefixMap http://www.w3.org/TR/2011/WD-rdf-interfaces-20110510/#idl-def-PrefixMap
43 | */
44 | api.PrefixMap = function PrefixMap(){
45 | this.prefixMap = new StringMap;
46 | };
47 | api.PrefixMap.prototype.get = function(prefix){
48 | // strip a trailing ":"
49 | if(prefix.slice(-1)==":") prefix=prefix.slice(0, -1);
50 | return this.prefixMap.get(prefix);
51 | };
52 | api.PrefixMap.prototype.set = function(prefix, iri){
53 | // strip a trailing ":"
54 | if(prefix.slice(-1)==":") prefix=prefix.slice(0, -1);
55 | if(typeof prefix!='string') throw new TypeError('Expected a string argument[0] `prefix`');
56 | if(iri===null) return void this.prefixMap.delete(prefix);
57 | if(typeof iri!='string') throw new TypeError('Expected a string argument[1] `iri`');
58 | if(prefix.length && !api.CURIE_PREFIX.exec(prefix)) throw new Error('Invalid prefix name');
59 | this.prefixMap.set(prefix, iri);
60 | };
61 | api.PrefixMap.prototype.list = function(){
62 | var list = [];
63 | this.prefixMap.forEach(function(expansion, prefix){
64 | list.push(prefix);
65 | });
66 | return list;
67 | };
68 | api.PrefixMap.prototype.remove = function(prefix){
69 | this.prefixMap.delete(prefix);
70 | };
71 | api.PrefixMap.prototype.resolve = function(curie){
72 | var index = curie.indexOf(":");
73 | if(index<0) return null;
74 | var prefix = curie.slice(0, index);
75 | var iri = this.get(prefix);
76 | if(!iri) return null;
77 | var resolved = iri.concat(curie.slice(index+1));
78 | if(resolved.match(api.SCHEME_MATCH)==null && this.base!=null){
79 | resolved = this.base.resolveReference(resolved);
80 | }
81 | return resolved.toString();
82 | };
83 | api.PrefixMap.prototype.shrink = function(uri) {
84 | if(typeof uri!='string') throw new TypeError('Expected string arguments[0] `uri`');
85 | var shrunk = uri;
86 | var matchedLen = '';
87 | this.prefixMap.forEach(function(expansion, prefix){
88 | if(uri.substr(0,expansion.length)==expansion && expansion.length>matchedLen){
89 | shrunk = prefix + ':' + uri.substring(expansion.length);
90 | matchedLen = expansion.length;
91 | }
92 | });
93 | return shrunk;
94 | };
95 | api.PrefixMap.prototype.setDefault = function(uri){
96 | this.set('', uri);
97 | };
98 | api.PrefixMap.prototype.addAll = function(prefixes, override){
99 | var localPrefixMap = this.prefixMap;
100 | if(override){
101 | prefixes.prefixMap.forEach(function(expansion, prefix){
102 | localPrefixMap.set(prefix, expansion);
103 | });
104 | }else{
105 | prefixes.prefixMap.forEach(function(expansion, prefix){
106 | if(!localPrefixMap.has(prefix)) localPrefixMap.set(prefix, expansion);
107 | });
108 | }
109 | };
110 |
111 | /**
112 | * Implements TermMap http://www.w3.org/TR/2011/WD-rdf-interfaces-20110510/#idl-def-TermMap
113 | */
114 | api.TermMap = function TermMap(){
115 | this.termMap = new StringMap;
116 | this.vocabulary = null;
117 | };
118 | api.TermMap.prototype.get = function(term){
119 | return this.termMap.get(term);
120 | };
121 | api.TermMap.prototype.set = function(term, iri){
122 | if(typeof term!='string') throw new TypeError('Expected a string argument[0] `prefix`');
123 | if(iri===null) return void this.termMap.delete(term);
124 | if(typeof iri!='string') throw new TypeError('Expected a string argument[1] `iri`');
125 | if(!api.CURIE_PREFIX.exec(term)) throw new Error('Invalid term name');
126 | this.termMap.set(term, iri);
127 | };
128 | api.TermMap.prototype.list = function(){
129 | var list = [];
130 | this.termMap.forEach(function(definition, term){
131 | list.push(term);
132 | });
133 | return list;
134 | };
135 | api.TermMap.prototype.remove = function(term){
136 | this.termMap.delete(term);
137 | };
138 | api.TermMap.prototype.resolve = function(term){
139 | var expansion = this.termMap.get(term);
140 | if(typeof expansion=='string') return expansion;
141 | if(typeof this.vocabulary=='string') return this.vocabulary+term;
142 | return null;
143 | };
144 | api.TermMap.prototype.shrink = function(uri){
145 | var shrunk = uri;
146 | this.termMap.forEach(function(definition, term){
147 | if(uri==definition){
148 | shrunk = term;
149 | }
150 | });
151 | if(typeof this.vocabulary==='string' && uri.substring(0, this.vocabulary.length)===this.vocabulary){
152 | return uri.substring(this.vocabulary.length);
153 | }
154 | return shrunk;
155 | };
156 | api.TermMap.prototype.setDefault = function(uri){
157 | this.vocabulary = (uri==='') ? null : uri;
158 | };
159 | api.TermMap.prototype.addAll = function(terms, override){
160 | var termMap = this.termMap;
161 | if(override){
162 | terms.termMap.forEach(function(definition, term){
163 | termMap.set(term, definition);
164 | });
165 | }else{
166 | terms.termMap.forEach(function(definition, term){
167 | if(!termMap.has(term)) termMap.set(term, definition);
168 | });
169 | }
170 | };
171 |
172 | /**
173 | * Implements Profile http://www.w3.org/TR/2011/WD-rdf-interfaces-20110510/#idl-def-Profile
174 | */
175 | api.Profile = function Profile() {
176 | this.prefixes = new api.PrefixMap;
177 | this.terms = new api.TermMap;
178 | };
179 | api.Profile.prototype.resolve = function(toresolve){
180 | if(toresolve.indexOf(":")<0) return this.terms.resolve(toresolve);
181 | else return this.prefixes.resolve(toresolve);
182 | };
183 | api.Profile.prototype.setDefaultVocabulary = function(uri){
184 | this.terms.setDefault(uri);
185 | };
186 | api.Profile.prototype.setDefaultPrefix = function(uri){
187 | this.prefixes.setDefault(uri);
188 | };
189 | api.Profile.prototype.setTerm = function(term, uri){
190 | this.terms.set(term, uri);
191 | };
192 | api.Profile.prototype.setPrefix = function(prefix, uri){
193 | this.prefixes.set(prefix, uri);
194 | };
195 | api.Profile.prototype.shrink = function(uri){
196 | return this.terms.shrink(this.prefixes.shrink(uri));
197 | };
198 | api.Profile.prototype.importProfile = function(profile, override){
199 | this.prefixes.addAll(profile.prefixes, override);
200 | this.terms.addAll(profile.terms, override);
201 | };
202 |
--------------------------------------------------------------------------------
/lib/RDFEnvironment.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var NamedNode = require("./RDFNode.js").NamedNode;
4 | var BlankNode = require("./RDFNode.js").BlankNode;
5 | var Literal = require("./RDFNode.js").Literal;
6 | var Triple = require("./RDFNode.js").Triple;
7 | var Graph = require("./Graph.js").Graph;
8 | var Profile = require("./Profile.js").Profile;
9 | var PrefixMap = require("./Profile.js").PrefixMap;
10 | var TermMap = require("./Profile.js").TermMap;
11 | var loadRequiredPrefixMap = require("./prefixes.js").loadRequiredPrefixMap;
12 |
13 | /**
14 | * Implements RDFEnvironment http://www.w3.org/TR/2011/WD-rdf-interfaces-20110510/#idl-def-RDFEnvironment
15 | */
16 | exports.RDFEnvironment = function RDFEnvironment(){
17 | Profile.call(this);
18 | loadRequiredPrefixMap(this);
19 | };
20 | exports.RDFEnvironment.prototype = Object.create(Profile.prototype, {constructor:{value:exports.RDFEnvironment, iterable:false}});
21 | exports.RDFEnvironment.prototype.createBlankNode = function(){
22 | return new BlankNode;
23 | };
24 | exports.RDFEnvironment.prototype.createNamedNode = function(v){
25 | return new NamedNode(v);
26 | };
27 | exports.RDFEnvironment.prototype.createLiteral = function(value, datatype, _dt){
28 | if(typeof value!='string') throw new Error('Expected argument[0] `value` to be a string');
29 | if(datatype!==undefined && datatype!==null && typeof datatype!=='string' && !(datatype instanceof NamedNode)) throw new TypeError('Expected optional argument[1] `datatype` to be a string');
30 | if(_dt!==undefined && _dt!==null && typeof _dt!=='string' && !(_dt instanceof NamedNode)) throw new TypeError('Expected optional argument[2] `_dt` to be a string');
31 | if(datatype instanceof NamedNode){
32 | return new Literal(value, datatype);
33 | }else if(typeof datatype=='string' && (_dt==null || _dt==undefined || _dt=='http://www.w3.org/1999/02/22-rdf-syntax-ns#langString')){
34 | // Process arguments as a typed and/or language literal
35 | return new Literal(value, datatype);
36 | }else if((datatype==null || datatype==undefined) && _dt){
37 | // Process arguments as a typed literal
38 | return Literal.typed(value, _dt);
39 | }
40 | return new Literal(value);
41 | };
42 | exports.RDFEnvironment.prototype.createTypedLiteral = function(value, datatype){
43 | return Literal.typed(value, datatype);
44 | };
45 | exports.RDFEnvironment.prototype.createLanguageLiteral = function(value, language){
46 | return Literal.language(value, language);
47 | };
48 | exports.RDFEnvironment.prototype.createTriple = function(s,p,o){
49 | return new Triple(s,p,o);
50 | };
51 | exports.RDFEnvironment.prototype.createGraph = function(g){
52 | return new Graph(g);
53 | };
54 | //exports.RDFEnvironment.prototype.createAction = function(){
55 | // return new Action;
56 | //}
57 | exports.RDFEnvironment.prototype.createProfile = function(){
58 | return new Profile;
59 | };
60 | exports.RDFEnvironment.prototype.createTermMap = function(){
61 | return new TermMap;
62 | };
63 | exports.RDFEnvironment.prototype.createPrefixMap = function(){
64 | return new PrefixMap;
65 | };
66 |
--------------------------------------------------------------------------------
/lib/RDFNode.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var encodeString = require('./encodeString.js');
4 | var api = exports;
5 |
6 | function inherits(ctor, superCtor) {
7 | //ctor.super_ = superCtor;
8 | ctor.prototype = Object.create(superCtor.prototype, {
9 | constructor: { value: ctor, enumerable: false },
10 | });
11 | }
12 |
13 | function nodeType(v){
14 | if(v.nodeType) return v.nodeType();
15 | if(typeof v=='string') return (v.substr(0,2)=='_:')?'BlankNode':'IRI';
16 | return 'TypedLiteral';
17 | }
18 | api.nodeType = nodeType;
19 |
20 | function RDFNodeEquals(other) {
21 | if(typeof other=='string'){
22 | return this.termType=="NamedNode" && this.value==other;
23 | }
24 | if(api.RDFNode.is(other)){
25 | if(nodeType(this)!=nodeType(other)) return false;
26 | switch(this.termType) {
27 | case "BlankNode":
28 | case "NamedNode":
29 | case "Variable":
30 | case "DefaultGraph":
31 | return this.toString()==other.toString();
32 | case "Literal":
33 | return ( this.language==other.language
34 | && this.nominalValue==other.nominalValue
35 | && this.datatype.toString()==other.datatype.toString()
36 | );
37 | }
38 | if(typeof this.toNT=='function' && typeof other.toNT=='function'){
39 | return this.toNT() == other.toNT();
40 | }
41 | }
42 | //throw new Error('Cannot compare values');
43 | return false;
44 | }
45 | api.RDFNodeEquals = RDFNodeEquals;
46 |
47 | function RDFNodeCompare(other) {
48 | // Node type order: IRI, BlankNode, Literal
49 | var typeThis=this.termType, typeOther=other.termType;
50 | if(typeThis != typeOther){
51 | switch(typeThis) {
52 | case "IRI":
53 | case "NamedNode":
54 | // must be a BlankNode or Literal
55 | return -1;
56 | case "BlankNode":
57 | if(typeOther=="Literal") return -1;
58 | else return 1;
59 | case "Literal":
60 | return 1;
61 | }
62 | throw new Error(typeThis);
63 | }
64 | // node types are the same, compare nomialValue
65 | if(typeof this.nominalValue=='string' && typeof other.nominalValue=='string'){
66 | if(this.nominalValue < other.nominalValue) return -1;
67 | if(this.nominalValue > other.nominalValue) return 1;
68 | }
69 | // values are the same, compare by datatype
70 | if(typeof this.datatype=='string' && typeof other.datatype=='string'){
71 | if(this.datatype < other.datatype) return -1;
72 | if(this.datatype > other.datatype) return 1;
73 | }
74 | if(typeof this.language=='string' || typeof other.language=='string'){
75 | if(typeof this.language=='string' && typeof other.language=='string'){
76 | if(this.language < other.language) return -1;
77 | if(this.language > other.language) return 1;
78 | }else{
79 | if(other.language) return -1;
80 | if(this.language) return 1;
81 | }
82 | }
83 | // Compare by any other metric?
84 | if(typeof this.valueOf=='function'){
85 | if(this.valueOf() < other) return -1;
86 | if(this.valueOf() > other) return 1;
87 | //if(this.valueOf() == other) return 0;
88 | }
89 | if(this.equals(other)) return 0;
90 | throw new Error('Cannot compare values');
91 | }
92 | api.RDFNodeEquals = RDFNodeEquals;
93 |
94 | /**
95 | * Implements Triple http://www.w3.org/TR/2011/WD-rdf-interfaces-20110510/#idl-def-Triple
96 | */
97 | api.Triple = function Triple(s, p, o) {
98 | if(typeof s=='string') s = new NamedNode(s);
99 | if(!api.RDFNode.is(s)) throw new Error('Triple subject is not an RDFNode');
100 | if(s.termType!=='NamedNode' && s.termType!=='BlankNode') throw new Error('subject must be a NamedNode/BlankNode');
101 |
102 | if(typeof p=='string') p = new NamedNode(p);
103 | if(!api.RDFNode.is(p)) throw new Error('Triple predicate is not an RDFNode');
104 | if(p.termType!=='NamedNode') throw new Error('predicate must be a NamedNode');
105 |
106 | if(typeof o=='string') o = new NamedNode(o);
107 | if(!api.RDFNode.is(o)) throw new Error('Triple object is not an RDFNode');
108 | if(o.termType!=='NamedNode' && o.termType!=='BlankNode' && o.termType!=='Literal') throw new Error('object must be a NamedNode/BlankNode/Literal');
109 |
110 | this.subject = s;
111 | this.predicate = p;
112 | this.object = o;
113 | };
114 | api.Triple.prototype.size = 3;
115 | api.Triple.prototype.length = 3;
116 | api.Triple.prototype.toString = function() {
117 | return this.subject.toNT() + " " + this.predicate.toNT() + " " + this.object.toNT() + " .";
118 | };
119 | api.Triple.prototype.toNT = function toNT() {
120 | return this.subject.toNT() + " " + this.predicate.toNT() + " " + this.object.toNT() + " .";
121 | };
122 | api.Triple.prototype.toTurtle = function toTurtle(profile) {
123 | return this.subject.toTurtle(profile) + " " + this.predicate.toTurtle(profile) + " " + this.object.toTurtle(profile) + " .";
124 | };
125 | api.Triple.prototype.equals = function(t) {
126 | return RDFNodeEquals.call(this.subject,t.subject) && RDFNodeEquals.call(this.predicate,t.predicate) && RDFNodeEquals.call(this.object,t.object);
127 | };
128 | api.Triple.prototype.compare = function(other) {
129 | var r = 0;
130 | // test the return value, also assign to `r`
131 | if(r = this.subject.compare(other.subject)) return r;
132 | if(r = this.predicate.compare(other.predicate)) return r;
133 | if(r = this.object.compare(other.object)) return r;
134 | };
135 |
136 | /**
137 | */
138 | api.Quad = function Quad(s, p, o, g) {
139 | if(typeof s=='string') s = new NamedNode(s);
140 | if(!api.RDFNode.is(s)) throw new Error('Quad subject is not an RDFNode');
141 | if(s.termType!=='NamedNode' && s.termType!=='BlankNode') throw new Error('`subject` must be a NamedNode/BlankNode');
142 |
143 | if(typeof p=='string') p = new NamedNode(p);
144 | if(!api.RDFNode.is(p)) throw new Error('Quad predicate is not an RDFNode');
145 | if(p.termType!=='NamedNode') throw new Error('`predicate` must be a NamedNode');
146 |
147 | if(typeof o=='string') o = new NamedNode(o);
148 | if(!api.RDFNode.is(o)) throw new Error('Quad object is not an RDFNode');
149 | if(o.termType!=='NamedNode' && o.termType!=='BlankNode' && o.termType!=='Literal') throw new Error('`object` must be a NamedNode/BlankNode/Literal');
150 |
151 | if(typeof g=='string') g = new NamedNode(g);
152 | if(!api.RDFNode.is(g)) throw new Error('Quad graph is not an RDFNode');
153 | if(g.termType!=='NamedNode' && g.termType!=='DefaultGraph') throw new Error('Quad `graph` must be a NamedNode/DefaultGraph');
154 |
155 | this.subject = s;
156 | this.predicate = p;
157 | this.object = o;
158 | this.graph = g;
159 | };
160 | api.Quad.prototype.size = 4;
161 | api.Quad.prototype.length = 4;
162 | api.Quad.prototype.toString = function() {
163 | return this.toNQ();
164 | };
165 | api.Quad.prototype.toNT = function toNT() {
166 | return this.subject.toNT() + " " + this.predicate.toNT() + " " + this.object.toNT() + " .";
167 | };
168 | api.Quad.prototype.toNQ = function toNQ() {
169 | if(this.graph){
170 | return this.subject.toNT() + " " + this.predicate.toNT() + " " + this.object.toNT() + " " + this.graph.toNT() + " .";
171 | }else{
172 | // the NT form is compatible with N-Quads
173 | return this.toNT();
174 | }
175 | };
176 | api.Quad.prototype.toTurtle = function toTurtle(profile) {
177 | return this.subject.toTurtle(profile) + " " + this.predicate.toTurtle(profile) + " " + this.object.toTurtle(profile) + " .";
178 | };
179 | api.Quad.prototype.equals = function(t) {
180 | return RDFNodeEquals.call(this.subject,t.subject) && RDFNodeEquals.call(this.predicate,t.predicate) && RDFNodeEquals.call(this.object,t.object) && RDFNodeEquals.call(this.graph,t.graph);
181 | };
182 | api.Quad.prototype.compare = function(other) {
183 | var r = 0;
184 | // test the return value, also assign to `r`
185 | if(r = this.subject.compare(other.subject)) return r;
186 | if(r = this.predicate.compare(other.predicate)) return r;
187 | if(r = this.object.compare(other.object)) return r;
188 | if(r = this.graph.compare(other.graph)) return r;
189 | };
190 |
191 | /**
192 | * Implements RDFNode http://www.w3.org/TR/2011/WD-rdf-interfaces-20110510/#idl-def-RDFNode
193 | */
194 | api.RDFNode = function RDFNode() {};
195 | api.RDFNode.is = function isRDFNode(n){
196 | if(!n) return false;
197 | if(n instanceof api.RDFNode) return true;
198 | if(typeof n.nodeType=='function') return true;
199 | return false;
200 | };
201 | api.RDFNode.prototype.equals = api.RDFNodeEquals = RDFNodeEquals;
202 | api.RDFNode.prototype.compare = api.RDFNodeCompare = RDFNodeCompare;
203 | api.RDFNode.prototype.nodeType = function() { return "RDFNode"; };
204 | api.RDFNode.prototype.toNT = function() { return ""; };
205 | api.RDFNode.prototype.toCanonical = function() { return this.toNT(); };
206 | api.RDFNode.prototype.toString = function() { return this.nominalValue; };
207 | api.RDFNode.prototype.valueOf = function() { return this.nominalValue; };
208 | // Alignment to "Interface Specification: RDF Representation"
209 | Object.defineProperty(api.RDFNode.prototype, 'value', { get: function(){
210 | return this.nominalValue;
211 | } });
212 |
213 | /**
214 | * BlankNode
215 | */
216 | api.BlankNode = BlankNode;
217 | inherits(api.BlankNode, api.RDFNode);
218 | function BlankNode(id) {
219 | if(typeof id=='string' && id.substr(0,2)=='_:') this.nominalValue=id.substr(2);
220 | else if(id) this.nominalValue=id;
221 | else this.nominalValue = 'b'+(++api.BlankNode.NextId).toString();
222 | }
223 | api.BlankNode.NextId = 0;
224 | api.BlankNode.prototype.nodeType = function() { return "BlankNode"; };
225 | api.BlankNode.prototype.interfaceName = "BlankNode";
226 | api.BlankNode.prototype.termType = "BlankNode";
227 | api.BlankNode.prototype.toNT = function() {
228 | return "_:"+this.nominalValue;
229 | };
230 | api.BlankNode.prototype.toTurtle = function toTurtle() {
231 | return this.toNT();
232 | };
233 | api.BlankNode.prototype.n3 = function() {
234 | return this.toNT();
235 | };
236 | api.BlankNode.prototype.toString = function() {
237 | return "_:"+this.nominalValue;
238 | };
239 |
240 | /**
241 | * Implements Literal http://www.w3.org/TR/2011/WD-rdf-interfaces-20110510/#idl-def-Literal
242 | */
243 | api.Literal = Literal;
244 | inherits(api.Literal, api.RDFNode);
245 | function Literal(value, type) {
246 | if(typeof value!='string') throw new TypeError('Expected argument[0] `value` to be a string');
247 | if(type!==null && type!==undefined && typeof type!='string' && !(type instanceof api.NamedNode)) throw new TypeError('Expected optional argument[1] `type` to be a string/RDFNode');
248 | this.nominalValue = value;
249 | if(type instanceof NamedNode){
250 | this.datatype = type;
251 | this.language = null;
252 | }else if(typeof type=='string'){
253 | if(type.match(/^[a-zA-Z]+(-[a-zA-Z0-9]+)*$/)){
254 | this.datatype = rdflangString;
255 | this.language = type;
256 | }else if(type.match(/^@[a-zA-Z]+(-[a-zA-Z0-9]+)*$/)){
257 | this.datatype = rdflangString;
258 | this.language = type.substring(1);
259 | }else if(type.match(/^[a-zA-Z][a-zA-Z0-9+.\-]*:/)){
260 | this.datatype = new NamedNode(type);
261 | this.language = null;
262 | }else{
263 | throw new Error('Expected argument[1] `type` to look like a LangTag or IRI');
264 | }
265 | }else{
266 | this.datatype = xsdstring;
267 | this.language = null;
268 | }
269 | }
270 | api.Literal.typed = function createTypedLiteral(value, datatype){
271 | if(typeof value!='string') throw new Error('Expected argument[0] `value` to be a string');
272 | if(typeof datatype!='string' && !(datatype instanceof api.NamedNode)) throw new Error('Expected argument[1] `datatype` to be a string');
273 | if(!datatype.toString().match(/^[a-zA-Z][a-zA-Z0-9+.\-]*:/)) throw new Error('Expected argument[1] `datatype` to be an IRI');
274 | var literal = new api.Literal(value);
275 | if(datatype.toString()!=='http://www.w3.org/2001/XMLSchema#string'){
276 | literal.datatype = datatype;
277 | }
278 | return literal;
279 | };
280 | api.Literal.language = function createLanguageLiteral(value, language){
281 | if(typeof value!='string') throw new Error('Expected argument[0] `value` to be a string');
282 | if(typeof language!='string') throw new Error('Expected argument[1] `language` to be a string');
283 | if(!language.match(/^[a-zA-Z]+(-[a-zA-Z0-9]+)*$/)) throw new Error('Expected argument[1] `language` to be a BCP47 language tag');
284 | var literal = new api.Literal(value);
285 | literal.language = language;
286 | return literal;
287 | };
288 | api.Literal.prototype.nodeType = function() {
289 | if(rdflangString.equals(this.datatype) && this.language) return 'PlainLiteral';
290 | if(xsdstring.equals(this.datatype)) return 'PlainLiteral';
291 | return 'TypedLiteral';
292 | };
293 | api.Literal.prototype.interfaceName = "Literal";
294 | api.Literal.prototype.termType = "Literal";
295 | api.Literal.prototype.toNT = function toNT() {
296 | var string = '"'+encodeString(this.nominalValue)+'"';
297 | if(this.language) return string+"@"+this.language;
298 | else if(xsdstring.equals(this.datatype)) return string;
299 | else if(this.datatype) return string+'^^<'+this.datatype+">";
300 | throw new Error('Unknown datatype');
301 | };
302 | api.Literal.prototype.toTurtle = function toTurtle(profile){
303 | if(xsdinteger.equals(this.datatype) && this.value.match(INTEGER)){
304 | return this.value;
305 | }
306 | if(xsddecimal.equals(this.datatype) && this.value.match(DECIMAL)){
307 | return this.value;
308 | }
309 | if(xsddouble.equals(this.datatype) && this.value.match(DOUBLE)){
310 | return this.value;
311 | }
312 | if(xsdboolean.equals(this.datatype) && this.value.match(BOOLEAN)){
313 | return this.value;
314 | }
315 | if(profile && this.type){
316 | var shrunk = profile.shrink(this.datatype.toString());
317 | if(shrunk!=this.datatype.toString()) return shrunk;
318 | }
319 | // TODO if it's xsd:integer/xsd:decimal/xsd:double/xsd:boolean, return simplified form
320 | return this.toNT();
321 | };
322 | api.Literal.prototype.n3 = function n3(profile){
323 | return this.toTurtle(profile);
324 | };
325 | // Literal#valueOf returns a language-native value - e.g. a number, boolean, or Date where possible
326 | api.Literal.prototype.valueOf = function() {
327 | if(this.datatype && typeof api.Literal.typeValueOf[this.datatype]=="function"){
328 | return api.Literal.typeValueOf[this.datatype](this.nominalValue, this.datatype);
329 | }
330 | return this.nominalValue;
331 | };
332 | Object.defineProperty(api.Literal.prototype, 'type', { get: function(){
333 | if(rdflangString.equals(this.datatype)) return null;
334 | if(xsdstring.equals(this.datatype)) return null;
335 | return this.datatype.nominalValue;
336 | } });
337 |
338 |
339 | api.Literal.typeValueOf = {};
340 | api.Literal.registerTypeConversion = function(datatype, f){
341 | api.Literal.typeValueOf[datatype] = f;
342 | };
343 | require('./space.js').loadDefaultTypeConverters(api.Literal);
344 |
345 | /**
346 | * NamedNode
347 | */
348 | api.NamedNode = NamedNode;
349 | inherits(api.NamedNode, api.RDFNode);
350 | function NamedNode(iri) {
351 | if(typeof iri!='string') throw new TypeError('argument iri not a string');
352 | if(iri[0]=='_' && iri[1]==':') throw new Error('unexpected BlankNode syntax');
353 | if(!iri.match(api.NamedNode.SCHEME_MATCH)) throw new Error('Expected arguments[0] `iri` to look like an IRI');
354 | if(iri.indexOf(' ') >= 0) throw new Error('Unexpected whitespace in arguments[0] `iri`');
355 | this.nominalValue = iri;
356 | }
357 | api.NamedNode.SCHEME_MATCH = new RegExp("^[a-z0-9-.+]+:", "i");
358 | api.NamedNode.prototype.nodeType = function nodeType() { return "IRI"; };
359 | api.NamedNode.prototype.interfaceName = "NamedNode";
360 | api.NamedNode.prototype.termType = "NamedNode";
361 | api.NamedNode.prototype.toNT = function toNT() {
362 | return "<" + encodeString(this.nominalValue) + ">";
363 | };
364 | api.NamedNode.prototype.toTurtle = function toTurtle(profile) {
365 | if(profile){
366 | var shrunk = profile.shrink(this.nominalValue);
367 | if(shrunk!=this.nominalValue) return shrunk;
368 | }
369 | return this.toNT();
370 | };
371 | api.NamedNode.prototype.n3 = function n3(profile) {
372 | return this.toTurtle(profile);
373 | };
374 |
375 | /**
376 | * TriplePattern
377 | */
378 | api.TriplePattern = function TriplePattern(s, p, o) {
379 | if(typeof s=='string') s = new NamedNode(s);
380 | if(!api.RDFNode.is(s)) throw new Error('TriplePattern subject is not an RDFNode');
381 | if(s.termType!=='NamedNode' && s.termType!=='BlankNode' && s.termType!=='Variable') throw new Error('subject must be a NamedNode/BlankNode/Variable');
382 |
383 | if(typeof p=='string') p = new NamedNode(p);
384 | if(!api.RDFNode.is(p)) throw new Error('TriplePattern predicate is not an RDFNode');
385 | if(p.termType!=='NamedNode' && p.termType!=='Variable') throw new Error('predicate must be a NamedNode/Variable');
386 |
387 | if(typeof o=='string') o = new NamedNode(o);
388 | if(!api.RDFNode.is(o)) throw new Error('TriplePattern object is not an RDFNode');
389 | if(o.termType!=='NamedNode' && o.termType!=='BlankNode' && o.termType!=='Literal' && o.termType!=='Variable') throw new Error('object must be a NamedNode/BlankNode/Literal/Variable');
390 |
391 | this.subject = s;
392 | this.predicate = p;
393 | this.object = o;
394 | };
395 | api.TriplePattern.prototype.size = 3;
396 | api.TriplePattern.prototype.length = 3;
397 | api.TriplePattern.prototype.toString = function() {
398 | return this.subject.n3() + " " + this.predicate.n3() + " " + this.object.n3() + " .";
399 | };
400 | api.TriplePattern.prototype.equals = function(t) {
401 | return RDFNodeEquals.call(this.subject,t.subject) && RDFNodeEquals.call(this.predicate,t.predicate) && RDFNodeEquals.call(this.object,t.object);
402 | };
403 |
404 | /**
405 | * Variable
406 | */
407 | api.Variable = Variable;
408 | inherits(api.Variable, api.RDFNode);
409 | function Variable(name) {
410 | if(typeof name!='string') throw new Error('Expected arguments[0] `name` to be a string');
411 | if(name[0]=='?' || name[0]=='$') name = name.substring(1);
412 | this.nominalValue = name;
413 | }
414 | api.Variable.SCHEME_MATCH = new RegExp("^[a-z0-9-.+]+:", "i");
415 | api.Variable.prototype.nodeType = function nodeType() { return "Variable"; };
416 | api.Variable.prototype.interfaceName = "Variable";
417 | api.Variable.prototype.termType = "Variable";
418 | api.Variable.prototype.toNT = function() {
419 | throw new Error('Cannot serialize variable to N-Triples');
420 | };
421 | api.Variable.prototype.toTurtle = function toTurtle() {
422 | throw new Error('Cannot serialize variable to Turtle');
423 | };
424 | api.Variable.prototype.n3 = function n3() {
425 | return '?'+this.nominalValue;
426 | };
427 |
428 | /*
429 | interface DefaultGraph : Term {
430 | attribute string termType;
431 | attribute string value;
432 | boolean equals(Term other);
433 | };
434 | */
435 | api.DefaultGraph = DefaultGraph;
436 | inherits(api.DefaultGraph, api.RDFNode);
437 | function DefaultGraph() {
438 | }
439 | api.DefaultGraph.prototype.interfaceName = "DefaultGraph";
440 | api.DefaultGraph.prototype.termType = "DefaultGraph";
441 | api.DefaultGraph.prototype.nominalValue = "";
442 | api.DefaultGraph.prototype.toNT = function() {
443 | throw new Error('Cannot serialize DefaultGraph to N-Triples');
444 | };
445 | api.DefaultGraph.prototype.toTurtle = function toTurtle() {
446 | throw new Error('Cannot serialize DefaultGraph to Turtle');
447 | };
448 | api.DefaultGraph.prototype.n3 = function n3() {
449 | throw new Error('Cannot serialize DefaultGraph to n3');
450 | };
451 |
452 | // Constants needed for processing Literals
453 | var xsdstring = new NamedNode('http://www.w3.org/2001/XMLSchema#string');
454 | var rdflangString = new NamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#langString');
455 |
456 | // Shamelessly copied from Builtins.js, also found in TurtleParser.js
457 | var xsdns = require('./ns.js').xsdns;
458 | var INTEGER = new RegExp("^(-|\\+)?[0-9]+$", "");
459 | var xsdinteger = new NamedNode(xsdns('integer'));
460 | var DOUBLE = new RegExp("^(-|\\+)?(([0-9]+\\.[0-9]*[eE]{1}(-|\\+)?[0-9]+)|(\\.[0-9]+[eE]{1}(-|\\+)?[0-9]+)|([0-9]+[eE]{1}(-|\\+)?[0-9]+))$", "");
461 | var xsddouble = new NamedNode(xsdns('double'));
462 | var DECIMAL = new RegExp("^(-|\\+)?[0-9]*\\.[0-9]+?$", "");
463 | var xsddecimal = new NamedNode(xsdns('decimal'));
464 | var BOOLEAN = new RegExp("^(true|false)", "");
465 | var xsdboolean = new NamedNode(xsdns('boolean'));
466 |
--------------------------------------------------------------------------------
/lib/ResultSet.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var Graph = require('./Graph.js');
4 | var RDFNode = require('./RDFNode.js');
5 |
6 | module.exports.ResultSet = ResultSet;
7 | function ResultSet(graph, initialNode){
8 | if(typeof initialNode=='string') initialNode = new RDFNode.NamedNode(initialNode);
9 | if(!(graph instanceof Graph.Graph)) throw new TypeError('Expected argument[0] `graph` to be a Graph');
10 | this.graph = graph;
11 | this.set = [];
12 | if(initialNode){
13 | if(!RDFNode.RDFNode.is(initialNode)) throw new Error('Triple initialNode is not an RDFNode');
14 | if(initialNode.termType!=='NamedNode' && initialNode.termType!=='BlankNode') throw new Error('subject must be a NamedNode/BlankNode');
15 | this.set.push(initialNode);
16 | }
17 | }
18 |
19 | ResultSet.prototype.set = [];
20 |
21 | ResultSet.prototype.add = function(node){
22 | // @@@TODO maybe verify that `node` is somewhere in the graph
23 | if(this.set.some(function(v){ return v.equals(node); })) return;
24 | this.set.push(node);
25 | };
26 |
27 | ResultSet.prototype.rel = function(predicate){
28 | if(typeof predicate=='string') predicate = new RDFNode.NamedNode(predicate);
29 | if(!RDFNode.RDFNode.is(predicate)) throw new Error('Expected argument[0] `predicate` to be an RDFNode');
30 | if(predicate.termType!=='NamedNode') throw new Error('Expected argument[0] `predicate` to be a NamedNode');
31 | var graph = this.graph;
32 | var set = this.set;
33 | var result = new ResultSet(graph);
34 | set.forEach(function(node){
35 | if(node.termType!='NamedNode' && node.termType!='BlankNode') return;
36 | graph.match(node, predicate, null).forEach(function(triple){
37 | result.add(triple.object);
38 | });
39 | });
40 | return result;
41 | };
42 |
43 | ResultSet.prototype.rev = function rev(predicate){
44 | if(typeof predicate=='string') predicate = new RDFNode.NamedNode(predicate);
45 | if(!RDFNode.RDFNode.is(predicate)) throw new Error('Expected argument[0] `predicate` to be an RDFNode');
46 | if(predicate.termType!=='NamedNode') throw new Error('Expected argument[0] `predicate` to be a NamedNode');
47 | var graph = this.graph;
48 | var set = this.set;
49 | var result = new ResultSet(graph);
50 | set.forEach(function(node){
51 | graph.match(null, predicate, node).forEach(function(triple){
52 | result.add(triple.subject);
53 | });
54 | });
55 | return result;
56 | };
57 |
58 | ResultSet.prototype.toArray = function toArray(callback){
59 | return this.set.slice();
60 | };
61 |
62 | ResultSet.prototype.some = function some(callback){
63 | return this.set.some(callback);
64 | };
65 |
66 | ResultSet.prototype.every = function every(callback){
67 | return this.set.every(callback);
68 | };
69 |
70 | ResultSet.prototype.filter = function filter(callback){
71 | var result = new ResultSet(this.graph);
72 | // FIXME this can probably be optimized since we're only removing nodes
73 | this.set.filter(callback).forEach(function(node){
74 | result.add(node);
75 | });
76 | return result;
77 | };
78 |
79 | ResultSet.prototype.forEach = function forEach(callback){
80 | return this.set.forEach(callback);
81 | };
82 |
83 | ResultSet.prototype.map = function map(callback){
84 | var result = new ResultSet(this.graph);
85 | this.set.map(callback).forEach(function(node){
86 | result.add(node);
87 | });
88 | return result;
89 | };
90 |
91 | ResultSet.prototype.reduce = function reduce(callback, initial){
92 | return this.set.reduce(callback, initial);
93 | };
94 |
95 | ResultSet.prototype.one = function one(callback){
96 | if(this.set.length>1) throw new Error('Expected one match');
97 | if(this.set.length===0) return null;
98 | return this.set[0];
99 | };
100 |
101 | Object.defineProperty(ResultSet.prototype, 'length', { get: function(){ return this.set.length; } });
102 |
--------------------------------------------------------------------------------
/lib/TurtleParser.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var parsers = exports;
4 |
5 | var IRI = require('iri').IRI;
6 | var env = require('./environment.js').environment;
7 | function rdfns(v){return 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'+v;}
8 | function xsdns(v){return 'http://www.w3.org/2001/XMLSchema#'+v;}
9 |
10 | parsers.u8 = new RegExp("\\\\U([0-9A-Fa-f]{8})", "g");
11 | parsers.u4 = new RegExp("\\\\u([0-9A-Fa-f]{4})", "g");
12 | parsers.hexToChar = function hexToChar(hex) {
13 | var result = "";
14 | var n = parseInt(hex, 16);
15 | if(n <= 65535) {
16 | result += String.fromCharCode(n);
17 | } else if(n <= 1114111) {
18 | n -= 65536;
19 | result += String.fromCharCode(55296 + (n >> 10), 56320 + (n & 1023));
20 | } else {
21 | throw new Error("code point isn't known: " + n);
22 | }
23 | return result;
24 | };
25 | parsers.decodeString = function decodeString(str) {
26 | str = str.replace(parsers.u8, function(matchstr, parens) { return parsers.hexToChar(parens); });
27 | str = str.replace(parsers.u4, function(matchstr, parens) { return parsers.hexToChar(parens); });
28 | str = str.replace(new RegExp("\\\\t", "g"), "\t");
29 | str = str.replace(new RegExp("\\\\b", "g"), "\b");
30 | str = str.replace(new RegExp("\\\\n", "g"), "\n");
31 | str = str.replace(new RegExp("\\\\r", "g"), "\r");
32 | str = str.replace(new RegExp("\\\\f", "g"), "\f");
33 | str = str.replace(new RegExp('\\\\"', "g"), '"');
34 | str = str.replace(new RegExp("\\\\\\\\", "g"), "\\");
35 | return str;
36 | };
37 | parsers.decodePrefixedName = function(str){
38 | var decoded = '';
39 | for(var i=0; i 0) {
113 | s = this.skipWS(s);
114 | if(s.length == 0) return true;
115 | s = (s.charAt(0)=="@" || s.substring(0,4).toUpperCase()=='BASE' || s.substring(0,6).toUpperCase()=='PREFIX') ? this.consumeDirective(s) : this.consumeStatement(s);
116 | s = this.skipWS(s);
117 | }
118 | return true;
119 | };
120 | Turtle.prototype.createTriple = function createTriple(s, p, o){
121 | return env.createTriple(s, p, o);
122 | };
123 | Turtle.prototype.createNamedNode = function createNamedNode(v){
124 | return env.createNamedNode(v);
125 | };
126 | Turtle.prototype.createBlankNode = function createBlankNode(){
127 | return env.createBlankNode();
128 | };
129 | Turtle.prototype.createLiteral = function createLiteral(v, l, t){
130 | return env.createLiteral(v, l, t);
131 | };
132 | Turtle.prototype.add = function(t) {
133 | var $use = true;
134 | if(this.filter != null) $use = this.filter(t, null, null);
135 | if(!$use) return;
136 | this.processor ? this.processor(null, t) : this.graph.add(t);
137 | };
138 | Turtle.prototype.consumeBlankNode = function(s, t) {
139 | t.o = this.createBlankNode();
140 | s = this.skipWS(s.slice(1));
141 | if(s.charAt(0) == "]") return s.slice(1);
142 | s = this.skipWS(this.consumePredicateObjectList(s, t));
143 | this.expect(s, "]");
144 | return this.skipWS(s.slice(1));
145 | };
146 | Turtle.prototype.consumeCollection = function(s, subject) {
147 | subject.o = this.createBlankNode();
148 | var listject = this.t();
149 | listject.o = subject.o;
150 | s = this.skipWS(s.slice(1));
151 | var cont = s.charAt(0) != ")";
152 | if(!cont) { subject.o = this.createNamedNode(rdfns("nil")); }
153 | while(cont) {
154 | var o = this.t();
155 | switch(s.charAt(0)) {
156 | case "[": s = this.consumeBlankNode(s, o); break;
157 | case "_": s = this.consumeKnownBlankNode(s, o); break;
158 | case "(": s = this.consumeCollection(s, o); break;
159 | case "<": s = this.consumeURI(s, o); break;
160 | case '"': case "'": s = this.consumeLiteral(s, o); break;
161 | case '+': case '-': case '.':
162 | case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
163 | var token;
164 | if(token = Turtle.tokenDouble.exec(s)){
165 | token = token[0];
166 | o.o = this.createLiteral(token, null, xsdns("double"));
167 | } else if(token = Turtle.tokenDecimal.exec(s)){
168 | token = token[0];
169 | o.o = this.createLiteral(token, null, xsdns("decimal"));
170 | } else if(token = Turtle.tokenInteger.exec(s)){
171 | token = token[0];
172 | o.o = this.createLiteral(token, null, xsdns("integer"));
173 | } else {
174 | throw new Error("Expected NumericLiteral");
175 | }
176 | s = s.slice(token.length);
177 | break;
178 | default:
179 | var token = s.match(Turtle.simpleObjectToken).shift();
180 | if(token.charAt(token.length - 1) == ")") {
181 | token = token.substring(0, token.length - 1);
182 | }
183 | if(token==="false" || token==="true"){
184 | o.o = this.createLiteral(token, null, xsdns("boolean"));
185 | }else if(token.indexOf(":") >= 0) {
186 | o.o = this.createNamedNode(this.environment.resolve(token));
187 | }
188 | s = s.slice(token.length);
189 | break;
190 | }
191 | this.add(this.createTriple(listject.o, this.createNamedNode(rdfns("first")), o.o));
192 | s = this.skipWS(s);
193 | cont = s.charAt(0) != ")";
194 | if(cont) {
195 | this.add(this.createTriple(listject.o, this.createNamedNode(rdfns("rest")), listject.o = this.createBlankNode()));
196 | } else {
197 | this.add(this.createTriple(listject.o, this.createNamedNode(rdfns("rest")), this.createNamedNode(rdfns("nil"))));
198 | }
199 | }
200 | return this.skipWS(s.slice(1));
201 | };
202 | Turtle.prototype.consumeDirective = function(s) {
203 | var p = 0;
204 | if(s.substring(1, 7) == "prefix") {
205 | s = this.skipWS(s.slice(7));
206 | p = s.indexOf(":");
207 | var prefix = s.substring(0, p);
208 | s = this.skipWS(s.slice(++p));
209 | this.expect(s, "<");
210 | this.environment.setPrefix(prefix, this.base.resolveReference(parsers.decodeIRIREF(s.substring(1, p = s.indexOf(">")))).toString());
211 | s = this.skipWS(s.slice(++p));
212 | this.expect(s, ".");
213 | s = s.slice(1);
214 | } else if(s.substring(0, 6).toUpperCase() == "PREFIX") {
215 | // SPARQL-style
216 | s = this.skipWS(s.slice(7));
217 | p = s.indexOf(":");
218 | var prefix = s.substring(0, p);
219 | s = this.skipWS(s.slice(++p));
220 | this.expect(s, "<");
221 | this.environment.setPrefix(prefix, this.base.resolveReference(parsers.decodeIRIREF(s.substring(1, p = s.indexOf(">")))).toString());
222 | s = this.skipWS(s.slice(++p));
223 | } else if(s.substring(1, 5) == "base") {
224 | s = this.skipWS(s.slice(5));
225 | this.expect(s, "<");
226 | this.base = this.base.resolveReference(parsers.decodeIRIREF(s.substring(1, p = s.indexOf(">"))));
227 | s = this.skipWS(s.slice(++p));
228 | this.expect(s, ".");
229 | s = s.slice(1);
230 | } else if(s.substring(0, 4).toUpperCase() == "BASE") {
231 | // SPARQL-style
232 | s = this.skipWS(s.slice(5));
233 | this.expect(s, "<");
234 | this.base = this.base.resolveReference(parsers.decodeIRIREF(s.substring(1, p = s.indexOf(">"))));
235 | s = this.skipWS(s.slice(++p));
236 | } else {
237 | throw new Error("Unknown directive: " + s.substring(0, 50));
238 | }
239 | return s;
240 | };
241 | Turtle.prototype.consumeKnownBlankNode = function(s, t) {
242 | this.expect(s, "_:");
243 | var bname = s.slice(2).match(Turtle.simpleToken).shift();
244 | t.o = this.getBlankNode(bname);
245 | return s.slice(bname.length + 2);
246 | };
247 | Turtle.prototype.consumeLiteral = function(s, o) {
248 | var char = s[0];
249 | var value = "";
250 | var end = 0;
251 | var longchar = char+char+char;
252 | if(s.substring(0, 3) == longchar) {
253 | for(end=3; end");
280 | if(iri_end<0) throw new Error('Could not find terminating ">"');
281 | var iri_esc = s.substring(1, iri_end);
282 | iri_val = this.createNamedNode(this.base.resolveReference(parsers.decodeIRIREF(iri_esc)).toString());
283 | s = this.skipWS(s.substring(iri_end+1));
284 | }else{
285 | var prefixedName = Turtle.PrefixedName.exec(s);
286 | if(!prefixedName) throw new Error('Expected PrefixedName');
287 | prefixedName = prefixedName[0];
288 | iri_val = this.environment.resolve(parsers.decodePrefixedName(prefixedName));
289 | if(!iri_val) throw new Error('Could not resolve PrefixedName '+JSON.stringify(parsers.decodePrefixedName(prefixedName)));
290 | s = this.skipWS(s.slice(prefixedName.length));
291 | }
292 | o.o = this.createLiteral(value, null, iri_val);
293 | break;
294 | default:
295 | o.o = this.createLiteral(value, null, null);
296 | break;
297 | }
298 | return s;
299 | };
300 | Turtle.prototype.consumeObjectList = function(s, subject, property) {
301 | var cont = true;
302 | while(cont) {
303 | var o = this.t();
304 | switch(s.charAt(0)) {
305 | case "[": s = this.consumeBlankNode(s, o); break;
306 | case "_": s = this.consumeKnownBlankNode(s, o); break;
307 | case "(": s = this.consumeCollection(s, o); break;
308 | case "<": s = this.consumeURI(s, o); break;
309 | case '"': case "'": s = this.consumeLiteral(s, o); break;
310 | case '+': case '-': case '.':
311 | case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
312 | var token;
313 | if(token = Turtle.tokenDouble.exec(s)){
314 | token = token[0];
315 | o.o = this.createLiteral(token, null, xsdns("double"));
316 | } else if(token = Turtle.tokenDecimal.exec(s)){
317 | token = token[0];
318 | o.o = this.createLiteral(token, null, xsdns("decimal"));
319 | } else if(token = Turtle.tokenInteger.exec(s)){
320 | token = token[0];
321 | o.o = this.createLiteral(token, null, xsdns("integer"));
322 | } else {
323 | throw new Error("Expected NumericLiteral");
324 | }
325 | s = s.slice(token.length);
326 | break;
327 | default:
328 | var token = s.match(Turtle.simpleObjectToken);
329 | var prefixedName;
330 | token = token&&token[0] || "";
331 | if(token.charAt(token.length - 1) == ".") {
332 | token = token.substring(0, token.length - 1);
333 | }
334 | if(token==="true" || token==="false"){
335 | o.o = this.createLiteral(token, null, xsdns("boolean"));
336 | s = s.slice(token.length);
337 | }else if(prefixedName=Turtle.PrefixedName.exec(token)) {
338 | var prefixedName = prefixedName[0];
339 | var iri = this.environment.resolve(parsers.decodePrefixedName(prefixedName));
340 | if(!iri) throw new Error('Could not resolve PrefixedName '+JSON.stringify(parsers.decodePrefixedName(prefixedName)));
341 | o.o = this.createNamedNode(iri);
342 | if(!o.o) throw new Error('Prefix not defined for '+token);
343 | s = s.slice(prefixedName.length);
344 | } else {
345 | throw new Error("Unrecognized token in ObjectList: " + token);
346 | }
347 | break;
348 | }
349 | s = this.skipWS(s);
350 | this.add(this.createTriple(subject.o, property, o.o));
351 | cont = s.charAt(0)==",";
352 | if(cont) { s = this.skipWS(s.slice(1)); }
353 | }
354 | return s;
355 | };
356 | Turtle.prototype.consumePredicateObjectList = function(s, subject) {
357 | var cont = true;
358 | while(cont) {
359 | var predicate = s.match(Turtle.PrefixedName);
360 | if(predicate){
361 | predicate = predicate.shift();
362 | var iri = this.environment.resolve(parsers.decodePrefixedName(predicate));
363 | if(!iri) throw new Error('Could not resolve PrefixedName '+JSON.stringify(parsers.decodePrefixedName(predicate)));
364 | property = this.createNamedNode(iri);
365 | s = this.skipWS(s.slice(predicate.length));
366 | s = this.consumeObjectList(s, subject, property);
367 | continue;
368 | }
369 | switch(s.charAt(0)) {
370 | case "a":
371 | var property = this.createNamedNode(rdfns("type"));
372 | s = this.skipWS(s.substring(1));
373 | break;
374 | case "<":
375 | var iri_end = s.indexOf(">");
376 | var iri = s.substring(1, iri_end);
377 | property = this.createNamedNode(this.base.resolveReference(parsers.decodeIRIREF(iri)).toString());
378 | s = this.skipWS(s.substring(iri_end+1));
379 | break;
380 | case "]": return s;
381 | case ".": return s;
382 | case ";":
383 | // empty predicate, skip
384 | s = this.skipWS(s.substring(1));
385 | continue;
386 | default:
387 | throw new Error('Expected PrefixedName');
388 | }
389 | s = this.consumeObjectList(s, subject, property);
390 | cont = s.charAt(0)==";";
391 | if(cont) { s = this.skipWS(s.slice(1)); }
392 | }
393 | return s;
394 | };
395 | Turtle.prototype.consumePrefixedName = function(s, t) {
396 | var name = s.match(Turtle.PrefixedName).shift();
397 | var iri = this.environment.resolve(parsers.decodePrefixedName(name));
398 | if(!iri) throw new Error('Could not resolve '+JSON.stringify(parsers.decodePrefixedName(name)));
399 | t.o = this.createNamedNode(iri);
400 | return s.slice(name.length);
401 | };
402 | Turtle.prototype.consumeStatement = function(s) {
403 | var t = this.t();
404 | switch(s.charAt(0)) {
405 | case "[":
406 | s = this.consumeBlankNode(s, t);
407 | if(s.charAt(0) == ".") return s.slice(1);
408 | break;
409 | case "_": s = this.consumeKnownBlankNode(s, t); break;
410 | case "(": s = this.consumeCollection(s, t); break;
411 | case "<": s = this.consumeURI(s, t); break;
412 | default: s = this.consumePrefixedName(s, t); break;
413 | }
414 | s = this.consumePredicateObjectList(this.skipWS(s), t);
415 | this.expect(s, ".");
416 | return s.slice(1);
417 | };
418 | Turtle.prototype.consumeURI = function(s, t) {
419 | this.expect(s, "<");
420 | var p = 0;
421 | t.o = this.createNamedNode(this.base.resolveReference(parsers.decodeIRIREF(s.substring(1, p=s.indexOf(">")))).toString());
422 | return s.slice(++p);
423 | };
424 | Turtle.prototype.getBlankNode = function(id) {
425 | if(this.bnHash[id]) return this.bnHash[id];
426 | return this.bnHash[id]=this.createBlankNode();
427 | };
428 | Turtle.prototype.skipWS = function(s) {
429 | while(Turtle.isWhitespace.test(s.charAt(0))) {
430 | s = s.replace(Turtle.initialWhitespace, "");
431 | if(s.charAt(0) == "#") {
432 | s = s.replace(Turtle.initialComment, "");
433 | }
434 | }
435 | return s;
436 | };
437 |
--------------------------------------------------------------------------------
/lib/encodeString.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | // #x22#x5C#xA#xD
4 | var encodeMap = {
5 | '"': '\\"',
6 | '\\': '\\\\',
7 | "\r": '\\r',
8 | "\n": '\\n',
9 | "\t": '\\t',
10 | };
11 |
12 | // Takes a string and produces an escaped Turtle String production but without quotes
13 | module.exports = encodeASCIIString;
14 |
15 | // Use this to output the unicode character whenever it's legal in N-Triples
16 | // var encodeSearch = /["\r\n\\]/g;
17 | // function encodeString(str) {
18 | // return str.replace(encodeSearch, function(a, b){
19 | // return encodeMap[b];
20 | // });
21 | // }
22 |
23 | var encodeASCIIStringSearch = /(["\r\n\t\\])|([\u0080-\uD7FF\uE000-\uFFFF])|([\uD800-\uDBFF][\uDC00-\uDFFF])/g;
24 | function encodeASCIIStringReplace(a, b, c, d){
25 | if(b){
26 | // These characters must be escaped
27 | // Actually \t doesn't have to, but it's allowed and common to do so
28 | return encodeMap[b];
29 | }
30 | if(c){
31 | // The match is a non-ASCII code point that's not a surrogate pair
32 | return '\\u'+('0000'+c.charCodeAt(0).toString(16).toUpperCase()).substr(-4);
33 | }
34 | if(d){
35 | // The match is a UTF-16 surrogate pair, compute the UTF-32 codepoint
36 | var hig = d.charCodeAt(0);
37 | var low = d.charCodeAt(1);
38 | var code = (hig - 0xD800) * 0x400 + (low - 0xDC00) + 0x10000;
39 | return '\\U'+('00000000'+code.toString(16).toUpperCase()).substr(-8);
40 | }
41 | }
42 |
43 | // Return a Turtle string with backslash escapes for all non-7-bit characters
44 | function encodeASCIIString(str){
45 | return str.replace(encodeASCIIStringSearch, encodeASCIIStringReplace);
46 | }
47 |
--------------------------------------------------------------------------------
/lib/environment.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var RDFEnvironment = require("./RDFEnvironment.js").RDFEnvironment;
4 | var DataFactory = require("./DataFactory.js").DataFactory;
5 |
6 | var env = exports.environment = new RDFEnvironment;
7 | require('./prefixes.js').loadDefaultPrefixMap(env);
8 | exports.factory = new DataFactory;
9 |
--------------------------------------------------------------------------------
/lib/ns.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | exports.ns = function(prefix){
4 | if(typeof prefix!='string') throw new TypeError('Expected argument[0] `prefix` to be a string');
5 | return function(suffix){
6 | if(typeof suffix!='string') throw new TypeError('Expected argument[0] `suffix` to be a string');
7 | return prefix.concat(suffix);
8 | };
9 | };
10 |
11 | exports.rdfns = exports.ns('http://www.w3.org/1999/02/22-rdf-syntax-ns#');
12 | exports.rdfsns = exports.ns('http://www.w3.org/2000/01/rdf-schema#');
13 | exports.xsdns = exports.ns('http://www.w3.org/2001/XMLSchema#');
14 |
--------------------------------------------------------------------------------
/lib/prefixes.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | exports.loadRequiredPrefixMap = function(context){
4 | context.setPrefix("owl", "http://www.w3.org/2002/07/owl#");
5 | context.setPrefix("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
6 | context.setPrefix("rdfs", "http://www.w3.org/2000/01/rdf-schema#");
7 | context.setPrefix("rdfa", "http://www.w3.org/ns/rdfa#");
8 | context.setPrefix("xhv", "http://www.w3.org/1999/xhtml/vocab#");
9 | context.setPrefix("xml", "http://www.w3.org/XML/1998/namespace");
10 | context.setPrefix("xsd", "http://www.w3.org/2001/XMLSchema#");
11 | };
12 | exports.loadDefaultPrefixMap = function(context){
13 | exports.loadRequiredPrefixMap(context);
14 | context.setPrefix("grddl", "http://www.w3.org/2003/g/data-view#");
15 | context.setPrefix("powder", "http://www.w3.org/2007/05/powder#");
16 | context.setPrefix("powders", "http://www.w3.org/2007/05/powder-s#");
17 | context.setPrefix("rif", "http://www.w3.org/2007/rif#");
18 | context.setPrefix("atom", "http://www.w3.org/2005/Atom/");
19 | context.setPrefix("xhtml", "http://www.w3.org/1999/xhtml#");
20 | context.setPrefix("formats", "http://www.w3.org/ns/formats/");
21 | context.setPrefix("xforms", "http://www.w3.org/2002/xforms/");
22 | context.setPrefix("xhtmlvocab", "http://www.w3.org/1999/xhtml/vocab/");
23 | context.setPrefix("xpathfn", "http://www.w3.org/2005/xpath-functions#");
24 | //context.setPrefix("http", "http://www.w3.org/2006/http#");
25 | context.setPrefix("link", "http://www.w3.org/2006/link#");
26 | context.setPrefix("time", "http://www.w3.org/2006/time#");
27 | context.setPrefix("acl", "http://www.w3.org/ns/auth/acl#");
28 | context.setPrefix("cert", "http://www.w3.org/ns/auth/cert#");
29 | context.setPrefix("rsa", "http://www.w3.org/ns/auth/rsa#");
30 | context.setPrefix("crypto", "http://www.w3.org/2000/10/swap/crypto#");
31 | context.setPrefix("list", "http://www.w3.org/2000/10/swap/list#");
32 | context.setPrefix("log", "http://www.w3.org/2000/10/swap/log#");
33 | context.setPrefix("math", "http://www.w3.org/2000/10/swap/math#");
34 | context.setPrefix("os", "http://www.w3.org/2000/10/swap/os#");
35 | context.setPrefix("string", "http://www.w3.org/2000/10/swap/string#");
36 | context.setPrefix("doc", "http://www.w3.org/2000/10/swap/pim/doc#");
37 | context.setPrefix("contact", "http://www.w3.org/2000/10/swap/pim/contact#");
38 | context.setPrefix("p3p", "http://www.w3.org/2002/01/p3prdfv1#");
39 | context.setPrefix("swrl", "http://www.w3.org/2003/11/swrl#");
40 | context.setPrefix("swrlb", "http://www.w3.org/2003/11/swrlb#");
41 | context.setPrefix("exif", "http://www.w3.org/2003/12/exif/ns#");
42 | context.setPrefix("earl", "http://www.w3.org/ns/earl#");
43 | context.setPrefix("ma", "http://www.w3.org/ns/ma-ont#");
44 | context.setPrefix("sawsdl", "http://www.w3.org/ns/sawsdl#");
45 | context.setPrefix("sd", "http://www.w3.org/ns/sparql-service-description#");
46 | context.setPrefix("skos", "http://www.w3.org/2004/02/skos/core#");
47 | context.setPrefix("fresnel", "http://www.w3.org/2004/09/fresnel#");
48 | context.setPrefix("gen", "http://www.w3.org/2006/gen/ont#");
49 | context.setPrefix("timezone", "http://www.w3.org/2006/timezone#");
50 | context.setPrefix("skosxl", "http://www.w3.org/2008/05/skos-xl#");
51 | context.setPrefix("org", "http://www.w3.org/ns/org#");
52 | context.setPrefix("ical", "http://www.w3.org/2002/12/cal/ical#");
53 | context.setPrefix("wgs84", "http://www.w3.org/2003/01/geo/wgs84_pos#");
54 | context.setPrefix("vcard", "http://www.w3.org/2006/vcard/ns#");
55 | context.setPrefix("turtle", "http://www.w3.org/2008/turtle#");
56 | context.setPrefix("pointers", "http://www.w3.org/2009/pointers#");
57 | context.setPrefix("dcat", "http://www.w3.org/ns/dcat#");
58 | context.setPrefix("imreg", "http://www.w3.org/2004/02/image-regions#");
59 | context.setPrefix("rdfg", "http://www.w3.org/2004/03/trix/rdfg-1/");
60 | context.setPrefix("swp", "http://www.w3.org/2004/03/trix/swp-2/");
61 | context.setPrefix("rei", "http://www.w3.org/2004/06/rei#");
62 | context.setPrefix("wairole", "http://www.w3.org/2005/01/wai-rdf/GUIRoleTaxonomy#");
63 | context.setPrefix("states", "http://www.w3.org/2005/07/aaa#");
64 | context.setPrefix("wn20schema", "http://www.w3.org/2006/03/wn/wn20/schema/");
65 | context.setPrefix("httph", "http://www.w3.org/2007/ont/httph#");
66 | context.setPrefix("act", "http://www.w3.org/2007/rif-builtin-action#");
67 | context.setPrefix("common", "http://www.w3.org/2007/uwa/context/common.owl#");
68 | context.setPrefix("dcn", "http://www.w3.org/2007/uwa/context/deliverycontext.owl#");
69 | context.setPrefix("hard", "http://www.w3.org/2007/uwa/context/hardware.owl#");
70 | context.setPrefix("java", "http://www.w3.org/2007/uwa/context/java.owl#");
71 | context.setPrefix("loc", "http://www.w3.org/2007/uwa/context/location.owl#");
72 | context.setPrefix("net", "http://www.w3.org/2007/uwa/context/network.owl#");
73 | context.setPrefix("push", "http://www.w3.org/2007/uwa/context/push.owl#");
74 | context.setPrefix("soft", "http://www.w3.org/2007/uwa/context/software.owl#");
75 | context.setPrefix("web", "http://www.w3.org/2007/uwa/context/web.owl#");
76 | context.setPrefix("content", "http://www.w3.org/2008/content#");
77 | context.setPrefix("vs", "http://www.w3.org/2003/06/sw-vocab-status/ns#");
78 | context.setPrefix("air", "http://dig.csail.mit.edu/TAMI/2007/amord/air#");
79 | context.setPrefix("ex", "http://example.org/");
80 | context.setPrefix("dc", "http://purl.org/dc/terms/");
81 | context.setPrefix("dc11", "http://purl.org/dc/elements/1.1/");
82 | context.setPrefix("dctype", "http://purl.org/dc/dcmitype/");
83 | context.setPrefix("foaf", "http://xmlns.com/foaf/0.1/");
84 | context.setPrefix("cc", "http://creativecommons.org/ns#");
85 | context.setPrefix("opensearch", "http://a9.com/-/spec/opensearch/1.1/");
86 | context.setPrefix("void", "http://rdfs.org/ns/void#");
87 | context.setPrefix("sioc", "http://rdfs.org/sioc/ns#");
88 | context.setPrefix("sioca", "http://rdfs.org/sioc/actions#");
89 | context.setPrefix("sioct", "http://rdfs.org/sioc/types#");
90 | context.setPrefix("lgd", "http://linkedgeodata.org/vocabulary#");
91 | context.setPrefix("moat", "http://moat-project.org/ns#");
92 | context.setPrefix("days", "http://ontologi.es/days#");
93 | context.setPrefix("giving", "http://ontologi.es/giving#");
94 | context.setPrefix("lang", "http://ontologi.es/lang/core#");
95 | context.setPrefix("like", "http://ontologi.es/like#");
96 | context.setPrefix("status", "http://ontologi.es/status#");
97 | context.setPrefix("og", "http://opengraphprotocol.org/schema/");
98 | context.setPrefix("protege", "http://protege.stanford.edu/system#");
99 | context.setPrefix("dady", "http://purl.org/NET/dady#");
100 | context.setPrefix("uri", "http://purl.org/NET/uri#");
101 | context.setPrefix("audio", "http://purl.org/media/audio#");
102 | context.setPrefix("video", "http://purl.org/media/video#");
103 | context.setPrefix("gridworks", "http://purl.org/net/opmv/types/gridworks#");
104 | context.setPrefix("hcterms", "http://purl.org/uF/hCard/terms/");
105 | context.setPrefix("bio", "http://purl.org/vocab/bio/0.1/");
106 | context.setPrefix("cs", "http://purl.org/vocab/changeset/schema#");
107 | context.setPrefix("geographis", "http://telegraphis.net/ontology/geography/geography#");
108 | context.setPrefix("doap", "http://usefulinc.com/ns/doap#");
109 | context.setPrefix("daml", "http://www.daml.org/2001/03/daml+oil#");
110 | context.setPrefix("geonames", "http://www.geonames.org/ontology#");
111 | context.setPrefix("sesame", "http://www.openrdf.org/schema/sesame#");
112 | context.setPrefix("cv", "http://rdfs.org/resume-rdf/");
113 | context.setPrefix("wot", "http://xmlns.com/wot/0.1/");
114 | context.setPrefix("media", "http://purl.org/microformat/hmedia/");
115 | context.setPrefix("ctag", "http://commontag.org/ns#");
116 | };
117 |
--------------------------------------------------------------------------------
/lib/space.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | function xsdns(v){ return 'http://www.w3.org/2001/XMLSchema#'.concat(v); }
4 |
5 | exports.stringConverter = function stringConverter(value, inputType) {
6 | return new String(value).valueOf();
7 | };
8 | exports.booleanConverter = function booleanConverter(value, inputType) {
9 | switch(value){
10 | case "false":case "0": return false;
11 | case "true":case "1": return true;
12 | }
13 | return(new Boolean(value)).valueOf();
14 | };
15 | exports.numberConverter = function numberConverter(value, inputType) {
16 | return(new Number(value)).valueOf();
17 | };
18 | exports.floatConverter = function floatConverter(value, inputType) {
19 | switch(value){
20 | case "INF": return Number.POSITIVE_INFINITY;
21 | case "-INF": return Number.NEGATIVE_INFINITY;
22 | default: return exports.numberConverter(value, inputType);
23 | }
24 | };
25 | exports.dateConverter = function dateConverter(value, inputType) {
26 | return new Date(value);
27 | };
28 |
29 | exports.loadDefaultTypeConverters = function(context){
30 | context.registerTypeConversion(xsdns("string"), exports.stringConverter);
31 | context.registerTypeConversion(xsdns("boolean"), exports.booleanConverter);
32 | context.registerTypeConversion(xsdns("float"), exports.floatConverter);
33 | context.registerTypeConversion(xsdns("integer"), exports.numberConverter);
34 | context.registerTypeConversion(xsdns("long"), exports.numberConverter);
35 | context.registerTypeConversion(xsdns("double"), exports.numberConverter);
36 | context.registerTypeConversion(xsdns("decimal"), exports.numberConverter);
37 | context.registerTypeConversion(xsdns("nonPositiveInteger"), exports.numberConverter);
38 | context.registerTypeConversion(xsdns("nonNegativeInteger"), exports.numberConverter);
39 | context.registerTypeConversion(xsdns("negativeInteger"), exports.numberConverter);
40 | context.registerTypeConversion(xsdns("int"), exports.numberConverter);
41 | context.registerTypeConversion(xsdns("unsignedLong"), exports.numberConverter);
42 | context.registerTypeConversion(xsdns("positiveInteger"), exports.numberConverter);
43 | context.registerTypeConversion(xsdns("short"), exports.numberConverter);
44 | context.registerTypeConversion(xsdns("unsignedInt"), exports.numberConverter);
45 | context.registerTypeConversion(xsdns("byte"), exports.numberConverter);
46 | context.registerTypeConversion(xsdns("unsignedShort"), exports.numberConverter);
47 | context.registerTypeConversion(xsdns("unsignedByte"), exports.numberConverter);
48 | context.registerTypeConversion(xsdns("date"), exports.dateConverter);
49 | context.registerTypeConversion(xsdns("time"), exports.dateConverter);
50 | context.registerTypeConversion(xsdns("dateTime"), exports.dateConverter);
51 | };
52 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rdf",
3 | "description": "RDF datatype integration, RDF Interfaces API, and utility functions",
4 | "homepage": "https://github.com/awwright/node-rdf",
5 | "author": "Austin Wright",
6 | "keywords": [
7 | "RDF",
8 | "RDF Interfaces",
9 | "IRI",
10 | "Turtle"
11 | ],
12 | "dependencies": {
13 | "iri": "~1"
14 | },
15 | "repository": {
16 | "type": "git",
17 | "url": "git://github.com/awwright/node-rdf.git",
18 | "web": "https://github.com/awwright/node-rdf"
19 | },
20 | "main": "index.js",
21 | "scripts": {
22 | "test": "mocha"
23 | },
24 | "license": "Unlicense",
25 | "devDependencies": {
26 | "mocha": "^10.0.0",
27 | "nyc": "^15.1.0"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/test/.eslintrc.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | module.exports = {
3 | "env": {
4 | "mocha": true,
5 | },
6 | "extends": "eslint:recommended",
7 | "parserOptions": {
8 | "ecmaVersion": 5,
9 | },
10 | "rules": {
11 | "indent": [ "error", "tab", {
12 | SwitchCase: 1,
13 | } ],
14 | "no-unreachable": [ "error" ],
15 | "linebreak-style": [ "error", "unix" ],
16 | //"semi": [ "error", "always" ],
17 | "comma-dangle": [ "error", "always-multiline" ],
18 | "no-console": [ "error" ],
19 | },
20 | };
21 |
--------------------------------------------------------------------------------
/test/BlankNode.test.js:
--------------------------------------------------------------------------------
1 | var assert = require('assert');
2 | var rdf = require('..');
3 |
4 | describe('BlankNode', function(){
5 | it("instance", function(){
6 | var t = new rdf.BlankNode();
7 | assert.ok(t instanceof rdf.BlankNode);
8 | assert.strictEqual(t.nodeType(), 'BlankNode');
9 | assert.strictEqual(t.interfaceName, 'BlankNode'); // 2012 Note variant
10 | assert.strictEqual(t.termType, 'BlankNode'); // 2017 Community Group variant
11 | assert.strictEqual(t.toNT(), t.n3());
12 | });
13 | });
14 |
--------------------------------------------------------------------------------
/test/BlankNodeMap.test.js:
--------------------------------------------------------------------------------
1 | var assert = require('assert');
2 | var rdf = require('..');
3 |
4 | function BlankNodeMapTests(){
5 | it("instance", function(){
6 | var bn = rdf.BlankNodeMap();
7 | assert(bn instanceof rdf.BlankNodeMap);
8 | });
9 | }
10 |
11 | describe('BlankNodeMap', BlankNodeMapTests);
12 |
13 | describe('BlankNodeMap (with builtins)', function(){
14 | before(function(){
15 | rdf.setBuiltins();
16 | });
17 | after(function(){
18 | rdf.unsetBuiltins();
19 | });
20 | BlankNodeMapTests();
21 | });
22 |
--------------------------------------------------------------------------------
/test/DataFactory.test.js:
--------------------------------------------------------------------------------
1 | var assert = require('assert');
2 | var rdf = require('..');
3 | var factory = rdf.factory;
4 |
5 | /*
6 | // Presumably these are implemented by the same object, even though the WebIDL doesn't seem to indicate as such
7 |
8 | interface DataFactory {
9 | NamedNode namedNode(string value);
10 | BlankNode blankNode(optional string value);
11 | Literal literal(string value, optional (string or NamedNode) languageOrDatatype);
12 | Variable variable(string value);
13 | DefaultGraph defaultGraph();
14 | Quad quad(Term subject, Term predicate, Term object, optional Term? graph);
15 | Term fromTerm(Term original);
16 | Quad fromQuad(Quad original);
17 | };
18 | interface DatasetCoreFactory {
19 | DatasetCore dataset (optional sequence quads);
20 | };
21 | */
22 |
23 | function DataFactoryTests(){
24 | it("default instance", function(){
25 | assert(rdf.factory instanceof rdf.DataFactory);
26 | });
27 | it("namedNode", function(){
28 | assert(factory.namedNode("http://example.com/") instanceof rdf.NamedNode);
29 | assert(factory.namedNode("http://example.com/").equals(new rdf.NamedNode('http://example.com/')));
30 | assert(!factory.namedNode("http://example.com/").equals(new rdf.NamedNode('http://foo.example.net/')));
31 | });
32 | it("blankNode", function(){
33 | assert(factory.blankNode() instanceof rdf.BlankNode);
34 | assert(factory.blankNode("foo") instanceof rdf.BlankNode);
35 | });
36 | it("literal", function(){
37 | assert(factory.literal("foo bar") instanceof rdf.Literal);
38 | assert(factory.literal("foo bar").equals(new rdf.Literal('foo bar')));
39 | assert(!factory.literal("foo bar").equals(new rdf.Literal('foo bar', '@en')));
40 | });
41 | it("variable", function(){
42 | assert(factory.variable("n") instanceof rdf.Variable);
43 | assert(factory.variable("n").equals(new rdf.Variable('n')));
44 | assert(!factory.variable("n").equals(new rdf.Variable('q')));
45 | });
46 | it("defaultGraph", function(){
47 | assert(factory.defaultGraph() instanceof rdf.DefaultGraph);
48 | assert(factory.defaultGraph()===factory.defaultGraph());
49 | });
50 | it("triple", function(){
51 | assert(factory.triple(factory.namedNode("http://example.com/"), factory.namedNode("http://example.com/"), factory.namedNode("http://example.com/")) instanceof rdf.Triple);
52 | assert(factory.triple(factory.namedNode("http://example.com/"), factory.namedNode("http://example.com/"), factory.namedNode("http://example.com/")).equals(new rdf.Triple(new rdf.NamedNode("http://example.com/"), new rdf.NamedNode("http://example.com/"), new rdf.NamedNode("http://example.com/"), new rdf.NamedNode("http://example.com/"))));
53 | });
54 | it("quad", function(){
55 | assert(factory.quad(factory.namedNode("http://example.com/"), factory.namedNode("http://example.com/"), factory.namedNode("http://example.com/")) instanceof rdf.Quad);
56 | assert(factory.quad(factory.namedNode("http://example.com/"), factory.namedNode("http://example.com/"), factory.namedNode("http://example.com/")).equals(new rdf.Quad(new rdf.NamedNode("http://example.com/"), new rdf.NamedNode("http://example.com/"), new rdf.NamedNode("http://example.com/"), new rdf.DefaultGraph)));
57 | });
58 | it("dataset", function(){
59 | assert(factory.dataset() instanceof rdf.Dataset);
60 | });
61 | describe("fromTerm", function(){
62 | it("fromTerm(NamedNode)", function(){
63 | var term = factory.fromTerm({termType:'NamedNode', value:'http://example.com/'});
64 | assert(term instanceof rdf.NamedNode);
65 | assert(term.equals(new rdf.NamedNode('http://example.com/')));
66 | assert(!term.equals(new rdf.NamedNode('http://foo.example.net/')));
67 | });
68 | it("fromTerm(BlankNode)", function(){
69 | var term = factory.fromTerm({termType:'BlankNode', value:'b1'});
70 | assert(term instanceof rdf.BlankNode);
71 | });
72 | it("fromTerm(xsd:string)", function(){
73 | var term = factory.fromTerm({termType:'Literal', value:'foo', datatype:{termType:"NamedNode", value:rdf.xsdns("string")}});
74 | assert(term instanceof rdf.Literal);
75 | assert(term.equals(new rdf.Literal('foo', rdf.xsdns("string"))));
76 | assert(term.equals(new rdf.Literal('foo')));
77 | assert(!term.equals(new rdf.Literal('foo', '@en')));
78 | });
79 | it("fromTerm(xsd:boolean)", function(){
80 | var term = factory.fromTerm({termType:'Literal', value:'foo', datatype:{termType:"NamedNode", value:rdf.xsdns("boolean")}});
81 | assert(term instanceof rdf.Literal);
82 | assert(term.equals(new rdf.Literal('foo', rdf.xsdns("boolean"))));
83 | assert(!term.equals(new rdf.Literal('foo')));
84 | });
85 | it("fromTerm(rdf:langString)", function(){
86 | var term = factory.fromTerm({termType:'Literal', value:'foo', datatype:{termType:"NamedNode", value:rdf.rdfns("langString")}, language:"en"});
87 | assert(term instanceof rdf.Literal);
88 | assert(term.equals(new rdf.Literal('foo', '@en')));
89 | assert(!term.equals(new rdf.Literal('foo')));
90 | });
91 | it("fromTerm(Variable)", function(){
92 | var term = factory.fromTerm({termType:'Variable', value:'name'});
93 | assert(term instanceof rdf.Variable);
94 | assert(term.equals(new rdf.Variable('name')));
95 | assert(!term.equals(new rdf.Variable('baz')));
96 | });
97 | it("fromTerm(DefaultGraph)", function(){
98 | var term = factory.fromTerm({termType:'DefaultGraph', value:''});
99 | assert(term instanceof rdf.DefaultGraph);
100 | assert(term.equals(factory.defaultGraph()));
101 | assert(!term.equals(factory.namedNode('http://example.com/')));
102 | });
103 | });
104 | it("fromTriple", function(){
105 | var quad = factory.fromTriple({
106 | subject: {termType:"NamedNode", value:"http://example.com/"},
107 | predicate: {termType:"NamedNode", value:"http://example.com/"},
108 | object: {termType:"NamedNode", value:"http://example.com/"},
109 | });
110 | assert(quad instanceof rdf.Triple);
111 | assert(quad.equals(new rdf.Triple('http://example.com/', 'http://example.com/', 'http://example.com/')));
112 | assert(!quad.equals(new rdf.Triple('http://example.com/', 'http://example.com/', 'http://foo.example.net/')));
113 | });
114 | it("fromQuad", function(){
115 | var quad = factory.fromQuad({
116 | subject: {termType:"NamedNode", value:"http://example.com/"},
117 | predicate: {termType:"NamedNode", value:"http://example.com/"},
118 | object: {termType:"NamedNode", value:"http://example.com/"},
119 | graph: {termType:"DefaultGraph"},
120 | });
121 | assert(quad instanceof rdf.Quad);
122 | assert(quad.equals(new rdf.Quad('http://example.com/', 'http://example.com/', 'http://example.com/', factory.defaultGraph())));
123 | assert(!quad.equals(new rdf.Quad('http://example.com/', 'http://example.com/', 'http://foo.example.net/', factory.defaultGraph())));
124 | });
125 | }
126 |
127 | describe('factory', DataFactoryTests);
128 |
129 | describe('factory (with builtins)', function(){
130 | before(function(){
131 | rdf.setBuiltins();
132 | });
133 | after(function(){
134 | rdf.unsetBuiltins();
135 | });
136 | DataFactoryTests();
137 | });
138 |
--------------------------------------------------------------------------------
/test/DefaultGraph.test.js:
--------------------------------------------------------------------------------
1 | var assert = require('assert');
2 | var rdf = require('..');
3 |
4 | function DefaultGraphTests(){
5 | it("RDF Representation", function(){
6 | /*
7 | interface DefaultGraph : Term {
8 | attribute string termType;
9 | attribute string value;
10 | boolean equals(Term other);
11 | };
12 | */
13 | var t = rdf.factory.defaultGraph();
14 | assert(t instanceof rdf.Term);
15 | assert.strictEqual(t.termType, 'DefaultGraph');
16 | assert.strictEqual(t.value, '');
17 | });
18 | it("DefaultGraph#toNT", function(){
19 | var t = rdf.factory.defaultGraph();
20 | assert.throws(function(){ t.toNT(); });
21 | });
22 | it("DefaultGraph#toTurtle", function(){
23 | var t = rdf.factory.defaultGraph();
24 | assert.throws(function(){ t.toTurtle(); });
25 | });
26 | it("DefaultGraph#toString", function(){
27 | var t = rdf.factory.defaultGraph();
28 | assert.strictEqual(t.toString(), '');
29 | });
30 | it("DefaultGraph#equals", function(){
31 | var t1 = rdf.factory.defaultGraph();
32 | var t2 = rdf.factory.defaultGraph();
33 | assert(t1.equals(t2));
34 | });
35 | }
36 |
37 | describe('DefaultGraph', DefaultGraphTests);
38 |
39 | describe('DefaultGraph (with builtins)', function(){
40 | before(function(){
41 | rdf.setBuiltins();
42 | });
43 | after(function(){
44 | rdf.unsetBuiltins();
45 | });
46 | DefaultGraphTests();
47 | });
48 |
--------------------------------------------------------------------------------
/test/Literal.test.js:
--------------------------------------------------------------------------------
1 | var assert = require('assert');
2 | var rdf = require('..');
3 |
4 | function LiteralTests(){
5 | it("js3", function(){
6 | var t = new rdf.Literal("A String");
7 | assert.strictEqual(t.nodeType(), 'PlainLiteral');
8 | assert.strictEqual(t.type, null);
9 | assert.strictEqual(t.language, null);
10 | assert.strictEqual(t.toNT(), '"A String"');
11 | assert.strictEqual(t.toTurtle(), '"A String"');
12 | assert.strictEqual(t.n3(), '"A String"');
13 | });
14 | it("RDF Interfaces", function(){
15 | /*
16 | [NoInterfaceObject]
17 | interface Literal : RDFNode {
18 | readonly attribute DOMString nominalValue;
19 | readonly attribute DOMString? language;
20 | readonly attribute NamedNode? datatype;
21 | any valueOf ();
22 | };
23 | [NoInterfaceObject]
24 | interface RDFNode {
25 | readonly attribute any nominalValue;
26 | readonly attribute DOMString interfaceName;
27 | DOMString toString ();
28 | any valueOf ();
29 | DOMString toNT ();
30 | boolean equals (any tocompare);
31 | };
32 | */
33 | var t = new rdf.Literal("A String");
34 | assert(t instanceof rdf.RDFNode);
35 | assert.strictEqual(t.nominalValue, "A String");
36 | assert.strictEqual(t.datatype.nominalValue, "http://www.w3.org/2001/XMLSchema#string");
37 | assert.strictEqual(t.language, null);
38 | assert.strictEqual(t.toNT(), '"A String"');
39 | assert(t.equals(new rdf.Literal("A String")));
40 | });
41 | it("RDF Representation", function(){
42 | /*
43 | interface Literal : Term {
44 | attribute string termType;
45 | attribute string value;
46 | attribute string language;
47 | attribute NamedNode datatype;
48 | boolean equals(Term other);
49 | };
50 | interface Term {
51 | attribute string termType;
52 | attribute string value;
53 | boolean equals(Term other);
54 | };
55 | */
56 | var t = new rdf.Literal("A String");
57 | assert(t instanceof rdf.Term);
58 | assert.strictEqual(t.termType, 'Literal');
59 | assert.strictEqual(t.value, 'A String');
60 | assert.strictEqual(t.datatype.value, 'http://www.w3.org/2001/XMLSchema#string');
61 | });
62 | it("Language instance @en", function(){
63 | var t = new rdf.Literal('That Seventies Show', '@en');
64 | assert.strictEqual(t.nodeType(), 'PlainLiteral');
65 | assert.strictEqual(t.termType, 'Literal');
66 | assert.strictEqual(t.datatype.value, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString');
67 | assert.strictEqual(t.language, 'en');
68 | assert.strictEqual(t.toNT(), '"That Seventies Show"@en');
69 | assert.strictEqual(t.toTurtle(), '"That Seventies Show"@en');
70 | assert.strictEqual(t.toTurtle(), '"That Seventies Show"@en');
71 | // Equality tests
72 | assert.ok(t.equals(new rdf.Literal('That Seventies Show', '@en')));
73 | //assert.ok(t.equals('That Seventies Show'));
74 | assert.ok(!t.equals(new rdf.Literal('String', '@en')));
75 | assert.ok(!t.equals(new rdf.Literal('That Seventies Show', '@fr-be')));
76 | //assert.ok(!t.equals('Cette Série des Années Septante'));
77 | });
78 | it("Language instance @fr-be", function(){
79 | var t = new rdf.Literal('Cette Série des Années Septante', 'fr-be');
80 | assert.strictEqual(t.nodeType(), 'PlainLiteral');
81 | assert.strictEqual(t.termType, 'Literal');
82 | assert.strictEqual(t.datatype.toString(), 'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString');
83 | assert.strictEqual(t.language, 'fr-be');
84 | assert.strictEqual(t.toNT(), '"Cette S\\u00E9rie des Ann\\u00E9es Septante"@fr-be');
85 | assert.strictEqual(t.toTurtle(), '"Cette S\\u00E9rie des Ann\\u00E9es Septante"@fr-be');
86 | // Equality tests
87 | assert.ok(t.equals(new rdf.Literal('Cette Série des Années Septante', '@fr-be')));
88 | assert.ok(!t.equals(new rdf.Literal('Cette Serie des Annees Septante', '@fr-be')));
89 | assert.ok(!t.equals(new rdf.Literal('Cette Série des Années Septante', '@en')));
90 | assert.ok(!t.equals('Cette Série des Années Septante'));
91 | assert.ok(!t.equals('That Seventies Show'));
92 | });
93 | it("Typed instance (string)", function(){
94 | var t = new rdf.Literal('123', 'http://www.w3.org/2001/XMLSchema#integer');
95 | assert.strictEqual(t.nodeType(), 'TypedLiteral');
96 | assert.strictEqual(t.termType, 'Literal');
97 | assert.equal(t.datatype.toString(), 'http://www.w3.org/2001/XMLSchema#integer');
98 | assert.strictEqual(t.language, null);
99 | assert.strictEqual(t.toNT(), '"123"^^');
100 | assert.strictEqual(t.toTurtle(), '123');
101 | // Equality tests
102 | assert.ok(t.equals(new rdf.Literal('123', 'http://www.w3.org/2001/XMLSchema#integer')));
103 | assert.ok(!t.equals('123'));
104 | assert.ok(!t.equals(new rdf.Literal('1', 'http://www.w3.org/2001/XMLSchema#integer')));
105 | assert.ok(!t.equals(new rdf.Literal('123', 'http://www.w3.org/2001/XMLSchema#decimal')));
106 | assert.ok(!t.equals('1'));
107 | });
108 | it("Typed instance (NamedNode)", function(){
109 | var t = new rdf.Literal('123', new rdf.NamedNode('http://www.w3.org/2001/XMLSchema#integer'));
110 | assert.ok(t instanceof rdf.Literal);
111 | assert.strictEqual(t.nodeType(), 'TypedLiteral');
112 | assert.strictEqual(t.termType, 'Literal');
113 | assert.equal(t.datatype.toString(), 'http://www.w3.org/2001/XMLSchema#integer');
114 | assert.strictEqual(t.language, null);
115 | assert.strictEqual(t.toNT(), '"123"^^');
116 | assert.strictEqual(t.toTurtle(), '123');
117 | assert.ok(t.equals(new rdf.Literal('123', 'http://www.w3.org/2001/XMLSchema#integer')));
118 | assert.ok(!t.equals('123'));
119 | assert.ok(!t.equals(new rdf.Literal('1', 'http://www.w3.org/2001/XMLSchema#integer')));
120 | assert.ok(!t.equals(new rdf.Literal('123', 'http://www.w3.org/2001/XMLSchema#decimal')));
121 | assert.ok(!t.equals('1'));
122 | });
123 | it("Typed instance (string) (xsd:string)", function(){
124 | var t = new rdf.Literal('123', 'http://www.w3.org/2001/XMLSchema#string');
125 | assert.ok(t instanceof rdf.Literal);
126 | // This datatype causes this exeption
127 | assert.strictEqual(t.nodeType(), 'PlainLiteral');
128 | assert.strictEqual(t.termType, 'Literal');
129 | assert.equal(t.datatype.toString(), 'http://www.w3.org/2001/XMLSchema#string');
130 | assert.strictEqual(t.language, null);
131 | assert.strictEqual(t.toNT(), '"123"');
132 | //assert.strictEqual(t.toTurtle(), '123');
133 | assert.ok(t.equals(new rdf.Literal('123', 'http://www.w3.org/2001/XMLSchema#string')));
134 | assert.ok(t.equals(new rdf.Literal('123')));
135 | assert.ok(!t.equals('123'));
136 | assert.ok(!t.equals(new rdf.Literal('1', 'http://www.w3.org/2001/XMLSchema#integer')));
137 | assert.ok(!t.equals(new rdf.Literal('123', 'http://www.w3.org/2001/XMLSchema#decimal')));
138 | assert.ok(!t.equals('1'));
139 | });
140 | it("Language string (rdf:langString)", function(){
141 | var t = new rdf.Literal('123', '@en', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString');
142 | assert.ok(t instanceof rdf.Literal);
143 | // Leave this behavior undefined for now, consider this deprecated anyways
144 | //assert.strictEqual(t.nodeType(), 'TypedLiteral');
145 | assert.strictEqual(t.termType, 'Literal');
146 | assert.equal(t.datatype.toString(), 'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString');
147 | assert.strictEqual(t.language, 'en');
148 | assert.strictEqual(t.toNT(), '"123"@en');
149 | assert.strictEqual(t.toTurtle(), '"123"@en');
150 | assert.ok(t.equals(new rdf.Literal('123', '@en')));
151 | assert.ok(!t.equals('123'));
152 | assert.ok(!t.equals(new rdf.Literal('123')));
153 | assert.ok(!t.equals(new rdf.Literal('123', 'http://www.w3.org/2001/XMLSchema#string')));
154 | assert.ok(!t.equals('1'));
155 | });
156 | it("Typed instance (NamedNode) (xsd:string)", function(){
157 | var t = new rdf.Literal('123', new rdf.NamedNode('http://www.w3.org/2001/XMLSchema#string'));
158 | assert.ok(t instanceof rdf.Literal);
159 | //assert.strictEqual(t.nodeType(), 'TypedLiteral');
160 | assert.strictEqual(t.termType, 'Literal');
161 | assert.equal(t.datatype.toString(), 'http://www.w3.org/2001/XMLSchema#string');
162 | assert.strictEqual(t.language, null);
163 | assert.strictEqual(t.toNT(), '"123"');
164 | assert.strictEqual(t.toTurtle(), '"123"');
165 | assert.ok(t.equals(new rdf.Literal('123', 'http://www.w3.org/2001/XMLSchema#string')));
166 | assert.ok(t.equals(new rdf.Literal('123')));
167 | assert.ok(!t.equals('123'));
168 | assert.ok(!t.equals(new rdf.Literal('1', 'http://www.w3.org/2001/XMLSchema#integer')));
169 | assert.ok(!t.equals(new rdf.Literal('123', 'http://www.w3.org/2001/XMLSchema#decimal')));
170 | });
171 | describe("toTurtle", function(){
172 | it("TypedLiteral xsd:integer", function(){
173 | var t = new rdf.Literal('123', new rdf.NamedNode('http://www.w3.org/2001/XMLSchema#integer'));
174 | assert.strictEqual(t.toNT(), '"123"^^');
175 | assert.strictEqual(t.toTurtle(), '123');
176 | });
177 | it("TypedLiteral invalid xsd:integer", function(){
178 | var t = new rdf.Literal('something', new rdf.NamedNode('http://www.w3.org/2001/XMLSchema#integer'));
179 | assert.strictEqual(t.toNT(), '"something"^^');
180 | assert.strictEqual(t.toTurtle(), '"something"^^');
181 | });
182 | it("TypedLiteral xsd:string", function(){
183 | var t = new rdf.Literal('a string', new rdf.NamedNode('http://www.w3.org/2001/XMLSchema#string'));
184 | assert.strictEqual(t.toNT(), '"a string"'); // NT strips xsd:string as a historical relic
185 | assert.strictEqual(t.toTurtle(), '"a string"');
186 | });
187 | it("TypedLiteral xsd:decimal", function(){
188 | var t = new rdf.Literal('123.0', new rdf.NamedNode('http://www.w3.org/2001/XMLSchema#decimal'));
189 | assert.strictEqual(t.toNT(), '"123.0"^^');
190 | assert.strictEqual(t.toTurtle(), '123.0');
191 | });
192 | it("TypedLiteral xsd:double", function(){
193 | var t = new rdf.Literal('4.2E9', new rdf.NamedNode('http://www.w3.org/2001/XMLSchema#double'));
194 | assert.strictEqual(t.toNT(), '"4.2E9"^^');
195 | assert.strictEqual(t.toTurtle(), '4.2E9');
196 | });
197 | it("TypedLiteral xsd:boolean", function(){
198 | var t = new rdf.Literal('true', new rdf.NamedNode('http://www.w3.org/2001/XMLSchema#boolean'));
199 | assert.strictEqual(t.toNT(), '"true"^^');
200 | assert.strictEqual(t.toTurtle(), 'true');
201 | });
202 | it("TypedLiteral xsd:boolean (number)", function(){
203 | var t = new rdf.Literal('1', new rdf.NamedNode('http://www.w3.org/2001/XMLSchema#boolean'));
204 | assert.strictEqual(t.toNT(), '"1"^^');
205 | assert.strictEqual(t.toTurtle(), '"1"^^');
206 | });
207 | });
208 | describe("valueOf", function(){
209 | testValueOf("A STRING", 'string', "A STRING");
210 | testValueOf("true", "boolean", true);
211 | testValueOf("1", "boolean", true);
212 | testValueOf("false", "boolean", false);
213 | testValueOf("0", "boolean", false);
214 | testValueOf("0.5", "float", 0.5);
215 | testValueOf("INF", "float", Number.POSITIVE_INFINITY);
216 | testValueOf("-INF", "float", Number.NEGATIVE_INFINITY);
217 | testValueOf("NaN", "float", 0/0);
218 | testValueOf("-14000", "integer", -14000);
219 | testValueOf("-9223372036854775808", "long", -9223372036854775808);
220 | testValueOf("9223372036854775807", "long", 9223372036854775807);
221 | testValueOf("1.578125", "float", 1.578125);
222 | testValueOf("-1.2344e56", "float", -1.2344e56);
223 | testValueOf("-42", "nonPositiveInteger", -42);
224 | testValueOf("0", "nonPositiveInteger", 0);
225 | testValueOf("42", "nonNegativeInteger", 42);
226 | testValueOf("0", "nonNegativeInteger", 0);
227 | testValueOf("-42", "negativeInteger", -42);
228 | testValueOf("-2147483648", "long", -2147483648);
229 | testValueOf("2147483647", "long", 2147483647);
230 | testValueOf("2000-01-01", "date", new Date('Sat, 01 Jan 2000 00:00:00 GMT'));
231 | //testValueOf("21:32:52", "time", new Date('Sat, 01 Jan 2000 00:00:00 GMT')); // There's no good way to represent just time-of-day... Ignore this guy?
232 | testValueOf("2001-10-26T21:32:52.12679", "dateTime", new Date('2001-10-26T21:32:52.12679'));
233 | // TODO probbly should verify the inputs are of the correct range?
234 | });
235 | }
236 |
237 | describe('Literal', LiteralTests);
238 |
239 | describe('Literal (with builtins)', function(){
240 | before(function(){
241 | rdf.setBuiltins();
242 | });
243 | after(function(){
244 | rdf.unsetBuiltins();
245 | });
246 | LiteralTests();
247 | });
248 |
249 | function testValueOf(literal, type, test){
250 | // Literal must be a string
251 | it('Literal('+JSON.stringify(literal)+', xsd:'+type+').valueOf()', function(){
252 | var value = new rdf.Literal(literal, rdf.xsdns(type)).valueOf();
253 | if(type=='date' || type=='dateTime'){
254 | assert.ok(value instanceof Date);
255 | assert.strictEqual(value.getTime(), test.getTime());
256 | }else if(Number.isNaN(test)){
257 | assert.ok(Number.isNaN(value));
258 | }else{
259 | assert.strictEqual(value, test);
260 | }
261 | });
262 | }
263 |
--------------------------------------------------------------------------------
/test/NamedNode.test.js:
--------------------------------------------------------------------------------
1 | var assert = require('assert');
2 | var rdf = require('..');
3 |
4 | function NamedNodeTests(){
5 | it("js3", function(){
6 | var t = new rdf.NamedNode('http://example.com/');
7 | assert.strictEqual(t.nodeType(), 'IRI');
8 | assert.strictEqual(t.toNT(), '');
9 | assert.strictEqual(t.toTurtle(), '');
10 | assert.strictEqual(t.n3(), '');
11 | });
12 | it("RDF Interfaces", function(){
13 | /*
14 | [NoInterfaceObject]
15 | interface NamedNode : RDFNode {
16 | readonly attribute any nominalValue;
17 | };
18 | [NoInterfaceObject]
19 | interface RDFNode {
20 | readonly attribute any nominalValue;
21 | readonly attribute DOMString interfaceName;
22 | DOMString toString ();
23 | any valueOf ();
24 | DOMString toNT ();
25 | boolean equals (any tocompare);
26 | };
27 | */
28 | var t = new rdf.NamedNode('http://example.com/');
29 | assert.strictEqual(t.nominalValue, 'http://example.com/');
30 | assert(t instanceof rdf.RDFNode);
31 | assert.strictEqual(t.interfaceName, 'NamedNode');
32 | assert.strictEqual(t.toString(), 'http://example.com/');
33 | assert.strictEqual(t.valueOf(), 'http://example.com/');
34 | assert.strictEqual(t.toNT(), '');
35 | assert(t.equals('http://example.com/'));
36 | assert(t.equals(new rdf.NamedNode('http://example.com/')));
37 | });
38 | it("RDF Representation", function(){
39 | /*
40 | interface NamedNode : Term {
41 | attribute string termType;
42 | attribute string value;
43 | boolean equals(Term other);
44 | };
45 | interface Term {
46 | attribute string termType;
47 | attribute string value;
48 | boolean equals(Term other);
49 | };
50 | */
51 | var t = new rdf.NamedNode('http://example.com/');
52 | assert(t instanceof rdf.Term);
53 | assert.strictEqual(t.termType, 'NamedNode'); // 2017 Community Group variant
54 | assert.strictEqual(t.value, 'http://example.com/'); // 2017 CG variant
55 | assert(t.equals(new rdf.NamedNode('http://example.com/')));
56 | });
57 | it("valueOf", function(){
58 | var t = new rdf.NamedNode('http://example.com/');
59 | assert.strictEqual(t.toString(), 'http://example.com/');
60 | });
61 | it("toNT", function(){
62 | var t = new rdf.NamedNode('http://example.com/');
63 | assert.strictEqual(t.toNT(), '');
64 | });
65 | it("toTurtle", function(){
66 | var t = new rdf.NamedNode('http://example.com/');
67 | assert.strictEqual(t.toTurtle(), '');
68 | });
69 | it("n3", function(){
70 | var t = new rdf.NamedNode('http://example.com/');
71 | assert.strictEqual(t.n3(), '');
72 | });
73 | it("equals", function(){
74 | var t = new rdf.NamedNode('http://example.com/');
75 | assert.ok(t.equals(new rdf.NamedNode('http://example.com/')));
76 | assert.ok(!t.equals(new rdf.NamedNode('http://example.com')));
77 | assert.ok(t.equals('http://example.com/'));
78 | assert.ok(!t.equals('http://example.com'));
79 | });
80 | }
81 |
82 | describe('NamedNode', NamedNodeTests);
83 |
84 | describe('NamedNode (with builtins)', function(){
85 | before(function(){
86 | rdf.setBuiltins();
87 | });
88 | after(function(){
89 | rdf.unsetBuiltins();
90 | });
91 | NamedNodeTests();
92 | });
93 |
--------------------------------------------------------------------------------
/test/PrefixMap.test.js:
--------------------------------------------------------------------------------
1 |
2 | var assert = require('assert');
3 | var rdf = require('..');
4 |
5 | /*
6 | [NoInterfaceObject]
7 | interface PrefixMap {
8 | omittable getter DOMString get (DOMString prefix);
9 | omittable setter void set (DOMString prefix, DOMString iri);
10 | omittable deleter void remove (DOMString prefix);
11 | DOMString resolve (DOMString curie);
12 | DOMString shrink (DOMString iri);
13 | void setDefault (DOMString iri);
14 | PrefixMap addAll (PrefixMap prefixes, optional boolean override);
15 | };
16 | */
17 |
18 | describe('PrefixMap', function(){
19 | it('PrefixMap#get(string, string)', function(){
20 | var map = new rdf.PrefixMap;
21 | assert.equal(typeof map.get, 'function');
22 | });
23 | it('PrefixMap#set(string, string)', function(){
24 | var map = new rdf.PrefixMap;
25 | assert.equal(typeof map.set, 'function');
26 | assert.equal(typeof map.set('ex', 'http://example.com/'), 'undefined');
27 | assert.equal(map.resolve('ex:type'), 'http://example.com/type');
28 | });
29 | it('PrefixMap#setDefault(string)', function(){
30 | var map = new rdf.PrefixMap;
31 | assert.equal(typeof map.set, 'function');
32 | assert.equal(typeof map.setDefault('http://example.com/'), 'undefined');
33 | assert.equal(map.resolve(':type'), 'http://example.com/type');
34 | });
35 | it("PrefixMap#set negative tests", function(){
36 | var map = new rdf.PrefixMap;
37 | assert.equal(typeof map.set, 'function');
38 | assert.throws(function(){
39 | map.set('0', 'http://example.com/');
40 | });
41 | assert.throws(function(){
42 | map.set('::', 'http://example.com/');
43 | });
44 | assert.throws(function(){
45 | map.set(' ', 'http://example.com/');
46 | });
47 | assert.throws(function(){
48 | map.set('.', 'http://example.com/');
49 | });
50 | });
51 | it("PrefixMap#remove(string)", function(){
52 | var map = new rdf.PrefixMap;
53 | map.set('prefix', 'http://example.com/vocab/foo/');
54 | map.remove('prefix');
55 | assert.strictEqual(map.resolve('prefix:foo'), null);
56 | });
57 | it("PrefixMap#resolve(string)", function(){
58 | var map = new rdf.PrefixMap;
59 | map.set('ex', 'http://example.com/');
60 | assert.equal(typeof map.resolve, 'function');
61 | assert.equal(typeof map.resolve('ex:type'), 'string');
62 | assert.equal(map.resolve('undefinedTerm'), null);
63 | });
64 | it("PrefixMap#shrink(string)", function(){
65 | var map = new rdf.PrefixMap;
66 | map.set('ex2', 'http://example.com/vocab/foo/');
67 | map.set('ex', 'http://example.com/');
68 | map.set('exv', 'http://example.com/vocab/');
69 | map.set('🐉', 'http://example.com/vocab/dragon/');
70 |
71 | assert.equal(map.shrink('http://example.com/vocab/a'), 'exv:a');
72 | assert.equal(map.shrink('http://example.com/vocab/foo/b'), 'ex2:b');
73 | assert.equal(map.shrink('http://example.com/c'), 'ex:c');
74 | // File is UTF-8 (probably), but escape sequence UTF-16 surrogate pairs
75 | // idk I didn't invent it, man
76 | assert.equal(map.shrink('http://example.com/vocab/dragon/🐲'), '\uD83D\uDC09:\uD83D\uDC32');
77 | assert.equal(map.shrink('http://example.com/vocab/dragon/🐲🐧'), '\uD83D\uDC09:\uD83D\uDC32\uD83D\uDC27');
78 | });
79 | it("PrefixMap#addAll", function(){
80 | var map = new rdf.PrefixMap;
81 | assert.equal(typeof map.addAll, 'function');
82 | map.set('ex', 'http://example.com/');
83 |
84 | var other = new rdf.PrefixMap;
85 | other.set('ex', 'http://example.org/vocab/');
86 | other.set('fx', 'http://example.org/vocab/');
87 |
88 | map.addAll(other);
89 | assert.equal(map.resolve('ex:a'), 'http://example.com/a');
90 | assert.equal(map.resolve('fx:a'), 'http://example.org/vocab/a');
91 | assert.strictEqual(map.resolve('c:foo'), null);
92 | });
93 | it("PrefixMap#addAll (overwrite=false)", function(){
94 | var map = new rdf.PrefixMap;
95 | map.set('ex', 'http://example.com/');
96 |
97 | var other = new rdf.PrefixMap;
98 | other.set('ex', 'http://example.org/vocab/');
99 | other.set('fx', 'http://example.org/vocab/');
100 |
101 | map.addAll(other, false);
102 | assert.equal(map.resolve('ex:a'), 'http://example.com/a');
103 | assert.equal(map.resolve('fx:a'), 'http://example.org/vocab/a');
104 | assert.strictEqual(map.resolve('c:foo'), null);
105 | });
106 | it("PrefixMap#addAll (overwrite=true)", function(){
107 | var map = new rdf.PrefixMap;
108 | map.set('ex', 'http://example.com/');
109 |
110 | var other = new rdf.PrefixMap;
111 | other.set('ex', 'http://example.org/vocab/');
112 | other.set('fx', 'http://example.org/vocab/');
113 |
114 | map.addAll(other, true);
115 | assert.equal(map.resolve('ex:a'), 'http://example.org/vocab/a');
116 | assert.equal(map.resolve('fx:a'), 'http://example.org/vocab/a');
117 | assert.strictEqual(map.resolve('c:foo'), null);
118 | });
119 | it("PrefixMap#list", function(){
120 | var map = new rdf.PrefixMap;
121 | assert.equal(map.list().length, 0);
122 | map.set('ex', 'http://example.com/');
123 | var list = map.list();
124 | assert.equal(list.length, 1);
125 | assert.equal(list[0], 'ex');
126 | });
127 | });
128 |
--------------------------------------------------------------------------------
/test/Profile.test.js:
--------------------------------------------------------------------------------
1 |
2 | var assert = require('assert');
3 | var rdf = require('..');
4 |
5 | /*
6 | [NoInterfaceObject]
7 | interface Profile {
8 | readonly attribute PrefixMap prefixes;
9 | readonly attribute TermMap terms;
10 | DOMString resolve (DOMString toresolve);
11 | void setDefaultVocabulary (DOMString iri);
12 | void setDefaultPrefix (DOMString iri);
13 | void setTerm (DOMString term, DOMString iri);
14 | void setPrefix (DOMString prefix, DOMString iri);
15 | Profile importProfile (Profile profile, optional boolean override);
16 | };
17 | */
18 |
19 | describe('Profile', function(){
20 | it("prefixes", function(){
21 | var profile = new rdf.Profile;
22 | assert.equal(typeof profile.prefixes, 'object');
23 | });
24 | it("terms", function(){
25 | var profile = new rdf.Profile;
26 | assert.equal(typeof profile.terms, 'object');
27 | });
28 | it('builtin prefixes', function(){
29 | var env = new rdf.RDFEnvironment;
30 | assert.strictEqual(env.resolve("rdf:type"), "http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
31 | assert.strictEqual(env.resolve("rdfs:Class"), "http://www.w3.org/2000/01/rdf-schema#Class");
32 | assert.strictEqual(env.resolve("unknownprefix2:foo"), null);
33 | });
34 | it('define prefix', function(){
35 | var env = new rdf.RDFEnvironment;
36 | assert.strictEqual(env.resolve("unkfoo:foo"), null);
37 | env.setPrefix("unkfoo", "http://example.com/1/ex/42/");
38 | assert.strictEqual(env.resolve("unkfoo:foo"), "http://example.com/1/ex/42/foo");
39 | });
40 | it('define default prefix', function(){
41 | var env = new rdf.RDFEnvironment;
42 | assert.strictEqual(env.resolve(":bar"), null);
43 | env.setDefaultPrefix("http://example.com/2/ex/42/");
44 | assert.strictEqual(env.resolve(":answer"), "http://example.com/2/ex/42/answer");
45 | });
46 | it("resolve", function(){
47 | var profile = new rdf.Profile;
48 | profile.setPrefix('ex', 'http://example.com/');
49 | assert.equal(typeof profile.resolve, 'function');
50 | assert.equal(typeof profile.resolve('ex:type'), 'string');
51 | assert.equal(profile.resolve('undefinedTerm'), null);
52 | });
53 | it("setDefaultVocabulary", function(){
54 | var profile = new rdf.Profile;
55 | assert.equal(typeof profile.setDefaultVocabulary, 'function');
56 | assert.equal(typeof profile.setDefaultVocabulary('http://example.com/q/'), 'undefined');
57 | assert.equal(profile.resolve('Friend'), 'http://example.com/q/Friend');
58 | assert.equal(profile.terms.resolve('Friend'), 'http://example.com/q/Friend');
59 | });
60 | it("setDefaultPrefix", function(){
61 | var profile = new rdf.Profile;
62 | assert.equal(typeof profile.setDefaultPrefix, 'function');
63 | assert.equal(typeof profile.setDefaultPrefix('http://example.org/vocab/'), 'undefined');
64 | assert.equal(profile.resolve(':Friend'), 'http://example.org/vocab/Friend');
65 | assert.equal(profile.prefixes.resolve(':Friend'), 'http://example.org/vocab/Friend');
66 | });
67 | it("setTerm", function(){
68 | var profile = new rdf.Profile;
69 | assert.equal(typeof profile.setTerm, 'function');
70 | assert.equal(typeof profile.setTerm('a', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), 'undefined');
71 | assert.equal(profile.resolve('a'), 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type');
72 | assert.equal(profile.terms.resolve('a'), 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type');
73 | });
74 | it("setPrefix", function(){
75 | var profile = new rdf.Profile;
76 | assert.equal(typeof profile.setPrefix, 'function');
77 | assert.equal(typeof profile.setPrefix('ex', 'http://example.com/'), 'undefined');
78 | assert.equal(profile.prefixes.resolve('ex:type'), 'http://example.com/type');
79 | assert.equal(profile.resolve('ex:type'), 'http://example.com/type');
80 | });
81 | it("setPrefix negative tests", function(){
82 | var profile = new rdf.Profile;
83 | assert.equal(typeof profile.setPrefix, 'function');
84 | assert.throws(function(){
85 | profile.setPrefix('0', 'http://example.com/');
86 | });
87 | assert.throws(function(){
88 | profile.setPrefix('::', 'http://example.com/');
89 | });
90 | assert.throws(function(){
91 | profile.setPrefix(' ', 'http://example.com/');
92 | });
93 | assert.throws(function(){
94 | profile.setPrefix('.', 'http://example.com/');
95 | });
96 | });
97 | it("importProfile", function(){
98 | var profile = new rdf.Profile;
99 | assert.equal(typeof profile.importProfile, 'function');
100 | profile.setPrefix('ex', 'http://example.com/');
101 | profile.setTerm('a', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type');
102 |
103 | var other = new rdf.Profile;
104 | other.setPrefix('ex', 'http://example.org/vocab/');
105 | other.setTerm('a', 'http://example.org/type');
106 | other.setPrefix('fx', 'http://example.org/vocab/');
107 | other.setTerm('b', 'http://example.org/type');
108 |
109 | profile.importProfile(other);
110 | assert.equal(profile.resolve('ex:a'), 'http://example.com/a');
111 | assert.equal(profile.resolve('a'), 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type');
112 | assert.equal(profile.resolve('fx:a'), 'http://example.org/vocab/a');
113 | assert.equal(profile.resolve('b'), 'http://example.org/type');
114 | assert.strictEqual(profile.resolve('term'), null);
115 | assert.strictEqual(profile.resolve('c:foo'), null);
116 | });
117 | it("importProfile (overwrite=false)", function(){
118 | var profile = new rdf.Profile;
119 | profile.setPrefix('ex', 'http://example.com/');
120 | profile.setTerm('a', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type');
121 |
122 | var other = new rdf.Profile;
123 | other.setPrefix('ex', 'http://example.org/vocab/');
124 | other.setTerm('a', 'http://example.org/type');
125 | other.setPrefix('fx', 'http://example.org/vocab/');
126 | other.setTerm('b', 'http://example.org/type');
127 |
128 | profile.importProfile(other, false);
129 | assert.equal(profile.resolve('ex:a'), 'http://example.com/a');
130 | assert.equal(profile.resolve('a'), 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type');
131 | assert.equal(profile.resolve('fx:a'), 'http://example.org/vocab/a');
132 | assert.equal(profile.resolve('b'), 'http://example.org/type');
133 | assert.strictEqual(profile.resolve('term'), null);
134 | assert.strictEqual(profile.resolve('c:foo'), null);
135 | });
136 | it("importProfile (overwrite=true)", function(){
137 | var profile = new rdf.Profile;
138 | profile.setPrefix('ex', 'http://example.com/');
139 | profile.setTerm('a', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type');
140 |
141 | var other = new rdf.Profile;
142 | other.setPrefix('ex', 'http://example.org/vocab/');
143 | other.setTerm('a', 'http://example.org/type');
144 | other.setPrefix('fx', 'http://example.org/vocab/');
145 | other.setTerm('b', 'http://example.org/type');
146 |
147 | profile.importProfile(other, true);
148 | assert.equal(profile.resolve('ex:a'), 'http://example.org/vocab/a');
149 | assert.equal(profile.resolve('a'), 'http://example.org/type');
150 | assert.equal(profile.resolve('fx:a'), 'http://example.org/vocab/a');
151 | assert.equal(profile.resolve('b'), 'http://example.org/type');
152 | assert.strictEqual(profile.resolve('term'), null);
153 | assert.strictEqual(profile.resolve('c:foo'), null);
154 | });
155 | it("shrink", function(){
156 | var profile = new rdf.Profile;
157 | profile.setTerm('a', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type');
158 | profile.setPrefix('ex2', 'http://example.com/vocab/foo/');
159 | profile.setPrefix('ex', 'http://example.com/');
160 | profile.setPrefix('exv', 'http://example.com/vocab/');
161 | profile.setPrefix('🐉', 'http://example.com/vocab/dragon/');
162 |
163 | assert.equal(profile.shrink('http://example.com/vocab/a'), 'exv:a');
164 | assert.equal(profile.shrink('http://example.com/vocab/foo/b'), 'ex2:b');
165 | assert.equal(profile.shrink('http://example.com/c'), 'ex:c');
166 | // File is UTF-8 (probably), but escape sequence UTF-16 surrogate pairs
167 | // idk I didn't invent it, man
168 | assert.equal(profile.shrink('http://example.com/vocab/dragon/🐲'), '\uD83D\uDC09:\uD83D\uDC32');
169 | assert.equal(profile.shrink('http://example.com/vocab/dragon/🐲🐧'), '\uD83D\uDC09:\uD83D\uDC32\uD83D\uDC27');
170 | assert.equal(profile.shrink('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), 'a');
171 | });
172 | it("remove", function(){
173 | var profile = new rdf.Profile;
174 | profile.setTerm('term', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type');
175 | profile.setPrefix('prefix', 'http://example.com/vocab/foo/');
176 | profile.terms.remove('term');
177 | profile.prefixes.remove('prefix');
178 | assert.strictEqual(profile.resolve('term'), null);
179 | assert.strictEqual(profile.resolve('prefix:foo'), null);
180 | });
181 | });
182 |
--------------------------------------------------------------------------------
/test/Quad.test.js:
--------------------------------------------------------------------------------
1 | var assert = require('assert');
2 | var rdf = require('..');
3 |
4 | describe('Quad', function(){
5 | it('Quad(iri, iri, iri)', function(){
6 | var env = new rdf.RDFEnvironment;
7 | var t = new rdf.Quad(
8 | env.createNamedNode('http://example.com/foo'),
9 | env.createNamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'),
10 | env.createNamedNode('http://www.w3.org/2000/01/rdf-schema#Class'),
11 | env.createNamedNode('http://example.com/graph'),
12 | );
13 | assert.ok(t);
14 | });
15 | it('Quad(bnode, iri, bnode)', function(){
16 | var env = new rdf.RDFEnvironment;
17 | var t = new rdf.Quad(
18 | env.createNamedNode('http://example.com/foo'),
19 | env.createNamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'),
20 | env.createNamedNode('http://www.w3.org/2000/01/rdf-schema#Class'),
21 | env.createNamedNode('http://example.com/graph'),
22 | );
23 | assert.ok(t);
24 | });
25 | it('Quad(iri, iri, literal)', function(){
26 | var env = new rdf.RDFEnvironment;
27 | var t = new rdf.Quad(
28 | env.createNamedNode('http://example.com/foo'),
29 | env.createNamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'),
30 | env.createLiteral('string!'),
31 | env.createNamedNode('http://example.com/graph'),
32 | );
33 | assert.ok(t);
34 | });
35 | it('Quad: literal subject throws', function(){
36 | var env = new rdf.RDFEnvironment;
37 | assert.throws(function(){
38 | new rdf.Quad(
39 | env.createLiteral('string!'),
40 | env.createNamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'),
41 | env.createNamedNode('http://www.w3.org/2000/01/rdf-schema#Class'),
42 | );
43 | });
44 | });
45 | it('Quad: bnode predicate throws', function(){
46 | var env = new rdf.RDFEnvironment;
47 | assert.throws(function(){
48 | new rdf.Quad(
49 | env.createNamedNode('http://example.com/foo'),
50 | env.createBlankNode(),
51 | env.createNamedNode('http://www.w3.org/2000/01/rdf-schema#Class'),
52 | );
53 | });
54 | });
55 | it('Quad: literal predicate throws', function(){
56 | var env = new rdf.RDFEnvironment;
57 | assert.throws(function(){
58 | new rdf.Quad(
59 | env.createNamedNode('http://example.com/foo'),
60 | env.createLiteral('string!'),
61 | env.createNamedNode('http://www.w3.org/2000/01/rdf-schema#Class'),
62 | );
63 | });
64 | });
65 | it('Quad: variable subject throws', function(){
66 | var env = new rdf.RDFEnvironment;
67 | assert.throws(function(){
68 | new rdf.Quad(
69 | new rdf.Variable('s'),
70 | env.createNamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'),
71 | env.createNamedNode('http://www.w3.org/2000/01/rdf-schema#Class'),
72 | );
73 | });
74 | });
75 | it('Quad: variable predicate throws', function(){
76 | var env = new rdf.RDFEnvironment;
77 | assert.throws(function(){
78 | new rdf.Quad(
79 | env.createNamedNode('http://example.com/foo'),
80 | new rdf.Variable('p'),
81 | env.createNamedNode('http://www.w3.org/2000/01/rdf-schema#Class'),
82 | );
83 | });
84 | });
85 | it('Quad: variable object throws', function(){
86 | var env = new rdf.RDFEnvironment;
87 | assert.throws(function(){
88 | new rdf.Quad(
89 | env.createNamedNode('http://example.com/foo'),
90 | env.createNamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'),
91 | new rdf.Variable('o'),
92 | );
93 | });
94 | });
95 | it('Quad: null subject throws', function(){
96 | var env = new rdf.RDFEnvironment;
97 | assert.throws(function(){
98 | new rdf.Quad(
99 | null,
100 | env.createNamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'),
101 | env.createNamedNode('http://www.w3.org/2000/01/rdf-schema#Class'),
102 | );
103 | });
104 | });
105 | it('Quad: null predicate throws', function(){
106 | var env = new rdf.RDFEnvironment;
107 | assert.throws(function(){
108 | new rdf.Quad(
109 | env.createNamedNode('http://example.com/foo'),
110 | null,
111 | env.createNamedNode('http://www.w3.org/2000/01/rdf-schema#Class'),
112 | );
113 | });
114 | });
115 | it('Quad: null object throws', function(){
116 | var env = new rdf.RDFEnvironment;
117 | assert.throws(function(){
118 | new rdf.Quad(
119 | env.createNamedNode('http://example.com/foo'),
120 | env.createNamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'),
121 | null,
122 | );
123 | });
124 | });
125 | it('Quad: string subject', function(){
126 | var env = new rdf.RDFEnvironment;
127 | new rdf.Quad(
128 | 'http://example.com/foo',
129 | env.createNamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'),
130 | env.createNamedNode('http://www.w3.org/2000/01/rdf-schema#Class'),
131 | env.createNamedNode('http://example.com/graph'),
132 | );
133 | });
134 | it('Quad: string predicate', function(){
135 | var env = new rdf.RDFEnvironment;
136 | new rdf.Quad(
137 | env.createNamedNode('http://example.com/foo'),
138 | 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type',
139 | env.createNamedNode('http://www.w3.org/2000/01/rdf-schema#Class'),
140 | env.createNamedNode('http://example.com/graph'),
141 | );
142 | });
143 | it('Quad: string object', function(){
144 | var env = new rdf.RDFEnvironment;
145 | new rdf.Quad(
146 | env.createNamedNode('http://example.com/foo'),
147 | env.createNamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'),
148 | 'http://www.w3.org/2000/01/rdf-schema#Class',
149 | env.createNamedNode('http://example.com/graph'),
150 | );
151 | });
152 | it('Quad: string graph', function(){
153 | var env = new rdf.RDFEnvironment;
154 | new rdf.Quad(
155 | env.createNamedNode('http://example.com/foo'),
156 | env.createNamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'),
157 | env.createNamedNode('http://www.w3.org/2000/01/rdf-schema#Class'),
158 | 'http://example.com/graph',
159 | );
160 | });
161 | it("toString", function(){
162 | var nn = new rdf.NamedNode('http://example.com/');
163 | var t = new rdf.Quad(nn, nn, nn, nn);
164 | assert.strictEqual(t.toString(), ' .');
165 | });
166 | it("equals", function(){
167 | var nn = new rdf.NamedNode('http://example.com/');
168 | var t = new rdf.Quad(nn, nn, nn, nn);
169 | var nn2 = new rdf.NamedNode('http://example.com/');
170 | assert.ok(t.equals(new rdf.Quad(nn2, nn2, nn2, nn2)));
171 | });
172 | it("equals (negative subject)", function(){
173 | var nn = new rdf.NamedNode('http://example.com/');
174 | var t = new rdf.Quad(nn, nn, nn, nn);
175 | var nn2 = new rdf.NamedNode('http://example.com/');
176 | var nn3 = new rdf.NamedNode('http://example.org/foo');
177 | assert(!t.equals(new rdf.Quad(nn3, nn2, nn2, nn2)));
178 | });
179 | it("equals (negative predicate)", function(){
180 | var nn = new rdf.NamedNode('http://example.com/');
181 | var t = new rdf.Quad(nn, nn, nn, nn);
182 | var nn2 = new rdf.NamedNode('http://example.com/');
183 | var nn3 = new rdf.NamedNode('http://example.org/foo');
184 | assert(!t.equals(new rdf.Quad(nn2, nn3, nn2, nn2)));
185 | });
186 | it("equals (negative object)", function(){
187 | var nn = new rdf.NamedNode('http://example.com/');
188 | var t = new rdf.Quad(nn, nn, nn, nn);
189 | var nn2 = new rdf.NamedNode('http://example.com/');
190 | var nn3 = new rdf.NamedNode('http://example.org/foo');
191 | assert(!t.equals(new rdf.Quad(nn2, nn2, nn3, nn2)));
192 | });
193 | it("equals (negative graph)", function(){
194 | var nn = new rdf.NamedNode('http://example.com/');
195 | var t = new rdf.Quad(nn, nn, nn, nn);
196 | var nn2 = new rdf.NamedNode('http://example.com/');
197 | var nn3 = new rdf.NamedNode('http://example.org/foo');
198 | assert(!t.equals(new rdf.Quad(nn2, nn2, nn2, nn3)));
199 | });
200 | });
201 |
--------------------------------------------------------------------------------
/test/RDF-MT.test.js:
--------------------------------------------------------------------------------
1 | // This expects the RDF Semantics test suite to be extracted,
2 | // with the manifest file at ./rdf-mt-tests/manifest.ttl
3 | // Run `make test` to download this
4 |
5 | var assert = require('assert');
6 | var fs = require('fs');
7 | var rdf = require('..');
8 | var TurtleParser = rdf.TurtleParser;
9 |
10 | var m$ = rdf.ns('http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#');
11 | var PositiveEntailmentTest = m$('PositiveEntailmentTest');
12 | var NegativeEntailmentTest = m$('NegativeEntailmentTest');
13 |
14 | var manifestBase = 'http://www.w3.org/2013/rdf-mt-tests/manifest.ttl';
15 | //var manifestBase = 'file://'+__dirname+'/rdf-mt-tests/manifest.ttl';
16 | var manifestData = require('fs').readFileSync('test/rdf-mt-tests/manifest.ttl');
17 | var manifestParse = TurtleParser.parse(manifestData, manifestBase);
18 | var manifestGraph = manifestParse.graph;
19 |
20 | var manifest = manifestGraph.match(manifestBase, m$('entries'), null).toArray();
21 | var manifestTests = manifestGraph.getCollection(manifest[0].object);
22 |
23 | describe('RDF Semantics test suite', function(){
24 | it('Parse Turtle test suite manifest', function(){
25 | assert.ok(manifestTests.length);
26 | });
27 | describe('test', function(){
28 | manifestTests.forEach(function(test){
29 | // Each test is one of the above kinds of tests. All tests have
30 | // - a name (mf:name),
31 | var testName = manifestGraph.reference(test).rel(m$('name')).one().toString();
32 | // - an input RDF graph URL (mf:action),
33 | var testInputURI = manifestGraph.reference(test).rel(m$('action')).one().toString();
34 | var testInputFile = testInputURI.replace('http://www.w3.org/2013/', 'test/');
35 | // - an output RDF graph URL or the special marker false (mf:result),
36 | var testOutputURI = manifestGraph.reference(test).rel(m$('result')).one().toString();
37 | var testOutputFile = testOutputURI.replace('http://www.w3.org/2013/', 'test/');
38 | // - an entailment regime, which is "simple", "RDF", or "RDFS" (mf:entailmentRegime),
39 | var entailmentRegime = manifestGraph.reference(test).rel(m$('entailmentRegime')).one().toString();
40 | // - a list of recognized datatypes (mf:recognizedDatatypes),
41 | // - a list of unrecognized datatypes (mf:unrecognizedDatatypes).
42 | if(entailmentRegime!=='simple') return;
43 | var types = manifestGraph.reference(test).rel(rdf.rdfns('type')).toArray();
44 | for(var j=0; jSome Literal
', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral');
56 | assert.ok(t instanceof rdf.Literal);
57 | assert.equal(t.toString(), 'Some Literal
');
58 | assert.equal(t.datatype.toString(), 'http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral');
59 | assert.equal(t.language, null);
60 | });
61 | it('createLiteral(value, NamedNode)', function(){
62 | var env = new rdf.RDFEnvironment;
63 | var t = env.createLiteral('Some Literal
', new rdf.NamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral'));
64 | assert.ok(t instanceof rdf.Literal);
65 | assert.equal(t.toString(), 'Some Literal
');
66 | assert.equal(t.datatype.toString(), 'http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral');
67 | assert.equal(t.language, null);
68 | });
69 | it('createLiteral(value, language)', function(){
70 | var env = new rdf.RDFEnvironment;
71 | var t = env.createLiteral('Some Literal', 'en');
72 | assert.ok(t instanceof rdf.Literal);
73 | assert.equal(t.toString(), 'Some Literal');
74 | assert.equal(t.datatype.toString(), 'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString');
75 | assert.equal(t.language, 'en');
76 | });
77 | it('createLiteral(value, LangTag)', function(){
78 | var env = new rdf.RDFEnvironment;
79 | var t = env.createLiteral('Some Literal', '@en');
80 | assert.ok(t instanceof rdf.Literal);
81 | assert.equal(t.toString(), 'Some Literal');
82 | assert.equal(t.datatype.toString(), 'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString');
83 | assert.equal(t.language, 'en');
84 | });
85 | it('createLiteral(value, null, datatype)', function(){
86 | var env = new rdf.RDFEnvironment;
87 | var t = env.createLiteral('Some Literal
', null, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral');
88 | assert.ok(t instanceof rdf.Literal);
89 | assert.equal(t.toString(), 'Some Literal
');
90 | assert.equal(t.datatype.toString(), 'http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral');
91 | assert.equal(t.language, null);
92 | });
93 | it('createLiteral(value, null, NamedNode)', function(){
94 | var env = new rdf.RDFEnvironment;
95 | var t = env.createLiteral('Some Literal
', null, new rdf.NamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral'));
96 | assert.ok(t instanceof rdf.Literal);
97 | assert.equal(t.toString(), 'Some Literal
');
98 | assert.equal(t.datatype.toString(), 'http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral');
99 | assert.equal(t.language, null);
100 | });
101 | it('createLanguageLiteral(value) throws', function(){
102 | var env = new rdf.RDFEnvironment;
103 | assert.throws(function(){
104 | var t = env.createLanguageLiteral('Some Literal
');
105 | });
106 | });
107 | it('createLanguageLiteral(value, datatype) throws', function(){
108 | var env = new rdf.RDFEnvironment;
109 | assert.throws(function(){
110 | var t = env.createLanguageLiteral('Some Literal
', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral');
111 | });
112 | });
113 | it('createLanguageLiteral(value, language)', function(){
114 | var env = new rdf.RDFEnvironment;
115 | var t = env.createLiteral('Some Literal', 'en');
116 | assert.ok(t instanceof rdf.Literal);
117 | assert.equal(t.toString(), 'Some Literal');
118 | assert.equal(t.datatype.toString(), 'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString');
119 | assert.equal(t.language, 'en');
120 | });
121 | it('createTypedLiteral(value) throws', function(){
122 | var env = new rdf.RDFEnvironment;
123 | assert.throws(function(){
124 | env.createTypedLiteral('Some Literal
');
125 | });
126 | });
127 | it('createTypedLiteral(value, datatype)', function(){
128 | var env = new rdf.RDFEnvironment;
129 | var t = env.createTypedLiteral('Some Literal
', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral');
130 | assert.ok(t instanceof rdf.Literal);
131 | assert.equal(t.toString(), 'Some Literal
');
132 | assert.equal(t.datatype.toString(), 'http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral');
133 | assert.equal(t.language, null);
134 | });
135 | it('createTypedLiteral(value, NamedNode)', function(){
136 | var env = new rdf.RDFEnvironment;
137 | var t = env.createTypedLiteral('Some Literal
', new rdf.NamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral'));
138 | assert.ok(t instanceof rdf.Literal);
139 | assert.equal(t.toString(), 'Some Literal
');
140 | assert.equal(t.datatype.toString(), 'http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral');
141 | assert.equal(t.language, null);
142 | });
143 | it('createTypedLiteral(value, language) throws', function(){
144 | var env = new rdf.RDFEnvironment;
145 | assert.throws(function(){
146 | var t = env.createTypedLiteral('Some Literal', 'en');
147 | });
148 | });
149 | it('createTriple(iri, iri, iri)', function(){
150 | var env = new rdf.RDFEnvironment;
151 | var t = env.createTriple(
152 | env.createNamedNode('http://example.com/foo'),
153 | env.createNamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'),
154 | env.createNamedNode('http://www.w3.org/2000/01/rdf-schema#Class'),
155 | );
156 | assert.ok(t);
157 | });
158 | it('createTriple(bnode, iri, bnode)', function(){
159 | var env = new rdf.RDFEnvironment;
160 | var t = env.createTriple(
161 | env.createNamedNode('http://example.com/foo'),
162 | env.createNamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'),
163 | env.createNamedNode('http://www.w3.org/2000/01/rdf-schema#Class'),
164 | );
165 | assert.ok(t);
166 | });
167 | it('createTriple(iri, iri, literal)', function(){
168 | var env = new rdf.RDFEnvironment;
169 | var t = env.createTriple(
170 | env.createNamedNode('http://example.com/foo'),
171 | env.createNamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'),
172 | env.createLiteral('string!'),
173 | );
174 | assert.ok(t);
175 | });
176 | it('createTriple: no literal subject', function(){
177 | var env = new rdf.RDFEnvironment;
178 | assert.throws(function(){
179 | env.createTriple(
180 | env.createLiteral('string!'),
181 | env.createNamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'),
182 | env.createNamedNode('http://www.w3.org/2000/01/rdf-schema#Class'),
183 | );
184 | });
185 | });
186 | it('createTriple: no bnode predicate', function(){
187 | var env = new rdf.RDFEnvironment;
188 | assert.throws(function(){
189 | env.createTriple(
190 | env.createNamedNode('http://example.com/foo'),
191 | env.createBlankNode(),
192 | env.createNamedNode('http://www.w3.org/2000/01/rdf-schema#Class'),
193 | );
194 | });
195 | });
196 | it('createTriple: no literal predicate', function(){
197 | var env = new rdf.RDFEnvironment;
198 | assert.throws(function(){
199 | env.createTriple(
200 | env.createNamedNode('http://example.com/foo'),
201 | env.createLiteral('string!'),
202 | env.createNamedNode('http://www.w3.org/2000/01/rdf-schema#Class'),
203 | );
204 | });
205 | });
206 | it('createProfile', function(){
207 | var env = new rdf.RDFEnvironment;
208 | var t = env.createProfile();
209 | assert.ok(t instanceof rdf.Profile);
210 | });
211 | it('createTermMap', function(){
212 | var env = new rdf.RDFEnvironment;
213 | var t = env.createTermMap();
214 | assert.ok(t instanceof rdf.TermMap);
215 | });
216 | it('createPrefixMap', function(){
217 | var env = new rdf.RDFEnvironment;
218 | var t = env.createPrefixMap();
219 | assert.ok(t instanceof rdf.PrefixMap);
220 | });
221 | });
222 |
--------------------------------------------------------------------------------
/test/RDFNode.test.js:
--------------------------------------------------------------------------------
1 | var assert = require('assert');
2 | var rdf = require('..');
3 |
4 | function LiteralTests(){
5 | it("compare (via sort)", function(){
6 | // Array to be sorted via RDFNode#compare
7 | var bros = [
8 | new rdf.BlankNode('_:a'),
9 | new rdf.Literal("A String", '@en-GB'),
10 | new rdf.Literal("A"),
11 | new rdf.Literal("A String"),
12 | new rdf.Literal("true", rdf.xsdns('boolean')),
13 | new rdf.Literal("A String", '@ja'),
14 | new rdf.Literal("false", rdf.xsdns('boolean')),
15 | new rdf.BlankNode('b'),
16 | new rdf.NamedNode("http://example.com/"),
17 | new rdf.Literal("A String", '@en'),
18 | new rdf.NamedNode("http://example.com/a"),
19 | new rdf.BlankNode('_:c'),
20 | new rdf.NamedNode("http://example.com/b"),
21 | ];
22 | bros.sort(function(a, b){ return a.compare(b); });
23 | //bros.forEach(function(v){ console.log(v.toNT()); });
24 | // I don't know if this order means much to people, but it's an order
25 | [
26 | new rdf.NamedNode("http://example.com/"),
27 | new rdf.NamedNode("http://example.com/a"),
28 | new rdf.NamedNode("http://example.com/b"),
29 | new rdf.BlankNode('a'),
30 | new rdf.BlankNode('b'),
31 | new rdf.BlankNode('c'),
32 | new rdf.Literal("A"),
33 | new rdf.Literal("A String"),
34 | new rdf.Literal("A String", '@en'),
35 | new rdf.Literal("A String", '@en-GB'),
36 | new rdf.Literal("A String", '@ja'),
37 | new rdf.Literal("false", rdf.xsdns('boolean')),
38 | new rdf.Literal("true", rdf.xsdns('boolean')),
39 | ].forEach(function(t, i){
40 | assert(t.equals(bros[i]), 'item '+i+' mismatch');
41 | });
42 | });
43 | }
44 |
45 | describe('RDFNode', LiteralTests);
46 |
47 | describe('RDFNode (with builtins)', function(){
48 | before(function(){
49 | rdf.setBuiltins();
50 | });
51 | after(function(){
52 | rdf.unsetBuiltins();
53 | });
54 | LiteralTests();
55 | });
56 |
--------------------------------------------------------------------------------
/test/TermMap.test.js:
--------------------------------------------------------------------------------
1 |
2 | var assert = require('assert');
3 | var rdf = require('..');
4 |
5 | /*
6 | [NoInterfaceObject]
7 | interface TermMap {
8 | omittable getter DOMString get (DOMString term);
9 | omittable setter void set (DOMString term, DOMString iri);
10 | omittable deleter void remove (DOMString term);
11 | DOMString resolve (DOMString term);
12 | DOMString shrink (DOMString iri);
13 | void setDefault (DOMString iri);
14 | TermMap addAll (TermMap terms, optional boolean override); // Corrected typo
15 | };
16 | */
17 |
18 | describe('TermMap', function(){
19 | it('TermMap#get(string, string)', function(){
20 | var map = new rdf.TermMap;
21 | assert.equal(typeof map.get, 'function');
22 | });
23 | it('TermMap#set(string, string)', function(){
24 | var map = new rdf.TermMap;
25 | assert.equal(typeof map.set, 'function');
26 | assert.equal(typeof map.set('type', 'http://example.com/type'), 'undefined');
27 | assert.equal(map.get('type'), 'http://example.com/type');
28 | assert.equal(map.resolve('type'), 'http://example.com/type');
29 | });
30 | it('TermMap#setDefault(string)', function(){
31 | var map = new rdf.TermMap;
32 | assert.equal(typeof map.set, 'function');
33 | assert.equal(typeof map.setDefault('http://example.com/'), 'undefined');
34 | assert.equal(map.resolve('type'), 'http://example.com/type');
35 | });
36 | it("TermMap#set negative tests", function(){
37 | var map = new rdf.TermMap;
38 | assert.equal(typeof map.set, 'function');
39 | assert.throws(function(){
40 | map.set('0', 'http://example.com/');
41 | });
42 | assert.throws(function(){
43 | map.set('::', 'http://example.com/');
44 | });
45 | assert.throws(function(){
46 | map.set(' ', 'http://example.com/');
47 | });
48 | assert.throws(function(){
49 | map.set('.', 'http://example.com/');
50 | });
51 | });
52 | it("TermMap#remove(string)", function(){
53 | var map = new rdf.TermMap;
54 | map.set('foo', 'http://example.com/vocab/foo/');
55 | map.remove('foo');
56 | assert.strictEqual(map.resolve('foo'), null);
57 | });
58 | it("TermMap#resolve(string)", function(){
59 | var map = new rdf.TermMap;
60 | map.set('type', 'http://example.com/');
61 | assert.equal(typeof map.resolve, 'function');
62 | assert.equal(typeof map.resolve('type'), 'string');
63 | assert.equal(map.resolve('undefinedTerm'), null);
64 | });
65 | it("TermMap#shrink(string)", function(){
66 | var map = new rdf.TermMap;
67 | map.set('ex', 'http://example.com/ex');
68 | map.setDefault('http://example.com/vocab/🐉/');
69 |
70 | assert.equal(map.shrink('http://example.com/ex'), 'ex');
71 | // File is UTF-8 (probably), but escape sequence UTF-16 surrogate pairs
72 | // idk I didn't invent it, man
73 | assert.equal(map.shrink('http://example.com/vocab/🐉/🐲'), '\uD83D\uDC32');
74 | });
75 | it("addAll", function(){
76 | var map = new rdf.TermMap;
77 | assert.equal(typeof map.addAll, 'function');
78 | map.set('a', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type');
79 |
80 | var other = new rdf.TermMap;
81 | other.set('a', 'http://example.org/type');
82 | other.set('b', 'http://example.org/type');
83 |
84 | map.addAll(other);
85 | assert.equal(map.resolve('a'), 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type');
86 | assert.equal(map.resolve('b'), 'http://example.org/type');
87 | assert.strictEqual(map.resolve('term'), null);
88 | });
89 | it("addAll (overwrite=false)", function(){
90 | var map = new rdf.TermMap;
91 | map.set('a', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type');
92 |
93 | var other = new rdf.TermMap;
94 | other.set('a', 'http://example.org/type');
95 | other.set('b', 'http://example.org/type');
96 |
97 | map.addAll(other, false);
98 | assert.equal(map.resolve('a'), 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type');
99 | assert.equal(map.resolve('b'), 'http://example.org/type');
100 | assert.strictEqual(map.resolve('term'), null);
101 | });
102 | it("addAll (overwrite=true)", function(){
103 | var map = new rdf.TermMap;
104 | map.set('a', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type');
105 |
106 | var other = new rdf.TermMap;
107 | other.set('a', 'http://example.org/type');
108 | other.set('b', 'http://example.org/type');
109 |
110 | map.addAll(other, true);
111 | assert.equal(map.resolve('a'), 'http://example.org/type');
112 | assert.equal(map.resolve('b'), 'http://example.org/type');
113 | assert.strictEqual(map.resolve('term'), null);
114 | });
115 | it("TermMap#list", function(){
116 | var map = new rdf.TermMap;
117 | assert.equal(map.list().length, 0);
118 | map.set('ex', 'http://example.com/');
119 | var list = map.list();
120 | assert.equal(list.length, 1);
121 | assert.equal(list[0], 'ex');
122 | });
123 | });
124 |
--------------------------------------------------------------------------------
/test/Triple.test.js:
--------------------------------------------------------------------------------
1 | var assert = require('assert');
2 | var rdf = require('..');
3 |
4 | describe('Triple', function(){
5 | it('Triple(iri, iri, iri)', function(){
6 | var env = new rdf.RDFEnvironment;
7 | var t = new rdf.Triple(
8 | env.createNamedNode('http://example.com/foo'),
9 | env.createNamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'),
10 | env.createNamedNode('http://www.w3.org/2000/01/rdf-schema#Class'),
11 | );
12 | assert.ok(t);
13 | });
14 | it('Triple(bnode, iri, bnode)', function(){
15 | var env = new rdf.RDFEnvironment;
16 | var t = new rdf.Triple(
17 | env.createNamedNode('http://example.com/foo'),
18 | env.createNamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'),
19 | env.createNamedNode('http://www.w3.org/2000/01/rdf-schema#Class'),
20 | );
21 | assert.ok(t);
22 | });
23 | it('Triple(iri, iri, literal)', function(){
24 | var env = new rdf.RDFEnvironment;
25 | var t = new rdf.Triple(
26 | env.createNamedNode('http://example.com/foo'),
27 | env.createNamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'),
28 | env.createLiteral('string!'),
29 | );
30 | assert.ok(t);
31 | });
32 | it('Triple: literal subject throws', function(){
33 | var env = new rdf.RDFEnvironment;
34 | assert.throws(function(){
35 | new rdf.Triple(
36 | env.createLiteral('string!'),
37 | env.createNamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'),
38 | env.createNamedNode('http://www.w3.org/2000/01/rdf-schema#Class'),
39 | );
40 | });
41 | });
42 | it('Triple: bnode predicate throws', function(){
43 | var env = new rdf.RDFEnvironment;
44 | assert.throws(function(){
45 | new rdf.Triple(
46 | env.createNamedNode('http://example.com/foo'),
47 | env.createBlankNode(),
48 | env.createNamedNode('http://www.w3.org/2000/01/rdf-schema#Class'),
49 | );
50 | });
51 | });
52 | it('Triple: literal predicate throws', function(){
53 | var env = new rdf.RDFEnvironment;
54 | assert.throws(function(){
55 | new rdf.Triple(
56 | env.createNamedNode('http://example.com/foo'),
57 | env.createLiteral('string!'),
58 | env.createNamedNode('http://www.w3.org/2000/01/rdf-schema#Class'),
59 | );
60 | });
61 | });
62 | it('Triple: variable subject throws', function(){
63 | var env = new rdf.RDFEnvironment;
64 | assert.throws(function(){
65 | new rdf.Triple(
66 | new rdf.Variable('s'),
67 | env.createNamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'),
68 | env.createNamedNode('http://www.w3.org/2000/01/rdf-schema#Class'),
69 | );
70 | });
71 | });
72 | it('Triple: variable predicate throws', function(){
73 | var env = new rdf.RDFEnvironment;
74 | assert.throws(function(){
75 | new rdf.Triple(
76 | env.createNamedNode('http://example.com/foo'),
77 | new rdf.Variable('p'),
78 | env.createNamedNode('http://www.w3.org/2000/01/rdf-schema#Class'),
79 | );
80 | });
81 | });
82 | it('Triple: variable object throws', function(){
83 | var env = new rdf.RDFEnvironment;
84 | assert.throws(function(){
85 | new rdf.Triple(
86 | env.createNamedNode('http://example.com/foo'),
87 | env.createNamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'),
88 | new rdf.Variable('o'),
89 | );
90 | });
91 | });
92 | it('Triple: null subject throws', function(){
93 | var env = new rdf.RDFEnvironment;
94 | assert.throws(function(){
95 | new rdf.Triple(
96 | null,
97 | env.createNamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'),
98 | env.createNamedNode('http://www.w3.org/2000/01/rdf-schema#Class'),
99 | );
100 | });
101 | });
102 | it('Triple: null predicate throws', function(){
103 | var env = new rdf.RDFEnvironment;
104 | assert.throws(function(){
105 | new rdf.Triple(
106 | env.createNamedNode('http://example.com/foo'),
107 | null,
108 | env.createNamedNode('http://www.w3.org/2000/01/rdf-schema#Class'),
109 | );
110 | });
111 | });
112 | it('Triple: null object throws', function(){
113 | var env = new rdf.RDFEnvironment;
114 | assert.throws(function(){
115 | new rdf.Triple(
116 | env.createNamedNode('http://example.com/foo'),
117 | env.createNamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'),
118 | null,
119 | );
120 | });
121 | });
122 | it('Triple: string subject', function(){
123 | var env = new rdf.RDFEnvironment;
124 | new rdf.Triple(
125 | 'http://example.com/foo',
126 | env.createNamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'),
127 | env.createNamedNode('http://www.w3.org/2000/01/rdf-schema#Class'),
128 | );
129 | });
130 | it('Triple: string predicate', function(){
131 | var env = new rdf.RDFEnvironment;
132 | new rdf.Triple(
133 | env.createNamedNode('http://example.com/foo'),
134 | 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type',
135 | env.createNamedNode('http://www.w3.org/2000/01/rdf-schema#Class'),
136 | );
137 | });
138 | it('Triple: string object', function(){
139 | var env = new rdf.RDFEnvironment;
140 | new rdf.Triple(
141 | env.createNamedNode('http://example.com/foo'),
142 | env.createNamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'),
143 | 'http://www.w3.org/2000/01/rdf-schema#Class',
144 | );
145 | });
146 | it("toString", function(){
147 | var nn = new rdf.NamedNode('http://example.com/');
148 | var t = new rdf.Triple(nn, nn, nn);
149 | assert.strictEqual(t.toString(), ' .');
150 | });
151 | it("equals", function(){
152 | var nn = new rdf.NamedNode('http://example.com/');
153 | var t = new rdf.Triple(nn, nn, nn);
154 | var nn2 = new rdf.NamedNode('http://example.com/');
155 | assert.ok(t.equals(new rdf.Triple(nn2, nn2, nn2)));
156 | });
157 | it("equals (negative subject)", function(){
158 | var nn = new rdf.NamedNode('http://example.com/');
159 | var t = new rdf.Triple(nn, nn, nn);
160 | var nn2 = new rdf.NamedNode('http://example.com/');
161 | var nn3 = new rdf.NamedNode('http://example.org/foo');
162 | assert(!t.equals(new rdf.Triple(nn3, nn2, nn2)));
163 | });
164 | it("equals (negative predicate)", function(){
165 | var nn = new rdf.NamedNode('http://example.com/');
166 | var t = new rdf.Triple(nn, nn, nn);
167 | var nn2 = new rdf.NamedNode('http://example.com/');
168 | var nn3 = new rdf.NamedNode('http://example.org/foo');
169 | assert(!t.equals(new rdf.Triple(nn2, nn3, nn2)));
170 | });
171 | it("equals (negative object)", function(){
172 | var nn = new rdf.NamedNode('http://example.com/');
173 | var t = new rdf.Triple(nn, nn, nn);
174 | var nn2 = new rdf.NamedNode('http://example.com/');
175 | var nn3 = new rdf.NamedNode('http://example.org/foo');
176 | assert(!t.equals(new rdf.Triple(nn2, nn2, nn3)));
177 | });
178 | // TODO: behavior for testing equal of things that are not Triple
179 | });
180 |
--------------------------------------------------------------------------------
/test/TriplePattern.test.js:
--------------------------------------------------------------------------------
1 | var assert = require('assert');
2 | var rdf = require('..');
3 |
4 | describe('TriplePattern', function(){
5 | it('TriplePattern(iri, iri, iri)', function(){
6 | var env = new rdf.RDFEnvironment;
7 | var t = new rdf.TriplePattern(
8 | env.createNamedNode('http://example.com/foo'),
9 | env.createNamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'),
10 | env.createNamedNode('http://www.w3.org/2000/01/rdf-schema#Class'),
11 | );
12 | assert.ok(t);
13 | });
14 | it('TriplePattern(variable, variable, variable)', function(){
15 | var env = new rdf.RDFEnvironment;
16 | var t = new rdf.TriplePattern(
17 | new rdf.Variable('s'),
18 | new rdf.Variable('p'),
19 | new rdf.Variable('o'),
20 | );
21 | assert.ok(t);
22 | });
23 | it('TriplePattern(bnode, iri, bnode)', function(){
24 | var env = new rdf.RDFEnvironment;
25 | var t = new rdf.TriplePattern(
26 | env.createNamedNode('http://example.com/foo'),
27 | env.createNamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'),
28 | env.createNamedNode('http://www.w3.org/2000/01/rdf-schema#Class'),
29 | );
30 | assert.ok(t);
31 | });
32 | it('TriplePattern(iri, iri, literal)', function(){
33 | var env = new rdf.RDFEnvironment;
34 | var t = new rdf.TriplePattern(
35 | env.createNamedNode('http://example.com/foo'),
36 | env.createNamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'),
37 | env.createLiteral('string!'),
38 | );
39 | assert.ok(t);
40 | });
41 | it('TriplePattern: literal subject throws', function(){
42 | var env = new rdf.RDFEnvironment;
43 | assert.throws(function(){
44 | new rdf.TriplePattern(
45 | env.createLiteral('string!'),
46 | env.createNamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'),
47 | env.createNamedNode('http://www.w3.org/2000/01/rdf-schema#Class'),
48 | );
49 | });
50 | });
51 | it('TriplePattern: bnode predicate throws', function(){
52 | var env = new rdf.RDFEnvironment;
53 | assert.throws(function(){
54 | new rdf.TriplePattern(
55 | env.createNamedNode('http://example.com/foo'),
56 | env.createBlankNode(),
57 | env.createNamedNode('http://www.w3.org/2000/01/rdf-schema#Class'),
58 | );
59 | });
60 | });
61 | it('TriplePattern: literal predicate throws', function(){
62 | var env = new rdf.RDFEnvironment;
63 | assert.throws(function(){
64 | new rdf.TriplePattern(
65 | env.createNamedNode('http://example.com/foo'),
66 | env.createLiteral('string!'),
67 | env.createNamedNode('http://www.w3.org/2000/01/rdf-schema#Class'),
68 | );
69 | });
70 | });
71 | it("toString", function(){
72 | var t = new rdf.TriplePattern(
73 | new rdf.Variable('s'),
74 | new rdf.Variable('p'),
75 | new rdf.Variable('o'),
76 | );
77 | assert.strictEqual(t.toString(), '?s ?p ?o .');
78 | });
79 | it("equals", function(){
80 | var nn = new rdf.NamedNode('http://example.com/');
81 | var t = new rdf.TriplePattern(nn, nn, nn);
82 | var nn2 = new rdf.NamedNode('http://example.com/');
83 | assert.ok(t.equals(new rdf.TriplePattern(nn2, nn2, nn2)));
84 | });
85 | });
86 |
--------------------------------------------------------------------------------
/test/TurtleParser.test.js:
--------------------------------------------------------------------------------
1 | // This expects the RDF Semantics test suite to be extracted,
2 | // with the manifest file at ./TurtleTests/manifest.ttl
3 | // Run `make test` to download this
4 |
5 | var assert = require('assert');
6 | var fs = require('fs');
7 | var rdf = require('..');
8 | var TurtleParser = rdf.TurtleParser;
9 |
10 | var m$ = rdf.ns('http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#');
11 |
12 | var manifestBase = 'http://www.w3.org/2013/TurtleTests/manifest.ttl';
13 | //var manifestBase = 'file://'+__dirname+'/TurtleTests/manifest.ttl';
14 | var manifestData = require('fs').readFileSync('test/TurtleTests/manifest.ttl');
15 | var manifestParse = TurtleParser.parse(manifestData, manifestBase);
16 | var manifestGraph = manifestParse.graph;
17 |
18 | var manifest = manifestGraph.match(manifestBase, m$('entries'), null).toArray();
19 | var manifestTests = manifestGraph.getCollection(manifest[0].object);
20 |
21 | describe('TurtleParser', function(){
22 | it('TurtleParser.parse', function(){
23 | var parse = rdf.TurtleParser.parse('<> a .', 'http://example.com/');
24 | assert.equal(parse.graph.toArray().join("\n"), ' .');
25 | });
26 | });
27 |
28 | describe('Turtle test suite', function(){
29 | it('Parse Turtle test suite manifest', function(){
30 | assert.ok(manifestTests.length);
31 | });
32 | describe('test', function(){
33 |
34 | manifestTests.forEach(function(test){
35 | var types = manifestGraph.reference(test).rel(rdf.rdfns('type')).toArray();
36 | var fileURI = manifestGraph.reference(test).rel(m$('action')).one().toString();
37 | var filename = fileURI.replace('http://www.w3.org/2013/', 'test/');
38 |
39 | for(var j=0; j', function(done){
43 | // First parse the expected data (in N-Triples format)
44 | var resultURI = manifestGraph.reference(test).rel(m$('result')).one().toString();
45 | var resultFile = resultURI.replace('http://www.w3.org/2013/', 'test/');
46 | fs.readFile(resultFile, 'utf8', function(err, data){
47 | if(err) throw err;
48 | var expectedParser = TurtleParser.parse(data, resultURI);
49 | var expectedGraph = expectedParser.graph;
50 | // Now parse the Turtle file
51 | fs.readFile(filename, 'utf8', function(err, data){
52 | if(err) throw err;
53 | var parser = TurtleParser.parse(data, fileURI);
54 | var graph = parser.graph;
55 | // Have the data, compare
56 | var expectedTriples = expectedGraph.toArray().sort();
57 | var outputTriples = graph.toArray().sort();
58 |
59 | if(!expectedGraph.isomorphic(graph)){
60 | assert.equal(outputTriples.join('\n'), expectedTriples.join('\n'));
61 | assert.ok(expectedGraph.isomorphic(graph));
62 | }
63 | done();
64 | });
65 | });
66 | });
67 | break;
68 | case 'http://www.w3.org/ns/rdftest#TestTurtlePositiveSyntax':
69 | it('positive test <'+filename+'>', function(done){
70 | fs.readFile(filename, 'utf8', function(err, data){
71 | if(err) throw err;
72 | var parser = TurtleParser.parse(data, fileURI);
73 | assert(parser.graph);
74 | done();
75 | });
76 | });
77 | break;
78 | case 'http://www.w3.org/ns/rdftest#TestTurtleNegativeSyntax':
79 | case 'http://www.w3.org/ns/rdftest#TestTurtleNegativeEval':
80 | it('negative test <'+filename+'>', function(done){
81 | fs.readFile(filename, 'utf8', function(err, data){
82 | if(err) throw err;
83 | assert.throws(function(){
84 | TurtleParser.parse(data, file);
85 | });
86 | done();
87 | });
88 | });
89 | break;
90 | default:
91 | break;
92 | }
93 | }
94 | });
95 | });
96 | });
97 |
--------------------------------------------------------------------------------
/test/Variable.test.js:
--------------------------------------------------------------------------------
1 | var assert = require('assert');
2 | var rdf = require('..');
3 |
4 | describe('Variable', function(){
5 | it("instance", function(){
6 | var t = new rdf.Variable('name');
7 | assert.ok(t instanceof rdf.Variable);
8 | assert.strictEqual(t.nodeType(), 'Variable');
9 | assert.strictEqual(t.interfaceName, 'Variable'); // 2012 Note variant
10 | assert.strictEqual(t.termType, 'Variable'); // 2017 Community Group variant
11 | });
12 | it("Variable(undefined) requires string argument", function(){
13 | assert.throws(function(){
14 | var t = new rdf.Variable();
15 | });
16 | });
17 | it("Variable(null) requires string argument", function(){
18 | assert.throws(function(){
19 | var t = new rdf.Variable(null);
20 | });
21 | });
22 | it("toNT throws", function(){
23 | var t = new rdf.Variable('name');
24 | assert.throws(function(){
25 | t.toNT();
26 | });
27 | });
28 | it("n3", function(){
29 | var t = new rdf.Variable('name');
30 | assert.strictEqual(t.n3(), '?name');
31 | });
32 | });
33 |
--------------------------------------------------------------------------------
/test/builtins-Number.test.js:
--------------------------------------------------------------------------------
1 | var assert = require('assert');
2 | var rdf = require('..');
3 | var util = require('util');
4 |
5 | function addNumberTest(t, nodeType, datatype, n3rep){
6 | it('('+util.inspect(t)+')', function(){
7 | assert.strictEqual(typeof t.n3, 'function');
8 | assert.strictEqual(typeof t.toNT, 'function');
9 | assert.strictEqual(typeof t.nodeType, 'function');
10 | assert.strictEqual(t.nodeType(), nodeType);
11 | assert.strictEqual(t.n3(), n3rep);
12 | assert.strictEqual(t.datatype, datatype);
13 | });
14 | }
15 |
16 | describe('Number builtins', function(){
17 | before(function(){
18 | rdf.setBuiltins();
19 | });
20 | after(function(){
21 | rdf.unsetBuiltins();
22 | });
23 |
24 | addNumberTest(Number.POSITIVE_INFINITY, "TypedLiteral", "http://www.w3.org/2001/XMLSchema#double", '"INF"^^');
25 | addNumberTest(Number.NEGATIVE_INFINITY, "TypedLiteral", "http://www.w3.org/2001/XMLSchema#double", '"-INF"^^');
26 | addNumberTest(Number.NaN, "TypedLiteral", "http://www.w3.org/2001/XMLSchema#double", '"NaN"^^');
27 | addNumberTest(8.5432, "TypedLiteral", "http://www.w3.org/2001/XMLSchema#decimal", '8.5432');
28 | addNumberTest(42, "TypedLiteral", "http://www.w3.org/2001/XMLSchema#integer", '42');
29 | addNumberTest(-42, "TypedLiteral", "http://www.w3.org/2001/XMLSchema#integer", '-42');
30 | addNumberTest(0, "TypedLiteral", "http://www.w3.org/2001/XMLSchema#integer", '0');
31 | });
32 |
--------------------------------------------------------------------------------
/test/builtins-Object.test.js:
--------------------------------------------------------------------------------
1 | var assert = require('assert');
2 | var rdf = require('..');
3 | var env = rdf.environment;
4 |
5 | function triple(s, p, o){
6 | // Don't normally use `new rdf.BlankNode`, except where determinism in output is needed
7 | return rdf.environment.createTriple(
8 | typeof s=='string' ? (s.substring(0,2)=='_:' ? new rdf.BlankNode(s) : rdf.environment.createNamedNode(s)) : s ,
9 | typeof p=='string' ? (p.substring(0,2)=='_:' ? new rdf.BlankNode(p) : rdf.environment.createNamedNode(p)) : p ,
10 | typeof o=='string' ? (o.substring(0,2)=='_:' ? new rdf.BlankNode(o) : rdf.environment.createNamedNode(o)) : o
11 | );
12 | }
13 |
14 | function generateRefTest(subject, topic, expectedn3, expectedNT, expectedtriples){
15 | // Setup tests
16 | var expectedGraph = new rdf.Graph;
17 | expectedGraph.addAll(expectedtriples);
18 |
19 | // Test interface
20 | it('('+subject+').ref() methods', function(){
21 | var t = topic().ref(subject);
22 | assert.equal(typeof t.n3, 'function');
23 | assert.equal(typeof t.toNT, 'function');
24 | assert.equal(typeof t.graphify, 'function');
25 | });
26 | it('('+subject+').ref().graphify()', function(){
27 | var t = topic().ref(subject);
28 | // test graphify
29 | var outputGraph = t.graphify();
30 | // Have the data, compare
31 | var expectedTriples = expectedGraph.toArray().sort();
32 | var outputTriples = outputGraph.toArray().sort();
33 | if(!expectedGraph.equals(outputGraph)){
34 | assert.equal(outputTriples.join('\n'), expectedTriples.join('\n'));
35 | assert(expectedGraph.equals(outputGraph));
36 | }
37 | });
38 | it('('+subject+').ref().n3() expected output', function(){
39 | var t = topic().ref(subject);
40 | var n3 = t.n3();
41 | // test n3
42 | assert.equal(n3, expectedn3);
43 | });
44 | it('('+subject+').ref().n3() parse graph', function(){
45 | var t = topic().ref(subject);
46 | var n3 = t.n3();
47 | // Parse the generated n3 as Turtle
48 | var outputGraph = env.createGraph();
49 | var parser = new rdf.TurtleParser(t.getProfile());
50 | parser.parse(n3, undefined, 'http://example.com/', null, outputGraph);
51 | // Have the data, compare
52 | var expectedTriples = expectedGraph.toArray().sort();
53 | var outputTriples = outputGraph.toArray().sort();
54 | if(!expectedGraph.equals(outputGraph)){
55 | assert.equal(outputTriples.join('\n'), expectedTriples.join('\n'));
56 | assert(expectedGraph.equals(outputGraph));
57 | }
58 | });
59 | if(expectedNT) it('('+subject+').ref().toNT() expected output', function(){
60 | var t = topic().ref(subject);
61 | var NT = t.toNT().replace(/_:b\d+/g, '_:bn');
62 | // test toNT
63 | assert.equal(NT, expectedNT);
64 | });
65 | it('('+subject+').ref().toNT() parsed graph', function(){
66 | var t = topic().ref(subject);
67 | var NT = t.toNT();
68 | // Parse the generated N-Triples
69 | var outputGraph = env.createGraph();
70 | var parser = new rdf.TurtleParser;
71 | parser.parse(NT, undefined, 'http://example.com/', null, outputGraph);
72 | // Have the data, compare
73 | var expectedTriples = expectedGraph.toArray().sort();
74 | var outputTriples = outputGraph.toArray().sort();
75 | if(!expectedGraph.equals(outputGraph)){
76 | assert.equal(outputTriples.join('\n'), expectedTriples.join('\n'));
77 | assert(expectedGraph.equals(outputGraph));
78 | }
79 | });
80 | }
81 |
82 | describe('Object builtins', function(){
83 | before(function(){
84 | rdf.setBuiltins();
85 | });
86 | after(function(){
87 | rdf.unsetBuiltins();
88 | });
89 |
90 | describe('().ref the a keyword', function(){
91 | generateRefTest('_:topic1',
92 | function(){
93 | return {a: 'rdfs:Class'};
94 | },
95 | '_:topic1 rdf:type rdfs:Class .',
96 | '_:topic1 .',
97 | [ triple('_:topic1', "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", 'http://www.w3.org/2000/01/rdf-schema#Class') ]
98 | );
99 | });
100 | describe('().ref integer', function(){
101 | generateRefTest('_:integer',
102 | function(){
103 | return {rdf$value: 42};
104 | },
105 | '_:integer rdf:value 42 .',
106 | '_:integer "42"^^ .',
107 | [ triple('_:integer', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#value', new rdf.Literal('42','http://www.w3.org/2001/XMLSchema#integer')) ]
108 | );
109 | });
110 | describe('().ref decimal', function(){
111 | generateRefTest('_:decimal',
112 | function(){
113 | return {rdf$value: 4.4};
114 | },
115 | '_:decimal rdf:value 4.4 .',
116 | '_:decimal "4.4"^^ .',
117 | [ triple('_:decimal', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#value', new rdf.Literal('4.4','http://www.w3.org/2001/XMLSchema#decimal')) ]
118 | );
119 | });
120 | describe('(_:topic4).ref string spaces', function(){
121 | generateRefTest('_:topic4',
122 | function(){
123 | return {rdf$value: env.createLiteral("A string 2000.")};
124 | },
125 | '_:topic4 rdf:value "A string 2000." .',
126 | '_:topic4 "A string 2000." .',
127 | [ triple('_:topic4', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#value', new rdf.Literal("A string 2000.")) ]
128 | );
129 | });
130 | describe('(_:topic5).ref language literal', function(){
131 | generateRefTest('_:topic5',
132 | function(){
133 | return {rdf$value: "The Hobbit".l('en')};
134 | },
135 | '_:topic5 rdf:value "The Hobbit"@en .',
136 | '_:topic5 "The Hobbit"@en .',
137 | [ triple('_:topic5', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#value', new rdf.Literal("The Hobbit",'@en')) ]
138 | );
139 | });
140 | describe('(_:topic6).ref', function(){
141 | // Normally, use env.createBlankNode
142 | // For deterministic tests, we use BlankNode with a name
143 | generateRefTest('_:topic6',
144 | function(){
145 | return {rdf$value: new rdf.BlankNode('_:target')};
146 | },
147 | '_:topic6 rdf:value _:target .',
148 | '_:topic6 _:target .',
149 | [ triple('_:topic6', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#value', '_:target') ]
150 | );
151 | });
152 | describe('(_:mval).ref multiple values', function(){
153 | // Normally, use env.createBlankNode
154 | // For deterministic tests, we use BlankNode with a name
155 | generateRefTest('_:mval',
156 | function(){ return {
157 | rdfs$label: [
158 | env.createLiteral("Harry Potter and the Philosopher's Stone", '@en'),
159 | env.createLiteral("Harry Potter and the Sorcerer's Stone", "@en-US"),
160 | ],
161 | }; },
162 | '_:mval rdfs:label "Harry Potter and the Philosopher\'s Stone"@en, "Harry Potter and the Sorcerer\'s Stone"@en-US .',
163 | null,
164 | [
165 | triple('_:mval', 'http://www.w3.org/2000/01/rdf-schema#label', new rdf.Literal("Harry Potter and the Philosopher's Stone", '@en')),
166 | triple('_:mval', 'http://www.w3.org/2000/01/rdf-schema#label', new rdf.Literal("Harry Potter and the Sorcerer's Stone", '@en-US')),
167 | ]
168 | );
169 | });
170 | describe('(_:mval).ref multiple values with bnode', function(){
171 | // Normally, use env.createBlankNode
172 | // For deterministic tests, we use BlankNode with a name
173 | generateRefTest('_:mval',
174 | function(){ return {
175 | rdfs$label: [
176 | env.createLiteral("Harry Potter and the Philosopher's Stone", '@en'),
177 | {
178 | rdf$type: "http://example.com/",
179 | rdfs$label: new rdf.Literal("Harry Potter and the Sorcerer's Stone", '@en-US'),
180 | },
181 | ],
182 | }; },
183 | '_:mval rdfs:label "Harry Potter and the Philosopher\'s Stone"@en, [\n\t\trdf:type ;\n\t\trdfs:label "Harry Potter and the Sorcerer\'s Stone"@en-US\n\t\t] .',
184 | null,
185 | [
186 | triple('_:mval', 'http://www.w3.org/2000/01/rdf-schema#label', new rdf.Literal("Harry Potter and the Philosopher's Stone", '@en')),
187 | triple('_:mval', 'http://www.w3.org/2000/01/rdf-schema#label', new rdf.BlankNode('_:a')),
188 | triple('_:a', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', new rdf.NamedNode('http://example.com/')),
189 | triple('_:a', 'http://www.w3.org/2000/01/rdf-schema#label', new rdf.Literal("Harry Potter and the Sorcerer's Stone", '@en-US')),
190 | ]);
191 | });
192 | describe('(_:topic7).ref objects are unlabeled blank nodes', function(){
193 | var b1 = new rdf.BlankNode('_:b1');
194 | var b2 = new rdf.BlankNode('_:target');
195 | generateRefTest('_:topic7',
196 | function(){
197 | return {rdf$value: {rdf$value: '_:target'}};
198 | },
199 | '_:topic7 rdf:value [\n\t\trdf:value _:target\n\t\t] .',
200 | '_:topic7 _:bn .\n_:bn _:target .',
201 | [
202 | triple('_:topic7', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#value', b1),
203 | triple(b1, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#value', b2),
204 | ]
205 | );
206 | });
207 | describe('(_:set).ref lists with @set', function(){
208 | generateRefTest('_:set',
209 | function(){
210 | return {rdf$value: {'@set': ['http://example.com/1', 'http://example.com/2']}};
211 | },
212 | '_:set rdf:value , .',
213 | '_:set .\n_:set .',
214 | [
215 | triple('_:set', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#value', 'http://example.com/1'),
216 | triple('_:set', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#value', 'http://example.com/2'),
217 | ]
218 | );
219 | });
220 | describe('(_:list).ref collections with @list', function(){
221 | var b1 = new rdf.BlankNode('_:b1');
222 | var b2 = new rdf.BlankNode('_:target');
223 | generateRefTest('_:list',
224 | function(){
225 | return {rdf$value: {'@list': ['http://example.com/1', 'http://example.com/2']}};
226 | },
227 | '_:list rdf:value ( ) .',
228 | null,
229 | [
230 | triple('_:list', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#value', b1),
231 | triple(b1, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'http://example.com/1'),
232 | triple(b1, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', b2),
233 | triple(b2, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'http://example.com/2'),
234 | triple(b2, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'),
235 | ]
236 | );
237 | });
238 | describe('(dbr:Albert_Einstein).ref', function(){
239 | /*
240 | dbp:dateOfBirth "1879-03-14"^^xsd:date ; # we only produce xsd:dateTime
241 | foaf:depiction .
242 | */
243 | generateRefTest( 'http://dbpedia.org/resource/Albert_Einstein',
244 | function(){
245 | return {
246 | $context: {
247 | 'dbr': 'http://dbpedia.org/resource/',
248 | 'dbp': 'http://dbpedia.org/property/',
249 | 'foaf': 'http://xmlns.com/foaf/0.1/',
250 | },
251 | dbp$dateOfBirth: new Date("1879-03-14"),
252 | 'foaf:depiction': 'http://en.wikipedia.org/wiki/Image:Albert_Einstein_Head.jpg',
253 | };
254 | },
255 | 'dbr:Albert_Einstein\n\tdbp:dateOfBirth "1879-03-14T00:00:00Z"^^xsd:dateTime;\n\tfoaf:depiction .',
256 | ' "1879-03-14T00:00:00Z"^^ .\n .',
257 | [
258 | triple("http://dbpedia.org/resource/Albert_Einstein", "http://xmlns.com/foaf/0.1/depiction", 'http://en.wikipedia.org/wiki/Image:Albert_Einstein_Head.jpg'),
259 | triple("http://dbpedia.org/resource/Albert_Einstein", "http://dbpedia.org/property/dateOfBirth", new rdf.Literal("1879-03-14T00:00:00Z",rdf.xsdns('dateTime'))),
260 | ]
261 | );
262 | });
263 | describe('(webr3).ref()', function(){
264 | generateRefTest('http://webr3.org/#me',
265 | function(){
266 | return {
267 | '@id': 'http://webr3.org/#me',
268 | '@context': {
269 | '@vocab': 'http://xmlns.com/foaf/0.1/',
270 | 'dbr': 'http://dbpedia.org/resource/',
271 | 'dbp': 'http://dbpedia.org/property/',
272 | 'foaf': 'http://xmlns.com/foaf/0.1/',
273 | },
274 | a: 'foaf:Person', // a CURIE
275 | foaf$name: env.createLiteral('Nathan'),
276 | foaf$age: 2018 - 1981,
277 | foaf$holdsAccount: {
278 | a: 'OnlineAccount',
279 | rdfs$label: rdf.environment.createLiteral("Nathan's twitter account", 'en'),
280 | accountName: env.createLiteral('webr3'),
281 | homepage: 'http://twitter.com/webr3',
282 | },
283 | foaf$nick: [env.createLiteral('webr3'), env.createLiteral('nath')],
284 | foaf$homepage: 'http://webr3.org/',
285 | };
286 | },
287 | '\n'
288 | + '\trdf:type foaf:Person;\n'
289 | + '\tfoaf:name "Nathan";\n'
290 | + '\tfoaf:age 37;\n'
291 | + '\tfoaf:holdsAccount [\n'
292 | + '\t\trdf:type foaf:OnlineAccount;\n'
293 | + '\t\trdfs:label "Nathan\'s twitter account"@en;\n'
294 | + '\t\tfoaf:accountName "webr3";\n'
295 | + '\t\tfoaf:homepage \n'
296 | + '\t\t];\n'
297 | + '\tfoaf:nick "webr3", "nath";\n'
298 | + '\tfoaf:homepage .'
299 | ,
300 | null,
301 | [
302 | triple("http://webr3.org/#me", 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', 'http://xmlns.com/foaf/0.1/Person'),
303 | triple("http://webr3.org/#me", "http://xmlns.com/foaf/0.1/name", new rdf.Literal("Nathan")),
304 | triple("http://webr3.org/#me", "http://xmlns.com/foaf/0.1/age", new rdf.Literal("37",rdf.xsdns('integer'))),
305 | triple("http://webr3.org/#me", "http://xmlns.com/foaf/0.1/homepage", 'http://webr3.org/'),
306 | triple("http://webr3.org/#me", "http://xmlns.com/foaf/0.1/holdsAccount", '_:account'),
307 | triple("http://webr3.org/#me", "http://xmlns.com/foaf/0.1/nick", new rdf.Literal('webr3')),
308 | triple("http://webr3.org/#me", "http://xmlns.com/foaf/0.1/nick", new rdf.Literal('nath')),
309 | triple("_:account", "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", 'http://xmlns.com/foaf/0.1/OnlineAccount'),
310 | triple("_:account", "http://www.w3.org/2000/01/rdf-schema#label", new rdf.Literal('Nathan\'s twitter account', '@en')),
311 | triple("_:account", "http://xmlns.com/foaf/0.1/accountName", new rdf.Literal('webr3')),
312 | triple("_:account", "http://xmlns.com/foaf/0.1/homepage", 'http://twitter.com/webr3'),
313 | ]);
314 | });
315 | });
316 |
--------------------------------------------------------------------------------
/test/builtins-String.test.js:
--------------------------------------------------------------------------------
1 | var assert = require('assert');
2 | var rdf = require('..');
3 |
4 | describe('String builtins', function(){
5 | before(function(){
6 | rdf.setBuiltins();
7 | });
8 | after(function(){
9 | rdf.unsetBuiltins();
10 | });
11 |
12 | it("String.prototype.profile", function(){
13 | var t = "".profile;
14 | assert(t instanceof rdf.Profile);
15 | assert.strictEqual(t, rdf.environment);
16 | });
17 | it("String.resolve rdf:type", function(){
18 | var t = "rdf:type".resolve();
19 | assert.strictEqual(t, "http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
20 | });
21 | it("String.resolve rdfs:Class", function(){
22 | var t = "rdfs:Class".resolve();
23 | assert.strictEqual(t, "http://www.w3.org/2000/01/rdf-schema#Class");
24 | assert.equal(typeof t, 'string');
25 | });
26 | it("String.resolve unknown CURIE", function(){
27 | var t = "unknownprefixfoo2:bar".resolve();
28 | assert.strictEqual(t, "unknownprefixfoo2:bar");
29 | assert.equal(t, "unknownprefixfoo2:bar");
30 | assert.equal(typeof t, "string");
31 | assert.ok("unknownprefixfoo2:bar".equals(t));
32 | });
33 | it("String.resolve defined CURIE", function(){
34 | assert.strictEqual("unknownprefixfoo2:answer".resolve(), 'unknownprefixfoo2:answer');
35 | rdf.environment.setPrefix("unknownprefixfoo2", "http://example.com/2/ex/42/");
36 | var t = "unknownprefixfoo2:answer".resolve();
37 | assert.strictEqual(t, "http://example.com/2/ex/42/answer");
38 | assert.strictEqual(t.valueOf(), "http://example.com/2/ex/42/answer");
39 | assert.ok("http://example.com/2/ex/42/answer".equals(t));
40 | rdf.environment.setPrefix("unknownprefixfoo2", null);
41 | assert.strictEqual("unknownprefixfoo2:answer".resolve(), 'unknownprefixfoo2:answer');
42 | });
43 | it("String.resolve defined term", function(){
44 | assert.strictEqual("term2".resolve(), 'term2');
45 | rdf.environment.setTerm("term2", "http://example.com/2/ex/42");
46 | var t = "term2".resolve();
47 | assert.strictEqual(t, "http://example.com/2/ex/42");
48 | //assert.strictEqual(t.valueOf(), "http://example.com/2/ex/42");
49 | //assert.ok("http://example.com/2/ex/42".equals(t));
50 | rdf.environment.setTerm("term2", null);
51 | assert.strictEqual("term2".resolve(), 'term2');
52 | });
53 | it("String.resolve http: URI", function(){
54 | assert.strictEqual("http://example.com/foo".resolve(), 'http://example.com/foo');
55 | });
56 | it("String.resolve https: URI", function(){
57 | assert.strictEqual("https://example.com/foo".resolve(), 'https://example.com/foo');
58 | });
59 | it("String.resolve urn:uuid: URI", function(){
60 | assert.strictEqual("urn:uuid:76E923E9-67CD-47AC-AB72-1C339A31CE57".resolve(), 'urn:uuid:76E923E9-67CD-47AC-AB72-1C339A31CE57');
61 | });
62 | it("string.resolve() resolved URI", function(){
63 | var t = "http://slashdot.org/".resolve();
64 | assert.strictEqual(t, 'http://slashdot.org/');
65 | });
66 | it("string.resolve() bnode syntax", function(){
67 | var t = "_:someBlankNode".resolve();
68 | assert.strictEqual(t, '_:someBlankNode');
69 | });
70 | it("string.n3()", function(){
71 | var t = "http://slashdot.org/".n3();
72 | assert.strictEqual(t, '');
73 | });
74 | it("string.toNT()", function(){
75 | var t = "http://slashdot.org/".toNT();
76 | assert.strictEqual(t, '');
77 | });
78 | it('string.l().n3()', function(){
79 | var t = "PLAINLITERAL".l().n3();
80 | assert.strictEqual(t, '"PLAINLITERAL"');
81 | });
82 | it('string.l().toNT()', function(){
83 | var t = "PLAINLITERAL".l().toNT();
84 | assert.strictEqual(t, '"PLAINLITERAL"');
85 | });
86 | it('string.l().n3()', function(){
87 | var t = "PLAIN LITERAL WITH A SPACE".l().n3();
88 | assert.strictEqual(t, '"PLAIN LITERAL WITH A SPACE"');
89 | });
90 | it('string.l().toNT()', function(){
91 | var t = "PLAIN LITERAL WITH A SPACE".l().toNT();
92 | assert.strictEqual(t, '"PLAIN LITERAL WITH A SPACE"');
93 | });
94 | it('string.l(en).n3()', function(){
95 | var t = "English language literal".l("en").n3();
96 | assert.strictEqual(t, '"English language literal"@en');
97 | });
98 | it('string.l(en).toNT()', function(){
99 | var t = "English language literal".l("en").toNT();
100 | assert.strictEqual(t, '"English language literal"@en');
101 | });
102 | it('string.tl(xsd:string).n3()', function(){
103 | var t = "XSD String".tl("xsd:string".resolve()).n3();
104 | assert.strictEqual(t, '"XSD String"');
105 | });
106 | it('string.tl(xsd:string).toNT()', function(){
107 | var t = "XSD String".tl("xsd:string".resolve()).toNT();
108 | assert.strictEqual(t, '"XSD String"');
109 | });
110 | });
111 |
--------------------------------------------------------------------------------
/test/environment.test.js:
--------------------------------------------------------------------------------
1 | var assert = require('assert');
2 | var rdf = require('..');
3 |
4 | describe('rdf.environment', function(){
5 | it("instance", function(){
6 | var t = rdf.environment;
7 | assert(t instanceof rdf.RDFEnvironment);
8 | });
9 | it("environment.prefixes.resolve rdf:type", function(){
10 | var t = rdf.environment.prefixes.resolve("rdf:type");
11 | assert.strictEqual(t, "http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
12 | });
13 | it("environment.prefixes.resolve rdfs:Class", function(){
14 | var t = rdf.environment.prefixes.resolve("rdfs:Class");
15 | assert.strictEqual(t, "http://www.w3.org/2000/01/rdf-schema#Class");
16 | });
17 | it("environment.prefixes.resolve unknown CURIE", function(){
18 | var t = rdf.environment.prefixes.resolve("unkfoo:bar");
19 | assert.equal(t, null);
20 | });
21 | it("environment.prefixes.resolve default prefix", function(){
22 | var t = rdf.environment.prefixes.resolve(":bar");
23 | assert.equal(t, null);
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/test/ns.test.js:
--------------------------------------------------------------------------------
1 | var assert = require('assert');
2 | var rdf = require('..');
3 |
4 | describe('ns', function(){
5 | it('rdf.ns', function(){
6 | var foaf = rdf.ns('http://xmlns.com/foaf/0.1/');
7 | assert.equal(foaf('name'), 'http://xmlns.com/foaf/0.1/name');
8 | });
9 | it('rdf.ns expects string', function(){
10 | assert.throws(function(){
11 | rdf.ns(1);
12 | });
13 | });
14 | it('rdf.ns output function expects string', function(){
15 | var foaf = rdf.ns('http://xmlns.com/foaf/0.1/');
16 | assert.throws(function(){
17 | foaf(2);
18 | });
19 | });
20 | });
21 | describe('ns builtins', function(){
22 | it('rdf.rdfns', function(){
23 | assert.equal(rdf.rdfns('type'), 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type');
24 | });
25 | it('rdf.rdfsns', function(){
26 | assert.equal(rdf.rdfsns('Class'), 'http://www.w3.org/2000/01/rdf-schema#Class');
27 | });
28 | it('rdf.xsdns', function(){
29 | assert.equal(rdf.xsdns('integer'), 'http://www.w3.org/2001/XMLSchema#integer');
30 | });
31 | });
32 |
--------------------------------------------------------------------------------
/test/parse.test.js:
--------------------------------------------------------------------------------
1 | var assert = require('assert');
2 | var rdf = require('..');
3 | var env = rdf.environment;
4 |
5 | function triple(s, p, o){
6 | // Don't normally use `new rdf.BlankNode`, except where determinism in output is needed
7 | return rdf.environment.createTriple(
8 | typeof s=='string' ? (s.substring(0,2)=='_:' ? new rdf.BlankNode(s) : rdf.environment.createNamedNode(s)) : s ,
9 | typeof p=='string' ? (p.substring(0,2)=='_:' ? new rdf.BlankNode(p) : rdf.environment.createNamedNode(p)) : p ,
10 | typeof o=='string' ? (o.substring(0,2)=='_:' ? new rdf.BlankNode(o) : rdf.environment.createNamedNode(o)) : o
11 | );
12 | }
13 |
14 | function generateRefTest(subject, topic, expectedn3, expectedNT, expectedtriples){
15 | // Setup tests
16 | var expectedGraph = new rdf.Graph;
17 | expectedGraph.addAll(expectedtriples);
18 |
19 | // Test interface
20 | it('parse('+subject+') methods', function(){
21 | var t = rdf.parse(topic(), subject);
22 | assert.equal(typeof t.n3, 'function');
23 | assert.equal(typeof t.toNT, 'function');
24 | assert.equal(typeof t.graphify, 'function');
25 | });
26 | it('parse('+subject+').graphify()', function(){
27 | var t = rdf.parse(topic(), subject);
28 | // test graphify
29 | var outputGraph = t.graphify();
30 | // Have the data, compare
31 | var expectedTriples = expectedGraph.toArray().sort();
32 | var outputTriples = outputGraph.toArray().sort();
33 | if(!expectedGraph.isomorphic(outputGraph)){
34 | assert.equal(outputTriples.join('\n'), expectedTriples.join('\n'));
35 | assert(expectedGraph.isomorphic(outputGraph));
36 | }
37 | });
38 | it('parse('+subject+').n3() expected output', function(){
39 | var t = rdf.parse(topic(), subject);
40 | var n3 = t.n3();
41 | // test n3
42 | assert.equal(n3, expectedn3);
43 | });
44 | it('parse('+subject+').n3() parse graph', function(){
45 | var t = rdf.parse(topic(), subject);
46 | var n3 = t.n3();
47 | // Parse the generated n3 as Turtle
48 | var outputGraph = env.createGraph();
49 | var parser = new rdf.TurtleParser(t.getProfile());
50 | parser.parse(n3, undefined, 'http://example.com/', null, outputGraph);
51 | // Have the data, compare
52 | var expectedTriples = expectedGraph.toArray().sort();
53 | var outputTriples = outputGraph.toArray().sort();
54 | if(!expectedGraph.isomorphic(outputGraph)){
55 | assert.equal(outputTriples.join('\n'), expectedTriples.join('\n'));
56 | assert(expectedGraph.isomorphic(outputGraph));
57 | }
58 | });
59 | if(expectedNT) it('parse('+subject+').toNT() expected output', function(){
60 | var t = rdf.parse(topic(), subject);
61 | var NT = t.toNT().replace(/_:b\d+/g, '_:bn');
62 | // test toNT
63 | assert.equal(NT, expectedNT);
64 | });
65 | it('parse('+subject+').toNT() parsed graph', function(){
66 | var t = rdf.parse(topic(), subject);
67 | var NT = t.toNT();
68 | // Parse the generated N-Triples
69 | var outputGraph = env.createGraph();
70 | var parser = new rdf.TurtleParser;
71 | parser.parse(NT, undefined, 'http://example.com/', null, outputGraph);
72 | // Have the data, compare
73 | var expectedTriples = expectedGraph.toArray().sort();
74 | var outputTriples = outputGraph.toArray().sort();
75 | if(!expectedGraph.isomorphic(outputGraph)){
76 | assert.equal(outputTriples.join('\n'), expectedTriples.join('\n'));
77 | assert(expectedGraph.isomorphic(outputGraph));
78 | }
79 | });
80 | }
81 |
82 | describe('parse', function(){
83 | describe('parse(_:topic1)', function(){
84 | generateRefTest('_:topic1',
85 | function(){
86 | return {a: 'rdfs:Class'};
87 | },
88 | '_:topic1 rdf:type rdfs:Class .',
89 | '_:topic1 .',
90 | [ triple('_:topic1', "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", 'http://www.w3.org/2000/01/rdf-schema#Class') ]
91 | );
92 | });
93 | describe('parse(_:integer)', function(){
94 | generateRefTest('_:integer',
95 | function(){
96 | return {rdf$value: 42};
97 | },
98 | '_:integer rdf:value 42 .',
99 | '_:integer "42"^^ .',
100 | [ triple('_:integer', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#value', new rdf.Literal('42','http://www.w3.org/2001/XMLSchema#integer')) ]
101 | );
102 | });
103 | describe('parse(_:decimal)', function(){
104 | generateRefTest('_:decimal',
105 | function(){
106 | return {rdf$value: 4.4};
107 | },
108 | '_:decimal rdf:value 4.4 .',
109 | '_:decimal "4.4"^^ .',
110 | [ triple('_:decimal', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#value', new rdf.Literal('4.4','http://www.w3.org/2001/XMLSchema#decimal')) ]
111 | );
112 | });
113 | describe('parse(_:topic4) string spaces', function(){
114 | generateRefTest('_:topic4',
115 | function(){
116 | return {rdf$value: env.createLiteral("A string 2000.")};
117 | },
118 | '_:topic4 rdf:value "A string 2000." .',
119 | '_:topic4 "A string 2000." .',
120 | [ triple('_:topic4', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#value', new rdf.Literal("A string 2000.")) ]
121 | );
122 | });
123 | describe('parse(_:topic5) language literal', function(){
124 | generateRefTest('_:topic5',
125 | function(){
126 | return {rdf$value: env.createLiteral("The Hobbit", '@en')};
127 | },
128 | '_:topic5 rdf:value "The Hobbit"@en .',
129 | '_:topic5 "The Hobbit"@en .',
130 | [ triple('_:topic5', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#value', new rdf.Literal("The Hobbit",'@en')) ]
131 | );
132 | });
133 | describe('parse(_:topic6)', function(){
134 | // Normally, use env.createBlankNode
135 | // For deterministic tests, we use BlankNode with a name
136 | generateRefTest('_:topic6',
137 | function(){
138 | return {rdf$value: new rdf.BlankNode('_:target')};
139 | },
140 | '_:topic6 rdf:value _:target .',
141 | '_:topic6 _:target .',
142 | [ triple('_:topic6', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#value', '_:target') ]
143 | );
144 | });
145 | describe('parse(_:mval) multiple values', function(){
146 | // Normally, use env.createBlankNode
147 | // For deterministic tests, we use BlankNode with a name
148 | generateRefTest('_:mval',
149 | function(){ return {
150 | rdfs$label: [
151 | env.createLiteral("Harry Potter and the Philosopher's Stone", '@en'),
152 | env.createLiteral("Harry Potter and the Sorcerer's Stone", "@en-US"),
153 | ],
154 | }; },
155 | '_:mval rdfs:label "Harry Potter and the Philosopher\'s Stone"@en, "Harry Potter and the Sorcerer\'s Stone"@en-US .',
156 | null,
157 | [
158 | triple('_:mval', 'http://www.w3.org/2000/01/rdf-schema#label', new rdf.Literal("Harry Potter and the Philosopher's Stone", '@en')),
159 | triple('_:mval', 'http://www.w3.org/2000/01/rdf-schema#label', new rdf.Literal("Harry Potter and the Sorcerer's Stone", '@en-US')),
160 | ]
161 | );
162 | });
163 | describe('parse(_:mval) multiple values with bnode', function(){
164 | // Normally, use env.createBlankNode
165 | // For deterministic tests, we use BlankNode with a name
166 | generateRefTest('_:mval',
167 | function(){ return {
168 | rdfs$label: [
169 | env.createLiteral("Harry Potter and the Philosopher's Stone", '@en'),
170 | {
171 | rdf$type: "http://example.com/",
172 | rdfs$label: new rdf.Literal("Harry Potter and the Sorcerer's Stone", '@en-US'),
173 | },
174 | ],
175 | }; },
176 | '_:mval rdfs:label "Harry Potter and the Philosopher\'s Stone"@en, [\n\t\trdf:type ;\n\t\trdfs:label "Harry Potter and the Sorcerer\'s Stone"@en-US\n\t\t] .',
177 | null,
178 | [
179 | triple('_:mval', 'http://www.w3.org/2000/01/rdf-schema#label', new rdf.Literal("Harry Potter and the Philosopher's Stone", '@en')),
180 | triple('_:mval', 'http://www.w3.org/2000/01/rdf-schema#label', new rdf.BlankNode('_:a')),
181 | triple('_:a', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', new rdf.NamedNode('http://example.com/')),
182 | triple('_:a', 'http://www.w3.org/2000/01/rdf-schema#label', new rdf.Literal("Harry Potter and the Sorcerer's Stone", '@en-US')),
183 | ]
184 | );
185 | });
186 | describe('parse(_:topic7) objects are unlabeled blank nodes', function(){
187 | var b1 = new rdf.BlankNode('_:b1');
188 | var b2 = new rdf.BlankNode('_:target');
189 | generateRefTest('_:topic7',
190 | function(){
191 | return {rdf$value: {rdf$value: '_:target'}};
192 | },
193 | '_:topic7 rdf:value [\n\t\trdf:value _:target\n\t\t] .',
194 | '_:topic7 _:bn .\n_:bn _:target .',
195 | [
196 | triple('_:topic7', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#value', b1),
197 | triple(b1, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#value', b2),
198 | ]);
199 | });
200 | describe('parse(_:set) lists with @set', function(){
201 | generateRefTest('_:set',
202 | function(){
203 | return {rdf$value: {'@set': ['http://example.com/1', 'http://example.com/2']}};
204 | },
205 | '_:set rdf:value , .',
206 | '_:set .\n_:set .',
207 | [
208 | triple('_:set', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#value', 'http://example.com/1'),
209 | triple('_:set', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#value', 'http://example.com/2'),
210 | ]);
211 | });
212 | describe('parse(_:list) collections with @list', function(){
213 | var b1 = new rdf.BlankNode('_:b1');
214 | var b2 = new rdf.BlankNode('_:target');
215 | generateRefTest('_:list',
216 | function(){
217 | return {rdf$value: {'@list': ['http://example.com/1', 'http://example.com/2']}};
218 | },
219 | '_:list rdf:value ( ) .',
220 | null,
221 | [
222 | triple('_:list', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#value', b1),
223 | triple(b1, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'http://example.com/1'),
224 | triple(b1, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', b2),
225 | triple(b2, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'http://example.com/2'),
226 | triple(b2, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'),
227 | ]
228 | );
229 | });
230 | describe('parse(dbr:Albert_Einstein)', function(){
231 | /*
232 | dbp:dateOfBirth "1879-03-14"^^xsd:date ; # we only produce xsd:dateTime
233 | foaf:depiction .
234 | */
235 | generateRefTest( 'http://dbpedia.org/resource/Albert_Einstein',
236 | function(){
237 | return {
238 | $context: {
239 | 'dbr': 'http://dbpedia.org/resource/',
240 | 'dbp': 'http://dbpedia.org/property/',
241 | 'foaf': 'http://xmlns.com/foaf/0.1/',
242 | },
243 | dbp$dateOfBirth: new Date("1879-03-14"),
244 | 'foaf:depiction': 'http://en.wikipedia.org/wiki/Image:Albert_Einstein_Head.jpg',
245 | };
246 | },
247 | 'dbr:Albert_Einstein\n\tdbp:dateOfBirth "1879-03-14T00:00:00Z"^^xsd:dateTime;\n\tfoaf:depiction .',
248 | ' "1879-03-14T00:00:00Z"^^ .\n .',
249 | [
250 | triple("http://dbpedia.org/resource/Albert_Einstein", "http://xmlns.com/foaf/0.1/depiction", 'http://en.wikipedia.org/wiki/Image:Albert_Einstein_Head.jpg'),
251 | triple("http://dbpedia.org/resource/Albert_Einstein", "http://dbpedia.org/property/dateOfBirth", new rdf.Literal("1879-03-14T00:00:00Z",rdf.xsdns('dateTime'))),
252 | ]
253 | );
254 | });
255 | describe('parse(webr3)', function(){
256 | generateRefTest('http://webr3.org/#me',
257 | function(){
258 | return {
259 | '@id': 'http://webr3.org/#me',
260 | '@context': {
261 | '@vocab': 'http://xmlns.com/foaf/0.1/',
262 | 'dbr': 'http://dbpedia.org/resource/',
263 | 'dbp': 'http://dbpedia.org/property/',
264 | 'foaf': 'http://xmlns.com/foaf/0.1/',
265 | },
266 | a: 'foaf:Person', // a CURIE
267 | foaf$name: env.createLiteral('Nathan'),
268 | foaf$age: 2018 - 1981,
269 | foaf$holdsAccount: {
270 | a: 'OnlineAccount',
271 | rdfs$label: rdf.environment.createLiteral("Nathan's twitter account", 'en'),
272 | accountName: env.createLiteral('webr3'),
273 | homepage: 'http://twitter.com/webr3',
274 | },
275 | foaf$nick: [env.createLiteral('webr3'), env.createLiteral('nath')],
276 | foaf$homepage: 'http://webr3.org/',
277 | };
278 | },
279 | '\n'
280 | + '\trdf:type foaf:Person;\n'
281 | + '\tfoaf:name "Nathan";\n'
282 | + '\tfoaf:age 37;\n'
283 | + '\tfoaf:holdsAccount [\n'
284 | + '\t\trdf:type foaf:OnlineAccount;\n'
285 | + '\t\trdfs:label "Nathan\'s twitter account"@en;\n'
286 | + '\t\tfoaf:accountName "webr3";\n'
287 | + '\t\tfoaf:homepage \n'
288 | + '\t\t];\n'
289 | + '\tfoaf:nick "webr3", "nath";\n'
290 | + '\tfoaf:homepage .'
291 | ,
292 | null,
293 | [
294 | triple("http://webr3.org/#me", 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', 'http://xmlns.com/foaf/0.1/Person'),
295 | triple("http://webr3.org/#me", "http://xmlns.com/foaf/0.1/name", new rdf.Literal("Nathan")),
296 | triple("http://webr3.org/#me", "http://xmlns.com/foaf/0.1/age", new rdf.Literal("37",rdf.xsdns('integer'))),
297 | triple("http://webr3.org/#me", "http://xmlns.com/foaf/0.1/homepage", 'http://webr3.org/'),
298 | triple("http://webr3.org/#me", "http://xmlns.com/foaf/0.1/holdsAccount", '_:account'),
299 | triple("http://webr3.org/#me", "http://xmlns.com/foaf/0.1/nick", new rdf.Literal('webr3')),
300 | triple("http://webr3.org/#me", "http://xmlns.com/foaf/0.1/nick", new rdf.Literal('nath')),
301 | triple("_:account", "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", 'http://xmlns.com/foaf/0.1/OnlineAccount'),
302 | triple("_:account", "http://www.w3.org/2000/01/rdf-schema#label", new rdf.Literal('Nathan\'s twitter account', '@en')),
303 | triple("_:account", "http://xmlns.com/foaf/0.1/accountName", new rdf.Literal('webr3')),
304 | triple("_:account", "http://xmlns.com/foaf/0.1/homepage", 'http://twitter.com/webr3'),
305 | ]
306 | );
307 | });
308 | });
309 |
--------------------------------------------------------------------------------