pax_global_header00006660000000000000000000000064134333336100014511gustar00rootroot0000000000000052 comment=b860dc4f253af558905e351b428d157635c835f9 N3.js-1.0.4/000077500000000000000000000000001343333361000124065ustar00rootroot00000000000000N3.js-1.0.4/.eslintrc000066400000000000000000000100631343333361000142320ustar00rootroot00000000000000{ env: { node: true, }, rules: { // Possible Errors comma-dangle: [2, "always-multiline"], no-cond-assign: 0, no-console: 2, no-constant-condition: 0, no-debugger: 2, no-dupe-args: 2, no-dupe-keys: 2, no-duplicate-case: 2, no-empty: 2, no-empty-character-class: 2, no-ex-assign: 2, no-extra-boolean-cast: 2, no-extra-parens: 0, no-extra-semi: 2, no-func-assign: 2, no-inner-declarations: 2, no-invalid-regexp: 2, no-irregular-whitespace: 2, no-negated-in-lhs: 2, no-obj-calls: 2, no-regex-spaces: 2, no-sparse-arrays: 2, no-unreachable: 2, use-isnan: 2, valid-jsdoc: 0, valid-typeof: 2, no-unexpected-multiline: 2, // Best Practices accessor-pairs: 2, block-scoped-var: 2, complexity: 0, consistent-return: 0, curly: 0, default-case: 0, dot-notation: 2, dot-location: [2, "property"], eqeqeq: 2, guard-for-in: 0, no-alert: 2, no-caller: 2, no-div-regex: 2, no-else-return: 0, no-labels: 2, no-eq-null: 2, no-eval: 2, no-extend-native: 2, no-extra-bind: 2, no-fallthrough: 0, no-floating-decimal: 2, no-implicit-coercion: 0, no-implied-eval: 2, no-invalid-this: 2, no-iterator: 2, no-lone-blocks: 2, no-loop-func: 2, no-multi-spaces: 0, no-multi-str: 2, no-native-reassign: 2, no-new-func: 2, no-new-wrappers: 2, no-new: 2, no-octal-escape: 2, no-octal: 2, no-param-reassign: 0, no-process-env: 2, no-proto: 2, no-redeclare: 2, no-return-assign: 0, no-script-url: 2, no-self-compare: 2, no-sequences: 0, // allow the comma operator no-throw-literal: 2, no-unused-expressions: 0, no-useless-call: 2, no-void: 2, no-warning-comments: 2, no-with: 2, radix: 2, vars-on-top: 0, wrap-iife: [2, "inside"], yoda: 2, // Strict Mode strict: [2, "never"], // Variables init-declarations: 0, no-catch-shadow: 2, no-delete-var: 2, no-label-var: 2, no-shadow-restricted-names: 2, no-shadow: 0, no-undef-init: 2, no-undef: 2, no-undefined: 0, no-unused-vars: [ 2, { args: "none" }], no-use-before-define: [2, "nofunc"], // Node.js callback-return: 0, handle-callback-err: 2, no-mixed-requires: 2, no-new-require: 2, no-path-concat: 2, no-process-exit: 2, no-restricted-modules: 2, no-sync: 2, // Stylistic Issues array-bracket-spacing: 2, block-spacing: 2, brace-style: [2, "stroustrup", { allowSingleLine: true }], camelcase: 2, comma-spacing: 2, comma-style: 2, computed-property-spacing: 2, consistent-this: 0, eol-last: 2, func-names: 0, func-style: [2, "declaration"], id-length: 0, id-match: 2, indent-legacy: [2, 2, { VariableDeclarator: 2 }], key-spacing: [2, { mode: "minimum" }], lines-around-comment: 2, linebreak-style: 2, max-nested-callbacks: [2, 1], new-cap: 2, new-parens: 2, newline-after-var: 0, no-array-constructor: 2, no-continue: 2, no-inline-comments: 0, no-lonely-if: 2, no-mixed-spaces-and-tabs: 2, no-multiple-empty-lines: 0, no-nested-ternary: 0, no-new-object: 2, no-spaced-func: 2, no-ternary: 0, no-trailing-spaces: 2, no-underscore-dangle: 0, no-unneeded-ternary: 2, object-curly-spacing: [2, "always"], object-curly-newline: 0, object-property-newline: 0, one-var: 0, operator-assignment: 2, operator-linebreak: [2, "after", { overrides: { ":": "ignore" } }], padded-blocks: [2, "never"], quote-props: [2, "consistent-as-needed"], quotes: [2, "single", "avoid-escape"], semi-spacing: 2, semi: 2, sort-vars: 0, keyword-spacing: 2, space-before-blocks: 2, space-before-function-paren: [2, {"anonymous": "always", "named": "never"}], space-in-parens: 2, space-infix-ops: 2, space-unary-ops: 2, spaced-comment: [2, "always", { block: { markers: ["!"] } }], wrap-regex: 0, }, } N3.js-1.0.4/.gitignore000066400000000000000000000001321343333361000143720ustar00rootroot00000000000000.nyc_output *.log docs browser/n3* node_modules spec/*.ttl coverage .rdf-test-suite-cache N3.js-1.0.4/.travis.yml000066400000000000000000000010441343333361000145160ustar00rootroot00000000000000language: node_js node_js: - "8" - "10" - "node" env: - DEFAULT_NODE_VERSION=10 script: - npm run lint - npm test - npm run spec-turtle - npm run spec-ntriples - npm run spec-nquads - npm run spec-trig - npm run docs after_success: - if [ "$TRAVIS_NODE_VERSION" == "$DEFAULT_NODE_VERSION" ]; then npm install coveralls; node_modules/.bin/nyc --reporter=text-lcov mocha | node_modules/.bin/coveralls; ./.travis_build_pages; fi cache: - npm - directories: - .rdf-test-suite-cache sudo: false N3.js-1.0.4/.travis_build_pages000077500000000000000000000015101343333361000162550ustar00rootroot00000000000000#!/bin/bash # Only publish from the main repository's master branch REPO_NAME="RubenVerborgh/N3.js" if [ "$TRAVIS_REPO_SLUG" != "$REPO_NAME" ] || [ "$TRAVIS_BRANCH" != "master" ] || [ "$TRAVIS_PULL_REQUEST" != "false" ]; then exit; fi echo -e "Generating gh-pages...\n" # Checkout the gh-pages branch REPO_PATH=$PWD pushd $HOME git clone --quiet --branch=gh-pages https://${GH_TOKEN}@github.com/$REPO_NAME gh-pages 2>&1 > /dev/null cd gh-pages # Don't update if already at the latest version if [[ `git log -1 --pretty=%B` == *$TRAVIS_COMMIT* ]]; then exit; fi # Update pages rm -r docs 2> /dev/null cp -r $REPO_PATH/docs . # Commit and push latest version git add . git config user.name "Travis" git config user.email "travis@travis-ci.org" git commit -m "Update to $TRAVIS_COMMIT." git push -fq origin gh-pages 2>&1 > /dev/null popd N3.js-1.0.4/LICENSE.md000066400000000000000000000021071343333361000140120ustar00rootroot00000000000000# License The MIT License (MIT) Copyright ©2012–2018 Ruben Verborgh Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. N3.js-1.0.4/N3.js000066400000000000000000000005731343333361000132310ustar00rootroot00000000000000module.exports = { DataFactory: require('./lib/N3DataFactory'), Lexer: require('./lib/N3Lexer'), Parser: require('./lib/N3Parser'), Writer: require('./lib/N3Writer'), Store: require('./lib/N3Store'), StreamParser: require('./lib/N3StreamParser'), StreamWriter: require('./lib/N3StreamWriter'), Util: require('./lib/N3Util'), }; N3.js-1.0.4/README.md000066400000000000000000000326061343333361000136740ustar00rootroot00000000000000# Lightning fast, asynchronous, streaming RDF for JavaScript [![Build Status](https://travis-ci.org/rdfjs/N3.js.svg?branch=master)](https://travis-ci.org/rdfjs/N3.js) [![Coverage Status](https://coveralls.io/repos/github/rdfjs/N3.js/badge.svg)](https://coveralls.io/github/rdfjs/N3.js) [![npm version](https://badge.fury.io/js/n3.svg)](https://www.npmjs.com/package/n3) [![DOI](https://zenodo.org/badge/3058202.svg)](https://zenodo.org/badge/latestdoi/3058202) The N3.js library is an implementation of the [RDF.js low-level specification](http://rdf.js.org/) that lets you handle [RDF](https://www.w3.org/TR/rdf-primer/) in JavaScript easily. It offers: - [**Parsing**](#parsing) triples/quads from [Turtle](https://www.w3.org/TR/turtle/), [TriG](https://www.w3.org/TR/trig/), [N-Triples](https://www.w3.org/TR/n-triples/), [N-Quads](https://www.w3.org/TR/n-quads/), and [Notation3 (N3)](https://www.w3.org/TeamSubmission/n3/) - [**Writing**](#writing) triples/quads to [Turtle](https://www.w3.org/TR/turtle/), [TriG](https://www.w3.org/TR/trig/), [N-Triples](https://www.w3.org/TR/n-triples/), and [N-Quads](https://www.w3.org/TR/n-quads/) - [**Storage**](#storing) of triples/quads in memory Parsing and writing is: - **asynchronous** – triples arrive as soon as possible - **streaming** – streams are parsed as data comes in, so you can parse files larger than memory - **fast** – by far the [fastest spec-compatible parser in JavaScript](https://github.com/rdfjs/N3.js/tree/master/perf) ## Installation For Node.js, N3.js comes as an [npm package](https://npmjs.org/package/n3). ```Bash $ npm install n3 ``` ```JavaScript const N3 = require('n3'); ``` N3.js seamlessly works in browsers via [webpack](https://webpack.js.org/) or [browserify](http://browserify.org/). If you're unfamiliar with these tools, you can read [_webpack: Creating a Bundle – getting started_](https://webpack.js.org/guides/getting-started/#creating-a-bundle) or [_Introduction to browserify_](https://writingjavascript.org/posts/introduction-to-browserify). ## Creating triples/quads N3.js follows the [RDF.js low-level specification](http://rdf.js.org/). `N3.DataFactory` will give you the [factory](http://rdf.js.org/#datafactory-interface) functions to create triples and quads: ```JavaScript const { DataFactory } = N3; const { namedNode, literal, defaultGraph, quad } = DataFactory; const myQuad = quad( namedNode('https://ruben.verborgh.org/profile/#me'), namedNode('http://xmlns.com/foaf/0.1/givenName'), literal('Ruben', 'en'), defaultGraph(), ); console.log(myQuad.subject.value); // https://ruben.verborgh.org/profile/#me console.log(myQuad.object.value); // Ruben console.log(myQuad.object.datatype.value); // http://www.w3.org/1999/02/22-rdf-syntax-ns#langString console.log(myQuad.object.language); // en ``` In the rest of this document, we will treat “triples” and “quads” equally: we assume that a quad is simply a triple in a named or default graph. ## Parsing ### From an RDF document to quads `N3.Parser` transforms Turtle, TriG, N-Triples, or N-Quads document into quads through a callback: ```JavaScript const parser = new N3.Parser(); parser.parse( `PREFIX c: c:Tom a c:Cat. c:Jerry a c:Mouse; c:smarterThan c:Tom.`, (error, quad, prefixes) => { if (quad) console.log(quad); else console.log("# That's all, folks!", prefixes); }); ``` The callback's first argument is an optional error value, the second is a quad. If there are no more quads, the callback is invoked one last time with `null` for `quad` and a hash of prefixes as third argument.
Pass a second callback to `parse` to retrieve prefixes as they are read.
If no callbacks are provided, parsing happens synchronously. By default, `N3.Parser` parses a permissive superset of Turtle, TriG, N-Triples, and N-Quads.
For strict compatibility with any of those languages, pass a `format` argument upon creation: ```JavaScript const parser1 = N3.Parser({ format: 'N-Triples' }); const parser2 = N3.Parser({ format: 'application/trig' }); ``` Notation3 (N3) is supported _only_ through the `format` argument: ```JavaScript const parser3 = N3.Parser({ format: 'N3' }); const parser4 = N3.Parser({ format: 'Notation3' }); const parser5 = N3.Parser({ format: 'text/n3' }); ``` It is possible to provide the base IRI of the document that you want to parse. This is done by passing a `baseIRI` argument upon creation: ```JavaScript const parser = new N3.Parser({ baseIRI: 'http://example.org/' }); ``` ### From an RDF stream to quads `N3.Parser` can parse [Node.js streams](http://nodejs.org/api/stream.html) as they grow, returning quads as soon as they're ready. ```JavaScript const parser = N3.Parser(), rdfStream = fs.createReadStream('cartoons.ttl'); parser.parse(rdfStream, console.log); ``` `N3.StreamParser` is a [Node.js stream](http://nodejs.org/api/stream.html) and [RDF.js Sink](http://rdf.js.org/#sink-interface) implementation. This solution is ideal if your consumer is slower, since source data is only read when the consumer is ready. ```JavaScript const streamParser = N3.StreamParser(), rdfStream = fs.createReadStream('cartoons.ttl'); rdfStream.pipe(streamParser); streamParser.pipe(new SlowConsumer()); function SlowConsumer() { const writer = new require('stream').Writable({ objectMode: true }); writer._write = (quad, encoding, done) => { console.log(quad); setTimeout(done, 1000); }; return writer; } ``` A dedicated `prefix` event signals every prefix with `prefix` and `term` arguments. ## Writing ### From quads to a string `N3.Writer` serializes quads as an RDF document. Write quads through `addQuad`. ```JavaScript const writer = N3.Writer({ prefixes: { c: 'http://example.org/cartoons#' } }); writer.addQuad( namedNode('http://example.org/cartoons#Tom'), namedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), namedNode('http://example.org/cartoons#Cat') ); writer.addQuad(quad( namedNode('http://example.org/cartoons#Tom'), namedNode('http://example.org/cartoons#name'), literal('Tom') )); writer.end((error, result) => console.log(result)); ``` By default, `N3.Writer` writes Turtle (or TriG if some quads are in a named graph).
To write N-Triples (or N-Quads) instead, pass a `format` argument upon creation: ```JavaScript const writer1 = N3.Writer({ format: 'N-Triples' }); const writer2 = N3.Writer({ format: 'application/trig' }); ``` ### From quads to an RDF stream `N3.Writer` can also write quads to a Node.js stream. ```JavaScript const writer = N3.Writer(process.stdout, { end: false, prefixes: { c: 'http://example.org/cartoons#' } }); writer.addQuad( namedNode('http://example.org/cartoons#Tom'), namedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), namedNode('http://example.org/cartoons#Cat') ); writer.addQuad(quad( namedNode('http://example.org/cartoons#Tom'), namedNode('http://example.org/cartoons#name'), literal('Tom') )); writer.end(); ``` ### From a quad stream to an RDF stream `N3.StreamWriter` is a [Node.js stream](http://nodejs.org/api/stream.html) and [RDF.js Sink](http://rdf.js.org/#sink-interface) implementation. ```JavaScript const streamParser = new N3.StreamParser(), inputStream = fs.createReadStream('cartoons.ttl'), streamWriter = new N3.StreamWriter({ prefixes: { c: 'http://example.org/cartoons#' } }); inputStream.pipe(streamParser); streamParser.pipe(streamWriter); streamWriter.pipe(process.stdout); ``` ### Blank nodes and lists You might want to use the `[…]` and list `(…)` notations of Turtle and TriG. However, a streaming writer cannot create these automatically: the shorthand notations are only possible if blank nodes or list heads are not used later on, which can only be determined conclusively at the end of the stream. The `blank` and `list` functions allow you to create them manually instead: ```JavaScript const writer = N3.Writer({ prefixes: { c: 'http://example.org/cartoons#', foaf: 'http://xmlns.com/foaf/0.1/' } }); writer.addQuad( writer.blank( namedNode('http://xmlns.com/foaf/0.1/givenName'), literal('Tom', 'en')), namedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), namedNode('http://example.org/cartoons#Cat') ); writer.addQuad(quad( namedNode('http://example.org/cartoons#Jerry'), namedNode('http://xmlns.com/foaf/0.1/knows'), writer.blank([{ predicate: namedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), object: namedNode('http://example.org/cartoons#Cat'), },{ predicate: namedNode('http://xmlns.com/foaf/0.1/givenName'), object: literal('Tom', 'en'), }]) )); writer.addQuad( namedNode('http://example.org/cartoons#Mammy'), namedNode('http://example.org/cartoons#hasPets'), writer.list([ namedNode('http://example.org/cartoons#Tom'), namedNode('http://example.org/cartoons#Jerry'), ]) ); writer.end((error, result) => console.log(result)); ``` ## Storing `N3.Store` allows you to store triples in memory and find them fast. In this example, we create a new store and add the triples `:Pluto a :Dog.` and `:Mickey a :Mouse`.
Then, we find triples with `:Mickey` as subject. ```JavaScript const store = N3.Store(); store.addQuad( namedNode('http://ex.org/Pluto'), namedNode('http://ex.org/type'), namedNode('http://ex.org/Dog') ); store.addQuad( namedNode('http://ex.org/Mickey'), namedNode('http://ex.org/type'), namedNode('http://ex.org/Mouse') ); const mickey = store.getQuads(namedNode('http://ex.org/Mickey'), null, null)[0]; console.log(mickey); ``` ### Addition and deletion of quads The store provides the following manipulation methods ([documentation](http://rdfjs.github.io/N3.js/docs/N3Store.html)): - `addQuad` to insert one quad - `addQuads` to insert an array of quads - `removeQuad` to remove one quad - `removeQuads` to remove an array of quads - `createBlankNode` returns an unused blank node identifier ### Searching quads or entities The store provides the following search methods ([documentation](http://rdfjs.github.io/N3.js/docs/N3Store.html)): - `getQuads` returns an array of quads matching the given pattern - `countQuads` counts the number of quads matching the given pattern - `forEach` executes a callback on all matching quads - `every` returns whether a callback on matching quads always returns true - `some` returns whether a callback on matching quads returns true at least once - `getSubjects` returns an array of unique subjects occurring in matching quads - `forSubjects` executes a callback on unique subjects occurring in matching quads - `getPredicates` returns an array of unique predicates occurring in matching quad - `forPredicates` executes a callback on unique predicates occurring in matching quads - `getObjects` returns an array of unique objects occurring in matching quad - `forObjects` executes a callback on unique objects occurring in matching quads - `getGraphs` returns an array of unique graphs occurring in matching quad - `forGraphs` executes a callback on unique graphs occurring in matching quads ## Compatibility ### Format specifications The N3.js parser and writer is fully compatible with the following W3C specifications: - [RDF 1.1 Turtle](https://www.w3.org/TR/turtle/) – [EARL report](https://raw.githubusercontent.com/rdfjs/N3.js/earl/n3js-earl-report-turtle.ttl) - [RDF 1.1 TriG](https://www.w3.org/TR/trig/) – [EARL report](https://raw.githubusercontent.com/rdfjs/N3.js/earl/n3js-earl-report-trig.ttl) - [RDF 1.1 N-Triples](https://www.w3.org/TR/n-triples/) – [EARL report](https://raw.githubusercontent.com/rdfjs/N3.js/earl/n3js-earl-report-ntriples.ttl) - [RDF 1.1 N-Quads](https://www.w3.org/TR/n-quads/) – [EARL report](https://raw.githubusercontent.com/rdfjs/N3.js/earl/n3js-earl-report-nquads.ttl) In addition, the N3.js parser also supports [Notation3 (N3)](https://www.w3.org/TeamSubmission/n3/) (no official specification yet). Pass a `format` option to the constructor with the name or MIME type of a format for strict, fault-intolerant behavior. ### Interface specifications The N3.js submodules are compatible with the following [RDF.js](http://rdf.js.org) interfaces: - `N3.DataFactory` implements [`DataFactory`](http://rdf.js.org/#datafactory-interface) - the terms it creates implement [`Term`](http://rdf.js.org/#term-interface) and one of [`NamedNode`](http://rdf.js.org/#namednode-interface), [`BlankNode`](http://rdf.js.org/#blanknode-interface), [`Literal`](http://rdf.js.org/#litereal-interface), [`Variable`](http://rdf.js.org/#variable-interface), [`DefaultGraph`](http://rdf.js.org/#defaultgraph-interface) - the triples/quads it creates implement [`Triple`](http://rdf.js.org/#triple-interface) and [`Quad`](http://rdf.js.org/#quad-interface) - `N3.StreamParser` implements [`Stream`](http://rdf.js.org/#stream-interface) and [`Sink`](http://rdf.js.org/#sink-interface) - `N3.StreamWriter` implements [`Stream`](http://rdf.js.org/#stream-interface) and [`Sink`](http://rdf.js.org/#sink-interface) - `N3.Store` implements [`Sink`](http://rdf.js.org/#sink-interface) ## License and contributions The N3.js library is copyrighted by [Ruben Verborgh](https://ruben.verborgh.org/) and released under the [MIT License](https://github.com/rdfjs/N3.js/blob/master/LICENSE.md). Contributions are welcome, and bug reports or pull requests are always helpful. If you plan to implement a larger feature, it's best to contact me first. N3.js-1.0.4/lib/000077500000000000000000000000001343333361000131545ustar00rootroot00000000000000N3.js-1.0.4/lib/IRIs.js000066400000000000000000000013031343333361000143150ustar00rootroot00000000000000var RDF = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', XSD = 'http://www.w3.org/2001/XMLSchema#', SWAP = 'http://www.w3.org/2000/10/swap/'; module.exports = { xsd: { decimal: XSD + 'decimal', boolean: XSD + 'boolean', double: XSD + 'double', integer: XSD + 'integer', string: XSD + 'string', }, rdf: { type: RDF + 'type', nil: RDF + 'nil', first: RDF + 'first', rest: RDF + 'rest', langString: RDF + 'langString', }, owl: { sameAs: 'http://www.w3.org/2002/07/owl#sameAs', }, r: { forSome: SWAP + 'reify#forSome', forAll: SWAP + 'reify#forAll', }, log: { implies: SWAP + 'log#implies', }, }; N3.js-1.0.4/lib/N3DataFactory.js000066400000000000000000000236551343333361000161270ustar00rootroot00000000000000// N3.js implementations of the RDF/JS core data types // See https://github.com/rdfjs/representation-task-force/blob/master/interface-spec.md var namespaces = require('./IRIs'); var rdf = namespaces.rdf, xsd = namespaces.xsd; var DataFactory, DEFAULTGRAPH; var _blankNodeCounter = 0; // ## Term constructor function Term(id) { if (!(this instanceof Term)) return new Term(id); this.id = id; } // ### Makes this class a subclass of the given type Term.subclass = function subclass(Type, name) { Type.prototype = Object.create(this.prototype, { constructor: { value: Type }, termType: { enumerable: true, value: name, }, }); Type.subclass = subclass; }; // ### Returns whether this object represents the same term as the other Term.prototype.equals = function (other) { // If both terms were created by this library, // equality can be computed through ids if (other instanceof Term) return this.id === other.id; // Otherwise, compare term type and value return !!other && this.termType === other.termType && this.value === other.value; }; // ### Returns a plain object representation of this term Term.prototype.toJSON = function () { return { termType: this.termType, value: this.value, }; }; // ### Constructs a term from the given internal string ID function fromId(id, factory) { factory = factory || DataFactory; // Falsy value or empty string indicate the default graph if (!id) return factory.defaultGraph(); // Identify the term type based on the first character switch (id[0]) { case '_': return factory.blankNode(id.substr(2)); case '?': return factory.variable(id.substr(1)); case '"': // Shortcut for internal literals if (factory === DataFactory) return new Literal(id); // Literal without datatype or language if (id[id.length - 1] === '"') return factory.literal(id.substr(1, id.length - 2)); // Literal with datatype or language var endPos = id.lastIndexOf('"', id.length - 1); return factory.literal(id.substr(1, endPos - 1), id[endPos + 1] === '@' ? id.substr(endPos + 2) : factory.namedNode(id.substr(endPos + 3))); default: return factory.namedNode(id); } } // ### Constructs an internal string ID from the given term or ID string function toId(term) { if (typeof term === 'string') return term; if (term instanceof Term) return term.id; if (!term) return DEFAULTGRAPH.value; // Term instantiated with another library switch (term.termType) { case 'NamedNode': return term.value; case 'BlankNode': return '_:' + term.value; case 'Variable': return '?' + term.value; case 'DefaultGraph': return ''; case 'Literal': return '"' + term.value + '"' + (term.language ? '@' + term.language : (term.datatype && term.datatype.value !== xsd.string ? '^^' + term.datatype.value : '')); default: throw new Error('Unexpected termType: ' + term.termType); } } // ## NamedNode constructor function NamedNode(iri) { if (!(this instanceof NamedNode)) return new NamedNode(iri); this.id = iri; } Term.subclass(NamedNode, 'NamedNode'); // ### The IRI of this named node Object.defineProperty(NamedNode.prototype, 'value', { enumerable: true, get: function () { return this.id; }, }); // ## BlankNode constructor function BlankNode(name) { if (!(this instanceof BlankNode)) return new BlankNode(name); this.id = '_:' + name; } Term.subclass(BlankNode, 'BlankNode'); // ### The name of this blank node Object.defineProperty(BlankNode.prototype, 'value', { enumerable: true, get: function () { return this.id.substr(2); }, }); // ## Variable constructor function Variable(name) { if (!(this instanceof Variable)) return new Variable(name); this.id = '?' + name; } Term.subclass(Variable, 'Variable'); // ### The name of this variable Object.defineProperty(Variable.prototype, 'value', { enumerable: true, get: function () { return this.id.substr(1); }, }); // ## Literal constructor function Literal(id) { if (!(this instanceof Literal)) return new Literal(id); this.id = id; } Term.subclass(Literal, 'Literal'); // ### The text value of this literal Object.defineProperty(Literal.prototype, 'value', { enumerable: true, get: function () { return this.id.substring(1, this.id.lastIndexOf('"')); }, }); // ### The language of this literal Object.defineProperty(Literal.prototype, 'language', { enumerable: true, get: function () { // Find the last quotation mark (e.g., '"abc"@en-us') var id = this.id, atPos = id.lastIndexOf('"') + 1; // If "@" it follows, return the remaining substring; empty otherwise return atPos < id.length && id[atPos++] === '@' ? id.substr(atPos).toLowerCase() : ''; }, }); // ### The datatype IRI of this literal Object.defineProperty(Literal.prototype, 'datatype', { enumerable: true, get: function () { return new NamedNode(this.datatypeString); }, }); // ### The datatype string of this literal Object.defineProperty(Literal.prototype, 'datatypeString', { enumerable: true, get: function () { // Find the last quotation mark (e.g., '"abc"^^http://ex.org/types#t') var id = this.id, dtPos = id.lastIndexOf('"') + 1, ch; // If "^" it follows, return the remaining substring return dtPos < id.length && (ch = id[dtPos]) === '^' ? id.substr(dtPos + 2) : // If "@" follows, return rdf:langString; xsd:string otherwise (ch !== '@' ? xsd.string : rdf.langString); }, }); // ### Returns whether this object represents the same term as the other Literal.prototype.equals = function (other) { // If both literals were created by this library, // equality can be computed through ids if (other instanceof Literal) return this.id === other.id; // Otherwise, compare term type, value, language, and datatype return !!other && !!other.datatype && this.termType === other.termType && this.value === other.value && this.language === other.language && this.datatype.value === other.datatype.value; }; // ### Returns a plain object representation of this term Literal.prototype.toJSON = function () { return { termType: this.termType, value: this.value, language: this.language, datatype: { termType: 'NamedNode', value: this.datatypeString }, }; }; // ## DefaultGraph singleton function DefaultGraph() { return DEFAULTGRAPH || this; } Term.subclass(DefaultGraph, 'DefaultGraph'); // Initialize singleton DEFAULTGRAPH = new DefaultGraph(); DEFAULTGRAPH.id = ''; // ### The empty string Object.defineProperty(DefaultGraph.prototype, 'value', { enumerable: true, value: '', }); // ### Returns whether this object represents the same term as the other DefaultGraph.prototype.equals = function (other) { // If both terms were created by this library, // equality can be computed through strict equality; // otherwise, compare term types. return (this === other) || (!!other && (this.termType === other.termType)); }; // ## Quad constructor function Quad(subject, predicate, object, graph) { if (!(this instanceof Quad)) return new Quad(subject, predicate, object, graph); this.subject = subject; this.predicate = predicate; this.object = object; this.graph = graph || DEFAULTGRAPH; } // ### Returns a plain object representation of this quad Quad.prototype.toJSON = function () { return { subject: this.subject.toJSON(), predicate: this.predicate.toJSON(), object: this.object.toJSON(), graph: this.graph.toJSON(), }; }; // ### Returns whether this object represents the same quad as the other Quad.prototype.equals = function (other) { return !!other && this.subject.equals(other.subject) && this.predicate.equals(other.predicate) && this.object.equals(other.object) && this.graph.equals(other.graph); }; // ## DataFactory functions // ### Creates an IRI function namedNode(iri) { return new NamedNode(iri); } // ### Creates a blank node function blankNode(name) { if (!name) name = 'n3-' + _blankNodeCounter++; return new BlankNode(name); } // ### Creates a literal function literal(value, languageOrDataType) { // Create a language-tagged string if (typeof languageOrDataType === 'string') return new Literal('"' + value + '"@' + languageOrDataType.toLowerCase()); // Create a datatyped literal var datatype = languageOrDataType && languageOrDataType.value || ''; if (!datatype) { switch (typeof value) { // Convert a boolean case 'boolean': datatype = xsd.boolean; break; // Convert an integer or double case 'number': if (Number.isFinite(value)) datatype = Number.isInteger(value) ? xsd.integer : xsd.double; else { datatype = xsd.double; if (!Number.isNaN(value)) value = value > 0 ? 'INF' : '-INF'; } break; // No datatype, so convert a plain string default: return new Literal('"' + value + '"'); } } return new Literal('"' + value + '"^^' + datatype); } // ### Creates a variable function variable(name) { return new Variable(name); } // ### Returns the default graph function defaultGraph() { return DEFAULTGRAPH; } // ### Creates a quad function quad(subject, predicate, object, graph) { return new Quad(subject, predicate, object, graph); } // ## Module exports module.exports = DataFactory = { // ### Public factory functions namedNode: namedNode, blankNode: blankNode, variable: variable, literal: literal, defaultGraph: defaultGraph, quad: quad, triple: quad, // ### Internal datatype constructors internal: { Term: Term, NamedNode: NamedNode, BlankNode: BlankNode, Variable: Variable, Literal: Literal, DefaultGraph: DefaultGraph, Quad: Quad, Triple: Quad, fromId: fromId, toId: toId, }, }; N3.js-1.0.4/lib/N3Lexer.js000066400000000000000000000453421343333361000150020ustar00rootroot00000000000000// **N3Lexer** tokenizes N3 documents. var xsd = require('./IRIs').xsd; var fromCharCode = String.fromCharCode; var immediately = typeof setImmediate === 'function' ? setImmediate : function setImmediate(func) { setTimeout(func, 0); }; // Regular expression and replacement string to escape N3 strings. // Note how we catch invalid unicode sequences separately (they will trigger an error). var escapeSequence = /\\u([a-fA-F0-9]{4})|\\U([a-fA-F0-9]{8})|\\[uU]|\\(.)/g; var escapeReplacements = { '\\': '\\', "'": "'", '"': '"', 'n': '\n', 'r': '\r', 't': '\t', 'f': '\f', 'b': '\b', '_': '_', '~': '~', '.': '.', '-': '-', '!': '!', '$': '$', '&': '&', '(': '(', ')': ')', '*': '*', '+': '+', ',': ',', ';': ';', '=': '=', '/': '/', '?': '?', '#': '#', '@': '@', '%': '%', }; var illegalIriChars = /[\x00-\x20<>\\"\{\}\|\^\`]/; var lineModeRegExps = { _iri: true, _unescapedIri: true, _unescapedQuote: true, _singleQuote: true, _langcode: true, _blank: true, _newline: true, _comment: true, _whitespace: true, _endOfFile: true, }; var invalidRegExp = /$0^/; // ## Constructor function N3Lexer(options) { if (!(this instanceof N3Lexer)) return new N3Lexer(options); options = options || {}; // In line mode (N-Triples or N-Quads), only simple features may be parsed if (this._lineMode = !!options.lineMode) { this._n3Mode = false; // Don't tokenize special literals for (var key in this) { if (!(key in lineModeRegExps) && this[key] instanceof RegExp) this[key] = invalidRegExp; } } // When not in line mode, enable N3 functionality by default else { this._n3Mode = options.n3 !== false; } // Don't output comment tokens by default this._comments = !!options.comments; } N3Lexer.prototype = { // ## Regular expressions // It's slightly faster to have these as properties than as in-scope variables _iri: /^<((?:[^ <>{}\\]|\\[uU])+)>[ \t]*/, // IRI with escape sequences; needs sanity check after unescaping _unescapedIri: /^<([^\x00-\x20<>\\"\{\}\|\^\`]*)>[ \t]*/, // IRI without escape sequences; no unescaping _unescapedQuote: /^"([^"\\\r\n]+)"/, // non-empty string without escape sequences _unescapedApos: /^'([^'\\\r\n]+)'/, _singleQuote: /^"((?:[^"\\\r\n]|\\.)*)"(?=[^"])/, _singleApos: /^'((?:[^'\\\r\n]|\\.)*)'(?=[^'])/, _tripleQuote: /^"""([^"\\]*(?:(?:\\.|"(?!""))[^"\\]*)*)"""/, _tripleApos: /^'''([^'\\]*(?:(?:\\.|'(?!''))[^'\\]*)*)'''/, _langcode: /^@([a-z]+(?:-[a-z0-9]+)*)(?=[^a-z0-9\-])/i, _prefix: /^((?:[A-Za-z\xc0-\xd6\xd8-\xf6\xf8-\u02ff\u0370-\u037d\u037f-\u1fff\u200c\u200d\u2070-\u218f\u2c00-\u2fef\u3001-\ud7ff\uf900-\ufdcf\ufdf0-\ufffd]|[\ud800-\udb7f][\udc00-\udfff])(?:\.?[\-0-9A-Z_a-z\xb7\xc0-\xd6\xd8-\xf6\xf8-\u037d\u037f-\u1fff\u200c\u200d\u203f\u2040\u2070-\u218f\u2c00-\u2fef\u3001-\ud7ff\uf900-\ufdcf\ufdf0-\ufffd]|[\ud800-\udb7f][\udc00-\udfff])*)?:(?=[#\s<])/, _prefixed: /^((?:[A-Za-z\xc0-\xd6\xd8-\xf6\xf8-\u02ff\u0370-\u037d\u037f-\u1fff\u200c\u200d\u2070-\u218f\u2c00-\u2fef\u3001-\ud7ff\uf900-\ufdcf\ufdf0-\ufffd]|[\ud800-\udb7f][\udc00-\udfff])(?:\.?[\-0-9A-Z_a-z\xb7\xc0-\xd6\xd8-\xf6\xf8-\u037d\u037f-\u1fff\u200c\u200d\u203f\u2040\u2070-\u218f\u2c00-\u2fef\u3001-\ud7ff\uf900-\ufdcf\ufdf0-\ufffd]|[\ud800-\udb7f][\udc00-\udfff])*)?:((?:(?:[0-:A-Z_a-z\xc0-\xd6\xd8-\xf6\xf8-\u02ff\u0370-\u037d\u037f-\u1fff\u200c\u200d\u2070-\u218f\u2c00-\u2fef\u3001-\ud7ff\uf900-\ufdcf\ufdf0-\ufffd]|[\ud800-\udb7f][\udc00-\udfff]|%[0-9a-fA-F]{2}|\\[!#-\/;=?\-@_~])(?:(?:[\.\-0-:A-Z_a-z\xb7\xc0-\xd6\xd8-\xf6\xf8-\u037d\u037f-\u1fff\u200c\u200d\u203f\u2040\u2070-\u218f\u2c00-\u2fef\u3001-\ud7ff\uf900-\ufdcf\ufdf0-\ufffd]|[\ud800-\udb7f][\udc00-\udfff]|%[0-9a-fA-F]{2}|\\[!#-\/;=?\-@_~])*(?:[\-0-:A-Z_a-z\xb7\xc0-\xd6\xd8-\xf6\xf8-\u037d\u037f-\u1fff\u200c\u200d\u203f\u2040\u2070-\u218f\u2c00-\u2fef\u3001-\ud7ff\uf900-\ufdcf\ufdf0-\ufffd]|[\ud800-\udb7f][\udc00-\udfff]|%[0-9a-fA-F]{2}|\\[!#-\/;=?\-@_~]))?)?)(?:[ \t]+|(?=\.?[,;!\^\s#()\[\]\{\}"'<]))/, _variable: /^\?(?:(?:[A-Z_a-z\xc0-\xd6\xd8-\xf6\xf8-\u02ff\u0370-\u037d\u037f-\u1fff\u200c\u200d\u2070-\u218f\u2c00-\u2fef\u3001-\ud7ff\uf900-\ufdcf\ufdf0-\ufffd]|[\ud800-\udb7f][\udc00-\udfff])(?:[\-0-:A-Z_a-z\xb7\xc0-\xd6\xd8-\xf6\xf8-\u037d\u037f-\u1fff\u200c\u200d\u203f\u2040\u2070-\u218f\u2c00-\u2fef\u3001-\ud7ff\uf900-\ufdcf\ufdf0-\ufffd]|[\ud800-\udb7f][\udc00-\udfff])*)(?=[.,;!\^\s#()\[\]\{\}"'<])/, _blank: /^_:((?:[0-9A-Z_a-z\xc0-\xd6\xd8-\xf6\xf8-\u02ff\u0370-\u037d\u037f-\u1fff\u200c\u200d\u2070-\u218f\u2c00-\u2fef\u3001-\ud7ff\uf900-\ufdcf\ufdf0-\ufffd]|[\ud800-\udb7f][\udc00-\udfff])(?:\.?[\-0-9A-Z_a-z\xb7\xc0-\xd6\xd8-\xf6\xf8-\u037d\u037f-\u1fff\u200c\u200d\u203f\u2040\u2070-\u218f\u2c00-\u2fef\u3001-\ud7ff\uf900-\ufdcf\ufdf0-\ufffd]|[\ud800-\udb7f][\udc00-\udfff])*)(?:[ \t]+|(?=\.?[,;:\s#()\[\]\{\}"'<]))/, _number: /^[\-+]?(?:\d+\.?\d*([eE](?:[\-\+])?\d+)|\d*\.?\d+)(?=\.?[,;:\s#()\[\]\{\}"'<])/, _boolean: /^(?:true|false)(?=[.,;\s#()\[\]\{\}"'<])/, _keyword: /^@[a-z]+(?=[\s#<:])/i, _sparqlKeyword: /^(?:PREFIX|BASE|GRAPH)(?=[\s#<])/i, _shortPredicates: /^a(?=\s+|<)/, _newline: /^[ \t]*(?:#[^\n\r]*)?(?:\r\n|\n|\r)[ \t]*/, _comment: /#([^\n\r]*)/, _whitespace: /^[ \t]+/, _endOfFile: /^(?:#[^\n\r]*)?$/, // ## Private methods // ### `_tokenizeToEnd` tokenizes as for as possible, emitting tokens through the callback _tokenizeToEnd: function (callback, inputFinished) { // Continue parsing as far as possible; the loop will return eventually var input = this._input, outputComments = this._comments; while (true) { // Count and skip whitespace lines var whiteSpaceMatch, comment; while (whiteSpaceMatch = this._newline.exec(input)) { // Try to find a comment if (outputComments && (comment = this._comment.exec(whiteSpaceMatch[0]))) callback(null, { line: this._line, type: 'comment', value: comment[1], prefix: '' }); // Advance the input input = input.substr(whiteSpaceMatch[0].length, input.length); this._line++; } // Skip whitespace on current line if (whiteSpaceMatch = this._whitespace.exec(input)) input = input.substr(whiteSpaceMatch[0].length, input.length); // Stop for now if we're at the end if (this._endOfFile.test(input)) { // If the input is finished, emit EOF if (inputFinished) { // Try to find a final comment if (outputComments && (comment = this._comment.exec(input))) callback(null, { line: this._line, type: 'comment', value: comment[1], prefix: '' }); callback(input = null, { line: this._line, type: 'eof', value: '', prefix: '' }); } return this._input = input; } // Look for specific token types based on the first character var line = this._line, type = '', value = '', prefix = '', firstChar = input[0], match = null, matchLength = 0, inconclusive = false; switch (firstChar) { case '^': // We need at least 3 tokens lookahead to distinguish ^^ and ^^pre:fixed if (input.length < 3) break; // Try to match a type else if (input[1] === '^') { this._previousMarker = '^^'; // Move to type IRI or prefixed name input = input.substr(2); if (input[0] !== '<') { inconclusive = true; break; } } // If no type, it must be a path expression else { if (this._n3Mode) { matchLength = 1; type = '^'; } break; } // Fall through in case the type is an IRI case '<': // Try to find a full IRI without escape sequences if (match = this._unescapedIri.exec(input)) type = 'IRI', value = match[1]; // Try to find a full IRI with escape sequences else if (match = this._iri.exec(input)) { value = this._unescape(match[1]); if (value === null || illegalIriChars.test(value)) return reportSyntaxError(this); type = 'IRI'; } // Try to find a backwards implication arrow else if (this._n3Mode && input.length > 1 && input[1] === '=') type = 'inverse', matchLength = 2, value = '>'; break; case '_': // Try to find a blank node. Since it can contain (but not end with) a dot, // we always need a non-dot character before deciding it is a blank node. // Therefore, try inserting a space if we're at the end of the input. if ((match = this._blank.exec(input)) || inputFinished && (match = this._blank.exec(input + ' '))) type = 'blank', prefix = '_', value = match[1]; break; case '"': // Try to find a literal without escape sequences if (match = this._unescapedQuote.exec(input)) value = match[1]; // Before attempting more complex string patterns, try to detect a closing quote else if (input.indexOf('"', 1) > 0) { // Try to find any other literal wrapped in a pair of quotes if (match = this._singleQuote.exec(input)) value = this._unescape(match[1]); // Try to find a literal wrapped in three pairs of quotes else if (match = this._tripleQuote.exec(input)) { value = match[1]; // Advance line counter this._line += value.split(/\r\n|\r|\n/).length - 1; value = this._unescape(value); } if (value === null) return reportSyntaxError(this); } if (match !== null) type = 'literal'; break; case "'": // Try to find a literal without escape sequences if (match = this._unescapedApos.exec(input)) value = match[1]; // Before attempting more complex string patterns, try to detect a closing apostrophe else if (input.indexOf("'", 1) > 0) { // Try to find any other literal wrapped in a pair of apostrophes if (match = this._singleApos.exec(input)) value = this._unescape(match[1]); // Try to find a literal wrapped in three pairs of apostrophes else if (match = this._tripleApos.exec(input)) { value = match[1]; // Advance line counter this._line += value.split(/\r\n|\r|\n/).length - 1; value = this._unescape(value); } if (value === null) return reportSyntaxError(this); } if (match !== null) type = 'literal'; break; case '?': // Try to find a variable if (this._n3Mode && (match = this._variable.exec(input))) type = 'var', value = match[0]; break; case '@': // Try to find a language code if (this._previousMarker === 'literal' && (match = this._langcode.exec(input))) type = 'langcode', value = match[1]; // Try to find a keyword else if (match = this._keyword.exec(input)) type = match[0]; break; case '.': // Try to find a dot as punctuation if (input.length === 1 ? inputFinished : (input[1] < '0' || input[1] > '9')) { type = '.'; matchLength = 1; break; } // Fall through to numerical case (could be a decimal dot) case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '+': case '-': // Try to find a number. Since it can contain (but not end with) a dot, // we always need a non-dot character before deciding it is a number. // Therefore, try inserting a space if we're at the end of the input. if (match = this._number.exec(input) || inputFinished && (match = this._number.exec(input + ' '))) { type = 'literal', value = match[0]; prefix = (match[1] ? xsd.double : (/^[+\-]?\d+$/.test(match[0]) ? xsd.integer : xsd.decimal)); } break; case 'B': case 'b': case 'p': case 'P': case 'G': case 'g': // Try to find a SPARQL-style keyword if (match = this._sparqlKeyword.exec(input)) type = match[0].toUpperCase(); else inconclusive = true; break; case 'f': case 't': // Try to match a boolean if (match = this._boolean.exec(input)) type = 'literal', value = match[0], prefix = xsd.boolean; else inconclusive = true; break; case 'a': // Try to find an abbreviated predicate if (match = this._shortPredicates.exec(input)) type = 'abbreviation', value = 'a'; else inconclusive = true; break; case '=': // Try to find an implication arrow or equals sign if (this._n3Mode && input.length > 1) { type = 'abbreviation'; if (input[1] !== '>') matchLength = 1, value = '='; else matchLength = 2, value = '>'; } break; case '!': if (!this._n3Mode) break; case ',': case ';': case '[': case ']': case '(': case ')': case '{': case '}': if (!this._lineMode) { matchLength = 1; type = firstChar; } break; default: inconclusive = true; } // Some first characters do not allow an immediate decision, so inspect more if (inconclusive) { // Try to find a prefix if ((this._previousMarker === '@prefix' || this._previousMarker === 'PREFIX') && (match = this._prefix.exec(input))) type = 'prefix', value = match[1] || ''; // Try to find a prefixed name. Since it can contain (but not end with) a dot, // we always need a non-dot character before deciding it is a prefixed name. // Therefore, try inserting a space if we're at the end of the input. else if ((match = this._prefixed.exec(input)) || inputFinished && (match = this._prefixed.exec(input + ' '))) type = 'prefixed', prefix = match[1] || '', value = this._unescape(match[2]); } // A type token is special: it can only be emitted after an IRI or prefixed name is read if (this._previousMarker === '^^') { switch (type) { case 'prefixed': type = 'type'; break; case 'IRI': type = 'typeIRI'; break; default: type = ''; } } // What if nothing of the above was found? if (!type) { // We could be in streaming mode, and then we just wait for more input to arrive. // Otherwise, a syntax error has occurred in the input. // One exception: error on an unaccounted linebreak (= not inside a triple-quoted literal). if (inputFinished || (!/^'''|^"""/.test(input) && /\n|\r/.test(input))) return reportSyntaxError(this); else return this._input = input; } // Emit the parsed token var token = { line: line, type: type, value: value, prefix: prefix }; callback(null, token); this.previousToken = token; this._previousMarker = type; // Advance to next part to tokenize input = input.substr(matchLength || match[0].length, input.length); } // Signals the syntax error through the callback function reportSyntaxError(self) { callback(self._syntaxError(/^\S*/.exec(input)[0])); } }, // ### `_unescape` replaces N3 escape codes by their corresponding characters _unescape: function (item) { try { return item.replace(escapeSequence, function (sequence, unicode4, unicode8, escapedChar) { var charCode; if (unicode4) { charCode = parseInt(unicode4, 16); if (isNaN(charCode)) throw new Error(); // can never happen (regex), but helps performance return fromCharCode(charCode); } else if (unicode8) { charCode = parseInt(unicode8, 16); if (isNaN(charCode)) throw new Error(); // can never happen (regex), but helps performance if (charCode <= 0xFFFF) return fromCharCode(charCode); return fromCharCode(0xD800 + ((charCode -= 0x10000) / 0x400), 0xDC00 + (charCode & 0x3FF)); } else { var replacement = escapeReplacements[escapedChar]; if (!replacement) throw new Error(); return replacement; } }); } catch (error) { return null; } }, // ### `_syntaxError` creates a syntax error for the given issue _syntaxError: function (issue) { this._input = null; var err = new Error('Unexpected "' + issue + '" on line ' + this._line + '.'); err.context = { token: undefined, line: this._line, previousToken: this.previousToken, }; return err; }, // ## Public methods // ### `tokenize` starts the transformation of an N3 document into an array of tokens. // The input can be a string or a stream. tokenize: function (input, callback) { var self = this; this._line = 1; // If the input is a string, continuously emit tokens through the callback until the end if (typeof input === 'string') { this._input = input; // If a callback was passed, asynchronously call it if (typeof callback === 'function') immediately(function () { self._tokenizeToEnd(callback, true); }); // If no callback was passed, tokenize synchronously and return else { var tokens = [], error; this._tokenizeToEnd(function (e, t) { e ? (error = e) : tokens.push(t); }, true); if (error) throw error; return tokens; } } // Otherwise, the input must be a stream else { this._input = ''; this._pendingBuffer = null; if (typeof input.setEncoding === 'function') input.setEncoding('utf8'); // Adds the data chunk to the buffer and parses as far as possible input.on('data', function (data) { if (self._input !== null && data.length !== 0) { // Prepend any previous pending writes if (self._pendingBuffer) { data = Buffer.concat([self._pendingBuffer, data]); self._pendingBuffer = null; } // Hold if the buffer ends in an incomplete unicode sequence if (data[data.length - 1] & 0x80) { self._pendingBuffer = data; } // Otherwise, tokenize as far as possible else { self._input += data; self._tokenizeToEnd(callback, false); } } }); // Parses until the end input.on('end', function () { if (self._input !== null) self._tokenizeToEnd(callback, true); }); input.on('error', callback); } }, }; // ## Exports module.exports = N3Lexer; N3.js-1.0.4/lib/N3Parser.js000066400000000000000000001051101343333361000151450ustar00rootroot00000000000000// **N3Parser** parses N3 documents. var N3Lexer = require('./N3Lexer'), DataFactory = require('./N3DataFactory'), namespaces = require('./IRIs'); // The next ID for new blank nodes var blankNodePrefix = 0, blankNodeCount = 0; // ## Constructor function N3Parser(options) { if (!(this instanceof N3Parser)) return new N3Parser(options); this._contextStack = []; this._graph = null; // Set the document IRI options = options || {}; this._setBase(options.baseIRI); options.factory && initDataFactory(this, options.factory); // Set supported features depending on the format var format = (typeof options.format === 'string') ? options.format.match(/\w*$/)[0].toLowerCase() : '', isTurtle = format === 'turtle', isTriG = format === 'trig', isNTriples = /triple/.test(format), isNQuads = /quad/.test(format), isN3 = this._n3Mode = /n3/.test(format), isLineMode = isNTriples || isNQuads; if (!(this._supportsNamedGraphs = !(isTurtle || isN3))) this._readPredicateOrNamedGraph = this._readPredicate; this._supportsQuads = !(isTurtle || isTriG || isNTriples || isN3); // Disable relative IRIs in N-Triples or N-Quads mode if (isLineMode) this._resolveRelativeIRI = function (iri) { return ''; }; this._blankNodePrefix = typeof options.blankNodePrefix !== 'string' ? '' : options.blankNodePrefix.replace(/^(?!_:)/, '_:'); this._lexer = options.lexer || new N3Lexer({ lineMode: isLineMode, n3: isN3 }); // Disable explicit quantifiers by default this._explicitQuantifiers = !!options.explicitQuantifiers; } // ## Private class methods // ### `_resetBlankNodeIds` restarts blank node identification N3Parser._resetBlankNodeIds = function () { blankNodePrefix = blankNodeCount = 0; }; N3Parser.prototype = { // ## Private methods // ### `_blank` creates a new blank node _blank: function () { return this._blankNode('b' + blankNodeCount++); }, // ### `_setBase` sets the base IRI to resolve relative IRIs _setBase: function (baseIRI) { if (!baseIRI) this._base = null; else { // Remove fragment if present var fragmentPos = baseIRI.indexOf('#'); if (fragmentPos >= 0) baseIRI = baseIRI.substr(0, fragmentPos); // Set base IRI and its components this._base = baseIRI; this._basePath = baseIRI.indexOf('/') < 0 ? baseIRI : baseIRI.replace(/[^\/?]*(?:\?.*)?$/, ''); baseIRI = baseIRI.match(/^(?:([a-z][a-z0-9+.-]*:))?(?:\/\/[^\/]*)?/i); this._baseRoot = baseIRI[0]; this._baseScheme = baseIRI[1]; } }, // ### `_saveContext` stores the current parsing context // when entering a new scope (list, blank node, formula) _saveContext: function (type, graph, subject, predicate, object) { var n3Mode = this._n3Mode; this._contextStack.push({ subject: subject, predicate: predicate, object: object, graph: graph, type: type, inverse: n3Mode ? this._inversePredicate : false, blankPrefix: n3Mode ? this._prefixes._ : '', quantified: n3Mode ? this._quantified : null, }); // The settings below only apply to N3 streams if (n3Mode) { // Every new scope resets the predicate direction this._inversePredicate = false; // In N3, blank nodes are scoped to a formula // (using a dot as separator, as a blank node label cannot start with it) this._prefixes._ = (this._graph ? this._graph.id.substr(2) + '.' : '.'); // Quantifiers are scoped to a formula this._quantified = Object.create(this._quantified); } }, // ### `_restoreContext` restores the parent context // when leaving a scope (list, blank node, formula) _restoreContext: function () { var context = this._contextStack.pop(), n3Mode = this._n3Mode; this._subject = context.subject; this._predicate = context.predicate; this._object = context.object; this._graph = context.graph; // The settings below only apply to N3 streams if (n3Mode) { this._inversePredicate = context.inverse; this._prefixes._ = context.blankPrefix; this._quantified = context.quantified; } }, // ### `_readInTopContext` reads a token when in the top context _readInTopContext: function (token) { switch (token.type) { // If an EOF token arrives in the top context, signal that we're done case 'eof': if (this._graph !== null) return this._error('Unclosed graph', token); delete this._prefixes._; return this._callback(null, null, this._prefixes); // It could be a prefix declaration case 'PREFIX': this._sparqlStyle = true; case '@prefix': return this._readPrefix; // It could be a base declaration case 'BASE': this._sparqlStyle = true; case '@base': return this._readBaseIRI; // It could be a graph case '{': if (this._supportsNamedGraphs) { this._graph = ''; this._subject = null; return this._readSubject; } case 'GRAPH': if (this._supportsNamedGraphs) return this._readNamedGraphLabel; // Otherwise, the next token must be a subject default: return this._readSubject(token); } }, // ### `_readEntity` reads an IRI, prefixed name, blank node, or variable _readEntity: function (token, quantifier) { var value; switch (token.type) { // Read a relative or absolute IRI case 'IRI': case 'typeIRI': var iri = this._resolveIRI(token.value); if (iri === '') return this._error('Invalid IRI', token); value = this._namedNode(iri); break; // Read a prefixed name case 'type': case 'prefixed': var prefix = this._prefixes[token.prefix]; if (prefix === undefined) return this._error('Undefined prefix "' + token.prefix + ':"', token); value = this._namedNode(prefix + token.value); break; // Read a blank node case 'blank': value = this._blankNode(this._prefixes[token.prefix] + token.value); break; // Read a variable case 'var': value = this._variable(token.value.substr(1)); break; // Everything else is not an entity default: return this._error('Expected entity but got ' + token.type, token); } // In N3 mode, replace the entity if it is quantified if (!quantifier && this._n3Mode && (value.id in this._quantified)) value = this._quantified[value.id]; return value; }, // ### `_readSubject` reads a quad's subject _readSubject: function (token) { this._predicate = null; switch (token.type) { case '[': // Start a new quad with a new blank node as subject this._saveContext('blank', this._graph, this._subject = this._blank(), null, null); return this._readBlankNodeHead; case '(': // Start a new list this._saveContext('list', this._graph, this.RDF_NIL, null, null); this._subject = null; return this._readListItem; case '{': // Start a new formula if (!this._n3Mode) return this._error('Unexpected graph', token); this._saveContext('formula', this._graph, this._graph = this._blank(), null, null); return this._readSubject; case '}': // No subject; the graph in which we are reading is closed instead return this._readPunctuation(token); case '@forSome': if (!this._n3Mode) return this._error('Unexpected "@forSome"', token); this._subject = null; this._predicate = this.N3_FORSOME; this._quantifier = this._blankNode; return this._readQuantifierList; case '@forAll': if (!this._n3Mode) return this._error('Unexpected "@forAll"', token); this._subject = null; this._predicate = this.N3_FORALL; this._quantifier = this._variable; return this._readQuantifierList; default: // Read the subject entity if ((this._subject = this._readEntity(token)) === undefined) return; // In N3 mode, the subject might be a path if (this._n3Mode) return this._getPathReader(this._readPredicateOrNamedGraph); } // The next token must be a predicate, // or, if the subject was actually a graph IRI, a named graph return this._readPredicateOrNamedGraph; }, // ### `_readPredicate` reads a quad's predicate _readPredicate: function (token) { var type = token.type; switch (type) { case 'inverse': this._inversePredicate = true; case 'abbreviation': this._predicate = this.ABBREVIATIONS[token.value]; break; case '.': case ']': case '}': // Expected predicate didn't come, must have been trailing semicolon if (this._predicate === null) return this._error('Unexpected ' + type, token); this._subject = null; return type === ']' ? this._readBlankNodeTail(token) : this._readPunctuation(token); case ';': // Additional semicolons can be safely ignored return this._predicate !== null ? this._readPredicate : this._error('Expected predicate but got ;', token); case 'blank': if (!this._n3Mode) return this._error('Disallowed blank node as predicate', token); default: if ((this._predicate = this._readEntity(token)) === undefined) return; } // The next token must be an object return this._readObject; }, // ### `_readObject` reads a quad's object _readObject: function (token) { switch (token.type) { case 'literal': // Regular literal, can still get a datatype or language if (token.prefix.length === 0) { this._literalValue = token.value; return this._readDataTypeOrLang; } // Pre-datatyped string literal (prefix stores the datatype) else this._object = this._literal(token.value, this._namedNode(token.prefix)); break; case '[': // Start a new quad with a new blank node as subject this._saveContext('blank', this._graph, this._subject, this._predicate, this._subject = this._blank()); return this._readBlankNodeHead; case '(': // Start a new list this._saveContext('list', this._graph, this._subject, this._predicate, this.RDF_NIL); this._subject = null; return this._readListItem; case '{': // Start a new formula if (!this._n3Mode) return this._error('Unexpected graph', token); this._saveContext('formula', this._graph, this._subject, this._predicate, this._graph = this._blank()); return this._readSubject; default: // Read the object entity if ((this._object = this._readEntity(token)) === undefined) return; // In N3 mode, the object might be a path if (this._n3Mode) return this._getPathReader(this._getContextEndReader()); } return this._getContextEndReader(); }, // ### `_readPredicateOrNamedGraph` reads a quad's predicate, or a named graph _readPredicateOrNamedGraph: function (token) { return token.type === '{' ? this._readGraph(token) : this._readPredicate(token); }, // ### `_readGraph` reads a graph _readGraph: function (token) { if (token.type !== '{') return this._error('Expected graph but got ' + token.type, token); // The "subject" we read is actually the GRAPH's label this._graph = this._subject, this._subject = null; return this._readSubject; }, // ### `_readBlankNodeHead` reads the head of a blank node _readBlankNodeHead: function (token) { if (token.type === ']') { this._subject = null; return this._readBlankNodeTail(token); } else { this._predicate = null; return this._readPredicate(token); } }, // ### `_readBlankNodeTail` reads the end of a blank node _readBlankNodeTail: function (token) { if (token.type !== ']') return this._readBlankNodePunctuation(token); // Store blank node quad if (this._subject !== null) this._emit(this._subject, this._predicate, this._object, this._graph); // Restore the parent context containing this blank node var empty = this._predicate === null; this._restoreContext(); // If the blank node was the subject, continue reading the predicate if (this._object === null) // If the blank node was empty, it could be a named graph label return empty ? this._readPredicateOrNamedGraph : this._readPredicateAfterBlank; // If the blank node was the object, restore previous context and read punctuation else return this._getContextEndReader(); }, // ### `_readPredicateAfterBlank` reads a predicate after an anonymous blank node _readPredicateAfterBlank: function (token) { switch (token.type) { case '.': case '}': // No predicate is coming if the triple is terminated here this._subject = null; return this._readPunctuation(token); default: return this._readPredicate(token); } }, // ### `_readListItem` reads items from a list _readListItem: function (token) { var item = null, // The item of the list list = null, // The list itself previousList = this._subject, // The previous list that contains this list stack = this._contextStack, // The stack of parent contexts parent = stack[stack.length - 1], // The parent containing the current list next = this._readListItem; // The next function to execute switch (token.type) { case '[': // Stack the current list quad and start a new quad with a blank node as subject this._saveContext('blank', this._graph, list = this._blank(), this.RDF_FIRST, this._subject = item = this._blank()); next = this._readBlankNodeHead; break; case '(': // Stack the current list quad and start a new list this._saveContext('list', this._graph, list = this._blank(), this.RDF_FIRST, this.RDF_NIL); this._subject = null; break; case ')': // Closing the list; restore the parent context this._restoreContext(); // If this list is contained within a parent list, return the membership quad here. // This will be ` rdf:first .`. if (stack.length !== 0 && stack[stack.length - 1].type === 'list') this._emit(this._subject, this._predicate, this._object, this._graph); // Was this list the parent's subject? if (this._predicate === null) { // The next token is the predicate next = this._readPredicate; // No list tail if this was an empty list if (this._subject === this.RDF_NIL) return next; } // The list was in the parent context's object else { next = this._getContextEndReader(); // No list tail if this was an empty list if (this._object === this.RDF_NIL) return next; } // Close the list by making the head nil list = this.RDF_NIL; break; case 'literal': // Regular literal, can still get a datatype or language if (token.prefix.length === 0) { this._literalValue = token.value; next = this._readListItemDataTypeOrLang; } // Pre-datatyped string literal (prefix stores the datatype) else { item = this._literal(token.value, this._namedNode(token.prefix)); next = this._getContextEndReader(); } break; default: if ((item = this._readEntity(token)) === undefined) return; } // Create a new blank node if no item head was assigned yet if (list === null) this._subject = list = this._blank(); // Is this the first element of the list? if (previousList === null) { // This list is either the subject or the object of its parent if (parent.predicate === null) parent.subject = list; else parent.object = list; } else { // Continue the previous list with the current list this._emit(previousList, this.RDF_REST, list, this._graph); } // If an item was read, add it to the list if (item !== null) { // In N3 mode, the item might be a path if (this._n3Mode && (token.type === 'IRI' || token.type === 'prefixed')) { // Create a new context to add the item's path this._saveContext('item', this._graph, list, this.RDF_FIRST, item); this._subject = item, this._predicate = null; // _readPath will restore the context and output the item return this._getPathReader(this._readListItem); } // Output the item this._emit(list, this.RDF_FIRST, item, this._graph); } return next; }, // ### `_readDataTypeOrLang` reads an _optional_ datatype or language _readDataTypeOrLang: function (token) { return this._completeLiteral(token, false); }, // ### `_readListItemDataTypeOrLang` reads an _optional_ datatype or language in a list _readListItemDataTypeOrLang: function (token) { return this._completeLiteral(token, true); }, // ### `_completeLiteral` completes a literal with an optional datatype or language _completeLiteral: function (token, listItem) { switch (token.type) { // Create a datatyped literal case 'type': case 'typeIRI': var datatype = this._readEntity(token); if (datatype === undefined) return; // No datatype means an error occurred this._object = this._literal(this._literalValue, datatype); token = null; break; // Create a language-tagged string case 'langcode': this._object = this._literal(this._literalValue, token.value); token = null; break; // Create a simple string literal default: this._object = this._literal(this._literalValue); } // If this literal was part of a list, write the item // (we could also check the context stack, but passing in a flag is faster) if (listItem) this._emit(this._subject, this.RDF_FIRST, this._object, this._graph); // If the token was consumed, continue with the rest of the input if (token === null) return this._getContextEndReader(); // Otherwise, consume the token now else { this._readCallback = this._getContextEndReader(); return this._readCallback(token); } }, // ### `_readFormulaTail` reads the end of a formula _readFormulaTail: function (token) { if (token.type !== '}') return this._readPunctuation(token); // Store the last quad of the formula if (this._subject !== null) this._emit(this._subject, this._predicate, this._object, this._graph); // Restore the parent context containing this formula this._restoreContext(); // If the formula was the subject, continue reading the predicate. // If the formula was the object, read punctuation. return this._object === null ? this._readPredicate : this._getContextEndReader(); }, // ### `_readPunctuation` reads punctuation between quads or quad parts _readPunctuation: function (token) { var next, subject = this._subject, graph = this._graph, inversePredicate = this._inversePredicate; switch (token.type) { // A closing brace ends a graph case '}': if (this._graph === null) return this._error('Unexpected graph closing', token); if (this._n3Mode) return this._readFormulaTail(token); this._graph = null; // A dot just ends the statement, without sharing anything with the next case '.': this._subject = null; next = this._contextStack.length ? this._readSubject : this._readInTopContext; if (inversePredicate) this._inversePredicate = false; break; // Semicolon means the subject is shared; predicate and object are different case ';': next = this._readPredicate; break; // Comma means both the subject and predicate are shared; the object is different case ',': next = this._readObject; break; default: // An entity means this is a quad (only allowed if not already inside a graph) if (this._supportsQuads && this._graph === null && (graph = this._readEntity(token)) !== undefined) { next = this._readQuadPunctuation; break; } return this._error('Expected punctuation to follow "' + this._object.id + '"', token); } // A quad has been completed now, so return it if (subject !== null) { var predicate = this._predicate, object = this._object; if (!inversePredicate) this._emit(subject, predicate, object, graph); else this._emit(object, predicate, subject, graph); } return next; }, // ### `_readBlankNodePunctuation` reads punctuation in a blank node _readBlankNodePunctuation: function (token) { var next; switch (token.type) { // Semicolon means the subject is shared; predicate and object are different case ';': next = this._readPredicate; break; // Comma means both the subject and predicate are shared; the object is different case ',': next = this._readObject; break; default: return this._error('Expected punctuation to follow "' + this._object.id + '"', token); } // A quad has been completed now, so return it this._emit(this._subject, this._predicate, this._object, this._graph); return next; }, // ### `_readQuadPunctuation` reads punctuation after a quad _readQuadPunctuation: function (token) { if (token.type !== '.') return this._error('Expected dot to follow quad', token); return this._readInTopContext; }, // ### `_readPrefix` reads the prefix of a prefix declaration _readPrefix: function (token) { if (token.type !== 'prefix') return this._error('Expected prefix to follow @prefix', token); this._prefix = token.value; return this._readPrefixIRI; }, // ### `_readPrefixIRI` reads the IRI of a prefix declaration _readPrefixIRI: function (token) { if (token.type !== 'IRI') return this._error('Expected IRI to follow prefix "' + this._prefix + ':"', token); var prefixNode = this._readEntity(token); this._prefixes[this._prefix] = prefixNode.value; this._prefixCallback(this._prefix, prefixNode); return this._readDeclarationPunctuation; }, // ### `_readBaseIRI` reads the IRI of a base declaration _readBaseIRI: function (token) { var iri = token.type === 'IRI' && this._resolveIRI(token.value); if (!iri) return this._error('Expected valid IRI to follow base declaration', token); this._setBase(iri); return this._readDeclarationPunctuation; }, // ### `_readNamedGraphLabel` reads the label of a named graph _readNamedGraphLabel: function (token) { switch (token.type) { case 'IRI': case 'blank': case 'prefixed': return this._readSubject(token), this._readGraph; case '[': return this._readNamedGraphBlankLabel; default: return this._error('Invalid graph label', token); } }, // ### `_readNamedGraphLabel` reads a blank node label of a named graph _readNamedGraphBlankLabel: function (token) { if (token.type !== ']') return this._error('Invalid graph label', token); this._subject = this._blank(); return this._readGraph; }, // ### `_readDeclarationPunctuation` reads the punctuation of a declaration _readDeclarationPunctuation: function (token) { // SPARQL-style declarations don't have punctuation if (this._sparqlStyle) { this._sparqlStyle = false; return this._readInTopContext(token); } if (token.type !== '.') return this._error('Expected declaration to end with a dot', token); return this._readInTopContext; }, // Reads a list of quantified symbols from a @forSome or @forAll statement _readQuantifierList: function (token) { var entity; switch (token.type) { case 'IRI': case 'prefixed': if ((entity = this._readEntity(token, true)) !== undefined) break; default: return this._error('Unexpected ' + token.type, token); } // Without explicit quantifiers, map entities to a quantified entity if (!this._explicitQuantifiers) this._quantified[entity.id] = this._quantifier('b' + blankNodeCount++); // With explicit quantifiers, output the reified quantifier else { // If this is the first item, start a new quantifier list if (this._subject === null) this._emit(this._graph || this.DEFAULTGRAPH, this._predicate, this._subject = this._blank(), this.QUANTIFIERS_GRAPH); // Otherwise, continue the previous list else this._emit(this._subject, this.RDF_REST, this._subject = this._blank(), this.QUANTIFIERS_GRAPH); // Output the list item this._emit(this._subject, this.RDF_FIRST, entity, this.QUANTIFIERS_GRAPH); } return this._readQuantifierPunctuation; }, // Reads punctuation from a @forSome or @forAll statement _readQuantifierPunctuation: function (token) { // Read more quantifiers if (token.type === ',') return this._readQuantifierList; // End of the quantifier list else { // With explicit quantifiers, close the quantifier list if (this._explicitQuantifiers) { this._emit(this._subject, this.RDF_REST, this.RDF_NIL, this.QUANTIFIERS_GRAPH); this._subject = null; } // Read a dot this._readCallback = this._getContextEndReader(); return this._readCallback(token); } }, // ### `_getPathReader` reads a potential path and then resumes with the given function _getPathReader: function (afterPath) { this._afterPath = afterPath; return this._readPath; }, // ### `_readPath` reads a potential path _readPath: function (token) { switch (token.type) { // Forward path case '!': return this._readForwardPath; // Backward path case '^': return this._readBackwardPath; // Not a path; resume reading where we left off default: var stack = this._contextStack, parent = stack.length && stack[stack.length - 1]; // If we were reading a list item, we still need to output it if (parent && parent.type === 'item') { // The list item is the remaining subejct after reading the path var item = this._subject; // Switch back to the context of the list this._restoreContext(); // Output the list item this._emit(this._subject, this.RDF_FIRST, item, this._graph); } return this._afterPath(token); } }, // ### `_readForwardPath` reads a '!' path _readForwardPath: function (token) { var subject, predicate, object = this._blank(); // The next token is the predicate if ((predicate = this._readEntity(token)) === undefined) return; // If we were reading a subject, replace the subject by the path's object if (this._predicate === null) subject = this._subject, this._subject = object; // If we were reading an object, replace the subject by the path's object else subject = this._object, this._object = object; // Emit the path's current quad and read its next section this._emit(subject, predicate, object, this._graph); return this._readPath; }, // ### `_readBackwardPath` reads a '^' path _readBackwardPath: function (token) { var subject = this._blank(), predicate, object; // The next token is the predicate if ((predicate = this._readEntity(token)) === undefined) return; // If we were reading a subject, replace the subject by the path's subject if (this._predicate === null) object = this._subject, this._subject = subject; // If we were reading an object, replace the subject by the path's subject else object = this._object, this._object = subject; // Emit the path's current quad and read its next section this._emit(subject, predicate, object, this._graph); return this._readPath; }, // ### `_getContextEndReader` gets the next reader function at the end of a context _getContextEndReader: function () { var contextStack = this._contextStack; if (!contextStack.length) return this._readPunctuation; switch (contextStack[contextStack.length - 1].type) { case 'blank': return this._readBlankNodeTail; case 'list': return this._readListItem; case 'formula': return this._readFormulaTail; } }, // ### `_emit` sends a quad through the callback _emit: function (subject, predicate, object, graph) { this._callback(null, this._quad(subject, predicate, object, graph || this.DEFAULTGRAPH)); }, // ### `_error` emits an error message through the callback _error: function (message, token) { var err = new Error(message + ' on line ' + token.line + '.'); err.context = { token: token, line: token.line, previousToken: this._lexer.previousToken, }; this._callback(err); this._callback = noop; }, // ### `_resolveIRI` resolves an IRI against the base path _resolveIRI: function (iri) { return /^[a-z][a-z0-9+.-]*:/i.test(iri) ? iri : this._resolveRelativeIRI(iri); }, // ### `_resolveRelativeIRI` resolves an IRI against the base path, // assuming that a base path has been set and that the IRI is indeed relative _resolveRelativeIRI: function (iri) { // An empty relative IRI indicates the base IRI if (!iri.length) return this._base; // Decide resolving strategy based in the first character switch (iri[0]) { // Resolve relative fragment IRIs against the base IRI case '#': return this._base + iri; // Resolve relative query string IRIs by replacing the query string case '?': return this._base.replace(/(?:\?.*)?$/, iri); // Resolve root-relative IRIs at the root of the base IRI case '/': // Resolve scheme-relative IRIs to the scheme return (iri[1] === '/' ? this._baseScheme : this._baseRoot) + this._removeDotSegments(iri); // Resolve all other IRIs at the base IRI's path default: // Relative IRIs cannot contain a colon in the first path segment return (/^[^/:]*:/.test(iri)) ? '' : this._removeDotSegments(this._basePath + iri); } }, // ### `_removeDotSegments` resolves './' and '../' path segments in an IRI as per RFC3986 _removeDotSegments: function (iri) { // Don't modify the IRI if it does not contain any dot segments if (!/(^|\/)\.\.?($|[/#?])/.test(iri)) return iri; // Start with an imaginary slash before the IRI in order to resolve trailing './' and '../' var result = '', length = iri.length, i = -1, pathStart = -1, segmentStart = 0, next = '/'; while (i < length) { switch (next) { // The path starts with the first slash after the authority case ':': if (pathStart < 0) { // Skip two slashes before the authority if (iri[++i] === '/' && iri[++i] === '/') // Skip to slash after the authority while ((pathStart = i + 1) < length && iri[pathStart] !== '/') i = pathStart; } break; // Don't modify a query string or fragment case '?': case '#': i = length; break; // Handle '/.' or '/..' path segments case '/': if (iri[i + 1] === '.') { next = iri[++i + 1]; switch (next) { // Remove a '/.' segment case '/': result += iri.substring(segmentStart, i - 1); segmentStart = i + 1; break; // Remove a trailing '/.' segment case undefined: case '?': case '#': return result + iri.substring(segmentStart, i) + iri.substr(i + 1); // Remove a '/..' segment case '.': next = iri[++i + 1]; if (next === undefined || next === '/' || next === '?' || next === '#') { result += iri.substring(segmentStart, i - 2); // Try to remove the parent path from result if ((segmentStart = result.lastIndexOf('/')) >= pathStart) result = result.substr(0, segmentStart); // Remove a trailing '/..' segment if (next !== '/') return result + '/' + iri.substr(i + 1); segmentStart = i + 1; } } } } next = iri[++i]; } return result + iri.substring(segmentStart); }, // ## Public methods // ### `parse` parses the N3 input and emits each parsed quad through the callback parse: function (input, quadCallback, prefixCallback) { var self = this; // The read callback is the next function to be executed when a token arrives. // We start reading in the top context. this._readCallback = this._readInTopContext; this._sparqlStyle = false; this._prefixes = Object.create(null); this._prefixes._ = this._blankNodePrefix ? this._blankNodePrefix.substr(2) : 'b' + blankNodePrefix++ + '_'; this._prefixCallback = prefixCallback || noop; this._inversePredicate = false; this._quantified = Object.create(null); // Parse synchronously if no quad callback is given if (!quadCallback) { var quads = [], error; this._callback = function (e, t) { e ? (error = e) : t && quads.push(t); }; this._lexer.tokenize(input).every(function (token) { return self._readCallback = self._readCallback(token); }); if (error) throw error; return quads; } // Parse asynchronously otherwise, executing the read callback when a token arrives this._callback = quadCallback; this._lexer.tokenize(input, function (error, token) { if (error !== null) self._callback(error), self._callback = noop; else if (self._readCallback) self._readCallback = self._readCallback(token); }); }, }; // The empty function function noop() {} // Initializes the parser with the given data factory function initDataFactory(parser, factory) { // Set factory methods var namedNode = factory.namedNode; parser._namedNode = namedNode; parser._blankNode = factory.blankNode; parser._literal = factory.literal; parser._variable = factory.variable; parser._quad = factory.quad; parser.DEFAULTGRAPH = factory.defaultGraph(); // Set common named nodes parser.RDF_FIRST = namedNode(namespaces.rdf.first); parser.RDF_REST = namedNode(namespaces.rdf.rest); parser.RDF_NIL = namedNode(namespaces.rdf.nil); parser.N3_FORALL = namedNode(namespaces.r.forAll); parser.N3_FORSOME = namedNode(namespaces.r.forSome); parser.ABBREVIATIONS = { 'a': namedNode(namespaces.rdf.type), '=': namedNode(namespaces.owl.sameAs), '>': namedNode(namespaces.log.implies), }; parser.QUANTIFIERS_GRAPH = namedNode('urn:n3:quantifiers'); } initDataFactory(N3Parser.prototype, DataFactory); // ## Exports module.exports = N3Parser; N3.js-1.0.4/lib/N3Store.js000066400000000000000000000647051343333361000150230ustar00rootroot00000000000000// **N3Store** objects store N3 quads by graph in memory. var DataFactory = require('./N3DataFactory'); var toId = DataFactory.internal.toId, fromId = DataFactory.internal.fromId; // ## Constructor function N3Store(quads, options) { if (!(this instanceof N3Store)) return new N3Store(quads, options); // The number of quads is initially zero this._size = 0; // `_graphs` contains subject, predicate, and object indexes per graph this._graphs = Object.create(null); // `_ids` maps entities such as `http://xmlns.com/foaf/0.1/name` to numbers, // saving memory by using only numbers as keys in `_graphs` this._id = 0; this._ids = Object.create(null); this._ids['><'] = 0; // dummy entry, so the first actual key is non-zero this._entities = Object.create(null); // inverse of `_ids` // `_blankNodeIndex` is the index of the last automatically named blank node this._blankNodeIndex = 0; // Shift parameters if `quads` is not given if (!options && quads && !quads[0]) options = quads, quads = null; options = options || {}; this._factory = options.factory || DataFactory; // Add quads if passed if (quads) this.addQuads(quads); } N3Store.prototype = { // ## Public properties // ### `size` returns the number of quads in the store get size() { // Return the quad count if if was cached var size = this._size; if (size !== null) return size; // Calculate the number of quads by counting to the deepest level size = 0; var graphs = this._graphs, subjects, subject; for (var graphKey in graphs) for (var subjectKey in (subjects = graphs[graphKey].subjects)) for (var predicateKey in (subject = subjects[subjectKey])) size += Object.keys(subject[predicateKey]).length; return this._size = size; }, // ## Private methods // ### `_addToIndex` adds a quad to a three-layered index. // Returns if the index has changed, if the entry did not already exist. _addToIndex: function (index0, key0, key1, key2) { // Create layers as necessary var index1 = index0[key0] || (index0[key0] = {}); var index2 = index1[key1] || (index1[key1] = {}); // Setting the key to _any_ value signals the presence of the quad var existed = key2 in index2; if (!existed) index2[key2] = null; return !existed; }, // ### `_removeFromIndex` removes a quad from a three-layered index _removeFromIndex: function (index0, key0, key1, key2) { // Remove the quad from the index var index1 = index0[key0], index2 = index1[key1], key; delete index2[key2]; // Remove intermediary index layers if they are empty for (key in index2) return; delete index1[key1]; for (key in index1) return; delete index0[key0]; }, // ### `_findInIndex` finds a set of quads in a three-layered index. // The index base is `index0` and the keys at each level are `key0`, `key1`, and `key2`. // Any of these keys can be undefined, which is interpreted as a wildcard. // `name0`, `name1`, and `name2` are the names of the keys at each level, // used when reconstructing the resulting quad // (for instance: _subject_, _predicate_, and _object_). // Finally, `graph` will be the graph of the created quads. // If `callback` is given, each result is passed through it // and iteration halts when it returns truthy for any quad. // If instead `array` is given, each result is added to the array. _findInIndex: function (index0, key0, key1, key2, name0, name1, name2, graph, callback, array) { var tmp, index1, index2, varCount = !key0 + !key1 + !key2, // depending on the number of variables, keys or reverse index are faster entityKeys = varCount > 1 ? Object.keys(this._ids) : this._entities; // If a key is specified, use only that part of index 0. if (key0) (tmp = index0, index0 = {})[key0] = tmp[key0]; for (var value0 in index0) { var entity0 = entityKeys[value0]; if (index1 = index0[value0]) { // If a key is specified, use only that part of index 1. if (key1) (tmp = index1, index1 = {})[key1] = tmp[key1]; for (var value1 in index1) { var entity1 = entityKeys[value1]; if (index2 = index1[value1]) { // If a key is specified, use only that part of index 2, if it exists. var values = key2 ? (key2 in index2 ? [key2] : []) : Object.keys(index2); // Create quads for all items found in index 2. for (var l = 0; l < values.length; l++) { var parts = { subject: null, predicate: null, object: null }; parts[name0] = fromId(entity0, this._factory); parts[name1] = fromId(entity1, this._factory); parts[name2] = fromId(entityKeys[values[l]], this._factory); var quad = this._factory.quad( parts.subject, parts.predicate, parts.object, fromId(graph, this._factory)); if (array) array.push(quad); else if (callback(quad)) return true; } } } } } return array; }, // ### `_loop` executes the callback on all keys of index 0 _loop: function (index0, callback) { for (var key0 in index0) callback(key0); }, // ### `_loopByKey0` executes the callback on all keys of a certain entry in index 0 _loopByKey0: function (index0, key0, callback) { var index1, key1; if (index1 = index0[key0]) { for (key1 in index1) callback(key1); } }, // ### `_loopByKey1` executes the callback on given keys of all entries in index 0 _loopByKey1: function (index0, key1, callback) { var key0, index1; for (key0 in index0) { index1 = index0[key0]; if (index1[key1]) callback(key0); } }, // ### `_loopBy2Keys` executes the callback on given keys of certain entries in index 2 _loopBy2Keys: function (index0, key0, key1, callback) { var index1, index2, key2; if ((index1 = index0[key0]) && (index2 = index1[key1])) { for (key2 in index2) callback(key2); } }, // ### `_countInIndex` counts matching quads in a three-layered index. // The index base is `index0` and the keys at each level are `key0`, `key1`, and `key2`. // Any of these keys can be undefined, which is interpreted as a wildcard. _countInIndex: function (index0, key0, key1, key2) { var count = 0, tmp, index1, index2; // If a key is specified, count only that part of index 0 if (key0) (tmp = index0, index0 = {})[key0] = tmp[key0]; for (var value0 in index0) { if (index1 = index0[value0]) { // If a key is specified, count only that part of index 1 if (key1) (tmp = index1, index1 = {})[key1] = tmp[key1]; for (var value1 in index1) { if (index2 = index1[value1]) { // If a key is specified, count the quad if it exists if (key2) (key2 in index2) && count++; // Otherwise, count all quads else count += Object.keys(index2).length; } } } } return count; }, // ### `_getGraphs` returns an array with the given graph, // or all graphs if the argument is null or undefined. _getGraphs: function (graph) { if (!isString(graph)) return this._graphs; var graphs = {}; graphs[graph] = this._graphs[graph]; return graphs; }, // ### `_uniqueEntities` returns a function that accepts an entity ID // and passes the corresponding entity to callback if it hasn't occurred before. _uniqueEntities: function (callback) { var uniqueIds = Object.create(null), entities = this._entities; return function (id) { if (!(id in uniqueIds)) { uniqueIds[id] = true; callback(fromId(entities[id])); } }; }, // ## Public methods // ### `addQuad` adds a new quad to the store. // Returns if the quad index has changed, if the quad did not already exist. addQuad: function (subject, predicate, object, graph) { // Shift arguments if a quad object is given instead of components if (!predicate) graph = subject.graph, object = subject.object, predicate = subject.predicate, subject = subject.subject; // Convert terms to internal string representation subject = toId(subject); predicate = toId(predicate); object = toId(object); graph = toId(graph); // Find the graph that will contain the triple var graphItem = this._graphs[graph]; // Create the graph if it doesn't exist yet if (!graphItem) { graphItem = this._graphs[graph] = { subjects: {}, predicates: {}, objects: {} }; // Freezing a graph helps subsequent `add` performance, // and properties will never be modified anyway Object.freeze(graphItem); } // Since entities can often be long IRIs, we avoid storing them in every index. // Instead, we have a separate index that maps entities to numbers, // which are then used as keys in the other indexes. var ids = this._ids; var entities = this._entities; subject = ids[subject] || (ids[entities[++this._id] = subject] = this._id); predicate = ids[predicate] || (ids[entities[++this._id] = predicate] = this._id); object = ids[object] || (ids[entities[++this._id] = object] = this._id); var changed = this._addToIndex(graphItem.subjects, subject, predicate, object); this._addToIndex(graphItem.predicates, predicate, object, subject); this._addToIndex(graphItem.objects, object, subject, predicate); // The cached quad count is now invalid this._size = null; return changed; }, // ### `addQuads` adds multiple quads to the store addQuads: function (quads) { for (var i = 0; i < quads.length; i++) this.addQuad(quads[i]); }, // ### `import` adds a stream of quads to the store import: function (stream) { var self = this; stream.on('data', function (quad) { self.addQuad(quad); }); return stream; }, // ### `removeQuad` removes a quad from the store if it exists removeQuad: function (subject, predicate, object, graph) { // Shift arguments if a quad object is given instead of components if (!predicate) graph = subject.graph, object = subject.object, predicate = subject.predicate, subject = subject.subject; // Convert terms to internal string representation subject = toId(subject); predicate = toId(predicate); object = toId(object); graph = toId(graph); // Find internal identifiers for all components // and verify the quad exists. var graphItem, ids = this._ids, graphs = this._graphs, subjects, predicates; if (!(subject = ids[subject]) || !(predicate = ids[predicate]) || !(object = ids[object]) || !(graphItem = graphs[graph]) || !(subjects = graphItem.subjects[subject]) || !(predicates = subjects[predicate]) || !(object in predicates)) return false; // Remove it from all indexes this._removeFromIndex(graphItem.subjects, subject, predicate, object); this._removeFromIndex(graphItem.predicates, predicate, object, subject); this._removeFromIndex(graphItem.objects, object, subject, predicate); if (this._size !== null) this._size--; // Remove the graph if it is empty for (subject in graphItem.subjects) return true; delete graphs[graph]; return true; }, // ### `removeQuads` removes multiple quads from the store removeQuads: function (quads) { for (var i = 0; i < quads.length; i++) this.removeQuad(quads[i]); }, // ### `remove` removes a stream of quads from the store remove: function (stream) { var self = this; stream.on('data', function (quad) { self.removeQuad(quad); }); return stream; }, // ### `getQuads` returns an array of quads matching a pattern. // Setting any field to `undefined` or `null` indicates a wildcard. getQuads: function (subject, predicate, object, graph) { // Convert terms to internal string representation subject = subject && toId(subject); predicate = predicate && toId(predicate); object = object && toId(object); graph = graph && toId(graph); var quads = [], graphs = this._getGraphs(graph), content, ids = this._ids, subjectId, predicateId, objectId; // Translate IRIs to internal index keys. if (isString(subject) && !(subjectId = ids[subject]) || isString(predicate) && !(predicateId = ids[predicate]) || isString(object) && !(objectId = ids[object])) return quads; for (var graphId in graphs) { // Only if the specified graph contains triples, there can be results if (content = graphs[graphId]) { // Choose the optimal index, based on what fields are present if (subjectId) { if (objectId) // If subject and object are given, the object index will be the fastest this._findInIndex(content.objects, objectId, subjectId, predicateId, 'object', 'subject', 'predicate', graphId, null, quads); else // If only subject and possibly predicate are given, the subject index will be the fastest this._findInIndex(content.subjects, subjectId, predicateId, null, 'subject', 'predicate', 'object', graphId, null, quads); } else if (predicateId) // If only predicate and possibly object are given, the predicate index will be the fastest this._findInIndex(content.predicates, predicateId, objectId, null, 'predicate', 'object', 'subject', graphId, null, quads); else if (objectId) // If only object is given, the object index will be the fastest this._findInIndex(content.objects, objectId, null, null, 'object', 'subject', 'predicate', graphId, null, quads); else // If nothing is given, iterate subjects and predicates first this._findInIndex(content.subjects, null, null, null, 'subject', 'predicate', 'object', graphId, null, quads); } } return quads; }, // ### `countQuads` returns the number of quads matching a pattern. // Setting any field to `undefined` or `null` indicates a wildcard. countQuads: function (subject, predicate, object, graph) { // Convert terms to internal string representation subject = subject && toId(subject); predicate = predicate && toId(predicate); object = object && toId(object); graph = graph && toId(graph); var count = 0, graphs = this._getGraphs(graph), content, ids = this._ids, subjectId, predicateId, objectId; // Translate IRIs to internal index keys. if (isString(subject) && !(subjectId = ids[subject]) || isString(predicate) && !(predicateId = ids[predicate]) || isString(object) && !(objectId = ids[object])) return 0; for (var graphId in graphs) { // Only if the specified graph contains triples, there can be results if (content = graphs[graphId]) { // Choose the optimal index, based on what fields are present if (subject) { if (object) // If subject and object are given, the object index will be the fastest count += this._countInIndex(content.objects, objectId, subjectId, predicateId); else // If only subject and possibly predicate are given, the subject index will be the fastest count += this._countInIndex(content.subjects, subjectId, predicateId, objectId); } else if (predicate) { // If only predicate and possibly object are given, the predicate index will be the fastest count += this._countInIndex(content.predicates, predicateId, objectId, subjectId); } else { // If only object is possibly given, the object index will be the fastest count += this._countInIndex(content.objects, objectId, subjectId, predicateId); } } } return count; }, // ### `forEach` executes the callback on all quads. // Setting any field to `undefined` or `null` indicates a wildcard. forEach: function (callback, subject, predicate, object, graph) { this.some(function (quad) { callback(quad); return false; }, subject, predicate, object, graph); }, // ### `every` executes the callback on all quads, // and returns `true` if it returns truthy for all them. // Setting any field to `undefined` or `null` indicates a wildcard. every: function (callback, subject, predicate, object, graph) { var some = false; var every = !this.some(function (quad) { some = true; return !callback(quad); }, subject, predicate, object, graph); return some && every; }, // ### `some` executes the callback on all quads, // and returns `true` if it returns truthy for any of them. // Setting any field to `undefined` or `null` indicates a wildcard. some: function (callback, subject, predicate, object, graph) { // Convert terms to internal string representation subject = subject && toId(subject); predicate = predicate && toId(predicate); object = object && toId(object); graph = graph && toId(graph); var graphs = this._getGraphs(graph), content, ids = this._ids, subjectId, predicateId, objectId; // Translate IRIs to internal index keys. if (isString(subject) && !(subjectId = ids[subject]) || isString(predicate) && !(predicateId = ids[predicate]) || isString(object) && !(objectId = ids[object])) return false; for (var graphId in graphs) { // Only if the specified graph contains triples, there can be results if (content = graphs[graphId]) { // Choose the optimal index, based on what fields are present if (subjectId) { if (objectId) { // If subject and object are given, the object index will be the fastest if (this._findInIndex(content.objects, objectId, subjectId, predicateId, 'object', 'subject', 'predicate', graphId, callback, null)) return true; } else // If only subject and possibly predicate are given, the subject index will be the fastest if (this._findInIndex(content.subjects, subjectId, predicateId, null, 'subject', 'predicate', 'object', graphId, callback, null)) return true; } else if (predicateId) { // If only predicate and possibly object are given, the predicate index will be the fastest if (this._findInIndex(content.predicates, predicateId, objectId, null, 'predicate', 'object', 'subject', graphId, callback, null)) { return true; } } else if (objectId) { // If only object is given, the object index will be the fastest if (this._findInIndex(content.objects, objectId, null, null, 'object', 'subject', 'predicate', graphId, callback, null)) { return true; } } else // If nothing is given, iterate subjects and predicates first if (this._findInIndex(content.subjects, null, null, null, 'subject', 'predicate', 'object', graphId, callback, null)) { return true; } } } return false; }, // ### `getSubjects` returns all subjects that match the pattern. // Setting any field to `undefined` or `null` indicates a wildcard. getSubjects: function (predicate, object, graph) { var results = []; this.forSubjects(function (s) { results.push(s); }, predicate, object, graph); return results; }, // ### `forSubjects` executes the callback on all subjects that match the pattern. // Setting any field to `undefined` or `null` indicates a wildcard. forSubjects: function (callback, predicate, object, graph) { // Convert terms to internal string representation predicate = predicate && toId(predicate); object = object && toId(object); graph = graph && toId(graph); var ids = this._ids, graphs = this._getGraphs(graph), content, predicateId, objectId; callback = this._uniqueEntities(callback); // Translate IRIs to internal index keys. if (isString(predicate) && !(predicateId = ids[predicate]) || isString(object) && !(objectId = ids[object])) return; for (graph in graphs) { // Only if the specified graph contains triples, there can be results if (content = graphs[graph]) { // Choose optimal index based on which fields are wildcards if (predicateId) { if (objectId) // If predicate and object are given, the POS index is best. this._loopBy2Keys(content.predicates, predicateId, objectId, callback); else // If only predicate is given, the SPO index is best. this._loopByKey1(content.subjects, predicateId, callback); } else if (objectId) // If only object is given, the OSP index is best. this._loopByKey0(content.objects, objectId, callback); else // If no params given, iterate all the subjects this._loop(content.subjects, callback); } } }, // ### `getPredicates` returns all predicates that match the pattern. // Setting any field to `undefined` or `null` indicates a wildcard. getPredicates: function (subject, object, graph) { var results = []; this.forPredicates(function (p) { results.push(p); }, subject, object, graph); return results; }, // ### `forPredicates` executes the callback on all predicates that match the pattern. // Setting any field to `undefined` or `null` indicates a wildcard. forPredicates: function (callback, subject, object, graph) { // Convert terms to internal string representation subject = subject && toId(subject); object = object && toId(object); graph = graph && toId(graph); var ids = this._ids, graphs = this._getGraphs(graph), content, subjectId, objectId; callback = this._uniqueEntities(callback); // Translate IRIs to internal index keys. if (isString(subject) && !(subjectId = ids[subject]) || isString(object) && !(objectId = ids[object])) return; for (graph in graphs) { // Only if the specified graph contains triples, there can be results if (content = graphs[graph]) { // Choose optimal index based on which fields are wildcards if (subjectId) { if (objectId) // If subject and object are given, the OSP index is best. this._loopBy2Keys(content.objects, objectId, subjectId, callback); else // If only subject is given, the SPO index is best. this._loopByKey0(content.subjects, subjectId, callback); } else if (objectId) // If only object is given, the POS index is best. this._loopByKey1(content.predicates, objectId, callback); else // If no params given, iterate all the predicates. this._loop(content.predicates, callback); } } }, // ### `getObjects` returns all objects that match the pattern. // Setting any field to `undefined` or `null` indicates a wildcard. getObjects: function (subject, predicate, graph) { var results = []; this.forObjects(function (o) { results.push(o); }, subject, predicate, graph); return results; }, // ### `forObjects` executes the callback on all objects that match the pattern. // Setting any field to `undefined` or `null` indicates a wildcard. forObjects: function (callback, subject, predicate, graph) { // Convert terms to internal string representation subject = subject && toId(subject); predicate = predicate && toId(predicate); graph = graph && toId(graph); var ids = this._ids, graphs = this._getGraphs(graph), content, subjectId, predicateId; callback = this._uniqueEntities(callback); // Translate IRIs to internal index keys. if (isString(subject) && !(subjectId = ids[subject]) || isString(predicate) && !(predicateId = ids[predicate])) return; for (graph in graphs) { // Only if the specified graph contains triples, there can be results if (content = graphs[graph]) { // Choose optimal index based on which fields are wildcards if (subjectId) { if (predicateId) // If subject and predicate are given, the SPO index is best. this._loopBy2Keys(content.subjects, subjectId, predicateId, callback); else // If only subject is given, the OSP index is best. this._loopByKey1(content.objects, subjectId, callback); } else if (predicateId) // If only predicate is given, the POS index is best. this._loopByKey0(content.predicates, predicateId, callback); else // If no params given, iterate all the objects. this._loop(content.objects, callback); } } }, // ### `getGraphs` returns all graphs that match the pattern. // Setting any field to `undefined` or `null` indicates a wildcard. getGraphs: function (subject, predicate, object) { var results = []; this.forGraphs(function (g) { results.push(g); }, subject, predicate, object); return results; }, // ### `forGraphs` executes the callback on all graphs that match the pattern. // Setting any field to `undefined` or `null` indicates a wildcard. forGraphs: function (callback, subject, predicate, object) { for (var graph in this._graphs) { this.some(function (quad) { callback(quad.graph); return true; // Halt iteration of some() }, subject, predicate, object, graph); } }, // ### `createBlankNode` creates a new blank node, returning its name createBlankNode: function (suggestedName) { var name, index; // Generate a name based on the suggested name if (suggestedName) { name = suggestedName = '_:' + suggestedName, index = 1; while (this._ids[name]) name = suggestedName + index++; } // Generate a generic blank node name else { do { name = '_:b' + this._blankNodeIndex++; } while (this._ids[name]); } // Add the blank node to the entities, avoiding the generation of duplicates this._ids[name] = ++this._id; this._entities[this._id] = name; return this._factory.blankNode(name.substr(2)); }, }; // Determines whether the argument is a string function isString(s) { return typeof s === 'string' || s instanceof String; } // ## Exports module.exports = N3Store; N3.js-1.0.4/lib/N3StreamParser.js000066400000000000000000000031371343333361000163270ustar00rootroot00000000000000// **N3StreamParser** parses a text stream into a quad stream. var Transform = require('stream').Transform, util = require('util'), N3Parser = require('./N3Parser.js'); // ## Constructor function N3StreamParser(options) { if (!(this instanceof N3StreamParser)) return new N3StreamParser(options); // Initialize Transform base class Transform.call(this, { decodeStrings: true }); this._readableState.objectMode = true; // Set up parser var self = this, parser = new N3Parser(options), onData, onEnd; // Pass dummy stream to obtain `data` and `end` callbacks parser.parse({ on: function (event, callback) { switch (event) { case 'data': onData = callback; break; case 'end': onEnd = callback; break; } }, }, // Handle quads by pushing them down the pipeline function (error, quad) { error && self.emit('error', error) || quad && self.push(quad); }, // Emit prefixes through the `prefix` event function (prefix, uri) { self.emit('prefix', prefix, uri); }); // Implement Transform methods through parser callbacks this._transform = function (chunk, encoding, done) { onData(chunk); done(); }; this._flush = function (done) { onEnd(); done(); }; } util.inherits(N3StreamParser, Transform); // ### Parses a stream of strings N3StreamParser.prototype.import = function (stream) { var self = this; stream.on('data', function (chunk) { self.write(chunk); }); stream.on('end', function () { self.end(); }); stream.on('error', function (error) { self.emit('error', error); }); return this; }; // ## Exports module.exports = N3StreamParser; N3.js-1.0.4/lib/N3StreamWriter.js000066400000000000000000000026221343333361000163450ustar00rootroot00000000000000// **N3StreamWriter** serializes a quad stream into a text stream. var Transform = require('stream').Transform, util = require('util'), N3Writer = require('./N3Writer.js'); // ## Constructor function N3StreamWriter(options) { if (!(this instanceof N3StreamWriter)) return new N3StreamWriter(options); // Initialize Transform base class Transform.call(this, { encoding: 'utf8' }); this._writableState.objectMode = true; // Set up writer with a dummy stream object var self = this; var writer = this._writer = new N3Writer({ write: function (quad, encoding, callback) { self.push(quad); callback && callback(); }, end: function (callback) { self.push(null); callback && callback(); }, }, options); // Implement Transform methods on top of writer this._transform = function (quad, encoding, done) { writer.addQuad(quad, done); }; this._flush = function (done) { writer.end(done); }; } util.inherits(N3StreamWriter, Transform); // ### Serializes a stream of quads N3StreamWriter.prototype.import = function (stream) { var self = this; stream.on('data', function (quad) { self.write(quad); }); stream.on('end', function () { self.end(); }); stream.on('error', function (error) { self.emit('error', error); }); stream.on('prefix', function (prefix, iri) { self._writer.addPrefix(prefix, iri); }); return this; }; // ## Exports module.exports = N3StreamWriter; N3.js-1.0.4/lib/N3Util.js000066400000000000000000000043751343333361000146410ustar00rootroot00000000000000// **N3Util** provides N3 utility functions. var DataFactory = require('./N3DataFactory'); var N3Util = { // Tests whether the given term represents an IRI isNamedNode: function (term) { return !!term && term.termType === 'NamedNode'; }, // Tests whether the given term represents a blank node isBlankNode: function (term) { return !!term && term.termType === 'BlankNode'; }, // Tests whether the given term represents a literal isLiteral: function (term) { return !!term && term.termType === 'Literal'; }, // Tests whether the given term represents a variable isVariable: function (term) { return !!term && term.termType === 'Variable'; }, // Tests whether the given term represents the default graph isDefaultGraph: function (term) { return !!term && term.termType === 'DefaultGraph'; }, // Tests whether the given quad is in the default graph inDefaultGraph: function (quad) { return N3Util.isDefaultGraph(quad.graph); }, // Creates a function that prepends the given IRI to a local name prefix: function (iri, factory) { return N3Util.prefixes({ '': iri }, factory)(''); }, // Creates a function that allows registering and expanding prefixes prefixes: function (defaultPrefixes, factory) { // Add all of the default prefixes var prefixes = Object.create(null); for (var prefix in defaultPrefixes) processPrefix(prefix, defaultPrefixes[prefix]); // Set the default factory if none was specified factory = factory || DataFactory; // Registers a new prefix (if an IRI was specified) // or retrieves a function that expands an existing prefix (if no IRI was specified) function processPrefix(prefix, iri) { // Create a new prefix if an IRI is specified or the prefix doesn't exist if (typeof iri === 'string') { // Create a function that expands the prefix var cache = Object.create(null); prefixes[prefix] = function (local) { return cache[local] || (cache[local] = factory.namedNode(iri + local)); }; } else if (!(prefix in prefixes)) { throw new Error('Unknown prefix: ' + prefix); } return prefixes[prefix]; } return processPrefix; }, }; // ## Exports module.exports = N3Util; N3.js-1.0.4/lib/N3Writer.js000066400000000000000000000303031343333361000151660ustar00rootroot00000000000000// **N3Writer** writes N3 documents. var namespaces = require('./IRIs'), DataFactory = require('./N3DataFactory'); var DEFAULTGRAPH = DataFactory.defaultGraph(); var rdf = namespaces.rdf, xsd = namespaces.xsd; // Characters in literals that require escaping var escape = /["\\\t\n\r\b\f\u0000-\u0019\ud800-\udbff]/, escapeAll = /["\\\t\n\r\b\f\u0000-\u0019]|[\ud800-\udbff][\udc00-\udfff]/g, escapedCharacters = { '\\': '\\\\', '"': '\\"', '\t': '\\t', '\n': '\\n', '\r': '\\r', '\b': '\\b', '\f': '\\f', }; // ## Constructor function N3Writer(outputStream, options) { if (!(this instanceof N3Writer)) return new N3Writer(outputStream, options); // Shift arguments if the first argument is not a stream if (outputStream && typeof outputStream.write !== 'function') options = outputStream, outputStream = null; options = options || {}; // If no output stream given, send the output as string through the end callback if (!outputStream) { var output = ''; this._outputStream = { write: function (chunk, encoding, done) { output += chunk; done && done(); }, end: function (done) { done && done(null, output); }, }; this._endStream = true; } else { this._outputStream = outputStream; this._endStream = options.end === undefined ? true : !!options.end; } // Initialize writer, depending on the format this._subject = null; if (!(/triple|quad/i).test(options.format)) { this._graph = DEFAULTGRAPH; this._prefixIRIs = Object.create(null); options.prefixes && this.addPrefixes(options.prefixes); } else { this._writeQuad = this._writeQuadLine; } } N3Writer.prototype = { // ## Private methods // ### Whether the current graph is the default graph get _inDefaultGraph() { return DEFAULTGRAPH.equals(this._graph); }, // ### `_write` writes the argument to the output stream _write: function (string, callback) { this._outputStream.write(string, 'utf8', callback); }, // ### `_writeQuad` writes the quad to the output stream _writeQuad: function (subject, predicate, object, graph, done) { try { // Write the graph's label if it has changed if (!graph.equals(this._graph)) { // Close the previous graph and start the new one this._write((this._subject === null ? '' : (this._inDefaultGraph ? '.\n' : '\n}\n')) + (DEFAULTGRAPH.equals(graph) ? '' : this._encodeIriOrBlank(graph) + ' {\n')); this._graph = graph; this._subject = null; } // Don't repeat the subject if it's the same if (subject.equals(this._subject)) { // Don't repeat the predicate if it's the same if (predicate.equals(this._predicate)) this._write(', ' + this._encodeObject(object), done); // Same subject, different predicate else this._write(';\n ' + this._encodePredicate(this._predicate = predicate) + ' ' + this._encodeObject(object), done); } // Different subject; write the whole quad else this._write((this._subject === null ? '' : '.\n') + this._encodeIriOrBlank(this._subject = subject) + ' ' + this._encodePredicate(this._predicate = predicate) + ' ' + this._encodeObject(object), done); } catch (error) { done && done(error); } }, // ### `_writeQuadLine` writes the quad to the output stream as a single line _writeQuadLine: function (subject, predicate, object, graph, done) { // Write the quad without prefixes delete this._prefixMatch; this._write(this.quadToString(subject, predicate, object, graph), done); }, // ### `quadToString` serializes a quad as a string quadToString: function (subject, predicate, object, graph) { return this._encodeIriOrBlank(subject) + ' ' + this._encodeIriOrBlank(predicate) + ' ' + this._encodeObject(object) + (graph && graph.value ? ' ' + this._encodeIriOrBlank(graph) + ' .\n' : ' .\n'); }, // ### `quadsToString` serializes an array of quads as a string quadsToString: function (quads) { return quads.map(function (t) { return this.quadToString(t.subject, t.predicate, t.object, t.graph); }, this).join(''); }, // ### `_encodeIriOrBlank` represents an IRI or blank node _encodeIriOrBlank: function (entity) { // A blank node or list is represented as-is if (entity.termType !== 'NamedNode') return 'id' in entity ? entity.id : '_:' + entity.value; // Escape special characters var iri = entity.value; if (escape.test(iri)) iri = iri.replace(escapeAll, characterReplacer); // Try to represent the IRI as prefixed name var prefixMatch = this._prefixRegex.exec(iri); return !prefixMatch ? '<' + iri + '>' : (!prefixMatch[1] ? iri : this._prefixIRIs[prefixMatch[1]] + prefixMatch[2]); }, // ### `_encodeLiteral` represents a literal _encodeLiteral: function (literal) { // Escape special characters var value = literal.value; if (escape.test(value)) value = value.replace(escapeAll, characterReplacer); // Write the literal, possibly with type or language if (literal.language) return '"' + value + '"@' + literal.language; else if (literal.datatype.value !== xsd.string) return '"' + value + '"^^' + this._encodeIriOrBlank(literal.datatype); else return '"' + value + '"'; }, // ### `_encodePredicate` represents a predicate _encodePredicate: function (predicate) { return predicate.value === rdf.type ? 'a' : this._encodeIriOrBlank(predicate); }, // ### `_encodeObject` represents an object _encodeObject: function (object) { return object.termType === 'Literal' ? this._encodeLiteral(object) : this._encodeIriOrBlank(object); }, // ### `_blockedWrite` replaces `_write` after the writer has been closed _blockedWrite: function () { throw new Error('Cannot write because the writer has been closed.'); }, // ### `addQuad` adds the quad to the output stream addQuad: function (subject, predicate, object, graph, done) { // The quad was given as an object, so shift parameters if (object === undefined) this._writeQuad(subject.subject, subject.predicate, subject.object, subject.graph, predicate); // The optional `graph` parameter was not provided else if (typeof graph === 'function') this._writeQuad(subject, predicate, object, DEFAULTGRAPH, graph); // The `graph` parameter was provided else this._writeQuad(subject, predicate, object, graph || DEFAULTGRAPH, done); }, // ### `addQuads` adds the quads to the output stream addQuads: function (quads) { for (var i = 0; i < quads.length; i++) this.addQuad(quads[i]); }, // ### `addPrefix` adds the prefix to the output stream addPrefix: function (prefix, iri, done) { var prefixes = {}; prefixes[prefix] = iri; this.addPrefixes(prefixes, done); }, // ### `addPrefixes` adds the prefixes to the output stream addPrefixes: function (prefixes, done) { // Add all useful prefixes var prefixIRIs = this._prefixIRIs, hasPrefixes = false; for (var prefix in prefixes) { // Verify whether the prefix can be used and does not exist yet var iri = prefixes[prefix]; if (typeof iri !== 'string') iri = iri.value; if (/[#\/]$/.test(iri) && prefixIRIs[iri] !== (prefix += ':')) { hasPrefixes = true; prefixIRIs[iri] = prefix; // Finish a possible pending quad if (this._subject !== null) { this._write(this._inDefaultGraph ? '.\n' : '\n}\n'); this._subject = null, this._graph = ''; } // Write prefix this._write('@prefix ' + prefix + ' <' + iri + '>.\n'); } } // Recreate the prefix matcher if (hasPrefixes) { var IRIlist = '', prefixList = ''; for (var prefixIRI in prefixIRIs) { IRIlist += IRIlist ? '|' + prefixIRI : prefixIRI; prefixList += (prefixList ? '|' : '') + prefixIRIs[prefixIRI]; } IRIlist = IRIlist.replace(/[\]\/\(\)\*\+\?\.\\\$]/g, '\\$&'); this._prefixRegex = new RegExp('^(?:' + prefixList + ')[^\/]*$|' + '^(' + IRIlist + ')([a-zA-Z][\\-_a-zA-Z0-9]*)$'); } // End a prefix block with a newline this._write(hasPrefixes ? '\n' : '', done); }, // ### `blank` creates a blank node with the given content blank: function (predicate, object) { var children = predicate, child, length; // Empty blank node if (predicate === undefined) children = []; // Blank node passed as blank(Term("predicate"), Term("object")) else if (predicate.termType) children = [{ predicate: predicate, object: object }]; // Blank node passed as blank({ predicate: predicate, object: object }) else if (!('length' in predicate)) children = [predicate]; switch (length = children.length) { // Generate an empty blank node case 0: return new SerializedTerm('[]'); // Generate a non-nested one-triple blank node case 1: child = children[0]; if (!(child.object instanceof SerializedTerm)) return new SerializedTerm('[ ' + this._encodePredicate(child.predicate) + ' ' + this._encodeObject(child.object) + ' ]'); // Generate a multi-triple or nested blank node default: var contents = '['; // Write all triples in order for (var i = 0; i < length; i++) { child = children[i]; // Write only the object is the predicate is the same as the previous if (child.predicate.equals(predicate)) contents += ', ' + this._encodeObject(child.object); // Otherwise, write the predicate and the object else { contents += (i ? ';\n ' : '\n ') + this._encodePredicate(child.predicate) + ' ' + this._encodeObject(child.object); predicate = child.predicate; } } return new SerializedTerm(contents + '\n]'); } }, // ### `list` creates a list node with the given content list: function (elements) { var length = elements && elements.length || 0, contents = new Array(length); for (var i = 0; i < length; i++) contents[i] = this._encodeObject(elements[i]); return new SerializedTerm('(' + contents.join(' ') + ')'); }, // ### `_prefixRegex` matches a prefixed name or IRI that begins with one of the added prefixes _prefixRegex: /$0^/, // ### `end` signals the end of the output stream end: function (done) { // Finish a possible pending quad if (this._subject !== null) { this._write(this._inDefaultGraph ? '.\n' : '\n}\n'); this._subject = null; } // Disallow further writing this._write = this._blockedWrite; // Try to end the underlying stream, ensuring done is called exactly one time var singleDone = done && function (error, result) { singleDone = null, done(error, result); }; if (this._endStream) { try { return this._outputStream.end(singleDone); } catch (error) { /* error closing stream */ } } singleDone && singleDone(); }, }; // Replaces a character by its escaped version function characterReplacer(character) { // Replace a single character by its escaped version var result = escapedCharacters[character]; if (result === undefined) { // Replace a single character with its 4-bit unicode escape sequence if (character.length === 1) { result = character.charCodeAt(0).toString(16); result = '\\u0000'.substr(0, 6 - result.length) + result; } // Replace a surrogate pair with its 8-bit unicode escape sequence else { result = ((character.charCodeAt(0) - 0xD800) * 0x400 + character.charCodeAt(1) + 0x2400).toString(16); result = '\\U00000000'.substr(0, 10 - result.length) + result; } } return result; } // ## Placeholder class to represent already pretty-printed terms function SerializedTerm(value) { this.id = value; } DataFactory.internal.Term.subclass(SerializedTerm); // Pretty-printed nodes are not equal to any other node // (e.g., [] does not equal []) SerializedTerm.prototype.equals = function () { return false; }; // ## Exports module.exports = N3Writer; N3.js-1.0.4/package-lock.json000066400000000000000000004536271343333361000156430ustar00rootroot00000000000000{ "name": "n3", "version": "1.0.4", "lockfileVersion": 1, "requires": true, "dependencies": { "@babel/code-frame": { "version": "7.0.0-beta.49", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.49.tgz", "integrity": "sha1-vs2AVIJzREDJ0TfkbXc0DmTX9Rs=", "dev": true, "requires": { "@babel/highlight": "7.0.0-beta.49" } }, "@babel/generator": { "version": "7.0.0-beta.49", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.0.0-beta.49.tgz", "integrity": "sha1-6c/9qROZaszseTu8JauRvBnQv3o=", "dev": true, "requires": { "@babel/types": "7.0.0-beta.49", "jsesc": "^2.5.1", "lodash": "^4.17.5", "source-map": "^0.5.0", "trim-right": "^1.0.1" } }, "@babel/helper-function-name": { "version": "7.0.0-beta.49", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.49.tgz", "integrity": "sha1-olwRGbnwNSeGcBJuAiXAMEHI3jI=", "dev": true, "requires": { "@babel/helper-get-function-arity": "7.0.0-beta.49", "@babel/template": "7.0.0-beta.49", "@babel/types": "7.0.0-beta.49" } }, "@babel/helper-get-function-arity": { "version": "7.0.0-beta.49", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.49.tgz", "integrity": "sha1-z1Aj8y0q2S0Ic3STnOwJUby1FEE=", "dev": true, "requires": { "@babel/types": "7.0.0-beta.49" } }, "@babel/helper-split-export-declaration": { "version": "7.0.0-beta.49", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-beta.49.tgz", "integrity": "sha1-QNeO2glo0BGxxShm5XRs+yPldUg=", "dev": true, "requires": { "@babel/types": "7.0.0-beta.49" } }, "@babel/highlight": { "version": "7.0.0-beta.49", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.49.tgz", "integrity": "sha1-lr3GtD4TSCASumaRsQGEktOWIsw=", "dev": true, "requires": { "chalk": "^2.0.0", "esutils": "^2.0.2", "js-tokens": "^3.0.0" } }, "@babel/parser": { "version": "7.0.0-beta.49", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.0.0-beta.49.tgz", "integrity": "sha1-lE0MW6KBK7FZ7b0iZ0Ov0mUXm9w=", "dev": true }, "@babel/template": { "version": "7.0.0-beta.49", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.49.tgz", "integrity": "sha1-44q+ghfLl5P0YaUwbXrXRdg+HSc=", "dev": true, "requires": { "@babel/code-frame": "7.0.0-beta.49", "@babel/parser": "7.0.0-beta.49", "@babel/types": "7.0.0-beta.49", "lodash": "^4.17.5" } }, "@babel/traverse": { "version": "7.0.0-beta.49", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.0.0-beta.49.tgz", "integrity": "sha1-TypzaCoYM07WYl0QCo0nMZ98LWg=", "dev": true, "requires": { "@babel/code-frame": "7.0.0-beta.49", "@babel/generator": "7.0.0-beta.49", "@babel/helper-function-name": "7.0.0-beta.49", "@babel/helper-split-export-declaration": "7.0.0-beta.49", "@babel/parser": "7.0.0-beta.49", "@babel/types": "7.0.0-beta.49", "debug": "^3.1.0", "globals": "^11.1.0", "invariant": "^2.2.0", "lodash": "^4.17.5" } }, "@babel/types": { "version": "7.0.0-beta.49", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.49.tgz", "integrity": "sha1-t+Oxw/TUz+Eb34yJ8e/V4WF7h6Y=", "dev": true, "requires": { "esutils": "^2.0.2", "lodash": "^4.17.5", "to-fast-properties": "^2.0.0" } }, "@rdfjs/data-model": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@rdfjs/data-model/-/data-model-1.1.1.tgz", "integrity": "sha512-4jb1zc77f27u/MLVhpE/zHR1uvdH4XElXG63rJP/kVnvKoHtVfyJSEqN9oRLANgqHJ9SNwKj9FXeNFZ4+GGfiw==", "dev": true, "requires": { "@types/rdf-js": "^2.0.1" } }, "@types/node": { "version": "10.12.12", "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.12.tgz", "integrity": "sha512-Pr+6JRiKkfsFvmU/LK68oBRCQeEg36TyAbPhc2xpez24OOZZCuoIhWGTd39VZy6nGafSbxzGouFPTFD/rR1A0A==", "dev": true }, "@types/rdf-js": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/rdf-js/-/rdf-js-2.0.1.tgz", "integrity": "sha512-x3Qct8TPilUos4znM1gANmtTvjOFdDRItmpEM2Nu9QgAx258FN9k22OvOu2TmPzOlx8a1FLdEW3o33UXHQt5ow==", "dev": true, "requires": { "@types/node": "*" } }, "JSONStream": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", "dev": true, "requires": { "jsonparse": "^1.2.0", "through": ">=2.2.7 <3" } }, "acorn": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", "dev": true }, "acorn-jsx": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", "dev": true, "requires": { "acorn": "^3.0.4" } }, "ajv": { "version": "5.5.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", "dev": true, "requires": { "co": "^4.6.0", "fast-deep-equal": "^1.0.0", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.3.0" } }, "ajv-keywords": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", "dev": true }, "ansi-escapes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz", "integrity": "sha512-O/klc27mWNUigtv0F8NJWbLF00OcegQalkqKURWdosW08YZKi4m6CnSUSvIZG1otNJbTWhN01Hhz389DW7mvDQ==", "dev": true }, "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, "ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "dev": true }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "requires": { "sprintf-js": "~1.0.2" } }, "array-union": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", "dev": true, "requires": { "array-uniq": "^1.0.1" } }, "array-uniq": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", "dev": true }, "arrayify-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/arrayify-stream/-/arrayify-stream-1.0.0.tgz", "integrity": "sha512-RP80ep76Lbew2wWN5ogrl2NluTnBVYYh2K3NNCcWfcmmUB7nBcNBctiJeEZAixp3I1vQ9H88iHZ9MbHSdkuupQ==", "dev": true }, "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "dev": true }, "assertion-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true }, "babel-code-frame": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", "dev": true, "requires": { "chalk": "^1.1.3", "esutils": "^2.0.2", "js-tokens": "^3.0.2" }, "dependencies": { "chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { "ansi-styles": "^2.2.1", "escape-string-regexp": "^1.0.2", "has-ansi": "^2.0.0", "strip-ansi": "^3.0.0", "supports-color": "^2.0.0" } }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { "ansi-regex": "^2.0.0" } } } }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, "buffer-from": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.0.0.tgz", "integrity": "sha512-83apNb8KK0Se60UE1+4Ukbe3HbfELJ6UlI4ldtOGs7So4KD26orJM8hIY9lxdzP+UpItH1Yh/Y8GUvNFWFFRxA==", "dev": true }, "caller-path": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", "dev": true, "requires": { "callsites": "^0.2.0" } }, "callsites": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", "dev": true }, "chai": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz", "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", "dev": true, "requires": { "assertion-error": "^1.0.1", "check-error": "^1.0.1", "deep-eql": "^3.0.0", "get-func-name": "^2.0.0", "pathval": "^1.0.0", "type-detect": "^4.0.0" } }, "chai-things": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/chai-things/-/chai-things-0.2.0.tgz", "integrity": "sha1-xVEoN4+bs5nplPAAUhUZhO1uvnA=", "dev": true }, "chalk": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" }, "dependencies": { "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { "color-convert": "^1.9.0" } }, "supports-color": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", "dev": true, "requires": { "has-flag": "^3.0.0" } } } }, "chardet": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", "dev": true }, "check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", "dev": true }, "circular-json": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", "dev": true }, "cli-cursor": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", "dev": true, "requires": { "restore-cursor": "^2.0.0" } }, "cli-width": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", "dev": true }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", "dev": true }, "color-convert": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", "dev": true, "requires": { "color-name": "^1.1.1" } }, "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, "colors": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.1.tgz", "integrity": "sha512-s8+wktIuDSLffCywiwSxQOMqtPxML11a/dtHE17tMn4B1MSWw/C22EKf7M2KGUBcDaVFEGT+S8N02geDXeuNKg==", "dev": true }, "commander": { "version": "2.15.1", "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", "dev": true }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, "concat-stream": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", "dev": true, "requires": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^2.2.2", "typedarray": "^0.0.6" } }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true }, "cross-spawn": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", "dev": true, "requires": { "lru-cache": "^4.0.1", "shebang-command": "^1.2.0", "which": "^1.2.9" } }, "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { "ms": "2.0.0" } }, "deep-eql": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", "dev": true, "requires": { "type-detect": "^4.0.0" } }, "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, "del": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", "dev": true, "requires": { "globby": "^5.0.0", "is-path-cwd": "^1.0.0", "is-path-in-cwd": "^1.0.0", "object-assign": "^4.0.1", "pify": "^2.0.0", "pinkie-promise": "^2.0.0", "rimraf": "^2.2.8" } }, "diff": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", "dev": true }, "docco": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/docco/-/docco-0.8.0.tgz", "integrity": "sha512-QcWBDnnGaT+rgC0wqynznXv0/4hd6nAFdWNs2fN4FvkH2yAnCYVeRU7GIZXNCeUQ955Lufq+TmZcSXiBa1cGQQ==", "dev": true, "requires": { "commander": ">= 0.5.2", "fs-extra": ">= 0.6.0", "highlight.js": ">= 8.0.x", "marked": ">= 0.2.7", "underscore": ">= 1.0.0" } }, "doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "requires": { "esutils": "^2.0.2" } }, "encoding": { "version": "0.1.12", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", "dev": true, "requires": { "iconv-lite": "~0.4.13" } }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, "eslint": { "version": "4.19.1", "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz", "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", "dev": true, "requires": { "ajv": "^5.3.0", "babel-code-frame": "^6.22.0", "chalk": "^2.1.0", "concat-stream": "^1.6.0", "cross-spawn": "^5.1.0", "debug": "^3.1.0", "doctrine": "^2.1.0", "eslint-scope": "^3.7.1", "eslint-visitor-keys": "^1.0.0", "espree": "^3.5.4", "esquery": "^1.0.0", "esutils": "^2.0.2", "file-entry-cache": "^2.0.0", "functional-red-black-tree": "^1.0.1", "glob": "^7.1.2", "globals": "^11.0.1", "ignore": "^3.3.3", "imurmurhash": "^0.1.4", "inquirer": "^3.0.6", "is-resolvable": "^1.0.0", "js-yaml": "^3.9.1", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.3.0", "lodash": "^4.17.4", "minimatch": "^3.0.2", "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", "optionator": "^0.8.2", "path-is-inside": "^1.0.2", "pluralize": "^7.0.0", "progress": "^2.0.0", "regexpp": "^1.0.1", "require-uncached": "^1.0.3", "semver": "^5.3.0", "strip-ansi": "^4.0.0", "strip-json-comments": "~2.0.1", "table": "4.0.2", "text-table": "~0.2.0" } }, "eslint-scope": { "version": "3.7.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", "dev": true, "requires": { "esrecurse": "^4.1.0", "estraverse": "^4.1.1" } }, "eslint-visitor-keys": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", "dev": true }, "espree": { "version": "3.5.4", "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", "dev": true, "requires": { "acorn": "^5.5.0", "acorn-jsx": "^3.0.0" }, "dependencies": { "acorn": { "version": "5.5.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.3.tgz", "integrity": "sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ==", "dev": true } } }, "esprima": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", "dev": true }, "esquery": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", "dev": true, "requires": { "estraverse": "^4.0.0" } }, "esrecurse": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", "dev": true, "requires": { "estraverse": "^4.1.0" } }, "estraverse": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", "dev": true }, "esutils": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", "dev": true }, "external-editor": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.1.0.tgz", "integrity": "sha512-E44iT5QVOUJBKij4IIV3uvxuNlbKS38Tw1HiupxEIHPv9qtC2PrDYohbXV5U+1jnfIXttny8gUhj+oZvflFlzA==", "dev": true, "requires": { "chardet": "^0.4.0", "iconv-lite": "^0.4.17", "tmp": "^0.0.33" } }, "fast-deep-equal": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", "dev": true }, "fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", "dev": true }, "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, "figures": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", "dev": true, "requires": { "escape-string-regexp": "^1.0.5" } }, "file-entry-cache": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", "dev": true, "requires": { "flat-cache": "^1.2.1", "object-assign": "^4.0.1" } }, "flat-cache": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", "dev": true, "requires": { "circular-json": "^0.3.1", "del": "^2.0.2", "graceful-fs": "^4.1.2", "write": "^0.2.1" } }, "fs-extra": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-6.0.1.tgz", "integrity": "sha512-GnyIkKhhzXZUWFCaJzvyDLEEgDkPfb4/TPvJCJVuS8MWZgoSsErf++QpiAlDnKFcqhRlm+tIOcencCjyJE6ZCA==", "dev": true, "requires": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, "get-func-name": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", "dev": true }, "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "globals": { "version": "11.3.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.3.0.tgz", "integrity": "sha512-kkpcKNlmQan9Z5ZmgqKH/SMbSmjxQ7QjyNqfXVc8VJcoBV2UEg+sxQD15GQofGRh2hfpwUb70VC31DR7Rq5Hdw==", "dev": true }, "globby": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", "dev": true, "requires": { "array-union": "^1.0.1", "arrify": "^1.0.0", "glob": "^7.0.3", "object-assign": "^4.0.1", "pify": "^2.0.0", "pinkie-promise": "^2.0.0" } }, "graceful-fs": { "version": "4.1.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", "dev": true }, "growl": { "version": "1.10.3", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", "dev": true }, "has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", "dev": true, "requires": { "ansi-regex": "^2.0.0" } }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, "he": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", "dev": true }, "highlight.js": { "version": "9.12.0", "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.12.0.tgz", "integrity": "sha1-5tnb5Xy+/mB1HwKvM2GVhwyQwB4=", "dev": true }, "iconv-lite": { "version": "0.4.19", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", "dev": true }, "ignore": { "version": "3.3.7", "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==", "dev": true }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" } }, "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true }, "inquirer": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", "dev": true, "requires": { "ansi-escapes": "^3.0.0", "chalk": "^2.0.0", "cli-cursor": "^2.1.0", "cli-width": "^2.0.0", "external-editor": "^2.0.4", "figures": "^2.0.0", "lodash": "^4.3.0", "mute-stream": "0.0.7", "run-async": "^2.2.0", "rx-lite": "^4.0.8", "rx-lite-aggregates": "^4.0.8", "string-width": "^2.1.0", "strip-ansi": "^4.0.0", "through": "^2.3.6" } }, "invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", "dev": true, "requires": { "loose-envify": "^1.0.0" } }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, "is-path-cwd": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", "dev": true }, "is-path-in-cwd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", "dev": true, "requires": { "is-path-inside": "^1.0.0" } }, "is-path-inside": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", "dev": true, "requires": { "path-is-inside": "^1.0.1" } }, "is-promise": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", "dev": true }, "is-resolvable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", "dev": true }, "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", "dev": true }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, "isomorphic-fetch": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", "dev": true, "requires": { "node-fetch": "^1.0.1", "whatwg-fetch": ">=0.10.0" } }, "istanbul-lib-coverage": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.0.tgz", "integrity": "sha512-yMSw5xLIbdaxiVXHk3amfNM2WeBxLrwH/BCyZ9HvA/fylwziAIJOG2rKqWyLqEJqwKT725vxxqidv+SyynnGAA==", "dev": true }, "istanbul-lib-instrument": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-2.2.0.tgz", "integrity": "sha512-ozQGtlIw+/a/F3n6QwWiuuyRAPp64+g2GVsKYsIez0sgIEzkU5ZpL2uZ5pmAzbEJ82anlRaPlOQZzkRXspgJyg==", "dev": true, "requires": { "@babel/generator": "7.0.0-beta.49", "@babel/parser": "7.0.0-beta.49", "@babel/template": "7.0.0-beta.49", "@babel/traverse": "7.0.0-beta.49", "@babel/types": "7.0.0-beta.49", "istanbul-lib-coverage": "^2.0.0", "semver": "^5.5.0" } }, "js-tokens": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", "dev": true }, "js-yaml": { "version": "3.11.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.11.0.tgz", "integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==", "dev": true, "requires": { "argparse": "^1.0.7", "esprima": "^4.0.0" } }, "jsesc": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.1.tgz", "integrity": "sha1-5CGiqOINawgZ3yiQj3glJrlt0f4=", "dev": true }, "json-schema-traverse": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", "dev": true }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, "jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", "dev": true, "requires": { "graceful-fs": "^4.1.6" } }, "jsonld-context-parser": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/jsonld-context-parser/-/jsonld-context-parser-1.0.1.tgz", "integrity": "sha512-jOFJ3E0/Ugd84KrXnxka2qSVJYo/9xWDnS1HK8MRu/yd6/IvkAaDi8RC44W/anRArMzl7b7DVm+ZFf12vkD9yg==", "dev": true, "requires": { "isomorphic-fetch": "^2.2.1" } }, "jsonparse": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", "dev": true }, "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", "dev": true, "requires": { "prelude-ls": "~1.1.2", "type-check": "~0.3.2" } }, "lodash": { "version": "4.17.5", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==", "dev": true }, "lodash.uniqwith": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniqwith/-/lodash.uniqwith-4.5.0.tgz", "integrity": "sha1-egy/ZfQ7WShiWp1NDcVLGMrcfvM=", "dev": true }, "log-symbols": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", "dev": true, "requires": { "chalk": "^2.0.1" } }, "loose-envify": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", "dev": true, "requires": { "js-tokens": "^3.0.0" } }, "lru-cache": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.2.tgz", "integrity": "sha512-wgeVXhrDwAWnIF/yZARsFnMBtdFXOg1b8RIrhilp+0iDYN4mdQcNZElDZ0e4B64BhaxeQ5zN7PMyvu7we1kPeQ==", "dev": true, "requires": { "pseudomap": "^1.0.2", "yallist": "^2.1.2" } }, "marked": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/marked/-/marked-0.4.0.tgz", "integrity": "sha512-tMsdNBgOsrUophCAFQl0XPe6Zqk/uy9gnue+jIIKhykO51hxyu6uNx7zBPy0+y/WKYVZZMspV9YeXLNdKk+iYw==", "dev": true }, "mimic-fn": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", "dev": true }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", "dev": true }, "mkdirp": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, "requires": { "minimist": "0.0.8" } }, "mocha": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.0.4.tgz", "integrity": "sha512-nMOpAPFosU1B4Ix1jdhx5e3q7XO55ic5a8cgYvW27CequcEY+BabS0kUVL1Cw1V5PuVHZWeNRWFLmEPexo79VA==", "dev": true, "requires": { "browser-stdout": "1.3.1", "commander": "2.11.0", "debug": "3.1.0", "diff": "3.5.0", "escape-string-regexp": "1.0.5", "glob": "7.1.2", "growl": "1.10.3", "he": "1.1.1", "mkdirp": "0.5.1", "supports-color": "4.4.0" }, "dependencies": { "commander": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", "dev": true }, "has-flag": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", "dev": true }, "supports-color": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", "dev": true, "requires": { "has-flag": "^2.0.0" } } } }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, "mute-stream": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", "dev": true }, "n3": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/n3/-/n3-1.0.1.tgz", "integrity": "sha512-2suWrEdCpe6BYKcPBEQgGV+BKO9GkgkNpEQ3xC2iSHti4Qb4bxHm3XRFLJP8u1MdBZv3EFs/WaNH34pFBoKm1Q==", "dev": true }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, "node-fetch": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", "dev": true, "requires": { "encoding": "^0.1.11", "is-stream": "^1.0.1" } }, "node-web-streams": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/node-web-streams/-/node-web-streams-0.2.2.tgz", "integrity": "sha1-CH52u+t+jcVmhrJdtOYMX/nbCR8=", "dev": true, "requires": { "is-stream": "^1.1.0", "web-streams-polyfill": "git://github.com/gwicke/web-streams-polyfill.git#42c488428adea1dc0c0245014e4896ad456b1ded" } }, "nyc": { "version": "12.0.2", "resolved": "https://registry.npmjs.org/nyc/-/nyc-12.0.2.tgz", "integrity": "sha1-ikpO1pCWbBHsWH/4fuoMEsl0upk=", "dev": true, "requires": { "archy": "^1.0.0", "arrify": "^1.0.1", "caching-transform": "^1.0.0", "convert-source-map": "^1.5.1", "debug-log": "^1.0.1", "default-require-extensions": "^1.0.0", "find-cache-dir": "^0.1.1", "find-up": "^2.1.0", "foreground-child": "^1.5.3", "glob": "^7.0.6", "istanbul-lib-coverage": "^1.2.0", "istanbul-lib-hook": "^1.1.0", "istanbul-lib-instrument": "^2.1.0", "istanbul-lib-report": "^1.1.3", "istanbul-lib-source-maps": "^1.2.5", "istanbul-reports": "^1.4.1", "md5-hex": "^1.2.0", "merge-source-map": "^1.1.0", "micromatch": "^3.1.10", "mkdirp": "^0.5.0", "resolve-from": "^2.0.0", "rimraf": "^2.6.2", "signal-exit": "^3.0.1", "spawn-wrap": "^1.4.2", "test-exclude": "^4.2.0", "yargs": "11.1.0", "yargs-parser": "^8.0.0" }, "dependencies": { "align-text": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", "dev": true, "requires": { "kind-of": "^3.0.2", "longest": "^1.0.1", "repeat-string": "^1.5.2" } }, "amdefine": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", "dev": true }, "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, "append-transform": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-0.4.0.tgz", "integrity": "sha1-126/jKlNJ24keja61EpLdKthGZE=", "dev": true, "requires": { "default-require-extensions": "^1.0.0" } }, "archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", "dev": true }, "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", "dev": true }, "arr-flatten": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", "dev": true }, "arr-union": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", "dev": true }, "array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "dev": true }, "assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", "dev": true }, "async": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", "dev": true }, "atob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.1.tgz", "integrity": "sha1-ri1acpR38onWDdf5amMUoi3Wwio=", "dev": true }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, "base": { "version": "0.11.2", "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "dev": true, "requires": { "cache-base": "^1.0.1", "class-utils": "^0.3.5", "component-emitter": "^1.2.1", "define-property": "^1.0.0", "isobject": "^3.0.1", "mixin-deep": "^1.2.0", "pascalcase": "^0.1.1" }, "dependencies": { "define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { "is-descriptor": "^1.0.0" } }, "is-accessor-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=", "dev": true, "requires": { "kind-of": "^6.0.0" } }, "is-data-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=", "dev": true, "requires": { "kind-of": "^6.0.0" } }, "is-descriptor": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=", "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", "kind-of": "^6.0.2" } }, "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", "integrity": "sha1-ARRrNqYhjmTljzqNZt5df8b20FE=", "dev": true } } }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "braces": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", "integrity": "sha1-WXn9PxTNUxVl5fot8av/8d+u5yk=", "dev": true, "requires": { "arr-flatten": "^1.1.0", "array-unique": "^0.3.2", "extend-shallow": "^2.0.1", "fill-range": "^4.0.0", "isobject": "^3.0.1", "repeat-element": "^1.1.2", "snapdragon": "^0.8.1", "snapdragon-node": "^2.0.1", "split-string": "^3.0.2", "to-regex": "^3.0.1" }, "dependencies": { "extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { "is-extendable": "^0.1.0" } } } }, "builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", "dev": true }, "cache-base": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", "dev": true, "requires": { "collection-visit": "^1.0.0", "component-emitter": "^1.2.1", "get-value": "^2.0.6", "has-value": "^1.0.0", "isobject": "^3.0.1", "set-value": "^2.0.0", "to-object-path": "^0.3.0", "union-value": "^1.0.0", "unset-value": "^1.0.0" } }, "caching-transform": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-1.0.1.tgz", "integrity": "sha1-bb2y8g+Nj7znnz6U6dF0Lc31wKE=", "dev": true, "requires": { "md5-hex": "^1.2.0", "mkdirp": "^0.5.1", "write-file-atomic": "^1.1.4" } }, "camelcase": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", "dev": true, "optional": true }, "center-align": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", "dev": true, "optional": true, "requires": { "align-text": "^0.1.3", "lazy-cache": "^1.0.3" } }, "class-utils": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", "dev": true, "requires": { "arr-union": "^3.1.0", "define-property": "^0.2.5", "isobject": "^3.0.0", "static-extend": "^0.1.1" }, "dependencies": { "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { "is-descriptor": "^0.1.0" } } } }, "cliui": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", "dev": true, "optional": true, "requires": { "center-align": "^0.1.1", "right-align": "^0.1.1", "wordwrap": "0.0.2" }, "dependencies": { "wordwrap": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", "dev": true, "optional": true } } }, "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true }, "collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", "dev": true, "requires": { "map-visit": "^1.0.0", "object-visit": "^1.0.0" } }, "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, "component-emitter": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", "dev": true }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, "convert-source-map": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", "dev": true }, "copy-descriptor": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", "dev": true }, "cross-spawn": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", "dev": true, "requires": { "lru-cache": "^4.0.1", "which": "^1.2.9" } }, "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", "dev": true, "requires": { "ms": "2.0.0" } }, "debug-log": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/debug-log/-/debug-log-1.0.1.tgz", "integrity": "sha1-IwdjLUwEOCuN+KMvcLiVBG1SdF8=", "dev": true }, "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, "decode-uri-component": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", "dev": true }, "default-require-extensions": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-1.0.0.tgz", "integrity": "sha1-836hXT4T/9m0N9M+GnW1+5eHTLg=", "dev": true, "requires": { "strip-bom": "^2.0.0" } }, "define-property": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "dev": true, "requires": { "is-descriptor": "^1.0.2", "isobject": "^3.0.1" }, "dependencies": { "is-accessor-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=", "dev": true, "requires": { "kind-of": "^6.0.0" } }, "is-data-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=", "dev": true, "requires": { "kind-of": "^6.0.0" } }, "is-descriptor": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=", "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", "kind-of": "^6.0.2" } }, "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", "integrity": "sha1-ARRrNqYhjmTljzqNZt5df8b20FE=", "dev": true } } }, "error-ex": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", "dev": true, "requires": { "is-arrayish": "^0.2.1" } }, "execa": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", "dev": true, "requires": { "cross-spawn": "^5.0.1", "get-stream": "^3.0.0", "is-stream": "^1.1.0", "npm-run-path": "^2.0.0", "p-finally": "^1.0.0", "signal-exit": "^3.0.0", "strip-eof": "^1.0.0" }, "dependencies": { "cross-spawn": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", "dev": true, "requires": { "lru-cache": "^4.0.1", "shebang-command": "^1.2.0", "which": "^1.2.9" } } } }, "expand-brackets": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "dev": true, "requires": { "debug": "^2.3.3", "define-property": "^0.2.5", "extend-shallow": "^2.0.1", "posix-character-classes": "^0.1.0", "regex-not": "^1.0.0", "snapdragon": "^0.8.1", "to-regex": "^3.0.1" }, "dependencies": { "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "dev": true, "requires": { "ms": "2.0.0" } }, "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { "is-descriptor": "^0.1.0" } }, "extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { "is-extendable": "^0.1.0" } } } }, "extend-shallow": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", "dev": true, "requires": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" }, "dependencies": { "is-extendable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "requires": { "is-plain-object": "^2.0.4" } } } }, "extglob": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", "integrity": "sha1-rQD+TcYSqSMuhxhxHcXLWrAoVUM=", "dev": true, "requires": { "array-unique": "^0.3.2", "define-property": "^1.0.0", "expand-brackets": "^2.1.4", "extend-shallow": "^2.0.1", "fragment-cache": "^0.2.1", "regex-not": "^1.0.0", "snapdragon": "^0.8.1", "to-regex": "^3.0.1" }, "dependencies": { "define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { "is-descriptor": "^1.0.0" } }, "extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { "is-extendable": "^0.1.0" } }, "is-accessor-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=", "dev": true, "requires": { "kind-of": "^6.0.0" } }, "is-data-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=", "dev": true, "requires": { "kind-of": "^6.0.0" } }, "is-descriptor": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=", "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", "kind-of": "^6.0.2" } }, "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", "integrity": "sha1-ARRrNqYhjmTljzqNZt5df8b20FE=", "dev": true } } }, "fill-range": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, "requires": { "extend-shallow": "^2.0.1", "is-number": "^3.0.0", "repeat-string": "^1.6.1", "to-regex-range": "^2.1.0" }, "dependencies": { "extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { "is-extendable": "^0.1.0" } } } }, "find-cache-dir": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-0.1.1.tgz", "integrity": "sha1-yN765XyKUqinhPnjHFfHQumToLk=", "dev": true, "requires": { "commondir": "^1.0.1", "mkdirp": "^0.5.1", "pkg-dir": "^1.0.0" } }, "find-up": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "dev": true, "requires": { "locate-path": "^2.0.0" } }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", "dev": true }, "foreground-child": { "version": "1.5.6", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=", "dev": true, "requires": { "cross-spawn": "^4", "signal-exit": "^3.0.0" } }, "fragment-cache": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", "dev": true, "requires": { "map-cache": "^0.2.2" } }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, "get-caller-file": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", "dev": true }, "get-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", "dev": true }, "get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", "dev": true }, "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "graceful-fs": { "version": "4.1.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", "dev": true }, "handlebars": { "version": "4.0.11", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.11.tgz", "integrity": "sha1-Ywo13+ApS8KB7a5v/F0yn8eYLcw=", "dev": true, "requires": { "async": "^1.4.0", "optimist": "^0.6.1", "source-map": "^0.4.4", "uglify-js": "^2.6" }, "dependencies": { "source-map": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", "dev": true, "requires": { "amdefine": ">=0.0.4" } } } }, "has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", "dev": true, "requires": { "get-value": "^2.0.6", "has-values": "^1.0.0", "isobject": "^3.0.0" } }, "has-values": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", "dev": true, "requires": { "is-number": "^3.0.0", "kind-of": "^4.0.0" }, "dependencies": { "kind-of": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, "requires": { "is-buffer": "^1.1.5" } } } }, "hosted-git-info": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.6.0.tgz", "integrity": "sha512-lIbgIIQA3lz5XaB6vxakj6sDHADJiZadYEJB+FgA+C4nubM1NwcuvUr9EJPmnH1skZqpqUzWborWo8EIUi0Sdw==", "dev": true }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" } }, "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true }, "invert-kv": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", "dev": true }, "is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { "kind-of": "^3.0.2" } }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, "is-builtin-module": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", "dev": true, "requires": { "builtin-modules": "^1.0.0" } }, "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { "kind-of": "^3.0.2" } }, "is-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha1-Nm2CQN3kh8pRgjsaufB6EKeCUco=", "dev": true, "requires": { "is-accessor-descriptor": "^0.1.6", "is-data-descriptor": "^0.1.4", "kind-of": "^5.0.0" }, "dependencies": { "kind-of": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", "integrity": "sha1-cpyR4thXt6QZofmqZWhcTDP1hF0=", "dev": true } } }, "is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", "dev": true }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, "is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { "kind-of": "^3.0.2" } }, "is-odd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-2.0.0.tgz", "integrity": "sha512-OTiixgpZAT1M4NHgS5IguFp/Vz2VI3U7Goh4/HA1adtwyLtSBrxYlcSYkhpAE07s4fKEcjrFxyvtQBND4vFQyQ==", "dev": true, "requires": { "is-number": "^4.0.0" }, "dependencies": { "is-number": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", "dev": true } } }, "is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, "requires": { "isobject": "^3.0.1" } }, "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", "dev": true }, "is-utf8": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", "dev": true }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true }, "istanbul-lib-coverage": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.0.tgz", "integrity": "sha512-GvgM/uXRwm+gLlvkWHTjDAvwynZkL9ns15calTrmhGgowlwJBbWMYzWbKqE2DT6JDP1AFXKa+Zi0EkqNCUqY0A==", "dev": true }, "istanbul-lib-hook": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.1.0.tgz", "integrity": "sha512-U3qEgwVDUerZ0bt8cfl3dSP3S6opBoOtk3ROO5f2EfBr/SRiD9FQqzwaZBqFORu8W7O0EXpai+k7kxHK13beRg==", "dev": true, "requires": { "append-transform": "^0.4.0" } }, "istanbul-lib-report": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.3.tgz", "integrity": "sha512-D4jVbMDtT2dPmloPJS/rmeP626N5Pr3Rp+SovrPn1+zPChGHcggd/0sL29jnbm4oK9W0wHjCRsdch9oLd7cm6g==", "dev": true, "requires": { "istanbul-lib-coverage": "^1.1.2", "mkdirp": "^0.5.1", "path-parse": "^1.0.5", "supports-color": "^3.1.2" }, "dependencies": { "has-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", "dev": true }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", "dev": true, "requires": { "has-flag": "^1.0.0" } } } }, "istanbul-lib-source-maps": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.5.tgz", "integrity": "sha1-/+a+Tnq4bTYD5CkNVJkLFFBvybE=", "dev": true, "requires": { "debug": "^3.1.0", "istanbul-lib-coverage": "^1.2.0", "mkdirp": "^0.5.1", "rimraf": "^2.6.1", "source-map": "^0.5.3" } }, "istanbul-reports": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.4.1.tgz", "integrity": "sha1-Ty6OkoqnoF0dpsQn1AmLJlXsczQ=", "dev": true, "requires": { "handlebars": "^4.0.3" } }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { "is-buffer": "^1.1.5" } }, "lazy-cache": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", "dev": true, "optional": true }, "lcid": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", "dev": true, "requires": { "invert-kv": "^1.0.0" } }, "load-json-file": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, "requires": { "graceful-fs": "^4.1.2", "parse-json": "^2.2.0", "pify": "^2.0.0", "pinkie-promise": "^2.0.0", "strip-bom": "^2.0.0" } }, "locate-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", "dev": true, "requires": { "p-locate": "^2.0.0", "path-exists": "^3.0.0" }, "dependencies": { "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true } } }, "longest": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", "dev": true }, "lru-cache": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", "integrity": "sha1-oRdc80lt/IQ2wVbDNLSVWZK85pw=", "dev": true, "requires": { "pseudomap": "^1.0.2", "yallist": "^2.1.2" } }, "map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", "dev": true }, "map-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", "dev": true, "requires": { "object-visit": "^1.0.0" } }, "md5-hex": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-1.3.0.tgz", "integrity": "sha1-0sSv6YPENwZiF5uMrRRSGRNQRsQ=", "dev": true, "requires": { "md5-o-matic": "^0.1.1" } }, "md5-o-matic": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/md5-o-matic/-/md5-o-matic-0.1.1.tgz", "integrity": "sha1-givM1l4RfFFPqxdrJZRdVBAKA8M=", "dev": true }, "mem": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", "dev": true, "requires": { "mimic-fn": "^1.0.0" } }, "merge-source-map": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", "dev": true, "requires": { "source-map": "^0.6.1" }, "dependencies": { "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true } } }, "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", "integrity": "sha1-cIWbyVyYQJUvNZoGij/En57PrCM=", "dev": true, "requires": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", "braces": "^2.3.1", "define-property": "^2.0.2", "extend-shallow": "^3.0.2", "extglob": "^2.0.4", "fragment-cache": "^0.2.1", "kind-of": "^6.0.2", "nanomatch": "^1.2.9", "object.pick": "^1.3.0", "regex-not": "^1.0.0", "snapdragon": "^0.8.1", "to-regex": "^3.0.2" }, "dependencies": { "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", "integrity": "sha1-ARRrNqYhjmTljzqNZt5df8b20FE=", "dev": true } } }, "mimic-fn": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", "dev": true }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", "dev": true }, "mixin-deep": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", "dev": true, "requires": { "for-in": "^1.0.2", "is-extendable": "^1.0.1" }, "dependencies": { "is-extendable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "requires": { "is-plain-object": "^2.0.4" } } } }, "mkdirp": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, "requires": { "minimist": "0.0.8" } }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, "nanomatch": { "version": "1.2.9", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz", "integrity": "sha512-n8R9bS8yQ6eSXaV6jHUpKzD8gLsin02w1HSFiegwrs9E098Ylhw5jdyKPaYqvHknHaSCKTPp7C8dGCQ0q9koXA==", "dev": true, "requires": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", "define-property": "^2.0.2", "extend-shallow": "^3.0.2", "fragment-cache": "^0.2.1", "is-odd": "^2.0.0", "is-windows": "^1.0.2", "kind-of": "^6.0.2", "object.pick": "^1.3.0", "regex-not": "^1.0.0", "snapdragon": "^0.8.1", "to-regex": "^3.0.1" }, "dependencies": { "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", "dev": true } } }, "normalize-package-data": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", "dev": true, "requires": { "hosted-git-info": "^2.1.4", "is-builtin-module": "^1.0.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" } }, "npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", "dev": true, "requires": { "path-key": "^2.0.0" } }, "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", "dev": true }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true }, "object-copy": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", "dev": true, "requires": { "copy-descriptor": "^0.1.0", "define-property": "^0.2.5", "kind-of": "^3.0.3" }, "dependencies": { "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { "is-descriptor": "^0.1.0" } } } }, "object-visit": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", "dev": true, "requires": { "isobject": "^3.0.0" } }, "object.pick": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", "dev": true, "requires": { "isobject": "^3.0.1" } }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "requires": { "wrappy": "1" } }, "optimist": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", "dev": true, "requires": { "minimist": "~0.0.1", "wordwrap": "~0.0.2" } }, "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true }, "os-locale": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", "dev": true, "requires": { "execa": "^0.7.0", "lcid": "^1.0.0", "mem": "^1.1.0" } }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", "dev": true }, "p-limit": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz", "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==", "dev": true, "requires": { "p-try": "^1.0.0" } }, "p-locate": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", "dev": true, "requires": { "p-limit": "^1.1.0" } }, "p-try": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", "dev": true }, "parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "dev": true, "requires": { "error-ex": "^1.2.0" } }, "pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", "dev": true }, "path-exists": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "dev": true, "requires": { "pinkie-promise": "^2.0.0" } }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", "dev": true }, "path-parse": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", "dev": true }, "path-type": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", "dev": true, "requires": { "graceful-fs": "^4.1.2", "pify": "^2.0.0", "pinkie-promise": "^2.0.0" } }, "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true }, "pinkie": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", "dev": true }, "pinkie-promise": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", "dev": true, "requires": { "pinkie": "^2.0.0" } }, "pkg-dir": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", "dev": true, "requires": { "find-up": "^1.0.0" }, "dependencies": { "find-up": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true, "requires": { "path-exists": "^2.0.0", "pinkie-promise": "^2.0.0" } } } }, "posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", "dev": true }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", "dev": true }, "read-pkg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", "dev": true, "requires": { "load-json-file": "^1.0.0", "normalize-package-data": "^2.3.2", "path-type": "^1.0.0" } }, "read-pkg-up": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", "dev": true, "requires": { "find-up": "^1.0.0", "read-pkg": "^1.0.0" }, "dependencies": { "find-up": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true, "requires": { "path-exists": "^2.0.0", "pinkie-promise": "^2.0.0" } } } }, "regex-not": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", "dev": true, "requires": { "extend-shallow": "^3.0.2", "safe-regex": "^1.1.0" } }, "repeat-element": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", "dev": true }, "repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", "dev": true }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, "require-main-filename": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", "dev": true }, "resolve-from": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=", "dev": true }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", "dev": true }, "ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "dev": true }, "right-align": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", "dev": true, "optional": true, "requires": { "align-text": "^0.1.1" } }, "rimraf": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", "dev": true, "requires": { "glob": "^7.0.5" } }, "safe-regex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "dev": true, "requires": { "ret": "~0.1.10" } }, "semver": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", "dev": true }, "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, "set-value": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", "dev": true, "requires": { "extend-shallow": "^2.0.1", "is-extendable": "^0.1.1", "is-plain-object": "^2.0.3", "split-string": "^3.0.1" }, "dependencies": { "extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { "is-extendable": "^0.1.0" } } } }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "dev": true, "requires": { "shebang-regex": "^1.0.0" } }, "shebang-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", "dev": true }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true }, "slide": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=", "dev": true }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", "dev": true, "requires": { "base": "^0.11.1", "debug": "^2.2.0", "define-property": "^0.2.5", "extend-shallow": "^2.0.1", "map-cache": "^0.2.2", "source-map": "^0.5.6", "source-map-resolve": "^0.5.0", "use": "^3.1.0" }, "dependencies": { "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "dev": true, "requires": { "ms": "2.0.0" } }, "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { "is-descriptor": "^0.1.0" } }, "extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { "is-extendable": "^0.1.0" } } } }, "snapdragon-node": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", "dev": true, "requires": { "define-property": "^1.0.0", "isobject": "^3.0.0", "snapdragon-util": "^3.0.1" }, "dependencies": { "define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { "is-descriptor": "^1.0.0" } }, "is-accessor-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=", "dev": true, "requires": { "kind-of": "^6.0.0" } }, "is-data-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=", "dev": true, "requires": { "kind-of": "^6.0.0" } }, "is-descriptor": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=", "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", "kind-of": "^6.0.2" } }, "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", "integrity": "sha1-ARRrNqYhjmTljzqNZt5df8b20FE=", "dev": true } } }, "snapdragon-util": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", "dev": true, "requires": { "kind-of": "^3.2.0" } }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, "source-map-resolve": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", "integrity": "sha1-cuLMNAlVQ+Q7LGKyxMENSpBU8lk=", "dev": true, "requires": { "atob": "^2.1.1", "decode-uri-component": "^0.2.0", "resolve-url": "^0.2.1", "source-map-url": "^0.4.0", "urix": "^0.1.0" } }, "source-map-url": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", "dev": true }, "spawn-wrap": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.4.2.tgz", "integrity": "sha512-vMwR3OmmDhnxCVxM8M+xO/FtIp6Ju/mNaDfCMMW7FDcLRTPFWUswec4LXJHTJE2hwTI9O0YBfygu4DalFl7Ylg==", "dev": true, "requires": { "foreground-child": "^1.5.6", "mkdirp": "^0.5.0", "os-homedir": "^1.0.1", "rimraf": "^2.6.2", "signal-exit": "^3.0.2", "which": "^1.3.0" } }, "spdx-correct": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" } }, "spdx-exceptions": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==", "dev": true }, "spdx-expression-parse": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", "dev": true, "requires": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "spdx-license-ids": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==", "dev": true }, "split-string": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", "dev": true, "requires": { "extend-shallow": "^3.0.0" } }, "static-extend": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", "dev": true, "requires": { "define-property": "^0.2.5", "object-copy": "^0.1.0" }, "dependencies": { "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { "is-descriptor": "^0.1.0" } } } }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" } }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { "ansi-regex": "^3.0.0" } }, "strip-bom": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "dev": true, "requires": { "is-utf8": "^0.2.0" } }, "strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", "dev": true }, "test-exclude": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-4.2.1.tgz", "integrity": "sha512-qpqlP/8Zl+sosLxBcVKl9vYy26T9NPalxSzzCP/OY6K7j938ui2oKgo+kRZYfxAeIpLqpbVnsHq1tyV70E4lWQ==", "dev": true, "requires": { "arrify": "^1.0.1", "micromatch": "^3.1.8", "object-assign": "^4.1.0", "read-pkg-up": "^1.0.1", "require-main-filename": "^1.0.1" } }, "to-object-path": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", "dev": true, "requires": { "kind-of": "^3.0.2" } }, "to-regex": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", "dev": true, "requires": { "define-property": "^2.0.2", "extend-shallow": "^3.0.2", "regex-not": "^1.0.2", "safe-regex": "^1.1.0" } }, "to-regex-range": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "dev": true, "requires": { "is-number": "^3.0.0", "repeat-string": "^1.6.1" } }, "uglify-js": { "version": "2.8.29", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", "dev": true, "optional": true, "requires": { "source-map": "~0.5.1", "uglify-to-browserify": "~1.0.0", "yargs": "~3.10.0" }, "dependencies": { "yargs": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", "dev": true, "optional": true, "requires": { "camelcase": "^1.0.2", "cliui": "^2.1.0", "decamelize": "^1.0.0", "window-size": "0.1.0" } } } }, "uglify-to-browserify": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", "dev": true, "optional": true }, "union-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", "dev": true, "requires": { "arr-union": "^3.1.0", "get-value": "^2.0.6", "is-extendable": "^0.1.1", "set-value": "^0.4.3" }, "dependencies": { "extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { "is-extendable": "^0.1.0" } }, "set-value": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", "dev": true, "requires": { "extend-shallow": "^2.0.1", "is-extendable": "^0.1.1", "is-plain-object": "^2.0.1", "to-object-path": "^0.3.0" } } } }, "unset-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", "dev": true, "requires": { "has-value": "^0.3.1", "isobject": "^3.0.0" }, "dependencies": { "has-value": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", "dev": true, "requires": { "get-value": "^2.0.3", "has-values": "^0.1.4", "isobject": "^2.0.0" }, "dependencies": { "isobject": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", "dev": true, "requires": { "isarray": "1.0.0" } } } }, "has-values": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", "dev": true } } }, "urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", "dev": true }, "use": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/use/-/use-3.1.0.tgz", "integrity": "sha512-6UJEQM/L+mzC3ZJNM56Q4DFGLX/evKGRg15UJHGB9X5j5Z3AFbgZvjUh2yq/UJUY4U5dh7Fal++XbNg1uzpRAw==", "dev": true, "requires": { "kind-of": "^6.0.2" }, "dependencies": { "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", "dev": true } } }, "validate-npm-package-license": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz", "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==", "dev": true, "requires": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" } }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha1-pFBD1U9YBTFtqNYvn1CRjT2nCwo=", "dev": true, "requires": { "isexe": "^2.0.0" } }, "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, "window-size": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", "dev": true, "optional": true }, "wordwrap": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", "dev": true }, "wrap-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", "dev": true, "requires": { "string-width": "^1.0.1", "strip-ansi": "^3.0.1" }, "dependencies": { "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, "is-fullwidth-code-point": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, "requires": { "number-is-nan": "^1.0.0" } }, "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", "strip-ansi": "^3.0.0" } }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { "ansi-regex": "^2.0.0" } } } }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, "write-file-atomic": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.3.4.tgz", "integrity": "sha1-+Aek8LHZ6ROuekgRLmzDrxmRtF8=", "dev": true, "requires": { "graceful-fs": "^4.1.11", "imurmurhash": "^0.1.4", "slide": "^1.1.5" } }, "y18n": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", "dev": true }, "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", "dev": true }, "yargs": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", "dev": true, "requires": { "cliui": "^4.0.0", "decamelize": "^1.1.1", "find-up": "^2.1.0", "get-caller-file": "^1.0.1", "os-locale": "^2.0.0", "require-directory": "^2.1.1", "require-main-filename": "^1.0.1", "set-blocking": "^2.0.0", "string-width": "^2.0.0", "which-module": "^2.0.0", "y18n": "^3.2.1", "yargs-parser": "^9.0.2" }, "dependencies": { "camelcase": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", "dev": true }, "cliui": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", "integrity": "sha1-NIQi2+gtgAswIu709qwQvy5NG0k=", "dev": true, "requires": { "string-width": "^2.1.1", "strip-ansi": "^4.0.0", "wrap-ansi": "^2.0.0" } }, "yargs-parser": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz", "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", "dev": true, "requires": { "camelcase": "^4.1.0" } } } }, "yargs-parser": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-8.1.0.tgz", "integrity": "sha512-yP+6QqN8BmrgW2ggLtTbdrOyBNSI7zBa4IykmiV5R1wl1JWNxQvWhMfMdmzIYtKU7oP3OOInY/tl2ov3BDjnJQ==", "dev": true, "requires": { "camelcase": "^4.1.0" }, "dependencies": { "camelcase": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", "dev": true } } } } }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "requires": { "wrappy": "1" } }, "onetime": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", "dev": true, "requires": { "mimic-fn": "^1.0.0" } }, "optionator": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", "dev": true, "requires": { "deep-is": "~0.1.3", "fast-levenshtein": "~2.0.4", "levn": "~0.3.0", "prelude-ls": "~1.1.2", "type-check": "~0.3.2", "wordwrap": "~1.0.0" } }, "os-shim": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/os-shim/-/os-shim-0.1.3.tgz", "integrity": "sha1-a2LDeRz3kJ6jXtRuF2WLtBfLORc=", "dev": true }, "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, "path-is-inside": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", "dev": true }, "pathval": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", "dev": true }, "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true }, "pinkie": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", "dev": true }, "pinkie-promise": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", "dev": true, "requires": { "pinkie": "^2.0.0" } }, "pluralize": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", "dev": true }, "pre-commit": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/pre-commit/-/pre-commit-1.2.2.tgz", "integrity": "sha1-287g7p3nI15X95xW186UZBpp7sY=", "dev": true, "requires": { "cross-spawn": "^5.0.1", "spawn-sync": "^1.0.15", "which": "1.2.x" }, "dependencies": { "which": { "version": "1.2.14", "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", "dev": true, "requires": { "isexe": "^2.0.0" } } } }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, "process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", "dev": true }, "progress": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", "dev": true }, "promise-polyfill": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-1.1.6.tgz", "integrity": "sha1-zQTv9G9clcOn0EVZHXm14+AfEtc=", "dev": true }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", "dev": true }, "rdf-isomorphic": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/rdf-isomorphic/-/rdf-isomorphic-1.1.0.tgz", "integrity": "sha512-E4E3RJJ0RBBCDGJ6cx7httfnV0Z2xcdF81epe581xSvPsCe42qWYysZ6DKTkBTrmMjNeScNnDkjubLS5RSODtw==", "dev": true, "requires": { "rdf-string": "^1.3.1", "rdf-terms": "^1.4.0" } }, "rdf-object": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/rdf-object/-/rdf-object-1.1.0.tgz", "integrity": "sha512-pyzLpPrJFPlo9Tdg4z9KR9tceC0SEpLLDTjXH2fWjsYcmF6oNkYIuxrxcUvuj2Hy1NnRv8oN490rRRRwxUXj3Q==", "dev": true, "requires": { "@rdfjs/data-model": "^1.1.1", "jsonld-context-parser": "^1.0.0", "rdf-string": "^1.3.1", "streamify-array": "^1.0.1" } }, "rdf-quad": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/rdf-quad/-/rdf-quad-1.3.0.tgz", "integrity": "sha512-K4+Kp4/zG5GauKrOaMTt6HYdiT8aCW8r1PKGF5kiUpxfrH9YCzZT72Rn9NFP+CU3NbHU+n61AeZcuIefoyzc7g==", "dev": true, "requires": { "@rdfjs/data-model": "^1.1.1", "rdf-string": "^1.3.1" } }, "rdf-string": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/rdf-string/-/rdf-string-1.3.1.tgz", "integrity": "sha512-Pcw6aZRfto2cZodK5kSqFZW8mz6nfKLxSfjOSrTi5ajb2CSIwzqGx7UniysgKoV2i7tQL5dpPgCgY80upCiRUw==", "dev": true, "requires": { "@rdfjs/data-model": "^1.1.1" } }, "rdf-terms": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/rdf-terms/-/rdf-terms-1.4.0.tgz", "integrity": "sha512-xvi9ckIpZraUWs6MfTrjan3OCy5ec7cl12Hrhw1Q7t4NTMyKpiNbC0IqeisDiVCPHrX0e/AbSIibBnIA5VDpyw==", "dev": true, "requires": { "@rdfjs/data-model": "^1.1.1", "lodash.uniqwith": "^4.5.0" } }, "rdf-test-suite": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/rdf-test-suite/-/rdf-test-suite-1.2.0.tgz", "integrity": "sha512-wjQMOWE93Ox+FGAX1fgUJMRJpgA8EOH8zd9ceyByYuFVNm9GUinfVfW2gRTcDqUy9+fk24cYgdAyTKkiGCOhkA==", "dev": true, "requires": { "@rdfjs/data-model": "^1.1.1", "arrayify-stream": "^1.0.0", "isomorphic-fetch": "^2.2.1", "log-symbols": "^2.2.0", "minimist": "^1.2.0", "n3": "^1.0.0", "node-web-streams": "^0.2.2", "rdf-isomorphic": "^1.1.0", "rdf-object": "^1.1.0", "rdf-quad": "^1.3.0", "rdf-string": "^1.3.1", "rdf-terms": "^1.4.0", "rdfxml-streaming-parser": "^1.1.0", "sparqljson-parse": "^1.5.0", "sparqlxml-parse": "^1.2.0", "stream-to-string": "^1.1.0", "streamify-string": "^1.0.1" }, "dependencies": { "minimist": { "version": "1.2.0", "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true } } }, "rdfxml-streaming-parser": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/rdfxml-streaming-parser/-/rdfxml-streaming-parser-1.1.0.tgz", "integrity": "sha512-0cMdocZQoqx6052vnFAh9fo0bVcRJbav6UVRCeAJiNQoRjNhvY/QwwIPPrk60h+oN7gUKJLk6adFQRBTjJJLqQ==", "dev": true, "requires": { "@rdfjs/data-model": "^1.1.1", "relative-to-absolute-iri": "^1.0.0", "sax": "^1.2.4" } }, "readable-stream": { "version": "2.3.5", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz", "integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==", "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.0.3", "util-deprecate": "~1.0.1" } }, "regexpp": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.0.1.tgz", "integrity": "sha512-8Ph721maXiOYSLtaDGKVmDn5wdsNaF6Px85qFNeMPQq0r8K5Y10tgP6YuR65Ws35n4DvzFcCxEnRNBIXQunzLw==", "dev": true }, "relative-to-absolute-iri": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/relative-to-absolute-iri/-/relative-to-absolute-iri-1.0.0.tgz", "integrity": "sha512-Yt4tG3eoy0R8111kS2G/jH3QE48U7RIAqGQLqek4LbA4MYKy5OXKVKJgAxu5tmZVengPHiaiP4R8tg1zZhXE+A==", "dev": true }, "require-uncached": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", "dev": true, "requires": { "caller-path": "^0.1.0", "resolve-from": "^1.0.0" } }, "resolve-from": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", "dev": true }, "restore-cursor": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", "dev": true, "requires": { "onetime": "^2.0.0", "signal-exit": "^3.0.2" } }, "rimraf": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", "dev": true, "requires": { "glob": "^7.0.5" } }, "run-async": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", "dev": true, "requires": { "is-promise": "^2.1.0" } }, "rx-lite": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", "dev": true }, "rx-lite-aggregates": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", "dev": true, "requires": { "rx-lite": "*" } }, "safe-buffer": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", "dev": true }, "sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", "dev": true }, "sax-stream": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/sax-stream/-/sax-stream-1.3.0.tgz", "integrity": "sha512-tcfsAAICAkyNNe4uiKtKmLKxx3C7qPAej13UUoN+7OLYq/P5kHGahZtJhhMVM3fIMndA6TlYHWFlFEzFkv1VGg==", "dev": true, "requires": { "debug": "~2", "sax": "~1" }, "dependencies": { "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { "ms": "2.0.0" } } } }, "semver": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", "dev": true }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "dev": true, "requires": { "shebang-regex": "^1.0.0" } }, "shebang-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", "dev": true }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true }, "slice-ansi": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0" } }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, "sparqljson-parse": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/sparqljson-parse/-/sparqljson-parse-1.5.0.tgz", "integrity": "sha512-9avQc1mfxhbNnLis4nW92CVeoX3vh7csIZw4WS7Zwlpgk++GHMeWIkGWc15mlFUoe97LosNkjGcJxEEkO7DHaw==", "dev": true, "requires": { "@rdfjs/data-model": "^1.1.1", "JSONStream": "^1.3.3" } }, "sparqlxml-parse": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/sparqlxml-parse/-/sparqlxml-parse-1.2.0.tgz", "integrity": "sha512-yRDYaRH5Fv6fHywWu8lG+WK2NLeg+p15DTjD5qkNq7njxJseKh2Eq1E1L9XvUEcwhR6aK5L8h07AO4lYA0BFFQ==", "dev": true, "requires": { "@rdfjs/data-model": "^1.1.1", "sax-stream": "^1.2.3" } }, "spawn-sync": { "version": "1.0.15", "resolved": "https://registry.npmjs.org/spawn-sync/-/spawn-sync-1.0.15.tgz", "integrity": "sha1-sAeZVX63+wyDdsKdROih6mfldHY=", "dev": true, "requires": { "concat-stream": "^1.4.7", "os-shim": "^0.1.2" } }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, "stream-to-string": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/stream-to-string/-/stream-to-string-1.1.0.tgz", "integrity": "sha1-OSELATF+ars16FRTjgEwN7ajWUA=", "dev": true, "requires": { "promise-polyfill": "^1.1.6" } }, "streamify-array": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/streamify-array/-/streamify-array-1.0.1.tgz", "integrity": "sha512-ZnswaBcC6B1bhPLSQOlC6CdaDUSzU0wr2lvvHpbHNms8V7+DLd8uEAzDAWpsjxbFkijBHhuObFO/qqu52DZUMA==", "dev": true }, "streamify-string": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/streamify-string/-/streamify-string-1.0.1.tgz", "integrity": "sha1-niIN4z4cR13TDgIG9bGBXMbJUls=", "dev": true }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" } }, "string_decoder": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", "dev": true, "requires": { "safe-buffer": "~5.1.0" } }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { "ansi-regex": "^3.0.0" }, "dependencies": { "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true } } }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "dev": true }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true }, "table": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", "dev": true, "requires": { "ajv": "^5.2.3", "ajv-keywords": "^2.1.0", "chalk": "^2.1.0", "lodash": "^4.17.4", "slice-ansi": "1.0.0", "string-width": "^2.1.1" } }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", "dev": true }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, "requires": { "os-tmpdir": "~1.0.2" } }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", "dev": true }, "trim-right": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", "dev": true }, "type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "dev": true, "requires": { "prelude-ls": "~1.1.2" } }, "type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, "underscore": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==", "dev": true }, "universalify": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz", "integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc=", "dev": true }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, "web-streams-polyfill": { "version": "git://github.com/gwicke/web-streams-polyfill.git#42c488428adea1dc0c0245014e4896ad456b1ded", "from": "git://github.com/gwicke/web-streams-polyfill.git#spec_performance_improvements", "dev": true }, "whatwg-fetch": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz", "integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==", "dev": true }, "which": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", "dev": true, "requires": { "isexe": "^2.0.0" } }, "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", "dev": true }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, "write": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", "dev": true, "requires": { "mkdirp": "^0.5.1" } }, "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", "dev": true } } } N3.js-1.0.4/package.json000066400000000000000000000054421343333361000147010ustar00rootroot00000000000000{ "name": "n3", "version": "1.0.4", "description": "Lightning fast, asynchronous, streaming Turtle / N3 / RDF library.", "author": "Ruben Verborgh ", "keywords": [ "turtle", "rdf", "n3", "streaming", "asynchronous" ], "license": "MIT", "main": "./N3.js", "engines": { "node": ">=8.0" }, "files": [ "N3.js", "lib" ], "devDependencies": { "arrayify-stream": "^1.0.0", "chai": "^4.0.2", "chai-things": "^0.2.0", "colors": "^1.1.2", "docco": "^0.8.0", "eslint": "^4.1.1", "mocha": "^5.0.1", "nyc": "^12.0.2", "pre-commit": "^1.2.2", "rdf-test-suite": "^1.2.0", "streamify-string": "^1.0.1" }, "scripts": { "test": "nyc mocha", "lint": "eslint lib perf test spec", "spec": "npm run spec-turtle && npm run spec-ntriples && npm run spec-nquads && npm run spec-trig", "spec-earl": "npm run spec-earl-turtle && npm run spec-earl-ntriples && npm run spec-earl-nquads && npm run spec-earl-trig", "spec-ntriples": "rdf-test-suite spec/parser.js http://w3c.github.io/rdf-tests/ntriples/manifest.ttl -i '{ \"format\": \"n-triples\" }' -c .rdf-test-suite-cache/", "spec-nquads": "rdf-test-suite spec/parser.js http://w3c.github.io/rdf-tests/nquads/manifest.ttl -i '{ \"format\": \"n-quads\" }' -c .rdf-test-suite-cache/", "spec-turtle": "rdf-test-suite spec/parser.js http://w3c.github.io/rdf-tests/turtle/manifest.ttl -i '{ \"format\": \"turtle\" }' -c .rdf-test-suite-cache/", "spec-trig": "rdf-test-suite spec/parser.js http://w3c.github.io/rdf-tests/trig/manifest.ttl -i '{ \"format\": \"trig\" }' -c .rdf-test-suite-cache/", "spec-earl-ntriples": "rdf-test-suite spec/parser.js http://w3c.github.io/rdf-tests/ntriples/manifest.ttl -i '{ \"format\": \"n-triples\" }' -c .rdf-test-suite-cache/ -o earl -p spec/earl-meta.json > spec/earl-ntriples.ttl", "spec-earl-nquads": "rdf-test-suite spec/parser.js http://w3c.github.io/rdf-tests/nquads/manifest.ttl -i '{ \"format\": \"n-quads\" }' -c .rdf-test-suite-cache/ -o earl -p spec/earl-meta.json > spec/earl-nquads.ttl", "spec-earl-turtle": "rdf-test-suite spec/parser.js http://w3c.github.io/rdf-tests/turtle/manifest.ttl -i '{ \"format\": \"turtle\" }' -c .rdf-test-suite-cache/ -o earl -p spec/earl-meta.json > spec/earl-turtle.ttl", "spec-earl-trig": "rdf-test-suite spec/parser.js http://w3c.github.io/rdf-tests/trig/manifest.ttl -i '{ \"format\": \"trig\" }' -c .rdf-test-suite-cache/ -o earl -p spec/earl-meta.json > spec/earl-trig.ttl", "spec-clean": "rm -r .rdf-test-suite-cache/", "docs": "docco lib/*.js" }, "repository": { "type": "git", "url": "https://github.com/rdfjs/N3.js.git" }, "bugs": { "url": "https://github.com/rdfjs/N3.js/issues" }, "pre-commit": [ "lint", "test" ] } N3.js-1.0.4/perf/000077500000000000000000000000001343333361000133425ustar00rootroot00000000000000N3.js-1.0.4/perf/.eslintrc000066400000000000000000000000461343333361000151660ustar00rootroot00000000000000{ rules: { no-console: 0, } } N3.js-1.0.4/perf/N3Lexer-perf.js000077500000000000000000000011651343333361000161200ustar00rootroot00000000000000#!/usr/bin/env node var N3 = require('../N3'); var fs = require('fs'), assert = require('assert'); if (process.argv.length !== 3) return console.error('Usage: N3Lexer-perf.js filename'); var filename = process.argv[2]; var TEST = '- Lexing file ' + filename; console.time(TEST); var count = 0; new N3.Lexer().tokenize(fs.createReadStream(filename), function (error, token) { assert(!error, error); count++; if (token.type === 'eof') { console.timeEnd(TEST); console.log('* Tokens lexed: ' + count); console.log('* Memory usage: ' + Math.round(process.memoryUsage().rss / 1024 / 1024) + 'MB'); } }); N3.js-1.0.4/perf/N3Parser-perf.js000077500000000000000000000013301343333361000162670ustar00rootroot00000000000000#!/usr/bin/env node var N3 = require('../N3'); var fs = require('fs'), path = require('path'), assert = require('assert'); if (process.argv.length !== 3) return console.error('Usage: N3Parser-perf.js filename'); var filename = path.resolve(process.cwd(), process.argv[2]), base = 'file://' + filename; var TEST = '- Parsing file ' + filename; console.time(TEST); var count = 0; new N3.Parser({ baseIRI: base }).parse(fs.createReadStream(filename), function (error, quad) { assert(!error, error); if (quad) count++; else { console.timeEnd(TEST); console.log('* Quads parsed: ' + count); console.log('* Memory usage: ' + Math.round(process.memoryUsage().rss / 1024 / 1024) + 'MB'); } }); N3.js-1.0.4/perf/N3Store-perf.js000077500000000000000000000061141343333361000161340ustar00rootroot00000000000000#!/usr/bin/env node var N3 = require('../N3'); var assert = require('assert'); console.log('N3Store performance test'); var prefix = 'http://example.org/#'; var TEST, dim, dimSquared, dimCubed, dimQuads, store; /* Test triples */ dim = parseInt(process.argv[2], 10) || 256; dimSquared = dim * dim; dimCubed = dimSquared * dim; store = new N3.Store(); TEST = '- Adding ' + dimCubed + ' triples to the default graph'; console.time(TEST); var i, j, k, l; for (i = 0; i < dim; i++) for (j = 0; j < dim; j++) for (k = 0; k < dim; k++) store.addQuad(prefix + i, prefix + j, prefix + k); console.timeEnd(TEST); console.log('* Memory usage for triples: ' + Math.round(process.memoryUsage().rss / 1024 / 1024) + 'MB'); TEST = '- Finding all ' + dimCubed + ' triples in the default graph ' + dimSquared * 1 + ' times (0 variables)'; console.time(TEST); for (i = 0; i < dim; i++) for (j = 0; j < dim; j++) for (k = 0; k < dim; k++) assert.equal(store.getQuads(prefix + i, prefix + j, prefix + k, '').length, 1); console.timeEnd(TEST); TEST = '- Finding all ' + dimCubed + ' triples in the default graph ' + dimSquared * 2 + ' times (1 variable)'; console.time(TEST); for (i = 0; i < dim; i++) for (j = 0; j < dim; j++) assert.equal(store.getQuads(prefix + i, prefix + j, null, '').length, dim); for (i = 0; i < dim; i++) for (j = 0; j < dim; j++) assert.equal(store.getQuads(prefix + i, null, prefix + j, '').length, dim); for (i = 0; i < dim; i++) for (j = 0; j < dim; j++) assert.equal(store.getQuads(null, prefix + i, prefix + j, '').length, dim); console.timeEnd(TEST); TEST = '- Finding all ' + dimCubed + ' triples in the default graph ' + dimSquared * 3 + ' times (2 variables)'; console.time(TEST); for (i = 0; i < dim; i++) assert.equal(store.getQuads(prefix + i, null, null, '').length, dimSquared); for (j = 0; j < dim; j++) assert.equal(store.getQuads(null, prefix + j, null, '').length, dimSquared); for (k = 0; k < dim; k++) assert.equal(store.getQuads(null, null, prefix + k, '').length, dimSquared); console.timeEnd(TEST); console.log(); /* Test quads */ dim /= 4, dimSquared = dim * dim; dimCubed = dimSquared * dim; dimQuads = dimCubed * dim; store = new N3.Store(); TEST = '- Adding ' + dimQuads + ' quads'; console.time(TEST); for (i = 0; i < dim; i++) for (j = 0; j < dim; j++) for (k = 0; k < dim; k++) for (l = 0; l < dim; l++) store.addQuad(prefix + i, prefix + j, prefix + k, prefix + l); console.timeEnd(TEST); console.log('* Memory usage for quads: ' + Math.round(process.memoryUsage().rss / 1024 / 1024) + 'MB'); TEST = '- Finding all ' + dimQuads + ' quads ' + dimCubed * 4 + ' times'; console.time(TEST); for (i = 0; i < dim; i++) assert.equal(store.getQuads(prefix + i, null, null, null).length, dimCubed); for (j = 0; j < dim; j++) assert.equal(store.getQuads(null, prefix + j, null, null).length, dimCubed); for (k = 0; k < dim; k++) assert.equal(store.getQuads(null, null, prefix + k, null).length, dimCubed); for (l = 0; l < dim; l++) assert.equal(store.getQuads(null, null, null, prefix + l).length, dimCubed); console.timeEnd(TEST); N3.js-1.0.4/spec/000077500000000000000000000000001343333361000133405ustar00rootroot00000000000000N3.js-1.0.4/spec/.eslintrc000066400000000000000000000002221343333361000151600ustar00rootroot00000000000000{ rules: { max-nested-callbacks: 0, no-console: 0, no-loop-func: 0, no-process-exit: 0, no-shadow: 0, no-sync: 0, } } N3.js-1.0.4/spec/earl-meta.json000066400000000000000000000014611343333361000161040ustar00rootroot00000000000000{ "applicationBugsUrl": "https://github.com/rdfjs/N3.js/issues", "applicationDescription": "Lightning fast, asynchronous, streaming Turtle / N3 / RDF library.", "applicationNameFull": "n3", "applicationNameNpm": "n3", "applicationHomepageUrl": "https://github.com/rdfjs/N3.js", "applicationBlogUrl": "https://ruben.verborgh.org/blog/", "applicationUri": "https://www.npmjs.com/package/n3/", "authors": [ { "homepage": null, "name": "Ruben Verborgh ", "uri": "https://ruben.verborgh.org/" } ], "licenseUri": "http://opensource.org/licenses/MIT", "reportUri": null, "specificationUris": [ "https://www.w3.org/TR/turtle/", "https://www.w3.org/TR/trig/", "https://www.w3.org/TR/n-triples/", "https://www.w3.org/TR/n-quads/" ] }N3.js-1.0.4/spec/parser.js000066400000000000000000000006501343333361000151730ustar00rootroot00000000000000var StreamParser = require('..').StreamParser; // Implements the IParser interface from rdf-test-suite // https://github.com/rubensworks/rdf-test-suite.js/blob/master/lib/testcase/rdfsyntax/IParser.ts module.exports = { parse: function (data, baseIRI, options) { return require('arrayify-stream')(require('streamify-string')(data).pipe( new StreamParser(Object.assign({ baseIRI: baseIRI }, options)))); }, }; N3.js-1.0.4/test/000077500000000000000000000000001343333361000133655ustar00rootroot00000000000000N3.js-1.0.4/test/.eslintrc000066400000000000000000000004541343333361000152140ustar00rootroot00000000000000{ globals: { describe: true, it: true, before: true, after: true, beforeEach: true, afterEach: true, expect: true, }, rules: { max-nested-callbacks: 0, // Mocha works with deeply nested callbacks new-cap: 0, // test constructors as regular functions }, } N3.js-1.0.4/test/BlankNode-test.js000066400000000000000000000052031343333361000165350ustar00rootroot00000000000000var DataFactory = require('../N3').DataFactory; var BlankNode = DataFactory.internal.BlankNode, Term = DataFactory.internal.Term; describe('BlankNode', function () { describe('The BlankNode module', function () { it('should be a function', function () { BlankNode.should.be.a('function'); }); it('should make BlankNode objects', function () { BlankNode().should.be.an.instanceof(BlankNode); }); it('should make Term objects', function () { BlankNode().should.be.an.instanceof(Term); }); it('should be a BlankNode constructor', function () { new BlankNode().should.be.an.instanceof(BlankNode); }); it('should be a Term constructor', function () { new BlankNode().should.be.an.instanceof(Term); }); }); describe('A BlankNode instance created from a name', function () { var blankNode; before(function () { blankNode = new BlankNode('b1'); }); it('should be a BlankNode', function () { blankNode.should.be.an.instanceof(BlankNode); }); it('should be a Term', function () { blankNode.should.be.an.instanceof(Term); }); it('should have term type "BlankNode"', function () { blankNode.termType.should.equal('BlankNode'); }); it('should have the name as value', function () { blankNode.should.have.property('value', 'b1'); }); it('should have "_:name" as id', function () { blankNode.should.have.property('id', '_:b1'); }); it('should equal a BlankNode instance with the same name', function () { blankNode.equals(new BlankNode('b1')).should.be.true; }); it('should equal an object with the same term type and value', function () { blankNode.equals({ termType: 'BlankNode', value: 'b1', }).should.be.true; }); it('should not equal a falsy object', function () { blankNode.equals(null).should.be.false; }); it('should not equal a BlankNode instance with another name', function () { blankNode.equals(new BlankNode('b2')).should.be.false; }); it('should not equal an object with the same term type but a different value', function () { blankNode.equals({ termType: 'BlankNode', value: 'b2', }).should.be.false; }); it('should not equal an object with a different term type but the same value', function () { blankNode.equals({ termType: 'NamedNode', value: 'b1', }).should.be.false; }); it('should provide a JSON representation', function () { blankNode.toJSON().should.deep.equal({ termType: 'BlankNode', value: 'b1', }); }); }); }); N3.js-1.0.4/test/DefaultGraph-test.js000066400000000000000000000044331343333361000172520ustar00rootroot00000000000000var DataFactory = require('../N3').DataFactory; var DefaultGraph = DataFactory.internal.DefaultGraph, Term = DataFactory.internal.Term; describe('DefaultGraph', function () { describe('The DefaultGraph module', function () { it('should be a function', function () { DefaultGraph.should.be.a('function'); }); it('should make DefaultGraph objects', function () { DefaultGraph().should.be.an.instanceof(DefaultGraph); }); it('should make Term objects', function () { DefaultGraph().should.be.an.instanceof(Term); }); it('should be a DefaultGraph constructor', function () { new DefaultGraph().should.be.an.instanceof(DefaultGraph); }); it('should be a Term constructor', function () { new DefaultGraph().should.be.an.instanceof(Term); }); }); describe('A DefaultGraph instance', function () { var defaultGraph; before(function () { defaultGraph = new DefaultGraph(); }); it('should be a DefaultGraph', function () { defaultGraph.should.be.an.instanceof(DefaultGraph); }); it('should be a Term', function () { defaultGraph.should.be.an.instanceof(Term); }); it('should have term type "DefaultGraph"', function () { defaultGraph.termType.should.equal('DefaultGraph'); }); it('should have the empty string as value', function () { defaultGraph.should.have.property('value', ''); }); it('should have the empty string as id', function () { defaultGraph.should.have.property('id', ''); }); it('should equal another DefaultGraph instance', function () { defaultGraph.equals(new DefaultGraph()).should.be.true; }); it('should equal an object with the same term type', function () { defaultGraph.equals({ termType: 'DefaultGraph', }).should.be.true; }); it('should not equal a falsy object', function () { defaultGraph.equals(null).should.be.false; }); it('should not equal an object with a different term type', function () { defaultGraph.equals({ termType: 'Literal', }).should.be.false; }); it('should provide a JSON representation', function () { defaultGraph.toJSON().should.deep.equal({ termType: 'DefaultGraph', value: '', }); }); }); }); N3.js-1.0.4/test/Literal-test.js000066400000000000000000000526671343333361000163140ustar00rootroot00000000000000var DataFactory = require('../N3').DataFactory; var Literal = DataFactory.internal.Literal, NamedNode = DataFactory.internal.NamedNode, Term = DataFactory.internal.Term; describe('Literal', function () { describe('The Literal module', function () { it('should be a function', function () { Literal.should.be.a('function'); }); it('should make Literal objects', function () { Literal().should.be.an.instanceof(Literal); }); it('should make Term objects', function () { Literal().should.be.an.instanceof(Term); }); it('should be a Literal constructor', function () { new Literal().should.be.an.instanceof(Literal); }); it('should be a Term constructor', function () { new Literal().should.be.an.instanceof(Term); }); }); describe('A Literal instance created from the empty string without language or datatype', function () { var literal; before(function () { literal = new Literal('""'); }); it('should be a Literal', function () { literal.should.be.an.instanceof(Literal); }); it('should be a Term', function () { literal.should.be.an.instanceof(Term); }); it('should have term type "Literal"', function () { literal.termType.should.equal('Literal'); }); it('should have the empty string as value', function () { literal.should.have.property('value', ''); }); it('should have the empty string as language', function () { literal.should.have.property('language', ''); }); it('should have xsd:string as datatype', function () { literal.should.have.property('datatype'); literal.datatype.should.be.an.instanceof(NamedNode); literal.datatype.value.should.equal('http://www.w3.org/2001/XMLSchema#string'); }); it('should have the quoted empty string as id', function () { literal.should.have.property('id', '""'); }); it('should equal a Literal instance with the same value', function () { literal.equals(new Literal('""')).should.be.true; }); it('should equal an object with the same term type, value, language, and datatype', function () { literal.equals({ termType: 'Literal', value: '', language: '', datatype: { value: 'http://www.w3.org/2001/XMLSchema#string', termType: 'NamedNode' }, }).should.be.true; }); it('should not equal a falsy object', function () { literal.equals(null).should.be.false; }); it('should not equal a Literal instance with a non-empty value', function () { literal.equals(new Literal('"x"')).should.be.false; }); it('should not equal an object with the same term type but a different value', function () { literal.equals({ termType: 'Literal', value: 'x', language: '', datatype: { value: 'http://www.w3.org/2001/XMLSchema#string', termType: 'NamedNode' }, }).should.be.false; }); it('should not equal an object with the same term type but a different language', function () { literal.equals({ termType: 'Literal', value: '', language: 'en', datatype: { value: 'http://www.w3.org/2001/XMLSchema#string', termType: 'NamedNode' }, }).should.be.false; }); it('should not equal an object with the same term type but a different datatype', function () { literal.equals({ termType: 'Literal', value: '', language: '', datatype: { value: 'other', termType: 'NamedNode' }, }).should.be.false; }); it('should not equal an object with a different term type', function () { literal.equals({ termType: 'NamedNode', value: '', language: '', datatype: { value: 'http://www.w3.org/2001/XMLSchema#string', termType: 'NamedNode' }, }).should.be.false; }); it('should provide a JSON representation', function () { literal.toJSON().should.deep.equal({ termType: 'Literal', value: '', language: '', datatype: { termType: 'NamedNode', value: 'http://www.w3.org/2001/XMLSchema#string', }, }); }); }); describe('A Literal instance created from a string without language or datatype', function () { var literal; before(function () { literal = new Literal('"my @^^ string"'); }); it('should be a Literal', function () { literal.should.be.an.instanceof(Literal); }); it('should be a Term', function () { literal.should.be.an.instanceof(Term); }); it('should have term type "Literal"', function () { literal.termType.should.equal('Literal'); }); it('should have the text value as value', function () { literal.should.have.property('value', 'my @^^ string'); }); it('should have the empty string as language', function () { literal.should.have.property('language', ''); }); it('should have xsd:string as datatype', function () { literal.should.have.property('datatype'); literal.datatype.should.be.an.instanceof(NamedNode); literal.datatype.value.should.equal('http://www.w3.org/2001/XMLSchema#string'); }); it('should have the quoted string as id', function () { literal.should.have.property('id', '"my @^^ string"'); }); it('should equal a Literal instance with the same value', function () { literal.equals(new Literal('"my @^^ string"')).should.be.true; }); it('should equal an object with the same term type, value, language, and datatype', function () { literal.equals({ termType: 'Literal', value: 'my @^^ string', language: '', datatype: { value: 'http://www.w3.org/2001/XMLSchema#string', termType: 'NamedNode' }, }).should.be.true; }); it('should not equal a falsy object', function () { literal.equals(null).should.be.false; }); it('should not equal a Literal instance with another value', function () { literal.equals(new Literal('"other string"')).should.be.false; }); it('should not equal an object with the same term type but a different value', function () { literal.equals({ termType: 'Literal', value: 'other string', language: '', datatype: { value: 'http://www.w3.org/2001/XMLSchema#string', termType: 'NamedNode' }, }).should.be.false; }); it('should not equal an object with the same term type but a different language', function () { literal.equals({ termType: 'Literal', value: 'my @^^ string', language: 'en', datatype: { value: 'http://www.w3.org/2001/XMLSchema#string', termType: 'NamedNode' }, }).should.be.false; }); it('should not equal an object with the same term type but a different datatype', function () { literal.equals({ termType: 'Literal', value: 'my @^^ string', language: '', datatype: { value: 'other', termType: 'NamedNode' }, }).should.be.false; }); it('should not equal an object with a different term type', function () { literal.equals({ termType: 'NamedNode', value: 'my @^^ string', language: '', datatype: { value: 'http://www.w3.org/2001/XMLSchema#string', termType: 'NamedNode' }, }).should.be.false; }); it('should provide a JSON representation', function () { literal.toJSON().should.deep.equal({ termType: 'Literal', value: 'my @^^ string', language: '', datatype: { termType: 'NamedNode', value: 'http://www.w3.org/2001/XMLSchema#string', }, }); }); }); describe('A Literal instance created from the empty string with a language', function () { var literal; before(function () { literal = new Literal('""@en-us'); }); it('should be a Literal', function () { literal.should.be.an.instanceof(Literal); }); it('should be a Term', function () { literal.should.be.an.instanceof(Term); }); it('should have term type "Literal"', function () { literal.termType.should.equal('Literal'); }); it('should have the empty string as value', function () { literal.should.have.property('value', ''); }); it('should have the language tag as language', function () { literal.should.have.property('language', 'en-us'); }); it('should have rdf:langString as datatype', function () { literal.should.have.property('datatype'); literal.datatype.should.be.an.instanceof(NamedNode); literal.datatype.value.should.equal('http://www.w3.org/1999/02/22-rdf-syntax-ns#langString'); }); it('should have the quoted empty string as id', function () { literal.should.have.property('id', '""@en-us'); }); it('should equal a Literal instance with the same value', function () { literal.equals(new Literal('""@en-us')).should.be.true; }); it('should equal an object with the same term type, value, language, and datatype', function () { literal.equals({ termType: 'Literal', value: '', language: 'en-us', datatype: { value: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString', termType: 'NamedNode' }, }).should.be.true; }); it('should not equal a falsy object', function () { literal.equals(null).should.be.false; }); it('should not equal a Literal instance with a non-empty value', function () { literal.equals(new Literal('"x"')).should.be.false; }); it('should not equal an object with the same term type but a different value', function () { literal.equals({ termType: 'Literal', value: 'x', language: 'en-us', datatype: { value: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString', termType: 'NamedNode' }, }).should.be.false; }); it('should not equal an object with the same term type but a different language', function () { literal.equals({ termType: 'Literal', value: '', language: '', datatype: { value: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString', termType: 'NamedNode' }, }).should.be.false; }); it('should not equal an object with the same term type but a different datatype', function () { literal.equals({ termType: 'Literal', value: '', language: 'en-us', datatype: { value: 'other', termType: 'NamedNode' }, }).should.be.false; }); it('should not equal an object with a different term type', function () { literal.equals({ termType: 'NamedNode', value: '', language: 'en-us', datatype: { value: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString', termType: 'NamedNode' }, }).should.be.false; }); it('should provide a JSON representation', function () { literal.toJSON().should.deep.equal({ termType: 'Literal', value: '', language: 'en-us', datatype: { termType: 'NamedNode', value: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString', }, }); }); }); describe('A Literal instance created from a string without language or datatype', function () { var literal; before(function () { literal = new Literal('"my @^^ string"@en-us'); }); it('should be a Literal', function () { literal.should.be.an.instanceof(Literal); }); it('should be a Term', function () { literal.should.be.an.instanceof(Term); }); it('should have term type "Literal"', function () { literal.termType.should.equal('Literal'); }); it('should have the text value as value', function () { literal.should.have.property('value', 'my @^^ string'); }); it('should have the language tag as language', function () { literal.should.have.property('language', 'en-us'); }); it('should have rdf:langString as datatype', function () { literal.should.have.property('datatype'); literal.datatype.should.be.an.instanceof(NamedNode); literal.datatype.value.should.equal('http://www.w3.org/1999/02/22-rdf-syntax-ns#langString'); }); it('should have the quoted string as id', function () { literal.should.have.property('id', '"my @^^ string"@en-us'); }); it('should equal a Literal instance with the same value', function () { literal.equals(new Literal('"my @^^ string"@en-us')).should.be.true; }); it('should equal an object with the same term type, value, language, and datatype', function () { literal.equals({ termType: 'Literal', value: 'my @^^ string', language: 'en-us', datatype: { value: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString', termType: 'NamedNode' }, }).should.be.true; }); it('should not equal a falsy object', function () { literal.equals(null).should.be.false; }); it('should not equal a Literal instance with another value', function () { literal.equals(new Literal('"other string"')).should.be.false; }); it('should not equal an object with the same term type but a different value', function () { literal.equals({ termType: 'Literal', value: 'other string', language: 'en-us', datatype: { value: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString', termType: 'NamedNode' }, }).should.be.false; }); it('should not equal an object with the same term type but a different language', function () { literal.equals({ termType: 'Literal', value: 'my @^^ string', language: 'fr', datatype: { value: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString', termType: 'NamedNode' }, }).should.be.false; }); it('should not equal an object with the same term type but a different datatype', function () { literal.equals({ termType: 'Literal', value: 'my @^^ string', language: 'en-us', datatype: { value: 'other', termType: 'NamedNode' }, }).should.be.false; }); it('should not equal an object with a different term type', function () { literal.equals({ termType: 'NamedNode', value: 'my @^^ string', language: 'en-us', datatype: { value: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString', termType: 'NamedNode' }, }).should.be.false; }); it('should provide a JSON representation', function () { literal.toJSON().should.deep.equal({ termType: 'Literal', value: 'my @^^ string', language: 'en-us', datatype: { termType: 'NamedNode', value: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString', }, }); }); }); describe('A Literal instance created from the empty string with a datatype', function () { var literal; before(function () { literal = new Literal('""^^http://example.org/types#type'); }); it('should be a Literal', function () { literal.should.be.an.instanceof(Literal); }); it('should be a Term', function () { literal.should.be.an.instanceof(Term); }); it('should have term type "Literal"', function () { literal.termType.should.equal('Literal'); }); it('should have the empty string as value', function () { literal.should.have.property('value', ''); }); it('should have the empty string as language', function () { literal.should.have.property('language', ''); }); it('should have the datatype', function () { literal.should.have.property('datatype'); literal.datatype.should.be.an.instanceof(NamedNode); literal.datatype.value.should.equal('http://example.org/types#type'); }); it('should have the quoted empty string as id', function () { literal.should.have.property('id', '""^^http://example.org/types#type'); }); it('should equal a Literal instance with the same value', function () { literal.equals(new Literal('""^^http://example.org/types#type')).should.be.true; }); it('should equal an object with the same term type, value, language, and datatype', function () { literal.equals({ termType: 'Literal', value: '', language: '', datatype: { value: 'http://example.org/types#type', termType: 'NamedNode' }, }).should.be.true; }); it('should not equal a falsy object', function () { literal.equals(null).should.be.false; }); it('should not equal a Literal instance with a non-empty value', function () { literal.equals(new Literal('"x"^^http://example.org/types#type')).should.be.false; }); it('should not equal an object with the same term type but a different value', function () { literal.equals({ termType: 'Literal', value: 'x', language: '', datatype: { value: 'http://example.org/types#type', termType: 'NamedNode' }, }).should.be.false; }); it('should not equal an object with the same term type but a different language', function () { literal.equals({ termType: 'Literal', value: '', language: 'en', datatype: { value: 'http://example.org/types#type', termType: 'NamedNode' }, }).should.be.false; }); it('should not equal an object with the same term type but a different datatype', function () { literal.equals({ termType: 'Literal', value: '', language: '', datatype: { value: 'other', termType: 'NamedNode' }, }).should.be.false; }); it('should not equal an object with a different term type', function () { literal.equals({ termType: 'NamedNode', value: '', language: '', datatype: { value: 'http://example.org/types#type', termType: 'NamedNode' }, }).should.be.false; }); it('should provide a JSON representation', function () { literal.toJSON().should.deep.equal({ termType: 'Literal', value: '', language: '', datatype: { termType: 'NamedNode', value: 'http://example.org/types#type', }, }); }); }); describe('A Literal instance created from a string with a datatype', function () { var literal; before(function () { literal = new Literal('"my @^^ string"^^http://example.org/types#type'); }); it('should be a Literal', function () { literal.should.be.an.instanceof(Literal); }); it('should be a Term', function () { literal.should.be.an.instanceof(Term); }); it('should have term type "Literal"', function () { literal.termType.should.equal('Literal'); }); it('should have the text value as value', function () { literal.should.have.property('value', 'my @^^ string'); }); it('should have the empty string as language', function () { literal.should.have.property('language', ''); }); it('should have the datatype', function () { literal.should.have.property('datatype'); literal.datatype.should.be.an.instanceof(NamedNode); literal.datatype.value.should.equal('http://example.org/types#type'); }); it('should have the quoted string as id', function () { literal.should.have.property('id', '"my @^^ string"^^http://example.org/types#type'); }); it('should equal a Literal instance with the same value', function () { literal.equals(new Literal('"my @^^ string"^^http://example.org/types#type')).should.be.true; }); it('should equal an object with the same term type, value, language, and datatype', function () { literal.equals({ termType: 'Literal', value: 'my @^^ string', language: '', datatype: { value: 'http://example.org/types#type', termType: 'NamedNode' }, }).should.be.true; }); it('should not equal a falsy object', function () { literal.equals(null).should.be.false; }); it('should not equal a Literal instance with another value', function () { literal.equals(new Literal('"other string"^^http://example.org/types#type')).should.be.false; }); it('should not equal an object with the same term type but a different value', function () { literal.equals({ termType: 'Literal', value: 'other string', language: '', datatype: { value: 'http://example.org/types#type', termType: 'NamedNode' }, }).should.be.false; }); it('should not equal an object with the same term type but a different language', function () { literal.equals({ termType: 'Literal', value: 'my @^^ string', language: 'en', datatype: { value: 'http://example.org/types#type', termType: 'NamedNode' }, }).should.be.false; }); it('should not equal an object with the same term type but a different datatype', function () { literal.equals({ termType: 'Literal', value: 'my @^^ string', language: '', datatype: { value: 'other', termType: 'NamedNode' }, }).should.be.false; }); it('should not equal an object with a different term type', function () { literal.equals({ termType: 'NamedNode', value: 'my @^^ string', language: '', datatype: { value: 'http://example.org/types#type', termType: 'NamedNode' }, }).should.be.false; }); it('should provide a JSON representation', function () { literal.toJSON().should.deep.equal({ termType: 'Literal', value: 'my @^^ string', language: '', datatype: { termType: 'NamedNode', value: 'http://example.org/types#type', }, }); }); }); }); N3.js-1.0.4/test/N3DataFactory-test.js000066400000000000000000000115671343333361000173140ustar00rootroot00000000000000var DataFactory = require('../lib/N3DataFactory'); var NamedNode = DataFactory.internal.NamedNode, Literal = DataFactory.internal.Literal, BlankNode = DataFactory.internal.BlankNode, Variable = DataFactory.internal.Variable, DefaultGraph = DataFactory.internal.DefaultGraph, Quad = DataFactory.internal.Quad; describe('DataFactory', function () { describe('namedNode', function () { it('converts a plain IRI', function () { DataFactory.namedNode('http://ex.org/foo#bar').should.deep.equal(new NamedNode('http://ex.org/foo#bar')); }); }); describe('blankNode', function () { it('converts a label', function () { DataFactory.blankNode('abc').should.deep.equal(new BlankNode('abc')); }); it('creates an anonymous blank node', function () { DataFactory.blankNode().should.deep.equal(new BlankNode('n3-0')); DataFactory.blankNode().should.deep.equal(new BlankNode('n3-1')); }); it('does not create two equal anonymous blank nodes', function () { DataFactory.blankNode().should.not.deep.equal(DataFactory.blankNode()); }); }); describe('literal', function () { it('converts the empty string', function () { DataFactory.literal('').should.deep.equal(new Literal('""')); }); it('converts the empty string with a language', function () { DataFactory.literal('', 'en-GB').should.deep.equal(new Literal('""@en-gb')); }); it('converts the empty string with a named node type', function () { DataFactory.literal('', new NamedNode('http://ex.org/type')).should.deep.equal(new Literal('""^^http://ex.org/type')); }); it('converts a non-empty string', function () { DataFactory.literal('abc').should.deep.equal(new Literal('"abc"')); }); it('converts a non-empty string with a language', function () { DataFactory.literal('abc', 'en-GB').should.deep.equal(new Literal('"abc"@en-gb')); }); it('converts a non-empty string with a named node type', function () { DataFactory.literal('abc', new NamedNode('http://ex.org/type')).should.deep.equal(new Literal('"abc"^^http://ex.org/type')); }); it('converts an integer', function () { DataFactory.literal(123).should.deep.equal(new Literal('"123"^^http://www.w3.org/2001/XMLSchema#integer')); }); it('converts a double', function () { DataFactory.literal(2.3).should.deep.equal(new Literal('"2.3"^^http://www.w3.org/2001/XMLSchema#double')); }); it('converts Infinity', function () { DataFactory.literal(Infinity).should.deep.equal(new Literal('"INF"^^http://www.w3.org/2001/XMLSchema#double')); }); it('converts -Infinity', function () { DataFactory.literal(-Infinity).should.deep.equal(new Literal('"-INF"^^http://www.w3.org/2001/XMLSchema#double')); }); it('converts NaN', function () { DataFactory.literal(NaN).should.deep.equal(new Literal('"NaN"^^http://www.w3.org/2001/XMLSchema#double')); }); it('converts false', function () { DataFactory.literal(false).should.deep.equal(new Literal('"false"^^http://www.w3.org/2001/XMLSchema#boolean')); }); it('converts true', function () { DataFactory.literal(true).should.deep.equal(new Literal('"true"^^http://www.w3.org/2001/XMLSchema#boolean')); }); }); describe('variable', function () { it('converts a label', function () { DataFactory.variable('abc').should.deep.equal(new Variable('abc')); }); }); describe('defaultGraph', function () { it('returns the default graph', function () { DataFactory.defaultGraph().should.deep.equal(new DefaultGraph()); }); }); describe('triple', function () { it('returns a quad in the default graph', function () { DataFactory.triple( new NamedNode('http://ex.org/a'), new NamedNode('http://ex.org/b'), new Literal('abc') ).should.deep.equal(new Quad( new NamedNode('http://ex.org/a'), new NamedNode('http://ex.org/b'), new Literal('abc'), new DefaultGraph() )); }); }); describe('quad', function () { it('returns a quad', function () { DataFactory.quad( new NamedNode('http://ex.org/a'), new NamedNode('http://ex.org/b'), new Literal('abc'), new NamedNode('http://ex.org/d') ).should.deep.equal(new Quad( new NamedNode('http://ex.org/a'), new NamedNode('http://ex.org/b'), new Literal('abc'), new NamedNode('http://ex.org/d') )); }); it('without graph parameter returns a quad in the default graph', function () { DataFactory.quad( new NamedNode('http://ex.org/a'), new NamedNode('http://ex.org/b'), new Literal('abc') ).should.deep.equal(new Quad( new NamedNode('http://ex.org/a'), new NamedNode('http://ex.org/b'), new Literal('abc'), new DefaultGraph() )); }); }); }); N3.js-1.0.4/test/N3Lexer-test.js000066400000000000000000001275601343333361000161730ustar00rootroot00000000000000var N3Lexer = require('../N3').Lexer; var EventEmitter = require('events'); describe('N3Lexer', function () { describe('The N3Lexer module', function () { it('should be a function', function () { N3Lexer.should.be.a('function'); }); it('should make N3Lexer objects', function () { N3Lexer().should.be.an.instanceof(N3Lexer); }); it('should be an N3Lexer constructor', function () { new N3Lexer().should.be.an.instanceof(N3Lexer); }); it('should provide a shim for setImmediate', function (done) { // Delete global setImmediate var setImmediate = global.setImmediate; global.setImmediate = null; // Clear require cache for (var key in require.cache) delete require.cache[key]; // N3Lexer must now fall back to shim var N3LexerWithShim = require('../N3').Lexer; new N3LexerWithShim().tokenize('', done); // Restore global setImmediate global.setImmediate = setImmediate; }); }); describe('An N3Lexer instance', function () { it('should tokenize the empty string', shouldTokenize('', { type: 'eof', line: 1 })); it('should tokenize a whitespace string', shouldTokenize(' \t \n ', { type: 'eof', line: 2 })); it('should tokenize an IRI', shouldTokenize('', { type: 'IRI', value: 'http://ex.org/?bla#foo', line: 1 }, { type: 'eof', line: 1 })); it('should not tokenize an IRI with disallowed characters', shouldNotTokenize('', 'Unexpected "" on line 1.')); it('should not tokenize an IRI with escaped characters', shouldNotTokenize('', 'Unexpected "" on line 1.')); it('should not tokenize an IRI with disallowed escaped characters', shouldNotTokenize('', 'Unexpected "" on line 1.')); it('should not tokenize an IRI with invalid 4-digit unicode escapes', shouldNotTokenize('', 'Unexpected "" on line 1.')); it('should not tokenize an IRI with invalid 8-digit unicode escapes', shouldNotTokenize('', 'Unexpected "" on line 1.')); it('should not tokenize an IRI with a non-numeric 4-digit unicode escapes', function (done) { // Replace global isNaN var isNaN = global.isNaN; global.isNaN = function () { return true; }; // Try parsing var stream = new EventEmitter(), lexer = new N3Lexer(); lexer.tokenize(stream, function (error, token) { error.should.be.an.instanceof(Error); error.message.should.equal('Unexpected "<\\u1234>" on line 1.'); done(token); }); stream.emit('data', '<\\u1234>'); // Restore global isNaN global.isNaN = isNaN; }); it('should not tokenize an IRI with a non-numeric 8-digit unicode escapes', function (done) { // Replace global isNaN var isNaN = global.isNaN; global.isNaN = function () { return true; }; // Try parsing var stream = new EventEmitter(), lexer = new N3Lexer(); lexer.tokenize(stream, function (error, token) { error.should.be.an.instanceof(Error); error.message.should.equal('Unexpected "<\\U12345678>" on line 1.'); done(token); }); stream.emit('data', '<\\U12345678>'); // Restore global isNaN global.isNaN = isNaN; }); it('should tokenize an IRI with four-digit unicode escapes', shouldTokenize('', { type: 'IRI', value: 'http://a.example/s', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize an IRI with eight-digit unicode escapes', shouldTokenize('', { type: 'IRI', value: 'http://a.example/s\uffc0\udc73', line: 1 }, { type: 'eof', line: 1 })); it('should not decode an IRI', shouldTokenize('', { type: 'IRI', value: 'http://a.example/%66oo-bar', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize two IRIs separated by whitespace', shouldTokenize(' \n\t \n\t \n\t', { type: 'IRI', value: 'http://ex.org/?bla#foo', line: 2 }, { type: 'IRI', value: 'http://ex.org/?bla#bar', line: 3 }, { type: 'eof', line: 4 })); it('should tokenize a statement with IRIs', shouldTokenize(' \n\t \n\t \n\t .', { type: 'IRI', value: 'http://ex.org/?bla#foo', line: 2 }, { type: 'IRI', value: 'http://ex.org/?bla#bar', line: 3 }, { type: 'IRI', value: 'http://ex.org/?bla#boo', line: 4 }, { type: '.', line: 4 }, { type: 'eof', line: 4 })); it('should tokenize prefixed names', shouldTokenize(':a b:c d-dd:e-ee.', { type: 'prefixed', prefix: '', value: 'a', line: 1 }, { type: 'prefixed', prefix: 'b', value: 'c', line: 1 }, { type: 'prefixed', prefix: 'd-dd', value: 'e-ee', line: 1 }, { type: '.', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize prefixed names with leading digits', shouldTokenize('leg:3032571 isbn13:9780136019701 ', { type: 'prefixed', prefix: 'leg', value: '3032571', line: 1 }, { type: 'prefixed', prefix: 'isbn13', value: '9780136019701', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize prefixed names starting with true', shouldTokenize('true:a truer:b ', { type: 'prefixed', prefix: 'true', value: 'a', line: 1 }, { type: 'prefixed', prefix: 'truer', value: 'b', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize prefixed names starting with false', shouldTokenize('false:a falser:b ', { type: 'prefixed', prefix: 'false', value: 'a', line: 1 }, { type: 'prefixed', prefix: 'falser', value: 'b', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize prefixed names with non-leading colons', shouldTokenize('og:video:height ', { type: 'prefixed', prefix: 'og', value: 'video:height', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize prefixed names with reserved escape sequences', shouldTokenize('wgs:lat\\-long ', { type: 'prefixed', prefix: 'wgs', value: 'lat-long', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize the colon prefixed name', shouldTokenize(': : :.', { type: 'prefixed', prefix: '', value: '', line: 1 }, { type: 'prefixed', prefix: '', value: '', line: 1 }, { type: 'prefixed', prefix: '', value: '', line: 1 }, { type: '.', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize a prefixed name with a dot, split in half while streaming', shouldTokenize(streamOf('dbpedia:Anthony_J._Batt', 'aglia '), { type: 'prefixed', prefix: 'dbpedia', value: 'Anthony_J._Battaglia', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize a prefixed name with a dot, split after the dot while streaming', shouldTokenize(streamOf('dbpedia:Anthony_J.', '_Battaglia '), { type: 'prefixed', prefix: 'dbpedia', value: 'Anthony_J._Battaglia', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize a blank node with a dot, split in half while streaming', shouldTokenize(streamOf('_:Anthony_J._Batt', 'aglia '), { type: 'blank', prefix: '_', value: 'Anthony_J._Battaglia', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize a blank node with a dot, split after the dot while streaming', shouldTokenize(streamOf('_:Anthony_J.', '_Battaglia '), { type: 'blank', prefix: '_', value: 'Anthony_J._Battaglia', line: 1 }, { type: 'eof', line: 1 })); it('should not decode a prefixed name', shouldTokenize('ex:%66oo-bar ', { type: 'prefixed', prefix: 'ex', value: '%66oo-bar', line: 1 }, { type: 'eof', line: 1 })); it('should not tokenize a prefixed name with disallowed characters', shouldNotTokenize('ex:bla"foo', 'Unexpected ""foo" on line 1.')); it('should not tokenize a prefixed name with escaped characters', shouldNotTokenize('ex:bla\\"foo', 'Unexpected "ex:bla\\"foo" on line 1.')); it('should not tokenize a prefixed name with disallowed escaped characters', shouldNotTokenize('ex:bla\\u0020foo', 'Unexpected "ex:bla\\u0020foo" on line 1.')); it('should not tokenize a prefixed name with invalid 4-digit unicode escapes', shouldNotTokenize('ex:bla\\uXYZZfoo', 'Unexpected "ex:bla\\uXYZZfoo" on line 1.')); it('should not tokenize a prefixed name with invalid 8-digit unicode escapes', shouldNotTokenize('ex:bla\\uXYZZxyzzfoo', 'Unexpected "ex:bla\\uXYZZxyzzfoo" on line 1.')); it('should not tokenize a prefixed name with four-digit unicode escapes', shouldNotTokenize('ex:foo\\u0073bar', 'Unexpected "ex:foo\\u0073bar" on line 1.')); it('should not tokenize a prefixed name with eight-digit unicode escapes', shouldNotTokenize('ex:foo\\U00000073\\U00A00073bar', 'Unexpected "ex:foo\\U00000073\\U00A00073bar" on line 1.')); it('should tokenize two prefixed names separated by whitespace', shouldTokenize(' \n\tex:foo \n\tex:bar \n\t', { type: 'prefixed', prefix: 'ex', value: 'foo', line: 2 }, { type: 'prefixed', prefix: 'ex', value: 'bar', line: 3 }, { type: 'eof', line: 4 })); it('should tokenize a statement with prefixed names', shouldTokenize(' \n\tex:foo \n\tex:bar \n\tex:baz .', { type: 'prefixed', prefix: 'ex', value: 'foo', line: 2 }, { type: 'prefixed', prefix: 'ex', value: 'bar', line: 3 }, { type: 'prefixed', prefix: 'ex', value: 'baz', line: 4 }, { type: '.', line: 4 }, { type: 'eof', line: 4 })); it('should correctly recognize different types of newlines', shouldTokenize('\r\n\r\n.', { type: 'IRI', value: 'a', line: 1 }, { type: 'IRI', value: 'b', line: 2 }, { type: 'IRI', value: 'c', line: 3 }, { type: '.', line: 4 }, { type: 'eof', line: 4 })); it('should tokenize a single comment', shouldTokenize('#mycomment', { type: 'eof', line: 1 })); it('should tokenize a stream with split comment', shouldTokenize(streamOf('#mycom', 'ment'), { type: 'eof', line: 1 })); it('should ignore comments', shouldTokenize('<#foo> #mycomment\n <#foo> #mycomment \r# mycomment\n\n<#bla>#', { type: 'IRI', value: '#foo', line: 1 }, { type: 'IRI', value: '#foo', line: 2 }, { type: 'IRI', value: '#bla', line: 5 }, { type: 'eof', line: 5 })); it('should tokenize a quoted string literal', shouldTokenize('"string" ', { type: 'literal', value: 'string', line: 1 }, { type: 'eof', line: 1 })); it('should not tokenize a quoted string literal with a newline', shouldNotTokenize('"abc\ndef" ', 'Unexpected ""abc" on line 1.')); it('should not tokenize a quoted string literal with a carriage return', shouldNotTokenize('"abc\rdef" ', 'Unexpected ""abc" on line 1.')); it('should tokenize a triple quoted string literal', shouldTokenize('"""string"""', { type: 'literal', value: 'string', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize a triple quoted string literal with quoted newlines inside', shouldTokenize('"""st"r\ni""ng"""', { type: 'literal', value: 'st"r\ni""ng', line: 1 }, { type: 'eof', line: 2 })); it('should tokenize a string with escape characters', shouldTokenize('"\\\\ \\\' \\" \\n \\r \\t \\ua1b2" \n """\\\\ \\\' \\" \\n \\r \\t \\U0000a1b2"""', { type: 'literal', value: '\\ \' " \n \r \t \ua1b2', line: 1 }, { type: 'literal', value: '\\ \' " \n \r \t \ua1b2', line: 2 }, { type: 'eof', line: 2 })); it('should not tokenize a string with invalid characters', shouldNotTokenize('"\\uXYZX" ', 'Unexpected ""\\uXYZX"" on line 1.')); it('should not tokenize a triple-quoted string with invalid characters', shouldNotTokenize("'''\\uXYZX''' ", "Unexpected \"'''\\uXYZX'''\" on line 1.")); it('should tokenize a quoted string literal with language code', shouldTokenize('"string"@en "string"@nl-be "string"@EN ', { type: 'literal', value: 'string', line: 1 }, { type: 'langcode', value: 'en', line: 1 }, { type: 'literal', value: 'string', line: 1 }, { type: 'langcode', value: 'nl-be', line: 1 }, { type: 'literal', value: 'string', line: 1 }, { type: 'langcode', value: 'EN', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize a quoted string literal with type', shouldTokenize('"stringA"^^ "stringB"^^ns:mytype ', { type: 'literal', value: 'stringA', line: 1 }, { type: 'typeIRI', value: 'type', line: 1 }, { type: 'literal', value: 'stringB', line: 1 }, { type: 'type', value: 'mytype', prefix: 'ns', line: 1 }, { type: 'eof', line: 1 })); it('should not tokenize a single hat', shouldNotTokenize('^', 'Unexpected "^" on line 1.')); it('should not tokenize a double hat followed by a non-IRI', shouldNotTokenize('^^1', 'Unexpected "1" on line 1.')); it('should tokenize a single-quoted string literal', shouldTokenize("'string' ", { type: 'literal', value: 'string', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize a triple single-quoted string literal', shouldTokenize("'''string'''", { type: 'literal', value: 'string', line: 1 }, { type: 'eof', line: 1 })); it('should not tokenize a single-quoted string literal with a newline', shouldNotTokenize("'abc\ndef' ", 'Unexpected "\'abc" on line 1.')); it('should not tokenize a single-quoted string literal with a carriage return', shouldNotTokenize("'abc\rdef' ", 'Unexpected "\'abc" on line 1.')); it('should tokenize a triple single-quoted string literal with quotes newlines inside', shouldTokenize("'''st'r\ni''ng'''", { type: 'literal', value: 'st\'r\ni\'\'ng', line: 1 }, { type: 'eof', line: 2 })); it('should tokenize a single-quoted string with escape characters', shouldTokenize("'\\\\ \\\" \\' \\n \\r \\t \\ua1b2' \n '''\\\\ \\\" \\' \\n \\r \\t \\U0020a1b2'''", { type: 'literal', value: '\\ " \' \n \r \t \ua1b2', line: 1 }, { type: 'literal', value: '\\ " \' \n \r \t \udfe8\uddb2', line: 2 }, { type: 'eof', line: 2 })); it('should tokenize a single-quoted string literal with language code', shouldTokenize("'string'@en 'string'@nl-be 'string'@EN ", { type: 'literal', value: 'string', line: 1 }, { type: 'langcode', value: 'en', line: 1 }, { type: 'literal', value: 'string', line: 1 }, { type: 'langcode', value: 'nl-be', line: 1 }, { type: 'literal', value: 'string', line: 1 }, { type: 'langcode', value: 'EN', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize a single-quoted string literal with type', shouldTokenize("'stringA'^^ 'stringB'^^ns:mytype ", { type: 'literal', value: 'stringA', line: 1 }, { type: 'typeIRI', value: 'type', line: 1 }, { type: 'literal', value: 'stringB', line: 1 }, { type: 'type', value: 'mytype', prefix: 'ns', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize an integer literal', shouldTokenize('10, +20. -30, 40. ', { type: 'literal', value: '10', prefix: 'http://www.w3.org/2001/XMLSchema#integer', line: 1 }, { type: ',', line: 1 }, { type: 'literal', value: '+20', prefix: 'http://www.w3.org/2001/XMLSchema#integer', line: 1 }, { type: '.', line: 1 }, { type: 'literal', value: '-30', prefix: 'http://www.w3.org/2001/XMLSchema#integer', line: 1 }, { type: ',', line: 1 }, { type: 'literal', value: '40', prefix: 'http://www.w3.org/2001/XMLSchema#integer', line: 1 }, { type: '.', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize a decimal literal', shouldTokenize('1. 2.0, .3. -0.4, -.5. ', { type: 'literal', value: '1', prefix: 'http://www.w3.org/2001/XMLSchema#integer', line: 1 }, { type: '.', line: 1 }, { type: 'literal', value: '2.0', prefix: 'http://www.w3.org/2001/XMLSchema#decimal', line: 1 }, { type: ',', line: 1 }, { type: 'literal', value: '.3', prefix: 'http://www.w3.org/2001/XMLSchema#decimal', line: 1 }, { type: '.', line: 1 }, { type: 'literal', value: '-0.4', prefix: 'http://www.w3.org/2001/XMLSchema#decimal', line: 1 }, { type: ',', line: 1 }, { type: 'literal', value: '-.5', prefix: 'http://www.w3.org/2001/XMLSchema#decimal', line: 1 }, { type: '.', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize a double literal', shouldTokenize('10e20, +30.40E+50. -60.70e-80. ', { type: 'literal', value: '10e20', prefix: 'http://www.w3.org/2001/XMLSchema#double', line: 1 }, { type: ',', line: 1 }, { type: 'literal', value: '+30.40E+50', prefix: 'http://www.w3.org/2001/XMLSchema#double', line: 1 }, { type: '.', line: 1 }, { type: 'literal', value: '-60.70e-80', prefix: 'http://www.w3.org/2001/XMLSchema#double', line: 1 }, { type: '.', line: 1 }, { type: 'eof', line: 1 })); it('should not tokenize an invalid number', shouldNotTokenize('10-10 ', 'Unexpected "10-10" on line 1.')); it('should tokenize booleans', shouldTokenize('true false ', { type: 'literal', value: 'true', prefix: 'http://www.w3.org/2001/XMLSchema#boolean', line: 1 }, { type: 'literal', value: 'false', prefix: 'http://www.w3.org/2001/XMLSchema#boolean', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize statements with shared subjects', shouldTokenize(' ;\n .', { type: 'IRI', value: 'a', line: 1 }, { type: 'IRI', value: 'b', line: 1 }, { type: 'IRI', value: 'c', line: 1 }, { type: ';', line: 1 }, { type: 'IRI', value: 'd', line: 2 }, { type: 'IRI', value: 'e', line: 2 }, { type: '.', line: 2 }, { type: 'eof', line: 2 })); it('should tokenize statements with shared subjects and predicates', shouldTokenize(' ,\n.', { type: 'IRI', value: 'a', line: 1 }, { type: 'IRI', value: 'b', line: 1 }, { type: 'IRI', value: 'c', line: 1 }, { type: ',', line: 1 }, { type: 'IRI', value: 'd', line: 2 }, { type: '.', line: 2 }, { type: 'eof', line: 2 })); it('should tokenize statements with shared subjects and predicates and prefixed names', shouldTokenize('a:a b:b c:c;d:d e:e,f:f.', { type: 'prefixed', prefix: 'a', value: 'a', line: 1 }, { type: 'prefixed', prefix: 'b', value: 'b', line: 1 }, { type: 'prefixed', prefix: 'c', value: 'c', line: 1 }, { type: ';', line: 1 }, { type: 'prefixed', prefix: 'd', value: 'd', line: 1 }, { type: 'prefixed', prefix: 'e', value: 'e', line: 1 }, { type: ',', line: 1 }, { type: 'prefixed', prefix: 'f', value: 'f', line: 1 }, { type: '.', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize a stream', shouldTokenize(streamOf('\n ', '"""', 'c\n', '"""', '.', ' ', '""', '.', ' "i"', '@e', 'n.'), { type: 'IRI', value: 'a', line: 1 }, { type: 'IRI', value: 'b', line: 2 }, { type: 'literal', value: 'c\n', line: 2 }, { type: '.', line: 3 }, { type: 'IRI', value: 'd', line: 3 }, { type: 'IRI', value: 'e', line: 3 }, { type: 'literal', value: '', line: 3 }, { type: '.', line: 3 }, { type: 'IRI', value: 'g', line: 3 }, { type: 'IRI', value: 'h', line: 3 }, { type: 'literal', value: 'i', line: 3 }, { type: 'langcode', value: 'en', line: 3 }, { type: '.', line: 3 }, { type: 'eof', line: 3 })); it('should tokenize a stream ending with a digit and a dot', shouldTokenize(streamOf('1', '.'), { type: 'literal', value: '1', prefix: 'http://www.w3.org/2001/XMLSchema#integer', line: 1 }, { type: '.', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize a stream containing a decimal without leading digit', shouldTokenize(streamOf('.', '1 '), { type: 'literal', value: '.1', prefix: 'http://www.w3.org/2001/XMLSchema#decimal', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize a stream containing a decimal with leading digit', shouldTokenize(streamOf('1.', '1 '), { type: 'literal', value: '1.1', prefix: 'http://www.w3.org/2001/XMLSchema#decimal', line: 1 }, { type: 'eof', line: 1 })); it('should immediately signal an error if a linebreak occurs anywhere outside a triple-quoted literal', shouldNotTokenize(streamOf('abc\n', null), 'Unexpected "abc" on line 1.')); it('should immediately signal an error if a linebreak occurs inside a single-quoted literal', shouldNotTokenize(streamOf('"abc\n', null), 'Unexpected ""abc" on line 1.')); it('should immediately signal an error if a carriage return occurs anywhere outside a triple-quoted literal', shouldNotTokenize(streamOf('abc\r', null), 'Unexpected "abc" on line 1.')); it('should immediately signal an error if a carriage return occurs inside a single-quoted literal', shouldNotTokenize(streamOf('"abc\r', null), 'Unexpected ""abc" on line 1.')); it('should tokenize a split single-quoted string', shouldTokenize(streamOf("'abc", "def'"), { type: 'literal', value: 'abcdef', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize a split triple-quoted string', shouldTokenize(streamOf('"""abc\n', 'def"""'), { type: 'literal', value: 'abc\ndef', line: 1 }, { type: 'eof', line: 2 })); it('should tokenize @ keywords', shouldTokenize('@prefix @base @forSome @forAll ', { type: '@prefix', line: 1 }, { type: '@base', line: 1 }, { type: '@forSome', line: 1 }, { type: '@forAll', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize @prefix declarations', shouldTokenize('@prefix : .\n@prefix abc:.\n@prefix:.', { type: '@prefix', line: 1 }, { type: 'prefix', value: '', line: 1 }, { type: 'IRI', value: 'http://iri.org/#', line: 1 }, { type: '.', line: 1 }, { type: '@prefix', line: 2 }, { type: 'prefix', value: 'abc', line: 2 }, { type: 'IRI', value: 'http://iri.org/#', line: 2 }, { type: '.', line: 2 }, { type: '@prefix', line: 3 }, { type: 'prefix', value: '', line: 3 }, { type: 'IRI', value: 'http://example/c/', line: 3 }, { type: '.', line: 3 }, { type: 'eof', line: 3 })); it('should not tokenize prefixes that end with a dot', shouldNotTokenize('@prefix abc.: .', 'Unexpected "abc.:" on line 1.')); it('should tokenize @base declarations', shouldTokenize('@base .\n@base .', { type: '@base', line: 1 }, { type: 'IRI', value: 'http://iri.org/#', line: 1 }, { type: '.', line: 1 }, { type: '@base', line: 2 }, { type: 'IRI', value: 'http://iri.org/#', line: 2 }, { type: '.', line: 2 }, { type: 'eof', line: 2 })); it('should tokenize PREFIX declarations', shouldTokenize('PREFIX : \npreFiX abc: ', { type: 'PREFIX', line: 1 }, { type: 'prefix', value: '', line: 1 }, { type: 'IRI', value: 'http://iri.org/#', line: 1 }, { type: 'PREFIX', line: 2 }, { type: 'prefix', value: 'abc', line: 2 }, { type: 'IRI', value: 'http://iri.org/#', line: 2 }, { type: 'eof', line: 2 })); it('should tokenize BASE declarations', shouldTokenize('BASE \nbAsE ', { type: 'BASE', line: 1 }, { type: 'IRI', value: 'http://iri.org/#', line: 1 }, { type: 'BASE', line: 2 }, { type: 'IRI', value: 'http://iri.org/#', line: 2 }, { type: 'eof', line: 2 })); it('should tokenize blank nodes', shouldTokenize('[] [ ] [a:b "c"^^d:e][a:b[]] _:a:b.', { type: '[', line: 1 }, { type: ']', line: 1 }, { type: '[', line: 1 }, { type: 'IRI', value: 'a', line: 1 }, { type: 'IRI', value: 'b', line: 1 }, { type: ']', line: 1 }, { type: '[', line: 1 }, { type: 'prefixed', prefix: 'a', value: 'b', line: 1 }, { type: 'literal', value: 'c', line: 1 }, { type: 'type', prefix: 'd', value: 'e', line: 1 }, { type: ']', line: 1 }, { type: '[', line: 1 }, { type: 'prefixed', prefix: 'a', value: 'b', line: 1 }, { type: '[', line: 1 }, { type: ']', line: 1 }, { type: ']', line: 1 }, { type: 'blank', prefix: '_', value: 'a', line: 1 }, { type: 'prefixed', prefix: '', value: 'b', line: 1 }, { type: '.', line: 1 }, { type: 'eof', line: 1 })); it('should not tokenize invalid blank nodes', shouldNotTokenize('_::', 'Unexpected "_::" on line 1.')); it('should tokenize lists', shouldTokenize('() () ( )', { type: '(', line: 1 }, { type: ')', line: 1 }, { type: '(', line: 1 }, { type: 'IRI', value: 'a', line: 1 }, { type: ')', line: 1 }, { type: '(', line: 1 }, { type: 'IRI', value: 'a', line: 1 }, { type: 'IRI', value: 'b', line: 1 }, { type: ')', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize mixed lists', shouldTokenize(' (1 "2" :o)(1()(1))', { type: 'IRI', value: 'a', line: 1 }, { type: 'IRI', value: 'b', line: 1 }, { type: '(', line: 1 }, { type: 'literal', value: '1', prefix: 'http://www.w3.org/2001/XMLSchema#integer', line: 1 }, { type: 'literal', value: '2', line: 1 }, { type: 'prefixed', value: 'o', line: 1 }, { type: ')', line: 1 }, { type: '(', line: 1 }, { type: 'literal', value: '1', prefix: 'http://www.w3.org/2001/XMLSchema#integer', line: 1 }, { type: '(', line: 1 }, { type: ')', line: 1 }, { type: '(', line: 1 }, { type: 'literal', value: '1', prefix: 'http://www.w3.org/2001/XMLSchema#integer', line: 1 }, { type: ')', line: 1 }, { type: ')', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize the "a" predicate', shouldTokenize(' a .', { type: 'IRI', value: 'x', line: 1 }, { type: 'abbreviation', value: 'a', line: 1 }, { type: 'IRI', value: 'y', line: 1 }, { type: '.', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize an empty default graph', shouldTokenize('{}', { type: '{', line: 1 }, { type: '}', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize a non-empty default graph', shouldTokenize('{ c:d}', { type: '{', line: 1 }, { type: 'IRI', value: 'a', line: 1 }, { type: 'IRI', value: 'b', line: 1 }, { type: 'prefixed', prefix: 'c', value: 'd', line: 1 }, { type: '}', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize an empty graph identified by an IRI', shouldTokenize('{}', { type: 'IRI', value: 'g', line: 1 }, { type: '{', line: 1 }, { type: '}', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize a non-empty graph identified by an IRI', shouldTokenize(' { c:d}', { type: 'IRI', value: 'g', line: 1 }, { type: '{', line: 1 }, { type: 'IRI', value: 'a', line: 1 }, { type: 'IRI', value: 'b', line: 1 }, { type: 'prefixed', prefix: 'c', value: 'd', line: 1 }, { type: '}', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize an empty graph identified by a blank node', shouldTokenize('_:g{}', { type: 'blank', prefix: '_', value: 'g', line: 1 }, { type: '{', line: 1 }, { type: '}', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize a non-empty graph identified by a blank node', shouldTokenize('_:g { c:d}', { type: 'blank', prefix: '_', value: 'g', line: 1 }, { type: '{', line: 1 }, { type: 'IRI', value: 'a', line: 1 }, { type: 'IRI', value: 'b', line: 1 }, { type: 'prefixed', prefix: 'c', value: 'd', line: 1 }, { type: '}', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize an empty graph with the GRAPH keyword', shouldTokenize('GRAPH{}', { type: 'GRAPH', line: 1 }, { type: 'IRI', value: 'g', line: 1 }, { type: '{', line: 1 }, { type: '}', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize a non-empty graph with the GRAPH keyword', shouldTokenize('graph { c:d}', { type: 'GRAPH', line: 1 }, { type: 'IRI', value: 'g', line: 1 }, { type: '{', line: 1 }, { type: 'IRI', value: 'a', line: 1 }, { type: 'IRI', value: 'b', line: 1 }, { type: 'prefixed', prefix: 'c', value: 'd', line: 1 }, { type: '}', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize variables', shouldTokenize('?a ?abc ?a_B_c.', { type: 'var', value: '?a', line: 1 }, { type: 'var', value: '?abc', line: 1 }, { type: 'var', value: '?a_B_c', line: 1 }, { type: '.', value: '', line: 1 }, { type: 'eof', line: 1 })); it('should not tokenize invalid variables', shouldNotTokenize('?0a ', 'Unexpected "?0a" on line 1.')); it('should tokenize the equality sign', shouldTokenize(' = ', { type: 'IRI', value: 'a', line: 1 }, { type: 'abbreviation', value: '=', line: 1 }, { type: 'IRI', value: 'b', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize the right implication', shouldTokenize(' => ', { type: 'IRI', value: 'a', line: 1 }, { type: 'abbreviation', value: '>', line: 1 }, { type: 'IRI', value: 'b', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize the left implication', shouldTokenize(' <= ', { type: 'IRI', value: 'a', line: 1 }, { type: 'inverse', value: '>', line: 1 }, { type: 'IRI', value: 'b', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize paths', shouldTokenize(':joe!fam:mother!loc:office!loc:zip :joe!fam:mother^fam:mother', { type: 'prefixed', prefix: '', value: 'joe', line: 1 }, { type: '!', line: 1 }, { type: 'prefixed', prefix: 'fam', value: 'mother', line: 1 }, { type: '!', line: 1 }, { type: 'prefixed', prefix: 'loc', value: 'office', line: 1 }, { type: '!', line: 1 }, { type: 'prefixed', prefix: 'loc', value: 'zip', line: 1 }, { type: 'prefixed', prefix: '', value: 'joe', line: 1 }, { type: '!', line: 1 }, { type: 'prefixed', prefix: 'fam', value: 'mother', line: 1 }, { type: '^', line: 1 }, { type: 'prefixed', prefix: 'fam', value: 'mother', line: 1 }, { type: 'eof', line: 1 })); it('should not tokenize an invalid document', shouldNotTokenize(' \n @!', 'Unexpected "@!" on line 2.')); it('does not call setEncoding if not available', function () { new N3Lexer().tokenize({ on: function () {} }); }); describe('passing data after the stream has been finished', function () { var tokens = [], error; before(function () { var stream = new EventEmitter(), lexer = new N3Lexer(); lexer.tokenize(stream, function (err, token) { if (err) error = err; else tokens.push(token); }); stream.emit('data', ' '); stream.emit('end'); stream.emit('data', ' '); stream.emit('end'); }); it('parses only the first chunk (plus EOF)', function () { tokens.should.have.length(2); }); it('does not emit an error', function () { expect(error).to.not.exist; }); }); describe('passing data after a syntax error', function () { var tokens = [], error; before(function () { var stream = new EventEmitter(), lexer = new N3Lexer(); lexer.tokenize(stream, function (err, token) { if (err) error = err; else tokens.push(token); }); stream.emit('data', ' '); stream.emit('data', ' error '); stream.emit('end'); stream.emit('data', ' '); stream.emit('end'); }); it('parses only the first chunk', function () { tokens.should.have.length(1); }); it('emits the error', function () { expect(error).to.exist; expect(error).to.have.property('message', 'Unexpected "error" on line 1.'); }); }); describe('when the stream errors', function () { var tokens = [], error; before(function () { var stream = new EventEmitter(), lexer = new N3Lexer(); lexer.tokenize(stream, function (err, token) { if (err) error = err; else tokens.push(token); }); stream.emit('error', new Error('my error')); }); it('passes the error', function () { expect(error).to.exist; expect(error).to.have.property('message', 'my error'); }); }); describe('called with a string and without callback', function () { var lexer = new N3Lexer(), tokens = lexer.tokenize(' .'); it('returns all tokens synchronously', function () { tokens.should.deep.equal([ { line: 1, type: 'IRI', value: 'a', prefix: '' }, { line: 1, type: 'IRI', value: 'b', prefix: '' }, { line: 1, type: 'IRI', value: 'c', prefix: '' }, { line: 1, type: '.', value: '', prefix: '' }, { line: 1, type: 'eof', value: '', prefix: '' }, ]); }); }); describe('called with an erroneous string and without callback', function () { var lexer = new N3Lexer(); it('throws an error', function () { (function () { lexer.tokenize(' bar'); }) .should.throw('Unexpected "bar" on line 1.'); }); }); }); }); describe('An N3Lexer instance with the n3 option set to false', function () { function createLexer() { return new N3Lexer({ n3: false }); } it('should not tokenize a variable', shouldNotTokenize(createLexer(), '?a', 'Unexpected "?a" on line 1.')); it('should not tokenize a right implication', shouldNotTokenize(createLexer(), ' => .', 'Unexpected "=>" on line 1.')); it('should not tokenize a left implication', shouldNotTokenize(createLexer(), ' <= .', 'Unexpected "<=" on line 1.')); it('should not tokenize an equality', shouldNotTokenize(createLexer(), ' = .', 'Unexpected "=" on line 1.')); it('should not tokenize a ! path', shouldNotTokenize(createLexer(), ':joe!fam:mother', 'Unexpected "!fam:mother" on line 1.')); it('should not tokenize a ^ path', shouldNotTokenize(createLexer(), ':joe^fam:father', 'Unexpected "^fam:father" on line 1.')); }); describe('An N3Lexer instance with the comment option set to true', function () { function createLexer() { return new N3Lexer({ comments: true }); } it('should tokenize a single comment', shouldTokenize(createLexer(), '#mycomment', { type: 'comment', value: 'mycomment', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize a stream with split comment', shouldTokenize(createLexer(), streamOf('#mycom', 'ment'), { type: 'comment', value: 'mycomment', line: 1 }, { type: 'eof', line: 1 })); it('should tokenize comments', shouldTokenize(createLexer(), '<#foo> #mycomment\n <#foo> #mycomment \r# mycomment\n\n<#bla>#', { type: 'IRI', value: '#foo', line: 1 }, { type: 'comment', value: 'mycomment', line: 1 }, { type: 'IRI', value: '#foo', line: 2 }, { type: 'comment', value: 'mycomment ', line: 2 }, { type: 'comment', value: ' mycomment', line: 3 }, { type: 'IRI', value: '#bla', line: 5 }, { type: 'comment', value: '', line: 5 }, { type: 'eof', line: 5 })); }); function shouldTokenize(lexer, input) { var expected = Array.prototype.slice.call(arguments, 1); // Shift parameters as necessary if (lexer instanceof N3Lexer) expected.shift(); else input = lexer, lexer = new N3Lexer(); return function (done) { var result = []; lexer.tokenize(input, tokenCallback); function tokenCallback(error, token) { expect(error).not.to.exist; expect(token).to.exist; var expectedItem = expected[result.length]; if (expectedItem) for (var attribute in token) if (token[attribute] === '' && expectedItem[attribute] !== '') delete token[attribute]; result.push(token); if (token.type === 'eof') { result.should.eql(expected); done(null, result); } } }; } function shouldNotTokenize(lexer, input, expectedError) { // Shift parameters if necessary if (!(lexer instanceof N3Lexer)) expectedError = input, input = lexer, lexer = new N3Lexer(); return function (done) { lexer.tokenize(input, tokenCallback); function tokenCallback(error, token) { if (error) { expect(token).not.to.exist; error.should.be.an.instanceof(Error); error.message.should.eql(expectedError); done(); } else if (token.type === 'eof') throw new Error('Expected error ' + expectedError); } }; } var immediately = typeof setImmediate === 'function' ? setImmediate : function setImmediate(func) { setTimeout(func, 0); }; function streamOf() { var elements = Array.prototype.slice.call(arguments), stream = new EventEmitter(); stream.setEncoding = function (encoding) { if (encoding === 'utf8') immediately(next, 0); }; function next() { if (elements.length) { var element = elements.shift(); // use "null" to stall the stream if (element !== null) { stream.emit('data', element); immediately(next, 0); } } else { stream.emit('end'); } } return stream; } N3.js-1.0.4/test/N3Parser-test.js000066400000000000000000003220611343333361000163410ustar00rootroot00000000000000var N3Parser = require('../N3').Parser; var DataFactory = require('../N3').DataFactory; var NamedNode = DataFactory.internal.NamedNode, Quad = DataFactory.internal.Quad, fromId = DataFactory.internal.fromId; var BASE_IRI = 'http://example.org/'; describe('N3Parser', function () { describe('The N3Parser module', function () { it('should be a function', function () { N3Parser.should.be.a('function'); }); it('should make N3Parser objects', function () { N3Parser().should.be.an.instanceof(N3Parser); }); it('should be an N3Parser constructor', function () { new N3Parser().should.be.an.instanceof(N3Parser); }); }); describe('An N3Parser instance', function () { beforeEach(N3Parser._resetBlankNodeIds); it('should parse the empty string', shouldParse('' /* no triples */)); it('should parse a whitespace string', shouldParse(' \t \n ' /* no triples */)); it('should parse a single triple', shouldParse(' .', ['a', 'b', 'c'])); it('should parse three triples', shouldParse(' .\n .\n .', ['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i'])); it('should parse a triple with a literal', shouldParse(' "string".', ['a', 'b', '"string"'])); it('should parse a triple with a numeric literal', shouldParse(' 3.0.', ['a', 'b', '"3.0"^^http://www.w3.org/2001/XMLSchema#decimal'])); it('should parse a triple with an integer literal', shouldParse(' 3.', ['a', 'b', '"3"^^http://www.w3.org/2001/XMLSchema#integer'])); it('should parse a triple with a floating point literal', shouldParse(' 1.3e2.', ['a', 'b', '"1.3e2"^^http://www.w3.org/2001/XMLSchema#double'])); it('should parse a triple with a boolean literal', shouldParse(' true.', ['a', 'b', '"true"^^http://www.w3.org/2001/XMLSchema#boolean'])); it('should parse a triple with a literal and a language code', shouldParse(' "string"@en.', ['a', 'b', '"string"@en'])); it('should normalize language codes to lowercase', shouldParse(' "string"@EN.', ['a', 'b', '"string"@en'])); it('should parse a triple with a literal and an IRI type', shouldParse(' "string"^^.', ['a', 'b', '"string"^^http://example.org/type'])); it('should parse a triple with a literal and a prefixed name type', shouldParse('@prefix x: . "string"^^x:z.', ['a', 'b', '"string"^^urn:x:y#z'])); it('should differentiate between IRI and prefixed name types', shouldParse('@prefix : . :a :b "x"^^. :a :b "x"^^:urn:foo.', ['noturn:a', 'noturn:b', '"x"^^urn:foo'], ['noturn:a', 'noturn:b', '"x"^^noturn:urn:foo'])); it('should not parse a triple with a literal and a prefixed name type with an inexistent prefix', shouldNotParse(' "string"^^x:z.', 'Undefined prefix "x:" on line 1.', { token: { line: 1, type: 'type', value: 'z', prefix: 'x', }, line: 1, previousToken: { line: 1, type: 'literal', value: 'string', prefix: '', }, })); it('should parse a triple with the "a" shorthand predicate', shouldParse(' a .', ['a', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', 't'])); it('should parse triples with prefixes', shouldParse('@prefix : <#>.\n' + '@prefix a: .\n' + ':x a:a a:b.', ['#x', 'a#a', 'a#b'])); it('should parse triples with the prefix "prefix"', shouldParse('@prefix prefix: .' + 'prefix:a prefix:b prefix:c.', ['http://prefix.cc/a', 'http://prefix.cc/b', 'http://prefix.cc/c'])); it('should parse triples with the prefix "base"', shouldParse('PREFIX base: ' + 'base:a base:b base:c.', ['http://prefix.cc/a', 'http://prefix.cc/b', 'http://prefix.cc/c'])); it('should parse triples with the prefix "graph"', shouldParse('PREFIX graph: ' + 'graph:a graph:b graph:c.', ['http://prefix.cc/a', 'http://prefix.cc/b', 'http://prefix.cc/c'])); it('should not parse @PREFIX', shouldNotParse('@PREFIX : <#>.', 'Expected entity but got @PREFIX on line 1.', { token: { line: 1, type: '@PREFIX', value: '', prefix: '', }, previousToken: undefined, line: 1, })); it('should parse triples with prefixes and different punctuation', shouldParse('@prefix : <#>.\n' + '@prefix a: .\n' + ':x a:a a:b;a:c a:d,a:e.', ['#x', 'a#a', 'a#b'], ['#x', 'a#c', 'a#d'], ['#x', 'a#c', 'a#e'])); it('should not parse undefined empty prefix in subject', shouldNotParse(':a ', 'Undefined prefix ":" on line 1.')); it('should not parse undefined prefix in subject', shouldNotParse('a:a ', 'Undefined prefix "a:" on line 1.')); it('should not parse undefined prefix in predicate', shouldNotParse(' b:c ', 'Undefined prefix "b:" on line 1.')); it('should not parse undefined prefix in object', shouldNotParse(' c:d ', 'Undefined prefix "c:" on line 1.')); it('should not parse undefined prefix in datatype', shouldNotParse(' "c"^^d:e ', 'Undefined prefix "d:" on line 1.')); it('should parse triples with SPARQL prefixes', shouldParse('PREFIX : <#>\n' + 'PrEfIX a: ' + ':x a:a a:b.', ['#x', 'a#a', 'a#b'])); it('should not parse prefix declarations without prefix', shouldNotParse('@prefix ', 'Expected prefix to follow @prefix on line 1.')); it('should not parse prefix declarations without IRI', shouldNotParse('@prefix : .', 'Expected IRI to follow prefix ":" on line 1.')); it('should not parse prefix declarations without a dot', shouldNotParse('@prefix : ;', 'Expected declaration to end with a dot on line 1.')); it('should parse statements with shared subjects', shouldParse(' ;\n .', ['a', 'b', 'c'], ['a', 'd', 'e'])); it('should parse statements with shared subjects and trailing semicolon', shouldParse(' ;\n ;\n.', ['a', 'b', 'c'], ['a', 'd', 'e'])); it('should parse statements with shared subjects and multiple semicolons', shouldParse(' ;;\n .', ['a', 'b', 'c'], ['a', 'd', 'e'])); it('should parse statements with shared subjects and predicates', shouldParse(' , .', ['a', 'b', 'c'], ['a', 'b', 'd'])); it('should not accept ; without preceding predicate', shouldNotParse(' . ; .', 'Expected predicate but got ; on line 1.')); it('should not accept , without preceding object', shouldNotParse(' . , .', 'Expected entity but got , on line 1.')); it('should parse diamonds', shouldParse('<> <> <> <>.\n(<>) <> (<>) <>.', [BASE_IRI, BASE_IRI, BASE_IRI, BASE_IRI], ['_:b0', BASE_IRI, '_:b1', BASE_IRI], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', BASE_IRI], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'], ['_:b1', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', BASE_IRI], ['_:b1', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'])); it('should parse statements with named blank nodes', shouldParse('_:a _:c.', ['_:b0_a', 'b', '_:b0_c'])); it('should not parse statements with blank predicates', shouldNotParse('PREFIX : <#>\n _:b .', 'Disallowed blank node as predicate on line 2.', { token: { line: 2, type: 'blank', value: 'b', prefix: '_', }, line: 2, previousToken: { line: 2, type: 'IRI', value: 'a', prefix: '', }, })); it('should parse statements with empty blank nodes', shouldParse('[] [].', ['_:b0', 'b', '_:b1'])); it('should parse statements with unnamed blank nodes in the subject', shouldParse('[ ] .', ['_:b0', 'c', 'd'], ['_:b0', 'a', 'b'])); it('should parse statements with unnamed blank nodes in the object', shouldParse(' [ ].', ['a', 'b', '_:b0'], ['_:b0', 'c', 'd'])); it('should parse statements with unnamed blank nodes with a string object', shouldParse(' [ "x"].', ['a', 'b', '_:b0'], ['_:b0', 'c', '"x"'])); it('should not parse a blank node with missing subject', shouldNotParse(' [].', 'Expected entity but got ] on line 1.')); it('should not parse a blank node with only a semicolon', shouldNotParse(' [;].', 'Expected predicate but got ; on line 1.')); it('should parse a blank node with a trailing semicolon', shouldParse(' [ ; ].', ['a', 'b', '_:b0'], ['_:b0', 'u', 'v'])); it('should parse a blank node with multiple trailing semicolons', shouldParse(' [ ;;; ].', ['a', 'b', '_:b0'], ['_:b0', 'u', 'v'])); it('should parse a multi-predicate blank node', shouldParse(' [ ; ].', ['a', 'b', '_:b0'], ['_:b0', 'u', 'v'], ['_:b0', 'w', 'z'])); it('should parse a multi-predicate blank node with multiple semicolons', shouldParse(' [ ;;; ].', ['a', 'b', '_:b0'], ['_:b0', 'u', 'v'], ['_:b0', 'w', 'z'])); it('should parse a multi-object blank node', shouldParse(' [ , ].', ['a', 'b', '_:b0'], ['_:b0', 'u', 'v'], ['_:b0', 'u', 'z'])); it('should parse a multi-statement blank node ending with a literal', shouldParse(' [ ; "z" ].', ['a', 'b', '_:b0'], ['_:b0', 'u', 'v'], ['_:b0', 'w', '"z"'])); it('should parse a multi-statement blank node ending with a typed literal', shouldParse(' [ ; "z"^^ ].', ['a', 'b', '_:b0'], ['_:b0', 'u', 'v'], ['_:b0', 'w', '"z"^^http://example.org/t'])); it('should parse a multi-statement blank node ending with a string with language', shouldParse(' [ ; "z"^^ ].', ['a', 'b', '_:b0'], ['_:b0', 'u', 'v'], ['_:b0', 'w', '"z"^^http://example.org/t'])); it('should parse a multi-statement blank node with trailing semicolon', shouldParse(' [ ; ; ].', ['a', 'b', '_:b0'], ['_:b0', 'u', 'v'], ['_:b0', 'w', 'z'])); it('should parse statements with nested blank nodes in the subject', shouldParse('[ [ ]] .', ['_:b0', 'c', 'd'], ['_:b0', 'a', '_:b1'], ['_:b1', 'x', 'y'])); it('should parse statements with nested blank nodes in the object', shouldParse(' [ [ ]].', ['a', 'b', '_:b0'], ['_:b0', 'c', '_:b1'], ['_:b1', 'd', 'e'])); it('should reuse identifiers of blank nodes within and outside of graphs', shouldParse('_:a _:c. { _:a _:c }', ['_:b0_a', 'b', '_:b0_c'], ['_:b0_a', 'b', '_:b0_c', 'g'])); it('should not parse an invalid blank node', shouldNotParse('[ .', 'Expected punctuation to follow "http://example.org/b" on line 1.')); it('should parse a statements with only an anonymous node', shouldParse('[

].', ['_:b0', 'p', 'o'])); it('should not parse a statement with only a blank anonymous node', shouldNotParse('[].', 'Unexpected . on line 1.')); it('should not parse an anonymous node with only an anonymous node inside', shouldNotParse('[[

]].', 'Expected entity but got [ on line 1.')); it('should parse statements with an empty list in the subject', shouldParse('() .', ['http://www.w3.org/1999/02/22-rdf-syntax-ns#nil', 'a', 'b'])); it('should parse statements with an empty list in the object', shouldParse(' ().', ['a', 'b', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'])); it('should parse statements with a single-element list in the subject', shouldParse('() .', ['_:b0', 'a', 'b'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'x'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'])); it('should parse statements with a single-element list in the object', shouldParse(' ().', ['a', 'b', '_:b0'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'x'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'])); it('should parse a list with a literal', shouldParse(' ("x").', ['a', 'b', '_:b0'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', '"x"'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'])); it('should parse a list with a typed literal', shouldParse(' ("x"^^).', ['a', 'b', '_:b0'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', '"x"^^http://example.org/y'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'])); it('should parse a list with a language-tagged literal', shouldParse(' ("x"@en-GB).', ['a', 'b', '_:b0'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', '"x"@en-gb'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'])); it('should parse statements with a multi-element list in the subject', shouldParse('( ) .', ['_:b0', 'a', 'b'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'x'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', '_:b1'], ['_:b1', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'y'], ['_:b1', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'])); it('should parse statements with a multi-element list in the object', shouldParse(' ( ).', ['a', 'b', '_:b0'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'x'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', '_:b1'], ['_:b1', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'y'], ['_:b1', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'])); it('should parse statements with a multi-element literal list in the object', shouldParse(' ("x" "y"@en-GB 1 "z"^^).', ['a', 'b', '_:b0'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', '"x"'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', '_:b1'], ['_:b1', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', '"y"@en-gb'], ['_:b1', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', '_:b2'], ['_:b2', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', '"1"^^http://www.w3.org/2001/XMLSchema#integer'], ['_:b2', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', '_:b3'], ['_:b3', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', '"z"^^http://example.org/t'], ['_:b3', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'])); it('should parse statements with prefixed names in lists', shouldParse('@prefix a: . (a:x a:y).', ['a', 'b', '_:b0'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'a#x'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', '_:b1'], ['_:b1', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'a#y'], ['_:b1', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'])); it('should not parse statements with undefined prefixes in lists', shouldNotParse(' (a:x a:y).', 'Undefined prefix "a:" on line 1.')); it('should parse statements with blank nodes in lists', shouldParse(' (_:x _:y).', ['a', 'b', '_:b0'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', '_:b0_x'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', '_:b1'], ['_:b1', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', '_:b0_y'], ['_:b1', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'])); it('should parse statements with a nested empty list', shouldParse(' ( ()).', ['a', 'b', '_:b0'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'x'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', '_:b1'], ['_:b1', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'], ['_:b1', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'])); it('should parse statements with non-empty nested lists', shouldParse(' ( ()).', ['a', 'b', '_:b0'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'x'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', '_:b1'], ['_:b1', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', '_:b2'], ['_:b1', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'], ['_:b2', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'y'], ['_:b2', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'])); it('should parse statements with a list containing a blank node', shouldParse('([]) .', ['_:b0', 'a', 'b'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', '_:b1'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'])); it('should parse statements with a list containing multiple blank nodes', shouldParse('([] [ ]) .', ['_:b0', 'a', 'b'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', '_:b1'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', '_:b2'], ['_:b2', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', '_:b3'], ['_:b2', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'], ['_:b3', 'x', 'y'])); it('should parse statements with a blank node containing a list', shouldParse('[ ()] .', ['_:b0', 'c', 'd'], ['_:b0', 'a', '_:b1'], ['_:b1', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'b'], ['_:b1', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'])); it('should not parse an invalid list', shouldNotParse(' (]).', 'Expected entity but got ] on line 1.')); it('should resolve IRIs against @base', shouldParse('@base .\n' + ' .\n' + '@base .\n' + ' .', ['http://ex.org/a', 'http://ex.org/b', 'http://ex.org/c'], ['http://ex.org/d/e', 'http://ex.org/d/f', 'http://ex.org/d/g'])); it('should not resolve IRIs against @BASE', shouldNotParse('@BASE .', 'Expected entity but got @BASE on line 1.')); it('should resolve IRIs against SPARQL base', shouldParse('BASE \n' + ' . ' + 'BASE ' + ' .', ['http://ex.org/a', 'http://ex.org/b', 'http://ex.org/c'], ['http://ex.org/d/e', 'http://ex.org/d/f', 'http://ex.org/d/g'])); it('should resolve IRIs against a @base with query string', shouldParse('@base .\n' + '<> .\n' + '@base .\n' + '<> .', ['http://ex.org/?foo', 'http://ex.org/b', 'http://ex.org/c'], ['http://ex.org/d/?bar', 'http://ex.org/d/f', 'http://ex.org/d/g'])); it('should resolve IRIs with query string against @base', shouldParse('@base .\n' + ' .\n' + '@base .\n' + ' .' + '@base .\n' + '<> .', ['http://ex.org/?', 'http://ex.org/?a', 'http://ex.org/?a=b'], ['http://ex.org/d?', 'http://ex.org/d?a', 'http://ex.org/d?a=b'], ['http://ex.org/d?e', 'http://ex.org/d?a', 'http://ex.org/d?a=b'])); it('should not resolve IRIs with colons', shouldParse('@base .\n' + ' .\n' + ' .\n' + ' .', ['http://ex.org/a', 'http://ex.org/b', 'http://ex.org/c'], ['A:', 'b:', 'c:'], ['a:a', 'b:B', 'C-D:c'])); it('should not allow relative URIs with a colon in the first path segment', shouldNotParse(' .', 'Invalid IRI on line 1.')); it('should not allow relative URIs with a colon in the first path segment as base', shouldNotParse('@base .', 'Expected valid IRI to follow base declaration on line 1.')); it('should resolve datatype IRIs against @base', shouldParse('@base .\n' + ' "c"^^.\n' + '@base .\n' + ' "g"^^.', ['http://ex.org/a', 'http://ex.org/b', '"c"^^http://ex.org/d'], ['http://ex.org/d/e', 'http://ex.org/d/f', '"g"^^http://ex.org/d/h'])); it('should resolve IRIs against a base with a fragment', shouldParse('@base .\n' + ' <#c>.\n', ['http://ex.org/a', 'http://ex.org/b', 'http://ex.org/foo#c'])); it('should resolve IRIs with an empty fragment', shouldParse('@base .\n' + '<#> <#c>.\n', ['http://ex.org/foo#', 'http://ex.org/b#', 'http://ex.org/foo#c'])); it('should not resolve prefixed names', shouldParse('PREFIX ex: \n' + 'ex:a ex:b ex:c .', ['http://ex.org/a/bb/ccc/../a', 'http://ex.org/a/bb/ccc/../b', 'http://ex.org/a/bb/ccc/../c'])); it('should parse an empty default graph', shouldParse('{}')); it('should parse a one-triple default graph ending without a dot', shouldParse('{ }', ['a', 'b', 'c'])); it('should parse a one-triple default graph ending with a dot', shouldParse('{ .}', ['a', 'b', 'c'])); it('should parse a three-triple default graph ending without a dot', shouldParse('{ ; ,}', ['a', 'b', 'c'], ['a', 'd', 'e'], ['a', 'd', 'f'])); it('should parse a three-triple default graph ending with a dot', shouldParse('{ ; ,.}', ['a', 'b', 'c'], ['a', 'd', 'e'], ['a', 'd', 'f'])); it('should parse a three-triple default graph ending with a semicolon', shouldParse('{ ; ,;}', ['a', 'b', 'c'], ['a', 'd', 'e'], ['a', 'd', 'f'])); it('should parse a default graph with a blank node ending with a dot', shouldParse('{ [

]. }', ['_:b0', 'p', 'o'])); it('should parse a default graph with a blank node ending without a dot', shouldParse('{ [

] }', ['_:b0', 'p', 'o'])); it('should parse an empty named graph with an IRI', shouldParse('{}')); it('should parse a one-triple named graph with an IRI ending without a dot', shouldParse(' { }', ['a', 'b', 'c', 'g'])); it('should parse a one-triple named graph with an IRI ending with a dot', shouldParse('{ .}', ['a', 'b', 'c', 'g'])); it('should parse a three-triple named graph with an IRI ending without a dot', shouldParse(' { ; ,}', ['a', 'b', 'c', 'g'], ['a', 'd', 'e', 'g'], ['a', 'd', 'f', 'g'])); it('should parse a three-triple named graph with an IRI ending with a dot', shouldParse('{ ; ,.}', ['a', 'b', 'c', 'g'], ['a', 'd', 'e', 'g'], ['a', 'd', 'f', 'g'])); it('should parse an empty named graph with a prefixed name', shouldParse('@prefix g: .\ng:h {}')); it('should parse a one-triple named graph with a prefixed name ending without a dot', shouldParse('@prefix g: .\ng:h { }', ['a', 'b', 'c', 'g#h'])); it('should parse a one-triple named graph with a prefixed name ending with a dot', shouldParse('@prefix g: .\ng:h{ .}', ['a', 'b', 'c', 'g#h'])); it('should parse a three-triple named graph with a prefixed name ending without a dot', shouldParse('@prefix g: .\ng:h { ; ,}', ['a', 'b', 'c', 'g#h'], ['a', 'd', 'e', 'g#h'], ['a', 'd', 'f', 'g#h'])); it('should parse a three-triple named graph with a prefixed name ending with a dot', shouldParse('@prefix g: .\ng:h{ ; ,.}', ['a', 'b', 'c', 'g#h'], ['a', 'd', 'e', 'g#h'], ['a', 'd', 'f', 'g#h'])); it('should parse a named graph with a blank node ending with a dot', shouldParse(' { [

]. }', ['_:b0', 'p', 'o', 'g'])); it('should parse a named graph with a blank node ending without a dot', shouldParse(' { [

] }', ['_:b0', 'p', 'o', 'g'])); it('should parse an empty anonymous graph', shouldParse('[] {}')); it('should parse a one-triple anonymous graph ending without a dot', shouldParse('[] { }', ['a', 'b', 'c', '_:b0'])); it('should parse a one-triple anonymous graph ending with a dot', shouldParse('[]{ .}', ['a', 'b', 'c', '_:b0'])); it('should parse a three-triple anonymous graph ending without a dot', shouldParse('[] { ; ,}', ['a', 'b', 'c', '_:b0'], ['a', 'd', 'e', '_:b0'], ['a', 'd', 'f', '_:b0'])); it('should parse a three-triple anonymous graph ending with a dot', shouldParse('[]{ ; ,.}', ['a', 'b', 'c', '_:b0'], ['a', 'd', 'e', '_:b0'], ['a', 'd', 'f', '_:b0'])); it('should parse an empty named graph with an IRI and the GRAPH keyword', shouldParse('GRAPH {}')); it('should parse an empty named graph with a prefixed name and the GRAPH keyword', shouldParse('@prefix g: .\nGRAPH g:h {}')); it('should parse an empty anonymous graph and the GRAPH keyword', shouldParse('GRAPH [] {}')); it('should parse a one-triple named graph with an IRI and the GRAPH keyword', shouldParse('GRAPH { }', ['a', 'b', 'c', 'g'])); it('should parse a one-triple named graph with a prefixed name and the GRAPH keyword', shouldParse('@prefix g: .\nGRAPH g:h { }', ['a', 'b', 'c', 'g#h'])); it('should parse a one-triple anonymous graph and the GRAPH keyword', shouldParse('GRAPH [] { }', ['a', 'b', 'c', '_:b0'])); it('should parse a graph with 8-bit unicode escape sequences', shouldParse('<\\U0001d400> {\n<\\U0001d400> <\\U0001d400> "\\U0001d400"^^<\\U0001d400>\n}\n', ['\ud835\udC00', '\ud835\udc00', '"\ud835\udc00"^^http://example.org/\ud835\udc00', '\ud835\udc00'])); it('should not parse a single closing brace', shouldNotParse('}', 'Unexpected graph closing on line 1.')); it('should not parse a single opening brace', shouldNotParse('{', 'Expected entity but got eof on line 1.')); it('should not parse a superfluous closing brace ', shouldNotParse('{}}', 'Unexpected graph closing on line 1.')); it('should not parse a graph with only a dot', shouldNotParse('{.}', 'Expected entity but got . on line 1.')); it('should not parse a graph with only a semicolon', shouldNotParse('{;}', 'Expected entity but got ; on line 1.')); it('should not parse an unclosed graph', shouldNotParse('{ .', 'Unclosed graph on line 1.')); it('should not parse a named graph with a list node as label', shouldNotParse('() {}', 'Expected entity but got { on line 1.')); it('should not parse a named graph with a non-empty blank node as label', shouldNotParse('[ ] {}', 'Expected entity but got { on line 1.')); it('should not parse a named graph with the GRAPH keyword and a non-empty blank node as label', shouldNotParse('GRAPH [ ] {}', 'Invalid graph label on line 1.')); it('should not parse a triple after the GRAPH keyword', shouldNotParse('GRAPH .', 'Expected graph but got IRI on line 1.')); it('should not parse repeated GRAPH keywords', shouldNotParse('GRAPH GRAPH {}', 'Invalid graph label on line 1.')); it('should parse a quad with 4 IRIs', shouldParse(' .', ['a', 'b', 'c', 'g'])); it('should parse a quad with 4 prefixed names', shouldParse('@prefix p: .\np:a p:b p:c p:g.', ['p#a', 'p#b', 'p#c', 'p#g'])); it('should not parse a quad with an undefined prefix', shouldNotParse(' p:g.', 'Undefined prefix "p:" on line 1.')); it('should parse a quad with 3 IRIs and a literal', shouldParse(' "c"^^ .', ['a', 'b', '"c"^^http://example.org/d', 'g'])); it('should parse a quad with 2 blank nodes and a literal', shouldParse('_:a "c"^^ _:g.', ['_:b0_a', 'b', '"c"^^http://example.org/d', '_:b0_g'])); it('should not parse a quad in a graph', shouldNotParse('{ .}', 'Expected punctuation to follow "http://example.org/c" on line 1.')); it('should not parse a quad with different punctuation', shouldNotParse(' ;', 'Expected dot to follow quad on line 1.')); it('should not parse base declarations without IRI', shouldNotParse('@base a: ', 'Expected valid IRI to follow base declaration on line 1.')); it('should not parse improperly nested parentheses and brackets', shouldNotParse(' [ (]).', 'Expected entity but got ] on line 1.')); it('should not parse improperly nested square brackets', shouldNotParse(' [ ]].', 'Expected entity but got ] on line 1.')); it('should error when an object is not there', shouldNotParse(' .', 'Expected entity but got . on line 1.')); it('should error when a dot is not there', shouldNotParse(' ', 'Expected entity but got eof on line 1.')); it('should error with an abbreviation in the subject', shouldNotParse('a .', 'Expected entity but got abbreviation on line 1.')); it('should error with an abbreviation in the object', shouldNotParse(' a .', 'Expected entity but got abbreviation on line 1.')); it('should error if punctuation follows a subject', shouldNotParse(' .', 'Unexpected . on line 1.')); it('should error if an unexpected token follows a subject', shouldNotParse(' [', 'Expected entity but got [ on line 1.'), { token: { line: 1, type: '@PREFIX', value: '', prefix: '', }, previousToken: undefined, line: 1, }); it('should not error if there is no triple callback', function () { new N3Parser().parse(''); }); it('should return prefixes through a callback', function (done) { var prefixes = {}; new N3Parser().parse('@prefix a: . a:a a:b a:c. @prefix b: .', tripleCallback, prefixCallback); function tripleCallback(error, triple) { expect(error).not.to.exist; if (!triple) { Object.keys(prefixes).should.have.length(2); expect(prefixes).to.have.property('a'); expect(prefixes.a).to.deep.equal(new NamedNode('http://a.org/#')); expect(prefixes).to.have.property('b'); expect(prefixes.b).to.deep.equal(new NamedNode('http://b.org/#')); done(); } } function prefixCallback(prefix, iri) { expect(prefix).to.exist; expect(iri).to.exist; prefixes[prefix] = iri; } }); it('should return prefixes through a callback without triple callback', function (done) { var prefixes = {}; new N3Parser().parse('@prefix a: . a:a a:b a:c. @prefix b: .', null, prefixCallback); function prefixCallback(prefix, iri) { expect(prefix).to.exist; expect(iri).to.exist; prefixes[prefix] = iri; if (Object.keys(prefixes).length === 2) done(); } }); it('should return prefixes at the last triple callback', function (done) { new N3Parser({ baseIRI: BASE_IRI }) .parse('@prefix a: . a:a a:b a:c. @prefix b: .', tripleCallback); function tripleCallback(error, triple, prefixes) { expect(error).not.to.exist; if (triple) expect(prefixes).not.to.exist; else { expect(prefixes).to.exist; Object.keys(prefixes).should.have.length(2); expect(prefixes).to.have.property('a', 'http://example.org/IRIa'); expect(prefixes).to.have.property('b', 'http://example.org/IRIb'); done(); } } }); it('should parse a string synchronously if no callback is given', function () { var triples = new N3Parser().parse('@prefix a: . a:a a:b a:c.'); triples.should.deep.equal([ new Quad(fromId('urn:a:a'), fromId('urn:a:b'), fromId('urn:a:c'), fromId('')), ]); }); it('should throw on syntax errors if no callback is given', function () { (function () { new N3Parser().parse(' bar '); }) .should.throw('Unexpected "bar" on line 1.').with.property('context').with.property('line', 1); }); it('should throw on grammar errors if no callback is given', function () { (function () { new N3Parser().parse(' '); }) .should.throw('Expected entity but got eof on line 1'); }); }); describe('An N3Parser instance with a document IRI', function () { function parser() { return new N3Parser({ baseIRI: 'http://ex.org/x/yy/zzz/f.ttl' }); } it('should resolve IRIs against the document IRI', shouldParse(parser, '@prefix : <#>.\n' + ' .\n' + ':d :e :f :g.', ['http://ex.org/x/yy/zzz/a', 'http://ex.org/x/yy/zzz/b', 'http://ex.org/x/yy/zzz/c', 'http://ex.org/x/yy/zzz/g'], ['http://ex.org/x/yy/zzz/f.ttl#d', 'http://ex.org/x/yy/zzz/f.ttl#e', 'http://ex.org/x/yy/zzz/f.ttl#f', 'http://ex.org/x/yy/zzz/f.ttl#g'])); it('should resolve IRIs with a trailing slash against the document IRI', shouldParse(parser, ' .\n', ['http://ex.org/a', 'http://ex.org/a/b', 'http://ex.org/a/b/c'])); it('should resolve IRIs starting with ./ against the document IRI', shouldParse(parser, '<./a> <./a/b> <./a/b/c>.\n', ['http://ex.org/x/yy/zzz/a', 'http://ex.org/x/yy/zzz/a/b', 'http://ex.org/x/yy/zzz/a/b/c'])); it('should resolve IRIs starting with multiple ./ sequences against the document IRI', shouldParse(parser, '<./././a> <./././././a/b> <././././././a/b/c>.\n', ['http://ex.org/x/yy/zzz/a', 'http://ex.org/x/yy/zzz/a/b', 'http://ex.org/x/yy/zzz/a/b/c'])); it('should resolve IRIs starting with ../ against the document IRI', shouldParse(parser, '<../a> <../a/b> <../a/b/c>.\n', ['http://ex.org/x/yy/a', 'http://ex.org/x/yy/a/b', 'http://ex.org/x/yy/a/b/c'])); it('should resolve IRIs starting multiple ../ sequences against the document IRI', shouldParse(parser, '<../../a> <../../../a/b> <../../../../../../../../a/b/c>.\n', ['http://ex.org/x/a', 'http://ex.org/a/b', 'http://ex.org/a/b/c'])); it('should resolve IRIs starting with mixes of ./ and ../ sequences against the document IRI', shouldParse(parser, '<.././a> <./.././a/b> <./.././.././a/b/c>.\n', ['http://ex.org/x/yy/a', 'http://ex.org/x/yy/a/b', 'http://ex.org/x/a/b/c'])); it('should resolve IRIs starting with .x, ..x, or .../ against the document IRI', shouldParse(parser, '<.x/a> <..x/a/b> <.../a/b/c>.\n', ['http://ex.org/x/yy/zzz/.x/a', 'http://ex.org/x/yy/zzz/..x/a/b', 'http://ex.org/x/yy/zzz/.../a/b/c'])); it('should resolve datatype IRIs against the document IRI', shouldParse(parser, ' "c"^^.', ['http://ex.org/x/yy/zzz/a', 'http://ex.org/x/yy/zzz/b', '"c"^^http://ex.org/x/yy/zzz/d'])); it('should resolve IRIs in lists against the document IRI', shouldParse(parser, '( )

( ).', ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'http://ex.org/x/yy/zzz/a'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', '_:b1'], ['_:b1', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'http://ex.org/x/yy/zzz/b'], ['_:b1', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'], ['_:b0', 'http://ex.org/x/yy/zzz/p', '_:b2'], ['_:b2', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'http://ex.org/x/yy/zzz/c'], ['_:b2', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', '_:b3'], ['_:b3', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'http://ex.org/x/yy/zzz/d'], ['_:b3', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'])); it('should respect @base statements', shouldParse(parser, ' .\n' + '@base .\n' + ' .\n' + '@base .\n' + ' .\n' + '@base .\n' + ' .', ['http://ex.org/x/yy/zzz/a', 'http://ex.org/x/yy/zzz/b', 'http://ex.org/x/yy/zzz/c'], ['http://ex.org/x/e', 'http://ex.org/x/f', 'http://ex.org/x/g'], ['http://ex.org/x/d/h', 'http://ex.org/x/d/i', 'http://ex.org/x/d/j'], ['http://ex.org/e/k', 'http://ex.org/e/l', 'http://ex.org/e/m'])); }); describe('An N3Parser instance with a blank node prefix', function () { function parser() { return new N3Parser({ baseIRI: BASE_IRI, blankNodePrefix: '_:blank' }); } it('should use the given prefix for blank nodes', shouldParse(parser, '_:a _:c.\n', ['_:blanka', 'b', '_:blankc'])); }); describe('An N3Parser instance with an empty blank node prefix', function () { function parser() { return new N3Parser({ baseIRI: BASE_IRI, blankNodePrefix: '' }); } it('should not use a prefix for blank nodes', shouldParse(parser, '_:a _:c.\n', ['_:a', 'b', '_:c'])); }); describe('An N3Parser instance with a non-string format', function () { function parser() { return new N3Parser({ baseIRI: BASE_IRI, format: 1 }); } it('should parse a single triple', shouldParse(parser, ' .', ['a', 'b', 'c'])); it('should parse a graph', shouldParse(parser, '{ }', ['a', 'b', 'c'])); }); describe('An N3Parser instance for the Turtle format', function () { function parser() { return new N3Parser({ baseIRI: BASE_IRI, format: 'Turtle' }); } it('should parse a single triple', shouldParse(parser, ' .', ['a', 'b', 'c'])); it('should not parse a default graph', shouldNotParse(parser, '{}', 'Unexpected graph on line 1.')); it('should not parse a named graph', shouldNotParse(parser, ' {}', 'Expected entity but got { on line 1.')); it('should not parse a named graph with the GRAPH keyword', shouldNotParse(parser, 'GRAPH {}', 'Expected entity but got GRAPH on line 1.')); it('should not parse a quad', shouldNotParse(parser, ' .', 'Expected punctuation to follow "http://example.org/c" on line 1.')); it('should not parse a variable', shouldNotParse(parser, '?a ?b ?c.', 'Unexpected "?a" on line 1.')); it('should not parse an equality statement', shouldNotParse(parser, ' = .', 'Unexpected "=" on line 1.')); it('should not parse a right implication statement', shouldNotParse(parser, ' => .', 'Unexpected "=>" on line 1.')); it('should not parse a left implication statement', shouldNotParse(parser, ' <= .', 'Unexpected "<=" on line 1.')); it('should not parse a formula as object', shouldNotParse(parser, ' {}.', 'Unexpected graph on line 1.')); it('should not parse @forSome', shouldNotParse(parser, '@forSome .', 'Unexpected "@forSome" on line 1.')); it('should not parse @forAll', shouldNotParse(parser, '@forAll .', 'Unexpected "@forAll" on line 1.')); }); describe('An N3Parser instance for the TriG format', function () { function parser() { return new N3Parser({ baseIRI: BASE_IRI, format: 'TriG' }); } it('should parse a single triple', shouldParse(parser, ' .', ['a', 'b', 'c'])); it('should parse a default graph', shouldParse(parser, '{}')); it('should parse a named graph', shouldParse(parser, ' {}')); it('should parse a named graph with the GRAPH keyword', shouldParse(parser, 'GRAPH {}')); it('should not parse a quad', shouldNotParse(parser, ' .', 'Expected punctuation to follow "http://example.org/c" on line 1.')); it('should not parse a variable', shouldNotParse(parser, '?a ?b ?c.', 'Unexpected "?a" on line 1.')); it('should not parse an equality statement', shouldNotParse(parser, ' = .', 'Unexpected "=" on line 1.')); it('should not parse a right implication statement', shouldNotParse(parser, ' => .', 'Unexpected "=>" on line 1.')); it('should not parse a left implication statement', shouldNotParse(parser, ' <= .', 'Unexpected "<=" on line 1.')); it('should not parse a formula as object', shouldNotParse(parser, ' {}.', 'Unexpected graph on line 1.')); it('should not parse @forSome', shouldNotParse(parser, '@forSome .', 'Unexpected "@forSome" on line 1.')); it('should not parse @forAll', shouldNotParse(parser, '@forAll .', 'Unexpected "@forAll" on line 1.')); }); describe('An N3Parser instance for the N-Triples format', function () { function parser() { return new N3Parser({ baseIRI: BASE_IRI, format: 'N-Triples' }); } it('should parse a single triple', shouldParse(parser, '_:a "c".', ['_:b0_a', 'http://ex.org/b', '"c"'])); it('should not parse a single quad', shouldNotParse(parser, '_:a "c" .', 'Expected punctuation to follow ""c"" on line 1.')); it('should not parse relative IRIs', shouldNotParse(parser, ' .', 'Invalid IRI on line 1.')); it('should not parse a prefix declaration', shouldNotParse(parser, '@prefix : .', 'Unexpected "@prefix" on line 1.')); it('should not parse triple-quoted literals', shouldNotParse(parser, '_:a """c""".', 'Unexpected """"c"""." on line 1.')); it('should not parse triple-apostrophe literals', shouldNotParse(parser, "_:a '''c'''.", "Unexpected \"'''c'''.\" on line 1.")); it('should not parse a variable', shouldNotParse(parser, '?a ?b ?c.', 'Unexpected "?a" on line 1.')); it('should not parse an equality statement', shouldNotParse(parser, ' = .', 'Unexpected "=" on line 1.')); it('should not parse a right implication statement', shouldNotParse(parser, ' => .', 'Unexpected "=>" on line 1.')); it('should not parse a left implication statement', shouldNotParse(parser, ' <= .', 'Unexpected "<=" on line 1.')); it('should not parse a formula as object', shouldNotParse(parser, ' {}.', 'Unexpected "{}." on line 1.')); it('should not parse @forSome', shouldNotParse(parser, '@forSome .', 'Unexpected "@forSome" on line 1.')); it('should not parse @forAll', shouldNotParse(parser, '@forAll .', 'Unexpected "@forAll" on line 1.')); }); describe('An N3Parser instance for the N-Quads format', function () { function parser() { return new N3Parser({ baseIRI: BASE_IRI, format: 'N-Quads' }); } it('should parse a single triple', shouldParse(parser, '_:a "c".', ['_:b0_a', 'http://ex.org/b', '"c"'])); it('should parse a single quad', shouldParse(parser, '_:a "c" .', ['_:b0_a', 'http://ex.org/b', '"c"', 'http://ex.org/g'])); it('should not parse relative IRIs', shouldNotParse(parser, ' .', 'Invalid IRI on line 1.')); it('should not parse a prefix declaration', shouldNotParse(parser, '@prefix : .', 'Unexpected "@prefix" on line 1.')); it('should not parse a variable', shouldNotParse(parser, '?a ?b ?c.', 'Unexpected "?a" on line 1.')); it('should not parse an equality statement', shouldNotParse(parser, ' = .', 'Unexpected "=" on line 1.')); it('should not parse a right implication statement', shouldNotParse(parser, ' => .', 'Unexpected "=>" on line 1.')); it('should not parse a left implication statement', shouldNotParse(parser, ' <= .', 'Unexpected "<=" on line 1.')); it('should not parse a formula as object', shouldNotParse(parser, ' {}.', 'Unexpected "{}." on line 1.')); it('should not parse @forSome', shouldNotParse(parser, '@forSome .', 'Unexpected "@forSome" on line 1.')); it('should not parse @forAll', shouldNotParse(parser, '@forAll .', 'Unexpected "@forAll" on line 1.')); }); describe('An N3Parser instance for the N3 format', function () { function parser() { return new N3Parser({ baseIRI: BASE_IRI, format: 'N3' }); } it('should parse a single triple', shouldParse(parser, ' .', ['a', 'b', 'c'])); it('should not parse a default graph', shouldNotParse(parser, '{}', 'Expected entity but got eof on line 1.')); it('should not parse a named graph', shouldNotParse(parser, ' {}', 'Expected entity but got { on line 1.')); it('should not parse a named graph with the GRAPH keyword', shouldNotParse(parser, 'GRAPH {}', 'Expected entity but got GRAPH on line 1.')); it('should not parse a quad', shouldNotParse(parser, ' .', 'Expected punctuation to follow "http://example.org/c" on line 1.')); it('allows a blank node label in predicate position', shouldParse(parser, ' _:b .', ['a', '_:b0_b', 'c'])); it('should parse a variable', shouldParse(parser, '?a ?b ?c.', ['?a', '?b', '?c'])); it('should parse a simple equality', shouldParse(parser, ' = .', ['a', 'http://www.w3.org/2002/07/owl#sameAs', 'b'])); it('should parse a simple right implication', shouldParse(parser, ' => .', ['a', 'http://www.w3.org/2000/10/swap/log#implies', 'b'])); it('should parse a simple left implication', shouldParse(parser, ' <= .', ['b', 'http://www.w3.org/2000/10/swap/log#implies', 'a'])); it('should parse a right implication between one-triple graphs', shouldParse(parser, '{ ?a ?b . } => { ?a }.', ['_:b0', 'http://www.w3.org/2000/10/swap/log#implies', '_:b1'], ['?a', '?b', 'c', '_:b0'], ['d', 'e', '?a', '_:b1'])); it('should parse a right implication between two-triple graphs', shouldParse(parser, '{ ?a ?b . . } => { ?a, }.', ['_:b0', 'http://www.w3.org/2000/10/swap/log#implies', '_:b1'], ['?a', '?b', 'c', '_:b0'], ['d', 'e', 'f', '_:b0'], ['d', 'e', '?a', '_:b1'], ['d', 'e', 'f', '_:b1'])); it('should parse a left implication between one-triple graphs', shouldParse(parser, '{ ?a ?b . } <= { ?a }.', ['_:b1', 'http://www.w3.org/2000/10/swap/log#implies', '_:b0'], ['?a', '?b', 'c', '_:b0'], ['d', 'e', '?a', '_:b1'])); it('should parse a left implication between two-triple graphs', shouldParse(parser, '{ ?a ?b . . } <= { ?a, }.', ['_:b1', 'http://www.w3.org/2000/10/swap/log#implies', '_:b0'], ['?a', '?b', 'c', '_:b0'], ['d', 'e', 'f', '_:b0'], ['d', 'e', '?a', '_:b1'], ['d', 'e', 'f', '_:b1'])); it('should parse an equality of one-triple graphs', shouldParse(parser, '{ ?a ?b . } = { ?a }.', ['_:b0', 'http://www.w3.org/2002/07/owl#sameAs', '_:b1'], ['?a', '?b', 'c', '_:b0'], ['d', 'e', '?a', '_:b1'])); it('should parse an equality of two-triple graphs', shouldParse(parser, '{ ?a ?b . . } = { ?a, }.', ['_:b0', 'http://www.w3.org/2002/07/owl#sameAs', '_:b1'], ['?a', '?b', 'c', '_:b0'], ['d', 'e', 'f', '_:b0'], ['d', 'e', '?a', '_:b1'], ['d', 'e', 'f', '_:b1'])); it('should parse nested implication graphs', shouldParse(parser, '{ { ?a ?b ?c }<={ ?d ?e ?f }. } <= { { ?g ?h ?i } => { ?j ?k ?l } }.', ['_:b3', 'http://www.w3.org/2000/10/swap/log#implies', '_:b0'], ['_:b2', 'http://www.w3.org/2000/10/swap/log#implies', '_:b1', '_:b0'], ['?a', '?b', '?c', '_:b1'], ['?d', '?e', '?f', '_:b2'], ['_:b4', 'http://www.w3.org/2000/10/swap/log#implies', '_:b5', '_:b3'], ['?g', '?h', '?i', '_:b4'], ['?j', '?k', '?l', '_:b5'])); it('should not reuse identifiers of blank nodes within and outside of formulas', shouldParse(parser, '_:a _:b _:c. { _:a _:b _:c } => { { _:a _:b _:c } => { _:a _:b _:c } }.', ['_:b0_a', '_:b0_b', '_:b0_c'], ['_:b0', 'http://www.w3.org/2000/10/swap/log#implies', '_:b1', ''], ['_:b0.a', '_:b0.b', '_:b0.c', '_:b0'], ['_:b2', 'http://www.w3.org/2000/10/swap/log#implies', '_:b3', '_:b1'], ['_:b2.a', '_:b2.b', '_:b2.c', '_:b2'], ['_:b3.a', '_:b3.b', '_:b3.c', '_:b3'])); it('should parse a @forSome statement', shouldParse(parser, '@forSome . .', ['_:b0', '_:b0', '_:b0'])); it('should parse a @forSome statement with multiple entities', shouldParse(parser, '@prefix a: . @base . @forSome a:x, , a:z. a:x a:z.', ['_:b0', '_:b1', '_:b2'])); it('should not parse a @forSome statement with an invalid prefix', shouldNotParse(parser, '@forSome a:b.', 'Undefined prefix "a:" on line 1.')); it('should not parse a @forSome statement with a blank node', shouldNotParse(parser, '@forSome _:a.', 'Unexpected blank on line 1.')); it('should not parse a @forSome statement with a variable', shouldNotParse(parser, '@forSome ?a.', 'Unexpected var on line 1.')); it('should correctly scope @forSome statements', shouldParse(parser, '@forSome . { @forSome . . }. .', ['_:b0', '_:b0', '_:b1'], ['_:b2', '_:b2', '_:b2', '_:b1'], ['_:b0', '_:b0', '_:b0'])); it('should parse a @forAll statement', shouldParse(parser, '@forAll . .', ['?b0', '?b0', '?b0'])); it('should parse a @forAll statement with multiple entities', shouldParse(parser, '@prefix a: . @base . @forAll a:x, , a:z. a:x a:z.', ['?b0', '?b1', '?b2'])); it('should not parse a @forAll statement with an invalid prefix', shouldNotParse(parser, '@forAll a:b.', 'Undefined prefix "a:" on line 1.')); it('should not parse a @forAll statement with a blank node', shouldNotParse(parser, '@forAll _:a.', 'Unexpected blank on line 1.')); it('should not parse a @forAll statement with a variable', shouldNotParse(parser, '@forAll ?a.', 'Unexpected var on line 1.')); it('should correctly scope @forAll statements', shouldParse(parser, '@forAll . { @forAll . . }. .', ['?b0', '?b0', '_:b1'], ['?b2', '?b2', '?b2', '_:b1'], ['?b0', '?b0', '?b0'])); it('should parse a ! path of length 2 as subject', shouldParse(parser, '@prefix : . @prefix fam: .' + ':joe!fam:mother a fam:Person.', ['ex:joe', 'f:mother', '_:b0'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', 'f:Person'])); it('should parse a ! path of length 4 as subject', shouldParse(parser, '@prefix : . @prefix fam: . @prefix loc: .' + ':joe!fam:mother!loc:office!loc:zip loc:code 1234.', ['ex:joe', 'f:mother', '_:b0'], ['_:b0', 'l:office', '_:b1'], ['_:b1', 'l:zip', '_:b2'], ['_:b2', 'l:code', '"1234"^^http://www.w3.org/2001/XMLSchema#integer'])); it('should parse a ! path of length 2 as object', shouldParse(parser, '@prefix : . @prefix fam: .' + ' :joe!fam:mother.', ['x', 'is', '_:b0'], ['ex:joe', 'f:mother', '_:b0'])); it('should parse a ! path of length 4 as object', shouldParse(parser, '@prefix : . @prefix fam: . @prefix loc: .' + ' :joe!fam:mother!loc:office!loc:zip.', ['x', 'is', '_:b2'], ['ex:joe', 'f:mother', '_:b0'], ['_:b0', 'l:office', '_:b1'], ['_:b1', 'l:zip', '_:b2'])); it('should parse a ^ path of length 2 as subject', shouldParse(parser, '@prefix : . @prefix fam: .' + ':joe^fam:son a fam:Person.', ['_:b0', 'f:son', 'ex:joe'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', 'f:Person'])); it('should parse a ^ path of length 4 as subject', shouldParse(parser, '@prefix : . @prefix fam: .' + ':joe^fam:son^fam:sister^fam:mother a fam:Person.', ['_:b0', 'f:son', 'ex:joe'], ['_:b1', 'f:sister', '_:b0'], ['_:b2', 'f:mother', '_:b1'], ['_:b2', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', 'f:Person'])); it('should parse a ^ path of length 2 as object', shouldParse(parser, '@prefix : . @prefix fam: .' + ' :joe^fam:son.', ['x', 'is', '_:b0'], ['_:b0', 'f:son', 'ex:joe'])); it('should parse a ^ path of length 4 as object', shouldParse(parser, '@prefix : . @prefix fam: .' + ' :joe^fam:son^fam:sister^fam:mother.', ['x', 'is', '_:b2'], ['_:b0', 'f:son', 'ex:joe'], ['_:b1', 'f:sister', '_:b0'], ['_:b2', 'f:mother', '_:b1'])); it('should parse mixed !/^ paths as subject', shouldParse(parser, '@prefix : . @prefix fam: .' + ':joe!fam:mother^fam:mother a fam:Person.', ['ex:joe', 'f:mother', '_:b0'], ['_:b1', 'f:mother', '_:b0'], ['_:b1', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', 'f:Person'])); it('should parse mixed !/^ paths as object', shouldParse(parser, '@prefix : . @prefix fam: .' + ' :joe!fam:mother^fam:mother.', ['x', 'is', '_:b1'], ['ex:joe', 'f:mother', '_:b0'], ['_:b1', 'f:mother', '_:b0'])); it('should parse a ! path in a blank node as subject', shouldParse(parser, '@prefix : . @prefix fam: .' + '[fam:knows :joe!fam:mother] a fam:Person.', ['_:b0', 'f:knows', '_:b1'], ['ex:joe', 'f:mother', '_:b1'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', 'f:Person'])); it('should parse a ! path in a blank node as object', shouldParse(parser, '@prefix : . @prefix fam: .' + ' [fam:knows :joe!fam:mother].', ['x', 'is', '_:b0'], ['_:b0', 'f:knows', '_:b1'], ['ex:joe', 'f:mother', '_:b1'])); it('should parse a ^ path in a blank node as subject', shouldParse(parser, '@prefix : . @prefix fam: .' + '[fam:knows :joe^fam:son] a fam:Person.', ['_:b0', 'f:knows', '_:b1'], ['_:b1', 'f:son', 'ex:joe'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', 'f:Person'])); it('should parse a ^ path in a blank node as object', shouldParse(parser, '@prefix : . @prefix fam: .' + ' [fam:knows :joe^fam:son].', ['x', 'is', '_:b0'], ['_:b0', 'f:knows', '_:b1'], ['_:b1', 'f:son', 'ex:joe'])); it('should parse a ! path in a list as subject', shouldParse(parser, '@prefix : . @prefix fam: .' + '( :joe!fam:mother ) a :List.', ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', 'ex:List'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'x'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', '_:b1'], ['_:b1', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', '_:b2'], ['_:b1', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', '_:b3'], ['_:b3', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'y'], ['_:b3', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'], ['ex:joe', 'f:mother', '_:b2'])); it('should parse a ! path in a list as object', shouldParse(parser, '@prefix : . @prefix fam: .' + ' ( :joe!fam:mother ).', ['l', 'is', '_:b0'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'x'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', '_:b1'], ['_:b1', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', '_:b2'], ['_:b1', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', '_:b3'], ['_:b3', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'y'], ['_:b3', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'], ['ex:joe', 'f:mother', '_:b2'])); it('should parse a ^ path in a list as subject', shouldParse(parser, '@prefix : . @prefix fam: .' + '( :joe^fam:son ) a :List.', ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', 'ex:List'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'x'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', '_:b1'], ['_:b1', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', '_:b2'], ['_:b1', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', '_:b3'], ['_:b3', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'y'], ['_:b3', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'], ['_:b2', 'f:son', 'ex:joe'])); it('should parse a ^ path in a list as object', shouldParse(parser, '@prefix : . @prefix fam: .' + ' ( :joe^fam:son ).', ['l', 'is', '_:b0'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'x'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', '_:b1'], ['_:b1', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', '_:b2'], ['_:b1', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', '_:b3'], ['_:b3', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'y'], ['_:b3', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'], ['_:b2', 'f:son', 'ex:joe'])); it('should not parse an invalid ! path', shouldNotParse(parser, '!"invalid" ', 'Expected entity but got literal on line 1.')); it('should not parse an invalid ^ path', shouldNotParse(parser, '^"invalid" ', 'Expected entity but got literal on line 1.')); }); describe('An N3Parser instance for the N3 format with the explicitQuantifiers option', function () { function parser() { return new N3Parser({ baseIRI: BASE_IRI, format: 'N3', explicitQuantifiers: true }); } it('should parse a @forSome statement', shouldParse(parser, '@forSome . .', ['', 'http://www.w3.org/2000/10/swap/reify#forSome', '_:b0', 'urn:n3:quantifiers'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'x', 'urn:n3:quantifiers'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil', 'urn:n3:quantifiers'], ['x', 'x', 'x'])); it('should parse a @forSome statement with multiple entities', shouldParse(parser, '@prefix a: . @base . @forSome a:x, , a:z. a:x a:z.', ['', 'http://www.w3.org/2000/10/swap/reify#forSome', '_:b0', 'urn:n3:quantifiers'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'a:x', 'urn:n3:quantifiers'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', '_:b1', 'urn:n3:quantifiers'], ['_:b1', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'b:y', 'urn:n3:quantifiers'], ['_:b1', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', '_:b2', 'urn:n3:quantifiers'], ['_:b2', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'a:z', 'urn:n3:quantifiers'], ['_:b2', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil', 'urn:n3:quantifiers'], ['a:x', 'b:y', 'a:z'])); it('should correctly scope @forSome statements', shouldParse(parser, '@forSome . { @forSome . . }. .', ['', 'http://www.w3.org/2000/10/swap/reify#forSome', '_:b0', 'urn:n3:quantifiers'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'x', 'urn:n3:quantifiers'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil', 'urn:n3:quantifiers'], ['x', 'x', '_:b1'], ['_:b1', 'http://www.w3.org/2000/10/swap/reify#forSome', '_:b2', 'urn:n3:quantifiers'], ['_:b2', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'x', 'urn:n3:quantifiers'], ['_:b2', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil', 'urn:n3:quantifiers'], ['x', 'x', 'x', '_:b1'], ['x', 'x', 'x'])); it('should parse a @forAll statement', shouldParse(parser, '@forAll . .', ['', 'http://www.w3.org/2000/10/swap/reify#forAll', '_:b0', 'urn:n3:quantifiers'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'x', 'urn:n3:quantifiers'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil', 'urn:n3:quantifiers'], ['x', 'x', 'x'])); it('should parse a @forAll statement with multiple entities', shouldParse(parser, '@prefix a: . @base . @forAll a:x, , a:z. a:x a:z.', ['', 'http://www.w3.org/2000/10/swap/reify#forAll', '_:b0', 'urn:n3:quantifiers'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'a:x', 'urn:n3:quantifiers'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', '_:b1', 'urn:n3:quantifiers'], ['_:b1', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'b:y', 'urn:n3:quantifiers'], ['_:b1', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', '_:b2', 'urn:n3:quantifiers'], ['_:b2', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'a:z', 'urn:n3:quantifiers'], ['_:b2', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil', 'urn:n3:quantifiers'], ['a:x', 'b:y', 'a:z'])); it('should correctly scope @forAll statements', shouldParse(parser, '@forAll . { @forAll . . }. .', ['', 'http://www.w3.org/2000/10/swap/reify#forAll', '_:b0', 'urn:n3:quantifiers'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'x', 'urn:n3:quantifiers'], ['_:b0', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil', 'urn:n3:quantifiers'], ['x', 'x', '_:b1'], ['_:b1', 'http://www.w3.org/2000/10/swap/reify#forAll', '_:b2', 'urn:n3:quantifiers'], ['_:b2', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first', 'x', 'urn:n3:quantifiers'], ['_:b2', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil', 'urn:n3:quantifiers'], ['x', 'x', 'x', '_:b1'], ['x', 'x', 'x'])); }); describe('An N3Parser instance with a custom DataFactory', function () { var parser, factory = {}; before(function () { factory.quad = function (s, p, o, g) { return { s: s, p: p, o: o, g: g }; }; ['namedNode', 'blankNode', 'literal', 'variable', 'defaultGraph'].forEach(function (f) { factory[f] = function (n) { return n ? f[0] + '-' + n : f; }; }); parser = new N3Parser({ baseIRI: BASE_IRI, format: 'n3', factory: factory }); }); beforeEach(N3Parser._resetBlankNodeIds); it('should use the custom factory', function () { parser.parse(' ?b 1, _:d.').should.deep.equal([ { s: 'n-http://example.org/a', p: 'v-b', o: 'l-1', g: 'defaultGraph' }, { s: 'n-http://example.org/a', p: 'v-b', o: 'b-b0_d', g: 'defaultGraph' }, ]); }); }); describe('IRI resolution', function () { describe('RFC3986 normal examples', function () { itShouldResolve('http://a/bb/ccc/d;p?q', 'g:h', 'g:h'); itShouldResolve('http://a/bb/ccc/d;p?q', 'g', 'http://a/bb/ccc/g'); itShouldResolve('http://a/bb/ccc/d;p?q', './g', 'http://a/bb/ccc/g'); itShouldResolve('http://a/bb/ccc/d;p?q', 'g/', 'http://a/bb/ccc/g/'); itShouldResolve('http://a/bb/ccc/d;p?q', '/g', 'http://a/g'); itShouldResolve('http://a/bb/ccc/d;p?q', '//g', 'http://g'); itShouldResolve('http://a/bb/ccc/d;p?q', '?y', 'http://a/bb/ccc/d;p?y'); itShouldResolve('http://a/bb/ccc/d;p?q', 'g?y', 'http://a/bb/ccc/g?y'); itShouldResolve('http://a/bb/ccc/d;p?q', '#s', 'http://a/bb/ccc/d;p?q#s'); itShouldResolve('http://a/bb/ccc/d;p?q', 'g#s', 'http://a/bb/ccc/g#s'); itShouldResolve('http://a/bb/ccc/d;p?q', 'g?y#s', 'http://a/bb/ccc/g?y#s'); itShouldResolve('http://a/bb/ccc/d;p?q', ';x', 'http://a/bb/ccc/;x'); itShouldResolve('http://a/bb/ccc/d;p?q', 'g;x', 'http://a/bb/ccc/g;x'); itShouldResolve('http://a/bb/ccc/d;p?q', 'g;x?y#s', 'http://a/bb/ccc/g;x?y#s'); itShouldResolve('http://a/bb/ccc/d;p?q', '', 'http://a/bb/ccc/d;p?q'); itShouldResolve('http://a/bb/ccc/d;p?q', '.', 'http://a/bb/ccc/'); itShouldResolve('http://a/bb/ccc/d;p?q', './', 'http://a/bb/ccc/'); itShouldResolve('http://a/bb/ccc/d;p?q', '..', 'http://a/bb/'); itShouldResolve('http://a/bb/ccc/d;p?q', '../', 'http://a/bb/'); itShouldResolve('http://a/bb/ccc/d;p?q', '../g', 'http://a/bb/g'); itShouldResolve('http://a/bb/ccc/d;p?q', '../..', 'http://a/'); itShouldResolve('http://a/bb/ccc/d;p?q', '../../', 'http://a/'); itShouldResolve('http://a/bb/ccc/d;p?q', '../../g', 'http://a/g'); }); describe('RFC3986 abnormal examples', function () { itShouldResolve('http://a/bb/ccc/d;p?q', '../../../g', 'http://a/g'); itShouldResolve('http://a/bb/ccc/d;p?q', '../../../../g', 'http://a/g'); itShouldResolve('http://a/bb/ccc/d;p?q', '/./g', 'http://a/g'); itShouldResolve('http://a/bb/ccc/d;p?q', '/../g', 'http://a/g'); itShouldResolve('http://a/bb/ccc/d;p?q', 'g.', 'http://a/bb/ccc/g.'); itShouldResolve('http://a/bb/ccc/d;p?q', '.g', 'http://a/bb/ccc/.g'); itShouldResolve('http://a/bb/ccc/d;p?q', 'g..', 'http://a/bb/ccc/g..'); itShouldResolve('http://a/bb/ccc/d;p?q', '..g', 'http://a/bb/ccc/..g'); itShouldResolve('http://a/bb/ccc/d;p?q', './../g', 'http://a/bb/g'); itShouldResolve('http://a/bb/ccc/d;p?q', './g/.', 'http://a/bb/ccc/g/'); itShouldResolve('http://a/bb/ccc/d;p?q', 'g/./h', 'http://a/bb/ccc/g/h'); itShouldResolve('http://a/bb/ccc/d;p?q', 'g/../h', 'http://a/bb/ccc/h'); itShouldResolve('http://a/bb/ccc/d;p?q', 'g;x=1/./y', 'http://a/bb/ccc/g;x=1/y'); itShouldResolve('http://a/bb/ccc/d;p?q', 'g;x=1/../y', 'http://a/bb/ccc/y'); itShouldResolve('http://a/bb/ccc/d;p?q', 'g?y/./x', 'http://a/bb/ccc/g?y/./x'); itShouldResolve('http://a/bb/ccc/d;p?q', 'g?y/../x', 'http://a/bb/ccc/g?y/../x'); itShouldResolve('http://a/bb/ccc/d;p?q', 'g#s/./x', 'http://a/bb/ccc/g#s/./x'); itShouldResolve('http://a/bb/ccc/d;p?q', 'g#s/../x', 'http://a/bb/ccc/g#s/../x'); itShouldResolve('http://a/bb/ccc/d;p?q', 'http:g', 'http:g'); }); describe('RFC3986 normal examples with trailing slash in base IRI', function () { itShouldResolve('http://a/bb/ccc/d/', 'g:h', 'g:h'); itShouldResolve('http://a/bb/ccc/d/', 'g', 'http://a/bb/ccc/d/g'); itShouldResolve('http://a/bb/ccc/d/', './g', 'http://a/bb/ccc/d/g'); itShouldResolve('http://a/bb/ccc/d/', 'g/', 'http://a/bb/ccc/d/g/'); itShouldResolve('http://a/bb/ccc/d/', '/g', 'http://a/g'); itShouldResolve('http://a/bb/ccc/d/', '//g', 'http://g'); itShouldResolve('http://a/bb/ccc/d/', '?y', 'http://a/bb/ccc/d/?y'); itShouldResolve('http://a/bb/ccc/d/', 'g?y', 'http://a/bb/ccc/d/g?y'); itShouldResolve('http://a/bb/ccc/d/', '#s', 'http://a/bb/ccc/d/#s'); itShouldResolve('http://a/bb/ccc/d/', 'g#s', 'http://a/bb/ccc/d/g#s'); itShouldResolve('http://a/bb/ccc/d/', 'g?y#s', 'http://a/bb/ccc/d/g?y#s'); itShouldResolve('http://a/bb/ccc/d/', ';x', 'http://a/bb/ccc/d/;x'); itShouldResolve('http://a/bb/ccc/d/', 'g;x', 'http://a/bb/ccc/d/g;x'); itShouldResolve('http://a/bb/ccc/d/', 'g;x?y#s', 'http://a/bb/ccc/d/g;x?y#s'); itShouldResolve('http://a/bb/ccc/d/', '', 'http://a/bb/ccc/d/'); itShouldResolve('http://a/bb/ccc/d/', '.', 'http://a/bb/ccc/d/'); itShouldResolve('http://a/bb/ccc/d/', './', 'http://a/bb/ccc/d/'); itShouldResolve('http://a/bb/ccc/d/', '..', 'http://a/bb/ccc/'); itShouldResolve('http://a/bb/ccc/d/', '../', 'http://a/bb/ccc/'); itShouldResolve('http://a/bb/ccc/d/', '../g', 'http://a/bb/ccc/g'); itShouldResolve('http://a/bb/ccc/d/', '../..', 'http://a/bb/'); itShouldResolve('http://a/bb/ccc/d/', '../../', 'http://a/bb/'); itShouldResolve('http://a/bb/ccc/d/', '../../g', 'http://a/bb/g'); }); describe('RFC3986 abnormal examples with trailing slash in base IRI', function () { itShouldResolve('http://a/bb/ccc/d/', '../../../g', 'http://a/g'); itShouldResolve('http://a/bb/ccc/d/', '../../../../g', 'http://a/g'); itShouldResolve('http://a/bb/ccc/d/', '/./g', 'http://a/g'); itShouldResolve('http://a/bb/ccc/d/', '/../g', 'http://a/g'); itShouldResolve('http://a/bb/ccc/d/', 'g.', 'http://a/bb/ccc/d/g.'); itShouldResolve('http://a/bb/ccc/d/', '.g', 'http://a/bb/ccc/d/.g'); itShouldResolve('http://a/bb/ccc/d/', 'g..', 'http://a/bb/ccc/d/g..'); itShouldResolve('http://a/bb/ccc/d/', '..g', 'http://a/bb/ccc/d/..g'); itShouldResolve('http://a/bb/ccc/d/', './../g', 'http://a/bb/ccc/g'); itShouldResolve('http://a/bb/ccc/d/', './g/.', 'http://a/bb/ccc/d/g/'); itShouldResolve('http://a/bb/ccc/d/', 'g/./h', 'http://a/bb/ccc/d/g/h'); itShouldResolve('http://a/bb/ccc/d/', 'g/../h', 'http://a/bb/ccc/d/h'); itShouldResolve('http://a/bb/ccc/d/', 'g;x=1/./y', 'http://a/bb/ccc/d/g;x=1/y'); itShouldResolve('http://a/bb/ccc/d/', 'g;x=1/../y', 'http://a/bb/ccc/d/y'); itShouldResolve('http://a/bb/ccc/d/', 'g?y/./x', 'http://a/bb/ccc/d/g?y/./x'); itShouldResolve('http://a/bb/ccc/d/', 'g?y/../x', 'http://a/bb/ccc/d/g?y/../x'); itShouldResolve('http://a/bb/ccc/d/', 'g#s/./x', 'http://a/bb/ccc/d/g#s/./x'); itShouldResolve('http://a/bb/ccc/d/', 'g#s/../x', 'http://a/bb/ccc/d/g#s/../x'); itShouldResolve('http://a/bb/ccc/d/', 'http:g', 'http:g'); }); describe('RFC3986 normal examples with /. in the base IRI', function () { itShouldResolve('http://a/bb/ccc/./d;p?q', 'g:h', 'g:h'); itShouldResolve('http://a/bb/ccc/./d;p?q', 'g', 'http://a/bb/ccc/g'); itShouldResolve('http://a/bb/ccc/./d;p?q', './g', 'http://a/bb/ccc/g'); itShouldResolve('http://a/bb/ccc/./d;p?q', 'g/', 'http://a/bb/ccc/g/'); itShouldResolve('http://a/bb/ccc/./d;p?q', '/g', 'http://a/g'); itShouldResolve('http://a/bb/ccc/./d;p?q', '//g', 'http://g'); itShouldResolve('http://a/bb/ccc/./d;p?q', '?y', 'http://a/bb/ccc/./d;p?y'); itShouldResolve('http://a/bb/ccc/./d;p?q', 'g?y', 'http://a/bb/ccc/g?y'); itShouldResolve('http://a/bb/ccc/./d;p?q', '#s', 'http://a/bb/ccc/./d;p?q#s'); itShouldResolve('http://a/bb/ccc/./d;p?q', 'g#s', 'http://a/bb/ccc/g#s'); itShouldResolve('http://a/bb/ccc/./d;p?q', 'g?y#s', 'http://a/bb/ccc/g?y#s'); itShouldResolve('http://a/bb/ccc/./d;p?q', ';x', 'http://a/bb/ccc/;x'); itShouldResolve('http://a/bb/ccc/./d;p?q', 'g;x', 'http://a/bb/ccc/g;x'); itShouldResolve('http://a/bb/ccc/./d;p?q', 'g;x?y#s', 'http://a/bb/ccc/g;x?y#s'); itShouldResolve('http://a/bb/ccc/./d;p?q', '', 'http://a/bb/ccc/./d;p?q'); itShouldResolve('http://a/bb/ccc/./d;p?q', '.', 'http://a/bb/ccc/'); itShouldResolve('http://a/bb/ccc/./d;p?q', './', 'http://a/bb/ccc/'); itShouldResolve('http://a/bb/ccc/./d;p?q', '..', 'http://a/bb/'); itShouldResolve('http://a/bb/ccc/./d;p?q', '../', 'http://a/bb/'); itShouldResolve('http://a/bb/ccc/./d;p?q', '../g', 'http://a/bb/g'); itShouldResolve('http://a/bb/ccc/./d;p?q', '../..', 'http://a/'); itShouldResolve('http://a/bb/ccc/./d;p?q', '../../', 'http://a/'); itShouldResolve('http://a/bb/ccc/./d;p?q', '../../g', 'http://a/g'); }); describe('RFC3986 abnormal examples with /. in the base IRI', function () { itShouldResolve('http://a/bb/ccc/./d;p?q', '../../../g', 'http://a/g'); itShouldResolve('http://a/bb/ccc/./d;p?q', '../../../../g', 'http://a/g'); itShouldResolve('http://a/bb/ccc/./d;p?q', '/./g', 'http://a/g'); itShouldResolve('http://a/bb/ccc/./d;p?q', '/../g', 'http://a/g'); itShouldResolve('http://a/bb/ccc/./d;p?q', 'g.', 'http://a/bb/ccc/g.'); itShouldResolve('http://a/bb/ccc/./d;p?q', '.g', 'http://a/bb/ccc/.g'); itShouldResolve('http://a/bb/ccc/./d;p?q', 'g..', 'http://a/bb/ccc/g..'); itShouldResolve('http://a/bb/ccc/./d;p?q', '..g', 'http://a/bb/ccc/..g'); itShouldResolve('http://a/bb/ccc/./d;p?q', './../g', 'http://a/bb/g'); itShouldResolve('http://a/bb/ccc/./d;p?q', './g/.', 'http://a/bb/ccc/g/'); itShouldResolve('http://a/bb/ccc/./d;p?q', 'g/./h', 'http://a/bb/ccc/g/h'); itShouldResolve('http://a/bb/ccc/./d;p?q', 'g/../h', 'http://a/bb/ccc/h'); itShouldResolve('http://a/bb/ccc/./d;p?q', 'g;x=1/./y', 'http://a/bb/ccc/g;x=1/y'); itShouldResolve('http://a/bb/ccc/./d;p?q', 'g;x=1/../y', 'http://a/bb/ccc/y'); itShouldResolve('http://a/bb/ccc/./d;p?q', 'g?y/./x', 'http://a/bb/ccc/g?y/./x'); itShouldResolve('http://a/bb/ccc/./d;p?q', 'g?y/../x', 'http://a/bb/ccc/g?y/../x'); itShouldResolve('http://a/bb/ccc/./d;p?q', 'g#s/./x', 'http://a/bb/ccc/g#s/./x'); itShouldResolve('http://a/bb/ccc/./d;p?q', 'g#s/../x', 'http://a/bb/ccc/g#s/../x'); itShouldResolve('http://a/bb/ccc/./d;p?q', 'http:g', 'http:g'); }); describe('RFC3986 normal examples with /.. in the base IRI', function () { itShouldResolve('http://a/bb/ccc/../d;p?q', 'g:h', 'g:h'); itShouldResolve('http://a/bb/ccc/../d;p?q', 'g', 'http://a/bb/g'); itShouldResolve('http://a/bb/ccc/../d;p?q', './g', 'http://a/bb/g'); itShouldResolve('http://a/bb/ccc/../d;p?q', 'g/', 'http://a/bb/g/'); itShouldResolve('http://a/bb/ccc/../d;p?q', '/g', 'http://a/g'); itShouldResolve('http://a/bb/ccc/../d;p?q', '//g', 'http://g'); itShouldResolve('http://a/bb/ccc/../d;p?q', '?y', 'http://a/bb/ccc/../d;p?y'); itShouldResolve('http://a/bb/ccc/../d;p?q', 'g?y', 'http://a/bb/g?y'); itShouldResolve('http://a/bb/ccc/../d;p?q', '#s', 'http://a/bb/ccc/../d;p?q#s'); itShouldResolve('http://a/bb/ccc/../d;p?q', 'g#s', 'http://a/bb/g#s'); itShouldResolve('http://a/bb/ccc/../d;p?q', 'g?y#s', 'http://a/bb/g?y#s'); itShouldResolve('http://a/bb/ccc/../d;p?q', ';x', 'http://a/bb/;x'); itShouldResolve('http://a/bb/ccc/../d;p?q', 'g;x', 'http://a/bb/g;x'); itShouldResolve('http://a/bb/ccc/../d;p?q', 'g;x?y#s', 'http://a/bb/g;x?y#s'); itShouldResolve('http://a/bb/ccc/../d;p?q', '', 'http://a/bb/ccc/../d;p?q'); itShouldResolve('http://a/bb/ccc/../d;p?q', '.', 'http://a/bb/'); itShouldResolve('http://a/bb/ccc/../d;p?q', './', 'http://a/bb/'); itShouldResolve('http://a/bb/ccc/../d;p?q', '..', 'http://a/'); itShouldResolve('http://a/bb/ccc/../d;p?q', '../', 'http://a/'); itShouldResolve('http://a/bb/ccc/../d;p?q', '../g', 'http://a/g'); itShouldResolve('http://a/bb/ccc/../d;p?q', '../..', 'http://a/'); itShouldResolve('http://a/bb/ccc/../d;p?q', '../../', 'http://a/'); itShouldResolve('http://a/bb/ccc/../d;p?q', '../../g', 'http://a/g'); }); describe('RFC3986 abnormal examples with /.. in the base IRI', function () { itShouldResolve('http://a/bb/ccc/../d;p?q', '../../../g', 'http://a/g'); itShouldResolve('http://a/bb/ccc/../d;p?q', '../../../../g', 'http://a/g'); itShouldResolve('http://a/bb/ccc/../d;p?q', '/./g', 'http://a/g'); itShouldResolve('http://a/bb/ccc/../d;p?q', '/../g', 'http://a/g'); itShouldResolve('http://a/bb/ccc/../d;p?q', 'g.', 'http://a/bb/g.'); itShouldResolve('http://a/bb/ccc/../d;p?q', '.g', 'http://a/bb/.g'); itShouldResolve('http://a/bb/ccc/../d;p?q', 'g..', 'http://a/bb/g..'); itShouldResolve('http://a/bb/ccc/../d;p?q', '..g', 'http://a/bb/..g'); itShouldResolve('http://a/bb/ccc/../d;p?q', './../g', 'http://a/g'); itShouldResolve('http://a/bb/ccc/../d;p?q', './g/.', 'http://a/bb/g/'); itShouldResolve('http://a/bb/ccc/../d;p?q', 'g/./h', 'http://a/bb/g/h'); itShouldResolve('http://a/bb/ccc/../d;p?q', 'g/../h', 'http://a/bb/h'); itShouldResolve('http://a/bb/ccc/../d;p?q', 'g;x=1/./y', 'http://a/bb/g;x=1/y'); itShouldResolve('http://a/bb/ccc/../d;p?q', 'g;x=1/../y', 'http://a/bb/y'); itShouldResolve('http://a/bb/ccc/../d;p?q', 'g?y/./x', 'http://a/bb/g?y/./x'); itShouldResolve('http://a/bb/ccc/../d;p?q', 'g?y/../x', 'http://a/bb/g?y/../x'); itShouldResolve('http://a/bb/ccc/../d;p?q', 'g#s/./x', 'http://a/bb/g#s/./x'); itShouldResolve('http://a/bb/ccc/../d;p?q', 'g#s/../x', 'http://a/bb/g#s/../x'); itShouldResolve('http://a/bb/ccc/../d;p?q', 'http:g', 'http:g'); }); describe('RFC3986 normal examples with trailing /. in the base IRI', function () { itShouldResolve('http://a/bb/ccc/.', 'g:h', 'g:h'); itShouldResolve('http://a/bb/ccc/.', 'g', 'http://a/bb/ccc/g'); itShouldResolve('http://a/bb/ccc/.', './g', 'http://a/bb/ccc/g'); itShouldResolve('http://a/bb/ccc/.', 'g/', 'http://a/bb/ccc/g/'); itShouldResolve('http://a/bb/ccc/.', '/g', 'http://a/g'); itShouldResolve('http://a/bb/ccc/.', '//g', 'http://g'); itShouldResolve('http://a/bb/ccc/.', '?y', 'http://a/bb/ccc/.?y'); itShouldResolve('http://a/bb/ccc/.', 'g?y', 'http://a/bb/ccc/g?y'); itShouldResolve('http://a/bb/ccc/.', '#s', 'http://a/bb/ccc/.#s'); itShouldResolve('http://a/bb/ccc/.', 'g#s', 'http://a/bb/ccc/g#s'); itShouldResolve('http://a/bb/ccc/.', 'g?y#s', 'http://a/bb/ccc/g?y#s'); itShouldResolve('http://a/bb/ccc/.', ';x', 'http://a/bb/ccc/;x'); itShouldResolve('http://a/bb/ccc/.', 'g;x', 'http://a/bb/ccc/g;x'); itShouldResolve('http://a/bb/ccc/.', 'g;x?y#s', 'http://a/bb/ccc/g;x?y#s'); itShouldResolve('http://a/bb/ccc/.', '', 'http://a/bb/ccc/.'); itShouldResolve('http://a/bb/ccc/.', '.', 'http://a/bb/ccc/'); itShouldResolve('http://a/bb/ccc/.', './', 'http://a/bb/ccc/'); itShouldResolve('http://a/bb/ccc/.', '..', 'http://a/bb/'); itShouldResolve('http://a/bb/ccc/.', '../', 'http://a/bb/'); itShouldResolve('http://a/bb/ccc/.', '../g', 'http://a/bb/g'); itShouldResolve('http://a/bb/ccc/.', '../..', 'http://a/'); itShouldResolve('http://a/bb/ccc/.', '../../', 'http://a/'); itShouldResolve('http://a/bb/ccc/.', '../../g', 'http://a/g'); }); describe('RFC3986 abnormal examples with trailing /. in the base IRI', function () { itShouldResolve('http://a/bb/ccc/.', '../../../g', 'http://a/g'); itShouldResolve('http://a/bb/ccc/.', '../../../../g', 'http://a/g'); itShouldResolve('http://a/bb/ccc/.', '/./g', 'http://a/g'); itShouldResolve('http://a/bb/ccc/.', '/../g', 'http://a/g'); itShouldResolve('http://a/bb/ccc/.', 'g.', 'http://a/bb/ccc/g.'); itShouldResolve('http://a/bb/ccc/.', '.g', 'http://a/bb/ccc/.g'); itShouldResolve('http://a/bb/ccc/.', 'g..', 'http://a/bb/ccc/g..'); itShouldResolve('http://a/bb/ccc/.', '..g', 'http://a/bb/ccc/..g'); itShouldResolve('http://a/bb/ccc/.', './../g', 'http://a/bb/g'); itShouldResolve('http://a/bb/ccc/.', './g/.', 'http://a/bb/ccc/g/'); itShouldResolve('http://a/bb/ccc/.', 'g/./h', 'http://a/bb/ccc/g/h'); itShouldResolve('http://a/bb/ccc/.', 'g/../h', 'http://a/bb/ccc/h'); itShouldResolve('http://a/bb/ccc/.', 'g;x=1/./y', 'http://a/bb/ccc/g;x=1/y'); itShouldResolve('http://a/bb/ccc/.', 'g;x=1/../y', 'http://a/bb/ccc/y'); itShouldResolve('http://a/bb/ccc/.', 'g?y/./x', 'http://a/bb/ccc/g?y/./x'); itShouldResolve('http://a/bb/ccc/.', 'g?y/../x', 'http://a/bb/ccc/g?y/../x'); itShouldResolve('http://a/bb/ccc/.', 'g#s/./x', 'http://a/bb/ccc/g#s/./x'); itShouldResolve('http://a/bb/ccc/.', 'g#s/../x', 'http://a/bb/ccc/g#s/../x'); itShouldResolve('http://a/bb/ccc/.', 'http:g', 'http:g'); }); describe('RFC3986 normal examples with trailing /.. in the base IRI', function () { itShouldResolve('http://a/bb/ccc/..', 'g:h', 'g:h'); itShouldResolve('http://a/bb/ccc/..', 'g', 'http://a/bb/ccc/g'); itShouldResolve('http://a/bb/ccc/..', './g', 'http://a/bb/ccc/g'); itShouldResolve('http://a/bb/ccc/..', 'g/', 'http://a/bb/ccc/g/'); itShouldResolve('http://a/bb/ccc/..', '/g', 'http://a/g'); itShouldResolve('http://a/bb/ccc/..', '//g', 'http://g'); itShouldResolve('http://a/bb/ccc/..', '?y', 'http://a/bb/ccc/..?y'); itShouldResolve('http://a/bb/ccc/..', 'g?y', 'http://a/bb/ccc/g?y'); itShouldResolve('http://a/bb/ccc/..', '#s', 'http://a/bb/ccc/..#s'); itShouldResolve('http://a/bb/ccc/..', 'g#s', 'http://a/bb/ccc/g#s'); itShouldResolve('http://a/bb/ccc/..', 'g?y#s', 'http://a/bb/ccc/g?y#s'); itShouldResolve('http://a/bb/ccc/..', ';x', 'http://a/bb/ccc/;x'); itShouldResolve('http://a/bb/ccc/..', 'g;x', 'http://a/bb/ccc/g;x'); itShouldResolve('http://a/bb/ccc/..', 'g;x?y#s', 'http://a/bb/ccc/g;x?y#s'); itShouldResolve('http://a/bb/ccc/..', '', 'http://a/bb/ccc/..'); itShouldResolve('http://a/bb/ccc/..', '.', 'http://a/bb/ccc/'); itShouldResolve('http://a/bb/ccc/..', './', 'http://a/bb/ccc/'); itShouldResolve('http://a/bb/ccc/..', '..', 'http://a/bb/'); itShouldResolve('http://a/bb/ccc/..', '../', 'http://a/bb/'); itShouldResolve('http://a/bb/ccc/..', '../g', 'http://a/bb/g'); itShouldResolve('http://a/bb/ccc/..', '../..', 'http://a/'); itShouldResolve('http://a/bb/ccc/..', '../../', 'http://a/'); itShouldResolve('http://a/bb/ccc/..', '../../g', 'http://a/g'); }); describe('RFC3986 abnormal examples with trailing /.. in the base IRI', function () { itShouldResolve('http://a/bb/ccc/..', '../../../g', 'http://a/g'); itShouldResolve('http://a/bb/ccc/..', '../../../../g', 'http://a/g'); itShouldResolve('http://a/bb/ccc/..', '/./g', 'http://a/g'); itShouldResolve('http://a/bb/ccc/..', '/../g', 'http://a/g'); itShouldResolve('http://a/bb/ccc/..', 'g.', 'http://a/bb/ccc/g.'); itShouldResolve('http://a/bb/ccc/..', '.g', 'http://a/bb/ccc/.g'); itShouldResolve('http://a/bb/ccc/..', 'g..', 'http://a/bb/ccc/g..'); itShouldResolve('http://a/bb/ccc/..', '..g', 'http://a/bb/ccc/..g'); itShouldResolve('http://a/bb/ccc/..', './../g', 'http://a/bb/g'); itShouldResolve('http://a/bb/ccc/..', './g/.', 'http://a/bb/ccc/g/'); itShouldResolve('http://a/bb/ccc/..', 'g/./h', 'http://a/bb/ccc/g/h'); itShouldResolve('http://a/bb/ccc/..', 'g/../h', 'http://a/bb/ccc/h'); itShouldResolve('http://a/bb/ccc/..', 'g;x=1/./y', 'http://a/bb/ccc/g;x=1/y'); itShouldResolve('http://a/bb/ccc/..', 'g;x=1/../y', 'http://a/bb/ccc/y'); itShouldResolve('http://a/bb/ccc/..', 'g?y/./x', 'http://a/bb/ccc/g?y/./x'); itShouldResolve('http://a/bb/ccc/..', 'g?y/../x', 'http://a/bb/ccc/g?y/../x'); itShouldResolve('http://a/bb/ccc/..', 'g#s/./x', 'http://a/bb/ccc/g#s/./x'); itShouldResolve('http://a/bb/ccc/..', 'g#s/../x', 'http://a/bb/ccc/g#s/../x'); itShouldResolve('http://a/bb/ccc/..', 'http:g', 'http:g'); }); describe('RFC3986 normal examples with fragment in base IRI', function () { itShouldResolve('http://a/bb/ccc/d;p?q#f', 'g:h', 'g:h'); itShouldResolve('http://a/bb/ccc/d;p?q#f', 'g', 'http://a/bb/ccc/g'); itShouldResolve('http://a/bb/ccc/d;p?q#f', './g', 'http://a/bb/ccc/g'); itShouldResolve('http://a/bb/ccc/d;p?q#f', 'g/', 'http://a/bb/ccc/g/'); itShouldResolve('http://a/bb/ccc/d;p?q#f', '/g', 'http://a/g'); itShouldResolve('http://a/bb/ccc/d;p?q#f', '//g', 'http://g'); itShouldResolve('http://a/bb/ccc/d;p?q#f', '?y', 'http://a/bb/ccc/d;p?y'); itShouldResolve('http://a/bb/ccc/d;p?q#f', 'g?y', 'http://a/bb/ccc/g?y'); itShouldResolve('http://a/bb/ccc/d;p?q#f', '#s', 'http://a/bb/ccc/d;p?q#s'); itShouldResolve('http://a/bb/ccc/d;p?q#f', 'g#s', 'http://a/bb/ccc/g#s'); itShouldResolve('http://a/bb/ccc/d;p?q#f', 'g?y#s', 'http://a/bb/ccc/g?y#s'); itShouldResolve('http://a/bb/ccc/d;p?q#f', ';x', 'http://a/bb/ccc/;x'); itShouldResolve('http://a/bb/ccc/d;p?q#f', 'g;x', 'http://a/bb/ccc/g;x'); itShouldResolve('http://a/bb/ccc/d;p?q#f', 'g;x?y#s', 'http://a/bb/ccc/g;x?y#s'); itShouldResolve('http://a/bb/ccc/d;p?q#f', '', 'http://a/bb/ccc/d;p?q'); itShouldResolve('http://a/bb/ccc/d;p?q#f', '.', 'http://a/bb/ccc/'); itShouldResolve('http://a/bb/ccc/d;p?q#f', './', 'http://a/bb/ccc/'); itShouldResolve('http://a/bb/ccc/d;p?q#f', '..', 'http://a/bb/'); itShouldResolve('http://a/bb/ccc/d;p?q#f', '../', 'http://a/bb/'); itShouldResolve('http://a/bb/ccc/d;p?q#f', '../g', 'http://a/bb/g'); itShouldResolve('http://a/bb/ccc/d;p?q#f', '../..', 'http://a/'); itShouldResolve('http://a/bb/ccc/d;p?q#f', '../../', 'http://a/'); itShouldResolve('http://a/bb/ccc/d;p?q#f', '../../g', 'http://a/g'); }); describe('RFC3986 abnormal examples with fragment in base IRI', function () { itShouldResolve('http://a/bb/ccc/d;p?q#f', '../../../g', 'http://a/g'); itShouldResolve('http://a/bb/ccc/d;p?q#f', '../../../../g', 'http://a/g'); itShouldResolve('http://a/bb/ccc/d;p?q#f', '/./g', 'http://a/g'); itShouldResolve('http://a/bb/ccc/d;p?q#f', '/../g', 'http://a/g'); itShouldResolve('http://a/bb/ccc/d;p?q#f', 'g.', 'http://a/bb/ccc/g.'); itShouldResolve('http://a/bb/ccc/d;p?q#f', '.g', 'http://a/bb/ccc/.g'); itShouldResolve('http://a/bb/ccc/d;p?q#f', 'g..', 'http://a/bb/ccc/g..'); itShouldResolve('http://a/bb/ccc/d;p?q#f', '..g', 'http://a/bb/ccc/..g'); itShouldResolve('http://a/bb/ccc/d;p?q#f', './../g', 'http://a/bb/g'); itShouldResolve('http://a/bb/ccc/d;p?q#f', './g/.', 'http://a/bb/ccc/g/'); itShouldResolve('http://a/bb/ccc/d;p?q#f', 'g/./h', 'http://a/bb/ccc/g/h'); itShouldResolve('http://a/bb/ccc/d;p?q#f', 'g/../h', 'http://a/bb/ccc/h'); itShouldResolve('http://a/bb/ccc/d;p?q#f', 'g;x=1/./y', 'http://a/bb/ccc/g;x=1/y'); itShouldResolve('http://a/bb/ccc/d;p?q#f', 'g;x=1/../y', 'http://a/bb/ccc/y'); itShouldResolve('http://a/bb/ccc/d;p?q#f', 'g?y/./x', 'http://a/bb/ccc/g?y/./x'); itShouldResolve('http://a/bb/ccc/d;p?q#f', 'g?y/../x', 'http://a/bb/ccc/g?y/../x'); itShouldResolve('http://a/bb/ccc/d;p?q#f', 'g#s/./x', 'http://a/bb/ccc/g#s/./x'); itShouldResolve('http://a/bb/ccc/d;p?q#f', 'g#s/../x', 'http://a/bb/ccc/g#s/../x'); itShouldResolve('http://a/bb/ccc/d;p?q#f', 'http:g', 'http:g'); }); describe('RFC3986 normal examples with file path', function () { itShouldResolve('file:///a/bb/ccc/d;p?q', 'g:h', 'g:h'); itShouldResolve('file:///a/bb/ccc/d;p?q', 'g', 'file:///a/bb/ccc/g'); itShouldResolve('file:///a/bb/ccc/d;p?q', './g', 'file:///a/bb/ccc/g'); itShouldResolve('file:///a/bb/ccc/d;p?q', 'g/', 'file:///a/bb/ccc/g/'); itShouldResolve('file:///a/bb/ccc/d;p?q', '/g', 'file:///g'); itShouldResolve('file:///a/bb/ccc/d;p?q', '//g', 'file://g'); itShouldResolve('file:///a/bb/ccc/d;p?q', '?y', 'file:///a/bb/ccc/d;p?y'); itShouldResolve('file:///a/bb/ccc/d;p?q', 'g?y', 'file:///a/bb/ccc/g?y'); itShouldResolve('file:///a/bb/ccc/d;p?q', '#s', 'file:///a/bb/ccc/d;p?q#s'); itShouldResolve('file:///a/bb/ccc/d;p?q', 'g#s', 'file:///a/bb/ccc/g#s'); itShouldResolve('file:///a/bb/ccc/d;p?q', 'g?y#s', 'file:///a/bb/ccc/g?y#s'); itShouldResolve('file:///a/bb/ccc/d;p?q', ';x', 'file:///a/bb/ccc/;x'); itShouldResolve('file:///a/bb/ccc/d;p?q', 'g;x', 'file:///a/bb/ccc/g;x'); itShouldResolve('file:///a/bb/ccc/d;p?q', 'g;x?y#s', 'file:///a/bb/ccc/g;x?y#s'); itShouldResolve('file:///a/bb/ccc/d;p?q', '', 'file:///a/bb/ccc/d;p?q'); itShouldResolve('file:///a/bb/ccc/d;p?q', '.', 'file:///a/bb/ccc/'); itShouldResolve('file:///a/bb/ccc/d;p?q', './', 'file:///a/bb/ccc/'); itShouldResolve('file:///a/bb/ccc/d;p?q', '..', 'file:///a/bb/'); itShouldResolve('file:///a/bb/ccc/d;p?q', '../', 'file:///a/bb/'); itShouldResolve('file:///a/bb/ccc/d;p?q', '../g', 'file:///a/bb/g'); itShouldResolve('file:///a/bb/ccc/d;p?q', '../..', 'file:///a/'); itShouldResolve('file:///a/bb/ccc/d;p?q', '../../', 'file:///a/'); itShouldResolve('file:///a/bb/ccc/d;p?q', '../../g', 'file:///a/g'); }); describe('RFC3986 abnormal examples with file path', function () { itShouldResolve('file:///a/bb/ccc/d;p?q', '../../../g', 'file:///g'); itShouldResolve('file:///a/bb/ccc/d;p?q', '../../../../g', 'file:///g'); itShouldResolve('file:///a/bb/ccc/d;p?q', '/./g', 'file:///g'); itShouldResolve('file:///a/bb/ccc/d;p?q', '/../g', 'file:///g'); itShouldResolve('file:///a/bb/ccc/d;p?q', 'g.', 'file:///a/bb/ccc/g.'); itShouldResolve('file:///a/bb/ccc/d;p?q', '.g', 'file:///a/bb/ccc/.g'); itShouldResolve('file:///a/bb/ccc/d;p?q', 'g..', 'file:///a/bb/ccc/g..'); itShouldResolve('file:///a/bb/ccc/d;p?q', '..g', 'file:///a/bb/ccc/..g'); itShouldResolve('file:///a/bb/ccc/d;p?q', './../g', 'file:///a/bb/g'); itShouldResolve('file:///a/bb/ccc/d;p?q', './g/.', 'file:///a/bb/ccc/g/'); itShouldResolve('file:///a/bb/ccc/d;p?q', 'g/./h', 'file:///a/bb/ccc/g/h'); itShouldResolve('file:///a/bb/ccc/d;p?q', 'g/../h', 'file:///a/bb/ccc/h'); itShouldResolve('file:///a/bb/ccc/d;p?q', 'g;x=1/./y', 'file:///a/bb/ccc/g;x=1/y'); itShouldResolve('file:///a/bb/ccc/d;p?q', 'g;x=1/../y', 'file:///a/bb/ccc/y'); itShouldResolve('file:///a/bb/ccc/d;p?q', 'g?y/./x', 'file:///a/bb/ccc/g?y/./x'); itShouldResolve('file:///a/bb/ccc/d;p?q', 'g?y/../x', 'file:///a/bb/ccc/g?y/../x'); itShouldResolve('file:///a/bb/ccc/d;p?q', 'g#s/./x', 'file:///a/bb/ccc/g#s/./x'); itShouldResolve('file:///a/bb/ccc/d;p?q', 'g#s/../x', 'file:///a/bb/ccc/g#s/../x'); itShouldResolve('file:///a/bb/ccc/d;p?q', 'http:g', 'http:g'); }); describe('additional cases', function () { // relative paths ending with '.' itShouldResolve('http://abc/', '.', 'http://abc/'); itShouldResolve('http://abc/def/ghi', '.', 'http://abc/def/'); itShouldResolve('http://abc/def/ghi', '.?a=b', 'http://abc/def/?a=b'); itShouldResolve('http://abc/def/ghi', '.#a=b', 'http://abc/def/#a=b'); // relative paths ending with '..' itShouldResolve('http://abc/', '..', 'http://abc/'); itShouldResolve('http://abc/def/ghi', '..', 'http://abc/'); itShouldResolve('http://abc/def/ghi', '..?a=b', 'http://abc/?a=b'); itShouldResolve('http://abc/def/ghi', '..#a=b', 'http://abc/#a=b'); // base path with empty subpaths (double slashes) itShouldResolve('http://ab//de//ghi', 'xyz', 'http://ab//de//xyz'); itShouldResolve('http://ab//de//ghi', './xyz', 'http://ab//de//xyz'); itShouldResolve('http://ab//de//ghi', '../xyz', 'http://ab//de/xyz'); // base path with colon (possible confusion with scheme) itShouldResolve('http://abc/d:f/ghi', 'xyz', 'http://abc/d:f/xyz'); itShouldResolve('http://abc/d:f/ghi', './xyz', 'http://abc/d:f/xyz'); itShouldResolve('http://abc/d:f/ghi', '../xyz', 'http://abc/xyz'); // base path consisting of '..' and/or '../' sequences itShouldResolve('./', 'abc', '/abc'); itShouldResolve('../', 'abc', '/abc'); itShouldResolve('./././', '././abc', '/abc'); itShouldResolve('../../../', '../../abc', '/abc'); itShouldResolve('.../././', '././abc', '.../abc'); // base path without authority itShouldResolve('a:b:c/', 'def/../', 'a:b:c/'); itShouldResolve('a:b:c', '/def', 'a:/def'); itShouldResolve('a:b/c', '/def', 'a:/def'); itShouldResolve('a:', '/.', 'a:/'); itShouldResolve('a:', '/..', 'a:/'); // base path with slashes in query string itShouldResolve('http://abc/def/ghi?q=xx/yyy/z', 'jjj', 'http://abc/def/jjj'); itShouldResolve('http://abc/def/ghi?q=xx/y?y/z', 'jjj', 'http://abc/def/jjj'); }); }); }); function shouldParse(createParser, input) { var expected = Array.prototype.slice.call(arguments, 1); // Shift parameters as necessary if (createParser.call) expected.shift(); else input = createParser, createParser = N3Parser; return function (done) { var results = []; var items = expected.map(function (item) { item = item.map(function (t) { // Append base to relative IRIs if (!/^$|^["?]|:/.test(t)) t = BASE_IRI + t; return fromId(t); }); return new Quad(item[0], item[1], item[2], item[3]); }); N3Parser._resetBlankNodeIds(); createParser({ baseIRI: BASE_IRI }).parse(input, function (error, triple) { expect(error).not.to.exist; if (triple) results.push(triple); else toSortedJSON(results).should.equal(toSortedJSON(items)), done(); }); }; } function toSortedJSON(triples) { triples = triples.map(function (t) { return JSON.stringify([ t.subject.toJSON(), t.predicate.toJSON(), t.object.toJSON(), t.graph.toJSON(), ]); }); triples.sort(); return '[\n ' + triples.join('\n ') + '\n]'; } function shouldNotParse(createParser, input, expectedError, expectedContext) { // Shift parameters if necessary if (!createParser.call) expectedContext = expectedError, expectedError = input, input = createParser, createParser = N3Parser; return function (done) { createParser({ baseIRI: BASE_IRI }).parse(input, function (error, triple) { if (error) { expect(triple).not.to.exist; error.should.be.an.instanceof(Error); error.message.should.eql(expectedError); if (expectedContext) error.context.should.deep.equal(expectedContext); done(); } else if (!triple) done(new Error('Expected error ' + expectedError)); }); }; } function itShouldResolve(baseIri, relativeIri, expected) { var result; describe('resolving <' + relativeIri + '> against <' + baseIri + '>', function () { before(function (done) { try { var doc = ' <' + relativeIri + '>.'; new N3Parser({ baseIRI: baseIri }).parse(doc, function (error, triple) { if (done) result = triple, done(error); done = null; }); } catch (error) { done(error); } }); it('should result in ' + expected, function () { expect(result.object.value).to.equal(expected); }); }); } N3.js-1.0.4/test/N3Store-test.js000066400000000000000000001336561343333361000162130ustar00rootroot00000000000000var N3Store = require('../N3').Store; var Readable = require('stream').Readable, DataFactory = require('../N3').DataFactory; var NamedNode = DataFactory.internal.NamedNode, DefaultGraph = DataFactory.internal.DefaultGraph, Quad = DataFactory.internal.Quad, fromId = DataFactory.internal.fromId; describe('N3Store', function () { describe('The N3Store module', function () { it('should be a function', function () { N3Store.should.be.a('function'); }); it('should make N3Store objects', function () { N3Store().should.be.an.instanceof(N3Store); }); it('should be an N3Store constructor', function () { new N3Store().should.be.an.instanceof(N3Store); }); }); describe('An empty N3Store', function () { var store = new N3Store({}); it('should have size 0', function () { expect(store.size).to.eql(0); }); it('should be empty', function () { store.getQuads().should.be.empty; }); describe('when importing a stream of 2 quads', function () { before(function (done) { var stream = new ArrayReader([ new Quad(new NamedNode('s1'), new NamedNode('p2'), new NamedNode('o2')), new Quad(new NamedNode('s1'), new NamedNode('p1'), new NamedNode('o1')), ]); var events = store.import(stream); events.on('end', done); }); it('should have size 2', function () { store.size.should.eql(2); }); }); describe('when removing a stream of 2 quads', function () { before(function (done) { var stream = new ArrayReader([ new Quad(new NamedNode('s1'), new NamedNode('p2'), new NamedNode('o2')), new Quad(new NamedNode('s1'), new NamedNode('p1'), new NamedNode('o1')), ]); var events = store.remove(stream); events.on('end', done); }); it('should have size 0', function () { store.size.should.eql(0); }); }); describe('every', function () { describe('with no parameters and a callback always returning true', function () { it('should return false', function () { store.every(alwaysTrue, null, null, null, null).should.be.false; }); }); describe('with no parameters and a callback always returning false', function () { it('should return false', function () { store.every(alwaysFalse, null, null, null, null).should.be.false; }); }); }); describe('some', function () { describe('with no parameters and a callback always returning true', function () { it('should return false', function () { store.some(alwaysTrue, null, null, null, null).should.be.false; }); }); describe('with no parameters and a callback always returning false', function () { it('should return false', function () { store.some(alwaysFalse, null, null, null, null).should.be.false; }); }); }); it('should still have size 0 (instead of null) after adding and removing a triple', function () { expect(store.size).to.eql(0); store.addQuad(new NamedNode('a'), new NamedNode('b'), new NamedNode('c')).should.be.true; store.removeQuad(new NamedNode('a'), new NamedNode('b'), new NamedNode('c')).should.be.true; expect(store.size).to.eql(0); }); it('should be able to generate unnamed blank nodes', function () { store.createBlankNode().value.should.eql('b0'); store.createBlankNode().value.should.eql('b1'); store.addQuad('_:b0', '_:b1', '_:b2').should.be.true; store.createBlankNode().value.should.eql('b3'); store.removeQuads(store.getQuads()); }); it('should be able to generate named blank nodes', function () { store.createBlankNode('blank').value.should.eql('blank'); store.createBlankNode('blank').value.should.eql('blank1'); store.createBlankNode('blank').value.should.eql('blank2'); }); it('should be able to store triples with generated blank nodes', function () { store.addQuad(store.createBlankNode('x'), new NamedNode('b'), new NamedNode('c')).should.be.true; shouldIncludeAll(store.getQuads(null, new NamedNode('b')), ['_:x', 'b', 'c'])(); store.removeQuads(store.getQuads()); }); }); describe('An N3Store with initialized with 3 elements', function () { var store = new N3Store([ new Quad(new NamedNode('s1'), new NamedNode('p1'), new NamedNode('o1')), new Quad(new NamedNode('s1'), new NamedNode('p1'), new NamedNode('o2')), new Quad(new NamedNode('s1'), new NamedNode('p1'), new NamedNode('o3')), ]); it('should have size 3', function () { store.size.should.eql(3); }); describe('adding a triple that already exists', function () { it('should return false', function () { store.addQuad('s1', 'p1', 'o1').should.be.false; }); it('should not increase the size', function () { store.size.should.eql(3); }); }); describe('adding a triple that did not exist yet', function () { it('should return true', function () { store.addQuad('s1', 'p1', 'o4').should.be.true; }); it('should increase the size', function () { store.size.should.eql(4); }); }); describe('removing an existing triple', function () { it('should return true', function () { store.removeQuad('s1', 'p1', 'o4').should.be.true; }); it('should decrease the size', function () { store.size.should.eql(3); }); }); describe('removing a non-existing triple', function () { it('should return false', function () { store.removeQuad('s1', 'p1', 'o5').should.be.false; }); it('should not decrease the size', function () { store.size.should.eql(3); }); }); }); describe('An N3Store with 5 elements', function () { var store = new N3Store(); store.addQuad('s1', 'p1', 'o1').should.be.true; store.addQuad({ subject: 's1', predicate: 'p1', object: 'o2' }).should.be.true; store.addQuads([ { subject: 's1', predicate: 'p2', object: 'o2' }, { subject: 's2', predicate: 'p1', object: 'o1' }, ]); store.addQuad('s1', 'p1', 'o1', 'c4').should.be.true; it('should have size 5', function () { store.size.should.eql(5); }); describe('when searched without parameters', function () { it('should return all items', shouldIncludeAll(store.getQuads(), ['s1', 'p1', 'o1'], ['s1', 'p1', 'o2'], ['s1', 'p2', 'o2'], ['s2', 'p1', 'o1'], ['s1', 'p1', 'o1', 'c4'])); }); describe('when searched with an existing subject parameter', function () { it('should return all items with this subject in all graphs', shouldIncludeAll(store.getQuads(new NamedNode('s1'), null, null), ['s1', 'p1', 'o1'], ['s1', 'p1', 'o2'], ['s1', 'p2', 'o2'], ['s1', 'p1', 'o1', 'c4'])); }); describe('when searched with a non-existing subject parameter', function () { itShouldBeEmpty(store.getQuads(new NamedNode('s3'), null, null)); }); describe('when searched with a non-existing subject parameter that exists elsewhere', function () { itShouldBeEmpty(store.getQuads(new NamedNode('p1'), null, null)); }); describe('when searched with an existing predicate parameter', function () { it('should return all items with this predicate in all graphs', shouldIncludeAll(store.getQuads(null, new NamedNode('p1'), null), ['s1', 'p1', 'o1'], ['s1', 'p1', 'o2'], ['s2', 'p1', 'o1'], ['s1', 'p1', 'o1', 'c4'])); }); describe('when searched with a non-existing predicate parameter', function () { itShouldBeEmpty(store.getQuads(null, new NamedNode('p3'), null)); }); describe('when searched with an existing object parameter', function () { it('should return all items with this object in all graphs', shouldIncludeAll(store.getQuads(null, null, new NamedNode('o1')), ['s1', 'p1', 'o1'], ['s2', 'p1', 'o1'], ['s1', 'p1', 'o1', 'c4'])); }); describe('when searched with a non-existing object parameter', function () { itShouldBeEmpty(store.getQuads(null, null, new NamedNode('o4'))); }); describe('when searched with existing subject and predicate parameters', function () { it('should return all items with this subject and predicate in all graphs', shouldIncludeAll(store.getQuads(new NamedNode('s1'), new NamedNode('p1'), null), ['s1', 'p1', 'o1'], ['s1', 'p1', 'o2'], ['s1', 'p1', 'o1', 'c4'])); }); describe('when searched with non-existing subject and predicate parameters', function () { itShouldBeEmpty(store.getQuads(new NamedNode('s2'), new NamedNode('p2'), null)); }); describe('when searched with existing subject and object parameters', function () { it('should return all items with this subject and object in all graphs', shouldIncludeAll(store.getQuads(new NamedNode('s1'), null, new NamedNode('o1')), ['s1', 'p1', 'o1'], ['s1', 'p1', 'o1', 'c4'])); }); describe('when searched with non-existing subject and object parameters', function () { itShouldBeEmpty(store.getQuads(new NamedNode('s2'), new NamedNode('p2'), null)); }); describe('when searched with existing predicate and object parameters', function () { it('should return all items with this predicate and object in all graphs', shouldIncludeAll(store.getQuads(null, new NamedNode('p1'), new NamedNode('o1')), ['s1', 'p1', 'o1'], ['s2', 'p1', 'o1'], ['s1', 'p1', 'o1', 'c4'])); }); describe('when searched with non-existing predicate and object parameters in the default graph', function () { itShouldBeEmpty(store.getQuads(null, new NamedNode('p2'), new NamedNode('o3'), new DefaultGraph())); }); describe('when searched with existing subject, predicate, and object parameters', function () { it('should return all items with this subject, predicate, and object in all graphs', shouldIncludeAll(store.getQuads(new NamedNode('s1'), new NamedNode('p1'), new NamedNode('o1')), ['s1', 'p1', 'o1'], ['s1', 'p1', 'o1', 'c4'])); }); describe('when searched with a non-existing triple', function () { itShouldBeEmpty(store.getQuads(new NamedNode('s2'), new NamedNode('p2'), new NamedNode('o1'))); }); describe('when searched with the default graph parameter', function () { it('should return all items in the default graph', shouldIncludeAll(store.getQuads(null, null, null, new DefaultGraph()), ['s1', 'p1', 'o1'], ['s1', 'p1', 'o2'], ['s1', 'p2', 'o2'], ['s2', 'p1', 'o1'])); }); describe('when searched with an existing named graph parameter', function () { it('should return all items in that graph', shouldIncludeAll(store.getQuads(null, null, null, new NamedNode('c4')), ['s1', 'p1', 'o1', 'c4'])); }); describe('when searched with a non-existing named graph parameter', function () { itShouldBeEmpty(store.getQuads(null, null, null, new NamedNode('c5'))); }); describe('getSubjects', function () { describe('with existing predicate, object and graph parameters', function () { it('should return all subjects with this predicate, object and graph', function () { store.getSubjects(new NamedNode('p1'), new NamedNode('o1'), new NamedNode('c4')).should.have.deep.members([new NamedNode('s1')]); }); }); describe('with existing predicate and object parameters', function () { it('should return all subjects with this predicate and object', function () { store.getSubjects(new NamedNode('p2'), new NamedNode('o2'), null).should.have.deep.members([new NamedNode('s1')]); }); }); describe('with existing predicate and graph parameters', function () { it('should return all subjects with this predicate and graph', function () { store.getSubjects(new NamedNode('p1'), null, new DefaultGraph()).should.have.deep.members([new NamedNode('s1'), new NamedNode('s2')]); }); }); describe('with existing object and graph parameters', function () { it('should return all subjects with this object and graph', function () { store.getSubjects(null, new NamedNode('o1'), new DefaultGraph()).should.have.deep.members([new NamedNode('s1'), new NamedNode('s2')]); }); }); describe('with an existing predicate parameter', function () { it('should return all subjects with this predicate', function () { store.getSubjects(new NamedNode('p1'), null, null).should.have.deep.members([new NamedNode('s1'), new NamedNode('s2')]); }); }); describe('with an existing object parameter', function () { it('should return all subjects with this object', function () { store.getSubjects(null, new NamedNode('o1'), null).should.have.deep.members([new NamedNode('s1'), new NamedNode('s2')]); }); }); describe('with an existing graph parameter', function () { it('should return all subjects in the graph', function () { store.getSubjects(null, null, new NamedNode('c4')).should.have.deep.members([new NamedNode('s1')]); }); }); describe('with no parameters', function () { it('should return all subjects', function () { store.getSubjects(null, null, null).should.have.deep.members([new NamedNode('s1'), new NamedNode('s2')]); }); }); }); describe('getPredicates', function () { describe('with existing subject, object and graph parameters', function () { it('should return all predicates with this subject, object and graph', function () { store.getPredicates(new NamedNode('s1'), new NamedNode('o1'), new NamedNode('c4')).should.have.deep.members([new NamedNode('p1')]); }); }); describe('with existing subject and object parameters', function () { it('should return all predicates with this subject and object', function () { store.getPredicates(new NamedNode('s1'), new NamedNode('o2'), null).should.have.deep.members([new NamedNode('p1'), new NamedNode('p2')]); }); }); describe('with existing subject and graph parameters', function () { it('should return all predicates with this subject and graph', function () { store.getPredicates(new NamedNode('s1'), null, new DefaultGraph()).should.have.deep.members([new NamedNode('p1'), new NamedNode('p2')]); }); }); describe('with existing object and graph parameters', function () { it('should return all predicates with this object and graph', function () { store.getPredicates(null, new NamedNode('o1'), new DefaultGraph()).should.have.deep.members([new NamedNode('p1')]); }); }); describe('with an existing subject parameter', function () { it('should return all predicates with this subject', function () { store.getPredicates(new NamedNode('s2'), null, null).should.have.deep.members([new NamedNode('p1')]); }); }); describe('with an existing object parameter', function () { it('should return all predicates with this object', function () { store.getPredicates(null, new NamedNode('o1'), null).should.have.deep.members([new NamedNode('p1')]); }); }); describe('with an existing graph parameter', function () { it('should return all predicates in the graph', function () { store.getPredicates(null, null, new NamedNode('c4')).should.have.deep.members([new NamedNode('p1')]); }); }); describe('with no parameters', function () { it('should return all predicates', function () { store.getPredicates(null, null, null).should.have.deep.members([new NamedNode('p1'), new NamedNode('p2')]); }); }); }); describe('getObjects', function () { describe('with existing subject, predicate and graph parameters', function () { it('should return all objects with this subject, predicate and graph', function () { store.getObjects(new NamedNode('s1'), new NamedNode('p1'), new DefaultGraph()).should.have.deep.members([new NamedNode('o1'), new NamedNode('o2')]); }); }); describe('with existing subject and predicate parameters', function () { it('should return all objects with this subject and predicate', function () { store.getObjects(new NamedNode('s1'), new NamedNode('p1'), null).should.have.deep.members([new NamedNode('o1'), new NamedNode('o2')]); }); }); describe('with existing subject and graph parameters', function () { it('should return all objects with this subject and graph', function () { store.getObjects(new NamedNode('s1'), null, new DefaultGraph()).should.have.deep.members([new NamedNode('o1'), new NamedNode('o2')]); }); }); describe('with existing predicate and graph parameters', function () { it('should return all objects with this predicate and graph', function () { store.getObjects(null, new NamedNode('p1'), new DefaultGraph()).should.have.deep.members([new NamedNode('o1'), new NamedNode('o2')]); }); }); describe('with an existing subject parameter', function () { it('should return all objects with this subject', function () { store.getObjects(new NamedNode('s1'), null, null).should.have.deep.members([new NamedNode('o1'), new NamedNode('o2')]); }); }); describe('with an existing predicate parameter', function () { it('should return all objects with this predicate', function () { store.getObjects(null, new NamedNode('p1'), null).should.have.deep.members([new NamedNode('o1'), new NamedNode('o2')]); }); }); describe('with an existing graph parameter', function () { it('should return all objects in the graph', function () { store.getObjects(null, null, new NamedNode('c4')).should.have.deep.members([new NamedNode('o1')]); }); }); describe('with no parameters', function () { it('should return all objects', function () { store.getObjects(null, null, null).should.have.deep.members([new NamedNode('o1'), new NamedNode('o2')]); }); }); }); describe('getGraphs', function () { describe('with existing subject, predicate and object parameters', function () { it('should return all graphs with this subject, predicate and object', function () { store.getGraphs(new NamedNode('s1'), new NamedNode('p1'), new NamedNode('o1')).should.have.deep.members([new NamedNode('c4'), new DefaultGraph()]); }); }); describe('with existing subject and predicate parameters', function () { it('should return all graphs with this subject and predicate', function () { store.getGraphs(new NamedNode('s1'), new NamedNode('p1'), null).should.have.deep.members([new NamedNode('c4'), new DefaultGraph()]); }); }); describe('with existing subject and object parameters', function () { it('should return all graphs with this subject and object', function () { store.getGraphs(new NamedNode('s1'), null, new NamedNode('o2')).should.have.deep.members([new DefaultGraph()]); }); }); describe('with existing predicate and object parameters', function () { it('should return all graphs with this predicate and object', function () { store.getGraphs(null, new NamedNode('p1'), new NamedNode('o1')).should.have.deep.members([new DefaultGraph(), new NamedNode('c4')]); }); }); describe('with an existing subject parameter', function () { it('should return all graphs with this subject', function () { store.getGraphs(new NamedNode('s1'), null, null).should.have.deep.members([new NamedNode('c4'), new DefaultGraph()]); }); }); describe('with an existing predicate parameter', function () { it('should return all graphs with this predicate', function () { store.getGraphs(null, new NamedNode('p1'), null).should.have.deep.members([new NamedNode('c4'), new DefaultGraph()]); }); }); describe('with an existing object parameter', function () { it('should return all graphs with this object', function () { store.getGraphs(null, null, new NamedNode('o2')).should.have.deep.members([new DefaultGraph()]); }); }); describe('with no parameters', function () { it('should return all graphs', function () { store.getGraphs(null, null, null).should.have.deep.members([new NamedNode('c4'), new DefaultGraph()]); }); }); }); describe('forEach', function () { describe('with existing subject, predicate, object and graph parameters', function () { it('should have iterated all items with this subject, predicate, object and graph', shouldIncludeAll(collect(store, 'forEach', 's1', 'p1', 'o2', ''), ['s1', 'p1', 'o2', ''])); }); describe('with existing subject, predicate and object parameters', function () { it('should have iterated all items with this subject, predicate and object', shouldIncludeAll(collect(store, 'forEach', 's1', 'p2', 'o2', null), ['s1', 'p2', 'o2', ''])); }); describe('with existing subject, predicate and graph parameters', function () { it('should have iterated all items with this subject, predicate and graph', shouldIncludeAll(collect(store, 'forEach', 's1', 'p1', null, ''), ['s1', 'p1', 'o1', ''], ['s1', 'p1', 'o2', ''])); }); describe('with existing subject, object and graph parameters', function () { it('should have iterated all items with this subject, object and graph', shouldIncludeAll(collect(store, 'forEach', 's1', null, 'o2', ''), ['s1', 'p1', 'o2', ''], ['s1', 'p2', 'o2', ''])); }); describe('with existing predicate, object and graph parameters', function () { it('should have iterated all items with this predicate, object and graph', shouldIncludeAll(collect(store, 'forEach', null, 'p1', 'o1', ''), ['s1', 'p1', 'o1', ''], ['s2', 'p1', 'o1', ''])); }); describe('with existing subject and predicate parameters', function () { it('should iterate all items with this subject and predicate', shouldIncludeAll(collect(store, 'forEach', 's1', 'p1', null, null), ['s1', 'p1', 'o1', ''], ['s1', 'p1', 'o2', ''], ['s1', 'p1', 'o1', 'c4'])); }); describe('with existing subject and object parameters', function () { it('should iterate all items with this subject and predicate', shouldIncludeAll(collect(store, 'forEach', 's1', null, 'o2', null), ['s1', 'p1', 'o2', ''], ['s1', 'p2', 'o2', ''])); }); describe('with existing subject and graph parameters', function () { it('should iterate all items with this subject and graph', shouldIncludeAll(collect(store, 'forEach', 's1', null, null, 'c4'), ['s1', 'p1', 'o1', 'c4'])); }); describe('with existing predicate and object parameters', function () { it('should iterate all items with this predicate and object', shouldIncludeAll(collect(store, 'forEach', null, 'p1', 'o1', null), ['s1', 'p1', 'o1', ''], ['s2', 'p1', 'o1', ''], ['s1', 'p1', 'o1', 'c4'])); }); describe('with existing predicate and graph parameters', function () { it('should iterate all items with this predicate and graph', shouldIncludeAll(collect(store, 'forEach', null, 'p1', null, ''), ['s1', 'p1', 'o1', ''], ['s1', 'p1', 'o2', ''], ['s2', 'p1', 'o1', ''])); }); describe('with existing object and graph parameters', function () { it('should iterate all items with this object and graph', shouldIncludeAll(collect(store, 'forEach', null, null, 'o1', ''), ['s1', 'p1', 'o1', ''], ['s2', 'p1', 'o1', ''])); }); describe('with an existing subject parameter', function () { it('should iterate all items with this subject', shouldIncludeAll(collect(store, 'forEach', 's2', null, null, null), ['s2', 'p1', 'o1', ''])); }); describe('with an existing predicate parameter', function () { it('should iterate all items with this predicate', shouldIncludeAll(collect(store, 'forEach', null, 'p1', null, null), ['s1', 'p1', 'o1', ''], ['s1', 'p1', 'o2', ''], ['s2', 'p1', 'o1', ''], ['s1', 'p1', 'o1', 'c4'])); }); describe('with an existing object parameter', function () { it('should iterate all items with this object', shouldIncludeAll(collect(store, 'forEach', null, null, 'o1', null), ['s1', 'p1', 'o1', ''], ['s2', 'p1', 'o1', ''], ['s1', 'p1', 'o1', 'c4'])); }); describe('with an existing graph parameter', function () { it('should iterate all items with this graph', shouldIncludeAll(collect(store, 'forEach', null, null, null, ''), ['s1', 'p1', 'o1'], ['s1', 'p1', 'o2'], ['s1', 'p2', 'o2'], ['s2', 'p1', 'o1'])); }); describe('with no parameters', function () { it('should iterate all items', shouldIncludeAll(collect(store, 'forEach', null, null, null, null), ['s1', 'p1', 'o1'], ['s1', 'p1', 'o2'], ['s1', 'p2', 'o2'], ['s2', 'p1', 'o1'], ['s1', 'p1', 'o1', 'c4'])); }); }); describe('forSubjects', function () { describe('with existing predicate, object and graph parameters', function () { it('should iterate all subjects with this predicate, object and graph', function () { collect(store, 'forSubjects', 'p1', 'o1', '').should.have.deep.members([new NamedNode('s1'), new NamedNode('s2')]); }); }); describe('with a non-existing predicate', function () { it('should be empty', function () { collect(store, 'forSubjects', 'p3', null, null).should.be.empty; }); }); describe('with a non-existing object', function () { it('should be empty', function () { collect(store, 'forSubjects', null, 'o4', null).should.be.empty; }); }); describe('with a non-existing graph', function () { it('should be empty', function () { collect(store, 'forSubjects', null, null, 'g2').should.be.empty; }); }); }); describe('forPredicates', function () { describe('with existing subject, object and graph parameters', function () { it('should iterate all predicates with this subject, object and graph', function () { collect(store, 'forPredicates', 's1', 'o2', '').should.have.deep.members([new NamedNode('p1'), new NamedNode('p2')]); }); }); describe('with a non-existing subject', function () { it('should be empty', function () { collect(store, 'forPredicates', 's3', null, null).should.be.empty; }); }); describe('with a non-existing object', function () { it('should be empty', function () { collect(store, 'forPredicates', null, 'o4', null).should.be.empty; }); }); describe('with a non-existing graph', function () { it('should be empty', function () { collect(store, 'forPredicates', null, null, 'g2').should.be.empty; }); }); }); describe('forObjects', function () { describe('with existing subject, predicate and graph parameters', function () { it('should iterate all objects with this subject, predicate and graph', function () { collect(store, 'forObjects', 's1', 'p1', '').should.have.deep.members([new NamedNode('o1'), new NamedNode('o2')]); }); }); describe('with a non-existing subject', function () { it('should be empty', function () { collect(store, 'forObjects', 's3', null, null).should.be.empty; }); }); describe('with a non-existing predicate', function () { it('should be empty', function () { collect(store, 'forObjects', null, 'p3', null).should.be.empty; }); }); describe('with a non-existing graph', function () { it('should be empty', function () { collect(store, 'forObjects', null, null, 'g2').should.be.empty; }); }); }); describe('forGraphs', function () { describe('with existing subject, predicate and object parameters', function () { it('should iterate all graphs with this subject, predicate and object', function () { collect(store, 'forGraphs', 's1', 'p1', 'o1').should.have.deep.members([new DefaultGraph(), new NamedNode('c4')]); }); }); describe('with a non-existing subject', function () { it('should be empty', function () { collect(store, 'forObjects', 's3', null, null).should.be.empty; }); }); describe('with a non-existing predicate', function () { it('should be empty', function () { collect(store, 'forObjects', null, 'p3', null).should.be.empty; }); }); describe('with a non-existing graph', function () { it('should be empty', function () { collect(store, 'forPredicates', null, null, 'g2').should.be.empty; }); }); }); describe('every', function () { var count = 3; function thirdTimeFalse() { return count-- === 0; } describe('with no parameters and a callback always returning true', function () { it('should return true', function () { store.every(alwaysTrue, null, null, null, null).should.be.true; }); }); describe('with no parameters and a callback always returning false', function () { it('should return false', function () { store.every(alwaysFalse, null, null, null, null).should.be.false; }); }); describe('with no parameters and a callback that returns false after 3 calls', function () { it('should return false', function () { store.every(thirdTimeFalse, null, null, null, null).should.be.false; }); }); }); describe('some', function () { var count = 3; function thirdTimeFalse() { return count-- !== 0; } describe('with no parameters and a callback always returning true', function () { it('should return true', function () { store.some(alwaysTrue, null, null, null, null).should.be.true; }); }); describe('with no parameters and a callback always returning false', function () { it('should return false', function () { store.some(alwaysFalse, null, null, null, null).should.be.false; }); }); describe('with no parameters and a callback that returns true after 3 calls', function () { it('should return false', function () { store.some(thirdTimeFalse, null, null, null, null).should.be.true; }); }); describe('with a non-existing subject', function () { it('should return true', function () { store.some(null, new NamedNode('s3'), null, null, null).should.be.false; }); }); describe('with a non-existing predicate', function () { it('should return false', function () { store.some(null, null, new NamedNode('p3'), null, null).should.be.false; }); }); describe('with a non-existing object', function () { it('should return false', function () { store.some(null, null, null, new NamedNode('o4'), null).should.be.false; }); }); describe('with a non-existing graph', function () { it('should return false', function () { store.some(null, null, null, null, new NamedNode('g2')).should.be.false; }); }); }); describe('when counted without parameters', function () { it('should count all items in all graphs', function () { store.countQuads().should.equal(5); }); }); describe('when counted with an existing subject parameter', function () { it('should count all items with this subject in all graphs', function () { store.countQuads(new NamedNode('s1'), null, null).should.equal(4); }); }); describe('when counted with a non-existing subject parameter', function () { it('should be empty', function () { store.countQuads(new NamedNode('s3'), null, null).should.equal(0); }); }); describe('when counted with a non-existing subject parameter that exists elsewhere', function () { it('should be empty', function () { store.countQuads(new NamedNode('p1'), null, null).should.equal(0); }); }); describe('when counted with an existing predicate parameter', function () { it('should count all items with this predicate in all graphs', function () { store.countQuads(null, new NamedNode('p1'), null).should.equal(4); }); }); describe('when counted with a non-existing predicate parameter', function () { it('should be empty', function () { store.countQuads(null, new NamedNode('p3'), null).should.equal(0); }); }); describe('when counted with an existing object parameter', function () { it('should count all items with this object in all graphs', function () { store.countQuads(null, null, 'o1').should.equal(3); }); }); describe('when counted with a non-existing object parameter', function () { it('should be empty', function () { store.countQuads(null, null, 'o4').should.equal(0); }); }); describe('when counted with existing subject and predicate parameters', function () { it('should count all items with this subject and predicate in all graphs', function () { store.countQuads('s1', 'p1', null).should.equal(3); }); }); describe('when counted with non-existing subject and predicate parameters', function () { it('should be empty', function () { store.countQuads('s2', 'p2', null).should.equal(0); }); }); describe('when counted with existing subject and object parameters', function () { it('should count all items with this subject and object in all graphs', function () { store.countQuads('s1', null, 'o1').should.equal(2); }); }); describe('when counted with non-existing subject and object parameters', function () { it('should be empty', function () { store.countQuads('s2', 'p2', null).should.equal(0); }); }); describe('when counted with existing predicate and object parameters', function () { it('should count all items with this predicate and object in all graphs', function () { store.countQuads(null, 'p1', 'o1').should.equal(3); }); }); describe('when counted with non-existing predicate and object parameters', function () { it('should be empty', function () { store.countQuads(null, 'p2', 'o3').should.equal(0); }); }); describe('when counted with existing subject, predicate, and object parameters', function () { it('should count all items with this subject, predicate, and object in all graphs', function () { store.countQuads('s1', 'p1', 'o1').should.equal(2); }); }); describe('when counted with a non-existing triple', function () { it('should be empty', function () { store.countQuads('s2', 'p2', 'o1').should.equal(0); }); }); describe('when counted with the default graph parameter', function () { it('should count all items in the default graph', function () { store.countQuads(null, null, null, new DefaultGraph()).should.equal(4); }); }); describe('when counted with an existing named graph parameter', function () { it('should count all items in that graph', function () { store.countQuads(null, null, null, 'c4').should.equal(1); }); }); describe('when counted with a non-existing named graph parameter', function () { it('should be empty', function () { store.countQuads(null, null, null, 'c5').should.equal(0); }); }); describe('when trying to remove a triple with a non-existing subject', function () { before(function () { store.removeQuad(new NamedNode('s0'), new NamedNode('p1'), new NamedNode('o1')).should.be.false; }); it('should still have size 5', function () { store.size.should.eql(5); }); }); describe('when trying to remove a triple with a non-existing predicate', function () { before(function () { store.removeQuad(new NamedNode('s1'), new NamedNode('p0'), new NamedNode('o1')).should.be.false; }); it('should still have size 5', function () { store.size.should.eql(5); }); }); describe('when trying to remove a triple with a non-existing object', function () { before(function () { store.removeQuad(new NamedNode('s1'), new NamedNode('p1'), new NamedNode('o0')).should.be.false; }); it('should still have size 5', function () { store.size.should.eql(5); }); }); describe('when trying to remove a triple for which no subjects exist', function () { before(function () { store.removeQuad(new NamedNode('o1'), new NamedNode('p1'), new NamedNode('o1')).should.be.false; }); it('should still have size 5', function () { store.size.should.eql(5); }); }); describe('when trying to remove a triple for which no predicates exist', function () { before(function () { store.removeQuad(new NamedNode('s1'), new NamedNode('s1'), new NamedNode('o1')).should.be.false; }); it('should still have size 5', function () { store.size.should.eql(5); }); }); describe('when trying to remove a triple for which no objects exist', function () { before(function () { store.removeQuad(new NamedNode('s1'), new NamedNode('p1'), new NamedNode('s1')).should.be.false; }); it('should still have size 5', function () { store.size.should.eql(5); }); }); describe('when trying to remove a triple that does not exist', function () { before(function () { store.removeQuad(new NamedNode('s1'), new NamedNode('p2'), new NamedNode('o1')).should.be.false; }); it('should still have size 5', function () { store.size.should.eql(5); }); }); describe('when trying to remove an incomplete triple', function () { before(function () { store.removeQuad(new NamedNode('s1'), null, null).should.be.false; }); it('should still have size 5', function () { store.size.should.eql(5); }); }); describe('when trying to remove a triple with a non-existing graph', function () { before(function () { store.removeQuad(new NamedNode('s1'), new NamedNode('p1'), new NamedNode('o1'), new NamedNode('c0')).should.be.false; }); it('should still have size 5', function () { store.size.should.eql(5); }); }); describe('when removing an existing triple', function () { before(function () { store.removeQuad(new NamedNode('s1'), new NamedNode('p1'), new NamedNode('o1')).should.be.true; }); it('should have size 4', function () { store.size.should.eql(4); }); it('should not contain that triple anymore', shouldIncludeAll(function () { return store.getQuads(); }, ['s1', 'p1', 'o2'], ['s1', 'p2', 'o2'], ['s2', 'p1', 'o1'], ['s1', 'p1', 'o1', 'c4'])); }); describe('when removing an existing triple from a named graph', function () { before(function () { store.removeQuad(new NamedNode('s1'), new NamedNode('p1'), new NamedNode('o1'), new NamedNode('c4')).should.be.true; }); it('should have size 3', function () { store.size.should.eql(3); }); itShouldBeEmpty(function () { return store.getQuads(null, null, null, 'c4'); }); }); describe('when removing multiple triples', function () { before(function () { store.removeQuads([ new Quad(new NamedNode('s1'), new NamedNode('p2'), new NamedNode('o2')), new Quad(new NamedNode('s2'), new NamedNode('p1'), new NamedNode('o1')), ]); }); it('should have size 1', function () { store.size.should.eql(1); }); it('should not contain those triples anymore', shouldIncludeAll(function () { return store.getQuads(); }, ['s1', 'p1', 'o2'])); }); describe('when adding and removing a triple', function () { before(function () { store.addQuad(new NamedNode('a'), new NamedNode('b'), new NamedNode('c')).should.be.true; store.removeQuad(new NamedNode('a'), new NamedNode('b'), new NamedNode('c')).should.be.true; }); it('should have an unchanged size', function () { store.size.should.eql(1); }); }); }); describe('An N3Store containing a blank node', function () { var store = new N3Store(); var b1 = store.createBlankNode(); store.addQuad(new NamedNode('s1'), new NamedNode('p1'), b1).should.be.true; describe('when searched with more than one variable', function () { it('should return a triple with the blank node as an object', shouldIncludeAll(store.getQuads(), ['s1', 'p1', '_:' + b1.value])); }); describe('when searched with one variable', function () { it('should return a triple with the blank node as an object', shouldIncludeAll(store.getQuads('s1', 'p1'), ['s1', 'p1', '_:' + b1.value])); }); }); describe('An N3Store with a custom DataFactory', function () { var store, factory = {}; before(function () { factory.quad = function (s, p, o, g) { return { s: s, p: p, o: o, g: g }; }; ['namedNode', 'blankNode', 'literal', 'variable', 'defaultGraph'].forEach(function (f) { factory[f] = function (n) { return n ? f[0] + '-' + n : f; }; }); store = new N3Store({ factory: factory }); store.addQuad('s1', 'p1', 'o1').should.be.true; store.addQuad({ subject: 's1', predicate: 'p1', object: 'o2' }).should.be.true; store.addQuads([ { subject: 's1', predicate: 'p2', object: 'o2' }, { subject: 's2', predicate: 'p1', object: 'o1' }, ]); store.addQuad('s1', 'p1', 'o1', 'c4').should.be.true; }); it('should use the factory when returning quads', function () { store.getQuads().should.deep.equal([ { s: 'n-s1', p: 'n-p1', o: 'n-o1', g: 'defaultGraph' }, { s: 'n-s1', p: 'n-p1', o: 'n-o2', g: 'defaultGraph' }, { s: 'n-s1', p: 'n-p2', o: 'n-o2', g: 'defaultGraph' }, { s: 'n-s2', p: 'n-p1', o: 'n-o1', g: 'defaultGraph' }, { s: 'n-s1', p: 'n-p1', o: 'n-o1', g: 'n-c4' }, ]); }); }); describe('An N3Store', function () { var store = new N3Store(); // Test inspired by http://www.devthought.com/2012/01/18/an-object-is-not-a-hash/. // The value `__proto__` is not supported however – fixing it introduces too much overhead. it('should be able to contain entities with JavaScript object property names', function () { store.addQuad('toString', 'valueOf', 'toLocaleString', 'hasOwnProperty').should.be.true; shouldIncludeAll(store.getQuads(null, null, null, 'hasOwnProperty'), ['toString', 'valueOf', 'toLocaleString', 'hasOwnProperty'])(); }); it('should be able to contain entities named "null"', function () { store.addQuad('null', 'null', 'null', 'null').should.be.true; shouldIncludeAll(store.getQuads(null, null, null, 'null'), ['null', 'null', 'null', 'null'])(); }); }); }); function alwaysTrue() { return true; } function alwaysFalse() { return false; } function collect(store, method, arg1, arg2, arg3, arg4) { var results = []; store[method](function (r) { results.push(r); }, arg1 && fromId(arg1), arg2 && fromId(arg2), arg3 && fromId(arg3), arg4 && fromId(arg4)); return results; } function itShouldBeEmpty(result) { it('should be empty', function () { if (typeof result === 'function') result = result(); result.should.be.empty; }); } function shouldIncludeAll(result) { var items = Array.prototype.slice.call(arguments, 1).map(function (arg) { return new Quad(fromId(arg[0]), fromId(arg[1]), fromId(arg[2]), fromId(arg[3] || '')); }); return function () { if (typeof result === 'function') result = result(); result = result.map(function (r) { return r.toJSON(); }); result.should.have.length(items.length); for (var i = 0; i < items.length; i++) result.should.include.something.that.deep.equals(items[i].toJSON()); }; } function ArrayReader(items) { var reader = new Readable({ objectMode: true }); reader._read = function () { this.push(items.shift() || null); }; return reader; } N3.js-1.0.4/test/N3StreamParser-test.js000066400000000000000000000100211343333361000175030ustar00rootroot00000000000000var N3StreamParser = require('../N3').StreamParser; var Readable = require('stream').Readable, Writable = require('stream').Writable, NamedNode = require('../N3').DataFactory.internal.NamedNode; describe('N3StreamParser', function () { describe('The N3StreamParser module', function () { it('should be a function', function () { N3StreamParser.should.be.a('function'); }); it('should make N3Lexer objects', function () { N3StreamParser().should.be.an.instanceof(N3StreamParser); }); it('should be an N3Lexer constructor', function () { new N3StreamParser().should.be.an.instanceof(N3StreamParser); }); }); describe('An N3StreamParser instance', function () { it('parses the empty stream', shouldParse([], 0)); it('parses the zero-length stream', shouldParse([''], 0)); it('parses one triple', shouldParse([' .'], 1)); it('parses two triples', shouldParse([' ', ' . ', '.'], 2)); it('should parse decimals that are split across chunks in the stream', shouldParse(' 11.2 .'.match(/.{1,2}/g), 1)); it('should parse non-breaking spaces that are split across chunks in the stream correctly', function (done) { var buffer = Buffer.from(' " " .'), chunks = [buffer, buffer.slice(0, 15), buffer.slice(15, buffer.length)]; shouldParse(chunks, 2, function (triples) { triples[0].should.deep.equal(triples[1]); })(done); }); it("doesn't parse an invalid stream", shouldNotParse(['z.'], 'Unexpected "z." on line 1.'), { token: undefined, line: 1, previousToken: undefined }); it('emits "prefix" events', shouldEmitPrefixes(['@prefix a: . a:a a:b a:c. @prefix b: .'], { a: new NamedNode('http://a.org/#'), b: new NamedNode('http://b.org/#') })); it('passes an error', function () { var input = new Readable(), parser = new N3StreamParser(), error = null; parser.on('error', function (e) { error = e; }); parser.import(input); input.emit('error', new Error()); expect(error).to.be.an.instanceof(Error); }); }); }); function shouldParse(chunks, expectedLength, validateTriples) { return function (done) { var triples = [], inputStream = new ArrayReader(chunks), parser = new N3StreamParser(), outputStream = new ArrayWriter(triples); parser.import(inputStream).should.equal(parser); parser.pipe(outputStream); parser.on('error', done); parser.on('end', function () { triples.should.have.length(expectedLength); if (validateTriples) validateTriples(triples); done(); }); }; } function shouldNotParse(chunks, expectedMessage, expectedContext) { return function (done) { var inputStream = new ArrayReader(chunks), parser = N3StreamParser(), outputStream = new ArrayWriter([]); inputStream.pipe(parser); parser.pipe(outputStream); parser.on('error', function (error) { error.should.be.an.instanceof(Error); error.message.should.equal(expectedMessage); if (expectedContext) error.context.should.deep.equal(expectedContext); done(); }); }; } function shouldEmitPrefixes(chunks, expectedPrefixes) { return function (done) { var prefixes = {}, parser = N3StreamParser(), inputStream = new ArrayReader(chunks); inputStream.pipe(parser); parser.on('data', function () {}); parser.on('prefix', function (prefix, iri) { prefixes[prefix] = iri; }); parser.on('error', done); parser.on('end', function (error) { prefixes.should.deep.equal(expectedPrefixes); done(error); }); }; } function ArrayReader(items) { var reader = new Readable(); reader._read = function () { this.push(items.shift() || null); }; return reader; } function ArrayWriter(items) { var writer = new Writable({ objectMode: true }); writer._write = function (chunk, encoding, done) { items.push(chunk); done(); }; return writer; } N3.js-1.0.4/test/N3StreamWriter-test.js000066400000000000000000000106701343333361000175350ustar00rootroot00000000000000var N3StreamWriter = require('../N3').StreamWriter; var Readable = require('stream').Readable, Writable = require('stream').Writable, DataFactory = require('../N3').DataFactory; var Quad = DataFactory.internal.Quad, NamedNode = DataFactory.internal.NamedNode, fromId = DataFactory.internal.fromId; describe('N3StreamWriter', function () { describe('The N3StreamWriter module', function () { it('should be a function', function () { N3StreamWriter.should.be.a('function'); }); it('should make N3Lexer objects', function () { N3StreamWriter().should.be.an.instanceof(N3StreamWriter); }); it('should be an N3Lexer constructor', function () { new N3StreamWriter().should.be.an.instanceof(N3StreamWriter); }); }); describe('An N3StreamWriter instance', function () { it('should serialize 0 triples', shouldSerialize('')); it('should serialize 1 triple', shouldSerialize(['abc', 'def', 'ghi'], ' .\n')); it('should serialize 2 triples', shouldSerialize(['abc', 'def', 'ghi'], ['jkl', 'mno', 'pqr'], ' .\n' + ' .\n')); it('should serialize 3 triples', shouldSerialize(['abc', 'def', 'ghi'], ['jkl', 'mno', 'pqr'], ['stu', 'vwx', 'yz'], ' .\n' + ' .\n' + ' .\n')); it('should use prefixes when possible', shouldSerialize({ prefixes: { a: 'http://a.org/', b: new NamedNode('http://a.org/b#'), c: 'http://a.org/b' } }, ['http://a.org/bc', 'http://a.org/b#ef', 'http://a.org/bhi'], ['http://a.org/bc/de', 'http://a.org/b#e#f', 'http://a.org/b#x/t'], ['http://a.org/3a', 'http://a.org/b#3a', 'http://a.org/b#a3'], '@prefix a: .\n' + '@prefix b: .\n\n' + 'a:bc b:ef a:bhi.\n' + ' .\n' + ' b:a3.\n')); it('should take over prefixes from the input stream', function (done) { var inputStream = new Readable(), writer = new N3StreamWriter(), outputStream = new StringWriter(); writer.import(inputStream); writer.pipe(outputStream); // emit prefixes and close inputStream.emit('prefix', 'a', new NamedNode('http://a.org/')); inputStream.emit('prefix', 'b', new NamedNode('http://b.org/')); inputStream.push(null); writer.on('error', done); writer.on('end', function () { outputStream.result.should.equal('@prefix a: .\n\n' + '@prefix b: .\n\n'); done(); }); }); }); it('passes an error', function () { var input = new Readable(), writer = new N3StreamWriter(), error = null; writer.on('error', function (e) { error = e; }); writer.import(input); input.emit('error', new Error()); expect(error).to.be.an.instanceof(Error); }); }); function shouldSerialize(/* options?, tripleArrays..., expectedResult */) { var tripleArrays = Array.prototype.slice.call(arguments), expectedResult = tripleArrays.pop(), options = tripleArrays[0] instanceof Array ? null : tripleArrays.shift(); tripleArrays = tripleArrays.map(function (i) { return new Quad(fromId(i[0]), fromId(i[1]), fromId(i[2])); }); return function (done) { var inputStream = new ArrayReader(tripleArrays), writer = new N3StreamWriter(options), outputStream = new StringWriter(); writer.import(inputStream).should.equal(writer); writer.pipe(outputStream); writer.on('error', done); writer.on('end', function () { outputStream.result.should.equal(expectedResult); done(); }); }; } function ArrayReader(items) { var reader = new Readable({ objectMode: true }); reader._read = function () { this.push(items.shift() || null); }; return reader; } function StringWriter() { var writer = new Writable({ encoding: 'utf-8', decodeStrings: false }); writer.result = ''; writer._write = function (chunk, encoding, done) { this.result += chunk; done(); }; return writer; } N3.js-1.0.4/test/N3Util-test.js000066400000000000000000000221661343333361000160250ustar00rootroot00000000000000var N3Util = require('../N3').Util; var DataFactory = require('../N3').DataFactory; var NamedNode = DataFactory.internal.NamedNode, Literal = DataFactory.internal.Literal, BlankNode = DataFactory.internal.BlankNode, Variable = DataFactory.internal.Variable, DefaultGraph = DataFactory.internal.DefaultGraph, Quad = DataFactory.internal.Quad; describe('N3Util', function () { describe('isNamedNode', function () { it('matches an IRI', function () { N3Util.isNamedNode(new NamedNode('http://example.org/')).should.be.true; }); it('matches an empty IRI', function () { N3Util.isNamedNode(new NamedNode('')).should.be.true; }); it('does not match a literal', function () { N3Util.isNamedNode(new Literal('"http://example.org/"')).should.be.false; }); it('does not match a blank node', function () { N3Util.isNamedNode(new BlankNode('x')).should.be.false; }); it('does not match a variable', function () { N3Util.isNamedNode(new Variable('x')).should.be.false; }); it('does not match null', function () { expect(N3Util.isNamedNode(null)).to.be.false; }); it('does not match undefined', function () { expect(N3Util.isNamedNode(undefined)).to.be.false; }); }); describe('isLiteral', function () { it('matches a literal', function () { N3Util.isLiteral(new Literal('"http://example.org/"')).should.be.true; }); it('matches a literal with a language', function () { N3Util.isLiteral(new Literal('"English"@en')).should.be.true; }); it('matches a literal with a language that contains a number', function () { N3Util.isLiteral(new Literal('"English"@es-419')).should.be.true; }); it('matches a literal with a type', function () { N3Util.isLiteral(new Literal('"3"^^http://www.w3.org/2001/XMLSchema#integer')).should.be.true; }); it('matches a literal with a newline', function () { N3Util.isLiteral(new Literal('"a\nb"')).should.be.true; }); it('matches a literal with a cariage return', function () { N3Util.isLiteral(new Literal('"a\rb"')).should.be.true; }); it('does not match an IRI', function () { N3Util.isLiteral(new NamedNode('http://example.org/')).should.be.false; }); it('does not match a blank node', function () { N3Util.isLiteral(new BlankNode('_:x')).should.be.false; }); it('does not match a variable', function () { N3Util.isLiteral(new Variable('x')).should.be.false; }); it('does not match null', function () { expect(N3Util.isLiteral(null)).to.be.false; }); it('does not match undefined', function () { expect(N3Util.isLiteral(undefined)).to.be.false; }); }); describe('isBlankNode', function () { it('matches a blank node', function () { N3Util.isBlankNode(new BlankNode('x')).should.be.true; }); it('does not match an IRI', function () { N3Util.isBlankNode(new NamedNode('http://example.org/')).should.be.false; }); it('does not match a literal', function () { N3Util.isBlankNode(new Literal('"http://example.org/"')).should.be.false; }); it('does not match a variable', function () { N3Util.isBlankNode(new Variable('x')).should.be.false; }); it('does not match null', function () { expect(N3Util.isBlankNode(null)).to.be.false; }); it('does not match undefined', function () { expect(N3Util.isBlankNode(undefined)).to.be.false; }); }); describe('isVariable', function () { it('matches a variable', function () { N3Util.isVariable(new Variable('x')).should.be.true; }); it('does not match an IRI', function () { N3Util.isVariable(new NamedNode('http://example.org/')).should.be.false; }); it('does not match a literal', function () { N3Util.isVariable(new Literal('"http://example.org/"')).should.be.false; }); it('does not match a blank node', function () { N3Util.isNamedNode(new BlankNode('x')).should.be.false; }); it('does not match null', function () { expect(N3Util.isVariable(null)).to.be.false; }); it('does not match undefined', function () { expect(N3Util.isVariable(undefined)).to.be.false; }); }); describe('isDefaultGraph', function () { it('does not match a blank node', function () { N3Util.isDefaultGraph(new BlankNode('x')).should.be.false; }); it('does not match an IRI', function () { N3Util.isDefaultGraph(new NamedNode('http://example.org/')).should.be.false; }); it('does not match a literal', function () { N3Util.isDefaultGraph(new Literal('"http://example.org/"')).should.be.false; }); it('does not match null', function () { expect(N3Util.isVariable(null)).to.be.false; }); it('does not match undefined', function () { expect(N3Util.isVariable(undefined)).to.be.false; }); }); describe('inDefaultGraph', function () { it('does not match a blank node', function () { N3Util.inDefaultGraph(new Quad(null, null, null, new BlankNode('x'))).should.be.false; }); it('does not match an IRI', function () { N3Util.inDefaultGraph(new Quad(null, null, null, new NamedNode('http://example.org/'))).should.be.false; }); it('does not match a literal', function () { N3Util.inDefaultGraph(new Quad(null, null, null, new Literal('"http://example.org/"'))).should.be.false; }); it('matches null', function () { N3Util.inDefaultGraph(new Quad(null, null, null, null)).should.be.true; }); it('matches undefined', function () { N3Util.inDefaultGraph(new Quad(null, null, null, undefined)).should.be.true; }); it('matches the default graph', function () { N3Util.inDefaultGraph(new Quad(null, null, null, new DefaultGraph())).should.be.true; }); }); describe('prefix', function () { var rdfs = N3Util.prefix('http://www.w3.org/2000/01/rdf-schema#'); it('should return a function', function () { expect(rdfs).to.be.an.instanceof(Function); }); describe('the function', function () { it('should expand the prefix', function () { expect(rdfs('label')).to.deep.equal(new NamedNode('http://www.w3.org/2000/01/rdf-schema#label')); }); it('should use a custom factory when specified', function () { var factory = { namedNode: function (s) { return 'n-' + s; } }; var rdfs = N3Util.prefix('http://www.w3.org/2000/01/rdf-schema#', factory); expect(rdfs('label')).to.equal('n-http://www.w3.org/2000/01/rdf-schema#label'); }); }); }); describe('prefixes', function () { describe('called without arguments', function () { var prefixes = N3Util.prefixes(); it('should return a function', function () { expect(prefixes).to.be.an.instanceof(Function); }); describe('the function', function () { it('should not expand non-registered prefixes', function () { expect(function () { prefixes('foo'); }).to.throw('Unknown prefix: foo'); }); it('should allow registering prefixes', function () { var p = prefixes('rdfs', 'http://www.w3.org/2000/01/rdf-schema#'); var rdfs = prefixes('rdfs'); expect(p).to.exist; expect(p).to.equal(rdfs); }); it('should expand the newly registered prefix', function () { var rdfs = prefixes('rdfs'); expect(rdfs('label')).to.deep.equal(new NamedNode('http://www.w3.org/2000/01/rdf-schema#label')); }); }); }); describe('called with a hash of prefixes', function () { var prefixes = N3Util.prefixes({ rdfs: 'http://www.w3.org/2000/01/rdf-schema#', owl: 'http://www.w3.org/2002/07/owl#', }); it('should return a function', function () { expect(prefixes).to.be.an.instanceof(Function); }); describe('the function', function () { it('should expand registered prefixes', function () { expect(prefixes('rdfs')('label')).to.deep.equal(new NamedNode('http://www.w3.org/2000/01/rdf-schema#label')); expect(prefixes('owl')('sameAs')).to.deep.equal(new NamedNode('http://www.w3.org/2002/07/owl#sameAs')); }); it('should not expand non-registered prefixes', function () { expect(function () { prefixes('foo'); }).to.throw('Unknown prefix: foo'); }); it('should allow registering prefixes', function () { var p = prefixes('my', 'http://example.org/#'); var my = prefixes('my'); expect(p).to.exist; expect(p).to.equal(my); }); it('should expand the newly registered prefix', function () { var my = prefixes('my'); expect(my('me')).to.deep.equal(new NamedNode('http://example.org/#me')); }); }); }); describe('called with a custom factory', function () { var factory = { namedNode: function (s) { return 'n-' + s; } }; var prefixes = N3Util.prefixes({ my: 'http://example.org/#' }, factory); it('should use the custom factory', function () { expect(prefixes('my')('foo')).to.equal('n-http://example.org/#foo'); }); }); }); }); N3.js-1.0.4/test/N3Writer-test.js000066400000000000000000000623521343333361000163650ustar00rootroot00000000000000var N3Writer = require('../N3').Writer; var DataFactory = require('../N3').DataFactory; var NamedNode = DataFactory.internal.NamedNode, Literal = DataFactory.internal.Literal, Quad = DataFactory.internal.Quad, fromId = DataFactory.internal.fromId; describe('N3Writer', function () { describe('The N3Writer module', function () { it('should be a function', function () { N3Writer.should.be.a('function'); }); it('should make N3Writer objects', function () { N3Writer().should.be.an.instanceof(N3Writer); }); it('should be an N3Writer constructor', function () { new N3Writer().should.be.an.instanceof(N3Writer); }); }); describe('An N3Writer instance', function () { it('should serialize a single triple', function () { var writer = N3Writer(); writer.quadToString(new NamedNode('a'), new NamedNode('b'), new NamedNode('c')).should.equal(' .\n'); }); it('should serialize a single quad', function () { var writer = N3Writer(); writer.quadToString(new NamedNode('a'), new NamedNode('b'), new NamedNode('c'), new NamedNode('g')).should.equal(' .\n'); }); it('should serialize an array of triples', function () { var writer = N3Writer(); var triples = [new Quad(new NamedNode('a'), new NamedNode('b'), new NamedNode('c')), new Quad(new NamedNode('d'), new NamedNode('e'), new NamedNode('f'))]; writer.quadsToString(triples).should.equal(' .\n .\n'); }); it('should serialize 0 triples', shouldSerialize('')); it('should serialize 1 triple', shouldSerialize(['abc', 'def', 'ghi'], ' .\n')); it('should serialize 2 triples', shouldSerialize(['abc', 'def', 'ghi'], ['jkl', 'mno', 'pqr'], ' .\n' + ' .\n')); it('should serialize 3 triples', shouldSerialize(['abc', 'def', 'ghi'], ['jkl', 'mno', 'pqr'], ['stu', 'vwx', 'yz'], ' .\n' + ' .\n' + ' .\n')); it('should serialize a literal', shouldSerialize(['a', 'b', '"cde"'], ' "cde".\n')); it('should serialize a literal with a type', shouldSerialize(['a', 'b', '"cde"^^fgh'], ' "cde"^^.\n')); it('should serialize a literal with a language', shouldSerialize(['a', 'b', '"cde"@en-us'], ' "cde"@en-us.\n')); // e.g. http://vocab.getty.edu/aat/300264727.ttl it('should serialize a literal with an artificial language', shouldSerialize(['a', 'b', '"cde"@qqq-002'], ' "cde"@qqq-002.\n')); it('should serialize a literal containing a single quote', shouldSerialize(['a', 'b', '"c\'de"'], ' "c\'de".\n')); it('should serialize a literal containing a double quote', shouldSerialize(['a', 'b', '"c"de"'], ' "c\\"de".\n')); it('should serialize a literal containing a backspace', shouldSerialize(['a', 'b', '"c\\de"'], ' "c\\\\de".\n')); it('should serialize a literal containing a tab character', shouldSerialize(['a', 'b', '"c\tde"'], ' "c\\tde".\n')); it('should serialize a literal containing a newline character', shouldSerialize(['a', 'b', '"c\nde"'], ' "c\\nde".\n')); it('should serialize a literal containing a cariage return character', shouldSerialize(['a', 'b', '"c\rde"'], ' "c\\rde".\n')); it('should serialize a literal containing a backspace character', shouldSerialize(['a', 'b', '"c\bde"'], ' "c\\bde".\n')); it('should serialize a literal containing a form feed character', shouldSerialize(['a', 'b', '"c\fde"'], ' "c\\fde".\n')); it('should serialize a literal containing a line separator', shouldSerialize(['a', 'b', '"c\u2028de"'], ' "c\u2028de".\n')); it('should serialize a literal containing a paragraph separator', shouldSerialize(['a', 'b', '"c\u2029de"'], ' "c\u2029de".\n')); it('should serialize a literal containing special unicode characters', shouldSerialize(['a', 'b', '"c\u0000\u0001"'], ' "c\\u0000\\u0001".\n')); it('should serialize blank nodes', shouldSerialize(['_:a', 'b', { termType: 'BlankNode', value: 'c' }], '_:a _:c.\n')); it('should not leave leading whitespace if the prefix set is empty', shouldSerialize({}, ['a', 'b', 'c'], ' .\n')); it('should serialize valid prefixes', shouldSerialize({ prefixes: { a: 'http://a.org/', b: new NamedNode('http://a.org/b#'), c: 'http://a.org/b' } }, '@prefix a: .\n' + '@prefix b: .\n\n')); it('should use prefixes when possible', shouldSerialize({ prefixes: { a: 'http://a.org/', b: 'http://a.org/b#', c: 'http://a.org/b' } }, ['http://a.org/bc', 'http://a.org/b#ef', 'http://a.org/bhi'], ['http://a.org/bc/de', 'http://a.org/b#e#f', 'http://a.org/b#x/t'], ['http://a.org/3a', 'http://a.org/b#3a', 'http://a.org/b#a3'], '@prefix a: .\n' + '@prefix b: .\n\n' + 'a:bc b:ef a:bhi.\n' + ' .\n' + ' b:a3.\n')); it('should expand prefixes when possible', shouldSerialize({ prefixes: { a: 'http://a.org/', b: 'http://a.org/b#' } }, ['a:bc', 'b:ef', 'c:bhi'], '@prefix a: .\n' + '@prefix b: .\n\n' + 'a:bc b:ef .\n')); it('should not repeat the same subjects', shouldSerialize(['abc', 'def', 'ghi'], ['abc', 'mno', 'pqr'], ['stu', 'vwx', 'yz'], ' ;\n' + ' .\n' + ' .\n')); it('should not repeat the same predicates', shouldSerialize(['abc', 'def', 'ghi'], ['abc', 'def', 'pqr'], ['abc', 'bef', 'ghi'], ['abc', 'bef', 'pqr'], ['stu', 'bef', 'yz'], ' , ;\n' + ' , .\n' + ' .\n')); it('should write rdf:type as "a"', shouldSerialize(['abc', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', 'def'], ' a .\n')); it('should serialize a graph with 1 triple', shouldSerialize(['abc', 'def', 'ghi', 'xyz'], ' {\n' + ' \n' + '}\n')); it('should serialize a graph with 3 triples', shouldSerialize(['abc', 'def', 'ghi', 'xyz'], ['jkl', 'mno', 'pqr', 'xyz'], ['stu', 'vwx', 'yz', 'xyz'], ' {\n' + ' .\n' + ' .\n' + ' \n' + '}\n')); it('should serialize three graphs', shouldSerialize(['abc', 'def', 'ghi', 'xyz'], ['jkl', 'mno', 'pqr', ''], ['stu', 'vwx', 'yz', 'abc'], ' {\n \n}\n' + ' .\n' + ' {\n \n}\n')); it('should output 8-bit unicode characters as escape sequences', shouldSerialize(['\ud835\udc00', '\ud835\udc00', '"\ud835\udc00"^^\ud835\udc00', '\ud835\udc00'], '<\\U0001d400> {\n<\\U0001d400> <\\U0001d400> "\\U0001d400"^^<\\U0001d400>\n}\n')); it('should not use escape sequences in blank nodes', shouldSerialize(['_:\ud835\udc00', '_:\ud835\udc00', '_:\ud835\udc00', '_:\ud835\udc00'], '_:\ud835\udc00 {\n_:\ud835\udc00 _:\ud835\udc00 _:\ud835\udc00\n}\n')); it('calls the done callback when ending the outputstream errors', function (done) { var writer = new N3Writer({ write: function () {}, end: function () { throw new Error('error'); }, }); writer.end(done); }); it('sends output through end when no stream argument is given', function (done) { var writer = new N3Writer(), notCalled = true; writer.addQuad(new Quad(new NamedNode('a'), new NamedNode('b'), new NamedNode('c')), function () { notCalled = false; }); writer.end(function (error, output) { output.should.equal(' .\n'); done(notCalled || error); }); }); it('respects the prefixes argument when no stream argument is given', function (done) { var writer = new N3Writer({ prefixes: { a: 'b#' } }); writer.addQuad(new Quad(new NamedNode('b#a'), new NamedNode('b#b'), new NamedNode('b#c'))); writer.end(function (error, output) { output.should.equal('@prefix a: .\n\na:a a:b a:c.\n'); done(error); }); }); it('does not repeat identical prefixes', function (done) { var writer = new N3Writer(); writer.addPrefix('a', 'b#'); writer.addPrefix('a', 'b#'); writer.addQuad(new Quad(new NamedNode('b#a'), new NamedNode('b#b'), new NamedNode('b#c'))); writer.addPrefix('a', 'b#'); writer.addPrefix('a', 'b#'); writer.addPrefix('b', 'b#'); writer.addPrefix('a', 'c#'); writer.end(function (error, output) { output.should.equal('@prefix a: .\n\na:a a:b a:c.\n' + '@prefix b: .\n\n@prefix a: .\n\n'); done(error); }); }); it('serializes triples of a graph with a prefix declaration in between', function (done) { var writer = new N3Writer(); writer.addPrefix('a', 'b#'); writer.addQuad(new Quad(new NamedNode('b#a'), new NamedNode('b#b'), new NamedNode('b#c'), new NamedNode('b#g'))); writer.addPrefix('d', 'e#'); writer.addQuad(new Quad(new NamedNode('b#a'), new NamedNode('b#b'), new NamedNode('b#d'), new NamedNode('b#g'))); writer.end(function (error, output) { output.should.equal('@prefix a: .\n\na:g {\na:a a:b a:c\n}\n' + '@prefix d: .\n\na:g {\na:a a:b a:d\n}\n'); done(error); }); }); it('should accept triples with separated components', function (done) { var writer = N3Writer(); writer.addQuad(new NamedNode('a'), new NamedNode('b'), new NamedNode('c')); writer.addQuad(new NamedNode('a'), new NamedNode('b'), new NamedNode('d')); writer.end(function (error, output) { output.should.equal(' , .\n'); done(error); }); }); it('should accept quads with separated components', function (done) { var writer = N3Writer(); writer.addQuad(new NamedNode('a'), new NamedNode('b'), new NamedNode('c'), new NamedNode('g')); writer.addQuad(new NamedNode('a'), new NamedNode('b'), new NamedNode('d'), new NamedNode('g')); writer.end(function (error, output) { output.should.equal(' {\n , \n}\n'); done(error); }); }); it('should serialize triples with an empty blank node as object', function (done) { var writer = N3Writer(); writer.addQuad(new NamedNode('a1'), new NamedNode('b'), writer.blank()); writer.addQuad(new NamedNode('a2'), new NamedNode('b'), writer.blank([])); writer.end(function (error, output) { output.should.equal(' [].\n' + ' [].\n'); done(error); }); }); it('should serialize triples with a one-triple blank node as object', function (done) { var writer = N3Writer(); writer.addQuad(new NamedNode('a1'), new NamedNode('b'), writer.blank(new NamedNode('d'), new NamedNode('e'))); writer.addQuad(new NamedNode('a2'), new NamedNode('b'), writer.blank({ predicate: new NamedNode('d'), object: new NamedNode('e') })); writer.addQuad(new NamedNode('a3'), new NamedNode('b'), writer.blank([{ predicate: new NamedNode('d'), object: new NamedNode('e') }])); writer.end(function (error, output) { output.should.equal(' [ ].\n' + ' [ ].\n' + ' [ ].\n'); done(error); }); }); it('should serialize triples with a two-triple blank node as object', function (done) { var writer = N3Writer(); writer.addQuad(new NamedNode('a'), new NamedNode('b'), writer.blank([ { predicate: new NamedNode('d'), object: new NamedNode('e') }, { predicate: new NamedNode('f'), object: new Literal('"g"') }, ])); writer.end(function (error, output) { output.should.equal(' [\n' + ' ;\n' + ' "g"\n' + '].\n'); done(error); }); }); it('should serialize triples with a three-triple blank node as object', function (done) { var writer = N3Writer(); writer.addQuad(new NamedNode('a'), new NamedNode('b'), writer.blank([ { predicate: new NamedNode('d'), object: new NamedNode('e') }, { predicate: new NamedNode('f'), object: new Literal('"g"') }, { predicate: new NamedNode('h'), object: new NamedNode('i') }, ])); writer.end(function (error, output) { output.should.equal(' [\n' + ' ;\n' + ' "g";\n' + ' \n' + '].\n'); done(error); }); }); it('should serialize triples with predicate-sharing blank node triples as object', function (done) { var writer = N3Writer(); writer.addQuad(new NamedNode('a'), new NamedNode('b'), writer.blank([ { predicate: new NamedNode('d'), object: new NamedNode('e') }, { predicate: new NamedNode('d'), object: new NamedNode('f') }, { predicate: new NamedNode('g'), object: new NamedNode('h') }, { predicate: new NamedNode('g'), object: new NamedNode('i') }, ])); writer.end(function (error, output) { output.should.equal(' [\n' + ' , ;\n' + ' , \n' + '].\n'); done(error); }); }); it('should serialize triples with nested blank nodes as object', function (done) { var writer = N3Writer(); writer.addQuad(new NamedNode('a1'), new NamedNode('b'), writer.blank([ { predicate: new NamedNode('d'), object: writer.blank() }, ])); writer.addQuad(new NamedNode('a2'), new NamedNode('b'), writer.blank([ { predicate: new NamedNode('d'), object: writer.blank(new NamedNode('e'), new NamedNode('f')) }, { predicate: new NamedNode('g'), object: writer.blank(new NamedNode('h'), new Literal('"i"')) }, ])); writer.addQuad(new NamedNode('a3'), new NamedNode('b'), writer.blank([ { predicate: new NamedNode('d'), object: writer.blank([ { predicate: new NamedNode('g'), object: writer.blank(new NamedNode('h'), new NamedNode('i')) }, { predicate: new NamedNode('j'), object: writer.blank(new NamedNode('k'), new Literal('"l"')) }, ]) }, ])); writer.end(function (error, output) { output.should.equal(' [\n' + ' []\n' + '].\n' + ' [\n' + ' [ ];\n' + ' [ "i" ]\n' + '].\n' + ' [\n' + ' [\n' + ' [ ];\n' + ' [ "l" ]\n' + ']\n' + '].\n'); done(error); }); }); it('should serialize triples with an empty blank node as subject', function (done) { var writer = N3Writer(); writer.addQuad(writer.blank(), new NamedNode('b'), new NamedNode('c')); writer.addQuad(writer.blank([]), new NamedNode('b'), new NamedNode('c')); writer.end(function (error, output) { output.should.equal('[] .\n' + '[] .\n'); done(error); }); }); it('should serialize triples with a one-triple blank node as subject', function (done) { var writer = N3Writer(); writer.addQuad(writer.blank(new NamedNode('a'), new NamedNode('b')), new NamedNode('c'), new NamedNode('d')); writer.addQuad(writer.blank({ predicate: new NamedNode('a'), object: new NamedNode('b') }), new NamedNode('c'), new NamedNode('d')); writer.addQuad(writer.blank([{ predicate: new NamedNode('a'), object: new NamedNode('b') }]), new NamedNode('c'), new NamedNode('d')); writer.end(function (error, output) { output.should.equal('[ ] .\n' + '[ ] .\n' + '[ ] .\n'); done(error); }); }); it('should serialize triples with an empty blank node as graph', function (done) { var writer = N3Writer(); writer.addQuad(new NamedNode('a'), new NamedNode('b'), new NamedNode('c'), writer.blank()); writer.addQuad(new NamedNode('a'), new NamedNode('b'), new NamedNode('c'), writer.blank([])); writer.end(function (error, output) { output.should.equal('[] {\n \n}\n' + '[] {\n \n}\n'); done(error); }); }); it('should serialize triples with an empty list as object', function (done) { var writer = N3Writer(); writer.addQuad(new NamedNode('a1'), new NamedNode('b'), writer.list()); writer.addQuad(new NamedNode('a2'), new NamedNode('b'), writer.list([])); writer.end(function (error, output) { output.should.equal(' ().\n' + ' ().\n'); done(error); }); }); it('should serialize triples with a one-element list as object', function (done) { var writer = N3Writer(); writer.addQuad(new NamedNode('a1'), new NamedNode('b'), writer.list([new NamedNode('c')])); writer.addQuad(new NamedNode('a2'), new NamedNode('b'), writer.list([new Literal('"c"')])); writer.end(function (error, output) { output.should.equal(' ().\n' + ' ("c").\n'); done(error); }); }); it('should serialize triples with a three-element list as object', function (done) { var writer = N3Writer(); writer.addQuad(new NamedNode('a1'), new NamedNode('b'), writer.list([new NamedNode('c'), new NamedNode('d'), new NamedNode('e')])); writer.addQuad(new NamedNode('a2'), new NamedNode('b'), writer.list([new Literal('"c"'), new Literal('"d"'), new Literal('"e"')])); writer.end(function (error, output) { output.should.equal(' ( ).\n' + ' ("c" "d" "e").\n'); done(error); }); }); it('should serialize triples with an empty list as subject', function (done) { var writer = N3Writer(); writer.addQuad(writer.list(), new NamedNode('b1'), new NamedNode('c')); writer.addQuad(writer.list([]), new NamedNode('b2'), new NamedNode('c')); writer.end(function (error, output) { output.should.equal('() .\n' + '() .\n'); done(error); }); }); it('should serialize triples with a one-element list as subject', function (done) { var writer = N3Writer(); writer.addQuad(writer.list([new NamedNode('a')]), new NamedNode('b1'), new NamedNode('c')); writer.addQuad(writer.list([new NamedNode('a')]), new NamedNode('b2'), new NamedNode('c')); writer.end(function (error, output) { output.should.equal('() .\n' + '() .\n'); done(error); }); }); it('should serialize triples with a three-element list as subject', function (done) { var writer = N3Writer(); writer.addQuad(writer.list([new NamedNode('a1'), new Literal('"b"'), new Literal('"c"')]), new NamedNode('d'), new NamedNode('e')); writer.end(function (error, output) { output.should.equal('( "b" "c") .\n'); done(error); }); }); it('should accept triples in bulk', function (done) { var writer = N3Writer(); writer.addQuads([new Quad(new NamedNode('a'), new NamedNode('b'), new NamedNode('c')), new Quad(new NamedNode('a'), new NamedNode('b'), new NamedNode('d'))]); writer.end(function (error, output) { output.should.equal(' , .\n'); done(error); }); }); it('should not allow writing after end', function (done) { var writer = N3Writer(); writer.addQuad(new Quad(new NamedNode('a'), new NamedNode('b'), new NamedNode('c'))); writer.end(); writer.addQuad(new Quad(new NamedNode('d'), new NamedNode('e'), new NamedNode('f')), function (error) { error.should.be.an.instanceof(Error); error.should.have.property('message', 'Cannot write because the writer has been closed.'); done(); }); }); it('should write simple triples in N-Quads mode', function (done) { var writer = N3Writer({ format: 'N-Quads' }); writer.addQuad(new NamedNode('a'), new NamedNode('b'), new NamedNode('c')); writer.addQuad(new NamedNode('a'), new NamedNode('b'), new NamedNode('d')); writer.end(function (error, output) { output.should.equal(' .\n .\n'); done(error); }); }); it('should write simple quads in N-Quads mode', function (done) { var writer = N3Writer({ format: 'N-Quads' }); var called = false; function callback() { called = true; } writer.addQuad(new NamedNode('a'), new NamedNode('b'), new NamedNode('c'), callback); writer.addQuad(new NamedNode('a'), new NamedNode('b'), new NamedNode('d'), new NamedNode('g')); writer.end(function (error, output) { called.should.be.true; output.should.equal(' .\n .\n'); done(error); }); }); it('should end when the end option is not set', function (done) { var outputStream = new QuickStream(), writer = N3Writer(outputStream, {}); outputStream.should.have.property('ended', false); writer.end(function () { outputStream.should.have.property('ended', true); done(); }); }); it('should end when the end option is set to true', function (done) { var outputStream = new QuickStream(), writer = N3Writer(outputStream, { end: true }); outputStream.should.have.property('ended', false); writer.end(function () { outputStream.should.have.property('ended', true); done(); }); }); it('should not end when the end option is set to false', function (done) { var outputStream = new QuickStream(), writer = N3Writer(outputStream, { end: false }); outputStream.should.have.property('ended', false); writer.end(function () { outputStream.should.have.property('ended', false); done(); }); }); }); }); function shouldSerialize(/* prefixes?, tripleArrays..., expectedResult */) { var tripleArrays = Array.prototype.slice.call(arguments), expectedResult = tripleArrays.pop(), prefixes = tripleArrays[0] instanceof Array ? null : tripleArrays.shift(); return function (done) { var outputStream = new QuickStream(), writer = N3Writer(outputStream, prefixes); (function next() { var item = tripleArrays.shift(); if (item) { var subject = typeof item[0] === 'string' ? fromId(item[0]) : item[0]; var predicate = typeof item[1] === 'string' ? fromId(item[1]) : item[1]; var object = typeof item[2] === 'string' ? fromId(item[2]) : item[2]; var graph = typeof item[3] === 'string' ? fromId(item[3]) : item[3]; writer.addQuad(new Quad(subject, predicate, object, graph), next); } else writer.end(function (error) { try { outputStream.result.should.equal(expectedResult); outputStream.should.have.property('ended', true); done(error); } catch (e) { done(e); } }); })(); }; } function QuickStream() { var stream = { ended: false }, buffer = ''; stream.write = function (chunk, encoding, callback) { buffer += chunk; callback && callback(); }; stream.end = function (callback) { stream.ended = true; stream.result = buffer; buffer = null; callback(); }; return stream; } N3.js-1.0.4/test/NamedNode-test.js000066400000000000000000000055211343333361000165350ustar00rootroot00000000000000var DataFactory = require('../N3').DataFactory; var NamedNode = DataFactory.internal.NamedNode, Term = DataFactory.internal.Term; describe('NamedNode', function () { describe('The NamedNode module', function () { it('should be a function', function () { NamedNode.should.be.a('function'); }); it('should make NamedNode objects', function () { NamedNode().should.be.an.instanceof(NamedNode); }); it('should make Term objects', function () { NamedNode().should.be.an.instanceof(Term); }); it('should be a NamedNode constructor', function () { new NamedNode().should.be.an.instanceof(NamedNode); }); it('should be a Term constructor', function () { new NamedNode().should.be.an.instanceof(Term); }); }); describe('A NamedNode instance created from an IRI', function () { var namedNode; before(function () { namedNode = new NamedNode('http://example.org/foo#bar'); }); it('should be a NamedNode', function () { namedNode.should.be.an.instanceof(NamedNode); }); it('should be a Term', function () { namedNode.should.be.an.instanceof(Term); }); it('should have term type "NamedNode"', function () { namedNode.termType.should.equal('NamedNode'); }); it('should have the IRI as value', function () { namedNode.should.have.property('value', 'http://example.org/foo#bar'); }); it('should have the IRI as id', function () { namedNode.should.have.property('id', 'http://example.org/foo#bar'); }); it('should equal a NamedNode instance with the same IRI', function () { namedNode.equals(new NamedNode('http://example.org/foo#bar')).should.be.true; }); it('should equal an object with the same term type and value', function () { namedNode.equals({ termType: 'NamedNode', value: 'http://example.org/foo#bar', }).should.be.true; }); it('should not equal a falsy object', function () { namedNode.equals(null).should.be.false; }); it('should not equal a NamedNode instance with another IRI', function () { namedNode.equals(new NamedNode('http://example.org/other')).should.be.false; }); it('should not equal an object with the same term type but a different value', function () { namedNode.equals({ termType: 'NamedNode', value: 'http://example.org/other', }).should.be.false; }); it('should not equal an object with a different term type but the same value', function () { namedNode.equals({ termType: 'BlankNode', value: 'http://example.org/foo#bar', }).should.be.false; }); it('should provide a JSON representation', function () { namedNode.toJSON().should.deep.equal({ termType: 'NamedNode', value: 'http://example.org/foo#bar', }); }); }); }); N3.js-1.0.4/test/Quad-test.js000066400000000000000000000126551343333361000156030ustar00rootroot00000000000000var DataFactory = require('../N3').DataFactory; var Quad = DataFactory.internal.Quad, Triple = DataFactory.internal.Triple, DefaultGraph = DataFactory.internal.DefaultGraph, fromId = DataFactory.internal.fromId; describe('Quad', function () { describe('The Quad module', function () { it('should be a function', function () { Quad.should.be.a('function'); }); it('should make Quad objects', function () { Quad().should.be.an.instanceof(Quad); }); it('should be a Quad constructor', function () { new Quad().should.be.an.instanceof(Quad); }); it('should equal Triple', function () { Quad.should.equal(Triple); }); }); describe('A Quad instance created with subject/predicate/object', function () { var quad, subject, predicate, object; before(function () { quad = new Quad( subject = fromId('s'), predicate = fromId('p'), object = fromId('o') ); }); it('should be a Quad', function () { quad.should.be.an.instanceof(Quad); }); it('should have the correct subject', function () { quad.subject.should.equal(subject); }); it('should have the correct predicate', function () { quad.predicate.should.equal(predicate); }); it('should have the correct object', function () { quad.object.should.equal(object); }); it('should have the default graph', function () { quad.graph.should.equal(new DefaultGraph()); }); it('should equal a quad with the same components', function () { quad.equals({ subject: subject, predicate: predicate, object: object, graph: new DefaultGraph(), }).should.be.true; }); it('should not equal a quad with a different subject', function () { quad.equals({ subject: fromId('x'), predicate: predicate, object: object, graph: new DefaultGraph(), }).should.be.false; }); it('should not equal a quad with a different predicate', function () { quad.equals({ subject: subject, predicate: fromId('x'), object: object, graph: new DefaultGraph(), }).should.be.false; }); it('should not equal a quad with a different object', function () { quad.equals({ subject: subject, predicate: predicate, object: fromId('x'), graph: new DefaultGraph(), }).should.be.false; }); it('should not equal a quad with a different graph', function () { quad.equals({ subject: subject, predicate: predicate, object: object, graph: fromId('x'), }).should.be.false; }); it('should provide a JSON representation', function () { quad.toJSON().should.deep.equal({ subject: { termType: 'NamedNode', value: 's' }, predicate: { termType: 'NamedNode', value: 'p' }, object: { termType: 'NamedNode', value: 'o' }, graph: { termType: 'DefaultGraph', value: '' }, }); }); }); describe('A Quad instance created with subject/predicate/object/graph', function () { var quad, subject, predicate, object, graph; before(function () { quad = new Quad( subject = fromId('s'), predicate = fromId('p'), object = fromId('o'), graph = fromId('g') ); }); it('should be a Quad', function () { quad.should.be.an.instanceof(Quad); }); it('should have the correct subject', function () { quad.subject.should.equal(subject); }); it('should have the correct predicate', function () { quad.predicate.should.equal(predicate); }); it('should have the correct object', function () { quad.object.should.equal(object); }); it('should have the default graph', function () { quad.graph.should.equal(graph); }); it('should equal a quad with the same components', function () { quad.equals({ subject: subject, predicate: predicate, object: object, graph: graph, }).should.be.true; }); it('should not equal a quad with a different subject', function () { quad.equals({ subject: fromId('x'), predicate: predicate, object: object, graph: graph, }).should.be.false; }); it('should not equal a quad with a different predicate', function () { quad.equals({ subject: subject, predicate: fromId('x'), object: object, graph: graph, }).should.be.false; }); it('should not equal a quad with a different object', function () { quad.equals({ subject: subject, predicate: predicate, object: fromId('x'), graph: graph, }).should.be.false; }); it('should not equal a quad with a different graph', function () { quad.equals({ subject: subject, predicate: predicate, object: object, graph: fromId('x'), }).should.be.false; }); it('should provide a JSON representation', function () { quad.toJSON().should.deep.equal({ subject: { termType: 'NamedNode', value: 's' }, predicate: { termType: 'NamedNode', value: 'p' }, object: { termType: 'NamedNode', value: 'o' }, graph: { termType: 'NamedNode', value: 'g' }, }); }); }); }); N3.js-1.0.4/test/Term-test.js000066400000000000000000000171621343333361000156160ustar00rootroot00000000000000var DataFactory = require('../N3').DataFactory; var Term = DataFactory.internal.Term, NamedNode = DataFactory.internal.NamedNode, BlankNode = DataFactory.internal.BlankNode, Literal = DataFactory.internal.Literal, Variable = DataFactory.internal.Variable, DefaultGraph = DataFactory.internal.DefaultGraph, toId = DataFactory.internal.toId, fromId = DataFactory.internal.fromId; describe('Term', function () { describe('The Term module', function () { it('should be a function', function () { Term.should.be.a('function'); }); it('should make Term objects', function () { Term().should.be.an.instanceof(Term); }); it('should be a Term constructor', function () { new Term().should.be.an.instanceof(Term); }); }); describe('fromId', function () { it('should create a DefaultGraph from a falsy value', function () { fromId(null).toJSON().should.deep.equal({ termType: 'DefaultGraph', value: '', }); }); it('should create a DefaultGraph from the empty string', function () { fromId('').toJSON().should.deep.equal({ termType: 'DefaultGraph', value: '', }); }); it('should create a NamedNode from an IRI', function () { fromId('http://example.org/foo#bar').toJSON().should.deep.equal({ termType: 'NamedNode', value: 'http://example.org/foo#bar', }); }); it('should create a BlankNode from a string that starts with an underscore', function () { fromId('_:b1').toJSON().should.deep.equal({ termType: 'BlankNode', value: 'b1', }); }); it('should create a Variable from a string that starts with a question mark', function () { fromId('?v1').toJSON().should.deep.equal({ termType: 'Variable', value: 'v1', }); }); it('should create a Literal from a string that starts with a quotation mark', function () { fromId('"abc"@en-us').toJSON().should.deep.equal({ termType: 'Literal', value: 'abc', language: 'en-us', datatype: { termType: 'NamedNode', value: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString', }, }); }); describe('with a custom factory', function () { var factory = { defaultGraph: function () { return ['d']; }, namedNode: function (n) { return ['n', n]; }, blankNode: function (b) { return ['b', b]; }, variable: function (v) { return ['v', v]; }, literal: function (l, m) { return ['l', l, m]; }, }; it('should create a DefaultGraph from a falsy value', function () { fromId(null, factory).should.deep.equal(['d']); }); it('should create a DefaultGraph from the empty string', function () { fromId('', factory).should.deep.equal(['d']); }); it('should create a NamedNode from an IRI', function () { fromId('http://example.org/foo#bar', factory).should.deep.equal(['n', 'http://example.org/foo#bar']); }); it('should create a BlankNode from a string that starts with an underscore', function () { fromId('_:b1', factory).should.deep.equal(['b', 'b1']); }); it('should create a Variable from a string that starts with a question mark', function () { fromId('?v1', factory).should.deep.equal(['v', 'v1']); }); it('should create a Literal without language or datatype', function () { fromId('"abc"', factory).should.deep.equal(['l', 'abc', undefined]); }); it('should create a Literal with a language', function () { fromId('"abc"@en-us', factory).should.deep.equal(['l', 'abc', 'en-us']); }); it('should create a Literal with a datatype', function () { fromId('"abc"^^https://ex.org/type', factory).should.deep.equal(['l', 'abc', ['n', 'https://ex.org/type']]); }); }); }); describe('toId', function () { it('should create the empty string a falsy value', function () { toId(null).should.equal(''); toId(false).should.equal(''); toId('').should.equal(''); }); it('should create the empty string from the DefaultGraph', function () { toId(new DefaultGraph()).should.equal(''); toId(new DefaultGraph().toJSON()).should.equal(''); }); it('should create an id that starts with a question mark from a Variable', function () { toId(new Variable('abc')).should.equal('?abc'); toId(new Variable('abc').toJSON()).should.equal('?abc'); }); it('should create an id that starts with a question mark from a Variable string', function () { toId('?abc').should.equal('?abc'); }); it('should create an id that starts with a quotation mark from a Literal', function () { toId(new Literal('"abc"')).should.equal('"abc"'); toId(new Literal('"abc"').toJSON()).should.equal('"abc"'); }); it('should create an id that starts with a quotation mark from a Literal string', function () { toId('"abc"').should.equal('"abc"'); }); it('should create an id that starts with a quotation mark and datatype from a Literal with a datatype', function () { toId(new Literal('"abc"^^http://example.org')).should.equal('"abc"^^http://example.org'); toId(new Literal('"abc"^^http://example.org').toJSON()).should.equal('"abc"^^http://example.org'); }); it('should create an id that starts with a quotation mark and datatype from a Literal string with a datatype', function () { toId('"abc"^^http://example.org').should.equal('"abc"^^http://example.org'); }); it('should create an id that starts with a quotation mark and language tag from a Literal with a language', function () { toId(new Literal('"abc"@en-us')).should.equal('"abc"@en-us'); toId(new Literal('"abc"@en-us').toJSON()).should.equal('"abc"@en-us'); }); it('should create an id that starts with a quotation mark and language tag from a Literal string with a language', function () { toId('"abc"@en-us').should.equal('"abc"@en-us'); }); it('should create an id that starts with a quotation mark, datatype and language tag from a Literal with a datatype and language', function () { toId(new Literal('"abc"^^http://example.org@en-us')).should.equal('"abc"^^http://example.org@en-us'); toId(new Literal('"abc"^^http://example.org@en-us').toJSON()).should.equal('"abc"^^http://example.org@en-us'); }); it('should create an id that starts with a quotation mark, datatype and language tag from a Literal string with a datatype and language', function () { toId('"abc"^^http://example.org@en-us').should.equal('"abc"^^http://example.org@en-us'); }); it('should create an id that starts with an underscore from a BlankNode', function () { toId(new BlankNode('abc')).should.equal('_:abc'); toId(new BlankNode('abc').toJSON()).should.equal('_:abc'); }); it('should create an id that starts with an underscore from a BlankNode string', function () { toId('_:abc').should.equal('_:abc'); }); it('should create an IRI from a NamedNode', function () { toId(new NamedNode('http://example.org/')).should.equal('http://example.org/'); toId(new NamedNode('http://example.org/').toJSON()).should.equal('http://example.org/'); }); it('should create an IRI from a NamedNode string', function () { toId('http://example.org/').should.equal('http://example.org/'); }); it('should throw on an unknown type', function () { (function () { toId({ termType: 'unknown' }); }) .should.throw('Unexpected termType: unknown'); }); }); }); N3.js-1.0.4/test/Variable-test.js000066400000000000000000000051371343333361000164330ustar00rootroot00000000000000var DataFactory = require('../N3').DataFactory; var Variable = DataFactory.internal.Variable, Term = DataFactory.internal.Term; describe('Variable', function () { describe('The Variable module', function () { it('should be a function', function () { Variable.should.be.a('function'); }); it('should make Variable objects', function () { Variable().should.be.an.instanceof(Variable); }); it('should make Term objects', function () { Variable().should.be.an.instanceof(Term); }); it('should be a Variable constructor', function () { new Variable().should.be.an.instanceof(Variable); }); it('should be a Term constructor', function () { new Variable().should.be.an.instanceof(Term); }); }); describe('A Variable instance created from a name', function () { var variable; before(function () { variable = new Variable('v1'); }); it('should be a Variable', function () { variable.should.be.an.instanceof(Variable); }); it('should be a Term', function () { variable.should.be.an.instanceof(Term); }); it('should have term type "Variable"', function () { variable.termType.should.equal('Variable'); }); it('should have the name as value', function () { variable.should.have.property('value', 'v1'); }); it('should have "?name" as id value', function () { variable.should.have.property('id', '?v1'); }); it('should equal a Variable instance with the same name', function () { variable.equals(new Variable('v1')).should.be.true; }); it('should equal an object with the same term type and value', function () { variable.equals({ termType: 'Variable', value: 'v1', }).should.be.true; }); it('should not equal a falsy object', function () { variable.equals(null).should.be.false; }); it('should not equal a Variable instance with another name', function () { variable.equals(new Variable('v2')).should.be.false; }); it('should not equal an object with the same term type but a different value', function () { variable.equals({ termType: 'Variable', value: 'v2', }).should.be.false; }); it('should not equal an object with a different term type but the same value', function () { variable.equals({ termType: 'NamedNode', value: 'v1', }).should.be.false; }); it('should provide a JSON representation', function () { variable.toJSON().should.deep.equal({ termType: 'Variable', value: 'v1', }); }); }); }); N3.js-1.0.4/test/mocha.opts000066400000000000000000000000621343333361000153610ustar00rootroot00000000000000--require test/test-setup --timeout 100 --slow 50 N3.js-1.0.4/test/test-setup.js000066400000000000000000000001521343333361000160360ustar00rootroot00000000000000var chai = require('chai'); global.expect = chai.expect; chai.should(); chai.use(require('chai-things'));