Skip to content

Commit

Permalink
fix: safer working with undefined context
Browse files Browse the repository at this point in the history
  • Loading branch information
tpluscode committed Jul 9, 2020
1 parent 9d6d07b commit 022b140
Show file tree
Hide file tree
Showing 8 changed files with 99 additions and 23 deletions.
2 changes: 1 addition & 1 deletion docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ Creates an iterator which iterates and rdf:List of the current term
<a name="Clownface+toArray"></a>

### clownface.toArray() ⇒ [<code>Array.&lt;Clownface&gt;</code>](#Clownface)
Returns an array of graph pointers where each on has a single _context
Returns an array of graph pointers where each one has a single _context

**Kind**: instance method of [<code>Clownface</code>](#Clownface)
<a name="Clownface+filter"></a>
Expand Down
6 changes: 4 additions & 2 deletions lib/Clownface.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,12 +149,14 @@ class Clownface {
}

/**
* Returns an array of graph pointers where each on has a single _context
* Returns an array of graph pointers where each one has a single _context
*
* @returns {Clownface[]}
*/
toArray () {
return this._context.map(context => Clownface.fromContext(context))
return this._context
.map(context => Clownface.fromContext(context))
.filter(context => context.terms.some(Boolean))
}

/**
Expand Down
32 changes: 20 additions & 12 deletions lib/Context.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,32 +46,40 @@ class Context {
addIn (predicates, subjects) {
const context = []

subjects.forEach(subject => {
predicates.forEach(predicate => {
this.dataset.add(this.factory.quad(subject, predicate, this.term, this.graph))
})
if (this.term) {
subjects.forEach(subject => {
predicates.forEach(predicate => {
this.dataset.add(this.factory.quad(subject, predicate, this.term, this.graph))
})

context.push(this.clone({ value: subject }))
})
context.push(this.clone({ value: subject }))
})
}

return context
}

addOut (predicates, objects) {
const context = []

objects.forEach(object => {
predicates.forEach(predicate => {
this.dataset.add(this.factory.quad(this.term, predicate, object, this.graph))
})
if (this.term) {
objects.forEach(object => {
predicates.forEach(predicate => {
this.dataset.add(this.factory.quad(this.term, predicate, object, this.graph))
})

context.push(this.clone({ value: object }))
})
context.push(this.clone({ value: object }))
})
}

return context
}

addList (predicates, items) {
if (!this.term) {
return
}

predicates.forEach(predicate => {
const nodes = items.map(() => this.factory.blankNode())

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"rdf-dataset-ext": "^1.0.0",
"rdf-ext": "^1.3.0",
"rimraf": "^3.0.2",
"sinon": "^9.0.2",
"standard": "^12.0.1",
"string-to-stream": "^3.0.1",
"tbbt-ld": "^1.1.0"
Expand Down
30 changes: 27 additions & 3 deletions test/Clownface/addIn.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* global describe, it */

const { describe, it } = require('mocha')
const assert = require('assert')
const sinon = require('sinon')
const clownface = require('../..')
const rdf = require('../support/factory')
const { addAll } = require('rdf-dataset-ext')
Expand Down Expand Up @@ -151,6 +151,7 @@ describe('.addIn', () => {
it('should use the provided factory', () => {
const dataset = rdf.dataset()
const predicate = rdf.namedNode('http://schema.org/knows')
const term = rdf.namedNode('http://localhost:8080/data/person/bernadette-rostenkowski')
const factory = {
quad: (s, p, o, g) => {
const quad = rdf.quad(s, p, o, g)
Expand All @@ -169,11 +170,34 @@ describe('.addIn', () => {
}
}

const cf = clownface({ dataset, factory }).addIn(predicate, 'test')
const cf = clownface({ dataset, factory, term }).addIn(predicate, 'test')

assert.strictEqual(cf.in(predicate).term.testProperty, 'test')
cf.dataset.match(null, predicate, null).forEach((quad) => {
assert.strictEqual(quad.testProperty, 'test')
})
})

it('should not add quads if context is undefined', () => {
const dataset = rdf.dataset()
const cf = clownface({ dataset })
const subject = rdf.namedNode('http://localhost:8080/data/person/bernadette-rostenkowski')
const predicate = rdf.namedNode('http://schema.org/knows')

cf.addIn(predicate, subject)

assert.strictEqual(dataset.size, 0)
})

it('should not call callback function if context is undefined', () => {
const dataset = rdf.dataset()
const cf = clownface({ dataset })
const subject = rdf.namedNode('http://localhost:8080/data/person/bernadette-rostenkowski')
const predicate = rdf.namedNode('http://schema.org/knows')
const callback = sinon.spy()

cf.addIn(predicate, subject, callback)

assert.strictEqual(callback.called, false)
})
})
13 changes: 11 additions & 2 deletions test/Clownface/addList.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/* global describe, it */

const { describe, it } = require('mocha')
const assert = require('assert')
const clownface = require('../..')
const rdf = require('../support/factory')
Expand Down Expand Up @@ -107,4 +106,14 @@ describe('.addList', () => {
assert.strictEqual(rest0.testProperty, 'test')
assert.strictEqual(rest0.predicate.testProperty, 'test')
})

it('should not add quads if context is undefined', () => {
const dataset = rdf.dataset()
const graph = clownface({ dataset })
const predicate = rdf.namedNode('http://example.org/foo')

graph.addList(predicate, ['bar', 'baz'])

assert.strictEqual(dataset.size, 0)
})
})
30 changes: 27 additions & 3 deletions test/Clownface/addOut.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* global describe, it */

const { describe, it } = require('mocha')
const assert = require('assert')
const sinon = require('sinon')
const clownface = require('../..')
const loadExample = require('../support/example')
const rdf = require('../support/factory')
Expand Down Expand Up @@ -168,6 +168,7 @@ describe('.addOut', () => {
it('should use the provided factory', () => {
const dataset = rdf.dataset()
const predicate = rdf.namedNode('http://schema.org/knows')
const term = rdf.namedNode('http://localhost:8080/data/person/mary-cooper')
const factory = {
quad: (s, p, o, g) => {
const quad = rdf.quad(s, p, o, g)
Expand All @@ -186,11 +187,34 @@ describe('.addOut', () => {
}
}

const cf = clownface({ dataset, factory }).addOut(predicate, 'test')
const cf = clownface({ dataset, factory, term }).addOut(predicate, 'test')

assert.strictEqual(cf.out(predicate).term.testProperty, 'test')
cf.dataset.match(null, predicate, null).forEach((quad) => {
assert.strictEqual(quad.testProperty, 'test')
})
})

it('should not add quads if context is undefined', () => {
const dataset = rdf.dataset()
const cf = clownface({ dataset })
const object = rdf.namedNode('http://localhost:8080/data/person/bernadette-rostenkowski')
const predicate = rdf.namedNode('http://schema.org/knows')

cf.addOut(predicate, object)

assert.strictEqual(dataset.size, 0)
})

it('should not call callback function if context is undefined', () => {
const dataset = rdf.dataset()
const cf = clownface({ dataset })
const object = rdf.namedNode('http://localhost:8080/data/person/bernadette-rostenkowski')
const predicate = rdf.namedNode('http://schema.org/knows')
const callback = sinon.spy()

cf.addOut(predicate, object, callback)

assert.strictEqual(callback.called, false)
})
})
8 changes: 8 additions & 0 deletions test/Clownface/toArray.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,12 @@ describe('.toArray', () => {
assert.strictEqual(result.length, 7)
assert(result[0] instanceof Clownface)
})

it('should not return an instance for undefined context', () => {
const cf = clownface({ dataset: rdf.dataset() })

const array = cf.toArray()

assert.strictEqual(array.length, 0)
})
})

0 comments on commit 022b140

Please sign in to comment.