Skip to content

Commit 0bbc061

Browse files
authored
Merge pull request #156 from linkeddata/dan-f/add-mocha-tests
Add a coherent unit test framework
2 parents 6f62b2b + 91df779 commit 0bbc061

File tree

12 files changed

+211
-83
lines changed

12 files changed

+211
-83
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
parsers/*.js
22
node_modules
3+
npm-debug.log
34
dist/rdflib.min.js
45
lib/

Makefile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ writable:
6262

6363
.PHONY: test
6464
test:
65-
@nodeunit tests/*.js
65+
@nodeunit tests/unit/nodeunit/*.js
6666
make -C tests/serialize
67-
tape tests/unit/*.js
6867
make cleantest

package.json

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,18 @@
3737
"devDependencies": {
3838
"babel-cli": "^6.11.4",
3939
"babel-preset-es2015": "^6.9.0",
40+
"babel-register": "^6.18.0",
4041
"babelify": "^7.3.0",
4142
"browserify": "^13.0.0",
43+
"chai": "^3.5.0",
4244
"minifyify": "^7.3.2",
43-
"nodeunit": "^0.9.1",
44-
"tape": "^4.6.0"
45+
"mocha": "^3.2.0",
46+
"nodeunit": "^0.9.1"
4547
},
4648
"scripts": {
47-
"test": "make test",
49+
"test": "npm run test:unit && make test",
50+
"test:unit": "mocha --growl --require babel-register tests/unit/**-test.js",
51+
"test:unit:dev": "mocha --watch --growl --require babel-register tests/unit/**-test.js",
4852
"prepublish": "make lib"
4953
},
5054
"files": [

src/literal.js

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -100,14 +100,13 @@ class Literal extends Node {
100100
throw new TypeError('Invalid argument to Literal.fromNumber()')
101101
}
102102
let datatype
103-
if (('' + value).indexOf('e') >= 0) {
104-
datatype = XSD.float
105-
} else if (('' + value).indexOf('.') >= 0) {
106-
datatype = XSD.decimal
103+
const strValue = value.toString()
104+
if (strValue.indexOf('e') < 0 && Math.abs(value) <= Number.MAX_SAFE_INTEGER) {
105+
datatype = Number.isInteger(value) ? XSD.integer : XSD.decimal
107106
} else {
108-
datatype = XSD.integer
107+
datatype = XSD.double
109108
}
110-
return new Literal('' + value, null, datatype)
109+
return new Literal(strValue, null, datatype)
111110
}
112111
/**
113112
* @method fromValue
@@ -118,7 +117,7 @@ class Literal extends Node {
118117
if (typeof value === 'undefined' || value === null) {
119118
return value
120119
}
121-
if (value && value.termType) { // this is a Node instance
120+
if (typeof value === 'object' && value.termType) { // this is a Node instance
122121
return value
123122
}
124123
switch (typeof value) {

src/named-node.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class NamedNode extends Node {
1414
constructor (iri) {
1515
super()
1616
this.termType = NamedNode.termType
17-
if (iri.indexOf(':') < 0){
17+
if (iri.indexOf(':') < 0) {
1818
console.log('Warning: NamedNode URI must be absolute. Relative URIs will fail in future versions')
1919
}
2020
this.value = iri

src/xsd.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ class XSD {}
55
XSD.boolean = new NamedNode('http://www.w3.org/2001/XMLSchema#boolean')
66
XSD.dateTime = new NamedNode('http://www.w3.org/2001/XMLSchema#dateTime')
77
XSD.decimal = new NamedNode('http://www.w3.org/2001/XMLSchema#decimal')
8-
XSD.float = new NamedNode('http://www.w3.org/2001/XMLSchema#float')
8+
XSD.double = new NamedNode('http://www.w3.org/2001/XMLSchema#double')
99
XSD.integer = new NamedNode('http://www.w3.org/2001/XMLSchema#integer')
1010
XSD.langString =
1111
new NamedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#langString')

tests/unit/indexed-formula-test.js

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/* eslint-env mocha */
2+
import { expect } from 'chai'
3+
4+
import IndexedFormula from '../../src/indexed-formula'
5+
import NamedNode from '../../src/named-node'
6+
import { triple } from '../../src/data-factory'
7+
8+
describe('IndexedFormula', () => {
9+
describe('match', () => {
10+
const s1 = NamedNode.fromValue('https://example.com/subject1')
11+
const p1 = NamedNode.fromValue('https://example.com/predicate1')
12+
const o1 = NamedNode.fromValue('https://example.com/object1')
13+
const triple1 = triple(s1, p1, o1)
14+
15+
const s2 = NamedNode.fromValue('https://example.com/subject2')
16+
const p2 = NamedNode.fromValue('https://example.com/predicate2')
17+
const o2 = NamedNode.fromValue('https://example.com/object2')
18+
const triple2 = triple(s2, p2, o2)
19+
20+
const s3 = NamedNode.fromValue('https://example.com/subject3')
21+
const p3 = NamedNode.fromValue('https://example.com/predicate3')
22+
const o3 = NamedNode.fromValue('https://example.com/object3')
23+
const triple3 = triple(s3, p3, o3)
24+
25+
const triple4 = triple(s1, p2, o3)
26+
27+
it('when given no arguments returns all statements', () => {
28+
const kb = new IndexedFormula()
29+
const triples = [ triple1, triple2, triple3 ]
30+
kb.addAll(triples)
31+
expect(kb.length).to.equal(3)
32+
expect(kb.match()).to.eql(triples)
33+
})
34+
35+
it('matches on subject', () => {
36+
let kb = new IndexedFormula()
37+
kb.addAll([ triple1, triple2, triple3, triple4 ])
38+
let s = NamedNode.fromValue('https://example.com/subject1')
39+
let matches = kb.match(s)
40+
expect(matches.length).to.equal(2)
41+
matches.sort()
42+
expect(matches[0].subject).to.eql(s1)
43+
expect(matches[1].subject).to.eql(s1)
44+
})
45+
46+
it('matches on predicate', () => {
47+
let kb = new IndexedFormula()
48+
kb.addAll([ triple1, triple2, triple3, triple4 ])
49+
let p = NamedNode.fromValue('https://example.com/predicate2')
50+
let matches = kb.match(null, p)
51+
expect(matches.length).to.equal(2)
52+
matches.sort()
53+
expect(matches[0].predicate).to.eql(p2)
54+
expect(matches[1].predicate).to.eql(p2)
55+
})
56+
57+
it('matches on subject and object', () => {
58+
let kb = new IndexedFormula()
59+
kb.addAll([ triple1, triple2, triple3, triple4 ])
60+
let matches = kb.match(
61+
NamedNode.fromValue('https://example.com/subject1'),
62+
null,
63+
NamedNode.fromValue('https://example.com/object1')
64+
)
65+
expect(matches.length).to.equal(1)
66+
expect(matches[0].subject).to.eql(s1)
67+
expect(matches[0].object).to.eql(o1)
68+
})
69+
})
70+
})

