From 3605154748bb721eab6037a7dfe1ff32a51e0c89 Mon Sep 17 00:00:00 2001 From: Daniel O'Grady <103028279+daogrady@users.noreply.github.com> Date: Tue, 19 Dec 2023 18:20:20 +0100 Subject: [PATCH] Export inline enums as coalesced static properties (#131) * Export inline enums as coalesced static properties * Add test case for nested enums * Add changelog entry --- CHANGELOG.md | 3 +++ lib/components/enum.js | 3 ++- lib/file.js | 2 +- test/unit/enum.test.js | 24 +++++++++++++++++++++++- test/unit/files/enums/nested.cds | 8 ++++++++ 5 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 test/unit/files/enums/nested.cds diff --git a/CHANGELOG.md b/CHANGELOG.md index 50200041..7fbfd909 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/). ### Added - Support for [scoped entities](https://cap.cloud.sap/docs/cds/cdl#scoped-names) +### Fixed +- Inline enums are now available during runtime as well + ## Version 0.14.0 - 2023-12-13 ### Added - Entities that are database views now also receive typings diff --git a/lib/components/enum.js b/lib/components/enum.js index a733b662..bcf08c15 100644 --- a/lib/components/enum.js +++ b/lib/components/enum.js @@ -104,7 +104,8 @@ const isInlineEnumType = (element, csn) => element.enum && !(element.type in csn * @param {string} name * @param {[string, string][]} kvs a list of key-value pairs. Values that are falsey are replaced by */ -const stringifyEnumImplementation = (name, kvs) => `module.exports.${name} = { ${kvs.map(([k,v]) => `${k}: ${v}`).join(', ')} }` +// ??= for inline enums. If there is some static property of that name, we don't want to override it (for example: ".actions" +const stringifyEnumImplementation = (name, kvs) => `module.exports.${name} ??= { ${kvs.map(([k,v]) => `${k}: ${v}`).join(', ')} }` module.exports = { diff --git a/lib/file.js b/lib/file.js index 9647e18a..2b77ea59 100644 --- a/lib/file.js +++ b/lib/file.js @@ -268,7 +268,7 @@ class SourceFile extends File { */ addInlineEnum(entityCleanName, entityFqName, propertyName, kvs) { this.enums.data.push({ - name: entityFqName, + name: `${entityCleanName}.${propertyName}`, property: propertyName, kvs, fq: `${entityCleanName}.${propertyName}` diff --git a/test/unit/enum.test.js b/test/unit/enum.test.js index cce3c131..4e14e11b 100644 --- a/test/unit/enum.test.js +++ b/test/unit/enum.test.js @@ -3,12 +3,34 @@ const fs = require('fs').promises const path = require('path') const cds2ts = require('../../lib/compile') -const { ASTWrapper, check } = require('../ast') +const { ASTWrapper, check, JSASTWrapper } = require('../ast') const { locations } = require('../util') const dir = locations.testOutput('enums_test') // FIXME: missing: inline enums (entity Foo { bar: String enum { ... }}) +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' }) + astw = await JSASTWrapper.initialise(path.join(paths[1], 'index.js')) + }) + + test('Coalescing Assignment Present', () => { + const stmts = astw.programm.body + const enm = stmts.find(n => n.type === 'ExpressionStatement' && n.expression.type === 'AssignmentExpression' && n.expression.operator === '??=') + expect(enm).toBeTruthy() + const { left } = enm.expression + // not checking the entire object chain here... + expect(left.property.name).toBe('someEnumProperty') + + console.log(42) + }) +}) + describe('Enum Types', () => { let astw diff --git a/test/unit/files/enums/nested.cds b/test/unit/files/enums/nested.cds new file mode 100644 index 00000000..77d0704d --- /dev/null +++ b/test/unit/files/enums/nested.cds @@ -0,0 +1,8 @@ +namespace a.b.c; + +entity Foobar { + someEnumProperty : String enum { + valueA; + valueB; + }; +} \ No newline at end of file