Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Std extension exec tests #456

Merged
merged 34 commits into from
Nov 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
00eb5a1
Added tests for ArchiveInterpreterExecutor
f3l1x98 Sep 25, 2023
f8a4954
Fixed duplication
f3l1x98 Sep 25, 2023
caf1a82
Fixed duplication
f3l1x98 Sep 25, 2023
e65c738
Merge remote-tracking branch 'origin/main' into feature/std-extension…
f3l1x98 Oct 9, 2023
2e014dd
Added first basic test for file-picker-executor
f3l1x98 Oct 9, 2023
feb49dd
Added custom error message in case file was not found
f3l1x98 Oct 9, 2023
5883bd8
Added new test for file not found
f3l1x98 Oct 9, 2023
f150b9a
Added basic file-util tests
f3l1x98 Oct 9, 2023
c005225
refactored tests like file-picker-extractor.spec.ts
f3l1x98 Oct 9, 2023
d24a8d6
- Added test utils containing function to create BinaryFile from loca…
f3l1x98 Oct 9, 2023
b7c69bc
Added try catch around GtfsRealtimeBindings decode in order to catch …
f3l1x98 Oct 9, 2023
784c520
Added tests for gtfs-rt-interpreter
f3l1x98 Oct 9, 2023
10f3730
Added missing licenses
f3l1x98 Oct 9, 2023
d501632
Removed duplicate expect
f3l1x98 Oct 9, 2023
da3871a
Added missing stdLangExtension import
f3l1x98 Oct 9, 2023
bef13e9
Fixed createBinaryFileFromLocalFile not inserting files
f3l1x98 Oct 9, 2023
c853d30
Started with HttpExtractorExecutor tests
f3l1x98 Oct 9, 2023
ee2706a
Added onError for ClientRequest
f3l1x98 Oct 16, 2023
df3275b
Added more tests and improved existing ones
f3l1x98 Oct 16, 2023
54fca19
Added missing test files to git
f3l1x98 Oct 16, 2023
aaf638d
Added TextFileInterpreterExecutor tests
f3l1x98 Oct 16, 2023
3ee0cfc
- Moved splitLines logic into separate string-utils for test reusage
f3l1x98 Oct 16, 2023
40b7893
Added TextLineDeleterExecutor tests
f3l1x98 Oct 16, 2023
98d6cb1
Fixed test name
f3l1x98 Oct 16, 2023
550136c
Added TextRangeSelectorExecutor tests
f3l1x98 Oct 16, 2023
5b67955
Fixed filepath hardcoded to file-picker test assets
f3l1x98 Oct 23, 2023
451c088
Fixed test names
f3l1x98 Oct 23, 2023
1ab1148
Extracted the `initializeWorkspace` for test extension loading into a…
f3l1x98 Nov 6, 2023
b6f8824
Fixed method name
f3l1x98 Nov 6, 2023
0bdcb38
Merge remote-tracking branch 'origin/main' into feature/std-extension…
f3l1x98 Nov 6, 2023
6c9ede0
Merge branch 'feature/load-test-extension-util' into feature/std-exte…
f3l1x98 Nov 6, 2023
5a2d5c2
Fixed import of renamed function
f3l1x98 Nov 6, 2023
9c97bff
Fixed tests using renamed function
f3l1x98 Nov 6, 2023
ea7c306
Applied new TestExtension loading
f3l1x98 Nov 6, 2023
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
158 changes: 158 additions & 0 deletions libs/extensions/std/exec/src/archive-interpreter-executor.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
// SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg
//
// SPDX-License-Identifier: AGPL-3.0-only

import * as path from 'path';

import * as R from '@jvalue/jayvee-execution';
import { getTestExecutionContext } from '@jvalue/jayvee-execution/test';
import {
BlockDefinition,
IOType,
createJayveeServices,
} from '@jvalue/jayvee-language-server';
import {
ParseHelperOptions,
expectNoParserAndLexerErrors,
loadTestExtensions,
parseHelper,
readJvTestAssetHelper,
} from '@jvalue/jayvee-language-server/test';
import { AstNode, AstNodeLocator, LangiumDocument } from 'langium';
import { NodeFileSystem } from 'langium/node';

