Skip to content

shapetrees/test-suite

Repository files navigation

Shape Trees - Test Suite

ShapeTrees maps resource hierarchies to shape constraints. This is a Solid work product -- https://github.com/solid/data-interoperability-panel

This contains:

installation

git clone --recursive https://github.com/shapetrees/test-suite
cd test-suite/shapetree.js/
npm install
cd ..
npm install
npm run genkeys

The last step requires openssl to be installed. It generates two files:

  • servers/ssl.key - private key file
  • servers/ssl.cert - fullchain certificate You can install your own key pair, such as what you might get from letsencrypt. You can override the location by editing the "LDP" entry in servers/config.json:
"LDP": {
  ...
  "keyFilePath": "servers/ssl.key",
  "certFilePath": "servers/ssl.cert",
  ...
}

run tests

npm test

browse playground

* npm run serve
* browse to http://localhost:12340/playground/index.html?manifest=../console/manifest.json

TODO

  • remove or disable slug to reinforce lack of semantics in Container labels.

test-suite hierarchy

test-suite
├── shapetree.js (subrepo) - general ShapeTree Javascript library
│      ├── dist
│      │      └── shape-tree.js
│      ├── ecosystems
│      │      └── simple-apps.js
│      ├── lib
│      │      ├── prefixes.js
│      │      ├── rdf-errors.js
│      │      ├── rdf-serialization.js
│      │      └── shape-tree.js
│      ├── storage - drivers for the shapetree.js library to talk to the server's resource hierarchy
│      │      ├── fetch-self-signed.js
│      │      └── fs-promises.js
│      ├── README.md
│      ├── webapp
│      │      └── index.js
│      └── webpack.config.js
├── test ... see test below - ShapeTree tests
├── www ... (subrepo) see shapetree-tests-output - result of running tests; a sample ShapeTree ecosystem.
├── playground ... (subrepo) see playground below - intaractive WebApp for exploring/exercising ShapeTrees
├── console - configuration for the playground to use test-suite test data
│      └── manifest.json
├── servers
│      ├── ldpServer.js ⎱__ two servers used in testing
│      ├── AppStore.js  ⎰
│      ├── run - run the two servers used in testing
│      ├── config.json - server configuration
│      ├── server.cert  ⎱__ generated SSL key pair
│      ├── server.key  ⎰
│      └── favicon.ico
├── solidApps ... see solidAps below - static content for the app store server
├── README.md
├── TODO.txt
└── update-www-repo.sh

test

data used in tests:

└── test
        ├── bad.test.js - general ShapeTree tests
        ├── bad - files for general ShapeTree tests
        │      ├── malformed-ref-1.ttl
        │      ├── ref-1.ttl
        │      ├── ref-invalid-2.ttl
        │      └── ref-valid-3.ttl
        ├── local.test.js - tests specific to the servers/LDP.js implementation
        └── apps - tests for example applications             ├── album
            │      └── ref-1.ttl
            ├── cal
            │      ├── 09abcdefghijklmnopqrstuvwx_20200107T140000Z.jsonld
            │      ├── 09abcdefghijklmnopqrstuvwx_20200107T140000Z.ttl
            │      ├── 19abcdefghijklmnopqrstuvwx_20200107T140000Z.jsonld
            │      ├── 19abcdefghijklmnopqrstuvwx_20200107T140000Z.ttl
            │      ├── commonAppointment1.ttl
            │      └── manifest.json
            ├── cal.test.js
            ├── gh
            │      ├── alice.json
            │      ├── alice-subscr1.ttl
            │      ├── alice.ttl
            │      ├── ericprud.ttl
            │      ├── jsg-issue1.ttl
            │      └── jsg.ttl
            ├── gh-deep.test.js
            ├── nevernote
            │      ├── img-M33_IR.jpg
            │      ├── inc-M33_IR.ttl
            │      └── note1.ttl
            ├── nevernote.test.js
            ├── photo
            │      └── 320px-Infrared_Triangulum_Galaxy_(M33).jpg
            ├── photoAlbum-shallow.test.js
            ├── photo.test.js
            └── test-harness.js

solidApps

files served by the app store server:

