refactor: Remove streamify array dependency

This commit is contained in:
Joachim Van Herwegen 2021-08-02 13:29:52 +02:00
parent 63e88578c3
commit 2ae95bd167
12 changed files with 70 additions and 106 deletions

18
package-lock.json generated
View File

@ -29,7 +29,6 @@
"@types/redis": "^2.8.30", "@types/redis": "^2.8.30",
"@types/redlock": "^4.0.1", "@types/redlock": "^4.0.1",
"@types/sparqljs": "^3.1.2", "@types/sparqljs": "^3.1.2",
"@types/streamify-array": "^1.0.0",
"@types/url-join": "^4.0.0", "@types/url-join": "^4.0.0",
"@types/uuid": "^8.3.0", "@types/uuid": "^8.3.0",
"@types/ws": "^7.4.5", "@types/ws": "^7.4.5",
@ -60,7 +59,6 @@
"redlock": "^4.2.0", "redlock": "^4.2.0",
"sparqlalgebrajs": "^3.0.0", "sparqlalgebrajs": "^3.0.0",
"sparqljs": "^3.4.2", "sparqljs": "^3.4.2",
"streamify-array": "^1.0.1",
"url-join": "^4.0.1", "url-join": "^4.0.1",
"uuid": "^8.3.2", "uuid": "^8.3.2",
"winston": "^3.3.3", "winston": "^3.3.3",
@ -5293,14 +5291,6 @@
"integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==",
"dev": true "dev": true
}, },
"node_modules/@types/streamify-array": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@types/streamify-array/-/streamify-array-1.0.0.tgz",
"integrity": "sha512-qBRnXKNEF8ejRM7TODp3bXIFnHjDfrUM3cTpCU8hnkrI5FHH708wGTo4jc/2VnyNDd73sNYtt3un2pT+9E1y1A==",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/superagent": { "node_modules/@types/superagent": {
"version": "4.1.11", "version": "4.1.11",
"resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-4.1.11.tgz", "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-4.1.11.tgz",
@ -21403,14 +21393,6 @@
"integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==",
"dev": true "dev": true
}, },
"@types/streamify-array": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@types/streamify-array/-/streamify-array-1.0.0.tgz",
"integrity": "sha512-qBRnXKNEF8ejRM7TODp3bXIFnHjDfrUM3cTpCU8hnkrI5FHH708wGTo4jc/2VnyNDd73sNYtt3un2pT+9E1y1A==",
"requires": {
"@types/node": "*"
}
},
"@types/superagent": { "@types/superagent": {
"version": "4.1.11", "version": "4.1.11",
"resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-4.1.11.tgz", "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-4.1.11.tgz",

View File

@ -95,7 +95,6 @@
"@types/redis": "^2.8.30", "@types/redis": "^2.8.30",
"@types/redlock": "^4.0.1", "@types/redlock": "^4.0.1",
"@types/sparqljs": "^3.1.2", "@types/sparqljs": "^3.1.2",
"@types/streamify-array": "^1.0.0",
"@types/url-join": "^4.0.0", "@types/url-join": "^4.0.0",
"@types/uuid": "^8.3.0", "@types/uuid": "^8.3.0",
"@types/ws": "^7.4.5", "@types/ws": "^7.4.5",
@ -126,7 +125,6 @@
"redlock": "^4.2.0", "redlock": "^4.2.0",
"sparqlalgebrajs": "^3.0.0", "sparqlalgebrajs": "^3.0.0",
"sparqljs": "^3.4.2", "sparqljs": "^3.4.2",
"streamify-array": "^1.0.1",
"url-join": "^4.0.1", "url-join": "^4.0.1",
"uuid": "^8.3.2", "uuid": "^8.3.2",
"winston": "^3.3.3", "winston": "^3.3.3",

View File

@ -3,12 +3,11 @@ import arrayifyStream from 'arrayify-stream';
import type { ParserOptions } from 'n3'; import type { ParserOptions } from 'n3';
import { StreamParser, StreamWriter } from 'n3'; import { StreamParser, StreamWriter } from 'n3';
import type { Quad } from 'rdf-js'; import type { Quad } from 'rdf-js';
import streamifyArray from 'streamify-array';
import type { Guarded } from './GuardedStream'; import type { Guarded } from './GuardedStream';
import { pipeSafely } from './StreamUtil'; import { guardedStreamFrom, pipeSafely } from './StreamUtil';
export function serializeQuads(quads: Quad[], contentType?: string): Guarded<Readable> { export function serializeQuads(quads: Quad[], contentType?: string): Guarded<Readable> {
return pipeSafely(streamifyArray(quads), new StreamWriter({ format: contentType })); return pipeSafely(guardedStreamFrom(quads), new StreamWriter({ format: contentType }));
} }
/** /**

View File

@ -1,6 +1,5 @@
import { Readable } from 'stream'; import { Readable } from 'stream';
import arrayifyStream from 'arrayify-stream'; import arrayifyStream from 'arrayify-stream';
import streamifyArray from 'streamify-array';
import { AcceptPreferenceParser } from '../../src/ldp/http/AcceptPreferenceParser'; import { AcceptPreferenceParser } from '../../src/ldp/http/AcceptPreferenceParser';
import { BasicRequestParser } from '../../src/ldp/http/BasicRequestParser'; import { BasicRequestParser } from '../../src/ldp/http/BasicRequestParser';
import { ContentTypeParser } from '../../src/ldp/http/metadata/ContentTypeParser'; import { ContentTypeParser } from '../../src/ldp/http/metadata/ContentTypeParser';
@ -8,6 +7,7 @@ import { OriginalUrlExtractor } from '../../src/ldp/http/OriginalUrlExtractor';
import { RawBodyParser } from '../../src/ldp/http/RawBodyParser'; import { RawBodyParser } from '../../src/ldp/http/RawBodyParser';
import { RepresentationMetadata } from '../../src/ldp/representation/RepresentationMetadata'; import { RepresentationMetadata } from '../../src/ldp/representation/RepresentationMetadata';
import type { HttpRequest } from '../../src/server/HttpRequest'; import type { HttpRequest } from '../../src/server/HttpRequest';
import { guardedStreamFrom } from '../../src/util/StreamUtil';
describe('A BasicRequestParser with simple input parsers', (): void => { describe('A BasicRequestParser with simple input parsers', (): void => {
const targetExtractor = new OriginalUrlExtractor(); const targetExtractor = new OriginalUrlExtractor();
@ -17,7 +17,7 @@ describe('A BasicRequestParser with simple input parsers', (): void => {
const requestParser = new BasicRequestParser({ targetExtractor, preferenceParser, metadataParser, bodyParser }); const requestParser = new BasicRequestParser({ targetExtractor, preferenceParser, metadataParser, bodyParser });
it('can parse an incoming request.', async(): Promise<void> => { it('can parse an incoming request.', async(): Promise<void> => {
const request = streamifyArray([ '<http://test.com/s> <http://test.com/p> <http://test.com/o>.' ]) as HttpRequest; const request = guardedStreamFrom([ '<http://test.com/s> <http://test.com/p> <http://test.com/o>.' ]) as HttpRequest;
request.method = 'POST'; request.method = 'POST';
request.url = '/'; request.url = '/';
request.headers = { request.headers = {

View File

@ -1,10 +1,10 @@
import arrayifyStream from 'arrayify-stream'; import arrayifyStream from 'arrayify-stream';
import streamifyArray from 'streamify-array';
import type { BodyParserArgs } from '../../../../src/ldp/http/BodyParser'; import type { BodyParserArgs } from '../../../../src/ldp/http/BodyParser';
import { RawBodyParser } from '../../../../src/ldp/http/RawBodyParser'; import { RawBodyParser } from '../../../../src/ldp/http/RawBodyParser';
import { RepresentationMetadata } from '../../../../src/ldp/representation/RepresentationMetadata'; import { RepresentationMetadata } from '../../../../src/ldp/representation/RepresentationMetadata';
import 'jest-rdf'; import 'jest-rdf';
import type { HttpRequest } from '../../../../src/server/HttpRequest'; import type { HttpRequest } from '../../../../src/server/HttpRequest';
import { guardedStreamFrom } from '../../../../src/util/StreamUtil';
describe('A RawBodyparser', (): void => { describe('A RawBodyparser', (): void => {
const bodyParser = new RawBodyParser(); const bodyParser = new RawBodyParser();
@ -19,34 +19,34 @@ describe('A RawBodyparser', (): void => {
}); });
it('returns empty output if there is no content length or transfer encoding.', async(): Promise<void> => { it('returns empty output if there is no content length or transfer encoding.', async(): Promise<void> => {
input.request = streamifyArray([ '' ]) as HttpRequest; input.request = guardedStreamFrom([ '' ]) as HttpRequest;
input.request.headers = {}; input.request.headers = {};
await expect(bodyParser.handle(input)).resolves.toBeUndefined(); await expect(bodyParser.handle(input)).resolves.toBeUndefined();
}); });
// https://github.com/solid/community-server/issues/498 // https://github.com/solid/community-server/issues/498
it('returns empty output if the content length is 0 and there is no content type.', async(): Promise<void> => { it('returns empty output if the content length is 0 and there is no content type.', async(): Promise<void> => {
input.request = streamifyArray([ '' ]) as HttpRequest; input.request = guardedStreamFrom([ '' ]) as HttpRequest;
input.request.headers = { 'content-length': '0' }; input.request.headers = { 'content-length': '0' };
await expect(bodyParser.handle(input)).resolves.toBeUndefined(); await expect(bodyParser.handle(input)).resolves.toBeUndefined();
}); });
it('errors when a content length is specified without content type.', async(): Promise<void> => { it('errors when a content length is specified without content type.', async(): Promise<void> => {
input.request = streamifyArray([ 'abc' ]) as HttpRequest; input.request = guardedStreamFrom([ 'abc' ]) as HttpRequest;
input.request.headers = { 'content-length': '1' }; input.request.headers = { 'content-length': '1' };
await expect(bodyParser.handle(input)).rejects await expect(bodyParser.handle(input)).rejects
.toThrow('HTTP request body was passed without a Content-Type header'); .toThrow('HTTP request body was passed without a Content-Type header');
}); });
it('errors when a transfer encoding is specified without content type.', async(): Promise<void> => { it('errors when a transfer encoding is specified without content type.', async(): Promise<void> => {
input.request = streamifyArray([ 'abc' ]) as HttpRequest; input.request = guardedStreamFrom([ 'abc' ]) as HttpRequest;
input.request.headers = { 'transfer-encoding': 'chunked' }; input.request.headers = { 'transfer-encoding': 'chunked' };
await expect(bodyParser.handle(input)).rejects await expect(bodyParser.handle(input)).rejects
.toThrow('HTTP request body was passed without a Content-Type header'); .toThrow('HTTP request body was passed without a Content-Type header');
}); });
it('returns a Representation if there is empty data.', async(): Promise<void> => { it('returns a Representation if there is empty data.', async(): Promise<void> => {
input.request = streamifyArray([]) as HttpRequest; input.request = guardedStreamFrom([]) as HttpRequest;
input.request.headers = { 'content-length': '0', 'content-type': 'text/turtle' }; input.request.headers = { 'content-length': '0', 'content-type': 'text/turtle' };
const result = (await bodyParser.handle(input))!; const result = (await bodyParser.handle(input))!;
expect(result).toEqual({ expect(result).toEqual({
@ -58,7 +58,7 @@ describe('A RawBodyparser', (): void => {
}); });
it('returns a Representation if there is non-empty data.', async(): Promise<void> => { it('returns a Representation if there is non-empty data.', async(): Promise<void> => {
input.request = streamifyArray([ '<http://test.com/s> <http://test.com/p> <http://test.com/o>.' ]) as HttpRequest; input.request = guardedStreamFrom([ '<http://test.com/s> <http://test.com/p> <http://test.com/o>.' ]) as HttpRequest;
input.request.headers = { 'transfer-encoding': 'chunked', 'content-type': 'text/turtle' }; input.request.headers = { 'transfer-encoding': 'chunked', 'content-type': 'text/turtle' };
const result = (await bodyParser.handle(input))!; const result = (await bodyParser.handle(input))!;
expect(result).toEqual({ expect(result).toEqual({

View File

@ -3,13 +3,13 @@ import { namedNode, quad } from '@rdfjs/data-model';
import arrayifyStream from 'arrayify-stream'; import arrayifyStream from 'arrayify-stream';
import { Algebra } from 'sparqlalgebrajs'; import { Algebra } from 'sparqlalgebrajs';
import * as algebra from 'sparqlalgebrajs'; import * as algebra from 'sparqlalgebrajs';
import streamifyArray from 'streamify-array';
import type { BodyParserArgs } from '../../../../src/ldp/http/BodyParser'; import type { BodyParserArgs } from '../../../../src/ldp/http/BodyParser';
import { SparqlUpdateBodyParser } from '../../../../src/ldp/http/SparqlUpdateBodyParser'; import { SparqlUpdateBodyParser } from '../../../../src/ldp/http/SparqlUpdateBodyParser';
import { RepresentationMetadata } from '../../../../src/ldp/representation/RepresentationMetadata'; import { RepresentationMetadata } from '../../../../src/ldp/representation/RepresentationMetadata';
import type { HttpRequest } from '../../../../src/server/HttpRequest'; import type { HttpRequest } from '../../../../src/server/HttpRequest';
import { BadRequestHttpError } from '../../../../src/util/errors/BadRequestHttpError'; import { BadRequestHttpError } from '../../../../src/util/errors/BadRequestHttpError';
import { UnsupportedMediaTypeHttpError } from '../../../../src/util/errors/UnsupportedMediaTypeHttpError'; import { UnsupportedMediaTypeHttpError } from '../../../../src/util/errors/UnsupportedMediaTypeHttpError';
import { guardedStreamFrom } from '../../../../src/util/StreamUtil';
describe('A SparqlUpdateBodyParser', (): void => { describe('A SparqlUpdateBodyParser', (): void => {
const bodyParser = new SparqlUpdateBodyParser(); const bodyParser = new SparqlUpdateBodyParser();
@ -32,7 +32,7 @@ describe('A SparqlUpdateBodyParser', (): void => {
}); });
it('errors when handling invalid SPARQL updates.', async(): Promise<void> => { it('errors when handling invalid SPARQL updates.', async(): Promise<void> => {
input.request = streamifyArray([ 'VERY INVALID UPDATE' ]) as HttpRequest; input.request = guardedStreamFrom([ 'VERY INVALID UPDATE' ]) as HttpRequest;
await expect(bodyParser.handle(input)).rejects.toThrow(BadRequestHttpError); await expect(bodyParser.handle(input)).rejects.toThrow(BadRequestHttpError);
}); });
@ -40,7 +40,7 @@ describe('A SparqlUpdateBodyParser', (): void => {
const mock = jest.spyOn(algebra, 'translate').mockImplementationOnce((): any => { const mock = jest.spyOn(algebra, 'translate').mockImplementationOnce((): any => {
throw 'apple'; throw 'apple';
}); });
input.request = streamifyArray( input.request = guardedStreamFrom(
[ 'DELETE DATA { <http://test.com/s> <http://test.com/p> <http://test.com/o> }' ], [ 'DELETE DATA { <http://test.com/s> <http://test.com/p> <http://test.com/o> }' ],
) as HttpRequest; ) as HttpRequest;
await expect(bodyParser.handle(input)).rejects.toThrow(BadRequestHttpError); await expect(bodyParser.handle(input)).rejects.toThrow(BadRequestHttpError);
@ -48,7 +48,7 @@ describe('A SparqlUpdateBodyParser', (): void => {
}); });
it('converts SPARQL updates to algebra.', async(): Promise<void> => { it('converts SPARQL updates to algebra.', async(): Promise<void> => {
input.request = streamifyArray( input.request = guardedStreamFrom(
[ 'DELETE DATA { <http://test.com/s> <http://test.com/p> <http://test.com/o> }' ], [ 'DELETE DATA { <http://test.com/s> <http://test.com/p> <http://test.com/o> }' ],
) as HttpRequest; ) as HttpRequest;
const result = await bodyParser.handle(input); const result = await bodyParser.handle(input);
@ -67,7 +67,7 @@ describe('A SparqlUpdateBodyParser', (): void => {
}); });
it('accepts relative references.', async(): Promise<void> => { it('accepts relative references.', async(): Promise<void> => {
input.request = streamifyArray( input.request = guardedStreamFrom(
[ 'INSERT DATA { <#it> <http://test.com/p> <http://test.com/o> }' ], [ 'INSERT DATA { <#it> <http://test.com/p> <http://test.com/o> }' ],
) as HttpRequest; ) as HttpRequest;
input.metadata.identifier = namedNode('http://test.com/my-document.ttl'); input.metadata.identifier = namedNode('http://test.com/my-document.ttl');

View File

@ -1,7 +1,7 @@
import 'jest-rdf'; import 'jest-rdf';
import { Readable } from 'stream';
import { namedNode } from '@rdfjs/data-model'; import { namedNode } from '@rdfjs/data-model';
import arrayifyStream from 'arrayify-stream'; import arrayifyStream from 'arrayify-stream';
import streamifyArray from 'streamify-array';
import { BasicRepresentation } from '../../../../src/ldp/representation/BasicRepresentation'; import { BasicRepresentation } from '../../../../src/ldp/representation/BasicRepresentation';
import { RepresentationMetadata } from '../../../../src/ldp/representation/RepresentationMetadata'; import { RepresentationMetadata } from '../../../../src/ldp/representation/RepresentationMetadata';
import { INTERNAL_QUADS } from '../../../../src/util/ContentTypes'; import { INTERNAL_QUADS } from '../../../../src/util/ContentTypes';
@ -34,7 +34,7 @@ describe('BasicRepresentation', (): void => {
}); });
it('creates a representation with (unguarded data, metadata).', (): void => { it('creates a representation with (unguarded data, metadata).', (): void => {
const data = streamifyArray([ '' ]); const data = Readable.from([ '' ]);
const metadata = new RepresentationMetadata(); const metadata = new RepresentationMetadata();
const representation = new BasicRepresentation(data, metadata); const representation = new BasicRepresentation(data, metadata);
expect(representation.data).toBe(data); expect(representation.data).toBe(data);

View File

@ -1,15 +1,14 @@
import { EventEmitter } from 'events'; import { EventEmitter } from 'events';
import fs from 'fs'; import fs from 'fs';
import { PassThrough } from 'stream'; import { PassThrough, Readable } from 'stream';
import { createResponse } from 'node-mocks-http'; import { createResponse } from 'node-mocks-http';
import streamifyArray from 'streamify-array';
import { StaticAssetHandler } from '../../../../src/server/middleware/StaticAssetHandler'; import { StaticAssetHandler } from '../../../../src/server/middleware/StaticAssetHandler';
import { NotFoundHttpError } from '../../../../src/util/errors/NotFoundHttpError'; import { NotFoundHttpError } from '../../../../src/util/errors/NotFoundHttpError';
import type { SystemError } from '../../../../src/util/errors/SystemError'; import type { SystemError } from '../../../../src/util/errors/SystemError';
import { getModuleRoot, joinFilePath } from '../../../../src/util/PathUtil'; import { getModuleRoot, joinFilePath } from '../../../../src/util/PathUtil';
const createReadStream = jest.spyOn(fs, 'createReadStream') const createReadStream = jest.spyOn(fs, 'createReadStream')
.mockImplementation((): any => streamifyArray([ 'file contents' ])); .mockImplementation((): any => Readable.from([ 'file contents' ]));
describe('A StaticAssetHandler', (): void => { describe('A StaticAssetHandler', (): void => {
const handler = new StaticAssetHandler({ const handler = new StaticAssetHandler({

View File

@ -1,6 +1,6 @@
import { namedNode, triple } from '@rdfjs/data-model'; import { namedNode, triple } from '@rdfjs/data-model';
import rdfSerializer from 'rdf-serialize'; import rdfSerializer from 'rdf-serialize';
import streamifyArray from 'streamify-array'; import { BasicRepresentation } from '../../../../src/ldp/representation/BasicRepresentation';
import type { Representation } from '../../../../src/ldp/representation/Representation'; import type { Representation } from '../../../../src/ldp/representation/Representation';
import { RepresentationMetadata } from '../../../../src/ldp/representation/RepresentationMetadata'; import { RepresentationMetadata } from '../../../../src/ldp/representation/RepresentationMetadata';
import type { RepresentationPreferences } from '../../../../src/ldp/representation/RepresentationPreferences'; import type { RepresentationPreferences } from '../../../../src/ldp/representation/RepresentationPreferences';
@ -48,14 +48,12 @@ describe('A QuadToRdfConverter', (): void => {
}); });
it('converts quads to Turtle.', async(): Promise<void> => { it('converts quads to Turtle.', async(): Promise<void> => {
const representation = { const representation = new BasicRepresentation([ triple(
data: streamifyArray([ triple( namedNode('http://test.com/s'),
namedNode('http://test.com/s'), namedNode('http://test.com/p'),
namedNode('http://test.com/p'), namedNode('http://test.com/o'),
namedNode('http://test.com/o'), ) ],
) ]), metadata);
metadata,
} as Representation;
const preferences: RepresentationPreferences = { type: { 'text/turtle': 1 }}; const preferences: RepresentationPreferences = { type: { 'text/turtle': 1 }};
const result = await converter.handle({ identifier, representation, preferences }); const result = await converter.handle({ identifier, representation, preferences });
expect(result).toMatchObject({ expect(result).toMatchObject({
@ -72,14 +70,12 @@ describe('A QuadToRdfConverter', (): void => {
it('converts quads with prefixes to Turtle.', async(): Promise<void> => { it('converts quads with prefixes to Turtle.', async(): Promise<void> => {
metadata.addQuad(DC.terms.namespace, PREFERRED_PREFIX_TERM, 'dc'); metadata.addQuad(DC.terms.namespace, PREFERRED_PREFIX_TERM, 'dc');
metadata.addQuad('http://test.com/', PREFERRED_PREFIX_TERM, 'test'); metadata.addQuad('http://test.com/', PREFERRED_PREFIX_TERM, 'test');
const representation = { const representation = new BasicRepresentation([ triple(
data: streamifyArray([ triple( namedNode('http://test.com/s'),
namedNode('http://test.com/s'), DC.terms.modified,
DC.terms.modified, namedNode('http://test.com/o'),
namedNode('http://test.com/o'), ) ],
) ]), metadata);
metadata,
} as Representation;
const preferences: RepresentationPreferences = { type: { 'text/turtle': 1 }}; const preferences: RepresentationPreferences = { type: { 'text/turtle': 1 }};
const result = await converter.handle({ identifier, representation, preferences }); const result = await converter.handle({ identifier, representation, preferences });
expect(result.metadata.contentType).toEqual('text/turtle'); expect(result.metadata.contentType).toEqual('text/turtle');
@ -93,14 +89,12 @@ test:s dc:modified test:o.
}); });
it('uses the base IRI when converting quads to Turtle.', async(): Promise<void> => { it('uses the base IRI when converting quads to Turtle.', async(): Promise<void> => {
const representation = { const representation = new BasicRepresentation([ triple(
data: streamifyArray([ triple( namedNode('http://example.org/foo/bar/'),
namedNode('http://example.org/foo/bar/'), namedNode('http://example.org/foo/bar/#abc'),
namedNode('http://example.org/foo/bar/#abc'), namedNode('http://example.org/foo/bar/def/ghi'),
namedNode('http://example.org/foo/bar/def/ghi'), ) ],
) ]), metadata);
metadata,
} as Representation;
const preferences: RepresentationPreferences = { type: { 'text/turtle': 1 }}; const preferences: RepresentationPreferences = { type: { 'text/turtle': 1 }};
const result = await converter.handle({ identifier, representation, preferences }); const result = await converter.handle({ identifier, representation, preferences });
expect(result.metadata.contentType).toEqual('text/turtle'); expect(result.metadata.contentType).toEqual('text/turtle');
@ -112,14 +106,12 @@ test:s dc:modified test:o.
it('converts quads to JSON-LD.', async(): Promise<void> => { it('converts quads to JSON-LD.', async(): Promise<void> => {
metadata.contentType = INTERNAL_QUADS; metadata.contentType = INTERNAL_QUADS;
const representation = { const representation = new BasicRepresentation([ triple(
data: streamifyArray([ triple( namedNode('http://test.com/s'),
namedNode('http://test.com/s'), namedNode('http://test.com/p'),
namedNode('http://test.com/p'), namedNode('http://test.com/o'),
namedNode('http://test.com/o'), ) ],
) ]), metadata);
metadata,
} as Representation;
const preferences: RepresentationPreferences = { type: { 'application/ld+json': 1 }}; const preferences: RepresentationPreferences = { type: { 'application/ld+json': 1 }};
const result = await converter.handle({ identifier, representation, preferences }); const result = await converter.handle({ identifier, representation, preferences });
expect(result).toMatchObject({ expect(result).toMatchObject({

View File

@ -3,7 +3,7 @@ import { Readable } from 'stream';
import { namedNode, triple } from '@rdfjs/data-model'; import { namedNode, triple } from '@rdfjs/data-model';
import arrayifyStream from 'arrayify-stream'; import arrayifyStream from 'arrayify-stream';
import rdfParser from 'rdf-parse'; import rdfParser from 'rdf-parse';
import streamifyArray from 'streamify-array'; import { BasicRepresentation } from '../../../../src/ldp/representation/BasicRepresentation';
import type { Representation } from '../../../../src/ldp/representation/Representation'; import type { Representation } from '../../../../src/ldp/representation/Representation';
import { RepresentationMetadata } from '../../../../src/ldp/representation/RepresentationMetadata'; import { RepresentationMetadata } from '../../../../src/ldp/representation/RepresentationMetadata';
import type { RepresentationPreferences } from '../../../../src/ldp/representation/RepresentationPreferences'; import type { RepresentationPreferences } from '../../../../src/ldp/representation/RepresentationPreferences';
@ -40,10 +40,9 @@ describe('A RdfToQuadConverter', (): void => {
it('converts turtle to quads.', async(): Promise<void> => { it('converts turtle to quads.', async(): Promise<void> => {
const metadata = new RepresentationMetadata('text/turtle'); const metadata = new RepresentationMetadata('text/turtle');
const representation = { const representation = new BasicRepresentation(
data: streamifyArray([ '<http://test.com/s> <http://test.com/p> <http://test.com/o>.' ]), '<http://test.com/s> <http://test.com/p> <http://test.com/o>.', metadata,
metadata, );
} as Representation;
const preferences: RepresentationPreferences = { type: { [INTERNAL_QUADS]: 1 }}; const preferences: RepresentationPreferences = { type: { [INTERNAL_QUADS]: 1 }};
const result = await converter.handle({ identifier, representation, preferences }); const result = await converter.handle({ identifier, representation, preferences });
expect(result).toEqual({ expect(result).toEqual({
@ -61,10 +60,9 @@ describe('A RdfToQuadConverter', (): void => {
it('converts JSON-LD to quads.', async(): Promise<void> => { it('converts JSON-LD to quads.', async(): Promise<void> => {
const metadata = new RepresentationMetadata('application/ld+json'); const metadata = new RepresentationMetadata('application/ld+json');
const representation = { const representation = new BasicRepresentation(
data: streamifyArray([ '{"@id": "http://test.com/s", "http://test.com/p": { "@id": "http://test.com/o" }}' ]), '{"@id": "http://test.com/s", "http://test.com/p": { "@id": "http://test.com/o" }}', metadata,
metadata, );
} as Representation;
const preferences: RepresentationPreferences = { type: { [INTERNAL_QUADS]: 1 }}; const preferences: RepresentationPreferences = { type: { [INTERNAL_QUADS]: 1 }};
const result = await converter.handle({ identifier, representation, preferences }); const result = await converter.handle({ identifier, representation, preferences });
expect(result).toEqual({ expect(result).toEqual({
@ -82,10 +80,9 @@ describe('A RdfToQuadConverter', (): void => {
it('throws an BadRequestHttpError on invalid triple data.', async(): Promise<void> => { it('throws an BadRequestHttpError on invalid triple data.', async(): Promise<void> => {
const metadata = new RepresentationMetadata('text/turtle'); const metadata = new RepresentationMetadata('text/turtle');
const representation = { const representation = new BasicRepresentation(
data: streamifyArray([ '<http://test.com/s> <http://test.com/p> <http://test.co' ]), '<http://test.com/s> <http://test.com/p> <http://test.co', metadata,
metadata, );
} as Representation;
const preferences: RepresentationPreferences = { type: { [INTERNAL_QUADS]: 1 }}; const preferences: RepresentationPreferences = { type: { [INTERNAL_QUADS]: 1 }};
const result = await converter.handle({ identifier, representation, preferences }); const result = await converter.handle({ identifier, representation, preferences });
expect(result).toEqual({ expect(result).toEqual({

View File

@ -1,6 +1,5 @@
import { PassThrough } from 'stream'; import { PassThrough, Readable } from 'stream';
import arrayifyStream from 'arrayify-stream'; import arrayifyStream from 'arrayify-stream';
import streamifyArray from 'streamify-array';
import type { Logger } from '../../../src/logging/Logger'; import type { Logger } from '../../../src/logging/Logger';
import { getLoggerFor } from '../../../src/logging/LogUtil'; import { getLoggerFor } from '../../../src/logging/LogUtil';
import { isHttpRequest } from '../../../src/server/HttpRequest'; import { isHttpRequest } from '../../../src/server/HttpRequest';
@ -19,7 +18,7 @@ jest.mock('../../../src/server/HttpRequest', (): any => ({
describe('StreamUtil', (): void => { describe('StreamUtil', (): void => {
describe('#readableToString', (): void => { describe('#readableToString', (): void => {
it('concatenates all elements of a Readable.', async(): Promise<void> => { it('concatenates all elements of a Readable.', async(): Promise<void> => {
const stream = streamifyArray([ 'a', 'b', 'c' ]); const stream = Readable.from([ 'a', 'b', 'c' ]);
await expect(readableToString(stream)).resolves.toEqual('abc'); await expect(readableToString(stream)).resolves.toEqual('abc');
}); });
}); });
@ -30,7 +29,7 @@ describe('StreamUtil', (): void => {
}); });
it('pipes data from one stream to the other.', async(): Promise<void> => { it('pipes data from one stream to the other.', async(): Promise<void> => {
const input = streamifyArray([ 'data' ]); const input = Readable.from([ 'data' ]);
const output = new PassThrough(); const output = new PassThrough();
const piped = pipeSafely(input, output); const piped = pipeSafely(input, output);
await expect(readableToString(piped)).resolves.toEqual('data'); await expect(readableToString(piped)).resolves.toEqual('data');
@ -50,7 +49,7 @@ describe('StreamUtil', (): void => {
}); });
it('supports mapping errors to something else.', async(): Promise<void> => { it('supports mapping errors to something else.', async(): Promise<void> => {
const input = streamifyArray([ 'data' ]); const input = Readable.from([ 'data' ]);
input.read = (): any => { input.read = (): any => {
input.emit('error', new Error('error')); input.emit('error', new Error('error'));
return null; return null;
@ -61,7 +60,7 @@ describe('StreamUtil', (): void => {
}); });
it('logs specific safer errors as debug.', async(): Promise<void> => { it('logs specific safer errors as debug.', async(): Promise<void> => {
const input = streamifyArray([ 'data' ]); const input = Readable.from([ 'data' ]);
input.read = (): any => { input.read = (): any => {
input.emit('error', new Error('Cannot call write after a stream was destroyed')); input.emit('error', new Error('Cannot call write after a stream was destroyed'));
return null; return null;
@ -123,7 +122,7 @@ describe('StreamUtil', (): void => {
it('can map errors if the input is an HttpRequest.', async(): Promise<void> => { it('can map errors if the input is an HttpRequest.', async(): Promise<void> => {
(isHttpRequest as unknown as jest.Mock).mockReturnValueOnce(true); (isHttpRequest as unknown as jest.Mock).mockReturnValueOnce(true);
const input = streamifyArray([ 'data' ]); const input = Readable.from([ 'data' ]);
input.read = (): any => { input.read = (): any => {
input.emit('error', new Error('error')); input.emit('error', new Error('error'));
return null; return null;
@ -136,7 +135,7 @@ describe('StreamUtil', (): void => {
describe('#transformSafely', (): void => { describe('#transformSafely', (): void => {
it('can transform a stream without arguments.', async(): Promise<void> => { it('can transform a stream without arguments.', async(): Promise<void> => {
const source = streamifyArray([ 'data' ]); const source = Readable.from([ 'data' ]);
const transformed = transformSafely(source); const transformed = transformSafely(source);
transformed.setEncoding('utf8'); transformed.setEncoding('utf8');
const result = await arrayifyStream(transformed); const result = await arrayifyStream(transformed);
@ -144,7 +143,7 @@ describe('StreamUtil', (): void => {
}); });
it('can transform a stream synchronously.', async(): Promise<void> => { it('can transform a stream synchronously.', async(): Promise<void> => {
const source = streamifyArray([ 'data' ]); const source = Readable.from([ 'data' ]);
const transformed = transformSafely<string>(source, { const transformed = transformSafely<string>(source, {
encoding: 'utf8', encoding: 'utf8',
transform(data: string): void { transform(data: string): void {
@ -160,7 +159,7 @@ describe('StreamUtil', (): void => {
}); });
it('can transform a stream asynchronously.', async(): Promise<void> => { it('can transform a stream asynchronously.', async(): Promise<void> => {
const source = streamifyArray([ 'data' ]); const source = Readable.from([ 'data' ]);
const transformed = transformSafely<string>(source, { const transformed = transformSafely<string>(source, {
encoding: 'utf8', encoding: 'utf8',
async transform(data: string): Promise<void> { async transform(data: string): Promise<void> {
@ -187,7 +186,7 @@ describe('StreamUtil', (): void => {
it('catches synchronous errors on transform.', async(): Promise<void> => { it('catches synchronous errors on transform.', async(): Promise<void> => {
const error = new Error('stream error'); const error = new Error('stream error');
const source = streamifyArray([ 'data' ]); const source = Readable.from([ 'data' ]);
const transformed = transformSafely<string>(source, { const transformed = transformSafely<string>(source, {
transform(): never { transform(): never {
throw error; throw error;
@ -198,7 +197,7 @@ describe('StreamUtil', (): void => {
it('catches synchronous errors on flush.', async(): Promise<void> => { it('catches synchronous errors on flush.', async(): Promise<void> => {
const error = new Error('stream error'); const error = new Error('stream error');
const source = streamifyArray([ 'data' ]); const source = Readable.from([ 'data' ]);
const transformed = transformSafely<string>(source, { const transformed = transformSafely<string>(source, {
async flush(): Promise<never> { async flush(): Promise<never> {
await new Promise((resolve): any => setImmediate(resolve)); await new Promise((resolve): any => setImmediate(resolve));
@ -210,7 +209,7 @@ describe('StreamUtil', (): void => {
it('catches asynchronous errors on transform.', async(): Promise<void> => { it('catches asynchronous errors on transform.', async(): Promise<void> => {
const error = new Error('stream error'); const error = new Error('stream error');
const source = streamifyArray([ 'data' ]); const source = Readable.from([ 'data' ]);
const transformed = transformSafely<string>(source, { const transformed = transformSafely<string>(source, {
transform(): never { transform(): never {
throw error; throw error;
@ -221,7 +220,7 @@ describe('StreamUtil', (): void => {
it('catches asynchronous errors on flush.', async(): Promise<void> => { it('catches asynchronous errors on flush.', async(): Promise<void> => {
const error = new Error('stream error'); const error = new Error('stream error');
const source = streamifyArray([ 'data' ]); const source = Readable.from([ 'data' ]);
const transformed = transformSafely<string>(source, { const transformed = transformSafely<string>(source, {
async flush(): Promise<never> { async flush(): Promise<never> {
await new Promise((resolve): any => setImmediate(resolve)); await new Promise((resolve): any => setImmediate(resolve));

View File

@ -1,7 +1,5 @@
import type { Dirent, Stats } from 'fs'; import type { Dirent, Stats } from 'fs';
import { PassThrough, Readable } from 'stream';
import { PassThrough } from 'stream';
import streamifyArray from 'streamify-array';
import type { SystemError } from '../../src/util/errors/SystemError'; import type { SystemError } from '../../src/util/errors/SystemError';
const portNames = [ const portNames = [
@ -95,7 +93,7 @@ export function mockFs(rootFilepath?: string, time?: Date): { data: any } {
const mock = { const mock = {
createReadStream(path: string): any { createReadStream(path: string): any {
const { folder, name } = getFolder(path); const { folder, name } = getFolder(path);
return streamifyArray([ folder[name] ]); return Readable.from([ folder[name] ]);
}, },
createWriteStream(path: string): any { createWriteStream(path: string): any {
const { folder, name } = getFolder(path); const { folder, name } = getFolder(path);