diff --git a/js/build_package.js b/js/build_package.js index 5ae96cb4..e06f84dc 100644 --- a/js/build_package.js +++ b/js/build_package.js @@ -1,31 +1,29 @@ #! /usr/bin/env node -const fs = require('fs') +const fs = require("fs"); // We copy file to the new directory -fs.mkdirSync('pkg') -for (const file of fs.readdirSync('./pkg-web')) { - fs.copyFileSync('./pkg-web/' + file, './pkg/' + file) +fs.mkdirSync("pkg"); +for (const file of fs.readdirSync("./pkg-web")) { + fs.copyFileSync(`./pkg-web/${file}`, `./pkg/${file}`); } -for (const file of fs.readdirSync('./pkg-node')) { - fs.copyFileSync('./pkg-node/' + file, './pkg/' + file) +for (const file of fs.readdirSync("./pkg-node")) { + fs.copyFileSync(`./pkg-node/${file}`, `./pkg/${file}`); } -const pkg = JSON.parse(fs.readFileSync('./pkg/package.json')) -pkg.name = 'oxigraph' -pkg.main = 'node.js' -pkg.browser = 'web.js' -pkg.files = [ - '*.{js,wasm,d.ts}' -] -pkg.homepage = 'https://github.com/oxigraph/oxigraph/tree/main/js' +const pkg = JSON.parse(fs.readFileSync("./pkg/package.json")); +pkg.name = "oxigraph"; +pkg.main = "node.js"; +pkg.browser = "web.js"; +pkg.files = ["*.{js,wasm,d.ts}"]; +pkg.homepage = "https://github.com/oxigraph/oxigraph/tree/main/js"; pkg.bugs = { - url: 'https://github.com/oxigraph/oxigraph/issues' -} -pkg.collaborators = undefined + url: "https://github.com/oxigraph/oxigraph/issues", +}; +pkg.collaborators = undefined; pkg.repository = { - type: 'git', - url: 'https://github.com/oxigraph/oxigraph.git', - directory: 'js' -} -fs.writeFileSync('./pkg/package.json', JSON.stringify(pkg, null, 2)) + type: "git", + url: "https://github.com/oxigraph/oxigraph.git", + directory: "js", +}; +fs.writeFileSync("./pkg/package.json", JSON.stringify(pkg, null, 2)); diff --git a/js/package.json b/js/package.json index a3ec41c9..e549c162 100644 --- a/js/package.json +++ b/js/package.json @@ -3,12 +3,13 @@ "description": "Oxigraph JS build and tests", "private": true, "devDependencies": { - "mocha": "^10.0.0", "@rdfjs/data-model": "^2.0.1", - "standard": "^17.0.0" + "mocha": "^10.0.0", + "rome": "^11.0.0" }, "scripts": { - "test": "standard && wasm-pack build --debug --target nodejs && mocha", + "fmt": "rome format . --write && rome check . --apply-suggested", + "test": "rome ci . && wasm-pack build --debug --target nodejs && mocha", "build": "rm -rf pkg && wasm-pack build --release --target web --out-name web && mv pkg pkg-web && wasm-pack build --release --target nodejs --out-name node && mv pkg pkg-node && node build_package.js && rm -r pkg-web && rm -r pkg-node", "release": "npm run build && npm publish ./pkg", "pack": "npm run build && npm pack ./pkg" diff --git a/js/rome.json b/js/rome.json new file mode 100644 index 00000000..d92e4ab6 --- /dev/null +++ b/js/rome.json @@ -0,0 +1,10 @@ +{ + "formatter": { + "indentStyle": "space", + "indentSize": 4, + "lineWidth": 100 + }, + "linter": { + "ignore": ["pkg"] + } +} \ No newline at end of file diff --git a/js/test/model.mjs b/js/test/model.mjs index 1844b062..e001843b 100644 --- a/js/test/model.mjs +++ b/js/test/model.mjs @@ -1,38 +1,52 @@ /* global describe, it */ -import oxigraph from '../pkg/oxigraph.js' -import assert from 'assert' -import runTests from '../node_modules/@rdfjs/data-model/test/index.js' - -runTests({ factory: oxigraph }) - -describe('DataModel', function () { - describe('#toString()', function () { - it('namedNode().toString() should return SPARQL compatible syntax', function () { - assert.strictEqual('', oxigraph.namedNode('http://example.com').toString()) - }) - - it('blankNode().toString() should return SPARQL compatible syntax', function () { - assert.strictEqual('_:a', oxigraph.blankNode('a').toString()) - }) - - it('literal().toString() should return SPARQL compatible syntax', function () { - assert.strictEqual('"a\\"b"@en', oxigraph.literal('a"b', 'en').toString()) - }) - - it('defaultGraph().toString() should return SPARQL compatible syntax', function () { - assert.strictEqual('DEFAULT', oxigraph.defaultGraph().toString()) - }) - - it('variable().toString() should return SPARQL compatible syntax', function () { - assert.strictEqual('?a', oxigraph.variable('a').toString()) - }) - - it('quad().toString() should return SPARQL compatible syntax', function () { - assert.strictEqual( - ' << >> ', - oxigraph.quad(oxigraph.namedNode('http://example.com/s'), oxigraph.namedNode('http://example.com/p'), oxigraph.quad(oxigraph.namedNode('http://example.com/s1'), oxigraph.namedNode('http://example.com/p1'), oxigraph.namedNode('http://example.com/o1')), oxigraph.namedNode('http://example.com/g')).toString() - ) - }) - }) -}) +import oxigraph from "../pkg/oxigraph.js"; +import assert from "assert"; +import runTests from "../node_modules/@rdfjs/data-model/test/index.js"; + +runTests({ factory: oxigraph }); + +describe("DataModel", function () { + describe("#toString()", function () { + it("namedNode().toString() should return SPARQL compatible syntax", function () { + assert.strictEqual( + "", + oxigraph.namedNode("http://example.com").toString(), + ); + }); + + it("blankNode().toString() should return SPARQL compatible syntax", function () { + assert.strictEqual("_:a", oxigraph.blankNode("a").toString()); + }); + + it("literal().toString() should return SPARQL compatible syntax", function () { + assert.strictEqual('"a\\"b"@en', oxigraph.literal('a"b', "en").toString()); + }); + + it("defaultGraph().toString() should return SPARQL compatible syntax", function () { + assert.strictEqual("DEFAULT", oxigraph.defaultGraph().toString()); + }); + + it("variable().toString() should return SPARQL compatible syntax", function () { + assert.strictEqual("?a", oxigraph.variable("a").toString()); + }); + + it("quad().toString() should return SPARQL compatible syntax", function () { + assert.strictEqual( + " << >> ", + oxigraph + .quad( + oxigraph.namedNode("http://example.com/s"), + oxigraph.namedNode("http://example.com/p"), + oxigraph.quad( + oxigraph.namedNode("http://example.com/s1"), + oxigraph.namedNode("http://example.com/p1"), + oxigraph.namedNode("http://example.com/o1"), + ), + oxigraph.namedNode("http://example.com/g"), + ) + .toString(), + ); + }); + }); +}); diff --git a/js/test/store.mjs b/js/test/store.mjs index a6fa5627..55a53a66 100644 --- a/js/test/store.mjs +++ b/js/test/store.mjs @@ -1,161 +1,192 @@ /* global describe, it */ -import { Store } from '../pkg/oxigraph.js' -import assert from 'assert' -import dataModel from '@rdfjs/data-model' +import { Store } from "../pkg/oxigraph.js"; +import assert from "assert"; +import dataModel from "@rdfjs/data-model"; -const ex = dataModel.namedNode('http://example.com') +const ex = dataModel.namedNode("http://example.com"); const triple = dataModel.quad( - dataModel.blankNode('s'), - dataModel.namedNode('http://example.com/p'), - dataModel.literal('o') -) - -describe('Store', function () { - describe('#add()', function () { - it('an added quad should be in the store', function () { - const store = new Store() - store.add(dataModel.quad(ex, ex, triple)) - assert(store.has(dataModel.quad(ex, ex, triple))) - }) - }) - - describe('#delete()', function () { - it('an removed quad should not be in the store anymore', function () { - const store = new Store([dataModel.quad(triple, ex, ex)]) - assert(store.has(dataModel.quad(triple, ex, ex))) - store.delete(dataModel.quad(triple, ex, ex)) - assert(!store.has(dataModel.quad(triple, ex, ex))) - }) - }) - - describe('#has()', function () { - it('an added quad should be in the store', function () { - const store = new Store([dataModel.quad(ex, ex, ex)]) - assert(store.has(dataModel.quad(ex, ex, ex))) - }) - }) - - describe('#size()', function () { - it('A store with one quad should have 1 for size', function () { - const store = new Store([dataModel.quad(ex, ex, ex)]) - assert.strictEqual(1, store.size) - }) - }) - - describe('#match_quads()', function () { - it('blank pattern should return all quads', function () { - const store = new Store([dataModel.quad(ex, ex, ex)]) - const results = store.match() - assert.strictEqual(1, results.length) - assert(dataModel.quad(ex, ex, ex).equals(results[0])) - }) - }) - - describe('#query()', function () { - it('ASK true', function () { - const store = new Store([dataModel.quad(ex, ex, ex)]) - assert.strictEqual(true, store.query('ASK { ?s ?s ?s }')) - }) - - it('ASK false', function () { - const store = new Store() - assert.strictEqual(false, store.query('ASK { FILTER(false)}')) - }) - - it('CONSTRUCT', function () { - const store = new Store([dataModel.quad(ex, ex, ex)]) - const results = store.query('CONSTRUCT { ?s ?p ?o } WHERE { ?s ?p ?o }') - assert.strictEqual(1, results.length) - assert(dataModel.quad(ex, ex, ex).equals(results[0])) - }) - - it('SELECT', function () { - const store = new Store([dataModel.quad(ex, ex, ex)]) - const results = store.query('SELECT ?s WHERE { ?s ?p ?o }') - assert.strictEqual(1, results.length) - assert(ex.equals(results[0].get('s'))) - }) - - it('SELECT with NOW()', function () { - const store = new Store([dataModel.quad(ex, ex, ex)]) - const results = store.query('SELECT * WHERE { FILTER(2022 <= YEAR(NOW()) && YEAR(NOW()) <= 2100) }') - assert.strictEqual(1, results.length) - }) - - it('SELECT with RAND()', function () { - const store = new Store([dataModel.quad(ex, ex, ex)]) - const results = store.query('SELECT (RAND() AS ?y) WHERE {}') - assert.strictEqual(1, results.length) - }) - }) - - describe('#update()', function () { - it('INSERT DATA', function () { - const store = new Store() - store.update('INSERT DATA { }') - assert.strictEqual(1, store.size) - }) - - it('DELETE DATA', function () { - const store = new Store([dataModel.quad(ex, ex, ex)]) - store.update('DELETE DATA { }') - assert.strictEqual(0, store.size) - }) - - it('DELETE WHERE', function () { - const store = new Store([dataModel.quad(ex, ex, ex)]) - store.update('DELETE WHERE { ?v ?v ?v }') - assert.strictEqual(0, store.size) - }) - }) - - describe('#load()', function () { - it('load NTriples in the default graph', function () { - const store = new Store() - store.load(' .', 'application/n-triples') - assert(store.has(dataModel.quad(ex, ex, ex))) - }) - - it('load NTriples in an other graph', function () { - const store = new Store() - store.load(' .', 'application/n-triples', null, ex) - assert(store.has(dataModel.quad(ex, ex, ex, ex))) - }) - - it('load Turtle with a base IRI', function () { - const store = new Store() - store.load(' <> .', 'text/turtle', 'http://example.com') - assert(store.has(dataModel.quad(ex, ex, ex))) - }) - - it('load NQuads', function () { - const store = new Store() - store.load(' .', 'application/n-quads') - assert(store.has(dataModel.quad(ex, ex, ex, ex))) - }) - - it('load TriG with a base IRI', function () { - const store = new Store() - store.load('GRAPH <> { <> }', 'application/trig', 'http://example.com') - assert(store.has(dataModel.quad(ex, ex, ex, ex))) - }) - }) - - describe('#dump()', function () { - it('dump dataset content', function () { - const store = new Store([dataModel.quad(ex, ex, ex, ex)]) - assert.strictEqual(' .\n', store.dump('application/n-quads')) - }) - - it('dump named graph content', function () { - const store = new Store([dataModel.quad(ex, ex, ex, ex)]) - assert.strictEqual(' .\n', store.dump('application/n-triples', ex)) - }) - - it('dump default graph content', function () { - const store = new Store([dataModel.quad(ex, ex, ex, ex)]) - assert.strictEqual('', store.dump('application/n-triples')) - }) - }) -}) + dataModel.blankNode("s"), + dataModel.namedNode("http://example.com/p"), + dataModel.literal("o"), +); + +describe("Store", function () { + describe("#add()", function () { + it("an added quad should be in the store", function () { + const store = new Store(); + store.add(dataModel.quad(ex, ex, triple)); + assert(store.has(dataModel.quad(ex, ex, triple))); + }); + }); + + describe("#delete()", function () { + it("an removed quad should not be in the store anymore", function () { + const store = new Store([dataModel.quad(triple, ex, ex)]); + assert(store.has(dataModel.quad(triple, ex, ex))); + store.delete(dataModel.quad(triple, ex, ex)); + assert(!store.has(dataModel.quad(triple, ex, ex))); + }); + }); + + describe("#has()", function () { + it("an added quad should be in the store", function () { + const store = new Store([dataModel.quad(ex, ex, ex)]); + assert(store.has(dataModel.quad(ex, ex, ex))); + }); + }); + + describe("#size()", function () { + it("A store with one quad should have 1 for size", function () { + const store = new Store([dataModel.quad(ex, ex, ex)]); + assert.strictEqual(1, store.size); + }); + }); + + describe("#match_quads()", function () { + it("blank pattern should return all quads", function () { + const store = new Store([dataModel.quad(ex, ex, ex)]); + const results = store.match(); + assert.strictEqual(1, results.length); + assert(dataModel.quad(ex, ex, ex).equals(results[0])); + }); + }); + + describe("#query()", function () { + it("ASK true", function () { + const store = new Store([dataModel.quad(ex, ex, ex)]); + assert.strictEqual(true, store.query("ASK { ?s ?s ?s }")); + }); + + it("ASK false", function () { + const store = new Store(); + assert.strictEqual(false, store.query("ASK { FILTER(false)}")); + }); + + it("CONSTRUCT", function () { + const store = new Store([dataModel.quad(ex, ex, ex)]); + const results = store.query("CONSTRUCT { ?s ?p ?o } WHERE { ?s ?p ?o }"); + assert.strictEqual(1, results.length); + assert(dataModel.quad(ex, ex, ex).equals(results[0])); + }); + + it("SELECT", function () { + const store = new Store([dataModel.quad(ex, ex, ex)]); + const results = store.query("SELECT ?s WHERE { ?s ?p ?o }"); + assert.strictEqual(1, results.length); + assert(ex.equals(results[0].get("s"))); + }); + + it("SELECT with NOW()", function () { + const store = new Store([dataModel.quad(ex, ex, ex)]); + const results = store.query( + "SELECT * WHERE { FILTER(2022 <= YEAR(NOW()) && YEAR(NOW()) <= 2100) }", + ); + assert.strictEqual(1, results.length); + }); + + it("SELECT with RAND()", function () { + const store = new Store([dataModel.quad(ex, ex, ex)]); + const results = store.query("SELECT (RAND() AS ?y) WHERE {}"); + assert.strictEqual(1, results.length); + }); + }); + + describe("#update()", function () { + it("INSERT DATA", function () { + const store = new Store(); + store.update( + "INSERT DATA { }", + ); + assert.strictEqual(1, store.size); + }); + + it("DELETE DATA", function () { + const store = new Store([dataModel.quad(ex, ex, ex)]); + store.update( + "DELETE DATA { }", + ); + assert.strictEqual(0, store.size); + }); + + it("DELETE WHERE", function () { + const store = new Store([dataModel.quad(ex, ex, ex)]); + store.update("DELETE WHERE { ?v ?v ?v }"); + assert.strictEqual(0, store.size); + }); + }); + + describe("#load()", function () { + it("load NTriples in the default graph", function () { + const store = new Store(); + store.load( + " .", + "application/n-triples", + ); + assert(store.has(dataModel.quad(ex, ex, ex))); + }); + + it("load NTriples in an other graph", function () { + const store = new Store(); + store.load( + " .", + "application/n-triples", + null, + ex, + ); + assert(store.has(dataModel.quad(ex, ex, ex, ex))); + }); + + it("load Turtle with a base IRI", function () { + const store = new Store(); + store.load( + " <> .", + "text/turtle", + "http://example.com", + ); + assert(store.has(dataModel.quad(ex, ex, ex))); + }); + + it("load NQuads", function () { + const store = new Store(); + store.load( + " .", + "application/n-quads", + ); + assert(store.has(dataModel.quad(ex, ex, ex, ex))); + }); + + it("load TriG with a base IRI", function () { + const store = new Store(); + store.load( + "GRAPH <> { <> }", + "application/trig", + "http://example.com", + ); + assert(store.has(dataModel.quad(ex, ex, ex, ex))); + }); + }); + + describe("#dump()", function () { + it("dump dataset content", function () { + const store = new Store([dataModel.quad(ex, ex, ex, ex)]); + assert.strictEqual( + " .\n", + store.dump("application/n-quads"), + ); + }); + + it("dump named graph content", function () { + const store = new Store([dataModel.quad(ex, ex, ex, ex)]); + assert.strictEqual( + " .\n", + store.dump("application/n-triples", ex), + ); + }); + + it("dump default graph content", function () { + const store = new Store([dataModel.quad(ex, ex, ex, ex)]); + assert.strictEqual("", store.dump("application/n-triples")); + }); + }); +});