import { createBinaryFileFromLocalFile } from '../test';

import { ArchiveInterpreterExecutor } from './archive-interpreter-executor';

describe('Validation of ArchiveInterpreterExecutor', () => {
let parse: (
input: string,
options?: ParseHelperOptions,
) => Promise<LangiumDocument<AstNode>>;

let locator: AstNodeLocator;

const readJvTestAsset = readJvTestAssetHelper(
__dirname,
'../test/assets/archive-interpreter-executor/',
);

function readTestArchive(fileName: string): R.BinaryFile {
const absoluteFileName = path.resolve(
__dirname,
'../test/assets/archive-interpreter-executor/',
fileName,
);
return createBinaryFileFromLocalFile(absoluteFileName);
}

async function parseAndExecuteArchiveInterpreter(
input: string,
IOInput: R.BinaryFile,
): Promise<R.Result<R.FileSystem>> {
const document = await parse(input, { validationChecks: 'all' });
expectNoParserAndLexerErrors(document);

const block = locator.getAstNode<BlockDefinition>(
document.parseResult.value,
'pipelines@0/blocks@1',
f3l1x98 marked this conversation as resolved.
Show resolved Hide resolved
) as BlockDefinition;

return new ArchiveInterpreterExecutor().doExecute(
IOInput,
getTestExecutionContext(locator, document, [block]),
);
}

beforeAll(async () => {
// Create language services
const services = createJayveeServices(NodeFileSystem).Jayvee;
await loadTestExtensions(services, [
path.resolve(__dirname, '../test/test-extension/TestBlockTypes.jv'),
]);
locator = services.workspace.AstNodeLocator;
// Parse function for Jayvee (without validation)
parse = parseHelper(services);
});

it('should diagnose no error on valid zip BinaryFile', async () => {
const text = readJvTestAsset('valid-zip-archive-interpreter.jv');

const testFile = readTestArchive('valid-zip.zip');
const result = await parseAndExecuteArchiveInterpreter(text, testFile);

expect(R.isErr(result)).toEqual(false);
if (R.isOk(result)) {
expect(result.right.ioType).toEqual(IOType.FILE_SYSTEM);
expect(result.right.getFile('/test.txt')).toEqual(
expect.objectContaining({
name: 'test.txt',
extension: 'txt',
ioType: IOType.FILE,
mimeType: R.MimeType.TEXT_PLAIN,
}),
);
}
});

it('should diagnose no error on valid gz BinaryFile', async () => {
const text = readJvTestAsset('valid-gz-archive-interpreter.jv');

const testFile = readTestArchive('valid-gz.gz');
const result = await parseAndExecuteArchiveInterpreter(text, testFile);

expect(R.isErr(result)).toEqual(false);
if (R.isOk(result)) {
expect(result.right.ioType).toEqual(IOType.FILE_SYSTEM);
expect(result.right.getFile('/valid-gz')).toEqual(
expect.objectContaining({
name: 'valid-gz',
extension: '',
ioType: IOType.FILE,
mimeType: R.MimeType.APPLICATION_OCTET_STREAM,
}),
);
}
});

it('should diagnose error on zip as gz archive', async () => {
const text = readJvTestAsset('valid-gz-archive-interpreter.jv');

const testFile = readTestArchive('valid-zip.zip');
const result = await parseAndExecuteArchiveInterpreter(text, testFile);

expect(R.isOk(result)).toEqual(false);
if (R.isErr(result)) {
expect(result.left.message).toEqual(
'Unexpected Error undefined occured during processing',
);
}
});

it('should diagnose error on invalid archive type', async () => {
const text = readJvTestAsset('valid-7z-archive-interpreter.jv');

const testFile = readTestArchive('valid-7z.7z');
const result = await parseAndExecuteArchiveInterpreter(text, testFile);

expect(R.isOk(result)).toEqual(false);
if (R.isErr(result)) {
expect(result.left.message).toEqual('Archive type is not supported');
}
});

it('should diagnose error on corrupted archive', async () => {
const text = readJvTestAsset('valid-zip-archive-interpreter.jv');

const testFile = readTestArchive('invalid-corrupt-zip.zip');
const result = await parseAndExecuteArchiveInterpreter(text, testFile);

expect(R.isOk(result)).toEqual(false);
if (R.isErr(result)) {
expect(result.left.message).toEqual(
"Unexpected Error Can't find end of central directory : is this a zip file ? If it is, see https://stuk.github.io/jszip/documentation/howto/read_zip.html occured during processing",
);
}
});
});
4 changes: 2 additions & 2 deletions libs/extensions/std/exec/src/archive-interpreter-executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import * as JSZip from 'jszip';

