Skip to content
This repository has been archived by the owner on May 14, 2020. It is now read-only.

Change blanknodes to namednodes #181

Merged
merged 4 commits into from
Jan 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions src/adaptors/in-memory-articles.ts
Original file line number Diff line number Diff line change
@@ -1,43 +1,43 @@
import {
BlankNode, DatasetCore, Quad, Quad_Object as QuadObject,
DatasetCore, NamedNode, Quad, Quad_Object as QuadObject,
} from 'rdf-js';
import Articles from '../articles';
import ArticleNotFound from '../errors/article-not-found';
import NotAnArticle from '../errors/not-an-article';
import { rdf, schema } from '../namespaces';

export default class InMemoryArticles implements Articles {
private articles: { [id: string]: [BlankNode, DatasetCore] } = {};
private articles: { [id: string]: [NamedNode, DatasetCore] } = {};

async set(id: BlankNode, article: DatasetCore): Promise<void> {
async set(id: NamedNode, article: DatasetCore): Promise<void> {
if (article.match(id, rdf.type, schema.Article).size === 0) {
throw new NotAnArticle([...article.match(id, rdf.type)].map((quad: Quad): QuadObject => quad.object));
}

this.articles[id.value] = [id, article];
}

async get(id: BlankNode): Promise<DatasetCore> {
async get(id: NamedNode): Promise<DatasetCore> {
if (!(id.value in this.articles)) {
throw new ArticleNotFound(id);
}

return this.articles[id.value][1];
}

async remove(id: BlankNode): Promise<void> {
async remove(id: NamedNode): Promise<void> {
delete this.articles[id.value];
}

async contains(id: BlankNode): Promise<boolean> {
async contains(id: NamedNode): Promise<boolean> {
return id.value in this.articles;
}

async count(): Promise<number> {
return Object.values(this.articles).length;
}

async* [Symbol.asyncIterator](): AsyncIterator<[BlankNode, DatasetCore]> {
async* [Symbol.asyncIterator](): AsyncIterator<[NamedNode, DatasetCore]> {
yield* Object.values(this.articles);
}
}
12 changes: 6 additions & 6 deletions src/articles.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { BlankNode, DatasetCore } from 'rdf-js';
import { DatasetCore, NamedNode } from 'rdf-js';

interface Articles extends AsyncIterable<[BlankNode, DatasetCore]> {
set(id: BlankNode, article: DatasetCore): Promise<void>;
interface Articles extends AsyncIterable<[NamedNode, DatasetCore]> {
set(id: NamedNode, article: DatasetCore): Promise<void>;

get(id: BlankNode): Promise<DatasetCore>;
get(id: NamedNode): Promise<DatasetCore>;

remove(id: BlankNode): Promise<void>;
remove(id: NamedNode): Promise<void>;

contains(id: BlankNode): Promise<boolean>;
contains(id: NamedNode): Promise<boolean>;

count(): Promise<number>;
}
Expand Down
6 changes: 3 additions & 3 deletions src/errors/article-not-found.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { BlankNode } from 'rdf-js';
import { NamedNode } from 'rdf-js';
import { termToString } from 'rdf-string';

export default class ArticleNotFound extends Error {
readonly id: BlankNode;
readonly id: NamedNode;

constructor(id: BlankNode) {
constructor(id: NamedNode) {
super(`Article ${termToString(id)} could not be found`);

this.id = id;
Expand Down
4 changes: 2 additions & 2 deletions src/routes/add-article.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import Routes from './index';

export default (): AppMiddleware => (
async ({
articles, dataFactory: { blankNode, quad }, request, response, router,
articles, dataFactory: { namedNode, quad }, request, response, router,
}: AppContext, next: Next): Promise<void> => {
const id = clownface({ dataset: request.dataset }).has(rdf.type, schema.Article).term;

Expand All @@ -28,7 +28,7 @@ export default (): AppMiddleware => (
throw new createHttpError.BadRequest(`Article must have at least one ${termToString(schema('name'))}`);
}

const newId = blankNode(uniqueString());
const newId = namedNode(uniqueString());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation says this should be an IRI, but we have good reasons to use host-free values.


[...request.dataset].forEach((originalQuad: Quad): void => {
let newQuad: Quad;
Expand Down
4 changes: 2 additions & 2 deletions src/routes/article-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { constants } from 'http2';
import all from 'it-all';
import { Next } from 'koa';
import { addAll } from 'rdf-dataset-ext';
import { BlankNode, DatasetCore } from 'rdf-js';
import { DatasetCore, NamedNode } from 'rdf-js';
import { toRdf } from 'rdf-literal';
import url from 'url';
import { AppContext, AppMiddleware } from '../app';
Expand All @@ -21,7 +21,7 @@ export default (): AppMiddleware => (

const listPromise = all(articles)
.then((list): void => {
list.forEach(([id, article]: [BlankNode, DatasetCore]): void => {
list.forEach(([id, article]: [NamedNode, DatasetCore]): void => {
graph.addOut(hydra.member, id);
addAll(graph.dataset, article);
});
Expand Down
34 changes: 17 additions & 17 deletions test/adaptors/in-memory-articles.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { blankNode, literal, quad } from '@rdfjs/data-model';
import { literal, namedNode, quad } from '@rdfjs/data-model';
import all from 'it-all';
import 'jest-rdf';
import { BlankNode, DatasetCore } from 'rdf-js';
import { DatasetCore, NamedNode } from 'rdf-js';
import InMemoryArticles from '../../src/adaptors/in-memory-articles';
import ArticleNotFound from '../../src/errors/article-not-found';
import NotAnArticle from '../../src/errors/not-an-article';
Expand All @@ -11,7 +11,7 @@ import createArticle from '../create-article';
describe('in-memory articles', (): void => {
it('can add an article', async (): Promise<void> => {
const articles = new InMemoryArticles();
const id = blankNode();
const id = namedNode('one');

expect(await articles.contains(id)).toBe(false);

Expand All @@ -22,7 +22,7 @@ describe('in-memory articles', (): void => {

it('can add an article with multiple types', async (): Promise<void> => {
const articles = new InMemoryArticles();
const id = blankNode();
const id = namedNode('one');
const article = createArticle({ id, types: [schema.Article, schema.NewsArticle] });

await articles.set(id, article);
Expand All @@ -32,7 +32,7 @@ describe('in-memory articles', (): void => {

it('can update an article', async (): Promise<void> => {
const articles = new InMemoryArticles();
const id = blankNode();
const id = namedNode('one');

await articles.set(id, createArticle({ id, name: literal('Original') }));
await articles.set(id, createArticle({ id, name: literal('Updated') }));
Expand All @@ -42,23 +42,23 @@ describe('in-memory articles', (): void => {

it('throws an error if it is not an article', async (): Promise<void> => {
const articles = new InMemoryArticles();
const id = blankNode();
const id = namedNode('one');
const article = createArticle({ id, types: [schema.NewsArticle] });

await expect(articles.set(id, article)).rejects.toThrow(new NotAnArticle([schema.NewsArticle]));
});

it('throws an error if it has no type', async (): Promise<void> => {
const articles = new InMemoryArticles();
const id = blankNode();
const id = namedNode('one');
const article = createArticle({ id, types: [] });

await expect(articles.set(id, article)).rejects.toThrow(new NotAnArticle());
});

it('can retrieve an article', async (): Promise<void> => {
const articles = new InMemoryArticles();
const id = blankNode();
const id = namedNode('one');
const article = createArticle({ id });

await articles.set(id, article);
Expand All @@ -68,15 +68,15 @@ describe('in-memory articles', (): void => {

it('throws an error if the article is not found', async (): Promise<void> => {
const articles = new InMemoryArticles();
const id = blankNode();
const id = namedNode('one');

await expect(articles.get(id)).rejects.toBeInstanceOf(ArticleNotFound);
await expect(articles.get(id)).rejects.toHaveProperty('id', id);
});

it('can remove an article', async (): Promise<void> => {
const articles = new InMemoryArticles();
const id = blankNode();
const id = namedNode('one');

await articles.set(id, createArticle({ id }));
await articles.remove(id);
Expand All @@ -86,7 +86,7 @@ describe('in-memory articles', (): void => {

it('does nothing when trying to remove an article that is not there', async (): Promise<void> => {
const articles = new InMemoryArticles();
const id = blankNode();
const id = namedNode('one');

await expect(articles.remove(id)).resolves.not.toThrow();
});
Expand All @@ -96,8 +96,8 @@ describe('in-memory articles', (): void => {

expect(await articles.count()).toBe(0);

const id1 = blankNode();
const id2 = blankNode();
const id1 = namedNode('one');
const id2 = namedNode('two');

await articles.set(id1, createArticle({ id: id1 }));
await articles.set(id2, createArticle({ id: id2 }));
Expand All @@ -109,15 +109,15 @@ describe('in-memory articles', (): void => {
it('can iterate through the articles', async (): Promise<void> => {
const articles = new InMemoryArticles();

const id1 = blankNode();
const id2 = blankNode();
const id3 = blankNode();
const id1 = namedNode('one');
const id2 = namedNode('two');
const id3 = namedNode('three');

await articles.set(id1, createArticle({ id: id1 }));
await articles.set(id3, createArticle({ id: id3 }));
await articles.set(id2, createArticle({ id: id2 }));

const ids = (await all(articles)).map((parts: [BlankNode, DatasetCore]): BlankNode => parts[0]);
const ids = (await all(articles)).map((parts: [NamedNode, DatasetCore]): NamedNode => parts[0]);

expect(ids).toStrictEqual([id1, id3, id2]);
});
Expand Down
10 changes: 5 additions & 5 deletions test/errors/article-not-found.test.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import { blankNode } from '@rdfjs/data-model';
import { namedNode } from '@rdfjs/data-model';
import ArticleNotFound from '../../src/errors/article-not-found';

describe('article not found error', (): void => {
it('should be an error', async (): Promise<void> => {
const error = new ArticleNotFound(blankNode());
const error = new ArticleNotFound(namedNode('one'));

expect(error).toBeInstanceOf(Error);
});

it('should have a message', async (): Promise<void> => {
const error = new ArticleNotFound(blankNode('12345'));
const error = new ArticleNotFound(namedNode('12345'));

expect(error.message).toBe('Article _:12345 could not be found');
expect(error.message).toBe('Article 12345 could not be found');
});

it('should have an ID', async (): Promise<void> => {
const id = blankNode();
const id = namedNode('one');
const error = new ArticleNotFound(id);

expect(error.id).toBe(id);
Expand Down
6 changes: 3 additions & 3 deletions test/routes/article-list.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { blankNode, namedNode, quad } from '@rdfjs/data-model';
import { namedNode, quad } from '@rdfjs/data-model';
import { Response } from 'koa';
import { toRdf } from 'rdf-literal';
import InMemoryArticles from '../../src/adaptors/in-memory-articles';
Expand Down Expand Up @@ -35,8 +35,8 @@ describe('article list', (): void => {
it('should return articles in the list', async (): Promise<void> => {
const articles = new InMemoryArticles();

const id1 = blankNode();
const id2 = blankNode();
const id1 = namedNode('one');
const id2 = namedNode('two');

await articles.set(id1, createArticle({ id: id1 }));
await articles.set(id2, createArticle({ id: id2 }));
Expand Down