└── solidApps
        └── staticRoot
               ├── album
               │      ├── PhotoAlbumShapeTree.jsonld
               │      ├── PhotoAlbumShapeTree.ttl
               │      ├── PhotoAlbumShapeTree.txt
               │      └── PhotoAlbum.shex
               ├── bad
               │      ├── PhotoAlbumShapeTree.jsonld
               │      ├── PhotoAlbumShapeTree.ttl
               │      ├── PhotoAlbum.shex
               │      ├── ShapeTreeMissingSchema.jsonld
               │      ├── ShapeTreeMissingSchema.ttl
               │      ├── ShapeTreeMissingShape.jsonld
               │      ├── ShapeTreeMissingShape.ttl
               │      ├── ShapeTreeNestedTwoStaticNames.jsonld
               │      ├── ShapeTreeNoShapeProperty.jsonld
               │      ├── ShapeTreeNoShapeProperty.ttl
               │      └── ShapeTreeTwoStaticNames.jsonld
               ├── cal
               │      ├── CalendarShapeTree.jsonld
               │      ├── CalendarShapeTree.ttl
               │      ├── Calendar.shex
               │      ├── GoogleCalendar.shex
               │      ├── GoogleShapeTree.jsonld
               │      ├── GoogleShapeTree.ttl
               │      ├── ical-owl-annot.shex
               │      ├── ical-owl.shex
               │      ├── MultiCalApp.ttl
               │      └── MultiCal.shex
               ├── contacts
               │      ├── ContactShapeTree.jsonld
               │      ├── ContactShapeTree.ttl
               │      └── Contact.shex
               ├── gh
               │      ├── gh-deep-Schema.shex
               │      ├── gh-deep-ShapeTree.jsonld
               │      ├── gh-deep-ShapeTree.ttl
               │      ├── gh-deep-ShapeTree.txt
               │      └── ghSkos.en.ttl
               ├── nevernote
               │      ├── NeverNoteBookShapeTree.jsonld
               │      ├── NeverNoteBookShapeTree.ttl
               │      ├── NeverNoteShapeTree.jsonld
               │      ├── NeverNoteShapeTree.ttl
               │      ├── NeverNote.shex
               │      ├── NN.js
               │      └── NN.shex
               ├── ns
               │      └── shapeTreeContext.jsonld
               └── photo
                        ├── PhotoShapeTree.jsonld
                        └── Photo.shex

playground

an interactive tool for playing with ShapeTrees

└── playground
        ├── index.html
        ├── LICENSE
        ├── popup.html
        ├── README.md
        ├── scripts
        │      ├── jquery.js
        │      ├── main.js
        │      ├── rdflib.min.js
        │      ├── rdflib.min.js.map
        │      ├── shapetree.js
        │      └── solid-auth-client.bundle.js
        └── styles
                └── main.css


architecture


server/LDP

module list

  • Prefixes shapetree.js/lib/prefixes
  • Errors shapetree.js/lib/rdf-errors
  • RdfSerialization shapetree.js/lib/rdf-serialization
  • Mutex shapetree.js/lib/mutex
  • Storage
    • fs-promises shapetree.js/storage/fs-promises
    • ld-proxy shapetree.js/storage/ldp-proxy
  • FetchSelfSigned shapetree.js/storage/fetch-self-signed
  • ShapeTree shapetree.js/lib/shape
  • ShapeTreeFetch shapetree.js/lib/shape
  • Ecosystem
    • Simple Apps shapetree.js/ecosystems/simple-apps
  • LdpConf servers/config.json
use

LDP server

Storage(LdpConf.documentRoot, LdpConf.indexFile, RdfSerialization)
CallEcosystemFetch = (url, options = {}) => Ecosystem.fetch(url, options);
ShapeTree(Storage, RdfSerialization, FetchSelfSigned(CallEcosystemFetch))
Ecosystem(Storage, ShapeTree, RdfSerialization);
NoShapeTrees = process.env.SHAPETREE === 'fetch';

ShapeTreeFetch

const fsModule = require('../shapetree.js/storage/ldp-proxy');
const fs = new fsModule(LdpBase, RdfSerialization, FetchSelfSigned);
Fetch = await require('../shapetree.js/lib/shape-tree-fetch')(fs, RdfSerialization, FetchSelfSigned, LdpBase, Confs.LDP);

Prefixes

RDF serialization prefixes used in LDP and ShapeTrees.


RdfSerialization

Internal functions to parse and serialize RDF, plus rudimentary query.

modules
  • n3
  • relateurl
  • jsonld
  • rdf-errors
API