tests/unit/literal-test.js

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
/* eslint-env mocha */
2+
import { expect } from 'chai'
3+
4+
import Literal from '../../src/literal'
5+
import XSD from '../../src/xsd'
6+
7+
describe('Literal', () => {
8+
describe('fromValue', () => {
9+
describe('for numbers', () => {
10+
it('detects integers', () => {
11+
expect(Literal.fromValue(0)).to.eql(new Literal('0', null, XSD.integer))
12+
expect(Literal.fromValue(1)).to.eql(new Literal('1', null, XSD.integer))
13+
expect(Literal.fromValue(Number.MAX_SAFE_INTEGER))
14+
.to.eql(new Literal(Number.MAX_SAFE_INTEGER.toString(), null, XSD.integer))
15+
expect(Literal.fromValue(Number.MIN_SAFE_INTEGER))
16+
.to.eql(new Literal(Number.MIN_SAFE_INTEGER.toString(), null, XSD.integer))
17+
})
18+
19+
it('detects decimals', () => {
20+
expect(Literal.fromValue(1.1)).to.eql(new Literal('1.1', null, XSD.decimal))
21+
})
22+
23+
it('detects doubles', () => {
24+
expect(Literal.fromValue(Number.MAX_SAFE_INTEGER + 1))
25+
.to.eql(new Literal((Number.MAX_SAFE_INTEGER + 1).toString(), null, XSD.double))
26+
expect(Literal.fromValue(Number.MIN_SAFE_INTEGER - 1))
27+
.to.eql(new Literal((Number.MIN_SAFE_INTEGER - 1).toString(), null, XSD.double))
28+
expect(Literal.fromValue(Number.MAX_VALUE))
29+
.to.eql(new Literal(Number.MAX_VALUE.toString(), null, XSD.double))
30+
expect(Literal.fromValue(-Number.MAX_VALUE))
31+
.to.eql(new Literal((-Number.MAX_VALUE).toString(), null, XSD.double))
32+
expect(Literal.fromValue(Number.MIN_VALUE))
33+
.to.eql(new Literal(Number.MIN_VALUE.toString(), null, XSD.double))
34+
})
35+
})
36+
37+
it('detects string values', () => {
38+
expect(Literal.fromValue('foo')).to.eql(new Literal('foo', null, null))
39+
})
40+
41+
it('detects boolean values', () => {
42+
expect(Literal.fromValue(true)).to.eql(new Literal('1', null, XSD.boolean))
43+
expect(Literal.fromValue(false)).to.eql(new Literal('0', null, XSD.boolean))
44+
})
45+
46+
it('constructs a literal representing a date value', () => {
47+
const date = new Date(Date.UTC(2010, 5, 10, 1, 2, 3))
48+
expect(Literal.fromValue(date))
49+
.to.eql(new Literal('2010-06-10T01:02:03Z', null, XSD.dateTime))
50+
})
51+
})
52+
53+
describe('toNT', () => {
54+
describe('for strings', () => {
55+
it('serializes strings with no language', () => {
56+
const node = Literal.fromValue('foo')
57+
expect(node.toNT()).to.equal('"foo"')
58+
})
59+
60+
it('serializes strings with a language', () => {
61+
const node = new Literal('foo', 'en')
62+
expect(node.toNT()).to.equal('"foo"@en')
63+
})
64+
})
65+
66+
describe('for numbers', () => {
67+
it('serializes integers', () => {
68+
const node = Literal.fromValue(1)
69+
expect(node.toNT()).to.equal('"1"^^<http://www.w3.org/2001/XMLSchema#integer>')
70+
})
71+
72+
it('serializes decimals', () => {
73+
const node = Literal.fromValue(1.5)
74+
expect(node.toNT()).to.equal('"1.5"^^<http://www.w3.org/2001/XMLSchema#decimal>')
75+
})
76+
77+
it('serializes doubles', () => {
78+
const largeDouble = Number.MAX_VALUE
79+
const node = Literal.fromValue(largeDouble)
80+
expect(node.toNT()).to.equal(`"${largeDouble.toString()}"^^<http://www.w3.org/2001/XMLSchema#double>`)
81+
})
82+
})
83+
84+
it('serializes boolean values', () => {
85+
expect(Literal.fromValue(true).toNT()).to.equal('"1"^^<http://www.w3.org/2001/XMLSchema#boolean>')
86+
expect(Literal.fromValue(false).toNT()).to.equal('"0"^^<http://www.w3.org/2001/XMLSchema#boolean>')
87+
})
88+
89+
it('serializes date values', () => {
90+
const date = new Date(Date.UTC(2010, 5, 10, 1, 2, 3))
91+
expect(Literal.fromValue(date).toNT())
92+
.to.equal('"2010-06-10T01:02:03Z"^^<http://www.w3.org/2001/XMLSchema#dateTime>')
93+
})
94+
})
95+
96+
describe('copy', () => {
97+
it('creates an identical copy of a node', () => {
98+
const node = Literal.fromValue('foo')
99+
expect(node).to.eql(node.copy())
100+
})
101+
})
102+
103+
describe('equals', () => {
104+
it('compares termType, value, language, and datatype', () => {
105+
const a = new Literal('hello world', 'en', XSD.langString)
106+
const b = new Literal('', '', null)
107+
expect(a.equals(b)).to.be.false
108+
expect(b.equals(a)).to.be.false
109+
b.value = 'hello world'
110+
expect(a.equals(b)).to.be.false
111+
expect(b.equals(a)).to.be.false
112+
b.language = 'en'
113+
expect(a.equals(b)).to.be.false
114+
expect(b.equals(a)).to.be.false
115+
b.datatype = XSD.langString
116+
expect(a.equals(b)).to.be.true
117+
expect(b.equals(a)).to.be.true
118+
})
119+
})
120+
})

tests/unit/match-test.js

Lines changed: 0 additions & 67 deletions
This file was deleted.

tests/unit/nodeunit/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Nodeunit tests are deprecated. Add new unit tests as mocha tests in the
2+
`tests/unit/` directory.

0 commit comments

Comments
 (0)