import {
inferFileExtensionFromFileExtensionString,
inferMimeTypeFromContentTypeString,
inferMimeTypeFromFileExtensionString,
} from './file-util';

@implementsStatic<BlockExecutorClass>()
Expand Down Expand Up @@ -133,7 +133,7 @@ export class ArchiveInterpreterExecutor extends AbstractBlockExecutor<
const extName = path.extname(fileName);

const mimeType =
inferMimeTypeFromContentTypeString(extName) ||
inferMimeTypeFromFileExtensionString(extName) ||
MimeType.APPLICATION_OCTET_STREAM;
const fileExtension =
inferFileExtensionFromFileExtensionString(extName) || FileExtension.NONE;
Expand Down
116 changes: 116 additions & 0 deletions libs/extensions/std/exec/src/file-picker-executor.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg
//
// SPDX-License-Identifier: AGPL-3.0-only

import * as path from 'path';

import * as R from '@jvalue/jayvee-execution';
import { getTestExecutionContext } from '@jvalue/jayvee-execution/test';
import {
BlockDefinition,
IOType,
createJayveeServices,
} from '@jvalue/jayvee-language-server';
import {
ParseHelperOptions,
expectNoParserAndLexerErrors,
loadTestExtensions,
parseHelper,
readJvTestAssetHelper,
} from '@jvalue/jayvee-language-server/test';
import { AstNode, AstNodeLocator, LangiumDocument } from 'langium';
import { NodeFileSystem } from 'langium/node';

import { createBinaryFileFromLocalFile } from '../test';

import { FilePickerExecutor } from './file-picker-executor';

describe('Validation of FilePickerExecutor', () => {
let parse: (
input: string,
options?: ParseHelperOptions,
) => Promise<LangiumDocument<AstNode>>;
let fileSystem: R.FileSystem;

let locator: AstNodeLocator;

const readJvTestAsset = readJvTestAssetHelper(
__dirname,
'../test/assets/file-picker-executor/',
);

function uploadTestFile(fileName: string) {
const absoluteFileName = path.resolve(
__dirname,
'../test/assets/file-picker-executor/',
fileName,
);
fileSystem.putFile(
`/${fileName}`,
createBinaryFileFromLocalFile(absoluteFileName),
);
}

async function parseAndExecuteArchiveInterpreter(
input: string,
IOInput: R.FileSystem,
): Promise<R.Result<R.BinaryFile | null>> {
const document = await parse(input, { validationChecks: 'all' });
expectNoParserAndLexerErrors(document);

const block = locator.getAstNode<BlockDefinition>(
document.parseResult.value,
'pipelines@0/blocks@1',
) as BlockDefinition;

return new FilePickerExecutor().doExecute(
IOInput,
getTestExecutionContext(locator, document, [block]),
);
}

beforeAll(async () => {
// Create language services
const services = createJayveeServices(NodeFileSystem).Jayvee;
await loadTestExtensions(services, [
path.resolve(__dirname, '../test/test-extension/TestBlockTypes.jv'),
]);
locator = services.workspace.AstNodeLocator;
// Parse function for Jayvee (without validation)
parse = parseHelper(services);
});
beforeEach(() => {
// Create fresh filesystem
fileSystem = new R.InMemoryFileSystem();
});

it('should diagnose no error on valid txt file picker', async () => {
const text = readJvTestAsset('valid-file-picker.jv');
uploadTestFile('test.txt');

const result = await parseAndExecuteArchiveInterpreter(text, fileSystem);

expect(R.isErr(result)).toEqual(false);
if (R.isOk(result)) {
expect(result.right).toEqual(
expect.objectContaining({
name: 'test.txt',
extension: 'txt',
ioType: IOType.FILE,
mimeType: R.MimeType.TEXT_PLAIN,
}),
);
}
});

it('should diagnose error on file not found', async () => {
const text = readJvTestAsset('valid-file-picker.jv');

const result = await parseAndExecuteArchiveInterpreter(text, fileSystem);

expect(R.isOk(result)).toEqual(false);
if (R.isErr(result)) {
expect(result.left.message).toEqual(`File '/test.txt' not found`);
}
});
});
6 changes: 6 additions & 0 deletions libs/extensions/std/exec/src/file-picker-executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ export class FilePickerExecutor extends AbstractBlockExecutor<
): Promise<R.Result<BinaryFile | null>> {
const path = context.getPropertyValue('path', PrimitiveValuetypes.Text);
const file = fileSystem.getFile(path);
if (file == null) {
return R.err({
message: `File '${path}' not found`,
diagnostic: { node: context.getCurrentNode() },
});
}
assert(file instanceof BinaryFile);
return R.ok(file);
}
Expand Down
71 changes: 71 additions & 0 deletions libs/extensions/std/exec/src/file-util.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg
//
// SPDX-License-Identifier: AGPL-3.0-only

