From 79e9a19698bd454b5bcfd259cccf78ddc0d53a55 Mon Sep 17 00:00:00 2001 From: Cristian Date: Thu, 6 Jan 2022 17:23:24 +0100 Subject: [PATCH 1/6] feat! added inE and outE functions --- lib/Clownface.js | 28 +++++++++++++++ lib/Context.js | 14 ++++++++ test/Clownface/inE.js | 80 ++++++++++++++++++++++++++++++++++++++++++ test/Clownface/outE.js | 80 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 202 insertions(+) create mode 100644 test/Clownface/inE.js create mode 100644 test/Clownface/outE.js diff --git a/lib/Clownface.js b/lib/Clownface.js index eb88dcc..ca94866 100644 --- a/lib/Clownface.js +++ b/lib/Clownface.js @@ -295,6 +295,19 @@ class Clownface { return Clownface.fromContext(context) } + /** + * A similar operation to in, but instead of returning the objects, it returns pointers to the matching predicates + * @param {Term|Term[]|Clownface|Clownface[]} [predicates] one or more RDF/JS term identifying a property + * @returns {Clownface} + */ + inE (predicates) { + predicates = this._toTermArray(predicates) + + const context = this._context.reduce((all, current) => all.concat(current.inE(predicates)), []) + + return Clownface.fromContext(context) + } + /** * Creates a graph pointer to the result nodes after following a predicate, or after * following any predicates in an array, starting from the subject(s) (current graph pointer) to the objects. @@ -311,6 +324,21 @@ class Clownface { return Clownface.fromContext(context) } + /** + * A similar operation to out, but instead of returning the objects, it returns pointers to the matching predicates + * @param {Term|Term[]|Clownface|Clownface[]} [predicates] any predicates to follow + * @param {object} [options] + * @param {string | string[] | undefined} [options.language] + * @returns {Clownface} + */ + outE (predicates, options = {}) { + predicates = this._toTermArray(predicates) + + const context = this._context.reduce((all, current) => all.concat(current.outE(predicates, options)), []) + + return Clownface.fromContext(context) + } + /** * Creates a graph pointer to nodes which are subjects of predicates, optionally also with specific objects * diff --git a/lib/Context.js b/lib/Context.js index fdfb2e7..cca3250 100644 --- a/lib/Context.js +++ b/lib/Context.js @@ -27,6 +27,12 @@ class Context { }) } + inE (predicate) { + return this.matchProperty(null, predicate, toArray(this.term), toArray(this.graph), 'predicate').map(subject => { + return this.clone({ value: subject }) + }) + } + out (predicate, { language } = {}) { let objects = this.matchProperty(toArray(this.term), predicate, null, toArray(this.graph), 'object') @@ -42,6 +48,14 @@ class Context { }) } + outE (predicate) { + let predicates = this.matchProperty(toArray(this.term), predicate, null, toArray(this.graph), 'predicate') + + return predicates.map(predicate => { + return this.clone({ value: predicate }) + }) + } + addIn (predicates, subjects) { const context = [] diff --git a/test/Clownface/inE.js b/test/Clownface/inE.js new file mode 100644 index 0000000..e1fbf48 --- /dev/null +++ b/test/Clownface/inE.js @@ -0,0 +1,80 @@ +/* global describe, it */ + +const assert = require('assert') +const clownface = require('../..') +const loadExample = require('../support/example') +const rdf = require('../support/factory') +const ns = require('../support/namespace') +const Clownface = require('../../lib/Clownface') + +describe('.inE', () => { + it('should be a function', () => { + const cf = clownface({ dataset: rdf.dataset() }) + + assert.strictEqual(typeof cf.inE, 'function') + }) + + it('should return a new Clownface instance', async () => { + const cf = clownface({ + dataset: await loadExample(), + value: '2311 North Los Robles Avenue, Aparment 4A' + }) + + const result = cf.inE(rdf.namedNode('http://schema.org/streetAddress')) + + assert(result instanceof Clownface) + assert.notStrictEqual(result, cf) + }) + + it('should search object -> subject without predicate', async () => { + const cf = clownface({ + dataset: await loadExample(), + term: ns.tbbtp('bernadette-rostenkowski') + }) + + const result = cf.inE() + + assert.strictEqual(result._context.length, 8) + }) + + it('should search object -> subject with predicate', async () => { + const cf = clownface({ + dataset: await loadExample(), + value: '2311 North Los Robles Avenue, Aparment 4A' + }) + + const result = cf.inE(rdf.namedNode('http://schema.org/streetAddress')) + + assert.strictEqual(result._context.length, 2) + assert.strictEqual(result._context[0].term.termType, 'NamedNode') + assert.strictEqual(result._context[0].term.value, 'http://schema.org/streetAddress') + }) + + it('should support multiple predicate values in an array', async () => { + const cf = clownface({ + dataset: await loadExample(), + term: rdf.namedNode('http://localhost:8080/data/person/bernadette-rostenkowski') + }) + + const result = cf.inE([ + rdf.namedNode('http://schema.org/spouse'), + rdf.namedNode('http://schema.org/knows') + ]) + + assert.strictEqual(result._context.length, 8) + }) + + it('should support clownface objects as predicates', async () => { + const cf = clownface({ + dataset: await loadExample(), + term: rdf.namedNode('http://localhost:8080/data/person/bernadette-rostenkowski') + }) + + const result = cf.inE(cf.node([ + rdf.namedNode('http://schema.org/spouse'), + rdf.namedNode('http://schema.org/knows') + ])) + + assert.strictEqual(result._context.length, 8) + }) +}) diff --git a/test/Clownface/outE.js b/test/Clownface/outE.js new file mode 100644 index 0000000..57f255b --- /dev/null +++ b/test/Clownface/outE.js @@ -0,0 +1,80 @@ +const { describe, it } = require('mocha') +const assert = require('assert') +const clownface = require('../..') +const loadExample = require('../support/example') +const rdf = require('../support/factory') +const Clownface = require('../../lib/Clownface') +const ns = require('../support/namespace') + +describe('.outE', () => { + it('should be a function', () => { + const cf = clownface({ dataset: rdf.dataset() }) + + assert.strictEqual(typeof cf.outE, 'function') + }) + + it('should return a new Clownface instance', async () => { + const cf = clownface({ + dataset: await loadExample(), + term: rdf.namedNode('http://localhost:8080/data/person/amy-farrah-fowler') + }) + + const result = cf.outE(rdf.namedNode('http://schema.org/jobTitle')) + + assert(result instanceof Clownface) + assert.notStrictEqual(result, cf) + }) + + it('should search subject -> object without predicate', async () => { + const cf = clownface({ + dataset: await loadExample(), + term: ns.tbbtp('amy-farrah-fowler') + }) + + const result = cf.outE() + + assert.strictEqual(result._context.length, 12) + }) + + it('should search subject -> predicate with predicate', async () => { + const cf = clownface({ + dataset: await loadExample(), + term: rdf.namedNode('http://localhost:8080/data/person/amy-farrah-fowler') + }) + + const result = cf.outE(rdf.namedNode('http://schema.org/jobTitle')) + + assert.strictEqual(result._context.length, 1) + assert.strictEqual(result._context[0].term.termType, 'NamedNode') + assert.strictEqual(result._context[0].term.value, 'http://schema.org/jobTitle') + }) + + it('should support multiple predicate values in an array', async () => { + const cf = clownface({ + dataset: await loadExample(), + term: rdf.namedNode('http://localhost:8080/data/person/bernadette-rostenkowski') + }) + + const result = cf.outE([ + rdf.namedNode('http://schema.org/familyName'), + rdf.namedNode('http://schema.org/givenName') + ]) + + assert.strictEqual(result._context.length, 2) + }) + + it('should support clownface objects as predicates', async () => { + const cf = clownface({ + dataset: await loadExample(), + term: rdf.namedNode('http://localhost:8080/data/person/bernadette-rostenkowski') + }) + + const result = cf.outE(cf.node([ + rdf.namedNode('http://schema.org/familyName'), + rdf.namedNode('http://schema.org/givenName') + ])) + + assert.strictEqual(result._context.length, 2) + }) + +}) From e287835ae4b04774835f291961c59ca6c5614375 Mon Sep 17 00:00:00 2001 From: Cristian Date: Thu, 6 Jan 2022 17:24:39 +0100 Subject: [PATCH 2/6] feat! added inE and outE functions --- test/Clownface/outE.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/Clownface/outE.js b/test/Clownface/outE.js index 57f255b..69360bb 100644 --- a/test/Clownface/outE.js +++ b/test/Clownface/outE.js @@ -76,5 +76,4 @@ describe('.outE', () => { assert.strictEqual(result._context.length, 2) }) - }) From 403d63e2acf809356c9537e01d1ff7eff667fddf Mon Sep 17 00:00:00 2001 From: Cristian Date: Thu, 6 Jan 2022 17:24:39 +0100 Subject: [PATCH 3/6] feat added outE and inE functions --- docs/api.md | 44 ++++++++++++++++++++++++++++++++++++++++++ test/Clownface/outE.js | 1 - 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/docs/api.md b/docs/api.md index 152ac5e..5a00329 100644 --- a/docs/api.md +++ b/docs/api.md @@ -53,7 +53,9 @@ A graph pointer object, which points at 0..N nodes within a dataset * [.literal(values, [languageOrDatatype])](#Clownface+literal) ⇒ [Clownface](#Clownface) * [.namedNode(values)](#Clownface+namedNode) ⇒ [Clownface](#Clownface) * [.in([predicates])](#Clownface+in) ⇒ [Clownface](#Clownface) + * [.inE([predicates])](#Clownface+inE) ⇒ [Clownface](#Clownface) * [.out([predicates], [options])](#Clownface+out) ⇒ [Clownface](#Clownface) + * [.outE([predicates], [options])](#Clownface+outE) ⇒ [Clownface](#Clownface) * [.has(predicates, [objects])](#Clownface+has) ⇒ [Clownface](#Clownface) * [.addIn(predicates, subjects, [callback])](#Clownface+addIn) ⇒ [Clownface](#Clownface) * [.addOut(predicates, objects, [callback])](#Clownface+addOut) ⇒ [Clownface](#Clownface) @@ -292,6 +294,25 @@ Creates a graph pointer to nodes which are linked to the current pointer by `pre + + +### clownface.inE([predicates]) ⇒ [Clownface](#Clownface) +A similar operation to in, but instead of returning the objects, it returns pointers to the matching predicates + +**Kind**: instance method of [Clownface](#Clownface) + + + + + + + + + + +
ParamTypeDescription
[predicates]Term | Array.<Term> | Clownface | Array.<Clownface>

one or more RDF/JS term identifying a property

+
+ ### clownface.out([predicates], [options]) ⇒ [Clownface](#Clownface) @@ -316,6 +337,29 @@ following any predicates in an array, starting from the subject(s) (current grap + + +### clownface.outE([predicates], [options]) ⇒ [Clownface](#Clownface) +A similar operation to out, but instead of returning the objects, it returns pointers to the matching predicates + +**Kind**: instance method of [Clownface](#Clownface) + + + + + + + + + + + + + + +
ParamTypeDescription
[predicates]Term | Array.<Term> | Clownface | Array.<Clownface>

any predicates to follow

+
[options]object
[options.language]string | Array.<string> | undefined
+ ### clownface.has(predicates, [objects]) ⇒ [Clownface](#Clownface) diff --git a/test/Clownface/outE.js b/test/Clownface/outE.js index 57f255b..69360bb 100644 --- a/test/Clownface/outE.js +++ b/test/Clownface/outE.js @@ -76,5 +76,4 @@ describe('.outE', () => { assert.strictEqual(result._context.length, 2) }) - }) From 861de5cd0c204f45920a482a855df07d5706ad94 Mon Sep 17 00:00:00 2001 From: Cristian Date: Thu, 6 Jan 2022 17:26:45 +0100 Subject: [PATCH 4/6] feat: added inE and outE functions --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 57c0163..c176b49 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "clownface", - "version": "1.4.0", + "version": "1.4.1", "description": "Simple but powerful graph traversing library", "main": "index.js", "scripts": { From 115af9b2046d18619ddedd80cc3d79c52b97362a Mon Sep 17 00:00:00 2001 From: Cristian Date: Tue, 18 Jan 2022 11:16:47 +0100 Subject: [PATCH 5/6] updated version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c176b49..57c0163 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "clownface", - "version": "1.4.1", + "version": "1.4.0", "description": "Simple but powerful graph traversing library", "main": "index.js", "scripts": { From 9a952ab41520cefb85021f9f73cb39a4e2cdb7bc Mon Sep 17 00:00:00 2001 From: Cristian Date: Wed, 19 Jan 2022 15:52:48 +0100 Subject: [PATCH 6/6] refactor: outE -> outProp, inE -> inProp --- lib/Clownface.js | 12 ++++++------ lib/Context.js | 4 ++-- package.json | 2 +- test/Clownface/{inE.js => inProp.js} | 14 +++++++------- test/Clownface/{outE.js => outProp.js} | 14 +++++++------- 5 files changed, 23 insertions(+), 23 deletions(-) rename test/Clownface/{inE.js => inProp.js} (86%) rename test/Clownface/{outE.js => outProp.js} (86%) diff --git a/lib/Clownface.js b/lib/Clownface.js index ca94866..87b4757 100644 --- a/lib/Clownface.js +++ b/lib/Clownface.js @@ -296,14 +296,14 @@ class Clownface { } /** - * A similar operation to in, but instead of returning the objects, it returns pointers to the matching predicates + * A similar operation to {@link in}, but instead of returning the objects, it returns pointers to the matching predicates * @param {Term|Term[]|Clownface|Clownface[]} [predicates] one or more RDF/JS term identifying a property * @returns {Clownface} */ - inE (predicates) { + inProp (predicates) { predicates = this._toTermArray(predicates) - const context = this._context.reduce((all, current) => all.concat(current.inE(predicates)), []) + const context = this._context.reduce((all, current) => all.concat(current.inProp(predicates)), []) return Clownface.fromContext(context) } @@ -325,16 +325,16 @@ class Clownface { } /** - * A similar operation to out, but instead of returning the objects, it returns pointers to the matching predicates + * A similar operation to {@link out}, but instead of returning the objects, it returns pointers to the matching predicates * @param {Term|Term[]|Clownface|Clownface[]} [predicates] any predicates to follow * @param {object} [options] * @param {string | string[] | undefined} [options.language] * @returns {Clownface} */ - outE (predicates, options = {}) { + outProp (predicates, options = {}) { predicates = this._toTermArray(predicates) - const context = this._context.reduce((all, current) => all.concat(current.outE(predicates, options)), []) + const context = this._context.reduce((all, current) => all.concat(current.outProp(predicates, options)), []) return Clownface.fromContext(context) } diff --git a/lib/Context.js b/lib/Context.js index cca3250..bf17a8d 100644 --- a/lib/Context.js +++ b/lib/Context.js @@ -27,7 +27,7 @@ class Context { }) } - inE (predicate) { + inProp (predicate) { return this.matchProperty(null, predicate, toArray(this.term), toArray(this.graph), 'predicate').map(subject => { return this.clone({ value: subject }) }) @@ -48,7 +48,7 @@ class Context { }) } - outE (predicate) { + outProp (predicate) { let predicates = this.matchProperty(toArray(this.term), predicate, null, toArray(this.graph), 'predicate') return predicates.map(predicate => { diff --git a/package.json b/package.json index 57c0163..c176b49 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "clownface", - "version": "1.4.0", + "version": "1.4.1", "description": "Simple but powerful graph traversing library", "main": "index.js", "scripts": { diff --git a/test/Clownface/inE.js b/test/Clownface/inProp.js similarity index 86% rename from test/Clownface/inE.js rename to test/Clownface/inProp.js index e1fbf48..1ee2497 100644 --- a/test/Clownface/inE.js +++ b/test/Clownface/inProp.js @@ -7,11 +7,11 @@ const rdf = require('../support/factory') const ns = require('../support/namespace') const Clownface = require('../../lib/Clownface') -describe('.inE', () => { +describe('.inProp', () => { it('should be a function', () => { const cf = clownface({ dataset: rdf.dataset() }) - assert.strictEqual(typeof cf.inE, 'function') + assert.strictEqual(typeof cf.inProp, 'function') }) it('should return a new Clownface instance', async () => { @@ -20,7 +20,7 @@ describe('.inE', () => { value: '2311 North Los Robles Avenue, Aparment 4A' }) - const result = cf.inE(rdf.namedNode('http://schema.org/streetAddress')) + const result = cf.inProp(rdf.namedNode('http://schema.org/streetAddress')) assert(result instanceof Clownface) assert.notStrictEqual(result, cf) @@ -32,7 +32,7 @@ describe('.inE', () => { term: ns.tbbtp('bernadette-rostenkowski') }) - const result = cf.inE() + const result = cf.inProp() assert.strictEqual(result._context.length, 8) }) @@ -43,7 +43,7 @@ describe('.inE', () => { value: '2311 North Los Robles Avenue, Aparment 4A' }) - const result = cf.inE(rdf.namedNode('http://schema.org/streetAddress')) + const result = cf.inProp(rdf.namedNode('http://schema.org/streetAddress')) assert.strictEqual(result._context.length, 2) assert.strictEqual(result._context[0].term.termType, 'NamedNode') @@ -56,7 +56,7 @@ describe('.inE', () => { term: rdf.namedNode('http://localhost:8080/data/person/bernadette-rostenkowski') }) - const result = cf.inE([ + const result = cf.inProp([ rdf.namedNode('http://schema.org/spouse'), rdf.namedNode('http://schema.org/knows') ]) @@ -70,7 +70,7 @@ describe('.inE', () => { term: rdf.namedNode('http://localhost:8080/data/person/bernadette-rostenkowski') }) - const result = cf.inE(cf.node([ + const result = cf.inProp(cf.node([ rdf.namedNode('http://schema.org/spouse'), rdf.namedNode('http://schema.org/knows') ])) diff --git a/test/Clownface/outE.js b/test/Clownface/outProp.js similarity index 86% rename from test/Clownface/outE.js rename to test/Clownface/outProp.js index 69360bb..6968cd9 100644 --- a/test/Clownface/outE.js +++ b/test/Clownface/outProp.js @@ -6,11 +6,11 @@ const rdf = require('../support/factory') const Clownface = require('../../lib/Clownface') const ns = require('../support/namespace') -describe('.outE', () => { +describe('.outProp', () => { it('should be a function', () => { const cf = clownface({ dataset: rdf.dataset() }) - assert.strictEqual(typeof cf.outE, 'function') + assert.strictEqual(typeof cf.outProp, 'function') }) it('should return a new Clownface instance', async () => { @@ -19,7 +19,7 @@ describe('.outE', () => { term: rdf.namedNode('http://localhost:8080/data/person/amy-farrah-fowler') }) - const result = cf.outE(rdf.namedNode('http://schema.org/jobTitle')) + const result = cf.outProp(rdf.namedNode('http://schema.org/jobTitle')) assert(result instanceof Clownface) assert.notStrictEqual(result, cf) @@ -31,7 +31,7 @@ describe('.outE', () => { term: ns.tbbtp('amy-farrah-fowler') }) - const result = cf.outE() + const result = cf.outProp() assert.strictEqual(result._context.length, 12) }) @@ -42,7 +42,7 @@ describe('.outE', () => { term: rdf.namedNode('http://localhost:8080/data/person/amy-farrah-fowler') }) - const result = cf.outE(rdf.namedNode('http://schema.org/jobTitle')) + const result = cf.outProp(rdf.namedNode('http://schema.org/jobTitle')) assert.strictEqual(result._context.length, 1) assert.strictEqual(result._context[0].term.termType, 'NamedNode') @@ -55,7 +55,7 @@ describe('.outE', () => { term: rdf.namedNode('http://localhost:8080/data/person/bernadette-rostenkowski') }) - const result = cf.outE([ + const result = cf.outProp([ rdf.namedNode('http://schema.org/familyName'), rdf.namedNode('http://schema.org/givenName') ]) @@ -69,7 +69,7 @@ describe('.outE', () => { term: rdf.namedNode('http://localhost:8080/data/person/bernadette-rostenkowski') }) - const result = cf.outE(cf.node([ + const result = cf.outProp(cf.node([ rdf.namedNode('http://schema.org/familyName'), rdf.namedNode('http://schema.org/givenName') ]))