From 00eb5a19189dc462c6dd70542eb835ad0e5400b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20M=C3=BCller?= Date: Mon, 25 Sep 2023 12:59:51 +0200 Subject: [PATCH 01/31] Added tests for ArchiveInterpreterExecutor --- .../src/archive-interpreter-executor.spec.ts | 229 ++++++++++++++++++ .../invalid-corrupt-zip.zip | 1 + .../valid-7z-archive-interpreter.jv | 18 ++ .../archive-interpreter-executor/valid-7z.7z | Bin 0 -> 147 bytes .../valid-gz-archive-interpreter.jv | 18 ++ .../archive-interpreter-executor/valid-gz.gz | Bin 0 -> 48 bytes .../valid-zip-archive-interpreter.jv | 18 ++ .../valid-zip.zip | Bin 0 -> 171 bytes 8 files changed, 284 insertions(+) create mode 100644 libs/extensions/std/exec/src/archive-interpreter-executor.spec.ts create mode 100644 libs/extensions/std/exec/test/assets/archive-interpreter-executor/invalid-corrupt-zip.zip create mode 100644 libs/extensions/std/exec/test/assets/archive-interpreter-executor/valid-7z-archive-interpreter.jv create mode 100644 libs/extensions/std/exec/test/assets/archive-interpreter-executor/valid-7z.7z create mode 100644 libs/extensions/std/exec/test/assets/archive-interpreter-executor/valid-gz-archive-interpreter.jv create mode 100644 libs/extensions/std/exec/test/assets/archive-interpreter-executor/valid-gz.gz create mode 100644 libs/extensions/std/exec/test/assets/archive-interpreter-executor/valid-zip-archive-interpreter.jv create mode 100644 libs/extensions/std/exec/test/assets/archive-interpreter-executor/valid-zip.zip diff --git a/libs/extensions/std/exec/src/archive-interpreter-executor.spec.ts b/libs/extensions/std/exec/src/archive-interpreter-executor.spec.ts new file mode 100644 index 000000000..ff7b936a5 --- /dev/null +++ b/libs/extensions/std/exec/src/archive-interpreter-executor.spec.ts @@ -0,0 +1,229 @@ +// SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg +// +// SPDX-License-Identifier: AGPL-3.0-only + +import { readFileSync } from 'fs'; +import * as path from 'path'; + +import * as R from '@jvalue/jayvee-execution'; +import { getTestExecutionContext } from '@jvalue/jayvee-execution/test'; +import { + BlockDefinition, + IOType, + createJayveeServices, + useExtension, +} from '@jvalue/jayvee-language-server'; +import { + ParseHelperOptions, + TestLangExtension, + expectNoParserAndLexerErrors, + parseHelper, + readJvTestAssetHelper, +} from '@jvalue/jayvee-language-server/test'; +import { AstNode, AstNodeLocator, LangiumDocument } from 'langium'; +import { NodeFileSystem } from 'langium/node'; + +import { ArchiveInterpreterExecutor } from './archive-interpreter-executor'; + +describe('Validation of ArchiveInterpreterExecutor', () => { + let parse: ( + input: string, + options?: ParseHelperOptions, + ) => Promise>; + + let locator: AstNodeLocator; + + const readJvTestAsset = readJvTestAssetHelper(__dirname, '../test/assets/'); + + function readTestArchive(fileName: string) { + return readFileSync(path.resolve(__dirname, '../test/assets/', fileName)); + } + + async function parseAndExecuteArchiveInterpreter( + input: string, + IOInput: R.BinaryFile, + ): Promise> { + const document = await parse(input, { validationChecks: 'all' }); + expectNoParserAndLexerErrors(document); + + const block = locator.getAstNode( + document.parseResult.value, + 'pipelines@0/blocks@1', + ) as BlockDefinition; + + return new ArchiveInterpreterExecutor().doExecute( + IOInput, + getTestExecutionContext(locator, document, [block]), + ); + } + + beforeAll(() => { + // Register test extension + useExtension(new TestLangExtension()); + // Create language services + const services = createJayveeServices(NodeFileSystem).Jayvee; + 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( + 'archive-interpreter-executor/valid-zip-archive-interpreter.jv', + ); + + try { + const testFile = readTestArchive( + 'archive-interpreter-executor/valid-zip.zip', + ); + const result = await parseAndExecuteArchiveInterpreter( + text, + new R.BinaryFile( + 'testArchive.zip', + R.FileExtension.ZIP, + R.MimeType.APPLICATION_ZIP, + testFile, + ), + ); + + if (R.isErr(result)) { + throw new Error(result.left.message); + } + 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, + }), + ); + } catch (e) { + expect(e).toEqual(undefined); + } + }); + + it('should diagnose no error on valid gz BinaryFile', async () => { + const text = readJvTestAsset( + 'archive-interpreter-executor/valid-gz-archive-interpreter.jv', + ); + + try { + const testFile = readTestArchive( + 'archive-interpreter-executor/valid-gz.gz', + ); + const result = await parseAndExecuteArchiveInterpreter( + text, + new R.BinaryFile( + 'testArchive.gz', + R.FileExtension.ZIP, + R.MimeType.APPLICATION_OCTET_STREAM, + testFile, + ), + ); + + if (R.isErr(result)) { + throw new Error(result.left.message); + } + expect(result.right.ioType).toEqual(IOType.FILE_SYSTEM); + expect(result.right.getFile('/testArchive')).toEqual( + expect.objectContaining({ + name: 'testArchive', + extension: '', + ioType: IOType.FILE, + mimeType: R.MimeType.APPLICATION_OCTET_STREAM, + }), + ); + } catch (e) { + expect(e).toEqual(undefined); + } + }); + + it('should diagnose error on zip as gz archive', async () => { + const text = readJvTestAsset( + 'archive-interpreter-executor/valid-gz-archive-interpreter.jv', + ); + + try { + const testFile = readTestArchive( + 'archive-interpreter-executor/valid-zip.zip', + ); + const result = await parseAndExecuteArchiveInterpreter( + text, + new R.BinaryFile( + 'testArchive.zip', + R.FileExtension.ZIP, + R.MimeType.APPLICATION_ZIP, + testFile, + ), + ); + + if (R.isOk(result)) { + throw new Error('Should throw processing error'); + } + expect(result.left.message).toEqual( + 'Unexpected Error undefined occured during processing', + ); + } catch (e) { + expect(e).toEqual(undefined); + } + }); + + it('should diagnose error on invalid archive type', async () => { + const text = readJvTestAsset( + 'archive-interpreter-executor/valid-7z-archive-interpreter.jv', + ); + + try { + const testFile = readTestArchive( + 'archive-interpreter-executor/valid-7z.7z', + ); + const result = await parseAndExecuteArchiveInterpreter( + text, + new R.BinaryFile( + 'testArchive.7z', + R.FileExtension.ZIP, + R.MimeType.APPLICATION_OCTET_STREAM, + testFile, + ), + ); + + if (R.isOk(result)) { + throw new Error('Should throw invalid archive type error'); + } + expect(result.left.message).toEqual('Archive type is not supported'); + } catch (e) { + expect(e).toEqual(undefined); + } + }); + + it('should diagnose error on corrupted archive', async () => { + const text = readJvTestAsset( + 'archive-interpreter-executor/valid-zip-archive-interpreter.jv', + ); + + try { + const testFile = readTestArchive( + 'archive-interpreter-executor/invalid-corrupt-zip.zip', + ); + const result = await parseAndExecuteArchiveInterpreter( + text, + new R.BinaryFile( + 'testArchive.zip', + R.FileExtension.ZIP, + R.MimeType.APPLICATION_ZIP, + testFile, + ), + ); + + if (R.isOk(result)) { + throw new Error('Should not be able to extract corrupted archive'); + } + 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", + ); + } catch (e) { + expect(e).toEqual(undefined); + } + }); +}); diff --git a/libs/extensions/std/exec/test/assets/archive-interpreter-executor/invalid-corrupt-zip.zip b/libs/extensions/std/exec/test/assets/archive-interpreter-executor/invalid-corrupt-zip.zip new file mode 100644 index 000000000..0168c1c10 --- /dev/null +++ b/libs/extensions/std/exec/test/assets/archive-interpreter-executor/invalid-corrupt-zip.zip @@ -0,0 +1 @@ +«7UGœ‡5¶w4´è#˜¨K`â^«n<$=òvoð¯*[Q¢îؤ~ Yg0ñ{QòÚüa!Ÿ ˜ùH'#£x£Fgª )+d‘\U¡×§”±¤õÈÆ”Ñ^¢Ë§ÊîJC’ª<¯µfÛ÷7o˜,Á»"‰·[àZ&‡$Òh§bäÈJíâA%RÚ4jõ%)§áÚˆ;`âȾEÛ£W£íE†/jÙ Ÿ \ No newline at end of file diff --git a/libs/extensions/std/exec/test/assets/archive-interpreter-executor/valid-7z-archive-interpreter.jv b/libs/extensions/std/exec/test/assets/archive-interpreter-executor/valid-7z-archive-interpreter.jv new file mode 100644 index 000000000..908541126 --- /dev/null +++ b/libs/extensions/std/exec/test/assets/archive-interpreter-executor/valid-7z-archive-interpreter.jv @@ -0,0 +1,18 @@ +// SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg +// +// SPDX-License-Identifier: AGPL-3.0-only + +pipeline TestPipeline { + + block TestExtractor oftype TestFileExtractor { + } + + block TestBlock oftype ArchiveInterpreter { + archiveType: '7z'; + } + + block TestLoader oftype TestFileLoader { + } + + TestExtractor -> TestBlock -> TestLoader; +} diff --git a/libs/extensions/std/exec/test/assets/archive-interpreter-executor/valid-7z.7z b/libs/extensions/std/exec/test/assets/archive-interpreter-executor/valid-7z.7z new file mode 100644 index 0000000000000000000000000000000000000000..abf9b605200d509be25cad9cbf304c0e49d35acf GIT binary patch literal 147 zcmXr7+Ou9=hJi(};$goe0|Z1t>A&Jd&lwp+LNYRo6@VyFp(M4qL?JCRCsmJ&fsuuc zfss>^ft{O?fl*PBk%32)frE=NZb$Pi1_o9}Ngk*nU`kM!p@boop%_T&0dWNoGcZUp bh;T77G;n`;KH>dMMo~6K28D(tjSLI`JhmI) literal 0 HcmV?d00001 diff --git a/libs/extensions/std/exec/test/assets/archive-interpreter-executor/valid-gz-archive-interpreter.jv b/libs/extensions/std/exec/test/assets/archive-interpreter-executor/valid-gz-archive-interpreter.jv new file mode 100644 index 000000000..eb44f6939 --- /dev/null +++ b/libs/extensions/std/exec/test/assets/archive-interpreter-executor/valid-gz-archive-interpreter.jv @@ -0,0 +1,18 @@ +// SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg +// +// SPDX-License-Identifier: AGPL-3.0-only + +pipeline TestPipeline { + + block TestExtractor oftype TestFileExtractor { + } + + block TestBlock oftype ArchiveInterpreter { + archiveType: 'gz'; + } + + block TestLoader oftype TestFileLoader { + } + + TestExtractor -> TestBlock -> TestLoader; +} diff --git a/libs/extensions/std/exec/test/assets/archive-interpreter-executor/valid-gz.gz b/libs/extensions/std/exec/test/assets/archive-interpreter-executor/valid-gz.gz new file mode 100644 index 0000000000000000000000000000000000000000..87c5b997b469ed2e413753bdf351833b41e67a6b GIT binary patch literal 48 zcmb2|=HOro5lm%ZE=ese(JQGaVc TestBlock -> TestLoader; +} diff --git a/libs/extensions/std/exec/test/assets/archive-interpreter-executor/valid-zip.zip b/libs/extensions/std/exec/test/assets/archive-interpreter-executor/valid-zip.zip new file mode 100644 index 0000000000000000000000000000000000000000..26f1dea6d1df58008257de285515072af8d4fd84 GIT binary patch literal 171 zcmWIWW@h1HW&i@FD9iA;9nH5yfou@w0OFF=;u5`*ijt6w%wh!~N>l)eD5PcPr0Q`6 zcr!BDGvm^%0@Mxy3JpsdK{U)LE(Qe Date: Mon, 25 Sep 2023 13:04:03 +0200 Subject: [PATCH 02/31] Fixed duplication --- .../src/archive-interpreter-executor.spec.ts | 25 +++++++------------ 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/libs/extensions/std/exec/src/archive-interpreter-executor.spec.ts b/libs/extensions/std/exec/src/archive-interpreter-executor.spec.ts index ff7b936a5..eb43e263b 100644 --- a/libs/extensions/std/exec/src/archive-interpreter-executor.spec.ts +++ b/libs/extensions/std/exec/src/archive-interpreter-executor.spec.ts @@ -33,7 +33,10 @@ describe('Validation of ArchiveInterpreterExecutor', () => { let locator: AstNodeLocator; - const readJvTestAsset = readJvTestAssetHelper(__dirname, '../test/assets/'); + const readJvTestAsset = readJvTestAssetHelper( + __dirname, + '../test/assets/archive-interpreter-executor/', + ); function readTestArchive(fileName: string) { return readFileSync(path.resolve(__dirname, '../test/assets/', fileName)); @@ -68,9 +71,7 @@ describe('Validation of ArchiveInterpreterExecutor', () => { }); it('should diagnose no error on valid zip BinaryFile', async () => { - const text = readJvTestAsset( - 'archive-interpreter-executor/valid-zip-archive-interpreter.jv', - ); + const text = readJvTestAsset('valid-zip-archive-interpreter.jv'); try { const testFile = readTestArchive( @@ -104,9 +105,7 @@ describe('Validation of ArchiveInterpreterExecutor', () => { }); it('should diagnose no error on valid gz BinaryFile', async () => { - const text = readJvTestAsset( - 'archive-interpreter-executor/valid-gz-archive-interpreter.jv', - ); + const text = readJvTestAsset('valid-gz-archive-interpreter.jv'); try { const testFile = readTestArchive( @@ -140,9 +139,7 @@ describe('Validation of ArchiveInterpreterExecutor', () => { }); it('should diagnose error on zip as gz archive', async () => { - const text = readJvTestAsset( - 'archive-interpreter-executor/valid-gz-archive-interpreter.jv', - ); + const text = readJvTestAsset('valid-gz-archive-interpreter.jv'); try { const testFile = readTestArchive( @@ -170,9 +167,7 @@ describe('Validation of ArchiveInterpreterExecutor', () => { }); it('should diagnose error on invalid archive type', async () => { - const text = readJvTestAsset( - 'archive-interpreter-executor/valid-7z-archive-interpreter.jv', - ); + const text = readJvTestAsset('valid-7z-archive-interpreter.jv'); try { const testFile = readTestArchive( @@ -198,9 +193,7 @@ describe('Validation of ArchiveInterpreterExecutor', () => { }); it('should diagnose error on corrupted archive', async () => { - const text = readJvTestAsset( - 'archive-interpreter-executor/valid-zip-archive-interpreter.jv', - ); + const text = readJvTestAsset('valid-zip-archive-interpreter.jv'); try { const testFile = readTestArchive( From caf1a82e813af3c77ec5f86331d9c47d6203c37d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20M=C3=BCller?= Date: Mon, 25 Sep 2023 13:05:18 +0200 Subject: [PATCH 03/31] Fixed duplication --- .../src/archive-interpreter-executor.spec.ts | 28 ++++++++----------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/libs/extensions/std/exec/src/archive-interpreter-executor.spec.ts b/libs/extensions/std/exec/src/archive-interpreter-executor.spec.ts index eb43e263b..ec90a35a2 100644 --- a/libs/extensions/std/exec/src/archive-interpreter-executor.spec.ts +++ b/libs/extensions/std/exec/src/archive-interpreter-executor.spec.ts @@ -39,7 +39,13 @@ describe('Validation of ArchiveInterpreterExecutor', () => { ); function readTestArchive(fileName: string) { - return readFileSync(path.resolve(__dirname, '../test/assets/', fileName)); + return readFileSync( + path.resolve( + __dirname, + '../test/assets/archive-interpreter-executor/', + fileName, + ), + ); } async function parseAndExecuteArchiveInterpreter( @@ -74,9 +80,7 @@ describe('Validation of ArchiveInterpreterExecutor', () => { const text = readJvTestAsset('valid-zip-archive-interpreter.jv'); try { - const testFile = readTestArchive( - 'archive-interpreter-executor/valid-zip.zip', - ); + const testFile = readTestArchive('valid-zip.zip'); const result = await parseAndExecuteArchiveInterpreter( text, new R.BinaryFile( @@ -108,9 +112,7 @@ describe('Validation of ArchiveInterpreterExecutor', () => { const text = readJvTestAsset('valid-gz-archive-interpreter.jv'); try { - const testFile = readTestArchive( - 'archive-interpreter-executor/valid-gz.gz', - ); + const testFile = readTestArchive('valid-gz.gz'); const result = await parseAndExecuteArchiveInterpreter( text, new R.BinaryFile( @@ -142,9 +144,7 @@ describe('Validation of ArchiveInterpreterExecutor', () => { const text = readJvTestAsset('valid-gz-archive-interpreter.jv'); try { - const testFile = readTestArchive( - 'archive-interpreter-executor/valid-zip.zip', - ); + const testFile = readTestArchive('valid-zip.zip'); const result = await parseAndExecuteArchiveInterpreter( text, new R.BinaryFile( @@ -170,9 +170,7 @@ describe('Validation of ArchiveInterpreterExecutor', () => { const text = readJvTestAsset('valid-7z-archive-interpreter.jv'); try { - const testFile = readTestArchive( - 'archive-interpreter-executor/valid-7z.7z', - ); + const testFile = readTestArchive('valid-7z.7z'); const result = await parseAndExecuteArchiveInterpreter( text, new R.BinaryFile( @@ -196,9 +194,7 @@ describe('Validation of ArchiveInterpreterExecutor', () => { const text = readJvTestAsset('valid-zip-archive-interpreter.jv'); try { - const testFile = readTestArchive( - 'archive-interpreter-executor/invalid-corrupt-zip.zip', - ); + const testFile = readTestArchive('invalid-corrupt-zip.zip'); const result = await parseAndExecuteArchiveInterpreter( text, new R.BinaryFile( From 2e014dd1d296ea38c3db97b32a0cbd3d91e3f101 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20M=C3=BCller?= Date: Mon, 9 Oct 2023 09:25:16 +0200 Subject: [PATCH 04/31] Added first basic test for file-picker-executor --- .../std/exec/src/file-picker-executor.spec.ts | 113 ++++++++++++++++++ .../test/assets/file-picker-executor/test.txt | 1 + .../file-picker-executor/valid-file-picker.jv | 18 +++ 3 files changed, 132 insertions(+) create mode 100644 libs/extensions/std/exec/src/file-picker-executor.spec.ts create mode 100644 libs/extensions/std/exec/test/assets/file-picker-executor/test.txt create mode 100644 libs/extensions/std/exec/test/assets/file-picker-executor/valid-file-picker.jv diff --git a/libs/extensions/std/exec/src/file-picker-executor.spec.ts b/libs/extensions/std/exec/src/file-picker-executor.spec.ts new file mode 100644 index 000000000..07ac5dd47 --- /dev/null +++ b/libs/extensions/std/exec/src/file-picker-executor.spec.ts @@ -0,0 +1,113 @@ +// SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg +// +// SPDX-License-Identifier: AGPL-3.0-only + +import { readFileSync } from 'fs'; +import * as path from 'path'; + +import * as R from '@jvalue/jayvee-execution'; +import { getTestExecutionContext } from '@jvalue/jayvee-execution/test'; +import { + BlockDefinition, + IOType, + createJayveeServices, + useExtension, +} from '@jvalue/jayvee-language-server'; +import { + ParseHelperOptions, + TestLangExtension, + expectNoParserAndLexerErrors, + parseHelper, + readJvTestAssetHelper, +} from '@jvalue/jayvee-language-server/test'; +import { AstNode, AstNodeLocator, LangiumDocument } from 'langium'; +import { NodeFileSystem } from 'langium/node'; + +import { FilePickerExecutor } from './file-picker-executor'; +import { + inferFileExtensionFromFileExtensionString, + inferMimeTypeFromContentTypeString, +} from './file-util'; + +describe('Validation of FilePickerExecutor', () => { + let parse: ( + input: string, + options?: ParseHelperOptions, + ) => Promise>; + let fileSystem: R.FileSystem; + + let locator: AstNodeLocator; + + const readJvTestAsset = readJvTestAssetHelper( + __dirname, + '../test/assets/file-picker-executor/', + ); + + function uploadTestFile(fileName: string) { + const extName = path.extname(fileName); + const mimeType = + inferMimeTypeFromContentTypeString(extName) || + R.MimeType.APPLICATION_OCTET_STREAM; + const fileExtension = + inferFileExtensionFromFileExtensionString(extName) || + R.FileExtension.NONE; + const file = readFileSync( + path.resolve(__dirname, '../test/assets/file-picker-executor/', fileName), + ); + + fileSystem.putFile( + `/${fileName}`, + new R.BinaryFile(fileName, fileExtension, mimeType, file), + ); + } + + async function parseAndExecuteArchiveInterpreter( + input: string, + IOInput: R.FileSystem, + ): Promise> { + const document = await parse(input, { validationChecks: 'all' }); + expectNoParserAndLexerErrors(document); + + const block = locator.getAstNode( + document.parseResult.value, + 'pipelines@0/blocks@1', + ) as BlockDefinition; + + return new FilePickerExecutor().doExecute( + IOInput, + getTestExecutionContext(locator, document, [block]), + ); + } + + beforeAll(() => { + // Register test extension + useExtension(new TestLangExtension()); + // Create language services + const services = createJayveeServices(NodeFileSystem).Jayvee; + locator = services.workspace.AstNodeLocator; + // Parse function for Jayvee (without validation) + parse = parseHelper(services); + // Prepare 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?.ioType).toEqual(IOType.FILE); + expect(result.right).toEqual( + expect.objectContaining({ + name: 'test.txt', + extension: 'txt', + ioType: IOType.FILE, + mimeType: R.MimeType.TEXT_PLAIN, + }), + ); + } + }); +}); diff --git a/libs/extensions/std/exec/test/assets/file-picker-executor/test.txt b/libs/extensions/std/exec/test/assets/file-picker-executor/test.txt new file mode 100644 index 000000000..4fff881e8 --- /dev/null +++ b/libs/extensions/std/exec/test/assets/file-picker-executor/test.txt @@ -0,0 +1 @@ +Test File diff --git a/libs/extensions/std/exec/test/assets/file-picker-executor/valid-file-picker.jv b/libs/extensions/std/exec/test/assets/file-picker-executor/valid-file-picker.jv new file mode 100644 index 000000000..169d79c41 --- /dev/null +++ b/libs/extensions/std/exec/test/assets/file-picker-executor/valid-file-picker.jv @@ -0,0 +1,18 @@ +// SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg +// +// SPDX-License-Identifier: AGPL-3.0-only + +pipeline TestPipeline { + + block TestExtractor oftype TestFileExtractor { + } + + block TestBlock oftype FilePicker { + path: '/test.txt'; + } + + block TestLoader oftype TestFileLoader { + } + + TestExtractor -> TestBlock -> TestLoader; +} From feb49ddfc98d85ae660a944dc1c999c548dece35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20M=C3=BCller?= Date: Mon, 9 Oct 2023 09:28:22 +0200 Subject: [PATCH 05/31] Added custom error message in case file was not found --- libs/extensions/std/exec/src/file-picker-executor.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libs/extensions/std/exec/src/file-picker-executor.ts b/libs/extensions/std/exec/src/file-picker-executor.ts index 51862d2a9..72f003a95 100644 --- a/libs/extensions/std/exec/src/file-picker-executor.ts +++ b/libs/extensions/std/exec/src/file-picker-executor.ts @@ -33,6 +33,12 @@ export class FilePickerExecutor extends AbstractBlockExecutor< ): Promise> { 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); } From 5883bd8dfc81ae58cf5d533990fc1f318b854bf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20M=C3=BCller?= Date: Mon, 9 Oct 2023 09:28:39 +0200 Subject: [PATCH 06/31] Added new test for file not found --- .../std/exec/src/file-picker-executor.spec.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/libs/extensions/std/exec/src/file-picker-executor.spec.ts b/libs/extensions/std/exec/src/file-picker-executor.spec.ts index 07ac5dd47..0b5f285cc 100644 --- a/libs/extensions/std/exec/src/file-picker-executor.spec.ts +++ b/libs/extensions/std/exec/src/file-picker-executor.spec.ts @@ -87,7 +87,9 @@ describe('Validation of FilePickerExecutor', () => { locator = services.workspace.AstNodeLocator; // Parse function for Jayvee (without validation) parse = parseHelper(services); - // Prepare filesystem + }); + beforeEach(() => { + // Create fresh filesystem fileSystem = new R.InMemoryFileSystem(); }); @@ -110,4 +112,15 @@ describe('Validation of FilePickerExecutor', () => { ); } }); + + 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`); + } + }); }); From f150b9a7fe7bd6c1c69fe66245882b8499885350 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20M=C3=BCller?= Date: Mon, 9 Oct 2023 10:36:45 +0200 Subject: [PATCH 07/31] Added basic file-util tests --- .../extensions/std/exec/src/file-util.spec.ts | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 libs/extensions/std/exec/src/file-util.spec.ts diff --git a/libs/extensions/std/exec/src/file-util.spec.ts b/libs/extensions/std/exec/src/file-util.spec.ts new file mode 100644 index 000000000..a469e6a92 --- /dev/null +++ b/libs/extensions/std/exec/src/file-util.spec.ts @@ -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, + inferMimeTypeFromContentTypeString, +} from './file-util'; + +describe('Validation of file-util', () => { + describe('Function inferMimeTypeFromContentTypeString', () => { + it('should diagnose no error on known mimeType', () => { + const result = inferMimeTypeFromContentTypeString('txt'); + + expect(result).toEqual(MimeType.TEXT_PLAIN); + }); + it('should diagnose no error on undefined input', () => { + const result = inferMimeTypeFromContentTypeString(undefined); + + expect(result).toEqual(undefined); + }); + it('should diagnose no error on unknown mimeType', () => { + const result = inferMimeTypeFromContentTypeString('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); + }); + }); +}); From c005225583a9b6eb1529b92af242802e71e3078c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20M=C3=BCller?= Date: Mon, 9 Oct 2023 10:43:06 +0200 Subject: [PATCH 08/31] refactored tests like file-picker-extractor.spec.ts --- .../src/archive-interpreter-executor.spec.ts | 140 ++++++++---------- 1 file changed, 60 insertions(+), 80 deletions(-) diff --git a/libs/extensions/std/exec/src/archive-interpreter-executor.spec.ts b/libs/extensions/std/exec/src/archive-interpreter-executor.spec.ts index ec90a35a2..816264468 100644 --- a/libs/extensions/std/exec/src/archive-interpreter-executor.spec.ts +++ b/libs/extensions/std/exec/src/archive-interpreter-executor.spec.ts @@ -79,21 +79,19 @@ describe('Validation of ArchiveInterpreterExecutor', () => { it('should diagnose no error on valid zip BinaryFile', async () => { const text = readJvTestAsset('valid-zip-archive-interpreter.jv'); - try { - const testFile = readTestArchive('valid-zip.zip'); - const result = await parseAndExecuteArchiveInterpreter( - text, - new R.BinaryFile( - 'testArchive.zip', - R.FileExtension.ZIP, - R.MimeType.APPLICATION_ZIP, - testFile, - ), - ); + const testFile = readTestArchive('valid-zip.zip'); + const result = await parseAndExecuteArchiveInterpreter( + text, + new R.BinaryFile( + 'testArchive.zip', + R.FileExtension.ZIP, + R.MimeType.APPLICATION_ZIP, + testFile, + ), + ); - if (R.isErr(result)) { - throw new Error(result.left.message); - } + 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({ @@ -103,29 +101,25 @@ describe('Validation of ArchiveInterpreterExecutor', () => { mimeType: R.MimeType.TEXT_PLAIN, }), ); - } catch (e) { - expect(e).toEqual(undefined); } }); it('should diagnose no error on valid gz BinaryFile', async () => { const text = readJvTestAsset('valid-gz-archive-interpreter.jv'); - try { - const testFile = readTestArchive('valid-gz.gz'); - const result = await parseAndExecuteArchiveInterpreter( - text, - new R.BinaryFile( - 'testArchive.gz', - R.FileExtension.ZIP, - R.MimeType.APPLICATION_OCTET_STREAM, - testFile, - ), - ); + const testFile = readTestArchive('valid-gz.gz'); + const result = await parseAndExecuteArchiveInterpreter( + text, + new R.BinaryFile( + 'testArchive.gz', + R.FileExtension.ZIP, + R.MimeType.APPLICATION_OCTET_STREAM, + testFile, + ), + ); - if (R.isErr(result)) { - throw new Error(result.left.message); - } + expect(R.isErr(result)).toEqual(false); + if (R.isOk(result)) { expect(result.right.ioType).toEqual(IOType.FILE_SYSTEM); expect(result.right.getFile('/testArchive')).toEqual( expect.objectContaining({ @@ -135,84 +129,70 @@ describe('Validation of ArchiveInterpreterExecutor', () => { mimeType: R.MimeType.APPLICATION_OCTET_STREAM, }), ); - } catch (e) { - expect(e).toEqual(undefined); } }); it('should diagnose error on zip as gz archive', async () => { const text = readJvTestAsset('valid-gz-archive-interpreter.jv'); - try { - const testFile = readTestArchive('valid-zip.zip'); - const result = await parseAndExecuteArchiveInterpreter( - text, - new R.BinaryFile( - 'testArchive.zip', - R.FileExtension.ZIP, - R.MimeType.APPLICATION_ZIP, - testFile, - ), - ); + const testFile = readTestArchive('valid-zip.zip'); + const result = await parseAndExecuteArchiveInterpreter( + text, + new R.BinaryFile( + 'testArchive.zip', + R.FileExtension.ZIP, + R.MimeType.APPLICATION_ZIP, + testFile, + ), + ); - if (R.isOk(result)) { - throw new Error('Should throw processing error'); - } + expect(R.isOk(result)).toEqual(false); + if (R.isErr(result)) { expect(result.left.message).toEqual( 'Unexpected Error undefined occured during processing', ); - } catch (e) { - expect(e).toEqual(undefined); } }); it('should diagnose error on invalid archive type', async () => { const text = readJvTestAsset('valid-7z-archive-interpreter.jv'); - try { - const testFile = readTestArchive('valid-7z.7z'); - const result = await parseAndExecuteArchiveInterpreter( - text, - new R.BinaryFile( - 'testArchive.7z', - R.FileExtension.ZIP, - R.MimeType.APPLICATION_OCTET_STREAM, - testFile, - ), - ); + const testFile = readTestArchive('valid-7z.7z'); + const result = await parseAndExecuteArchiveInterpreter( + text, + new R.BinaryFile( + 'testArchive.7z', + R.FileExtension.ZIP, + R.MimeType.APPLICATION_OCTET_STREAM, + testFile, + ), + ); - if (R.isOk(result)) { - throw new Error('Should throw invalid archive type error'); - } + expect(R.isOk(result)).toEqual(false); + if (R.isErr(result)) { expect(result.left.message).toEqual('Archive type is not supported'); - } catch (e) { - expect(e).toEqual(undefined); } }); it('should diagnose error on corrupted archive', async () => { const text = readJvTestAsset('valid-zip-archive-interpreter.jv'); - try { - const testFile = readTestArchive('invalid-corrupt-zip.zip'); - const result = await parseAndExecuteArchiveInterpreter( - text, - new R.BinaryFile( - 'testArchive.zip', - R.FileExtension.ZIP, - R.MimeType.APPLICATION_ZIP, - testFile, - ), - ); + const testFile = readTestArchive('invalid-corrupt-zip.zip'); + const result = await parseAndExecuteArchiveInterpreter( + text, + new R.BinaryFile( + 'testArchive.zip', + R.FileExtension.ZIP, + R.MimeType.APPLICATION_ZIP, + testFile, + ), + ); - if (R.isOk(result)) { - throw new Error('Should not be able to extract corrupted archive'); - } + 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", ); - } catch (e) { - expect(e).toEqual(undefined); } }); }); From d24a8d61245621b52b32ed707f12104d5a4a7f3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20M=C3=BCller?= Date: Mon, 9 Oct 2023 11:04:50 +0200 Subject: [PATCH 09/31] - Added test utils containing function to create BinaryFile from local file - Refactored tests to use new util --- .../src/archive-interpreter-executor.spec.ts | 70 ++++--------------- .../std/exec/src/file-picker-executor.spec.ts | 23 ++---- libs/extensions/std/exec/test/index.ts | 1 + libs/extensions/std/exec/test/utils.ts | 26 +++++++ 4 files changed, 49 insertions(+), 71 deletions(-) create mode 100644 libs/extensions/std/exec/test/utils.ts diff --git a/libs/extensions/std/exec/src/archive-interpreter-executor.spec.ts b/libs/extensions/std/exec/src/archive-interpreter-executor.spec.ts index 816264468..ea00693c2 100644 --- a/libs/extensions/std/exec/src/archive-interpreter-executor.spec.ts +++ b/libs/extensions/std/exec/src/archive-interpreter-executor.spec.ts @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: AGPL-3.0-only -import { readFileSync } from 'fs'; import * as path from 'path'; import * as R from '@jvalue/jayvee-execution'; @@ -23,6 +22,8 @@ import { 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', () => { @@ -38,14 +39,13 @@ describe('Validation of ArchiveInterpreterExecutor', () => { '../test/assets/archive-interpreter-executor/', ); - function readTestArchive(fileName: string) { - return readFileSync( - path.resolve( - __dirname, - '../test/assets/archive-interpreter-executor/', - fileName, - ), + function readTestArchive(fileName: string): R.BinaryFile { + const absoluteFileName = path.resolve( + __dirname, + '../test/assets/archive-interpreter-executor/', + fileName, ); + return createBinaryFileFromLocalFile(absoluteFileName); } async function parseAndExecuteArchiveInterpreter( @@ -80,15 +80,7 @@ describe('Validation of ArchiveInterpreterExecutor', () => { const text = readJvTestAsset('valid-zip-archive-interpreter.jv'); const testFile = readTestArchive('valid-zip.zip'); - const result = await parseAndExecuteArchiveInterpreter( - text, - new R.BinaryFile( - 'testArchive.zip', - R.FileExtension.ZIP, - R.MimeType.APPLICATION_ZIP, - testFile, - ), - ); + const result = await parseAndExecuteArchiveInterpreter(text, testFile); expect(R.isErr(result)).toEqual(false); if (R.isOk(result)) { @@ -108,22 +100,14 @@ describe('Validation of ArchiveInterpreterExecutor', () => { const text = readJvTestAsset('valid-gz-archive-interpreter.jv'); const testFile = readTestArchive('valid-gz.gz'); - const result = await parseAndExecuteArchiveInterpreter( - text, - new R.BinaryFile( - 'testArchive.gz', - R.FileExtension.ZIP, - R.MimeType.APPLICATION_OCTET_STREAM, - testFile, - ), - ); + 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('/testArchive')).toEqual( + expect(result.right.getFile('/valid-gz')).toEqual( expect.objectContaining({ - name: 'testArchive', + name: 'valid-gz', extension: '', ioType: IOType.FILE, mimeType: R.MimeType.APPLICATION_OCTET_STREAM, @@ -136,15 +120,7 @@ describe('Validation of ArchiveInterpreterExecutor', () => { const text = readJvTestAsset('valid-gz-archive-interpreter.jv'); const testFile = readTestArchive('valid-zip.zip'); - const result = await parseAndExecuteArchiveInterpreter( - text, - new R.BinaryFile( - 'testArchive.zip', - R.FileExtension.ZIP, - R.MimeType.APPLICATION_ZIP, - testFile, - ), - ); + const result = await parseAndExecuteArchiveInterpreter(text, testFile); expect(R.isOk(result)).toEqual(false); if (R.isErr(result)) { @@ -158,15 +134,7 @@ describe('Validation of ArchiveInterpreterExecutor', () => { const text = readJvTestAsset('valid-7z-archive-interpreter.jv'); const testFile = readTestArchive('valid-7z.7z'); - const result = await parseAndExecuteArchiveInterpreter( - text, - new R.BinaryFile( - 'testArchive.7z', - R.FileExtension.ZIP, - R.MimeType.APPLICATION_OCTET_STREAM, - testFile, - ), - ); + const result = await parseAndExecuteArchiveInterpreter(text, testFile); expect(R.isOk(result)).toEqual(false); if (R.isErr(result)) { @@ -178,15 +146,7 @@ describe('Validation of ArchiveInterpreterExecutor', () => { const text = readJvTestAsset('valid-zip-archive-interpreter.jv'); const testFile = readTestArchive('invalid-corrupt-zip.zip'); - const result = await parseAndExecuteArchiveInterpreter( - text, - new R.BinaryFile( - 'testArchive.zip', - R.FileExtension.ZIP, - R.MimeType.APPLICATION_ZIP, - testFile, - ), - ); + const result = await parseAndExecuteArchiveInterpreter(text, testFile); expect(R.isOk(result)).toEqual(false); if (R.isErr(result)) { diff --git a/libs/extensions/std/exec/src/file-picker-executor.spec.ts b/libs/extensions/std/exec/src/file-picker-executor.spec.ts index 0b5f285cc..1b82a3b2a 100644 --- a/libs/extensions/std/exec/src/file-picker-executor.spec.ts +++ b/libs/extensions/std/exec/src/file-picker-executor.spec.ts @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: AGPL-3.0-only -import { readFileSync } from 'fs'; import * as path from 'path'; import * as R from '@jvalue/jayvee-execution'; @@ -23,11 +22,9 @@ import { import { AstNode, AstNodeLocator, LangiumDocument } from 'langium'; import { NodeFileSystem } from 'langium/node'; +import { createBinaryFileFromLocalFile } from '../test'; + import { FilePickerExecutor } from './file-picker-executor'; -import { - inferFileExtensionFromFileExtensionString, - inferMimeTypeFromContentTypeString, -} from './file-util'; describe('Validation of FilePickerExecutor', () => { let parse: ( @@ -44,20 +41,14 @@ describe('Validation of FilePickerExecutor', () => { ); function uploadTestFile(fileName: string) { - const extName = path.extname(fileName); - const mimeType = - inferMimeTypeFromContentTypeString(extName) || - R.MimeType.APPLICATION_OCTET_STREAM; - const fileExtension = - inferFileExtensionFromFileExtensionString(extName) || - R.FileExtension.NONE; - const file = readFileSync( - path.resolve(__dirname, '../test/assets/file-picker-executor/', fileName), + const absoluteFileName = path.resolve( + __dirname, + '../test/assets/file-picker-executor/', + fileName, ); - fileSystem.putFile( `/${fileName}`, - new R.BinaryFile(fileName, fileExtension, mimeType, file), + createBinaryFileFromLocalFile(absoluteFileName), ); } diff --git a/libs/extensions/std/exec/test/index.ts b/libs/extensions/std/exec/test/index.ts index 460aca6a3..cfe12da6f 100644 --- a/libs/extensions/std/exec/test/index.ts +++ b/libs/extensions/std/exec/test/index.ts @@ -3,3 +3,4 @@ // SPDX-License-Identifier: AGPL-3.0-only export * from './mocks'; +export * from './utils'; diff --git a/libs/extensions/std/exec/test/utils.ts b/libs/extensions/std/exec/test/utils.ts new file mode 100644 index 000000000..1fd817a1c --- /dev/null +++ b/libs/extensions/std/exec/test/utils.ts @@ -0,0 +1,26 @@ +// SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg +// +// SPDX-License-Identifier: AGPL-3.0-only + +import { readFileSync } from 'fs'; +import * as path from 'path'; + +import { BinaryFile, FileExtension, MimeType } from '@jvalue/jayvee-execution'; + +import { + inferFileExtensionFromFileExtensionString, + inferMimeTypeFromContentTypeString, +} from '../src/file-util'; + +export function createBinaryFileFromLocalFile(fileName: string): BinaryFile { + const extName = path.extname(fileName); + const mimeType = + inferMimeTypeFromContentTypeString(extName) || + MimeType.APPLICATION_OCTET_STREAM; + const fileExtension = + inferFileExtensionFromFileExtensionString(extName) || FileExtension.NONE; + const file = readFileSync( + path.resolve(__dirname, '../test/assets/file-picker-executor/', fileName), + ); + return new BinaryFile(fileName, fileExtension, mimeType, file); +} From b7c69bcf235de5eb7b2dcd0f0ef7601a94943152 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20M=C3=BCller?= Date: Mon, 9 Oct 2023 11:49:48 +0200 Subject: [PATCH 10/31] Added try catch around GtfsRealtimeBindings decode in order to catch decode errors --- .../exec/src/gtfs-rt-interpreter-executor.ts | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/libs/extensions/std/exec/src/gtfs-rt-interpreter-executor.ts b/libs/extensions/std/exec/src/gtfs-rt-interpreter-executor.ts index 8fda95331..01497ebc3 100644 --- a/libs/extensions/std/exec/src/gtfs-rt-interpreter-executor.ts +++ b/libs/extensions/std/exec/src/gtfs-rt-interpreter-executor.ts @@ -35,10 +35,19 @@ export class GtfsRTInterpreterExecutor extends AbstractBlockExecutor< const entity = context.getPropertyValue('entity', PrimitiveValuetypes.Text); // https://github.com/MobilityData/gtfs-realtime-bindings/tree/master/nodejs - const feedMessage = - GtfsRealtimeBindings.transit_realtime.FeedMessage.decode( + let feedMessage; + try { + feedMessage = GtfsRealtimeBindings.transit_realtime.FeedMessage.decode( new Uint8Array(inputFile.content), ); + } catch (e) { + return Promise.resolve( + R.err({ + message: `Failed to decode gtfs file: ${this.getErrorMessage(e)}`, + diagnostic: { node: context.getCurrentNode() }, + }), + ); + } // Parse all possible feedentity to Sheet const sheet = await this.parseFeedMessage(entity, feedMessage, context); @@ -53,6 +62,13 @@ export class GtfsRTInterpreterExecutor extends AbstractBlockExecutor< return R.ok(sheet.right); } + private getErrorMessage(e: unknown): string { + if (e instanceof Error) { + return e.message; + } + return String(e); + } + private async parseFeedMessage( entityType: string, feedMessage: GtfsRealtimeBindings.transit_realtime.FeedMessage, From 784c5208b0dc415ff5d5da0028512f9749c97b1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20M=C3=BCller?= Date: Mon, 9 Oct 2023 11:50:10 +0200 Subject: [PATCH 11/31] Added tests for gtfs-rt-interpreter --- .../src/gtfs-rt-interpreter-executor.spec.ts | 171 ++++++++++++++++++ .../gtfs/invalid-gtfs | 1 + .../gtfs/valid-alerts.json | Bin 0 -> 111 bytes .../gtfs/valid-alerts.json.license | 3 + .../gtfs/valid-trip-update | Bin 0 -> 738 bytes .../gtfs/valid-trip-update.license | 3 + .../gtfs/valid-vehicle | Bin 0 -> 86 bytes .../gtfs/valid-vehicle.license | 3 + .../invalid-entity-parameter.jv | 18 ++ .../valid-alerts-gtfs-interpreter.jv | 18 ++ .../valid-trip-update-gtfs-interpreter.jv | 18 ++ .../valid-vehicle-gtfs-interpreter.jv | 18 ++ 12 files changed, 253 insertions(+) create mode 100644 libs/extensions/std/exec/src/gtfs-rt-interpreter-executor.spec.ts create mode 100644 libs/extensions/std/exec/test/assets/gtfs-rt-interpreter-executor/gtfs/invalid-gtfs create mode 100644 libs/extensions/std/exec/test/assets/gtfs-rt-interpreter-executor/gtfs/valid-alerts.json create mode 100644 libs/extensions/std/exec/test/assets/gtfs-rt-interpreter-executor/gtfs/valid-alerts.json.license create mode 100644 libs/extensions/std/exec/test/assets/gtfs-rt-interpreter-executor/gtfs/valid-trip-update create mode 100644 libs/extensions/std/exec/test/assets/gtfs-rt-interpreter-executor/gtfs/valid-trip-update.license create mode 100644 libs/extensions/std/exec/test/assets/gtfs-rt-interpreter-executor/gtfs/valid-vehicle create mode 100644 libs/extensions/std/exec/test/assets/gtfs-rt-interpreter-executor/gtfs/valid-vehicle.license create mode 100644 libs/extensions/std/exec/test/assets/gtfs-rt-interpreter-executor/invalid-entity-parameter.jv create mode 100644 libs/extensions/std/exec/test/assets/gtfs-rt-interpreter-executor/valid-alerts-gtfs-interpreter.jv create mode 100644 libs/extensions/std/exec/test/assets/gtfs-rt-interpreter-executor/valid-trip-update-gtfs-interpreter.jv create mode 100644 libs/extensions/std/exec/test/assets/gtfs-rt-interpreter-executor/valid-vehicle-gtfs-interpreter.jv diff --git a/libs/extensions/std/exec/src/gtfs-rt-interpreter-executor.spec.ts b/libs/extensions/std/exec/src/gtfs-rt-interpreter-executor.spec.ts new file mode 100644 index 000000000..e98f5453a --- /dev/null +++ b/libs/extensions/std/exec/src/gtfs-rt-interpreter-executor.spec.ts @@ -0,0 +1,171 @@ +// 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, + useExtension, +} from '@jvalue/jayvee-language-server'; +import { + ParseHelperOptions, + TestLangExtension, + expectNoParserAndLexerErrors, + parseHelper, + readJvTestAssetHelper, +} from '@jvalue/jayvee-language-server/test'; +import { AstNode, AstNodeLocator, LangiumDocument } from 'langium'; +import { NodeFileSystem } from 'langium/node'; + +import { createBinaryFileFromLocalFile } from '../test'; + +import { GtfsRTInterpreterExecutor } from './gtfs-rt-interpreter-executor'; + +describe('Validation of GtfsRTInterpreterExecutor', () => { + let parse: ( + input: string, + options?: ParseHelperOptions, + ) => Promise>; + + let locator: AstNodeLocator; + + const readJvTestAsset = readJvTestAssetHelper( + __dirname, + '../test/assets/gtfs-rt-interpreter-executor/', + ); + + function readTestFile(fileName: string): R.BinaryFile { + const absoluteFileName = path.resolve( + __dirname, + '../test/assets/gtfs-rt-interpreter-executor/gtfs/', + fileName, + ); + return createBinaryFileFromLocalFile(absoluteFileName); + } + + async function parseAndExecuteExecutor( + input: string, + IOInput: R.BinaryFile, + ): Promise> { + const document = await parse(input, { validationChecks: 'all' }); + expectNoParserAndLexerErrors(document); + + const block = locator.getAstNode( + document.parseResult.value, + 'pipelines@0/blocks@1', + ) as BlockDefinition; + + return new GtfsRTInterpreterExecutor().doExecute( + IOInput, + getTestExecutionContext(locator, document, [block]), + ); + } + + beforeAll(() => { + // Register test extension + useExtension(new TestLangExtension()); + // Create language services + const services = createJayveeServices(NodeFileSystem).Jayvee; + locator = services.workspace.AstNodeLocator; + // Parse function for Jayvee (without validation) + parse = parseHelper(services); + }); + + it('should diagnose no error on valid trip update gtfs file', async () => { + const text = readJvTestAsset('valid-trip-update-gtfs-interpreter.jv'); + + const testFile = readTestFile('valid-trip-update'); + const result = await parseAndExecuteExecutor(text, testFile); + + expect(R.isErr(result)).toEqual(false); + if (R.isOk(result)) { + expect(result.right.ioType).toEqual(IOType.SHEET); + expect(result.right.getNumberOfColumns()).toEqual(10); + expect(result.right.getNumberOfRows()).toEqual(23); + expect(result.right.getData()[0]).toContain( + 'entity.trip_update.trip.trip_id', + ); + } + }); + + it('should diagnose no error on valid alert gtfs file', async () => { + const text = readJvTestAsset('valid-alerts-gtfs-interpreter.jv'); + + const testFile = readTestFile('valid-alerts.json'); + const result = await parseAndExecuteExecutor(text, testFile); + + expect(R.isErr(result)).toEqual(false); + if (R.isOk(result)) { + expect(result.right.ioType).toEqual(IOType.SHEET); + expect(result.right.getNumberOfColumns()).toEqual(7); + expect(result.right.getNumberOfRows()).toEqual(2); + expect(result.right.getData()[0]).toContain( + 'entity.alert.informed_entity.route_id', + ); + } + }); + + it('should diagnose no error on valid vehicle gtfs file', async () => { + const text = readJvTestAsset('valid-vehicle-gtfs-interpreter.jv'); + + const testFile = readTestFile('valid-vehicle'); + const result = await parseAndExecuteExecutor(text, testFile); + + expect(R.isErr(result)).toEqual(false); + if (R.isOk(result)) { + expect(result.right.ioType).toEqual(IOType.SHEET); + expect(result.right.getNumberOfColumns()).toEqual(10); + expect(result.right.getNumberOfRows()).toEqual(2); + expect(result.right.getData()[0]).toContain( + 'entity.vehicle_position.vehicle_descriptor.id', + ); + } + }); + + it('should diagnose no error on wrong gtfs file for specified entity parameter', async () => { + const text = readJvTestAsset('valid-trip-update-gtfs-interpreter.jv'); + + const testFile = readTestFile('valid-alerts.json'); + const result = await parseAndExecuteExecutor(text, testFile); + + expect(R.isErr(result)).toEqual(false); + if (R.isOk(result)) { + expect(result.right.ioType).toEqual(IOType.SHEET); + expect(result.right.getNumberOfColumns()).toEqual(10); + expect(result.right.getNumberOfRows()).toEqual(1); // only header row + } + }); + + it('should diagnose no error on invalid entity parameter', async () => { + const text = readJvTestAsset('invalid-entity-parameter.jv'); + + const testFile = readTestFile('valid-trip-update'); + const result = await parseAndExecuteExecutor(text, testFile); + + expect(R.isOk(result)).toEqual(false); + if (R.isErr(result)) { + expect(result.left.message).toEqual( + 'Entity invalid not allowed for block GtfsRTInterpreterblock, expected "trip_update", "alert" or "vehicle".', + ); + } + }); + + it('should diagnose no error on invalid gtfs file input', async () => { + const text = readJvTestAsset('invalid-entity-parameter.jv'); + + const testFile = readTestFile('invalid-gtfs'); + const result = await parseAndExecuteExecutor(text, testFile); + + expect(R.isOk(result)).toEqual(false); + if (R.isErr(result)) { + expect(result.left.message).toEqual( + 'Failed to decode gtfs file: invalid wire type 4 at offset 1', + ); + } + }); +}); diff --git a/libs/extensions/std/exec/test/assets/gtfs-rt-interpreter-executor/gtfs/invalid-gtfs b/libs/extensions/std/exec/test/assets/gtfs-rt-interpreter-executor/gtfs/invalid-gtfs new file mode 100644 index 000000000..5a9d444be --- /dev/null +++ b/libs/extensions/std/exec/test/assets/gtfs-rt-interpreter-executor/gtfs/invalid-gtfs @@ -0,0 +1 @@ +This is not a gtfs file diff --git a/libs/extensions/std/exec/test/assets/gtfs-rt-interpreter-executor/gtfs/valid-alerts.json b/libs/extensions/std/exec/test/assets/gtfs-rt-interpreter-executor/gtfs/valid-alerts.json new file mode 100644 index 0000000000000000000000000000000000000000..aebc307df9803df3b90e391dc9e4a446591b2c50 GIT binary patch literal 111 zcmd<$?klPOL&Iv9!=#qGcfgrkL0qFZM-WBdS4Ob&hk|4gW$qb|C+ zIB4SHV4|Dx3mC)f@7^B7=}GhCz4rQ8vsNa*oSRQA4Ey&z!|rCR*@OMvy$yG@m@l}w zb>}y2%~@>pxRiE__99E!#{BoiL(gzDIV*+2-xRS+c7p8tWnw|jHakt}?ZBqVK3*jj zuminwh}N=&E8-f9bSvmM1Ekrv4pEkVezg>z>} zerXAE){eGHQoZ#l{V&8yVXffYjYFtM3X!uNgg89WpQgx-ay5*_D8oQIkh50DYe(KV z!>6_&XHnb?YZbCtWayqI=Yrg%;4ntE*BV!YD j6D=k~10jB1^);4GqI>z}56Chw=s0UIIB|1v!gT-uMwJpA literal 0 HcmV?d00001 diff --git a/libs/extensions/std/exec/test/assets/gtfs-rt-interpreter-executor/gtfs/valid-vehicle.license b/libs/extensions/std/exec/test/assets/gtfs-rt-interpreter-executor/gtfs/valid-vehicle.license new file mode 100644 index 000000000..17c5d2bad --- /dev/null +++ b/libs/extensions/std/exec/test/assets/gtfs-rt-interpreter-executor/gtfs/valid-vehicle.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg + +SPDX-License-Identifier: AGPL-3.0-only diff --git a/libs/extensions/std/exec/test/assets/gtfs-rt-interpreter-executor/invalid-entity-parameter.jv b/libs/extensions/std/exec/test/assets/gtfs-rt-interpreter-executor/invalid-entity-parameter.jv new file mode 100644 index 000000000..1b8d7472d --- /dev/null +++ b/libs/extensions/std/exec/test/assets/gtfs-rt-interpreter-executor/invalid-entity-parameter.jv @@ -0,0 +1,18 @@ +// SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg +// +// SPDX-License-Identifier: AGPL-3.0-only + +pipeline TestPipeline { + + block TestExtractor oftype TestFileExtractor { + } + + block TestBlock oftype GtfsRTInterpreter { + entity: 'invalid'; + } + + block TestLoader oftype TestSheetLoader { + } + + TestExtractor -> TestBlock -> TestLoader; +} diff --git a/libs/extensions/std/exec/test/assets/gtfs-rt-interpreter-executor/valid-alerts-gtfs-interpreter.jv b/libs/extensions/std/exec/test/assets/gtfs-rt-interpreter-executor/valid-alerts-gtfs-interpreter.jv new file mode 100644 index 000000000..10b666a39 --- /dev/null +++ b/libs/extensions/std/exec/test/assets/gtfs-rt-interpreter-executor/valid-alerts-gtfs-interpreter.jv @@ -0,0 +1,18 @@ +// SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg +// +// SPDX-License-Identifier: AGPL-3.0-only + +pipeline TestPipeline { + + block TestExtractor oftype TestFileExtractor { + } + + block TestBlock oftype GtfsRTInterpreter { + entity: 'alert'; + } + + block TestLoader oftype TestSheetLoader { + } + + TestExtractor -> TestBlock -> TestLoader; +} diff --git a/libs/extensions/std/exec/test/assets/gtfs-rt-interpreter-executor/valid-trip-update-gtfs-interpreter.jv b/libs/extensions/std/exec/test/assets/gtfs-rt-interpreter-executor/valid-trip-update-gtfs-interpreter.jv new file mode 100644 index 000000000..e2decf141 --- /dev/null +++ b/libs/extensions/std/exec/test/assets/gtfs-rt-interpreter-executor/valid-trip-update-gtfs-interpreter.jv @@ -0,0 +1,18 @@ +// SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg +// +// SPDX-License-Identifier: AGPL-3.0-only + +pipeline TestPipeline { + + block TestExtractor oftype TestFileExtractor { + } + + block TestBlock oftype GtfsRTInterpreter { + entity: 'trip_update'; + } + + block TestLoader oftype TestSheetLoader { + } + + TestExtractor -> TestBlock -> TestLoader; +} diff --git a/libs/extensions/std/exec/test/assets/gtfs-rt-interpreter-executor/valid-vehicle-gtfs-interpreter.jv b/libs/extensions/std/exec/test/assets/gtfs-rt-interpreter-executor/valid-vehicle-gtfs-interpreter.jv new file mode 100644 index 000000000..0f9be12a0 --- /dev/null +++ b/libs/extensions/std/exec/test/assets/gtfs-rt-interpreter-executor/valid-vehicle-gtfs-interpreter.jv @@ -0,0 +1,18 @@ +// SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg +// +// SPDX-License-Identifier: AGPL-3.0-only + +pipeline TestPipeline { + + block TestExtractor oftype TestFileExtractor { + } + + block TestBlock oftype GtfsRTInterpreter { + entity: 'vehicle'; + } + + block TestLoader oftype TestSheetLoader { + } + + TestExtractor -> TestBlock -> TestLoader; +} From 10f373046965275dbc28e910d64c2727e8e725c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20M=C3=BCller?= Date: Mon, 9 Oct 2023 11:57:38 +0200 Subject: [PATCH 12/31] Added missing licenses --- .../invalid-corrupt-zip.zip.license | 3 +++ .../assets/archive-interpreter-executor/valid-7z.7z.license | 3 +++ .../assets/archive-interpreter-executor/valid-gz.gz.license | 3 +++ .../assets/archive-interpreter-executor/valid-zip.zip.license | 3 +++ .../std/exec/test/assets/file-picker-executor/test.txt.license | 3 +++ .../gtfs-rt-interpreter-executor/gtfs/invalid-gtfs.license | 3 +++ 6 files changed, 18 insertions(+) create mode 100644 libs/extensions/std/exec/test/assets/archive-interpreter-executor/invalid-corrupt-zip.zip.license create mode 100644 libs/extensions/std/exec/test/assets/archive-interpreter-executor/valid-7z.7z.license create mode 100644 libs/extensions/std/exec/test/assets/archive-interpreter-executor/valid-gz.gz.license create mode 100644 libs/extensions/std/exec/test/assets/archive-interpreter-executor/valid-zip.zip.license create mode 100644 libs/extensions/std/exec/test/assets/file-picker-executor/test.txt.license create mode 100644 libs/extensions/std/exec/test/assets/gtfs-rt-interpreter-executor/gtfs/invalid-gtfs.license diff --git a/libs/extensions/std/exec/test/assets/archive-interpreter-executor/invalid-corrupt-zip.zip.license b/libs/extensions/std/exec/test/assets/archive-interpreter-executor/invalid-corrupt-zip.zip.license new file mode 100644 index 000000000..17c5d2bad --- /dev/null +++ b/libs/extensions/std/exec/test/assets/archive-interpreter-executor/invalid-corrupt-zip.zip.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg + +SPDX-License-Identifier: AGPL-3.0-only diff --git a/libs/extensions/std/exec/test/assets/archive-interpreter-executor/valid-7z.7z.license b/libs/extensions/std/exec/test/assets/archive-interpreter-executor/valid-7z.7z.license new file mode 100644 index 000000000..17c5d2bad --- /dev/null +++ b/libs/extensions/std/exec/test/assets/archive-interpreter-executor/valid-7z.7z.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg + +SPDX-License-Identifier: AGPL-3.0-only diff --git a/libs/extensions/std/exec/test/assets/archive-interpreter-executor/valid-gz.gz.license b/libs/extensions/std/exec/test/assets/archive-interpreter-executor/valid-gz.gz.license new file mode 100644 index 000000000..17c5d2bad --- /dev/null +++ b/libs/extensions/std/exec/test/assets/archive-interpreter-executor/valid-gz.gz.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg + +SPDX-License-Identifier: AGPL-3.0-only diff --git a/libs/extensions/std/exec/test/assets/archive-interpreter-executor/valid-zip.zip.license b/libs/extensions/std/exec/test/assets/archive-interpreter-executor/valid-zip.zip.license new file mode 100644 index 000000000..17c5d2bad --- /dev/null +++ b/libs/extensions/std/exec/test/assets/archive-interpreter-executor/valid-zip.zip.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg + +SPDX-License-Identifier: AGPL-3.0-only diff --git a/libs/extensions/std/exec/test/assets/file-picker-executor/test.txt.license b/libs/extensions/std/exec/test/assets/file-picker-executor/test.txt.license new file mode 100644 index 000000000..17c5d2bad --- /dev/null +++ b/libs/extensions/std/exec/test/assets/file-picker-executor/test.txt.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg + +SPDX-License-Identifier: AGPL-3.0-only diff --git a/libs/extensions/std/exec/test/assets/gtfs-rt-interpreter-executor/gtfs/invalid-gtfs.license b/libs/extensions/std/exec/test/assets/gtfs-rt-interpreter-executor/gtfs/invalid-gtfs.license new file mode 100644 index 000000000..17c5d2bad --- /dev/null +++ b/libs/extensions/std/exec/test/assets/gtfs-rt-interpreter-executor/gtfs/invalid-gtfs.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg + +SPDX-License-Identifier: AGPL-3.0-only From d501632cbb8cc0b3a4a56fd7bcde8da624e247e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20M=C3=BCller?= Date: Mon, 9 Oct 2023 12:38:16 +0200 Subject: [PATCH 13/31] Removed duplicate expect --- libs/extensions/std/exec/src/file-picker-executor.spec.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/libs/extensions/std/exec/src/file-picker-executor.spec.ts b/libs/extensions/std/exec/src/file-picker-executor.spec.ts index 1b82a3b2a..c65ec4625 100644 --- a/libs/extensions/std/exec/src/file-picker-executor.spec.ts +++ b/libs/extensions/std/exec/src/file-picker-executor.spec.ts @@ -92,7 +92,6 @@ describe('Validation of FilePickerExecutor', () => { expect(R.isErr(result)).toEqual(false); if (R.isOk(result)) { - expect(result.right?.ioType).toEqual(IOType.FILE); expect(result.right).toEqual( expect.objectContaining({ name: 'test.txt', From da3871a85dcca4a1f72a4457a55f4b80e96abab1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20M=C3=BCller?= Date: Mon, 9 Oct 2023 12:57:58 +0200 Subject: [PATCH 14/31] Added missing stdLangExtension import --- .../std/exec/src/archive-interpreter-executor.spec.ts | 4 +++- libs/extensions/std/exec/src/file-picker-executor.spec.ts | 4 +++- .../std/exec/src/gtfs-rt-interpreter-executor.spec.ts | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/libs/extensions/std/exec/src/archive-interpreter-executor.spec.ts b/libs/extensions/std/exec/src/archive-interpreter-executor.spec.ts index ea00693c2..060b52aba 100644 --- a/libs/extensions/std/exec/src/archive-interpreter-executor.spec.ts +++ b/libs/extensions/std/exec/src/archive-interpreter-executor.spec.ts @@ -6,6 +6,7 @@ import * as path from 'path'; import * as R from '@jvalue/jayvee-execution'; import { getTestExecutionContext } from '@jvalue/jayvee-execution/test'; +import { StdLangExtension } from '@jvalue/jayvee-extensions/std/lang'; import { BlockDefinition, IOType, @@ -67,7 +68,8 @@ describe('Validation of ArchiveInterpreterExecutor', () => { } beforeAll(() => { - // Register test extension + // Register extensions + useExtension(new StdLangExtension()); useExtension(new TestLangExtension()); // Create language services const services = createJayveeServices(NodeFileSystem).Jayvee; diff --git a/libs/extensions/std/exec/src/file-picker-executor.spec.ts b/libs/extensions/std/exec/src/file-picker-executor.spec.ts index c65ec4625..e4d49c698 100644 --- a/libs/extensions/std/exec/src/file-picker-executor.spec.ts +++ b/libs/extensions/std/exec/src/file-picker-executor.spec.ts @@ -6,6 +6,7 @@ import * as path from 'path'; import * as R from '@jvalue/jayvee-execution'; import { getTestExecutionContext } from '@jvalue/jayvee-execution/test'; +import { StdLangExtension } from '@jvalue/jayvee-extensions/std/lang'; import { BlockDefinition, IOType, @@ -71,7 +72,8 @@ describe('Validation of FilePickerExecutor', () => { } beforeAll(() => { - // Register test extension + // Register extensions + useExtension(new StdLangExtension()); useExtension(new TestLangExtension()); // Create language services const services = createJayveeServices(NodeFileSystem).Jayvee; diff --git a/libs/extensions/std/exec/src/gtfs-rt-interpreter-executor.spec.ts b/libs/extensions/std/exec/src/gtfs-rt-interpreter-executor.spec.ts index e98f5453a..28b16b747 100644 --- a/libs/extensions/std/exec/src/gtfs-rt-interpreter-executor.spec.ts +++ b/libs/extensions/std/exec/src/gtfs-rt-interpreter-executor.spec.ts @@ -6,6 +6,7 @@ import * as path from 'path'; import * as R from '@jvalue/jayvee-execution'; import { getTestExecutionContext } from '@jvalue/jayvee-execution/test'; +import { StdLangExtension } from '@jvalue/jayvee-extensions/std/lang'; import { BlockDefinition, IOType, @@ -67,7 +68,8 @@ describe('Validation of GtfsRTInterpreterExecutor', () => { } beforeAll(() => { - // Register test extension + // Register extensions + useExtension(new StdLangExtension()); useExtension(new TestLangExtension()); // Create language services const services = createJayveeServices(NodeFileSystem).Jayvee; From bef13e971bd62e91da81f3b13815a418ccb714d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20M=C3=BCller?= Date: Mon, 9 Oct 2023 13:02:29 +0200 Subject: [PATCH 15/31] Fixed createBinaryFileFromLocalFile not inserting files --- libs/extensions/std/exec/test/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/extensions/std/exec/test/utils.ts b/libs/extensions/std/exec/test/utils.ts index 1fd817a1c..3b5584775 100644 --- a/libs/extensions/std/exec/test/utils.ts +++ b/libs/extensions/std/exec/test/utils.ts @@ -22,5 +22,5 @@ export function createBinaryFileFromLocalFile(fileName: string): BinaryFile { const file = readFileSync( path.resolve(__dirname, '../test/assets/file-picker-executor/', fileName), ); - return new BinaryFile(fileName, fileExtension, mimeType, file); + return new BinaryFile(path.basename(fileName), fileExtension, mimeType, file); } From c853d302df01c5bb0d20c001a4e96837830f9b8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20M=C3=BCller?= Date: Mon, 9 Oct 2023 13:03:36 +0200 Subject: [PATCH 16/31] Started with HttpExtractorExecutor tests --- .../exec/src/http-extractor-executor.spec.ts | 141 ++++++++++++++++++ .../assets/http-extractor-executor/test.txt | 1 + .../http-extractor-executor/test.txt.license | 3 + .../http-extractor-executor/valid-http.jv | 18 +++ .../http-extractor-executor/valid-https.jv | 18 +++ 5 files changed, 181 insertions(+) create mode 100644 libs/extensions/std/exec/src/http-extractor-executor.spec.ts create mode 100644 libs/extensions/std/exec/test/assets/http-extractor-executor/test.txt create mode 100644 libs/extensions/std/exec/test/assets/http-extractor-executor/test.txt.license create mode 100644 libs/extensions/std/exec/test/assets/http-extractor-executor/valid-http.jv create mode 100644 libs/extensions/std/exec/test/assets/http-extractor-executor/valid-https.jv diff --git a/libs/extensions/std/exec/src/http-extractor-executor.spec.ts b/libs/extensions/std/exec/src/http-extractor-executor.spec.ts new file mode 100644 index 000000000..8acc79d77 --- /dev/null +++ b/libs/extensions/std/exec/src/http-extractor-executor.spec.ts @@ -0,0 +1,141 @@ +// 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 { StdLangExtension } from '@jvalue/jayvee-extensions/std/lang'; +import { + BlockDefinition, + IOType, + createJayveeServices, + useExtension, +} from '@jvalue/jayvee-language-server'; +import { + ParseHelperOptions, + TestLangExtension, + expectNoParserAndLexerErrors, + parseHelper, + readJvTestAssetHelper, +} from '@jvalue/jayvee-language-server/test'; +import { AstNode, AstNodeLocator, LangiumDocument } from 'langium'; +import { NodeFileSystem } from 'langium/node'; +import * as nock from 'nock'; + +import { HttpExtractorExecutor } from './http-extractor-executor'; + +describe('Validation of HttpExtractorExecutor', () => { + let parse: ( + input: string, + options?: ParseHelperOptions, + ) => Promise>; + + let locator: AstNodeLocator; + + const readJvTestAsset = readJvTestAssetHelper( + __dirname, + '../test/assets/http-extractor-executor/', + ); + + async function parseAndExecuteExecutor( + input: string, + ): Promise> { + const document = await parse(input, { validationChecks: 'all' }); + expectNoParserAndLexerErrors(document); + + const block = locator.getAstNode( + document.parseResult.value, + 'pipelines@0/blocks@1', + ) as BlockDefinition; + + return new HttpExtractorExecutor().doExecute( + R.NONE, + getTestExecutionContext(locator, document, [block]), + ); + } + + beforeAll(() => { + // Register extensions + useExtension(new StdLangExtension()); + useExtension(new TestLangExtension()); + // Create language services + const services = createJayveeServices(NodeFileSystem).Jayvee; + locator = services.workspace.AstNodeLocator; + // Parse function for Jayvee (without validation) + parse = parseHelper(services); + }); + + afterEach(() => { + nock.restore(); + }); + + it('should diagnose no error on valid http url', async () => { + const text = readJvTestAsset('valid-http.jv'); + nock('http://localhost') + .get('/test.txt') + .replyWithFile( + 200, + path.resolve( + __dirname, + '../test/assets/http-extractor-executor/test.txt', + ), + { + 'Content-Type': 'text/plain', + }, + ); + + const result = await parseAndExecuteExecutor(text); + + 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.APPLICATION_OCTET_STREAM, + }), + ); + } + }); + + it('should diagnose no error on valid https url', async () => { + const text = readJvTestAsset('valid-https.jv'); + nock('https://localhost') + .get('/test.txt') + .replyWithFile( + 200, + path.resolve( + __dirname, + '../test/assets/http-extractor-executor/test.txt', + ), + { + 'Content-Type': 'text/plain', + }, + ); + + const result = await parseAndExecuteExecutor(text); + + 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.APPLICATION_OCTET_STREAM, + }), + ); + } + }); + + /* it('should diagnose no error on retries exceeded', () => {}); + + it('should diagnose no error on url not found', () => {}); + + it('should diagnose no error on download error', () => {}); + + it('should diagnose no error on ignoring redirects', () => {});*/ +}); diff --git a/libs/extensions/std/exec/test/assets/http-extractor-executor/test.txt b/libs/extensions/std/exec/test/assets/http-extractor-executor/test.txt new file mode 100644 index 000000000..4fff881e8 --- /dev/null +++ b/libs/extensions/std/exec/test/assets/http-extractor-executor/test.txt @@ -0,0 +1 @@ +Test File diff --git a/libs/extensions/std/exec/test/assets/http-extractor-executor/test.txt.license b/libs/extensions/std/exec/test/assets/http-extractor-executor/test.txt.license new file mode 100644 index 000000000..17c5d2bad --- /dev/null +++ b/libs/extensions/std/exec/test/assets/http-extractor-executor/test.txt.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg + +SPDX-License-Identifier: AGPL-3.0-only diff --git a/libs/extensions/std/exec/test/assets/http-extractor-executor/valid-http.jv b/libs/extensions/std/exec/test/assets/http-extractor-executor/valid-http.jv new file mode 100644 index 000000000..e932e7875 --- /dev/null +++ b/libs/extensions/std/exec/test/assets/http-extractor-executor/valid-http.jv @@ -0,0 +1,18 @@ +// SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg +// +// SPDX-License-Identifier: AGPL-3.0-only + +pipeline TestPipeline { + + block TestExtractor oftype TestFileExtractor { + } + + block TestBlock oftype HttpExtractor { + url: 'http://localhost/test.txt'; + } + + block TestLoader oftype TestSheetLoader { + } + + TestExtractor -> TestBlock -> TestLoader; +} diff --git a/libs/extensions/std/exec/test/assets/http-extractor-executor/valid-https.jv b/libs/extensions/std/exec/test/assets/http-extractor-executor/valid-https.jv new file mode 100644 index 000000000..cdc9ef43d --- /dev/null +++ b/libs/extensions/std/exec/test/assets/http-extractor-executor/valid-https.jv @@ -0,0 +1,18 @@ +// SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg +// +// SPDX-License-Identifier: AGPL-3.0-only + +pipeline TestPipeline { + + block TestExtractor oftype TestFileExtractor { + } + + block TestBlock oftype HttpExtractor { + url: 'https://localhost/test.txt'; + } + + block TestLoader oftype TestSheetLoader { + } + + TestExtractor -> TestBlock -> TestLoader; +} From ee2706ae0adaa376b82778963e92cda1a540e2ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20M=C3=BCller?= Date: Mon, 16 Oct 2023 09:30:20 +0200 Subject: [PATCH 17/31] Added onError for ClientRequest --- libs/extensions/std/exec/src/http-extractor-executor.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libs/extensions/std/exec/src/http-extractor-executor.ts b/libs/extensions/std/exec/src/http-extractor-executor.ts index 03534cfcb..91f8d9e71 100644 --- a/libs/extensions/std/exec/src/http-extractor-executor.ts +++ b/libs/extensions/std/exec/src/http-extractor-executor.ts @@ -193,6 +193,13 @@ export class HttpExtractorExecutor extends AbstractBlockExecutor< }), ); }); + }).on('error', (e: Error) => { + resolve( + R.err({ + message: e.message, + diagnostic: { node: context.getCurrentNode(), property: 'name' }, + }), + ); }); }); } From df3275b8d1060a9d1873fb72113f91534302784d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20M=C3=BCller?= Date: Mon, 16 Oct 2023 09:30:35 +0200 Subject: [PATCH 18/31] Added more tests and improved existing ones --- .../exec/src/http-extractor-executor.spec.ts | 91 +++++++++++++++++-- 1 file changed, 85 insertions(+), 6 deletions(-) diff --git a/libs/extensions/std/exec/src/http-extractor-executor.spec.ts b/libs/extensions/std/exec/src/http-extractor-executor.spec.ts index 8acc79d77..207a04b4b 100644 --- a/libs/extensions/std/exec/src/http-extractor-executor.spec.ts +++ b/libs/extensions/std/exec/src/http-extractor-executor.spec.ts @@ -71,9 +71,16 @@ describe('Validation of HttpExtractorExecutor', () => { nock.restore(); }); + beforeEach(() => { + if (!nock.isActive()) { + nock.activate(); + } + nock.cleanAll(); + }); + it('should diagnose no error on valid http url', async () => { const text = readJvTestAsset('valid-http.jv'); - nock('http://localhost') + const nockScope = nock('http://localhost') .get('/test.txt') .replyWithFile( 200, @@ -90,6 +97,7 @@ describe('Validation of HttpExtractorExecutor', () => { expect(R.isErr(result)).toEqual(false); if (R.isOk(result)) { + expect(nockScope.isDone()).toEqual(true); expect(result.right).toEqual( expect.objectContaining({ name: 'test.txt', @@ -103,7 +111,39 @@ describe('Validation of HttpExtractorExecutor', () => { it('should diagnose no error on valid https url', async () => { const text = readJvTestAsset('valid-https.jv'); - nock('https://localhost') + const nockScope = nock('https://localhost') + .get('/test.txt') + .replyWithFile( + 200, + path.resolve( + __dirname, + '../test/assets/http-extractor-executor/test.txt', + ), + { + 'Content-Type': 'text/plain', + }, + ); + + const result = await parseAndExecuteExecutor(text); + + expect(R.isErr(result)).toEqual(false); + if (R.isOk(result)) { + expect(nockScope.isDone()).toEqual(true); + expect(result.right).toEqual( + expect.objectContaining({ + name: 'test.txt', + extension: 'txt', + ioType: IOType.FILE, + mimeType: R.MimeType.APPLICATION_OCTET_STREAM, + }), + ); + } + }); + + it('should diagnose no error on retry', async () => { + const text = readJvTestAsset('valid-one-retry.jv'); + const nockScope404 = nock('https://localhost').get('/test.txt').reply(404); + const nockScope200 = nock('https://localhost') .get('/test.txt') .replyWithFile( 200, @@ -120,6 +160,8 @@ describe('Validation of HttpExtractorExecutor', () => { expect(R.isErr(result)).toEqual(false); if (R.isOk(result)) { + expect(nockScope404.isDone()).toEqual(true); + expect(nockScope200.isDone()).toEqual(true); expect(result.right).toEqual( expect.objectContaining({ name: 'test.txt', @@ -131,11 +173,48 @@ describe('Validation of HttpExtractorExecutor', () => { } }); - /* it('should diagnose no error on retries exceeded', () => {}); + it('should diagnose no error on url not found', async () => { + const text = readJvTestAsset('valid-http.jv'); + const nockScope = nock('http://localhost').get('/test.txt').reply(404); - it('should diagnose no error on url not found', () => {}); + const result = await parseAndExecuteExecutor(text); - it('should diagnose no error on download error', () => {}); + expect(R.isOk(result)).toEqual(false); + if (R.isErr(result)) { + expect(nockScope.isDone()).toEqual(true); + expect(result.left.message).toEqual( + 'HTTP fetch failed with code 404. Please check your connection.', + ); + } + }); + + it('should diagnose no error on ClientRequest error', async () => { + const text = readJvTestAsset('valid-https.jv'); + const nockScope = nock('https://localhost') + .get('/test.txt') + .replyWithError('Test error'); - it('should diagnose no error on ignoring redirects', () => {});*/ + const result = await parseAndExecuteExecutor(text); + + expect(R.isOk(result)).toEqual(false); + if (R.isErr(result)) { + expect(nockScope.isDone()).toEqual(true); + expect(result.left.message).toEqual('Test error'); + } + }); + + it('should diagnose no error on ignoring redirects', async () => { + const text = readJvTestAsset('valid-http.jv'); + const nockScope = nock('http://localhost').get('/test.txt').reply(301); + + const result = await parseAndExecuteExecutor(text); + + expect(R.isOk(result)).toEqual(false); + if (R.isErr(result)) { + expect(nockScope.isDone()).toEqual(true); + expect(result.left.message).toEqual( + 'HTTP fetch was redirected with code 301. Redirects are either disabled or maximum number of redirects was exeeded.', + ); + } + }); }); From 54fca192a7aa6a87c6821f4c195ad7a77f1e91f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20M=C3=BCller?= Date: Mon, 16 Oct 2023 09:46:09 +0200 Subject: [PATCH 19/31] Added missing test files to git --- .../valid-ignore-redirects.jv | 19 +++++++++++++++++++ .../valid-one-retry.jv | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 libs/extensions/std/exec/test/assets/http-extractor-executor/valid-ignore-redirects.jv create mode 100644 libs/extensions/std/exec/test/assets/http-extractor-executor/valid-one-retry.jv diff --git a/libs/extensions/std/exec/test/assets/http-extractor-executor/valid-ignore-redirects.jv b/libs/extensions/std/exec/test/assets/http-extractor-executor/valid-ignore-redirects.jv new file mode 100644 index 000000000..9b3793ba2 --- /dev/null +++ b/libs/extensions/std/exec/test/assets/http-extractor-executor/valid-ignore-redirects.jv @@ -0,0 +1,19 @@ +// SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg +// +// SPDX-License-Identifier: AGPL-3.0-only + +pipeline TestPipeline { + + block TestExtractor oftype TestFileExtractor { + } + + block TestBlock oftype HttpExtractor { + url: 'https://localhost/test.txt'; + followRedirects: false; + } + + block TestLoader oftype TestSheetLoader { + } + + TestExtractor -> TestBlock -> TestLoader; +} diff --git a/libs/extensions/std/exec/test/assets/http-extractor-executor/valid-one-retry.jv b/libs/extensions/std/exec/test/assets/http-extractor-executor/valid-one-retry.jv new file mode 100644 index 000000000..6760e797e --- /dev/null +++ b/libs/extensions/std/exec/test/assets/http-extractor-executor/valid-one-retry.jv @@ -0,0 +1,19 @@ +// SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg +// +// SPDX-License-Identifier: AGPL-3.0-only + +pipeline TestPipeline { + + block TestExtractor oftype TestFileExtractor { + } + + block TestBlock oftype HttpExtractor { + url: 'https://localhost/test.txt'; + retries: 1; + } + + block TestLoader oftype TestSheetLoader { + } + + TestExtractor -> TestBlock -> TestLoader; +} From aaf638d031d4ebfc0efb8a16a4ad93d73d80ef3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20M=C3=BCller?= Date: Mon, 16 Oct 2023 10:20:16 +0200 Subject: [PATCH 20/31] Added TextFileInterpreterExecutor tests --- .../text-file-interpreter-executor.spec.ts | 125 ++++++++++++++++++ .../gtfs-vehicle | Bin 0 -> 86 bytes .../gtfs-vehicle.license | 3 + .../text-file-interpreter-executor/test.txt | 2 + .../test.txt.license | 3 + .../valid-custom-line-break.jv | 18 +++ .../valid-default-file-interpreter.jv | 17 +++ 7 files changed, 168 insertions(+) create mode 100644 libs/extensions/std/exec/src/text-file-interpreter-executor.spec.ts create mode 100644 libs/extensions/std/exec/test/assets/text-file-interpreter-executor/gtfs-vehicle create mode 100644 libs/extensions/std/exec/test/assets/text-file-interpreter-executor/gtfs-vehicle.license create mode 100644 libs/extensions/std/exec/test/assets/text-file-interpreter-executor/test.txt create mode 100644 libs/extensions/std/exec/test/assets/text-file-interpreter-executor/test.txt.license create mode 100644 libs/extensions/std/exec/test/assets/text-file-interpreter-executor/valid-custom-line-break.jv create mode 100644 libs/extensions/std/exec/test/assets/text-file-interpreter-executor/valid-default-file-interpreter.jv diff --git a/libs/extensions/std/exec/src/text-file-interpreter-executor.spec.ts b/libs/extensions/std/exec/src/text-file-interpreter-executor.spec.ts new file mode 100644 index 000000000..c477fb9e3 --- /dev/null +++ b/libs/extensions/std/exec/src/text-file-interpreter-executor.spec.ts @@ -0,0 +1,125 @@ +// 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 { StdLangExtension } from '@jvalue/jayvee-extensions/std/lang'; +import { + BlockDefinition, + IOType, + createJayveeServices, + useExtension, +} from '@jvalue/jayvee-language-server'; +import { + ParseHelperOptions, + TestLangExtension, + expectNoParserAndLexerErrors, + parseHelper, + readJvTestAssetHelper, +} from '@jvalue/jayvee-language-server/test'; +import { AstNode, AstNodeLocator, LangiumDocument } from 'langium'; +import { NodeFileSystem } from 'langium/node'; + +import { createBinaryFileFromLocalFile } from '../test'; + +import { TextFileInterpreterExecutor } from './text-file-interpreter-executor'; + +describe('Validation of TextFileInterpreterExecutor', () => { + let parse: ( + input: string, + options?: ParseHelperOptions, + ) => Promise>; + + let locator: AstNodeLocator; + + const readJvTestAsset = readJvTestAssetHelper( + __dirname, + '../test/assets/text-file-interpreter-executor/', + ); + + function readTestFile(fileName: string): R.BinaryFile { + const absoluteFileName = path.resolve( + __dirname, + '../test/assets/text-file-interpreter-executor/', + fileName, + ); + return createBinaryFileFromLocalFile(absoluteFileName); + } + + async function parseAndExecuteExecutor( + input: string, + IOInput: R.BinaryFile, + ): Promise> { + const document = await parse(input, { validationChecks: 'all' }); + expectNoParserAndLexerErrors(document); + + const block = locator.getAstNode( + document.parseResult.value, + 'pipelines@0/blocks@1', + ) as BlockDefinition; + + return new TextFileInterpreterExecutor().doExecute( + IOInput, + getTestExecutionContext(locator, document, [block]), + ); + } + + beforeAll(() => { + // Register extensions + useExtension(new StdLangExtension()); + useExtension(new TestLangExtension()); + // Create language services + const services = createJayveeServices(NodeFileSystem).Jayvee; + locator = services.workspace.AstNodeLocator; + // Parse function for Jayvee (without validation) + parse = parseHelper(services); + }); + + it('should diagnose no error on valid text file', async () => { + const text = readJvTestAsset('valid-default-file-interpreter.jv'); + + const testFile = readTestFile('test.txt'); + const result = await parseAndExecuteExecutor(text, testFile); + + expect(R.isErr(result)).toEqual(false); + if (R.isOk(result)) { + expect(result.right.ioType).toEqual(IOType.TEXT_FILE); + expect(result.right.content).toEqual( + expect.arrayContaining(['Multiline ', 'Test File']), + ); + } + }); + + it('should diagnose no error on non text file', async () => { + const text = readJvTestAsset('valid-default-file-interpreter.jv'); + + const testFile = readTestFile('gtfs-vehicle'); + const result = await parseAndExecuteExecutor(text, testFile); + + expect(R.isErr(result)).toEqual(false); + if (R.isOk(result)) { + expect(result.right.ioType).toEqual(IOType.TEXT_FILE); + expect(result.right.content).toEqual( + expect.arrayContaining(['vehicle:268435857"0']), + ); + } + }); + + it('should diagnose no error on custom lineBreak', async () => { + const text = readJvTestAsset('valid-custom-line-break.jv'); + + const testFile = readTestFile('test.txt'); + const result = await parseAndExecuteExecutor(text, testFile); + + expect(R.isErr(result)).toEqual(false); + if (R.isOk(result)) { + expect(result.right.ioType).toEqual(IOType.TEXT_FILE); + expect(result.right.content).toEqual( + expect.arrayContaining(['Multiline \nTest', 'File\n']), + ); + } + }); +}); diff --git a/libs/extensions/std/exec/test/assets/text-file-interpreter-executor/gtfs-vehicle b/libs/extensions/std/exec/test/assets/text-file-interpreter-executor/gtfs-vehicle new file mode 100644 index 0000000000000000000000000000000000000000..944ad0dccc964594e7d979d9fe6670b6a292b1a8 GIT binary patch literal 86 zcmd<$%;4ntE*BV!YD j6D=k~10jB1^);4GqI>z}56Chw=s0UIIB|1v!gT-uMwJpA literal 0 HcmV?d00001 diff --git a/libs/extensions/std/exec/test/assets/text-file-interpreter-executor/gtfs-vehicle.license b/libs/extensions/std/exec/test/assets/text-file-interpreter-executor/gtfs-vehicle.license new file mode 100644 index 000000000..17c5d2bad --- /dev/null +++ b/libs/extensions/std/exec/test/assets/text-file-interpreter-executor/gtfs-vehicle.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg + +SPDX-License-Identifier: AGPL-3.0-only diff --git a/libs/extensions/std/exec/test/assets/text-file-interpreter-executor/test.txt b/libs/extensions/std/exec/test/assets/text-file-interpreter-executor/test.txt new file mode 100644 index 000000000..b118aec1c --- /dev/null +++ b/libs/extensions/std/exec/test/assets/text-file-interpreter-executor/test.txt @@ -0,0 +1,2 @@ +Multiline +Test File diff --git a/libs/extensions/std/exec/test/assets/text-file-interpreter-executor/test.txt.license b/libs/extensions/std/exec/test/assets/text-file-interpreter-executor/test.txt.license new file mode 100644 index 000000000..17c5d2bad --- /dev/null +++ b/libs/extensions/std/exec/test/assets/text-file-interpreter-executor/test.txt.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg + +SPDX-License-Identifier: AGPL-3.0-only diff --git a/libs/extensions/std/exec/test/assets/text-file-interpreter-executor/valid-custom-line-break.jv b/libs/extensions/std/exec/test/assets/text-file-interpreter-executor/valid-custom-line-break.jv new file mode 100644 index 000000000..cb5aa5ce0 --- /dev/null +++ b/libs/extensions/std/exec/test/assets/text-file-interpreter-executor/valid-custom-line-break.jv @@ -0,0 +1,18 @@ +// SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg +// +// SPDX-License-Identifier: AGPL-3.0-only + +pipeline TestPipeline { + + block TestExtractor oftype TestFileExtractor { + } + + block TestBlock oftype TextFileInterpreter { + lineBreak: / /; + } + + block TestLoader oftype TestTextFileLoader { + } + + TestExtractor -> TestBlock -> TestLoader; +} diff --git a/libs/extensions/std/exec/test/assets/text-file-interpreter-executor/valid-default-file-interpreter.jv b/libs/extensions/std/exec/test/assets/text-file-interpreter-executor/valid-default-file-interpreter.jv new file mode 100644 index 000000000..864a10d69 --- /dev/null +++ b/libs/extensions/std/exec/test/assets/text-file-interpreter-executor/valid-default-file-interpreter.jv @@ -0,0 +1,17 @@ +// SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg +// +// SPDX-License-Identifier: AGPL-3.0-only + +pipeline TestPipeline { + + block TestExtractor oftype TestFileExtractor { + } + + block TestBlock oftype TextFileInterpreter { + } + + block TestLoader oftype TestTextFileLoader { + } + + TestExtractor -> TestBlock -> TestLoader; +} From 3ee0cfcd78d1ea35ddf00c9cd0cc04e1b765e2d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20M=C3=BCller?= Date: Mon, 16 Oct 2023 10:50:54 +0200 Subject: [PATCH 21/31] - Moved splitLines logic into separate string-utils for test reusage - Added test util function for creating TEXT_FILE from local file --- libs/extensions/std/exec/src/string-util.ts | 14 ++++++++++ .../src/text-file-interpreter-executor.ts | 13 ++------- libs/extensions/std/exec/test/utils.ts | 28 ++++++++++++++++++- 3 files changed, 43 insertions(+), 12 deletions(-) create mode 100644 libs/extensions/std/exec/src/string-util.ts diff --git a/libs/extensions/std/exec/src/string-util.ts b/libs/extensions/std/exec/src/string-util.ts new file mode 100644 index 000000000..55b7d78b0 --- /dev/null +++ b/libs/extensions/std/exec/src/string-util.ts @@ -0,0 +1,14 @@ +// SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg +// +// SPDX-License-Identifier: AGPL-3.0-only + +export function splitLines(textContent: string, lineBreak: RegExp): string[] { + const lines = textContent.split(lineBreak); + + // There may be an additional empty line due to the previous splitting + if (lines[lines.length - 1] === '') { + lines.splice(lines.length - 1, 1); + } + + return lines; +} diff --git a/libs/extensions/std/exec/src/text-file-interpreter-executor.ts b/libs/extensions/std/exec/src/text-file-interpreter-executor.ts index 3efe2e9c1..c265aae3a 100644 --- a/libs/extensions/std/exec/src/text-file-interpreter-executor.ts +++ b/libs/extensions/std/exec/src/text-file-interpreter-executor.ts @@ -15,6 +15,8 @@ import { } from '@jvalue/jayvee-execution'; import { IOType, PrimitiveValuetypes } from '@jvalue/jayvee-language-server'; +import { splitLines } from './string-util'; + @implementsStatic() export class TextFileInterpreterExecutor extends AbstractBlockExecutor< IOType.FILE, @@ -57,14 +59,3 @@ export class TextFileInterpreterExecutor extends AbstractBlockExecutor< return R.ok(new TextFile(file.name, file.extension, file.mimeType, lines)); } } - -function splitLines(textContent: string, lineBreak: RegExp): string[] { - const lines = textContent.split(lineBreak); - - // There may be an additional empty line due to the previous splitting - if (lines[lines.length - 1] === '') { - lines.splice(lines.length - 1, 1); - } - - return lines; -} diff --git a/libs/extensions/std/exec/test/utils.ts b/libs/extensions/std/exec/test/utils.ts index 3b5584775..594b80d75 100644 --- a/libs/extensions/std/exec/test/utils.ts +++ b/libs/extensions/std/exec/test/utils.ts @@ -5,12 +5,18 @@ import { readFileSync } from 'fs'; import * as path from 'path'; -import { BinaryFile, FileExtension, MimeType } from '@jvalue/jayvee-execution'; +import { + BinaryFile, + FileExtension, + MimeType, + TextFile, +} from '@jvalue/jayvee-execution'; import { inferFileExtensionFromFileExtensionString, inferMimeTypeFromContentTypeString, } from '../src/file-util'; +import { splitLines } from '../src/string-util'; export function createBinaryFileFromLocalFile(fileName: string): BinaryFile { const extName = path.extname(fileName); @@ -24,3 +30,23 @@ export function createBinaryFileFromLocalFile(fileName: string): BinaryFile { ); return new BinaryFile(path.basename(fileName), fileExtension, mimeType, file); } + +export function createTextFileFromLocalFile(fileName: string): TextFile { + const extName = path.extname(fileName); + const mimeType = + inferMimeTypeFromContentTypeString(extName) || + MimeType.APPLICATION_OCTET_STREAM; + const fileExtension = + inferFileExtensionFromFileExtensionString(extName) || FileExtension.NONE; + const fileContent = readFileSync( + path.resolve(__dirname, '../test/assets/file-picker-executor/', fileName), + 'utf-8', + ); + + return new TextFile( + path.basename(fileName), + fileExtension, + mimeType, + splitLines(fileContent, /\r?\n/), + ); +} From 40b7893fadcbaafa54b332b4bf27ac9064414ac5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20M=C3=BCller?= Date: Mon, 16 Oct 2023 10:51:10 +0200 Subject: [PATCH 22/31] Added TextLineDeleterExecutor tests --- .../src/text-line-deleter-executor.spec.ts | 139 ++++++++++++++++++ .../text-line-deleter-executor/test-empty.txt | 0 .../test-empty.txt.license | 3 + .../text-line-deleter-executor/test.txt | 2 + .../test.txt.license | 3 + .../valid-duplicate-line.jv | 18 +++ .../valid-first-line.jv | 18 +++ .../valid-no-line.jv | 18 +++ 8 files changed, 201 insertions(+) create mode 100644 libs/extensions/std/exec/src/text-line-deleter-executor.spec.ts create mode 100644 libs/extensions/std/exec/test/assets/text-line-deleter-executor/test-empty.txt create mode 100644 libs/extensions/std/exec/test/assets/text-line-deleter-executor/test-empty.txt.license create mode 100644 libs/extensions/std/exec/test/assets/text-line-deleter-executor/test.txt create mode 100644 libs/extensions/std/exec/test/assets/text-line-deleter-executor/test.txt.license create mode 100644 libs/extensions/std/exec/test/assets/text-line-deleter-executor/valid-duplicate-line.jv create mode 100644 libs/extensions/std/exec/test/assets/text-line-deleter-executor/valid-first-line.jv create mode 100644 libs/extensions/std/exec/test/assets/text-line-deleter-executor/valid-no-line.jv diff --git a/libs/extensions/std/exec/src/text-line-deleter-executor.spec.ts b/libs/extensions/std/exec/src/text-line-deleter-executor.spec.ts new file mode 100644 index 000000000..26f4f63a5 --- /dev/null +++ b/libs/extensions/std/exec/src/text-line-deleter-executor.spec.ts @@ -0,0 +1,139 @@ +// 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 { StdLangExtension } from '@jvalue/jayvee-extensions/std/lang'; +import { + BlockDefinition, + IOType, + createJayveeServices, + useExtension, +} from '@jvalue/jayvee-language-server'; +import { + ParseHelperOptions, + TestLangExtension, + expectNoParserAndLexerErrors, + parseHelper, + readJvTestAssetHelper, +} from '@jvalue/jayvee-language-server/test'; +import { AstNode, AstNodeLocator, LangiumDocument } from 'langium'; +import { NodeFileSystem } from 'langium/node'; + +import { createTextFileFromLocalFile } from '../test'; + +import { TextLineDeleterExecutor } from './text-line-deleter-executor'; + +describe('Validation of TextFileInterpreterExecutor', () => { + let parse: ( + input: string, + options?: ParseHelperOptions, + ) => Promise>; + + let locator: AstNodeLocator; + + const readJvTestAsset = readJvTestAssetHelper( + __dirname, + '../test/assets/text-line-deleter-executor/', + ); + + function readTestFile(fileName: string): R.TextFile { + const absoluteFileName = path.resolve( + __dirname, + '../test/assets/text-line-deleter-executor/', + fileName, + ); + return createTextFileFromLocalFile(absoluteFileName); + } + + async function parseAndExecuteExecutor( + input: string, + IOInput: R.TextFile, + ): Promise> { + const document = await parse(input, { validationChecks: 'all' }); + expectNoParserAndLexerErrors(document); + + const block = locator.getAstNode( + document.parseResult.value, + 'pipelines@0/blocks@1', + ) as BlockDefinition; + + return new TextLineDeleterExecutor().doExecute( + IOInput, + getTestExecutionContext(locator, document, [block]), + ); + } + + beforeAll(() => { + // Register extensions + useExtension(new StdLangExtension()); + useExtension(new TestLangExtension()); + // Create language services + const services = createJayveeServices(NodeFileSystem).Jayvee; + locator = services.workspace.AstNodeLocator; + // Parse function for Jayvee (without validation) + parse = parseHelper(services); + }); + + it('should diagnose no error on valid text file with at least one line', async () => { + const text = readJvTestAsset('valid-first-line.jv'); + + const testFile = readTestFile('test.txt'); + const result = await parseAndExecuteExecutor(text, testFile); + + expect(R.isErr(result)).toEqual(false); + if (R.isOk(result)) { + expect(result.right.ioType).toEqual(IOType.TEXT_FILE); + expect(result.right.content).toEqual( + expect.arrayContaining(['Test File']), + ); + } + }); + + it('should diagnose no error on empty lines parameter', async () => { + const text = readJvTestAsset('valid-no-line.jv'); + + const testFile = readTestFile('test.txt'); + const result = await parseAndExecuteExecutor(text, testFile); + + expect(R.isErr(result)).toEqual(false); + if (R.isOk(result)) { + expect(result.right.ioType).toEqual(IOType.TEXT_FILE); + expect(result.right.content).toEqual( + expect.arrayContaining(['Multiline', 'Test File']), + ); + } + }); + + it('should diagnose no error on empty text', async () => { + const text = readJvTestAsset('valid-first-line.jv'); + + const testFile = readTestFile('test-empty.txt'); + const result = await parseAndExecuteExecutor(text, testFile); + + expect(R.isOk(result)).toEqual(false); + if (R.isErr(result)) { + expect(result.left.message).toEqual( + 'Line 1 does not exist in the text file, only 0 line(s) are present', + ); + } + }); + + it('should diagnose no error on duplicate line', async () => { + const text = readJvTestAsset('valid-duplicate-line.jv'); + + const testFile = readTestFile('test.txt'); + const result = await parseAndExecuteExecutor(text, testFile); + + expect(R.isErr(result)).toEqual(false); + if (R.isOk(result)) { + expect(result.right.ioType).toEqual(IOType.TEXT_FILE); + expect(result.right.content).toEqual( + expect.arrayContaining(['Test File']), + ); + } + }); +}); diff --git a/libs/extensions/std/exec/test/assets/text-line-deleter-executor/test-empty.txt b/libs/extensions/std/exec/test/assets/text-line-deleter-executor/test-empty.txt new file mode 100644 index 000000000..e69de29bb diff --git a/libs/extensions/std/exec/test/assets/text-line-deleter-executor/test-empty.txt.license b/libs/extensions/std/exec/test/assets/text-line-deleter-executor/test-empty.txt.license new file mode 100644 index 000000000..17c5d2bad --- /dev/null +++ b/libs/extensions/std/exec/test/assets/text-line-deleter-executor/test-empty.txt.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg + +SPDX-License-Identifier: AGPL-3.0-only diff --git a/libs/extensions/std/exec/test/assets/text-line-deleter-executor/test.txt b/libs/extensions/std/exec/test/assets/text-line-deleter-executor/test.txt new file mode 100644 index 000000000..ab23659f7 --- /dev/null +++ b/libs/extensions/std/exec/test/assets/text-line-deleter-executor/test.txt @@ -0,0 +1,2 @@ +Multiline +Test File diff --git a/libs/extensions/std/exec/test/assets/text-line-deleter-executor/test.txt.license b/libs/extensions/std/exec/test/assets/text-line-deleter-executor/test.txt.license new file mode 100644 index 000000000..17c5d2bad --- /dev/null +++ b/libs/extensions/std/exec/test/assets/text-line-deleter-executor/test.txt.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg + +SPDX-License-Identifier: AGPL-3.0-only diff --git a/libs/extensions/std/exec/test/assets/text-line-deleter-executor/valid-duplicate-line.jv b/libs/extensions/std/exec/test/assets/text-line-deleter-executor/valid-duplicate-line.jv new file mode 100644 index 000000000..bee371121 --- /dev/null +++ b/libs/extensions/std/exec/test/assets/text-line-deleter-executor/valid-duplicate-line.jv @@ -0,0 +1,18 @@ +// SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg +// +// SPDX-License-Identifier: AGPL-3.0-only + +pipeline TestPipeline { + + block TestExtractor oftype TestFileExtractor { + } + + block TestBlock oftype TextLineDeleter { + lines: [1,1]; + } + + block TestLoader oftype TestTextFileLoader { + } + + TestExtractor -> TestBlock -> TestLoader; +} diff --git a/libs/extensions/std/exec/test/assets/text-line-deleter-executor/valid-first-line.jv b/libs/extensions/std/exec/test/assets/text-line-deleter-executor/valid-first-line.jv new file mode 100644 index 000000000..c0d367ad5 --- /dev/null +++ b/libs/extensions/std/exec/test/assets/text-line-deleter-executor/valid-first-line.jv @@ -0,0 +1,18 @@ +// SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg +// +// SPDX-License-Identifier: AGPL-3.0-only + +pipeline TestPipeline { + + block TestExtractor oftype TestFileExtractor { + } + + block TestBlock oftype TextLineDeleter { + lines: [1]; + } + + block TestLoader oftype TestTextFileLoader { + } + + TestExtractor -> TestBlock -> TestLoader; +} diff --git a/libs/extensions/std/exec/test/assets/text-line-deleter-executor/valid-no-line.jv b/libs/extensions/std/exec/test/assets/text-line-deleter-executor/valid-no-line.jv new file mode 100644 index 000000000..6f589315c --- /dev/null +++ b/libs/extensions/std/exec/test/assets/text-line-deleter-executor/valid-no-line.jv @@ -0,0 +1,18 @@ +// SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg +// +// SPDX-License-Identifier: AGPL-3.0-only + +pipeline TestPipeline { + + block TestExtractor oftype TestFileExtractor { + } + + block TestBlock oftype TextLineDeleter { + lines: []; + } + + block TestLoader oftype TestTextFileLoader { + } + + TestExtractor -> TestBlock -> TestLoader; +} From 98d6cb1f21a44f09757cf512b7ed441ec7fdfe3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20M=C3=BCller?= Date: Mon, 16 Oct 2023 10:54:00 +0200 Subject: [PATCH 23/31] Fixed test name --- libs/extensions/std/exec/src/text-line-deleter-executor.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/extensions/std/exec/src/text-line-deleter-executor.spec.ts b/libs/extensions/std/exec/src/text-line-deleter-executor.spec.ts index 26f4f63a5..09db95864 100644 --- a/libs/extensions/std/exec/src/text-line-deleter-executor.spec.ts +++ b/libs/extensions/std/exec/src/text-line-deleter-executor.spec.ts @@ -27,7 +27,7 @@ import { createTextFileFromLocalFile } from '../test'; import { TextLineDeleterExecutor } from './text-line-deleter-executor'; -describe('Validation of TextFileInterpreterExecutor', () => { +describe('Validation of TextLineDeleterExecutor', () => { let parse: ( input: string, options?: ParseHelperOptions, From 550136c3cb03e0bae0662feb960f227b64a3ddd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20M=C3=BCller?= Date: Mon, 16 Oct 2023 11:25:50 +0200 Subject: [PATCH 24/31] Added TextRangeSelectorExecutor tests --- .../src/text-range-selector-executor.spec.ts | 108 ++++++++++++++++++ .../test-empty.txt | 0 .../test-empty.txt.license | 3 + .../text-range-selector-executor/test.txt | 3 + .../test.txt.license | 3 + .../valid-range.jv | 19 +++ 6 files changed, 136 insertions(+) create mode 100644 libs/extensions/std/exec/src/text-range-selector-executor.spec.ts create mode 100644 libs/extensions/std/exec/test/assets/text-range-selector-executor/test-empty.txt create mode 100644 libs/extensions/std/exec/test/assets/text-range-selector-executor/test-empty.txt.license create mode 100644 libs/extensions/std/exec/test/assets/text-range-selector-executor/test.txt create mode 100644 libs/extensions/std/exec/test/assets/text-range-selector-executor/test.txt.license create mode 100644 libs/extensions/std/exec/test/assets/text-range-selector-executor/valid-range.jv diff --git a/libs/extensions/std/exec/src/text-range-selector-executor.spec.ts b/libs/extensions/std/exec/src/text-range-selector-executor.spec.ts new file mode 100644 index 000000000..e5e534533 --- /dev/null +++ b/libs/extensions/std/exec/src/text-range-selector-executor.spec.ts @@ -0,0 +1,108 @@ +// 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 { StdLangExtension } from '@jvalue/jayvee-extensions/std/lang'; +import { + BlockDefinition, + IOType, + createJayveeServices, + useExtension, +} from '@jvalue/jayvee-language-server'; +import { + ParseHelperOptions, + TestLangExtension, + expectNoParserAndLexerErrors, + parseHelper, + readJvTestAssetHelper, +} from '@jvalue/jayvee-language-server/test'; +import { AstNode, AstNodeLocator, LangiumDocument } from 'langium'; +import { NodeFileSystem } from 'langium/node'; + +import { createTextFileFromLocalFile } from '../test'; + +import { TextRangeSelectorExecutor } from './text-range-selector-executor'; + +describe('Validation of TextRangeSelectorExecutor', () => { + let parse: ( + input: string, + options?: ParseHelperOptions, + ) => Promise>; + + let locator: AstNodeLocator; + + const readJvTestAsset = readJvTestAssetHelper( + __dirname, + '../test/assets/text-range-selector-executor/', + ); + + function readTestFile(fileName: string): R.TextFile { + const absoluteFileName = path.resolve( + __dirname, + '../test/assets/text-range-selector-executor/', + fileName, + ); + return createTextFileFromLocalFile(absoluteFileName); + } + + async function parseAndExecuteExecutor( + input: string, + IOInput: R.TextFile, + ): Promise> { + const document = await parse(input, { validationChecks: 'all' }); + expectNoParserAndLexerErrors(document); + + const block = locator.getAstNode( + document.parseResult.value, + 'pipelines@0/blocks@1', + ) as BlockDefinition; + + return new TextRangeSelectorExecutor().doExecute( + IOInput, + getTestExecutionContext(locator, document, [block]), + ); + } + + beforeAll(() => { + // Register extensions + useExtension(new StdLangExtension()); + useExtension(new TestLangExtension()); + // Create language services + const services = createJayveeServices(NodeFileSystem).Jayvee; + locator = services.workspace.AstNodeLocator; + // Parse function for Jayvee (without validation) + parse = parseHelper(services); + }); + + it('should diagnose no error on valid file', async () => { + const text = readJvTestAsset('valid-range.jv'); + + const testFile = readTestFile('test.txt'); + const result = await parseAndExecuteExecutor(text, testFile); + + expect(R.isErr(result)).toEqual(false); + if (R.isOk(result)) { + expect(result.right.ioType).toEqual(IOType.TEXT_FILE); + expect(result.right.content).toEqual( + expect.arrayContaining(['Multiline', 'Test ']), + ); + } + }); + + it('should diagnose no error on empty text file', async () => { + const text = readJvTestAsset('valid-range.jv'); + + const testFile = readTestFile('test-empty.txt'); + const result = await parseAndExecuteExecutor(text, testFile); + + expect(R.isErr(result)).toEqual(false); + if (R.isOk(result)) { + expect(result.right.ioType).toEqual(IOType.TEXT_FILE); + expect(result.right.content).toHaveLength(0); + } + }); +}); diff --git a/libs/extensions/std/exec/test/assets/text-range-selector-executor/test-empty.txt b/libs/extensions/std/exec/test/assets/text-range-selector-executor/test-empty.txt new file mode 100644 index 000000000..e69de29bb diff --git a/libs/extensions/std/exec/test/assets/text-range-selector-executor/test-empty.txt.license b/libs/extensions/std/exec/test/assets/text-range-selector-executor/test-empty.txt.license new file mode 100644 index 000000000..17c5d2bad --- /dev/null +++ b/libs/extensions/std/exec/test/assets/text-range-selector-executor/test-empty.txt.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg + +SPDX-License-Identifier: AGPL-3.0-only diff --git a/libs/extensions/std/exec/test/assets/text-range-selector-executor/test.txt b/libs/extensions/std/exec/test/assets/text-range-selector-executor/test.txt new file mode 100644 index 000000000..5f660012c --- /dev/null +++ b/libs/extensions/std/exec/test/assets/text-range-selector-executor/test.txt @@ -0,0 +1,3 @@ +Multiline +Test +File diff --git a/libs/extensions/std/exec/test/assets/text-range-selector-executor/test.txt.license b/libs/extensions/std/exec/test/assets/text-range-selector-executor/test.txt.license new file mode 100644 index 000000000..17c5d2bad --- /dev/null +++ b/libs/extensions/std/exec/test/assets/text-range-selector-executor/test.txt.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg + +SPDX-License-Identifier: AGPL-3.0-only diff --git a/libs/extensions/std/exec/test/assets/text-range-selector-executor/valid-range.jv b/libs/extensions/std/exec/test/assets/text-range-selector-executor/valid-range.jv new file mode 100644 index 000000000..13059cce8 --- /dev/null +++ b/libs/extensions/std/exec/test/assets/text-range-selector-executor/valid-range.jv @@ -0,0 +1,19 @@ +// SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg +// +// SPDX-License-Identifier: AGPL-3.0-only + +pipeline TestPipeline { + + block TestExtractor oftype TestFileExtractor { + } + + block TestBlock oftype TextRangeSelector { + lineFrom: 1; + lineTo: 2; + } + + block TestLoader oftype TestTextFileLoader { + } + + TestExtractor -> TestBlock -> TestLoader; +} From 5b679555d864dcdf984c47485c9483c6a5fd17ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20M=C3=BCller?= Date: Mon, 23 Oct 2023 08:42:34 +0200 Subject: [PATCH 25/31] Fixed filepath hardcoded to file-picker test assets --- libs/extensions/std/exec/test/utils.ts | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/libs/extensions/std/exec/test/utils.ts b/libs/extensions/std/exec/test/utils.ts index 594b80d75..c6fc34e63 100644 --- a/libs/extensions/std/exec/test/utils.ts +++ b/libs/extensions/std/exec/test/utils.ts @@ -25,9 +25,7 @@ export function createBinaryFileFromLocalFile(fileName: string): BinaryFile { MimeType.APPLICATION_OCTET_STREAM; const fileExtension = inferFileExtensionFromFileExtensionString(extName) || FileExtension.NONE; - const file = readFileSync( - path.resolve(__dirname, '../test/assets/file-picker-executor/', fileName), - ); + const file = readFileSync(path.resolve(__dirname, fileName)); return new BinaryFile(path.basename(fileName), fileExtension, mimeType, file); } @@ -38,10 +36,7 @@ export function createTextFileFromLocalFile(fileName: string): TextFile { MimeType.APPLICATION_OCTET_STREAM; const fileExtension = inferFileExtensionFromFileExtensionString(extName) || FileExtension.NONE; - const fileContent = readFileSync( - path.resolve(__dirname, '../test/assets/file-picker-executor/', fileName), - 'utf-8', - ); + const fileContent = readFileSync(path.resolve(__dirname, fileName), 'utf-8'); return new TextFile( path.basename(fileName), From 451c0882fa96a8dcbfd7e8cabfde2fc2d4fe6647 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20M=C3=BCller?= Date: Mon, 23 Oct 2023 10:23:06 +0200 Subject: [PATCH 26/31] Fixed test names --- .../std/exec/src/gtfs-rt-interpreter-executor.spec.ts | 4 ++-- .../extensions/std/exec/src/http-extractor-executor.spec.ts | 6 +++--- .../std/exec/src/text-line-deleter-executor.spec.ts | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libs/extensions/std/exec/src/gtfs-rt-interpreter-executor.spec.ts b/libs/extensions/std/exec/src/gtfs-rt-interpreter-executor.spec.ts index 28b16b747..12d3dc689 100644 --- a/libs/extensions/std/exec/src/gtfs-rt-interpreter-executor.spec.ts +++ b/libs/extensions/std/exec/src/gtfs-rt-interpreter-executor.spec.ts @@ -143,7 +143,7 @@ describe('Validation of GtfsRTInterpreterExecutor', () => { } }); - it('should diagnose no error on invalid entity parameter', async () => { + it('should diagnose error on invalid entity parameter', async () => { const text = readJvTestAsset('invalid-entity-parameter.jv'); const testFile = readTestFile('valid-trip-update'); @@ -157,7 +157,7 @@ describe('Validation of GtfsRTInterpreterExecutor', () => { } }); - it('should diagnose no error on invalid gtfs file input', async () => { + it('should diagnose error on invalid gtfs file input', async () => { const text = readJvTestAsset('invalid-entity-parameter.jv'); const testFile = readTestFile('invalid-gtfs'); diff --git a/libs/extensions/std/exec/src/http-extractor-executor.spec.ts b/libs/extensions/std/exec/src/http-extractor-executor.spec.ts index 207a04b4b..cd680792f 100644 --- a/libs/extensions/std/exec/src/http-extractor-executor.spec.ts +++ b/libs/extensions/std/exec/src/http-extractor-executor.spec.ts @@ -173,7 +173,7 @@ describe('Validation of HttpExtractorExecutor', () => { } }); - it('should diagnose no error on url not found', async () => { + it('should diagnose error on url not found', async () => { const text = readJvTestAsset('valid-http.jv'); const nockScope = nock('http://localhost').get('/test.txt').reply(404); @@ -188,7 +188,7 @@ describe('Validation of HttpExtractorExecutor', () => { } }); - it('should diagnose no error on ClientRequest error', async () => { + it('should diagnose error on ClientRequest error', async () => { const text = readJvTestAsset('valid-https.jv'); const nockScope = nock('https://localhost') .get('/test.txt') @@ -203,7 +203,7 @@ describe('Validation of HttpExtractorExecutor', () => { } }); - it('should diagnose no error on ignoring redirects', async () => { + it('should diagnose error on ignoring redirects', async () => { const text = readJvTestAsset('valid-http.jv'); const nockScope = nock('http://localhost').get('/test.txt').reply(301); diff --git a/libs/extensions/std/exec/src/text-line-deleter-executor.spec.ts b/libs/extensions/std/exec/src/text-line-deleter-executor.spec.ts index 09db95864..3ae786cb2 100644 --- a/libs/extensions/std/exec/src/text-line-deleter-executor.spec.ts +++ b/libs/extensions/std/exec/src/text-line-deleter-executor.spec.ts @@ -108,7 +108,7 @@ describe('Validation of TextLineDeleterExecutor', () => { } }); - it('should diagnose no error on empty text', async () => { + it('should diagnose error on empty text', async () => { const text = readJvTestAsset('valid-first-line.jv'); const testFile = readTestFile('test-empty.txt'); From 1ab1148231a9484abd18a24dcaee33fde93c3ed5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20M=C3=BCller?= Date: Mon, 6 Nov 2023 10:37:11 +0100 Subject: [PATCH 27/31] Extracted the `initializeWorkspace` for test extension loading into a correspondingly named utils function for easier understanding --- libs/interpreter-lib/src/parsing-util.spec.ts | 15 ++++++--------- .../runtime-parameter-literal.spec.ts | 15 ++++++--------- libs/language-server/src/test/utils.ts | 16 ++++++++++++++++ 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/libs/interpreter-lib/src/parsing-util.spec.ts b/libs/interpreter-lib/src/parsing-util.spec.ts index 2975927b6..7f8ab9abf 100644 --- a/libs/interpreter-lib/src/parsing-util.spec.ts +++ b/libs/interpreter-lib/src/parsing-util.spec.ts @@ -8,11 +8,11 @@ import { CachedLogger } from '@jvalue/jayvee-execution'; import { JayveeServices, createJayveeServices, - initializeWorkspace, } from '@jvalue/jayvee-language-server'; import { ParseHelperOptions, expectNoParserAndLexerErrors, + loadTestExtensions, parseHelper, readJvTestAssetHelper, } from '@jvalue/jayvee-language-server/test'; @@ -52,14 +52,11 @@ describe('Validation of parsing-util', () => { // Create language services services = createJayveeServices(NodeFileSystem).Jayvee; - await initializeWorkspace(services, [ - { - uri: path.resolve( - __dirname, - '../test/assets/parsing-util/test-extension', - ), - name: 'TestBlockTypes.jv', - }, + await loadTestExtensions(services, [ + path.resolve( + __dirname, + '../test/assets/parsing-util/test-extension/TestBlockTypes.jv', + ), ]); // Parse function for Jayvee (without validation) diff --git a/libs/interpreter-lib/src/validation-checks/runtime-parameter-literal.spec.ts b/libs/interpreter-lib/src/validation-checks/runtime-parameter-literal.spec.ts index 9e61c42f6..f835f4c9e 100644 --- a/libs/interpreter-lib/src/validation-checks/runtime-parameter-literal.spec.ts +++ b/libs/interpreter-lib/src/validation-checks/runtime-parameter-literal.spec.ts @@ -11,11 +11,11 @@ import { RuntimeParameterProvider, ValidationContext, createJayveeServices, - initializeWorkspace, } from '@jvalue/jayvee-language-server'; import { ParseHelperOptions, expectNoParserAndLexerErrors, + loadTestExtensions, parseHelper, readJvTestAssetHelper, validationAcceptorMockImpl, @@ -71,14 +71,11 @@ describe('Validation of validateRuntimeParameterLiteral', () => { // Create language services const services = createJayveeServices(NodeFileSystem).Jayvee; - await initializeWorkspace(services, [ - { - uri: path.resolve( - __dirname, - '../../test/assets/runtime-parameter-literal/test-extension', - ), - name: 'TestBlockTypes.jv', - }, + await loadTestExtensions(services, [ + path.resolve( + __dirname, + '../../test/assets/runtime-parameter-literal/test-extension/TestBlockTypes.jv', + ), ]); locator = services.workspace.AstNodeLocator; diff --git a/libs/language-server/src/test/utils.ts b/libs/language-server/src/test/utils.ts index c5c9e72e9..159e01b56 100644 --- a/libs/language-server/src/test/utils.ts +++ b/libs/language-server/src/test/utils.ts @@ -2,11 +2,15 @@ // // SPDX-License-Identifier: AGPL-3.0-only +import * as assert from 'assert'; import { readFileSync } from 'fs'; import * as path from 'path'; import { AstNode, LangiumDocument, ValidationAcceptor } from 'langium'; +import { WorkspaceFolder } from 'vscode-languageserver-protocol'; +import { JayveeServices } from '../lib'; +import { initializeWorkspace } from '../lib/builtin-library/jayvee-workspace-manager'; import { constraintMetaInfRegistry } from '../lib/meta-information/meta-inf-registry'; // eslint-disable-next-line @typescript-eslint/no-empty-function @@ -46,3 +50,15 @@ export function expectNoParserAndLexerErrors( export function clearMetaInfRegistry() { constraintMetaInfRegistry.clear(); } + +export async function loadTestExtensions( + services: JayveeServices, + testExtensionJvFiles: string[], +) { + assert(testExtensionJvFiles.every((file) => file.endsWith('.jv'))); + const extensions: WorkspaceFolder[] = testExtensionJvFiles.map((file) => ({ + uri: path.dirname(file), + name: path.basename(file), + })); + return initializeWorkspace(services, extensions); +} From b6f88246388c61568004f3fb9c7cafc5b1b4b25a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20M=C3=BCller?= Date: Mon, 6 Nov 2023 11:19:43 +0100 Subject: [PATCH 28/31] Fixed method name --- libs/extensions/std/exec/src/archive-interpreter-executor.ts | 4 ++-- libs/extensions/std/exec/src/file-util.ts | 2 +- libs/extensions/std/exec/src/http-extractor-executor.ts | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libs/extensions/std/exec/src/archive-interpreter-executor.ts b/libs/extensions/std/exec/src/archive-interpreter-executor.ts index bf78fe65d..ccd07d491 100644 --- a/libs/extensions/std/exec/src/archive-interpreter-executor.ts +++ b/libs/extensions/std/exec/src/archive-interpreter-executor.ts @@ -24,7 +24,7 @@ import * as JSZip from 'jszip'; import { inferFileExtensionFromFileExtensionString, - inferMimeTypeFromContentTypeString, + inferMimeTypeFromFileExtensionString, } from './file-util'; @implementsStatic() @@ -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; diff --git a/libs/extensions/std/exec/src/file-util.ts b/libs/extensions/std/exec/src/file-util.ts index d82ef000c..ff828156d 100644 --- a/libs/extensions/std/exec/src/file-util.ts +++ b/libs/extensions/std/exec/src/file-util.ts @@ -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) { diff --git a/libs/extensions/std/exec/src/http-extractor-executor.ts b/libs/extensions/std/exec/src/http-extractor-executor.ts index 91f8d9e71..c9f052e85 100644 --- a/libs/extensions/std/exec/src/http-extractor-executor.ts +++ b/libs/extensions/std/exec/src/http-extractor-executor.ts @@ -24,7 +24,7 @@ import { AstNode } from 'langium'; import { inferFileExtensionFromContentTypeString, inferFileExtensionFromFileExtensionString, - inferMimeTypeFromContentTypeString, + inferMimeTypeFromFileExtensionString, } from './file-util'; import { createBackoffStrategy, @@ -151,7 +151,7 @@ export class HttpExtractorExecutor extends AbstractBlockExecutor< // Infer Mimetype from HTTP-Header, if not inferrable, then default to application/octet-stream const mimeType: MimeType | undefined = - inferMimeTypeFromContentTypeString( + inferMimeTypeFromFileExtensionString( response.headers['content-type'], ) || MimeType.APPLICATION_OCTET_STREAM; From 5a2d5c25021a24480f5f98ec7460ffa530f8307c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20M=C3=BCller?= Date: Mon, 6 Nov 2023 11:30:04 +0100 Subject: [PATCH 29/31] Fixed import of renamed function --- libs/extensions/std/exec/test/utils.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libs/extensions/std/exec/test/utils.ts b/libs/extensions/std/exec/test/utils.ts index c6fc34e63..7b7d43d5b 100644 --- a/libs/extensions/std/exec/test/utils.ts +++ b/libs/extensions/std/exec/test/utils.ts @@ -14,14 +14,14 @@ import { import { inferFileExtensionFromFileExtensionString, - inferMimeTypeFromContentTypeString, + inferMimeTypeFromFileExtensionString, } from '../src/file-util'; import { splitLines } from '../src/string-util'; export function createBinaryFileFromLocalFile(fileName: string): BinaryFile { const extName = path.extname(fileName); const mimeType = - inferMimeTypeFromContentTypeString(extName) || + inferMimeTypeFromFileExtensionString(extName) || MimeType.APPLICATION_OCTET_STREAM; const fileExtension = inferFileExtensionFromFileExtensionString(extName) || FileExtension.NONE; @@ -32,7 +32,7 @@ export function createBinaryFileFromLocalFile(fileName: string): BinaryFile { export function createTextFileFromLocalFile(fileName: string): TextFile { const extName = path.extname(fileName); const mimeType = - inferMimeTypeFromContentTypeString(extName) || + inferMimeTypeFromFileExtensionString(extName) || MimeType.APPLICATION_OCTET_STREAM; const fileExtension = inferFileExtensionFromFileExtensionString(extName) || FileExtension.NONE; From 9c97bff0f25972351d04615f43ee68219e7a210e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20M=C3=BCller?= Date: Mon, 6 Nov 2023 11:36:56 +0100 Subject: [PATCH 30/31] Fixed tests using renamed function --- libs/extensions/std/exec/src/file-util.spec.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libs/extensions/std/exec/src/file-util.spec.ts b/libs/extensions/std/exec/src/file-util.spec.ts index a469e6a92..decef2317 100644 --- a/libs/extensions/std/exec/src/file-util.spec.ts +++ b/libs/extensions/std/exec/src/file-util.spec.ts @@ -7,23 +7,23 @@ import { FileExtension, MimeType } from '@jvalue/jayvee-execution'; import { inferFileExtensionFromContentTypeString, inferFileExtensionFromFileExtensionString, - inferMimeTypeFromContentTypeString, + inferMimeTypeFromFileExtensionString, } from './file-util'; describe('Validation of file-util', () => { describe('Function inferMimeTypeFromContentTypeString', () => { it('should diagnose no error on known mimeType', () => { - const result = inferMimeTypeFromContentTypeString('txt'); + const result = inferMimeTypeFromFileExtensionString('txt'); expect(result).toEqual(MimeType.TEXT_PLAIN); }); it('should diagnose no error on undefined input', () => { - const result = inferMimeTypeFromContentTypeString(undefined); + const result = inferMimeTypeFromFileExtensionString(undefined); expect(result).toEqual(undefined); }); it('should diagnose no error on unknown mimeType', () => { - const result = inferMimeTypeFromContentTypeString('unity'); + const result = inferMimeTypeFromFileExtensionString('unity'); expect(result).toEqual(undefined); }); From ea7c306e80a0b3628258b05ad7f503fd73ce00ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20M=C3=BCller?= Date: Mon, 6 Nov 2023 11:37:19 +0100 Subject: [PATCH 31/31] Applied new TestExtension loading --- .../src/archive-interpreter-executor.spec.ts | 12 ++++------ .../std/exec/src/file-picker-executor.spec.ts | 12 ++++------ .../src/gtfs-rt-interpreter-executor.spec.ts | 12 ++++------ .../exec/src/http-extractor-executor.spec.ts | 12 ++++------ .../text-file-interpreter-executor.spec.ts | 12 ++++------ .../src/text-line-deleter-executor.spec.ts | 12 ++++------ .../src/text-range-selector-executor.spec.ts | 12 ++++------ .../test/test-extension/TestBlockTypes.jv | 23 +++++++++++++++++++ 8 files changed, 58 insertions(+), 49 deletions(-) create mode 100644 libs/extensions/std/exec/test/test-extension/TestBlockTypes.jv diff --git a/libs/extensions/std/exec/src/archive-interpreter-executor.spec.ts b/libs/extensions/std/exec/src/archive-interpreter-executor.spec.ts index 060b52aba..7b174ae11 100644 --- a/libs/extensions/std/exec/src/archive-interpreter-executor.spec.ts +++ b/libs/extensions/std/exec/src/archive-interpreter-executor.spec.ts @@ -6,17 +6,15 @@ import * as path from 'path'; import * as R from '@jvalue/jayvee-execution'; import { getTestExecutionContext } from '@jvalue/jayvee-execution/test'; -import { StdLangExtension } from '@jvalue/jayvee-extensions/std/lang'; import { BlockDefinition, IOType, createJayveeServices, - useExtension, } from '@jvalue/jayvee-language-server'; import { ParseHelperOptions, - TestLangExtension, expectNoParserAndLexerErrors, + loadTestExtensions, parseHelper, readJvTestAssetHelper, } from '@jvalue/jayvee-language-server/test'; @@ -67,12 +65,12 @@ describe('Validation of ArchiveInterpreterExecutor', () => { ); } - beforeAll(() => { - // Register extensions - useExtension(new StdLangExtension()); - useExtension(new TestLangExtension()); + 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); diff --git a/libs/extensions/std/exec/src/file-picker-executor.spec.ts b/libs/extensions/std/exec/src/file-picker-executor.spec.ts index e4d49c698..8fd8e3578 100644 --- a/libs/extensions/std/exec/src/file-picker-executor.spec.ts +++ b/libs/extensions/std/exec/src/file-picker-executor.spec.ts @@ -6,17 +6,15 @@ import * as path from 'path'; import * as R from '@jvalue/jayvee-execution'; import { getTestExecutionContext } from '@jvalue/jayvee-execution/test'; -import { StdLangExtension } from '@jvalue/jayvee-extensions/std/lang'; import { BlockDefinition, IOType, createJayveeServices, - useExtension, } from '@jvalue/jayvee-language-server'; import { ParseHelperOptions, - TestLangExtension, expectNoParserAndLexerErrors, + loadTestExtensions, parseHelper, readJvTestAssetHelper, } from '@jvalue/jayvee-language-server/test'; @@ -71,12 +69,12 @@ describe('Validation of FilePickerExecutor', () => { ); } - beforeAll(() => { - // Register extensions - useExtension(new StdLangExtension()); - useExtension(new TestLangExtension()); + 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); diff --git a/libs/extensions/std/exec/src/gtfs-rt-interpreter-executor.spec.ts b/libs/extensions/std/exec/src/gtfs-rt-interpreter-executor.spec.ts index 12d3dc689..75d8ae8d9 100644 --- a/libs/extensions/std/exec/src/gtfs-rt-interpreter-executor.spec.ts +++ b/libs/extensions/std/exec/src/gtfs-rt-interpreter-executor.spec.ts @@ -6,17 +6,15 @@ import * as path from 'path'; import * as R from '@jvalue/jayvee-execution'; import { getTestExecutionContext } from '@jvalue/jayvee-execution/test'; -import { StdLangExtension } from '@jvalue/jayvee-extensions/std/lang'; import { BlockDefinition, IOType, createJayveeServices, - useExtension, } from '@jvalue/jayvee-language-server'; import { ParseHelperOptions, - TestLangExtension, expectNoParserAndLexerErrors, + loadTestExtensions, parseHelper, readJvTestAssetHelper, } from '@jvalue/jayvee-language-server/test'; @@ -67,12 +65,12 @@ describe('Validation of GtfsRTInterpreterExecutor', () => { ); } - beforeAll(() => { - // Register extensions - useExtension(new StdLangExtension()); - useExtension(new TestLangExtension()); + 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); diff --git a/libs/extensions/std/exec/src/http-extractor-executor.spec.ts b/libs/extensions/std/exec/src/http-extractor-executor.spec.ts index cd680792f..7bccbb58d 100644 --- a/libs/extensions/std/exec/src/http-extractor-executor.spec.ts +++ b/libs/extensions/std/exec/src/http-extractor-executor.spec.ts @@ -6,17 +6,15 @@ import * as path from 'path'; import * as R from '@jvalue/jayvee-execution'; import { getTestExecutionContext } from '@jvalue/jayvee-execution/test'; -import { StdLangExtension } from '@jvalue/jayvee-extensions/std/lang'; import { BlockDefinition, IOType, createJayveeServices, - useExtension, } from '@jvalue/jayvee-language-server'; import { ParseHelperOptions, - TestLangExtension, expectNoParserAndLexerErrors, + loadTestExtensions, parseHelper, readJvTestAssetHelper, } from '@jvalue/jayvee-language-server/test'; @@ -56,12 +54,12 @@ describe('Validation of HttpExtractorExecutor', () => { ); } - beforeAll(() => { - // Register extensions - useExtension(new StdLangExtension()); - useExtension(new TestLangExtension()); + 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); diff --git a/libs/extensions/std/exec/src/text-file-interpreter-executor.spec.ts b/libs/extensions/std/exec/src/text-file-interpreter-executor.spec.ts index c477fb9e3..342bceeab 100644 --- a/libs/extensions/std/exec/src/text-file-interpreter-executor.spec.ts +++ b/libs/extensions/std/exec/src/text-file-interpreter-executor.spec.ts @@ -6,17 +6,15 @@ import * as path from 'path'; import * as R from '@jvalue/jayvee-execution'; import { getTestExecutionContext } from '@jvalue/jayvee-execution/test'; -import { StdLangExtension } from '@jvalue/jayvee-extensions/std/lang'; import { BlockDefinition, IOType, createJayveeServices, - useExtension, } from '@jvalue/jayvee-language-server'; import { ParseHelperOptions, - TestLangExtension, expectNoParserAndLexerErrors, + loadTestExtensions, parseHelper, readJvTestAssetHelper, } from '@jvalue/jayvee-language-server/test'; @@ -67,12 +65,12 @@ describe('Validation of TextFileInterpreterExecutor', () => { ); } - beforeAll(() => { - // Register extensions - useExtension(new StdLangExtension()); - useExtension(new TestLangExtension()); + 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); diff --git a/libs/extensions/std/exec/src/text-line-deleter-executor.spec.ts b/libs/extensions/std/exec/src/text-line-deleter-executor.spec.ts index 3ae786cb2..8ca8a191e 100644 --- a/libs/extensions/std/exec/src/text-line-deleter-executor.spec.ts +++ b/libs/extensions/std/exec/src/text-line-deleter-executor.spec.ts @@ -6,17 +6,15 @@ import * as path from 'path'; import * as R from '@jvalue/jayvee-execution'; import { getTestExecutionContext } from '@jvalue/jayvee-execution/test'; -import { StdLangExtension } from '@jvalue/jayvee-extensions/std/lang'; import { BlockDefinition, IOType, createJayveeServices, - useExtension, } from '@jvalue/jayvee-language-server'; import { ParseHelperOptions, - TestLangExtension, expectNoParserAndLexerErrors, + loadTestExtensions, parseHelper, readJvTestAssetHelper, } from '@jvalue/jayvee-language-server/test'; @@ -67,12 +65,12 @@ describe('Validation of TextLineDeleterExecutor', () => { ); } - beforeAll(() => { - // Register extensions - useExtension(new StdLangExtension()); - useExtension(new TestLangExtension()); + 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); diff --git a/libs/extensions/std/exec/src/text-range-selector-executor.spec.ts b/libs/extensions/std/exec/src/text-range-selector-executor.spec.ts index e5e534533..73e333359 100644 --- a/libs/extensions/std/exec/src/text-range-selector-executor.spec.ts +++ b/libs/extensions/std/exec/src/text-range-selector-executor.spec.ts @@ -6,17 +6,15 @@ import * as path from 'path'; import * as R from '@jvalue/jayvee-execution'; import { getTestExecutionContext } from '@jvalue/jayvee-execution/test'; -import { StdLangExtension } from '@jvalue/jayvee-extensions/std/lang'; import { BlockDefinition, IOType, createJayveeServices, - useExtension, } from '@jvalue/jayvee-language-server'; import { ParseHelperOptions, - TestLangExtension, expectNoParserAndLexerErrors, + loadTestExtensions, parseHelper, readJvTestAssetHelper, } from '@jvalue/jayvee-language-server/test'; @@ -67,12 +65,12 @@ describe('Validation of TextRangeSelectorExecutor', () => { ); } - beforeAll(() => { - // Register extensions - useExtension(new StdLangExtension()); - useExtension(new TestLangExtension()); + 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); diff --git a/libs/extensions/std/exec/test/test-extension/TestBlockTypes.jv b/libs/extensions/std/exec/test/test-extension/TestBlockTypes.jv new file mode 100644 index 000000000..3abfdb4e2 --- /dev/null +++ b/libs/extensions/std/exec/test/test-extension/TestBlockTypes.jv @@ -0,0 +1,23 @@ +// SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg +// +// SPDX-License-Identifier: AGPL-3.0-only + +builtin blocktype TestFileExtractor { + input inPort oftype None; + output outPort oftype File; +} + +builtin blocktype TestFileLoader { + input inPort oftype File; + output outPort oftype None; +} + +builtin blocktype TestSheetLoader { + input inPort oftype Sheet; + output outPort oftype None; +} + +builtin blocktype TestTextFileLoader { + input inPort oftype TextFile; + output outPort oftype None; +}