import { FileExtension, MimeType } from '@jvalue/jayvee-execution';

import {
inferFileExtensionFromContentTypeString,
inferFileExtensionFromFileExtensionString,
inferMimeTypeFromFileExtensionString,
} from './file-util';

describe('Validation of file-util', () => {
describe('Function inferMimeTypeFromContentTypeString', () => {
it('should diagnose no error on known mimeType', () => {
const result = inferMimeTypeFromFileExtensionString('txt');

expect(result).toEqual(MimeType.TEXT_PLAIN);
});
it('should diagnose no error on undefined input', () => {
const result = inferMimeTypeFromFileExtensionString(undefined);

expect(result).toEqual(undefined);
});
it('should diagnose no error on unknown mimeType', () => {
const result = inferMimeTypeFromFileExtensionString('unity');

expect(result).toEqual(undefined);
});
});
describe('Function inferFileExtensionFromFileExtensionString', () => {
it('should diagnose no error on valid file extension', () => {
const result = inferFileExtensionFromFileExtensionString('txt');

expect(result).toEqual(FileExtension.TXT);
});
it('should diagnose no error on valid file extension starting with .', () => {
const result = inferFileExtensionFromFileExtensionString('.txt');

expect(result).toEqual(FileExtension.TXT);
});
it('should diagnose no error on undefined input', () => {
const result = inferFileExtensionFromFileExtensionString(undefined);

expect(result).toEqual(undefined);
});
it('should diagnose no error on unknown file extension', () => {
const result = inferFileExtensionFromFileExtensionString('unity');

expect(result).toEqual(undefined);
});
});
describe('Function inferFileExtensionFromContentTypeString', () => {
it('should diagnose no error on valid content type', () => {
const result = inferFileExtensionFromContentTypeString('text/csv');

expect(result).toEqual(FileExtension.CSV);
});
it('should diagnose no error on undefined input', () => {
const result = inferFileExtensionFromContentTypeString(undefined);

expect(result).toEqual(undefined);
});
it('should diagnose no error on unknown content type', () => {
const result =
inferFileExtensionFromContentTypeString('application/unity');

expect(result).toEqual(undefined);
});
});
});
2 changes: 1 addition & 1 deletion libs/extensions/std/exec/src/file-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import { FileExtension, MimeType } from '@jvalue/jayvee-execution';
import * as mime from 'mime-types';

export function inferMimeTypeFromContentTypeString(
export function inferMimeTypeFromFileExtensionString(
fileExtension: string | undefined,
): MimeType | undefined {
if (fileExtension !== undefined) {
Expand Down
Loading
Loading