Skip to content

Commit

Permalink
Implement DataFactory interface in N3Util
Browse files Browse the repository at this point in the history
  • Loading branch information
rubensworks authored and RubenVerborgh committed Apr 9, 2018
1 parent 35256b9 commit f9b355e
Show file tree
Hide file tree
Showing 2 changed files with 194 additions and 36 deletions.
58 changes: 49 additions & 9 deletions lib/N3Util.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,34 @@ var XsdBoolean = Xsd + 'boolean';
var Datatype = require('./Datatypes');
var Term = Datatype.Term,
NamedNode = Datatype.NamedNode,
Literal = Datatype.Literal;
BlankNode = Datatype.BlankNode,
Literal = Datatype.Literal,
Variable = Datatype.Variable,
DefaultGraph = Datatype.DefaultGraph,
Quad = Datatype.Quad;

var N3Util = {
// An internal counter for creating anonymous blank node labels
_blankNodeCounter: 0,

// Tests whether the given entity (triple object) represents an IRI
isIRI: function (entity) {
isNamedNode: function (entity) {
return !!entity && entity.termType === 'NamedNode';
},

// Tests whether the given entity (triple object) represents a blank node
isBlank: function (entity) {
return !!entity && entity.termType === 'BlankNode';
},

// Tests whether the given entity (triple object) represents a literal
isLiteral: function (entity) {
return !!entity && entity.termType === 'Literal';
},

// Tests whether the given entity (triple object) represents a blank node
isBlank: function (entity) {
return !!entity && entity.termType === 'BlankNode';
// Tests whether the given entity represents a variable
isVariable: function (entity) {
return !!entity && entity.termType === 'Variable';
},

// Tests whether the given entity represents the default graph
Expand Down Expand Up @@ -76,13 +88,21 @@ var N3Util = {
base + prefixedName.substr(index + prefix.length + 4));
},

// Creates an IRI in N3.js representation
createIRI: function (iri) {
// Creates an IRI
namedNode: function (iri) {
return iri && new NamedNode(iri[0] === '"' ? Term.fromId(iri).value : iri);
},

// Creates a literal in N3.js representation
createLiteral: function (value, modifier) {
// Creates a blank node
blankNode: function (name) {
if (!name)
name = 'n3' + N3Util._blankNodeCounter++;
return new BlankNode(name);
},

// Creates a literal
literal: function (value, languageOrDataType) {
var modifier = languageOrDataType && languageOrDataType.termType ? languageOrDataType.value : languageOrDataType;
if (!modifier) {
switch (typeof value) {
case 'boolean':
Expand All @@ -106,6 +126,26 @@ var N3Util = {
: '"^^' + modifier));
},

// Creates a variable
variable: function (name) {
return new Variable(name);
},

// Returns the default graph
defaultGraph: function () {
return new DefaultGraph();
},

// Creates a triple
triple: function (subject, predicate, object) {
return N3Util.quad(subject, predicate, object);
},

// Creates a quad
quad: function (subject, predicate, object, graph) {
return new Quad(subject, predicate, object, graph);
},

// Creates a function that prepends the given IRI to a local name
prefix: function (iri) {
return N3Util.prefixes({ '': iri })('');
Expand Down
172 changes: 145 additions & 27 deletions test/N3Util-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,38 @@ var N3Util = require('../N3').Util,
var NamedNode = Datatype.NamedNode,
Literal = Datatype.Literal,
BlankNode = Datatype.BlankNode,
Variable = Datatype.Variable,
DefaultGraph = Datatype.DefaultGraph,
Quad = Datatype.Quad;

describe('N3Util', function () {
describe('isIRI', function () {
describe('isNamedNode', function () {
it('matches an IRI', function () {
N3Util.isIRI(new NamedNode('http://example.org/')).should.be.true;
N3Util.isNamedNode(new NamedNode('http://example.org/')).should.be.true;
});

it('matches an empty IRI', function () {
N3Util.isIRI(new NamedNode('')).should.be.true;
N3Util.isNamedNode(new NamedNode('')).should.be.true;
});

it('does not match a literal', function () {
N3Util.isIRI(new Literal('"http://example.org/"')).should.be.false;
N3Util.isNamedNode(new Literal('"http://example.org/"')).should.be.false;
});

it('does not match a blank node', function () {
N3Util.isIRI(new BlankNode('x')).should.be.false;
N3Util.isNamedNode(new BlankNode('x')).should.be.false;
});

it('does not match a variable', function () {
N3Util.isNamedNode(new Variable('x')).should.be.false;
});

it('does not match null', function () {
expect(N3Util.isIRI(null)).to.be.false;
expect(N3Util.isNamedNode(null)).to.be.false;
});

it('does not match undefined', function () {
expect(N3Util.isIRI(undefined)).to.be.false;
expect(N3Util.isNamedNode(undefined)).to.be.false;
});
});

Expand Down Expand Up @@ -66,6 +71,10 @@ describe('N3Util', function () {
N3Util.isLiteral(new BlankNode('_:x')).should.be.false;
});

it('does not match a variable', function () {
N3Util.isLiteral(new Variable('x')).should.be.false;
});

it('does not match null', function () {
expect(N3Util.isLiteral(null)).to.be.false;
});
Expand All @@ -88,6 +97,10 @@ describe('N3Util', function () {
N3Util.isBlank(new Literal('"http://example.org/"')).should.be.false;
});

it('does not match a variable', function () {
N3Util.isBlank(new Variable('x')).should.be.false;
});

it('does not match null', function () {
expect(N3Util.isBlank(null)).to.be.false;
});
Expand All @@ -97,6 +110,32 @@ describe('N3Util', function () {
});
});

describe('isVariable', function () {
it('matches a variable', function () {
N3Util.isVariable(new Variable('x')).should.be.true;
});

it('does not match an IRI', function () {
N3Util.isVariable(new NamedNode('http://example.org/')).should.be.false;
});

it('does not match a literal', function () {
N3Util.isVariable(new Literal('"http://example.org/"')).should.be.false;
});

it('does not match a blank node', function () {
N3Util.isNamedNode(new BlankNode('x')).should.be.false;
});

it('does not match null', function () {
expect(N3Util.isVariable(null)).to.be.false;
});

it('does not match undefined', function () {
expect(N3Util.isVariable(undefined)).to.be.false;
});
});

describe('isDefaultGraph', function () {
it('does not match a blank node', function () {
N3Util.isDefaultGraph(new BlankNode('x')).should.be.false;
Expand Down Expand Up @@ -315,71 +354,150 @@ describe('N3Util', function () {
});
});

describe('createIRI', function () {
describe('namedNode', function () {
it('converts a plain IRI', function () {
N3Util.createIRI('http://ex.org/foo#bar').should.deep.equal(new NamedNode('http://ex.org/foo#bar'));
N3Util.namedNode('http://ex.org/foo#bar').should.deep.equal(new NamedNode('http://ex.org/foo#bar'));
});

it('converts a literal', function () {
N3Util.createIRI('"http://ex.org/foo#bar"^^uri:type').should.deep.equal(new NamedNode('http://ex.org/foo#bar'));
N3Util.namedNode('"http://ex.org/foo#bar"^^uri:type').should.deep.equal(new NamedNode('http://ex.org/foo#bar'));
});

it('converts null', function () {
expect(N3Util.createIRI(null)).to.be.null;
expect(N3Util.namedNode(null)).to.be.null;
});
});

describe('createLiteral', function () {
describe('blankNode', function () {
it('converts a label', function () {
N3Util.blankNode('abc').should.deep.equal(new BlankNode('abc'));
});

it('converts an anonymous blank node', function () {
N3Util.blankNode().should.deep.equal(new BlankNode('n30'));
N3Util.blankNode().should.deep.equal(new BlankNode('n31'));
});

it('does not create two equal anonymous blank nodes', function () {
N3Util.blankNode().should.not.deep.equal(N3Util.blankNode());
});
});

describe('literal', function () {
it('converts the empty string', function () {
N3Util.createLiteral('').should.deep.equal(new Literal('""'));
N3Util.literal('').should.deep.equal(new Literal('""'));
});

it('converts the empty string with a language', function () {
N3Util.createLiteral('', 'en-GB').should.deep.equal(new Literal('""@en-gb'));
N3Util.literal('', 'en-GB').should.deep.equal(new Literal('""@en-gb'));
});

it('converts the empty string with a named node type', function () {
N3Util.literal('', new NamedNode('http://ex.org/type')).should.deep.equal(new Literal('""^^http://ex.org/type'));
});

it('converts the empty string with a type', function () {
N3Util.createLiteral('', 'http://ex.org/type').should.deep.equal(new Literal('""^^http://ex.org/type'));
it('converts the empty string with a string type', function () {
N3Util.literal('', 'http://ex.org/type').should.deep.equal(new Literal('""^^http://ex.org/type'));
});

it('converts a non-empty string', function () {
N3Util.createLiteral('abc').should.deep.equal(new Literal('"abc"'));
N3Util.literal('abc').should.deep.equal(new Literal('"abc"'));
});

it('converts a non-empty string with a language', function () {
N3Util.createLiteral('abc', 'en-GB').should.deep.equal(new Literal('"abc"@en-gb'));
N3Util.literal('abc', 'en-GB').should.deep.equal(new Literal('"abc"@en-gb'));
});

it('converts a non-empty string with a type', function () {
N3Util.createLiteral('abc', 'http://ex.org/type').should.deep.equal(new Literal('"abc"^^http://ex.org/type'));
it('converts a non-empty string with a named node type', function () {
N3Util.literal('abc', new NamedNode('http://ex.org/type')).should.deep.equal(new Literal('"abc"^^http://ex.org/type'));
});

it('converts a non-empty string with a string type', function () {
N3Util.literal('abc', 'http://ex.org/type').should.deep.equal(new Literal('"abc"^^http://ex.org/type'));
});

it('converts an integer', function () {
N3Util.createLiteral(123).should.deep.equal(new Literal('"123"^^http://www.w3.org/2001/XMLSchema#integer'));
N3Util.literal(123).should.deep.equal(new Literal('"123"^^http://www.w3.org/2001/XMLSchema#integer'));
});

it('converts a double', function () {
N3Util.createLiteral(2.3).should.deep.equal(new Literal('"2.3"^^http://www.w3.org/2001/XMLSchema#double'));
N3Util.literal(2.3).should.deep.equal(new Literal('"2.3"^^http://www.w3.org/2001/XMLSchema#double'));
});

it('converts Infinity', function () {
N3Util.createLiteral(Infinity).should.deep.equal(new Literal('"INF"^^http://www.w3.org/2001/XMLSchema#double'));
N3Util.literal(Infinity).should.deep.equal(new Literal('"INF"^^http://www.w3.org/2001/XMLSchema#double'));
});

it('converts -Infinity', function () {
N3Util.createLiteral(-Infinity).should.deep.equal(new Literal('"-INF"^^http://www.w3.org/2001/XMLSchema#double'));
N3Util.literal(-Infinity).should.deep.equal(new Literal('"-INF"^^http://www.w3.org/2001/XMLSchema#double'));
});

it('converts NaN', function () {
N3Util.createLiteral(NaN).should.deep.equal(new Literal('"NaN"^^http://www.w3.org/2001/XMLSchema#double'));
N3Util.literal(NaN).should.deep.equal(new Literal('"NaN"^^http://www.w3.org/2001/XMLSchema#double'));
});

it('converts false', function () {
N3Util.createLiteral(false).should.deep.equal(new Literal('"false"^^http://www.w3.org/2001/XMLSchema#boolean'));
N3Util.literal(false).should.deep.equal(new Literal('"false"^^http://www.w3.org/2001/XMLSchema#boolean'));
});

it('converts true', function () {
N3Util.createLiteral(true).should.deep.equal(new Literal('"true"^^http://www.w3.org/2001/XMLSchema#boolean'));
N3Util.literal(true).should.deep.equal(new Literal('"true"^^http://www.w3.org/2001/XMLSchema#boolean'));
});
});

describe('variable', function () {
it('converts a label', function () {
N3Util.variable('abc').should.deep.equal(new Variable('abc'));
});
});

describe('defaultGraph', function () {
it('returns the default graph', function () {
N3Util.defaultGraph().should.deep.equal(new DefaultGraph());
});
});

describe('triple', function () {
it('returns a quad in the default graph', function () {
N3Util.triple(
new NamedNode('http://ex.org/a'),
new NamedNode('http://ex.org/b'),
new Literal('abc')
).should.deep.equal(new Quad(
new NamedNode('http://ex.org/a'),
new NamedNode('http://ex.org/b'),
new Literal('abc'),
new DefaultGraph()
));
});
});

describe('quad', function () {
it('returns a quad', function () {
N3Util.quad(
new NamedNode('http://ex.org/a'),
new NamedNode('http://ex.org/b'),
new Literal('abc'),
new NamedNode('http://ex.org/d')
).should.deep.equal(new Quad(
new NamedNode('http://ex.org/a'),
new NamedNode('http://ex.org/b'),
new Literal('abc'),
new NamedNode('http://ex.org/d')
));
});

it('without graph parameter returns a quad in the default graph', function () {
N3Util.quad(
new NamedNode('http://ex.org/a'),
new NamedNode('http://ex.org/b'),
new Literal('abc')
).should.deep.equal(new Quad(
new NamedNode('http://ex.org/a'),
new NamedNode('http://ex.org/b'),
new Literal('abc'),
new DefaultGraph()
));
});
});

Expand Down

0 comments on commit f9b355e

Please sign in to comment.