parseRdf (body, base, contentType, prefixes = {}) parseTurtleSync (text, base, prefixes) async parseTurtle (text, base, prefixes) serializeTurtleSync (graph, base, prefixes) async serializeTurtle (graph, base, prefixes) async parseJsonLd (text, base) expectOne (g, s, p, o, nullable) function zeroOrOne (g, s, p, o) function one (g, s, p, o) renderRdfTerm (t)


Errors

Internal standard errors which result from e.g. improper input.

class API
  • class ManagedError extends Error
  • class ParserError extends ManagedError
  • class NotFoundError extends ManagedError
  • class MiscHttpError extends ManagedError
  • class MissingShapeError extends ManagedError
  • class ShapeTreeStructureError extends ManagedError
  • class ValidationError extends ManagedError
  • class UriTemplateMatchError extends ManagedError
function API
  • async makeHttpError (operation, resource, role, resp)
  • async getOrThrow (fetch, url)

Storage

Perform basic CRUD operations.

operation LDP-C LDP-R
read existing read(url) readContainer(url, prefixes)
write existing or new write(url, body) writeContainer(url, prefixex)
create and name new invent(parentUrl, requestedName, body, mediaType) inventContainer(url, requestedName, title, prefixes)
delete existing remove(url) removeContainer(url)
ensure existence of -- ensureContainer(url, prefixes, title)
get resource info of rstat(url) rstat(url)
API
  • async rstat (url)
  • async read (url)
  • async write (url, body)
  • async invent (parentUrl, requestedName, body, mediaType)
  • async remove (url)
  • async readContainer (url, prefixes)
  • async writeContainer (url, graph, prefixes)
  • async inventContainer (url, requestedName, title, prefixes)
  • async removeContainer (url)
  • async ensureContainer (url, prefixes, title)
  • getIndexFilePath (url)
implementations
module use modules constructor arguments
fs-promises convert URLs to local paths and R/W with require('fs').promises fs, path docRoot, indexFile, rdfInterface, encoding='utf8'
ldp-proxy execute API as fetch calls to a generic LDP server n3 ldpServer, rdfInterface, fetch

ShapeTree

constructor (storage, rdfInterface, fetch)

modules
  • debug
  • path
  • n3
  • rdf-errors
  • prefixes
  • uri-template-lite
  • @shexjs/core
  • @shexjs/parser
Container

Generic LDP Container.

methods
  • constructor (url, title) {
  • url
  • prefixes
  • graph
  • subdirs
  • ready
  • async write ()
  • async remove ()
  • async merge (payload, base)
  • addMember (location, shapeTreeUrl)
  • removeMember (location, shapeTreeUrl)
  • addSubdirs (addUs)
  • async asManagedContainer (shapeTreeUrl, shapeTreeInstancePath)
ManagedContainer

extends Container

Container in a ShapeTree instance.

methods
  • constructor (url, title, shapeTreeUrl, shapeTreeInstancePath)
  • shapeTreeUrl
  • shapeTreeInstancePath
  • shapeTreeInstanceRoot
  • async getRootedShapeTree ()
  • async validatePayload (payload, location, mediaType, ldpType, entityUrl)
Container factories
  • async function loadContainer (url)
RemoteShapeTree
  • constructor (url, path = '.')
  • getRdfRoot ()
  • matchingStep (shapeTreeNode, slug)
  • async instantiateStatic (stepNode, rootUrl, pathWithinShapeTree, parent, container = null)
  • async validate (shape, payloadGraph, node)

Ecosystem

modules
  • fs
  • node-fetch
  • lib/rdf-errors
  • lib/prefixes
simpleApps
  • constructor (storage, shapeTrees, rdfInterface) {
  • storage:Storage
  • shapeTrees:ShapeTree
  • initialize (baseUrl, LdpConf) {
  • baseUrl:URL
  • appsUrl:URL
  • cacheUrl:URL
  • indexInstalledShapeTree (parent, instanceUrl, shapeTreeUrl)
  • unindexInstalledShapeTree (parent, instanceUrl, shapeTreeUrl)
  • reuseShapeTree (parent, shapeTreeUrl)
  • async plantShapeTreeInstance (shapeTreeUrl, postedContainer, requestedLocation, payloadGraph)
  • async registerInstance(appData, shapeTreeUrl, instanceUrl)
  • parseInstatiationPayload (graph)
  • async fetch (url, opts = {})