generated from jeswr/template-typescript
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
225 additions
and
59 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,5 +2,6 @@ node_modules | |
coverage | ||
dist | ||
bundle | ||
eye | ||
lib/eye.ts | ||
perf/output.txt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
/* eslint-disable */ | ||
// TODO: Remove the above before merging | ||
import fs from 'fs-extra'; | ||
import path from 'path'; | ||
import { Parser, Store, DataFactory as DF } from 'n3'; | ||
import { mapTerms } from 'rdf-terms'; | ||
import { execFileSync, exec, execSync } from 'child_process'; | ||
|
||
import { n3reasoner } from '../dist'; | ||
import 'jest-rdf'; | ||
import { Quad } from '@rdfjs/types'; | ||
|
||
const examplesPath = path.join(__dirname, '..', 'eye', 'reasoning'); | ||
const expectedStart = 'eye "$@"'; | ||
const cacheComponent = ' --wcache http://eyereasoner.github.io/eye/reasoning .. '; | ||
const longStart = expectedStart + cacheComponent; | ||
|
||
const ignoreFolders = [ | ||
// n3reasoner does not support extra images | ||
'dt', 'image', | ||
// n3reasoner does not support multiquery | ||
'mq', | ||
]; | ||
|
||
// These exceptions should eventually be removed | ||
const ignoreOutputs = [ | ||
// This complains because `$` is used as a term | ||
'bi/biA.n3', | ||
// This complains because of https://github.com/rdfjs/N3.js/issues/328 | ||
'crypto/crypto-proof.n3', | ||
// This just states `true .` but it's not a valid N3 file | ||
'entail/socrates-check.n3', | ||
// This complains because of https://github.com/rdfjs/N3.js/issues/328 | ||
'preduction/palindrome-proof.n3', | ||
// This complains because of https://github.com/rdfjs/N3.js/issues/328 | ||
'preduction/palindrome2-proof.n3', | ||
]; | ||
|
||
function readFile(subPath: string) { | ||
return fs.readFileSync(path.join(examplesPath, subPath)).toString(); | ||
} | ||
|
||
function dereference(subPath: string) { | ||
const parser = new Parser({ format: 'text/n3', baseIRI: `http://eyereasoner.github.io/eye/reasoning${subPath}` }); | ||
// @ts-expect-error | ||
parser._supportsRDFStar = true; | ||
return parser.parse(readFile(subPath)); | ||
} | ||
|
||
function loadFiles(files: string[]) { | ||
return [...new Store(files.map((file) => dereference(file)).flat())] | ||
// Workaround for https://github.com/rdfjs/N3.js/issues/332 | ||
.map((quad) => mapTerms(quad, (term) => (term.termType === 'BlankNode' ? DF.blankNode(term.value.replace(/^\./, '')) : term))); | ||
} | ||
|
||
const invMapping = { | ||
derivations: '--pass-only-new', | ||
deductive_closure: '--pass', | ||
deductive_closure_plus_rules: '--pass-all', | ||
grounded_deductive_closure_plus_rules: '--pass-all-ground', | ||
} as const; | ||
|
||
describe('Testing examples from eye repository', () => { | ||
const cases: [string, string[]][] = []; | ||
|
||
for (const folder of fs.readdirSync(examplesPath).filter(folder => fs.statSync(path.join(examplesPath, folder)).isDirectory())) { | ||
if (ignoreFolders.includes(folder)) | ||
continue; | ||
|
||
try { | ||
// FIXME: Don't have stderr show in the console | ||
const tests = execSync( | ||
fs.readFileSync(path.join(examplesPath, folder, 'test')).toString().replace(/eye /g, 'echo ') | ||
).toString().split('\n').slice(0, -1); | ||
|
||
// FIXME: Add a verification to make sure we are only skipping what we want | ||
if (tests.length > 0) { | ||
cases.push([folder, tests]) | ||
} | ||
} catch (e) { | ||
if (!(e as any).toString().includes('swipl')) { | ||
throw e; | ||
} | ||
// Don't error if the problem is just that the test is trying to test the swipl command | ||
} | ||
} | ||
|
||
describe.each(cases)('Testing examples for %s', (folder, args) => { | ||
it.each(args)('%s', async (args) => { | ||
let argsArray = args.split(/\ |\=/g) | ||
// Remove the --turtle flag because it's just a performance optimisation | ||
.filter((arg) => !['--turtle'].includes(arg)) | ||
// | ||
.map(arg => arg.replace('http://eyereasoner.github.io/eye/reasoning/', '')); | ||
|
||
|
||
if (argsArray[argsArray.length - 2] !== '--output') { | ||
throw new Error(`Expected --output to be the last argument on [${args}]`); | ||
} | ||
|
||
if (argsArray[0] !== '--wcache' || argsArray[1] !== 'http://eyereasoner.github.io/eye/reasoning' || argsArray[2] !== '..') { | ||
throw new Error(`Expected --wcache to be the first argument on [${args}]`); | ||
} | ||
|
||
const subPath = path.join(folder, argsArray[argsArray.length - 1]); | ||
argsArray = argsArray.slice(3, -2); | ||
|
||
let query: Quad[] | undefined = undefined; | ||
|
||
if (argsArray.includes('--query')) { | ||
const qind = argsArray.indexOf('--query'); | ||
query = loadFiles([argsArray[qind + 1]]); | ||
argsArray = [...argsArray.slice(0, qind), ...argsArray.slice(qind + 2)]; | ||
} | ||
|
||
const output = (Object.keys(invMapping) as (keyof typeof invMapping)[]).find(key => argsArray.includes(invMapping[key])); | ||
|
||
if (output) { | ||
argsArray = argsArray.filter(arg => arg !== invMapping[output]); | ||
} | ||
|
||
if (argsArray.includes('--nope') && !ignoreOutputs.includes(subPath)) { | ||
await expect( | ||
n3reasoner( | ||
loadFiles(argsArray.filter(arg => arg !== '--nope')), | ||
query, | ||
{ output }, | ||
), | ||
) | ||
.resolves | ||
.toBeRdfIsomorphic(dereference(subPath)); | ||
} | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,64 +1,68 @@ | ||
|
||
// This is a workaround for https://github.com/rdfjs/N3.js/issues/316 | ||
import { Quad, Term } from '@rdfjs/types'; | ||
import { DataFactory as DF, Store, Writer } from 'n3'; | ||
// import { Quad, Term } from '@rdfjs/types'; | ||
// import { DataFactory as DF, Store, Writer } from 'n3'; | ||
export { write } from "@jeswr/pretty-turtle"; | ||
|
||
function isQuoted(term: Term, store: Store) { | ||
return term.termType === 'BlankNode' && store.getQuads(null, null, null, term).length > 0; | ||
} | ||
// function isQuoted(term: Term, store: Store) { | ||
// return term.termType === 'BlankNode' && store.getQuads(null, null, null, term).length > 0; | ||
// } | ||
|
||
export class N3Writer { | ||
private _writer: any = new Writer(); | ||
// export class N3Writer { | ||
// private _writer: any = new Writer(); | ||
|
||
_encodePredicate(term: Term): string { | ||
if (term.termType === 'NamedNode') { | ||
switch (term.value) { | ||
case 'http://www.w3.org/2000/10/swap/log#implies': | ||
return '=>'; | ||
case 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type': | ||
return 'a' | ||
} | ||
} | ||
return this._writer._encodeIriOrBlank(term); | ||
} | ||
// _encodePredicate(term: Term): string { | ||
// if (term.termType === 'NamedNode') { | ||
// switch (term.value) { | ||
// case 'http://www.w3.org/2000/10/swap/log#implies': | ||
// return '=>'; | ||
// case 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type': | ||
// return 'a' | ||
// } | ||
// } | ||
// return this._writer._encodeIriOrBlank(term); | ||
// } | ||
|
||
_encodeSubject(entity: Term, store: Store): string { | ||
if (isQuoted(entity, store)) { | ||
return `{${this.quadsStoreToString(store, entity)}}` | ||
} | ||
return this._writer._encodeSubject(entity) | ||
} | ||
// _encodeSubject(entity: Term, store: Store): string { | ||
// if (isQuoted(entity, store)) { | ||
// return `{${this.quadsStoreToString(store, entity)}}` | ||
// } | ||
// if (entity.termType === 'Literal') { | ||
// return this._writer._encodeObject(entity); | ||
// } | ||
// return this._writer._encodeSubject(entity); | ||
// } | ||
|
||
_encodeObject(entity: Term, store: Store): string { | ||
if (isQuoted(entity, store)) { | ||
return `{${this.quadsStoreToString(store, entity)}}` | ||
} | ||
return this._writer._encodeObject(entity) | ||
} | ||
// _encodeObject(entity: Term, store: Store): string { | ||
// if (isQuoted(entity, store)) { | ||
// return `{${this.quadsStoreToString(store, entity)}}` | ||
// } | ||
// return this._writer._encodeObject(entity) | ||
// } | ||
|
||
// ### `quadToString` serializes a quad as a string | ||
quadToString(t: Quad, store: Store): string { | ||
return `${ | ||
this._encodeSubject(t.subject, store) | ||
} ${ | ||
this._encodePredicate(t.predicate as any) | ||
} ${ | ||
this._encodeObject(t.object, store) | ||
}`; | ||
} | ||
// // ### `quadToString` serializes a quad as a string | ||
// quadToString(t: Quad, store: Store): string { | ||
// return `${ | ||
// this._encodeSubject(t.subject, store) | ||
// } ${ | ||
// this._encodePredicate(t.predicate as any) | ||
// } ${ | ||
// this._encodeObject(t.object, store) | ||
// }`; | ||
// } | ||
|
||
// ### `quadsToString` serializes an array of quads as a string | ||
quadsStoreToString(store: Store, graph: Term = DF.defaultGraph()): string { | ||
return store.getQuads(null, null, null, graph) | ||
.map(t => this.quadToString(t, store)) | ||
.join(' . ') + ' . '; | ||
} | ||
// // ### `quadsToString` serializes an array of quads as a string | ||
// quadsStoreToString(store: Store, graph: Term = DF.defaultGraph()): string { | ||
// return store.getQuads(null, null, null, graph) | ||
// .map(t => this.quadToString(t, store)) | ||
// .join(' . ') + ' . '; | ||
// } | ||
|
||
quadsToString(quads: Quad[]): string { | ||
return this.quadsStoreToString(new Store(quads)) | ||
} | ||
} | ||
// quadsToString(quads: Quad[]): string { | ||
// return this.quadsStoreToString(new Store(quads)) | ||
// } | ||
// } | ||
|
||
export function write(quads: Quad[]) { | ||
return (new N3Writer).quadsToString(quads); | ||
} | ||
// export function write(quads: Quad[]) { | ||
// return (new N3Writer).quadsToString(quads); | ||
// } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters