Skip to content

Commit

Permalink
Merge pull request #456 from jvalue/feature/std-extension-exec-tests
Browse files Browse the repository at this point in the history
Std extension exec tests
  • Loading branch information
f3l1x98 authored Nov 6, 2023
2 parents fdd7c04 + ea7c306 commit 282fcf0
Show file tree
Hide file tree
Showing 68 changed files with 1,608 additions and 18 deletions.
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',
) 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

0 comments on commit 282fcf0

Please sign in to comment.