diff --git a/test/ast.js b/test/ast.js index 17f0ed25..249aaa81 100644 --- a/test/ast.js +++ b/test/ast.js @@ -387,7 +387,7 @@ class JSASTWrapper { } constructor(code) { - this.programm = acorn.parse(code, { ecmaVersion: 'latest'}) + this.program = acorn.parse(code, { ecmaVersion: 'latest'}) } exportsAre(expected) { @@ -402,7 +402,7 @@ class JSASTWrapper { } getExports() { - return this.exports ??= this.programm.body.filter(node => { + return this.exports ??= this.program.body.filter(node => { if (node.type !== 'ExpressionStatement') return false if (node.expression.left.type !== 'MemberExpression') return false const { object, property } = node.expression.left.object diff --git a/test/unit/actions.test.js b/test/unit/actions.test.js index 95f87490..9b794529 100644 --- a/test/unit/actions.test.js +++ b/test/unit/actions.test.js @@ -1,19 +1,23 @@ 'use strict' -const fs = require('fs').promises const path = require('path') -const { ASTWrapper, checkFunction, check } = require('../ast') -const { locations, cds2ts } = require('../util') -const dir = locations.testOutput('actions_test') +const { checkFunction, check, ASTWrapper } = require('../ast') +const { locations, prepareUnitTest } = require('../util') describe('Actions', () => { - beforeEach(async () => await fs.unlink(dir).catch(() => {})) + let paths + let astwBound + let astwUnbound + + beforeAll(async () => { + paths = (await prepareUnitTest('actions/model.cds', locations.testOutput('actions_test'))).paths + astwBound = new ASTWrapper(path.join(paths[1], 'index.ts')) + astwUnbound = new ASTWrapper(path.join(paths[2], 'index.ts')) + }) test('Bound', async () => { - const paths = await cds2ts('actions/model.cds', { outputDirectory: dir, inlineDeclarations: 'structured' }) - const astw = new ASTWrapper(path.join(paths[1], 'index.ts')) - const actions = astw.getAspectProperty('_EAspect', 'actions') + const actions = astwBound.getAspectProperty('_EAspect', 'actions') expect(actions.modifiers.some(check.isStatic)).toBeTruthy() checkFunction(actions.type.members.find(fn => fn.name === 'f'), { parameterCheck: ({members: [fst]}) => fst.name === 'x' && check.isNullable(fst.type, [check.isString]) @@ -31,8 +35,7 @@ describe('Actions', () => { }) test('Unbound', async () => { - const paths = await cds2ts('actions/model.cds', { outputDirectory: dir, inlineDeclarations: 'structured' }) - const ast = new ASTWrapper(path.join(paths[2], 'index.ts')).tree + const ast = astwUnbound.tree checkFunction(ast.find(node => node.name === 'free'), { modifiersCheck: (modifiers = []) => !modifiers.some(check.isStatic), callCheck: type => check.isNullable(type) @@ -50,9 +53,7 @@ describe('Actions', () => { }) test('Bound Returning External Type', async () => { - const paths = await cds2ts('actions/model.cds', { outputDirectory: dir, inlineDeclarations: 'structured' }) - const astw = new ASTWrapper(path.join(paths[1], 'index.ts')) - const actions = astw.getAspectProperty('_EAspect', 'actions') + const actions = astwBound.getAspectProperty('_EAspect', 'actions') expect(actions.modifiers.some(check.isStatic)).toBeTruthy() checkFunction(actions.type.members.find(fn => fn.name === 'f'), { callCheck: signature => check.isAny(signature), @@ -72,8 +73,7 @@ describe('Actions', () => { }) test('Unbound Returning External Type', async () => { - const paths = await cds2ts('actions/model.cds', { outputDirectory: dir, inlineDeclarations: 'structured' }) - const ast = new ASTWrapper(path.join(paths[2], 'index.ts')).tree + const ast = astwUnbound.tree checkFunction(ast.find(node => node.name === 'free2'), { modifiersCheck: (modifiers = []) => !modifiers.some(check.isStatic), @@ -89,11 +89,8 @@ describe('Actions', () => { }) test('Bound Expecting $self Arguments', async () => { - const paths = await cds2ts('actions/model.cds', { outputDirectory: dir, inlineDeclarations: 'structured' }) - const astw = new ASTWrapper(path.join(paths[1], 'index.ts')) - const actions = astw.getAspectProperty('_EAspect', 'actions') + const actions = astwBound.getAspectProperty('_EAspect', 'actions') expect(actions.modifiers.some(check.isStatic)).toBeTruthy() - // mainly make sure $self parameter is not present at all checkFunction(actions.type.members.find(fn => fn.name === 's1'), { diff --git a/test/unit/arrayof.test.js b/test/unit/arrayof.test.js index 505193ae..d188c000 100644 --- a/test/unit/arrayof.test.js +++ b/test/unit/arrayof.test.js @@ -1,29 +1,16 @@ 'use strict' -const fs = require('fs').promises -const path = require('path') -const cds2ts = require('../../lib/compile') -const { ASTWrapper, checkFunction, check } = require('../ast') -const { locations } = require('../util') - -const dir = locations.testOutput('arrayof_test') - +const { checkFunction, check } = require('../ast') +const { locations, prepareUnitTest } = require('../util') describe('array of', () => { - let ast + let astw - beforeEach(async () => await fs.unlink(dir).catch(() => {})) - beforeAll(async () => { - const paths = await cds2ts - .compileFromFile(locations.unit.files('arrayof/model.cds'), { outputDirectory: dir, inlineDeclarations: 'structured' }) - // eslint-disable-next-line no-console - .catch((err) => console.error(err)) - ast = new ASTWrapper(path.join(paths[1], 'index.ts')) - }) + beforeAll(async () => astw = (await prepareUnitTest('arrayof/model.cds', locations.testOutput('arrayof_test'))).astw) describe('Entity Properties', () => { let aspect - beforeAll(async () => aspect = ast.tree.find(n => n.name === '_EAspect').body[0]) + beforeAll(async () => aspect = astw.tree.find(n => n.name === '_EAspect').body[0]) test('array of String', async () => { expect(aspect.members.find(m => m.name === 'stringz' @@ -59,7 +46,7 @@ describe('array of', () => { describe('Function', () => { let func - beforeAll(async () => func = ast.tree.find(n => n.name === 'fn')) + beforeAll(async () => func = astw.tree.find(n => n.name === 'fn')) test('Returning array of String', async () => { //expect(func.type.type.full === 'Array' && func.type.type.args[0].keyword === 'string').toBeTruthy() diff --git a/test/unit/autoexpose.test.js b/test/unit/autoexpose.test.js index 4498903e..1cd795ed 100644 --- a/test/unit/autoexpose.test.js +++ b/test/unit/autoexpose.test.js @@ -1,18 +1,11 @@ 'use strict' -const fs = require('fs').promises -const path = require('path') -const { ASTWrapper } = require('../ast') -const { locations, cds2ts } = require('../util') - -const dir = locations.testOutput('autoexpose_test') +const { locations, prepareUnitTest } = require('../util') describe('Autoexpose', () => { - beforeEach(async () => await fs.unlink(dir).catch(() => {})) + let ast + + beforeAll(async () => ast = (await prepareUnitTest('autoexpose/service.cds', locations.testOutput('autoexpose_test'))).astw.tree) - test('Autoexposed Composition Target Present in Service', async () => { - const paths = await cds2ts('autoexpose/service.cds', { outputDirectory: dir, inlineDeclarations: 'structured' }) - const ast = new ASTWrapper(path.join(paths[1], 'index.ts')).tree - expect(ast.find(n => n.name === 'Books')).toBeTruthy() - }) + test('Autoexposed Composition Target Present in Service', async () => expect(ast.find(n => n.name === 'Books')).toBeTruthy()) }) \ No newline at end of file diff --git a/test/unit/delimited.test.js b/test/unit/delimited.test.js index 80a387f0..5b4852b4 100644 --- a/test/unit/delimited.test.js +++ b/test/unit/delimited.test.js @@ -1,22 +1,11 @@ 'use strict' -const fs = require('fs').promises -const path = require('path') -const cds2ts = require('../../lib/compile') -const { ASTWrapper } = require('../ast') -const { locations } = require('../util') - -const dir = locations.testOutput('enums_test') +const { locations, prepareUnitTest } = require('../util') describe('Delimited Identifiers', () => { let astw - beforeEach(async () => await fs.unlink(dir).catch(() => {})) - beforeAll(async () => { - const paths = await cds2ts - .compileFromFile(locations.unit.files('delimident/model.cds'), { outputDirectory: dir, inlineDeclarations: 'structured' }) - astw = new ASTWrapper(path.join(paths[1], 'index.ts')) - }) + beforeAll(async () => astw = (await prepareUnitTest('delimident/model.cds', locations.testOutput('delimident_test'))).astw) test('Properties in Aspect Present', () => { expect(astw.getAspectProperty('_FooAspect', 'sap-icon://a')).toBeTruthy() diff --git a/test/unit/draft.test.js b/test/unit/draft.test.js index a3e5d8b0..2330844a 100644 --- a/test/unit/draft.test.js +++ b/test/unit/draft.test.js @@ -1,18 +1,15 @@ 'use strict' -const fs = require('fs').promises const path = require('path') -const cds2ts = require('../../lib/compile') const { ASTWrapper } = require('../ast') -const { locations } = require('../util') +const { locations, prepareUnitTest } = require('../util') -const dir = locations.testOutput('draft_test') const draftable_ = (entity, ast) => ast.find(n => n.name === entity && n.members.find(({name}) => name === 'drafts')) const draftable = (entity, ast, plural = e => `${e}_`) => draftable_(entity, ast) && draftable_(plural(entity), ast) describe('bookshop', () => { test('Projections Up and Down', async () => { - const paths = await cds2ts.compileFromFile(locations.unit.files('draft/catalog-service.cds'), { outputDirectory: dir }) + const paths = (await prepareUnitTest('draft/catalog-service.cds', locations.testOutput('bookshop_projection'))).paths const service = new ASTWrapper(path.join(paths[1], 'index.ts')).tree const model = new ASTWrapper(path.join(paths[2], 'index.ts')).tree @@ -26,12 +23,7 @@ describe('bookshop', () => { describe('@odata.draft.enabled', () => { let ast - beforeAll(async () => { - await fs.unlink(dir).catch(() => {}) - const paths = await cds2ts - .compileFromFile(locations.unit.files('draft/model.cds'), { outputDirectory: dir }) - ast = new ASTWrapper(path.join(paths[1], 'index.ts')).tree - }) + beforeAll(async () => ast = (await prepareUnitTest('draft/model.cds', locations.testOutput('draft_test'))).astw.tree) test('Direct Annotation', async () => expect(draftable('A', ast)).toBeTruthy()) diff --git a/test/unit/enum.test.js b/test/unit/enum.test.js index e0d7fa0b..bbcb863f 100644 --- a/test/unit/enum.test.js +++ b/test/unit/enum.test.js @@ -1,23 +1,14 @@ 'use strict' -const fs = require('fs').promises const path = require('path') -const cds2ts = require('../../lib/compile') -const { ASTWrapper, check, JSASTWrapper, checkFunction } = require('../ast') -const { locations } = require('../util') - -const dir = locations.testOutput('enums_test') +const { check, JSASTWrapper, checkFunction } = require('../ast') +const { locations, prepareUnitTest } = require('../util') // FIXME: missing: inline enums (entity Foo { bar: String enum { ... }}) describe('Enum Action Parameters', () => { let astw - beforeEach(async () => await fs.unlink(dir).catch(() => {})) - beforeAll(async () => { - const paths = await cds2ts - .compileFromFile(locations.unit.files('enums/actions.cds'), { outputDirectory: dir, inlineDeclarations: 'structured' }) - astw = new ASTWrapper(path.join(paths[1], 'index.ts')) - }) + beforeAll(async () => astw = (await prepareUnitTest('enums/actions.cds', locations.testOutput('enums_test_actions'))).astw) test('Coalescing Assignment Present', () => { const actions = astw.getAspectProperty('_FoobarAspect', 'actions') @@ -43,15 +34,13 @@ describe('Enum Action Parameters', () => { describe('Nested Enums', () => { let astw - beforeEach(async () => await fs.unlink(dir).catch(() => {})) beforeAll(async () => { - const paths = await cds2ts - .compileFromFile(locations.unit.files('enums/nested.cds'), { outputDirectory: dir, inlineDeclarations: 'structured' }) + const paths = (await prepareUnitTest('enums/nested.cds', locations.testOutput('enums_test_nested'))).paths astw = await JSASTWrapper.initialise(path.join(paths[1], 'index.js')) }) test('Coalescing Assignment Present', () => { - const stmts = astw.programm.body + const stmts = astw.program.body const enm = stmts.find(n => n.type === 'ExpressionStatement' && n.expression.type === 'AssignmentExpression' && n.expression.operator === '??=') expect(enm).toBeTruthy() const { left } = enm.expression @@ -64,12 +53,7 @@ describe('Nested Enums', () => { describe('Enum Types', () => { let astw - beforeEach(async () => await fs.unlink(dir).catch(() => {})) - beforeAll(async () => { - const paths = await cds2ts - .compileFromFile(locations.unit.files('enums/model.cds'), { outputDirectory: dir, inlineDeclarations: 'structured' }) - astw = new ASTWrapper(path.join(paths[1], 'index.ts')) - }) + beforeAll(async () => astw = (await prepareUnitTest('enums/model.cds', locations.testOutput('enums_test_model'))).astw) describe('Anonymous', () => { describe('Within type Definition', () => { diff --git a/test/unit/events.test.js b/test/unit/events.test.js index a120437e..836184a4 100644 --- a/test/unit/events.test.js +++ b/test/unit/events.test.js @@ -1,29 +1,16 @@ 'use strict' -const fs = require('fs').promises -const path = require('path') -const cds2ts = require('../../lib/compile') -const { ASTWrapper, check } = require('../ast') -const { locations } = require('../util') - -const dir = locations.testOutput('events_test') - +const { check } = require('../ast') +const { locations, prepareUnitTest } = require('../util') describe('events', () => { - let ast - - beforeEach(async () => await fs.unlink(dir).catch(() => {})) - beforeAll(async () => { - const paths = await cds2ts - .compileFromFile(locations.unit.files('events/model.cds'), { outputDirectory: dir, inlineDeclarations: 'structured' }) - // eslint-disable-next-line no-console - .catch((err) => console.error(err)) - ast = new ASTWrapper(path.join(paths[1], 'index.ts')) - }) + let astw + beforeAll(async () => astw = (await prepareUnitTest('events/model.cds', locations.testOutput('events_test'))).astw) + describe('Event Type Present', () => { test('Top Level Event', async () => { - expect(ast.tree.find(cls => cls.name === 'Bar' + expect(astw.tree.find(cls => cls.name === 'Bar' && cls.members.length === 2 && cls.members[0].name === 'id' && check.isNullable(cls.members[0].type, [check.isNumber]) && cls.members[1].name === 'name' && check.isNullable(cls.members[1].type, [check.isIndexedAccessType]) diff --git a/test/unit/excluding.test.js b/test/unit/excluding.test.js index c606b612..39b2de46 100644 --- a/test/unit/excluding.test.js +++ b/test/unit/excluding.test.js @@ -1,20 +1,13 @@ 'use strict' -const fs = require('fs').promises const path = require('path') -const cds2ts = require('../../lib/compile') const { ASTWrapper } = require('../ast') -const { locations } = require('../util') -const dir = locations.testOutput('excluding_test') +const { locations, prepareUnitTest } = require('../util') describe('Excluding Clause', () => { let paths - beforeEach(async () => await fs.unlink(dir).catch(() => {})) - beforeAll(async () => { - paths = await cds2ts - .compileFromFile(locations.unit.files('excluding/model.cds'), { outputDirectory: dir }) - }) + beforeAll(async () => paths = (await prepareUnitTest('excluding/model.cds', locations.testOutput('excluding_test'))).paths) test('Element Present in Original', async () => expect(new ASTWrapper(path.join(paths[1], 'index.ts')).exists('_TestObjectAspect', 'dependencies')).toBeTruthy()) diff --git a/test/unit/foreignkeys.test.js b/test/unit/foreignkeys.test.js index 1f7e7e41..abbad5cc 100644 --- a/test/unit/foreignkeys.test.js +++ b/test/unit/foreignkeys.test.js @@ -1,35 +1,24 @@ 'use strict' -const fs = require('fs').promises -const path = require('path') -const cds2ts = require('../../lib/compile') -const { ASTWrapper } = require('../ast') -const { locations } = require('../util') - -const dir = locations.testOutput('foreign_keys') +const { locations, prepareUnitTest } = require('../util') describe('Foreign Keys', () => { - let ast - beforeEach(async () => await fs.unlink(dir).catch(() => {})) - beforeAll(async () => { - const paths = await cds2ts - .compileFromFile(locations.unit.files('foreignkeys/model.cds'), { outputDirectory: dir }) - ast = new ASTWrapper(path.join(paths[1], 'index.ts')) - }) + let astw + beforeAll(async () => astw = (await prepareUnitTest('foreignkeys/model.cds', locations.testOutput('foreign_keys'))).astw) test('One Level Deep', async () => { - expect(ast.exists('_BAspect', 'c_ID', m => m.type.keyword === 'string')).toBeTruthy() - expect(ast.exists('_BAspect', 'd_ID', m => m.type.keyword === 'string')).toBeTruthy() - expect(ast.exists('_CAspect', 'e_ID', m => m.type.keyword === 'string')).toBeTruthy() + expect(astw.exists('_BAspect', 'c_ID', m => m.type.keyword === 'string')).toBeTruthy() + expect(astw.exists('_BAspect', 'd_ID', m => m.type.keyword === 'string')).toBeTruthy() + expect(astw.exists('_CAspect', 'e_ID', m => m.type.keyword === 'string')).toBeTruthy() }) test('Two Levels Deep', async () => { - expect(ast.exists('_AAspect', 'b_c_ID', m => m.type.keyword === 'string')).toBeTruthy() - expect(ast.exists('_AAspect', 'b_d_ID', m => m.type.keyword === 'string')).toBeTruthy() - expect(ast.exists('_BAspect', 'c_e_ID', m => m.type.keyword === 'string')).toBeTruthy() + expect(astw.exists('_AAspect', 'b_c_ID', m => m.type.keyword === 'string')).toBeTruthy() + expect(astw.exists('_AAspect', 'b_d_ID', m => m.type.keyword === 'string')).toBeTruthy() + expect(astw.exists('_BAspect', 'c_e_ID', m => m.type.keyword === 'string')).toBeTruthy() }) test('Three Levels Deep', async () => { - expect(ast.exists('_AAspect', 'b_c_e_ID', m => m.type.keyword === 'string')).toBeTruthy() + expect(astw.exists('_AAspect', 'b_c_e_ID', m => m.type.keyword === 'string')).toBeTruthy() }) }) \ No newline at end of file diff --git a/test/unit/hana.test.js b/test/unit/hana.test.js index ea3ad6c9..3dd4b6cd 100644 --- a/test/unit/hana.test.js +++ b/test/unit/hana.test.js @@ -1,50 +1,36 @@ 'use strict' -const path = require('path') -const cds2ts = require('../../lib/compile') -const { locations } = require('../util') -const { ASTWrapper, check } = require('../ast') +const { locations, prepareUnitTest } = require('../util') +const { check } = require('../ast') -const dir = locations.testOutput('hana_files') - -// compilation produces semantically complete Typescript describe('Builtin HANA Datatypes', () => { let paths - let ast + let astw - beforeAll(async () => { - paths = await cds2ts - .compileFromFile(locations.unit.files('hana/model.cds'), { - outputDirectory: dir, - }) - // eslint-disable-next-line no-console - .catch((err) => console.error(err)) - ast = new ASTWrapper(path.join(paths[1], 'index.ts')) - }) + beforeAll(async () => ({astw, paths} = await prepareUnitTest('hana/model.cds', locations.testOutput('hana_files')))) - test('Output Files Created', () => { - expect(paths).toHaveLength(3) // the one module [1] + baseDefinitions [0] + hana definitions [2] - }) + // the one module [1] + baseDefinitions [0] + hana definitions [2] + test('Output Files Created', () => expect(paths).toHaveLength(3)) test('Import of HANA Types Present', () => { - const imp = ast.getImports() + const imp = astw.getImports() expect(imp.length).toBe(2) expect(imp[0].as).toBe('_cds_hana') }) test('Types Correct', () => { - ast.exists('_EverythingAspect', 'bar', ({type}) => check.isNullable(type, [check.isString])) - ast.exists('_EverythingAspect', 'smallint', ({type}) => check.isNullable(type, [t => t.name === 'SMALLINT'])) - ast.exists('_EverythingAspect', 'tinyint', ({type}) => check.isNullable(type, [t => t.name === 'TINYINT'])) - ast.exists('_EverythingAspect', 'smalldecimal', ({type}) => check.isNullable(type, [t => t.name === 'SMALLDECIMAL'])) - ast.exists('_EverythingAspect', 'real', ({type}) => check.isNullable(type, [t => t.name === 'REAL'])) - ast.exists('_EverythingAspect', 'char', ({type}) => check.isNullable(type, [t => t.name === 'CHAR'])) - ast.exists('_EverythingAspect', 'nchar', ({type}) => check.isNullable(type, [t => t.name === 'NCHAR'])) - ast.exists('_EverythingAspect', 'varchar', ({type}) => check.isNullable(type, [t => t.name === 'VARCHAR'])) - ast.exists('_EverythingAspect', 'clob', ({type}) => check.isNullable(type, [t => t.name === 'CLOB'])) - ast.exists('_EverythingAspect', 'binary', ({type}) => check.isNullable(type, [t => t.name === 'BINARY'])) - ast.exists('_EverythingAspect', 'point', ({type}) => check.isNullable(type, [t => t.name === 'ST_POINT'])) - ast.exists('_EverythingAspect', 'geometry', ({type}) => check.isNullable(type, [t => t.name === 'ST_GEOMETRY'])) - ast.exists('_EverythingAspect', 'shorthand', ({type}) => check.isNullable(type, [t => t.name === 'REAL'])) + astw.exists('_EverythingAspect', 'bar', ({type}) => check.isNullable(type, [check.isString])) + astw.exists('_EverythingAspect', 'smallint', ({type}) => check.isNullable(type, [t => t.name === 'SMALLINT'])) + astw.exists('_EverythingAspect', 'tinyint', ({type}) => check.isNullable(type, [t => t.name === 'TINYINT'])) + astw.exists('_EverythingAspect', 'smalldecimal', ({type}) => check.isNullable(type, [t => t.name === 'SMALLDECIMAL'])) + astw.exists('_EverythingAspect', 'real', ({type}) => check.isNullable(type, [t => t.name === 'REAL'])) + astw.exists('_EverythingAspect', 'char', ({type}) => check.isNullable(type, [t => t.name === 'CHAR'])) + astw.exists('_EverythingAspect', 'nchar', ({type}) => check.isNullable(type, [t => t.name === 'NCHAR'])) + astw.exists('_EverythingAspect', 'varchar', ({type}) => check.isNullable(type, [t => t.name === 'VARCHAR'])) + astw.exists('_EverythingAspect', 'clob', ({type}) => check.isNullable(type, [t => t.name === 'CLOB'])) + astw.exists('_EverythingAspect', 'binary', ({type}) => check.isNullable(type, [t => t.name === 'BINARY'])) + astw.exists('_EverythingAspect', 'point', ({type}) => check.isNullable(type, [t => t.name === 'ST_POINT'])) + astw.exists('_EverythingAspect', 'geometry', ({type}) => check.isNullable(type, [t => t.name === 'ST_GEOMETRY'])) + astw.exists('_EverythingAspect', 'shorthand', ({type}) => check.isNullable(type, [t => t.name === 'REAL'])) }) }) \ No newline at end of file diff --git a/test/unit/inline.test.js b/test/unit/inline.test.js index d93582e0..4638821a 100644 --- a/test/unit/inline.test.js +++ b/test/unit/inline.test.js @@ -1,25 +1,12 @@ 'use strict' -const fs = require('fs').promises -const path = require('path') -const cds2ts = require('../../lib/compile') -const { ASTWrapper, check } = require('../ast') -const { locations } = require('../util') +const { check } = require('../ast') +const { locations, prepareUnitTest } = require('../util') -const dir = locations.testOutput('inline_test') -console.log(check) - -// compilation produces semantically complete Typescript describe('Inline Type Declarations', () => { - beforeEach(async () => await fs.unlink(dir).catch(() => {})) //console.log('INFO', `Unable to unlink '${dir}' (${err}). This may not be an issue.`) - test('Structured', async () => { - const paths = await cds2ts - .compileFromFile(locations.unit.files('inline/model.cds'), { outputDirectory: dir, inlineDeclarations: 'structured' }) - // eslint-disable-next-line no-console - .catch((err) => console.error(err)) - const ast = new ASTWrapper(path.join(paths[1], 'index.ts')) - expect(ast.exists('_BarAspect', 'x', ({name, type}) => { + const astw = (await prepareUnitTest('inline/model.cds', locations.testOutput('inline_test_structured'))).astw + expect(astw.exists('_BarAspect', 'x', ({name, type}) => { const [nonNullType] = type.subtypes const [a, y] = nonNullType.members const [b, c] = a.type.subtypes[0].members @@ -38,13 +25,9 @@ describe('Inline Type Declarations', () => { }) test('Flat', async () => { - const paths = await cds2ts - .compileFromFile(locations.unit.files('inline/model.cds'), { outputDirectory: dir, inlineDeclarations: 'flat' }) - // eslint-disable-next-line no-console - .catch((err) => console.error(err)) - const ast = new ASTWrapper(path.join(paths[1], 'index.ts')) - expect(ast.exists('_BarAspect', 'x_a_b', ({type}) => check.isNullable(type, [check.isNumber]))).toBeTruthy() - expect(ast.exists('_BarAspect', 'x_y', ({type}) => check.isNullable(type, [check.isString]))).toBeTruthy() - expect(ast.exists('_BarAspect', 'x_a_c', ({type}) => check.isNullable(type, [m => m.name === 'to' && m.args[0].full === 'Foo' ]))).toBeTruthy() + const astw = (await prepareUnitTest('inline/model.cds', locations.testOutput('inline_test_flat'), { inlineDeclarations: 'flat' })).astw + expect(astw.exists('_BarAspect', 'x_a_b', ({type}) => check.isNullable(type, [check.isNumber]))).toBeTruthy() + expect(astw.exists('_BarAspect', 'x_y', ({type}) => check.isNullable(type, [check.isString]))).toBeTruthy() + expect(astw.exists('_BarAspect', 'x_a_c', ({type}) => check.isNullable(type, [m => m.name === 'to' && m.args[0].full === 'Foo' ]))).toBeTruthy() }) }) \ No newline at end of file diff --git a/test/unit/notnull.test.js b/test/unit/notnull.test.js index 66c3a3ff..7ac1a229 100644 --- a/test/unit/notnull.test.js +++ b/test/unit/notnull.test.js @@ -1,23 +1,14 @@ 'use strict' -const fs = require('fs').promises -const path = require('path') -const cds2ts = require('../../lib/compile') -const { ASTWrapper, check, checkFunction } = require('../ast') -const { locations } = require('../util') +const { check, checkFunction } = require('../ast') +const { locations, prepareUnitTest } = require('../util') const dir = locations.testOutput('not_null_test') - describe('Not Null', () => { let astw - beforeEach(async () => await fs.unlink(dir).catch(() => {})) - beforeAll(async () => { - const paths = await cds2ts - .compileFromFile(locations.unit.files('notnull/model.cds'), { outputDirectory: dir, inlineDeclarations: 'structured' }) - astw = new ASTWrapper(path.join(paths[1], 'index.ts')) - }) + beforeAll(async () => astw = (await prepareUnitTest('notnull/model.cds', dir)).astw) describe('Properties', () => { test('Primitive', async () => diff --git a/test/unit/output.test.js b/test/unit/output.test.js index 1b780d6f..c05bd093 100644 --- a/test/unit/output.test.js +++ b/test/unit/output.test.js @@ -1,28 +1,16 @@ 'use strict' -const fs = require('fs/promises') const path = require('path') -const cds2ts = require('../../lib/compile') -const { ASTWrapper, JSASTWrapper, check } = require('../ast') -const { locations } = require('../util') +const { JSASTWrapper, check } = require('../ast') +const { locations, prepareUnitTest } = require('../util') -const dir = locations.testOutput('output_test') - -// compilation produces semantically complete Typescript describe('Compilation', () => { - //console.log('INFO', `Unable to unlink '${dir}' (${err}). This may not be an issue.`) - beforeEach(() => fs.unlink(dir).catch(() => {})) - let paths - let ast + let astw describe('Bookshoplet', () => { - beforeAll(async () => { - paths = await cds2ts - .compileFromFile(locations.unit.files('bookshoplet/model.cds'), { outputDirectory: dir }) - ast = new ASTWrapper(path.join(paths[1], 'index.ts')) - }) + beforeAll(async () => ({paths, astw} = await prepareUnitTest('bookshoplet/model.cds', locations.testOutput('output_test/bookshoplet')))) test('index.js', async () => { const jsw = await JSASTWrapper.initialise(path.join(paths[1], 'index.js')) @@ -51,7 +39,7 @@ describe('Compilation', () => { test('Generated Paths', () => expect(paths).toHaveLength(2)) // the one module [1] + baseDefinitions [0] test('Aspects', () => { - const aspects = ast.getAspects() + const aspects = astw.getAspects() const expected = [ '_BookAspect', '_AuthorAspect', @@ -68,7 +56,7 @@ describe('Compilation', () => { }) test('Aspect Functions', () => { - const fns = ast.getAspectFunctions() + const fns = astw.getAspectFunctions() const expected = [ '_BookAspect', '_AuthorAspect', @@ -85,7 +73,7 @@ describe('Compilation', () => { }) test('Classes', () => { - const fns = ast.getTopLevelClassDeclarations() + const fns = astw.getTopLevelClassDeclarations() const expected = [ 'Book', 'Books', @@ -112,55 +100,39 @@ describe('Compilation', () => { }) describe('Builtin Types', () => { - let paths - let ast + let astw - beforeAll(async () => { - paths = await cds2ts - .compileFromFile(locations.unit.files('builtins/model.cds'), { - outputDirectory: dir, - }) - // eslint-disable-next-line no-console - .catch((err) => console.error(err)) - ast = new ASTWrapper(path.join(paths[1], 'index.ts')) - }) + beforeAll(async () => astw = (await prepareUnitTest('builtins/model.cds', locations.testOutput('output_test/builtin'))).astw) test('Primitives', () => { - expect(ast.exists('_EAspect', 'uuid', m => check.isNullable(m.type, [check.isString]))).toBeTruthy() - expect(ast.exists('_EAspect', 'str', m => check.isNullable(m.type, [check.isString]))).toBeTruthy() - expect(ast.exists('_EAspect', 'bin', m => check.isNullable(m.type, [check.isString]))).toBeTruthy() - expect(ast.exists('_EAspect', 'lstr', m => check.isNullable(m.type, [check.isString]))).toBeTruthy() - expect(ast.exists('_EAspect', 'lbin', m => check.isUnionType(m.type, [ + expect(astw.exists('_EAspect', 'uuid', m => check.isNullable(m.type, [check.isString]))).toBeTruthy() + expect(astw.exists('_EAspect', 'str', m => check.isNullable(m.type, [check.isString]))).toBeTruthy() + expect(astw.exists('_EAspect', 'bin', m => check.isNullable(m.type, [check.isString]))).toBeTruthy() + expect(astw.exists('_EAspect', 'lstr', m => check.isNullable(m.type, [check.isString]))).toBeTruthy() + expect(astw.exists('_EAspect', 'lbin', m => check.isUnionType(m.type, [ st => st.full === 'Buffer', check.isString ]))).toBeTruthy() - expect(ast.exists('_EAspect', 'integ', m => check.isNullable(m.type, [check.isNumber]))).toBeTruthy() - expect(ast.exists('_EAspect', 'uint8', m => check.isNullable(m.type, [check.isNumber]))).toBeTruthy() - expect(ast.exists('_EAspect', 'int16', m => check.isNullable(m.type, [check.isNumber]))).toBeTruthy() - expect(ast.exists('_EAspect', 'int32', m => check.isNullable(m.type, [check.isNumber]))).toBeTruthy() - expect(ast.exists('_EAspect', 'int64', m => check.isNullable(m.type, [check.isNumber]))).toBeTruthy() - expect(ast.exists('_EAspect', 'integer64', m => check.isNullable(m.type, [check.isNumber]))).toBeTruthy() - expect(ast.exists('_EAspect', 'dec', m => check.isNullable(m.type, [check.isNumber]))).toBeTruthy() - expect(ast.exists('_EAspect', 'doub', m => check.isNullable(m.type, [check.isNumber]))).toBeTruthy() - expect(ast.exists('_EAspect', 'd', m => check.isNullable(m.type, [check.isString]))).toBeTruthy() - expect(ast.exists('_EAspect', 'dt', m => check.isNullable(m.type, [check.isString]))).toBeTruthy() - expect(ast.exists('_EAspect', 'ts', m => check.isNullable(m.type, [check.isString]))).toBeTruthy() + expect(astw.exists('_EAspect', 'integ', m => check.isNullable(m.type, [check.isNumber]))).toBeTruthy() + expect(astw.exists('_EAspect', 'uint8', m => check.isNullable(m.type, [check.isNumber]))).toBeTruthy() + expect(astw.exists('_EAspect', 'int16', m => check.isNullable(m.type, [check.isNumber]))).toBeTruthy() + expect(astw.exists('_EAspect', 'int32', m => check.isNullable(m.type, [check.isNumber]))).toBeTruthy() + expect(astw.exists('_EAspect', 'int64', m => check.isNullable(m.type, [check.isNumber]))).toBeTruthy() + expect(astw.exists('_EAspect', 'integer64', m => check.isNullable(m.type, [check.isNumber]))).toBeTruthy() + expect(astw.exists('_EAspect', 'dec', m => check.isNullable(m.type, [check.isNumber]))).toBeTruthy() + expect(astw.exists('_EAspect', 'doub', m => check.isNullable(m.type, [check.isNumber]))).toBeTruthy() + expect(astw.exists('_EAspect', 'd', m => check.isNullable(m.type, [check.isString]))).toBeTruthy() + expect(astw.exists('_EAspect', 'dt', m => check.isNullable(m.type, [check.isString]))).toBeTruthy() + expect(astw.exists('_EAspect', 'ts', m => check.isNullable(m.type, [check.isString]))).toBeTruthy() }) }) describe('Inflection', () => { let paths - let ast + let astw + + beforeAll(async () => ({paths, astw} = await prepareUnitTest('inflection/model.cds', locations.testOutput('output_test/inflection')))) - beforeAll(async () => { - paths = await cds2ts - .compileFromFile(locations.unit.files('inflection/model.cds'), { - outputDirectory: dir, - }) - // eslint-disable-next-line no-console - .catch((err) => console.error(err)) - ast = new ASTWrapper(path.join(paths[1], 'index.ts')) - }) test('Generated Paths', () => expect(paths).toHaveLength(2)) // the one module [1] + baseDefinitions [0] @@ -193,7 +165,7 @@ describe('Compilation', () => { }) test('Aspects', () => { - const aspects = ast.getAspects() + const aspects = astw.getAspects() const expected = [ '_GizmoAspect', '_FooSingularAspect', @@ -209,7 +181,7 @@ describe('Compilation', () => { }) test('Classes', () => { - const fns = ast.getTopLevelClassDeclarations() + const fns = astw.getTopLevelClassDeclarations() const expected = [ 'Gizmo', 'Gizmos', @@ -233,34 +205,34 @@ describe('Compilation', () => { }) test('Annotated Assoc/ Comp', () => { - expect(ast.exists('_RefererAspect', 'a', m => check.isNullable(m.type, [ + expect(astw.exists('_RefererAspect', 'a', m => check.isNullable(m.type, [ ({name, args}) => name === 'to' && args[0].name === 'BazSingular' ]))).toBeTruthy() - expect(ast.exists('_RefererAspect', 'b', m => true + expect(astw.exists('_RefererAspect', 'b', m => true && m.type.name === 'many' && m.type.args[0].name === 'BazPlural' )).toBeTruthy() - expect(ast.exists('_RefererAspect', 'c', m => check.isNullable(m.type, [ + expect(astw.exists('_RefererAspect', 'c', m => check.isNullable(m.type, [ ({name, args}) => name === 'of' && args[0].name === 'BazSingular' ]))).toBeTruthy() - expect(ast.exists('_RefererAspect', 'd', m => true + expect(astw.exists('_RefererAspect', 'd', m => true && m.type.name === 'many' && m.type.args[0].name === 'BazPlural' )).toBeTruthy() }) test('Inferred Assoc/ Comp', () => { - expect(ast.exists('_RefererAspect', 'e', m => check.isNullable(m.type, [ + expect(astw.exists('_RefererAspect', 'e', m => check.isNullable(m.type, [ ({name, args}) => name === 'to' && args[0].name === 'Gizmo' ]))).toBeTruthy() - expect(ast.exists('_RefererAspect', 'f', m => true + expect(astw.exists('_RefererAspect', 'f', m => true && m.type.name === 'many' && m.type.args[0].name === 'Gizmos' )).toBeTruthy() - expect(ast.exists('_RefererAspect', 'g', m => check.isNullable(m.type, [ + expect(astw.exists('_RefererAspect', 'g', m => check.isNullable(m.type, [ ({name, args}) => name === 'of' && args[0].name === 'Gizmo' ]))).toBeTruthy() - expect(ast.exists('_RefererAspect', 'h', m => true + expect(astw.exists('_RefererAspect', 'h', m => true && m.type.name === 'many' && m.type.args[0].name === 'Gizmos' )).toBeTruthy() diff --git a/test/unit/references.test.js b/test/unit/references.test.js index 5695a9d9..ef00a9a1 100644 --- a/test/unit/references.test.js +++ b/test/unit/references.test.js @@ -1,47 +1,35 @@ 'use strict' -const fs = require('fs').promises -const path = require('path') -const cds2ts = require('../../lib/compile') -const { ASTWrapper, check } = require('../ast') -const { locations } = require('../util') +const { check } = require('../ast') +const { locations, prepareUnitTest } = require('../util') -const dir = locations.testOutput('output/references') - -// compilation produces semantically complete Typescript describe('References', () => { - beforeEach(async () => await fs.unlink(dir).catch(() => {})) //console.log('INFO', `Unable to unlink '${dir}' (${err}). This may not be an issue.`) + let astw + + beforeAll(async () => astw = (await prepareUnitTest('references/model.cds', locations.testOutput('references_test'))).astw) test('Entity', async () => { - const paths = await cds2ts - .compileFromFile(locations.unit.files('references/model.cds'), { outputDirectory: dir, inlineDeclarations: 'structured' }) - const ast = new ASTWrapper(path.join(paths[1], 'index.ts')) - expect(ast.exists('_BarAspect', 'assoc_one', m => check.isNullable(m.type, [ + expect(astw.exists('_BarAspect', 'assoc_one', m => check.isNullable(m.type, [ ({name, args}) => name === 'to' && args[0].name === 'Foo' ]))).toBeTruthy() - expect(ast.exists('_BarAspect', 'assoc_many', m => true + expect(astw.exists('_BarAspect', 'assoc_many', m => true && m.type.name === 'many' && m.type.args[0].name === 'Foo_' )).toBeTruthy() - expect(ast.exists('_BarAspect', 'comp_one', m => check.isNullable(m.type, [ + expect(astw.exists('_BarAspect', 'comp_one', m => check.isNullable(m.type, [ ({name, args}) => name === 'of' && args[0].name === 'Foo' ]))).toBeTruthy() - expect(ast.exists('_BarAspect', 'comp_many', m => true + expect(astw.exists('_BarAspect', 'comp_many', m => true && m.type.name === 'many' && m.type.args[0].name === 'Foo_' )).toBeTruthy() - expect(ast.exists('_BarAspect', 'assoc_one_first_key', m => check.isNullable(m.type, [check.isString]))).toBeTruthy() - expect(ast.exists('_BarAspect', 'assoc_one_second_key', m => check.isNullable(m.type, [check.isString]))).toBeTruthy() - expect(ast.exists('_BarAspect', 'assoc_one_ID', m => check.isNullable(m.type, [check.isString]))).toBeTruthy() + expect(astw.exists('_BarAspect', 'assoc_one_first_key', m => check.isNullable(m.type, [check.isString]))).toBeTruthy() + expect(astw.exists('_BarAspect', 'assoc_one_second_key', m => check.isNullable(m.type, [check.isString]))).toBeTruthy() + expect(astw.exists('_BarAspect', 'assoc_one_ID', m => check.isNullable(m.type, [check.isString]))).toBeTruthy() }) test('Inline', async () => { - const paths = await cds2ts - .compileFromFile(locations.unit.files('references/model.cds'), { outputDirectory: dir, inlineDeclarations: 'structured' }) - // eslint-disable-next-line no-console - .catch((err) => console.error(err)) - const ast = new ASTWrapper(path.join(paths[1], 'index.ts')) - expect(ast.exists('_BarAspect', 'inl_comp_one', m => { + expect(astw.exists('_BarAspect', 'inl_comp_one', m => { const comp = m.type.subtypes[0] const [a] = comp.args[0].members return check.isNullable(m.type) @@ -49,7 +37,7 @@ describe('References', () => { && a.name === 'a' && check.isNullable(a.type, [check.isString]) })).toBeTruthy() - expect(ast.exists('_BarAspect', 'inl_comp_many', m => { + expect(astw.exists('_BarAspect', 'inl_comp_many', m => { const [arr] = m.type.args return m.type.name === 'many' && arr.name === 'Array' @@ -57,6 +45,6 @@ describe('References', () => { && check.isNullable(arr.args[0].members[0].type, [check.isString]) })).toBeTruthy() // inline ID is not propagated into the parent entity - expect(() => ast.exists('_BarAspect', 'inl_comp_one_ID')).toThrow(Error) + expect(() => astw.exists('_BarAspect', 'inl_comp_one_ID')).toThrow(Error) }) }) \ No newline at end of file diff --git a/test/unit/scoped.test.js b/test/unit/scoped.test.js index 2f7dedb4..8725f4e3 100644 --- a/test/unit/scoped.test.js +++ b/test/unit/scoped.test.js @@ -1,22 +1,11 @@ 'use strict' -const fs = require('fs').promises -const path = require('path') -const cds2ts = require('../../lib/compile') -const { ASTWrapper } = require('../ast') -const { locations } = require('../util') - -const dir = locations.testOutput('scoped_test') +const { locations, prepareUnitTest } = require('../util') describe('Scoped Entities', () => { let astw - beforeEach(async () => await fs.unlink(dir).catch(() => {})) - beforeAll(async () => { - const paths = await cds2ts - .compileFromFile(locations.unit.files('scoped/model.cds'), { outputDirectory: dir, inlineDeclarations: 'structured' }) - astw = new ASTWrapper(path.join(paths[1], 'index.ts')) - }) + beforeAll(async () => astw = (await prepareUnitTest('scoped/model.cds', locations.testOutput('scoped_test'))).astw) test('Namespace Exists', () => expect(astw.getModuleDeclaration('Name')).toBeTruthy()) test('Namespace Entity Exists', () => expect(astw.getAspect('_NameAspect')).toBeTruthy()) diff --git a/test/unit/type.test.js b/test/unit/type.test.js index c1eda719..f6469310 100644 --- a/test/unit/type.test.js +++ b/test/unit/type.test.js @@ -1,34 +1,20 @@ 'use strict' -const fs = require('fs').promises -const path = require('path') -const cds2ts = require('../../lib/compile') -const { ASTWrapper } = require('../ast') -const { locations } = require('../util') - -const dir = locations.testOutput('type_test') - +const { locations, prepareUnitTest } = require('../util') describe('type Definitions', () => { - let ast + let astw - beforeEach(async () => await fs.unlink(dir).catch(() => {})) - beforeAll(async () => { - const paths = await cds2ts - .compileFromFile(locations.unit.files('type/model.cds'), { outputDirectory: dir, inlineDeclarations: 'structured' }) - // eslint-disable-next-line no-console - .catch((err) => console.error(err)) - ast = new ASTWrapper(path.join(paths[1], 'index.ts')) - }) + beforeAll(async () => astw = (await prepareUnitTest('type/model.cds', locations.testOutput('type_test'))).astw) test('All Definitions Present', async () => { - expect(ast.tree.find(({name, nodeType}) => name === 'IntAlias' && nodeType === 'typeAliasDeclaration')).toBeTruthy() - expect(ast.tree.find(({name, nodeType}) => name === 'Points' && nodeType === 'classDeclaration')).toBeTruthy() - expect(ast.tree.find(({name, nodeType}) => name === 'Lines' && nodeType === 'typeAliasDeclaration')).toBeTruthy() + expect(astw.tree.find(({name, nodeType}) => name === 'IntAlias' && nodeType === 'typeAliasDeclaration')).toBeTruthy() + expect(astw.tree.find(({name, nodeType}) => name === 'Points' && nodeType === 'classDeclaration')).toBeTruthy() + expect(astw.tree.find(({name, nodeType}) => name === 'Lines' && nodeType === 'typeAliasDeclaration')).toBeTruthy() }) test('Types as Properties', async () => { - const members = ast.tree.find(def => def.name === '_PersonAspect').body[0].members + const members = astw.tree.find(def => def.name === '_PersonAspect').body[0].members expect(members.find(({name, type}) => name === 'id' && type.full === 'IntAlias')) expect(members.find(({name, type}) => name === 'pos' && type.full === 'Points')) expect(members.find(({name, type}) => name === 'history' && type.full === 'Array' && type.args[0].full === 'Points')) diff --git a/test/unit/typeof.test.js b/test/unit/typeof.test.js index e2695279..7b891825 100644 --- a/test/unit/typeof.test.js +++ b/test/unit/typeof.test.js @@ -1,62 +1,35 @@ 'use strict' -const fs = require('fs').promises -const path = require('path') -const cds2ts = require('../../lib/compile') -const { ASTWrapper, check } = require('../ast') -const { locations } = require('../util') +const { check } = require('../ast') +const { locations, prepareUnitTest } = require('../util') -const dir = locations.testOutput('typeof') - -// compilation produces semantically complete Typescript describe('Typeof Syntax', () => { - beforeEach(async () => await fs.unlink(dir).catch(() => {})) //console.log('INFO', `Unable to unlink '${dir}' (${err}). This may not be an issue.`) test('Structured', async () => { - const paths = await cds2ts - .compileFromFile(locations.unit.files('typeof/model.cds'), { outputDirectory: dir, inlineDeclarations: 'structured' }) - // eslint-disable-next-line no-console - .catch((err) => console.error(err)) - const ast = new ASTWrapper(path.join(paths[1], 'index.ts')) - expect(ast.exists('_BarAspect', 'ref_a', + const astw = (await prepareUnitTest('typeof/model.cds', locations.testOutput('typeof_structured'))).astw + expect(astw.exists('_BarAspect', 'ref_a', m => check.isNullable(m.type, [st => check.isIndexedAccessType(st) && st.indexType.literal === 'a']) )).toBeTruthy() - expect(ast.exists('_BarAspect', 'ref_b', + expect(astw.exists('_BarAspect', 'ref_b', m => check.isNullable(m.type, [st => check.isIndexedAccessType(st) && st.indexType.literal === 'b']) )).toBeTruthy() // meh, this is not exactly correct, as I apparently did not retrieve the chained type accesses properly, // but it's kinda good enough - expect(ast.exists('_BarAspect', 'ref_c', + expect(astw.exists('_BarAspect', 'ref_c', m => check.isNullable(m.type, [st => check.isIndexedAccessType(st) && st.indexType.literal === 'x']) )).toBeTruthy() }) test('Flat', async () => { - const paths = await cds2ts - .compileFromFile(locations.unit.files('typeof/model.cds'), { outputDirectory: dir }) - // eslint-disable-next-line no-console - .catch((err) => console.error(err)) - const ast = new ASTWrapper(path.join(paths[1], 'index.ts')) - expect(ast.exists('_BarAspect', 'ref_a', + const astw = (await prepareUnitTest('typeof/model.cds', locations.testOutput('typeof_flat'), { inlineDeclarations: 'flat' })).astw + expect(astw.exists('_BarAspect', 'ref_a', m => check.isNullable(m.type, [st => check.isIndexedAccessType(st) && st.indexType.literal === 'a']) )).toBeTruthy() - expect(ast.exists('_BarAspect', 'ref_b', + expect(astw.exists('_BarAspect', 'ref_b', m => check.isNullable(m.type, [st => check.isIndexedAccessType(st) && st.indexType.literal === 'b']) )).toBeTruthy() - expect(ast.exists('_BarAspect', 'ref_c', + expect(astw.exists('_BarAspect', 'ref_c', m => check.isNullable(m.type, [st => check.isIndexedAccessType(st) && st.indexType.literal === 'c_x']) )).toBeTruthy() - /* - && m.type.members.length === 2 - && m.type.members[0].name === 'a' - && m.type.members[0].type.members.length === 2 - && m.type.members[0].type.members[0].name === 'b' - && m.type.members[0].type.members[0].type.keyword === 'number' - && m.type.members[0].type.members[1].name === 'c' - && m.type.members[0].type.members[1].type.nodeType === 'typeReference' - && m.type.members[0].type.members[1].type.args[0].full === 'Foo' - && m.type.members[1].name === 'y' - && m.type.members[1].type.keyword === 'string' - */ }) }) \ No newline at end of file diff --git a/test/unit/views.test.js b/test/unit/views.test.js index 187299de..1eafab3c 100644 --- a/test/unit/views.test.js +++ b/test/unit/views.test.js @@ -1,35 +1,23 @@ 'use strict' -const fs = require('fs').promises -const path = require('path') -const cds2ts = require('../../lib/compile') -const { ASTWrapper, check } = require('../ast') -const { locations } = require('../util') - -const dir = locations.testOutput('views_test') +const { check } = require('../ast') +const { locations, prepareUnitTest } = require('../util') describe('View Entities', () => { let astw - beforeEach(async () => await fs.unlink(dir).catch(() => {})) - beforeAll(async () => { - const paths = await cds2ts - .compileFromFile(locations.unit.files('views/model.cds'), { outputDirectory: dir, inlineDeclarations: 'structured' }) - astw = new ASTWrapper(path.join(paths[1], 'index.ts')) - }) + beforeAll(async () => astw = (await prepareUnitTest('views/model.cds', locations.testOutput('views_test'))).astw) - test('View Entity Present', () => { - astw.exists('_FooViewAspect') - }) + test('View Entity Present', () => expect(astw.exists('_FooViewAspect')).toBeTruthy()) test('Expected Properties Present', () => { - astw.exists('_FooViewAspect', 'id', ({type}) => check.isNullable(type, [check.isNumber])) - astw.exists('_FooViewAspect', 'code', ({type}) => check.isNullable(type, [check.isString])) + expect(astw.exists('_FooViewAspect', 'id', ({type}) => check.isNullable(type, [check.isNumber]))).toBeTruthy() + expect(astw.exists('_FooViewAspect', 'code', ({type}) => check.isNullable(type, [check.isString]))).toBeTruthy() // including alias - astw.exists('_FooViewAspect', 'alias', ({type}) => check.isNullable(type, [check.isString])) + expect(astw.exists('_FooViewAspect', 'alias', ({type}) => check.isNullable(type, [check.isString]))).toBeTruthy() }) - test('Unselected Field Not Present', () => { - expect(() => astw.exists('_FooViewAspect', 'flag', ({type}) => check.isNullable(type, [check.isString]))).toThrow(Error) + test('Unselected Field Not Present', () => { expect(() => + expect(astw.exists('_FooViewAspect', 'flag', ({type}) => check.isNullable(type, [check.isString]))).toThrow(Error)).toBeTruthy() }) }) diff --git a/test/util.d.ts b/test/util.d.ts index 1dd6921b..edd395bd 100644 --- a/test/util.d.ts +++ b/test/util.d.ts @@ -17,4 +17,6 @@ export interface TSParseResult { export class TSParser { private _parseClassBody(lines: string[]): ClassBody public parse(file: string): TSParseResult; -} \ No newline at end of file +} + +declare function prepareUnitTest(model: string, outputDirectory: string, typerOptions?: {}, fileSelector?: (paths: string[]) => string): void; diff --git a/test/util.js b/test/util.js index 6394d073..d0582d6f 100644 --- a/test/util.js +++ b/test/util.js @@ -1,11 +1,12 @@ /* eslint-disable no-console */ const fs = require('fs') +const { unlink } = require('fs').promises const path = require('path') const { Logger } = require('../lib/logging') const { fail } = require('assert') const os = require('os') const typer = require('../lib/compile') - +const { ASTWrapper } = require('./ast') /** * Hackish. When having code as string, we can either: @@ -319,6 +320,15 @@ const cds2ts = async (cdsFile, options = {}) => typer.compileFromFile( options ) +async function prepareUnitTest(model, outputDirectory, typerOptions = {}, fileSelector = paths => paths[1]) { + const options = {...{ outputDirectory: outputDirectory, inlineDeclarations: 'structured' }, ...typerOptions} + await unlink(outputDirectory).catch(() => {}) + const paths = await cds2ts(model, options) + // eslint-disable-next-line no-console + .catch((err) => console.error(err)) + return { astw: new ASTWrapper(path.join(fileSelector(paths), 'index.ts')), paths } +} + module.exports = { loadModule, toHaveAll, @@ -329,5 +339,6 @@ module.exports = { validateDTSTypes, toHavePropertyOfType, locations, - cds2ts + cds2ts, + prepareUnitTest }