eyeling 1.18.1 → 1.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/HANDBOOK.md +110 -75
- package/README.md +4 -3
- package/eyeling.js +20 -9
- package/lib/cli.js +20 -9
- package/package.json +1 -1
- package/test/api.test.js +49 -0
package/HANDBOOK.md
CHANGED
|
@@ -1777,12 +1777,16 @@ Install from npm:
|
|
|
1777
1777
|
npm i eyeling
|
|
1778
1778
|
```
|
|
1779
1779
|
|
|
1780
|
-
Run a
|
|
1780
|
+
Run a self-contained example from stdin:
|
|
1781
1781
|
|
|
1782
1782
|
```bash
|
|
1783
|
-
|
|
1783
|
+
echo '@prefix : <http://example.org/> .
|
|
1784
|
+
:Socrates a :Man .
|
|
1785
|
+
{ ?x a :Man } => { ?x a :Mortal } .' | npx eyeling
|
|
1784
1786
|
```
|
|
1785
1787
|
|
|
1788
|
+
You can also pass a file path, or `-` to read explicitly from stdin.
|
|
1789
|
+
|
|
1786
1790
|
Show the available options:
|
|
1787
1791
|
|
|
1788
1792
|
```bash
|
|
@@ -1823,6 +1827,8 @@ The current CLI supports a small set of flags (see `lib/cli.js`):
|
|
|
1823
1827
|
- `-t`, `--stream` — stream derived triples as soon as they are derived.
|
|
1824
1828
|
- `-v`, `--version` — print version and exit.
|
|
1825
1829
|
- `-h`, `--help` — show usage.
|
|
1830
|
+
- With no positional argument, Eyeling reads from stdin when input is piped.
|
|
1831
|
+
- Use `-` as the input path to read explicitly from stdin.
|
|
1826
1832
|
|
|
1827
1833
|
### 14.3 `lib/entry.js`: bundler-friendly exports
|
|
1828
1834
|
|
|
@@ -1833,7 +1839,14 @@ The current CLI supports a small set of flags (see `lib/cli.js`):
|
|
|
1833
1839
|
|
|
1834
1840
|
`rdfjs` is a small built-in RDF/JS `DataFactory`, so browser / worker code can construct quads without pulling in another package first.
|
|
1835
1841
|
|
|
1836
|
-
### 14.4
|
|
1842
|
+
### 14.4 JavaScript API
|
|
1843
|
+
|
|
1844
|
+
Eyeling exposes two JavaScript entry styles:
|
|
1845
|
+
|
|
1846
|
+
- `reason(...)` from `index.js` when you want the same text output as the CLI
|
|
1847
|
+
- `reasonStream(...)` / `reasonRdfJs(...)` from the bundle entry when you want in-process reasoning and structured RDF/JS results
|
|
1848
|
+
|
|
1849
|
+
#### 14.4.1 npm helper: `reason(...)`
|
|
1837
1850
|
|
|
1838
1851
|
The npm `reason(...)` function does something intentionally simple and robust:
|
|
1839
1852
|
|
|
@@ -1844,119 +1857,141 @@ The npm `reason(...)` function does something intentionally simple and robust:
|
|
|
1844
1857
|
|
|
1845
1858
|
This keeps the observable output identical to the CLI while still allowing richer JS-side inputs.
|
|
1846
1859
|
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
- raw N3 strings
|
|
1850
|
-
- RDF/JS fact inputs (`quads`, `facts`, or `dataset`)
|
|
1851
|
-
- Eyeling rule objects or full AST bundles like `[prefixes, triples, frules, brules]`
|
|
1860
|
+
CommonJS:
|
|
1852
1861
|
|
|
1853
|
-
|
|
1862
|
+
```js
|
|
1863
|
+
const { reason } = require('eyeling');
|
|
1854
1864
|
|
|
1855
|
-
|
|
1865
|
+
const input = `
|
|
1866
|
+
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
|
|
1867
|
+
@prefix : <http://example.org/socrates#>.
|
|
1856
1868
|
|
|
1857
|
-
|
|
1869
|
+
:Socrates a :Human.
|
|
1870
|
+
:Human rdfs:subClassOf :Mortal.
|
|
1858
1871
|
|
|
1859
|
-
|
|
1872
|
+
{ ?s a ?A. ?A rdfs:subClassOf ?B. } => { ?s a ?B. }.
|
|
1873
|
+
`;
|
|
1860
1874
|
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
- `dataset`
|
|
1875
|
+
console.log(reason({ proofComments: false }, input));
|
|
1876
|
+
```
|
|
1864
1877
|
|
|
1865
|
-
|
|
1878
|
+
ESM:
|
|
1866
1879
|
|
|
1867
1880
|
```js
|
|
1868
|
-
|
|
1881
|
+
import eyeling from 'eyeling';
|
|
1869
1882
|
|
|
1870
|
-
const input =
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
|
|
1880
|
-
@prefix : <http://example.org/>.
|
|
1881
|
-
:Human rdfs:subClassOf :Mortal.
|
|
1882
|
-
{ ?x a ?c. ?c rdfs:subClassOf ?d. } => { ?x a ?d. }.
|
|
1883
|
-
`,
|
|
1884
|
-
};
|
|
1883
|
+
const input = `
|
|
1884
|
+
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
|
|
1885
|
+
@prefix : <http://example.org/socrates#>.
|
|
1886
|
+
|
|
1887
|
+
:Socrates a :Human.
|
|
1888
|
+
:Human rdfs:subClassOf :Mortal.
|
|
1889
|
+
|
|
1890
|
+
{ ?s a ?A. ?A rdfs:subClassOf ?B. } => { ?s a ?B. }.
|
|
1891
|
+
`;
|
|
1885
1892
|
|
|
1886
|
-
|
|
1893
|
+
console.log(eyeling.reason({ proofComments: false }, input));
|
|
1887
1894
|
```
|
|
1888
1895
|
|
|
1889
|
-
|
|
1896
|
+
Notes:
|
|
1897
|
+
|
|
1898
|
+
- `reason()` returns the same textual output you would get from the CLI for the same input and options.
|
|
1899
|
+
- By default, the npm helper keeps output machine-friendly (`proofComments: false`).
|
|
1900
|
+
- Use this path when you want CLI-equivalent behavior inside JavaScript.
|
|
1901
|
+
|
|
1902
|
+
#### 14.4.2 RDF-JS and Eyeling rule-object interoperability
|
|
1890
1903
|
|
|
1891
|
-
|
|
1904
|
+
The JavaScript APIs accept three input styles:
|
|
1892
1905
|
|
|
1893
|
-
|
|
1906
|
+
1. plain N3 text
|
|
1907
|
+
2. RDF/JS fact input (`quads`, `facts`, or `dataset`)
|
|
1908
|
+
3. Eyeling rule objects or full AST bundles
|
|
1894
1909
|
|
|
1895
|
-
|
|
1910
|
+
If you want to use N3 source text, pass the whole input as a plain string.
|
|
1911
|
+
|
|
1912
|
+
For RDF/JS facts, the graph must be the default graph. Named-graph quads are rejected.
|
|
1913
|
+
|
|
1914
|
+
If you already have rules in structured form, Eyeling rule objects can be passed directly in the API:
|
|
1896
1915
|
|
|
1897
1916
|
```js
|
|
1898
|
-
const { reason } = require('eyeling');
|
|
1917
|
+
const { reason, rdfjs } = require('eyeling');
|
|
1899
1918
|
|
|
1900
|
-
const
|
|
1901
|
-
|
|
1902
|
-
|
|
1919
|
+
const ex = 'http://example.org/';
|
|
1920
|
+
|
|
1921
|
+
const rule = {
|
|
1922
|
+
_type: 'Rule',
|
|
1923
|
+
premise: [
|
|
1924
|
+
{
|
|
1925
|
+
_type: 'Triple',
|
|
1926
|
+
s: { _type: 'Var', name: 'x' },
|
|
1927
|
+
p: { _type: 'Iri', value: ex + 'parent' },
|
|
1928
|
+
o: { _type: 'Var', name: 'y' },
|
|
1929
|
+
},
|
|
1903
1930
|
],
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1931
|
+
conclusion: [
|
|
1932
|
+
{
|
|
1933
|
+
_type: 'Triple',
|
|
1934
|
+
s: { _type: 'Var', name: 'x' },
|
|
1935
|
+
p: { _type: 'Iri', value: ex + 'ancestor' },
|
|
1936
|
+
o: { _type: 'Var', name: 'y' },
|
|
1937
|
+
},
|
|
1909
1938
|
],
|
|
1939
|
+
isForward: true,
|
|
1940
|
+
isFuse: false,
|
|
1941
|
+
headBlankLabels: [],
|
|
1910
1942
|
};
|
|
1911
1943
|
|
|
1912
|
-
const out = reason(
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1944
|
+
const out = reason(
|
|
1945
|
+
{ proofComments: false },
|
|
1946
|
+
{
|
|
1947
|
+
quads: [rdfjs.quad(rdfjs.namedNode(ex + 'alice'), rdfjs.namedNode(ex + 'parent'), rdfjs.namedNode(ex + 'bob'))],
|
|
1948
|
+
rules: [rule],
|
|
1949
|
+
},
|
|
1950
|
+
);
|
|
1916
1951
|
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
- `backwardRules` or `brules`
|
|
1920
|
-
- `queryRules`, `logQueryRules`, or `qrules`
|
|
1921
|
-
- a full AST bundle like `[prefixes, triples, frules, brules, queryRules]`
|
|
1952
|
+
console.log(out);
|
|
1953
|
+
```
|
|
1922
1954
|
|
|
1923
|
-
|
|
1955
|
+
You can also pass a full AST bundle directly, for example `[prefixes, triples, forwardRules, backwardRules]`.
|
|
1924
1956
|
|
|
1925
|
-
#### 14.4.3
|
|
1957
|
+
#### 14.4.3 In-process bundle API: `reasonStream(...)` and `reasonRdfJs(...)`
|
|
1926
1958
|
|
|
1927
|
-
|
|
1959
|
+
Use the bundle entry if you want structured results while the engine is running instead of final CLI text after the fact.
|
|
1928
1960
|
|
|
1929
|
-
|
|
1961
|
+
`reasonStream(...)` can emit RDF/JS quads while reasoning runs:
|
|
1930
1962
|
|
|
1931
1963
|
```js
|
|
1932
|
-
|
|
1964
|
+
import eyeling from './eyeling.js';
|
|
1933
1965
|
|
|
1934
|
-
reasonStream(input, {
|
|
1935
|
-
|
|
1936
|
-
onDerived({
|
|
1937
|
-
|
|
1938
|
-
// quad = RDF/JS Quad for the same derived fact
|
|
1966
|
+
const result = eyeling.reasonStream(input, {
|
|
1967
|
+
proof: false,
|
|
1968
|
+
onDerived: ({ quad }) => {
|
|
1969
|
+
if (quad) console.log(quad);
|
|
1939
1970
|
},
|
|
1940
1971
|
});
|
|
1941
1972
|
```
|
|
1942
1973
|
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
Second, `reasonRdfJs(...)` exposes the same derived results as an **async stream of RDF/JS quads**:
|
|
1974
|
+
That same path also lets derived results be consumed as an async stream of RDF/JS quads:
|
|
1946
1975
|
|
|
1947
1976
|
```js
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
for await (const quad of reasonRdfJs(input)) {
|
|
1951
|
-
// consume RDF/JS quads incrementally
|
|
1977
|
+
for await (const quad of eyeling.reasonRdfJs(input)) {
|
|
1978
|
+
console.log(quad);
|
|
1952
1979
|
}
|
|
1953
1980
|
```
|
|
1954
1981
|
|
|
1955
|
-
|
|
1982
|
+
Use these entry points when you need one or more of the following:
|
|
1983
|
+
|
|
1984
|
+
- RDF/JS quads as fact input
|
|
1985
|
+
- Eyeling rule objects passed directly from JavaScript
|
|
1986
|
+
- derived results consumed as RDF/JS quads
|
|
1987
|
+
- streaming derived RDF/JS quads during reasoning
|
|
1988
|
+
|
|
1989
|
+
### 14.5 Choosing the right entry point
|
|
1956
1990
|
|
|
1957
|
-
|
|
1991
|
+
A practical rule of thumb:
|
|
1958
1992
|
|
|
1959
|
-
- if you want
|
|
1993
|
+
- if you want the same final text output as the CLI, use `reason(...)`
|
|
1994
|
+
- if you want in-process access to structured facts, quads, or streaming derivations, use `reasonStream(...)` / `reasonRdfJs(...)`
|
|
1960
1995
|
|
|
1961
1996
|
---
|
|
1962
1997
|
|
package/README.md
CHANGED
|
@@ -7,13 +7,14 @@ A compact [Notation3 (N3)](https://notation3.org/) reasoner in **JavaScript**.
|
|
|
7
7
|
## Quick start
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
echo '@prefix : <http://example.org/> .
|
|
11
|
+
:Socrates a :Man .
|
|
12
|
+
{ ?x a :Man } => { ?x a :Mortal } .' | npx eyeling
|
|
12
13
|
```
|
|
13
14
|
|
|
14
15
|
## Read more
|
|
15
16
|
|
|
16
17
|
- **Handbook:** [eyereasoner.github.io/eyeling/HANDBOOK](https://eyereasoner.github.io/eyeling/HANDBOOK)
|
|
17
|
-
- **Semantics:** [eyereasoner.github.io/eyeling/SEMANTICS](https://eyereasoner.github.io/eyeling/SEMANTICS)
|
|
18
18
|
- **Playground:** [eyereasoner.github.io/eyeling/demo](https://eyereasoner.github.io/eyeling/demo)
|
|
19
|
+
- **Semantics:** [eyereasoner.github.io/eyeling/SEMANTICS](https://eyereasoner.github.io/eyeling/SEMANTICS)
|
|
19
20
|
- **Conformance report:** [codeberg.org/phochste/notation3tests/.../report.md](https://codeberg.org/phochste/notation3tests/src/branch/main/reports/report.md)
|
package/eyeling.js
CHANGED
|
@@ -4536,6 +4536,11 @@ function formatN3SyntaxError(err, text, path) {
|
|
|
4536
4536
|
}
|
|
4537
4537
|
|
|
4538
4538
|
// CLI entry point (invoked when eyeling.js is run directly)
|
|
4539
|
+
function readTextFromStdinSync() {
|
|
4540
|
+
const fs = require('node:fs');
|
|
4541
|
+
return fs.readFileSync(0, { encoding: 'utf8' });
|
|
4542
|
+
}
|
|
4543
|
+
|
|
4539
4544
|
function main() {
|
|
4540
4545
|
// Drop "node" and script name; keep only user-provided args
|
|
4541
4546
|
// Expand combined short options: -pt == -p -t
|
|
@@ -4555,7 +4560,8 @@ function main() {
|
|
|
4555
4560
|
|
|
4556
4561
|
function printHelp(toStderr = false) {
|
|
4557
4562
|
const msg =
|
|
4558
|
-
`Usage: ${prog} [options]
|
|
4563
|
+
`Usage: ${prog} [options] [file.n3|-]\n\n` +
|
|
4564
|
+
`When no file is given and stdin is piped, read N3 from stdin.\n\n` +
|
|
4559
4565
|
`Options:\n` +
|
|
4560
4566
|
` -a, --ast Print parsed AST as JSON and exit.\n` +
|
|
4561
4567
|
` --builtin <module.js> Load a custom builtin module (repeatable).\n` +
|
|
@@ -4626,12 +4632,13 @@ function main() {
|
|
|
4626
4632
|
}
|
|
4627
4633
|
|
|
4628
4634
|
// Positional args (the N3 file)
|
|
4629
|
-
|
|
4635
|
+
const useImplicitStdin = positional.length === 0 && !process.stdin.isTTY;
|
|
4636
|
+
if (positional.length === 0 && !useImplicitStdin) {
|
|
4630
4637
|
printHelp(false);
|
|
4631
4638
|
process.exit(0);
|
|
4632
4639
|
}
|
|
4633
|
-
if (positional.length
|
|
4634
|
-
console.error('Error: expected
|
|
4640
|
+
if (positional.length > 1) {
|
|
4641
|
+
console.error('Error: expected at most one input [file.n3|-].');
|
|
4635
4642
|
printHelp(true);
|
|
4636
4643
|
process.exit(1);
|
|
4637
4644
|
}
|
|
@@ -4646,13 +4653,17 @@ function main() {
|
|
|
4646
4653
|
}
|
|
4647
4654
|
}
|
|
4648
4655
|
|
|
4649
|
-
const
|
|
4656
|
+
const sourceLabel = useImplicitStdin || positional[0] === '-' ? '<stdin>' : positional[0];
|
|
4650
4657
|
let text;
|
|
4651
4658
|
try {
|
|
4652
|
-
|
|
4653
|
-
|
|
4659
|
+
if (sourceLabel === '<stdin>') text = readTextFromStdinSync();
|
|
4660
|
+
else {
|
|
4661
|
+
const fs = require('node:fs');
|
|
4662
|
+
text = fs.readFileSync(sourceLabel, { encoding: 'utf8' });
|
|
4663
|
+
}
|
|
4654
4664
|
} catch (e) {
|
|
4655
|
-
console.error(`Error reading
|
|
4665
|
+
if (sourceLabel === '<stdin>') console.error(`Error reading stdin: ${e.message}`);
|
|
4666
|
+
else console.error(`Error reading file ${JSON.stringify(sourceLabel)}: ${e.message}`);
|
|
4656
4667
|
process.exit(1);
|
|
4657
4668
|
}
|
|
4658
4669
|
|
|
@@ -4666,7 +4677,7 @@ function main() {
|
|
|
4666
4677
|
engine.setTracePrefixes(prefixes);
|
|
4667
4678
|
} catch (e) {
|
|
4668
4679
|
if (e && e.name === 'N3SyntaxError') {
|
|
4669
|
-
console.error(formatN3SyntaxError(e, text,
|
|
4680
|
+
console.error(formatN3SyntaxError(e, text, sourceLabel));
|
|
4670
4681
|
process.exit(1);
|
|
4671
4682
|
}
|
|
4672
4683
|
throw e;
|
package/lib/cli.js
CHANGED
|
@@ -45,6 +45,11 @@ function formatN3SyntaxError(err, text, path) {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
// CLI entry point (invoked when eyeling.js is run directly)
|
|
48
|
+
function readTextFromStdinSync() {
|
|
49
|
+
const fs = require('node:fs');
|
|
50
|
+
return fs.readFileSync(0, { encoding: 'utf8' });
|
|
51
|
+
}
|
|
52
|
+
|
|
48
53
|
function main() {
|
|
49
54
|
// Drop "node" and script name; keep only user-provided args
|
|
50
55
|
// Expand combined short options: -pt == -p -t
|
|
@@ -64,7 +69,8 @@ function main() {
|
|
|
64
69
|
|
|
65
70
|
function printHelp(toStderr = false) {
|
|
66
71
|
const msg =
|
|
67
|
-
`Usage: ${prog} [options]
|
|
72
|
+
`Usage: ${prog} [options] [file.n3|-]\n\n` +
|
|
73
|
+
`When no file is given and stdin is piped, read N3 from stdin.\n\n` +
|
|
68
74
|
`Options:\n` +
|
|
69
75
|
` -a, --ast Print parsed AST as JSON and exit.\n` +
|
|
70
76
|
` --builtin <module.js> Load a custom builtin module (repeatable).\n` +
|
|
@@ -135,12 +141,13 @@ function main() {
|
|
|
135
141
|
}
|
|
136
142
|
|
|
137
143
|
// Positional args (the N3 file)
|
|
138
|
-
|
|
144
|
+
const useImplicitStdin = positional.length === 0 && !process.stdin.isTTY;
|
|
145
|
+
if (positional.length === 0 && !useImplicitStdin) {
|
|
139
146
|
printHelp(false);
|
|
140
147
|
process.exit(0);
|
|
141
148
|
}
|
|
142
|
-
if (positional.length
|
|
143
|
-
console.error('Error: expected
|
|
149
|
+
if (positional.length > 1) {
|
|
150
|
+
console.error('Error: expected at most one input [file.n3|-].');
|
|
144
151
|
printHelp(true);
|
|
145
152
|
process.exit(1);
|
|
146
153
|
}
|
|
@@ -155,13 +162,17 @@ function main() {
|
|
|
155
162
|
}
|
|
156
163
|
}
|
|
157
164
|
|
|
158
|
-
const
|
|
165
|
+
const sourceLabel = useImplicitStdin || positional[0] === '-' ? '<stdin>' : positional[0];
|
|
159
166
|
let text;
|
|
160
167
|
try {
|
|
161
|
-
|
|
162
|
-
|
|
168
|
+
if (sourceLabel === '<stdin>') text = readTextFromStdinSync();
|
|
169
|
+
else {
|
|
170
|
+
const fs = require('node:fs');
|
|
171
|
+
text = fs.readFileSync(sourceLabel, { encoding: 'utf8' });
|
|
172
|
+
}
|
|
163
173
|
} catch (e) {
|
|
164
|
-
console.error(`Error reading
|
|
174
|
+
if (sourceLabel === '<stdin>') console.error(`Error reading stdin: ${e.message}`);
|
|
175
|
+
else console.error(`Error reading file ${JSON.stringify(sourceLabel)}: ${e.message}`);
|
|
165
176
|
process.exit(1);
|
|
166
177
|
}
|
|
167
178
|
|
|
@@ -175,7 +186,7 @@ function main() {
|
|
|
175
186
|
engine.setTracePrefixes(prefixes);
|
|
176
187
|
} catch (e) {
|
|
177
188
|
if (e && e.name === 'N3SyntaxError') {
|
|
178
|
-
console.error(formatN3SyntaxError(e, text,
|
|
189
|
+
console.error(formatN3SyntaxError(e, text, sourceLabel));
|
|
179
190
|
process.exit(1);
|
|
180
191
|
}
|
|
181
192
|
throw e;
|
package/package.json
CHANGED
package/test/api.test.js
CHANGED
|
@@ -1762,6 +1762,55 @@ _:x :hates { _:foo :making :mess }.
|
|
|
1762
1762
|
},
|
|
1763
1763
|
expect: [/http:\/\/example\.org\/ancestor/m],
|
|
1764
1764
|
},
|
|
1765
|
+
{
|
|
1766
|
+
name: '67 CLI stdin: accepts piped N3 when no file argument is given',
|
|
1767
|
+
run() {
|
|
1768
|
+
const input = `@prefix : <http://example.org/> .
|
|
1769
|
+
:Socrates a :Man .
|
|
1770
|
+
{ ?x a :Man } => { ?x a :Mortal } .
|
|
1771
|
+
`;
|
|
1772
|
+
const r = spawnSync(process.execPath, [path.join(ROOT, 'eyeling.js')], {
|
|
1773
|
+
input,
|
|
1774
|
+
encoding: 'utf8',
|
|
1775
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
1776
|
+
});
|
|
1777
|
+
if (r.error) throw r.error;
|
|
1778
|
+
if (r.status !== 0) {
|
|
1779
|
+
const err = new Error(`CLI failed with exit ${r.status}`);
|
|
1780
|
+
err.code = r.status;
|
|
1781
|
+
err.stdout = r.stdout;
|
|
1782
|
+
err.stderr = r.stderr;
|
|
1783
|
+
throw err;
|
|
1784
|
+
}
|
|
1785
|
+
return r.stdout;
|
|
1786
|
+
},
|
|
1787
|
+
expect: [/:(?:Socrates)\s+a\s+:(?:Mortal)\s*\./],
|
|
1788
|
+
},
|
|
1789
|
+
{
|
|
1790
|
+
name: '68 CLI stdin: accepts explicit - for stdin',
|
|
1791
|
+
run() {
|
|
1792
|
+
const input = `@prefix : <http://example.org/> .
|
|
1793
|
+
:Socrates a :Man .
|
|
1794
|
+
{ ?x a :Man } => { ?x a :Mortal } .
|
|
1795
|
+
`;
|
|
1796
|
+
const r = spawnSync(process.execPath, [path.join(ROOT, 'eyeling.js'), '-'], {
|
|
1797
|
+
input,
|
|
1798
|
+
encoding: 'utf8',
|
|
1799
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
1800
|
+
});
|
|
1801
|
+
if (r.error) throw r.error;
|
|
1802
|
+
if (r.status !== 0) {
|
|
1803
|
+
const err = new Error(`CLI failed with exit ${r.status}`);
|
|
1804
|
+
err.code = r.status;
|
|
1805
|
+
err.stdout = r.stdout;
|
|
1806
|
+
err.stderr = r.stderr;
|
|
1807
|
+
throw err;
|
|
1808
|
+
}
|
|
1809
|
+
return r.stdout;
|
|
1810
|
+
},
|
|
1811
|
+
expect: [/:(?:Socrates)\s+a\s+:(?:Mortal)\s*\./],
|
|
1812
|
+
},
|
|
1813
|
+
|
|
1765
1814
|
{
|
|
1766
1815
|
name: '240 custom builtin module can be loaded via --builtin',
|
|
1767
1816
|
run() {
|