Skip to content

Commit ca11b21

Browse files
authored
Add logging to highlight Aspect Model resolving issues (#110)
* Add logging to highlight Aspect Model resolving issues * Fix unit tests
1 parent f00daa6 commit ca11b21

File tree

2 files changed

+35
-23
lines changed

2 files changed

+35
-23
lines changed

src/ng-generate/types/aspect-model-type-generator-visitor.ts

+8
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ export class AspectModelTypeGeneratorVisitor extends DefaultAspectModelVisitor<B
8787
lines.push(this.getJavaDoc(aspect));
8888
lines.push(`export interface ${aspect.name} {\n`);
8989

90+
this.options.spinner.info(`|-> Resolve Aspect: ${aspect.name}`);
91+
9092
aspect.properties.forEach(property => {
9193
// Visit the property to eventually generate a new data type and return
9294
// the appropriate data type name.
@@ -287,7 +289,13 @@ export class AspectModelTypeGeneratorVisitor extends DefaultAspectModelVisitor<B
287289
lines.push(this.getJavaDoc(entity));
288290
lines.push(`export interface ${entity.name} ${entity.extends ? `extends ${entity.extends?.name}` : ''} {\n`);
289291

292+
this.options.spinner.info(`|--> Resolve Entity: ${entity.name}; Urn: ${entity.urn}`);
293+
290294
entity.getOwnProperties().forEach((property: Property): void => {
295+
if(property.characteristic === null) {
296+
this.options.spinner.fail(`|---> Property ${property.name} has no characteristic defined.`);
297+
}
298+
291299
const dataTypeName = resolveJsPropertyType(property) || 'any';
292300
let variableName = '';
293301
if (property.name) {

test/types/aspect-model-type-generator-visitor.spec.ts

+27-23
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ let visitor: AspectModelTypeGeneratorVisitor;
2424

2525
const readFile = util.promisify(fs.readFile);
2626

27-
beforeEach(function () {
27+
beforeEach(function() {
2828
visitor = new AspectModelTypeGeneratorVisitor({
2929
excludedProperties: [],
3030
complexProps: [],
@@ -34,19 +34,23 @@ beforeEach(function () {
3434
customRowActions: [],
3535
addCommandBar: true,
3636
selectedModelElement: {
37-
name: 'Movement',
37+
name: 'Movement'
3838
},
3939
selectedModelElementUrn: 'urn:samm:org.esmf.digitaltwin:2.1.0#Movement',
4040
enabledCommandBarFunctions: [],
4141
enableRemoteDataHandling: true,
4242
enableVersionSupport: false,
4343
overwrite: true,
4444
templateHelper: new TemplateHelper(),
45+
spinner: {
46+
info: jest.fn(),
47+
warn: jest.fn()
48+
}
4549
} as any);
4650
});
4751

4852
describe('Generation of types from aspect model', (): void => {
49-
it('works for movement.ttl', async function (): Promise<void> {
53+
it('works for movement.ttl', async function(): Promise<void> {
5054
const generatedTypeDefinitions = await readModelsFromFS('test/models/movement.ttl')
5155
.then((models: string[]): Promise<Aspect> => {
5256
return lastValueFrom(loader.load('', ...models));
@@ -75,7 +79,7 @@ describe('Generation of types from aspect model', (): void => {
7579
expect(generatedTypeDefinitions).toMatch(/altitude\s*\?:\s*number\s*;/);
7680
});
7781

78-
it('works for built-in SAMM-C characteristics', async function (): Promise<void> {
82+
it('works for built-in SAMM-C characteristics', async function(): Promise<void> {
7983
const generatedTypeDefinitions = await readModelsFromFS('test/models/test-sammc-characteristics.ttl')
8084
.then((models: string[]): Promise<Aspect> => {
8185
return lastValueFrom(loader.load('', ...models));
@@ -92,7 +96,7 @@ describe('Generation of types from aspect model', (): void => {
9296
expect(generatedTypeDefinitions).toMatch(/c\s*:\s*Date\s*;/);
9397
});
9498

95-
it('works for XSD Core types', async function (): Promise<void> {
99+
it('works for XSD Core types', async function(): Promise<void> {
96100
const generatedTypeDefinitions = await readModelsFromFS('test/models/test-xsd-core-types.ttl')
97101
.then((models: string[]): Promise<Aspect> => {
98102
return lastValueFrom(loader.load('', ...models));
@@ -113,7 +117,7 @@ describe('Generation of types from aspect model', (): void => {
113117
expect(generatedTypeDefinitions).toMatch(/d\s*:\s*number\s*;/);
114118
});
115119

116-
it('works for XSD Floating-Point Number types', async function (): Promise<void> {
120+
it('works for XSD Floating-Point Number types', async function(): Promise<void> {
117121
const generatedTypeDefinitions = await readModelsFromFS('test/models/test-xsd-floating-point-number-types.ttl')
118122
.then((models: string[]): Promise<Aspect> => {
119123
return lastValueFrom(loader.load('', ...models));
@@ -132,7 +136,7 @@ describe('Generation of types from aspect model', (): void => {
132136
expect(generatedTypeDefinitions).toMatch(/b\s*:\s*number\s*;/);
133137
});
134138

135-
it('works for XSD Time and Date types', async function (): Promise<void> {
139+
it('works for XSD Time and Date types', async function(): Promise<void> {
136140
const generatedTypeDefinitions = await readModelsFromFS('test/models/test-xsd-time-and-date-types.ttl')
137141
.then((models: string[]): Promise<Aspect> => {
138142
return lastValueFrom(loader.load('', ...models));
@@ -153,7 +157,7 @@ describe('Generation of types from aspect model', (): void => {
153157
expect(generatedTypeDefinitions).toMatch(/d\s*:\s*Date\s*;/);
154158
});
155159

156-
it('works for XSD Limited-range Integer Number types', async function (): Promise<void> {
160+
it('works for XSD Limited-range Integer Number types', async function(): Promise<void> {
157161
const generatedTypeDefinitions = await readModelsFromFS('test/models/test-xsd-limited-range-integer-number-types.ttl')
158162
.then(models => {
159163
return loader.load('', ...models).toPromise();
@@ -184,7 +188,7 @@ describe('Generation of types from aspect model', (): void => {
184188
expect(generatedTypeDefinitions).toMatch(/npi\s*:\s*number\s*;/);
185189
});
186190

187-
it('works for XSD Miscellaneous types', async function (): Promise<void> {
191+
it('works for XSD Miscellaneous types', async function(): Promise<void> {
188192
const generatedTypeDefinitions = await readModelsFromFS('test/models/test-xsd-miscellaneous-types.ttl')
189193
.then((models: string[]): Promise<Aspect> => {
190194
return lastValueFrom(loader.load('', ...models));
@@ -204,7 +208,7 @@ describe('Generation of types from aspect model', (): void => {
204208
expect(generatedTypeDefinitions).toMatch(/c\s*:\s*MultiLanguageText\s*;/);
205209
});
206210

207-
it('works for enumeration types', async function () {
211+
it('works for enumeration types', async function() {
208212
const generatedTypeDefinitions = await readModelsFromFS('test/models/test-enumeration-types.ttl')
209213
.then(models => {
210214
return loader.load('', ...models).toPromise();
@@ -231,17 +235,17 @@ describe('Generation of types from aspect model', (): void => {
231235
expect(generatedTypeDefinitions).toMatch(/NUMBER_19\s*=\s*19\s*,/);
232236

233237
expect(generatedTypeDefinitions).toMatch(
234-
/static StatusInProgress\s*=\s*new PartStatus\(\s*'inprogress'\s*,\s*10\s*,\s*\{value:\s*'In Progress'\s*,\s*language:\s*'en'\s*\}\);/,
238+
/static StatusInProgress\s*=\s*new PartStatus\(\s*'inprogress'\s*,\s*10\s*,\s*\{value:\s*'In Progress'\s*,\s*language:\s*'en'\s*\}\);/
235239
);
236240
expect(generatedTypeDefinitions).toMatch(
237-
/static StatusCancelled\s*=\s*new PartStatus\('cancelled'\s*,\s*11\s*,\s*\{value:\s*'Cancelled',\s*language:\s*'en'\s*\}\);/,
241+
/static StatusCancelled\s*=\s*new PartStatus\('cancelled'\s*,\s*11\s*,\s*\{value:\s*'Cancelled',\s*language:\s*'en'\s*\}\);/
238242
);
239243
expect(generatedTypeDefinitions).toMatch(
240-
/static StatusInactive\s*=\s*new PartStatus\('inactive',\s*55\s*,\s*\{value:\s*'Cancelled'\s*,\s*language:\s*'en'\s*\}\);/,
244+
/static StatusInactive\s*=\s*new PartStatus\('inactive',\s*55\s*,\s*\{value:\s*'Cancelled'\s*,\s*language:\s*'en'\s*\}\);/
241245
);
242246
});
243247

244-
it('works for entity types', async function (): Promise<void> {
248+
it('works for entity types', async function(): Promise<void> {
245249
const generatedTypeDefinitions = await readModelsFromFS('test/models/test-entity-types.ttl')
246250
.then((models: string[]): Promise<Aspect> => {
247251
return lastValueFrom(loader.load('', ...models));
@@ -261,7 +265,7 @@ describe('Generation of types from aspect model', (): void => {
261265
expect(generatedTypeDefinitions).toMatch(/z\s*:\s*number\s*;/);
262266
});
263267

264-
it('works for entity instances', async function (): Promise<void> {
268+
it('works for entity instances', async function(): Promise<void> {
265269
const generatedTypeDefinitions = await readModelsFromFS('test/models/test-entity-instances.ttl')
266270
.then((models: string[]): Promise<Aspect> => {
267271
return lastValueFrom(loader.load('', ...models));
@@ -282,7 +286,7 @@ describe('Generation of types from aspect model', (): void => {
282286
expect(generatedTypeDefinitions).toMatch(/description\s*:\s*string\s*;/);
283287
});
284288

285-
it('works for entity instances with langString', async function (): Promise<void> {
289+
it('works for entity instances with langString', async function(): Promise<void> {
286290
const generatedTypeDefinitions = await readModelsFromFS('test/models/test-entity-instances-with-langString.ttl')
287291
.then((models: string[]): Promise<Aspect> => {
288292
return lastValueFrom(loader.load('', ...models));
@@ -297,17 +301,17 @@ describe('Generation of types from aspect model', (): void => {
297301
expect(generatedTypeDefinitions).toMatch(/export interface TestEntityInstancesWithLangString/);
298302
expect(generatedTypeDefinitions).toMatch(/export class Enumeration/);
299303
expect(generatedTypeDefinitions).toMatch(
300-
/static Code101\s*=\s*new Enumeration\(\s*101\s*,\s*\{value\s*:\s*'Starting'\s*,\s*language:\s*'en'\}\);/,
304+
/static Code101\s*=\s*new Enumeration\(\s*101\s*,\s*\{value\s*:\s*'Starting'\s*,\s*language:\s*'en'\}\);/
301305
);
302306
expect(generatedTypeDefinitions).toMatch(
303-
/static Code102\s*=\s*new Enumeration\(\s*102\s*\s*,\s*\{value\s*:\s*'Ready',\s*language:\s*'en'\}\);/,
307+
/static Code102\s*=\s*new Enumeration\(\s*102\s*\s*,\s*\{value\s*:\s*'Ready',\s*language:\s*'en'\}\);/
304308
);
305309
expect(generatedTypeDefinitions).toMatch(/step\s*:\s*number\s*;/);
306310
expect(generatedTypeDefinitions).toMatch(/export interface Entity/);
307311
expect(generatedTypeDefinitions).toMatch(/description\s*:\s*MultiLanguageText\s*;/);
308312
});
309313

310-
it('works for entity instances with collection of langString', async function (): Promise<void> {
314+
it('works for entity instances with collection of langString', async function(): Promise<void> {
311315
const generatedTypeDefinitions = await readModelsFromFS('test/models/test-entity-instances-with-collection-of-langString.ttl')
312316
.then((models: string[]): Promise<Aspect> => {
313317
return lastValueFrom(loader.load('', ...models));
@@ -322,17 +326,17 @@ describe('Generation of types from aspect model', (): void => {
322326
expect(generatedTypeDefinitions).toMatch(/export interface TestEntityInstancesWithCollectionOfLangString/);
323327
expect(generatedTypeDefinitions).toMatch(/export class Enumeration/);
324328
expect(generatedTypeDefinitions).toMatch(
325-
/static Code101\s*=\s*new Enumeration\s*\(\s*101\s*,\s*\(\s*\[\s*\{\s*value\s*:\s*'Starting'\s*,\s*language\s*:\s*'en'\s*\}\s*,\s*\{\s*value\s*:\s*'Start'\s*,\s*language\s*:\s*'de'\s*\}\s*\]\s*as\s+Array<MultiLanguageText>\s*\)\s*\)\s*;/,
329+
/static Code101\s*=\s*new Enumeration\s*\(\s*101\s*,\s*\(\s*\[\s*\{\s*value\s*:\s*'Starting'\s*,\s*language\s*:\s*'en'\s*\}\s*,\s*\{\s*value\s*:\s*'Start'\s*,\s*language\s*:\s*'de'\s*\}\s*\]\s*as\s+Array<MultiLanguageText>\s*\)\s*\)\s*;/
326330
);
327331
expect(generatedTypeDefinitions).toMatch(
328-
/static Code102\s*=\s*new Enumeration\s*\(\s*102\s*,\s*\(\s*\[\s*\{\s*value\s*:\s*'Ready'\s*,\s*language\s*:\s*'en'\s*\}\s*,\s*\{\s*value\s*:\s*'Los'\s*,\s*language\s*:\s*'de'\s*\}\s*\]\s*as\s+Array<MultiLanguageText>\s*\)\s*\)\s*;/,
332+
/static Code102\s*=\s*new Enumeration\s*\(\s*102\s*,\s*\(\s*\[\s*\{\s*value\s*:\s*'Ready'\s*,\s*language\s*:\s*'en'\s*\}\s*,\s*\{\s*value\s*:\s*'Los'\s*,\s*language\s*:\s*'de'\s*\}\s*\]\s*as\s+Array<MultiLanguageText>\s*\)\s*\)\s*;/
329333
);
330334
expect(generatedTypeDefinitions).toMatch(/step\s*:\s*number\s*;/);
331335
expect(generatedTypeDefinitions).toMatch(/description\s*:\s*Array<MultiLanguageText>\s*;/);
332336
expect(generatedTypeDefinitions).toMatch(/export interface Entity/);
333337
});
334338

335-
it('works for collection types', async function (): Promise<void> {
339+
it('works for collection types', async function(): Promise<void> {
336340
const generatedTypeDefinitions = await readModelsFromFS('test/models/test-collection-types.ttl')
337341
.then((models: string[]): Promise<Aspect> => {
338342
return lastValueFrom(loader.load('', ...models));
@@ -353,7 +357,7 @@ describe('Generation of types from aspect model', (): void => {
353357
expect(generatedTypeDefinitions).toMatch(/productClass\s*:\s*string\s*;/);
354358
});
355359

356-
it('works for either types', async function (): Promise<void> {
360+
it('works for either types', async function(): Promise<void> {
357361
const generatedTypeDefinitions = await readModelsFromFS('test/models/test-sammc-characteristics.ttl')
358362
.then((models: string[]): Promise<Aspect> => {
359363
return lastValueFrom(loader.load('', ...models));

0 commit comments

Comments
 (0)