@api-client/core 0.12.1 → 0.12.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/bin/plugins/sinon/assert.ts +29 -0
  2. package/bin/test.ts +2 -0
  3. package/build/src/browser.d.ts +4 -0
  4. package/build/src/browser.d.ts.map +1 -1
  5. package/build/src/browser.js +3 -0
  6. package/build/src/browser.js.map +1 -1
  7. package/build/src/index.d.ts +4 -0
  8. package/build/src/index.d.ts.map +1 -1
  9. package/build/src/index.js +3 -0
  10. package/build/src/index.js.map +1 -1
  11. package/build/src/modeling/DataDomain.d.ts +4 -0
  12. package/build/src/modeling/DataDomain.d.ts.map +1 -1
  13. package/build/src/modeling/DataDomain.js +11 -0
  14. package/build/src/modeling/DataDomain.js.map +1 -1
  15. package/build/src/modeling/DomainAssociation.js +1 -1
  16. package/build/src/modeling/DomainAssociation.js.map +1 -1
  17. package/build/src/modeling/DomainEntity.d.ts +46 -0
  18. package/build/src/modeling/DomainEntity.d.ts.map +1 -1
  19. package/build/src/modeling/DomainEntity.js +71 -0
  20. package/build/src/modeling/DomainEntity.js.map +1 -1
  21. package/build/src/modeling/DomainImpactAnalysis.d.ts +31 -8
  22. package/build/src/modeling/DomainImpactAnalysis.d.ts.map +1 -1
  23. package/build/src/modeling/DomainImpactAnalysis.js +118 -46
  24. package/build/src/modeling/DomainImpactAnalysis.js.map +1 -1
  25. package/build/src/modeling/DomainProperty.js +1 -1
  26. package/build/src/modeling/DomainProperty.js.map +1 -1
  27. package/build/src/modeling/validation/association_validation.d.ts +38 -0
  28. package/build/src/modeling/validation/association_validation.d.ts.map +1 -0
  29. package/build/src/modeling/validation/association_validation.js +108 -0
  30. package/build/src/modeling/validation/association_validation.js.map +1 -0
  31. package/build/src/modeling/validation/entity_validation.d.ts +52 -0
  32. package/build/src/modeling/validation/entity_validation.d.ts.map +1 -0
  33. package/build/src/modeling/validation/entity_validation.js +241 -0
  34. package/build/src/modeling/validation/entity_validation.js.map +1 -0
  35. package/build/src/modeling/validation/postgresql.d.ts +2 -0
  36. package/build/src/modeling/validation/postgresql.d.ts.map +1 -0
  37. package/build/src/modeling/validation/postgresql.js +58 -0
  38. package/build/src/modeling/validation/postgresql.js.map +1 -0
  39. package/build/src/modeling/validation/property_validation.d.ts +29 -0
  40. package/build/src/modeling/validation/property_validation.d.ts.map +1 -0
  41. package/build/src/modeling/validation/property_validation.js +58 -0
  42. package/build/src/modeling/validation/property_validation.js.map +1 -0
  43. package/build/src/modeling/validation/rules.d.ts +55 -0
  44. package/build/src/modeling/validation/rules.d.ts.map +1 -0
  45. package/build/src/modeling/validation/rules.js +110 -0
  46. package/build/src/modeling/validation/rules.js.map +1 -0
  47. package/package.json +1 -1
  48. package/src/modeling/DataDomain.ts +12 -0
  49. package/src/modeling/DomainAssociation.ts +1 -1
  50. package/src/modeling/DomainEntity.ts +75 -0
  51. package/src/modeling/DomainImpactAnalysis.ts +144 -54
  52. package/src/modeling/DomainProperty.ts +1 -1
  53. package/src/modeling/validation/association_validation.ts +109 -0
  54. package/src/modeling/validation/entity_validation.ts +246 -0
  55. package/src/modeling/validation/postgresql.ts +57 -0
  56. package/src/modeling/validation/property_validation.ts +58 -0
  57. package/src/modeling/validation/rules.ts +152 -0
  58. package/tests/unit/modeling/data_domain_associations.spec.ts +1 -1
  59. package/tests/unit/modeling/data_domain_property.spec.ts +1 -1
  60. package/tests/unit/modeling/domain.property.spec.ts +7 -7
  61. package/tests/unit/modeling/domain_asociation.spec.ts +3 -3
  62. package/tests/unit/modeling/domain_entity_associations.spec.ts +1 -1
  63. package/tests/unit/modeling/domain_entity_properties.spec.ts +2 -2
  64. package/tests/unit/modeling/domain_impact_analysis.spec.ts +138 -29
  65. package/tests/unit/modeling/validation/association_validation.spec.ts +157 -0
  66. package/tests/unit/modeling/validation/entity_validation.spec.ts +192 -0
  67. package/tests/unit/modeling/validation/property_validation.spec.ts +135 -0
@@ -12,6 +12,7 @@ import {
12
12
  DomainEntity,
13
13
  DomainProperty,
14
14
  DomainAssociation,
15
+ DataDomainKind,
15
16
  } from '../../../src/index.js'
16
17
 
17
18
  test.group('DomainImpactAnalysis', (group) => {
@@ -89,28 +90,28 @@ test.group('DomainImpactAnalysis', (group) => {
89
90
  assert.equal(n1r.kind, DomainNamespaceKind)
90
91
  assert.equal(n1r.type, 'delete')
91
92
  assert.equal(n1r.impact, `The n1 namespace will be deleted.`)
92
- assert.isFalse(n1r.blocking)
93
+ assert.equal(n1r.severity, 'info')
93
94
 
94
95
  assert.ok(n2r)
95
96
  assert.equal(n2r.key, n2.key)
96
97
  assert.equal(n2r.kind, DomainNamespaceKind)
97
98
  assert.equal(n2r.type, 'delete')
98
99
  assert.equal(n2r.impact, `The n2 namespace will be deleted.`)
99
- assert.isFalse(n2r.blocking)
100
+ assert.equal(n2r.severity, 'info')
100
101
 
101
102
  assert.ok(m3r)
102
103
  assert.equal(m3r.key, m3.key)
103
104
  assert.equal(m3r.kind, DomainModelKind)
104
105
  assert.equal(m3r.type, 'delete')
105
106
  assert.equal(m3r.impact, `The m3 data model will be deleted.`)
106
- assert.isFalse(m3r.blocking)
107
+ assert.equal(m3r.severity, 'info')
107
108
 
108
109
  assert.ok(e3r)
109
110
  assert.equal(e3r.key, e3.key)
110
111
  assert.equal(e3r.kind, DomainEntityKind)
111
112
  assert.equal(e3r.type, 'delete')
112
113
  assert.equal(e3r.impact, `The e3 entity will be deleted.`)
113
- assert.isFalse(e3r.blocking)
114
+ assert.equal(e3r.severity, 'info')
114
115
 
115
116
  assert.ok(e4r)
116
117
  assert.equal(e4r.key, e4.key)
@@ -118,7 +119,7 @@ test.group('DomainImpactAnalysis', (group) => {
118
119
  assert.equal(e4r.type, 'delete')
119
120
  assert.equal(e4r.impact, `The "e4" entity will become an orphan because it is a child of the "e3" entity.`)
120
121
  assert.equal(e4r.resolution, `The "e3" entity will be removed as the parent of the "e4" entity.`)
121
- assert.isTrue(e4r.blocking)
122
+ assert.equal(e4r.severity, 'error')
122
123
  assert.equal(e4r.relationship, 'child')
123
124
 
124
125
  assert.ok(m2r)
@@ -126,14 +127,14 @@ test.group('DomainImpactAnalysis', (group) => {
126
127
  assert.equal(m2r.kind, DomainModelKind)
127
128
  assert.equal(m2r.type, 'delete')
128
129
  assert.equal(m2r.impact, `The m2 data model will be deleted.`)
129
- assert.isFalse(m2r.blocking)
130
+ assert.equal(m2r.severity, 'info')
130
131
 
131
132
  assert.ok(e2r)
132
133
  assert.equal(e2r.key, e2.key)
133
134
  assert.equal(e2r.kind, DomainEntityKind)
134
135
  assert.equal(e2r.type, 'delete')
135
136
  assert.equal(e2r.impact, `The e2 entity will be deleted.`)
136
- assert.isFalse(e2r.blocking)
137
+ assert.equal(e2r.severity, 'info')
137
138
 
138
139
  assert.ok(a1r)
139
140
  assert.equal(a1r.key, a1.key)
@@ -141,7 +142,7 @@ test.group('DomainImpactAnalysis', (group) => {
141
142
  assert.equal(a1r.type, 'delete')
142
143
  assert.equal(a1r.impact, `The a1 association will be broken because it has a target to e2.`)
143
144
  assert.equal(a1r.resolution, `The a1 association will be removed from e2.`)
144
- assert.isTrue(a1r.blocking)
145
+ assert.equal(a1r.severity, 'error')
145
146
  })
146
147
 
147
148
  test('returns a report for deleting a data model', ({ assert }) => {
@@ -164,28 +165,28 @@ test.group('DomainImpactAnalysis', (group) => {
164
165
  assert.equal(m1r.kind, DomainModelKind)
165
166
  assert.equal(m1r.type, 'delete')
166
167
  assert.equal(m1r.impact, `The m1 data model will be deleted.`)
167
- assert.isFalse(m1r.blocking)
168
+ assert.equal(m1r.severity, 'info')
168
169
 
169
170
  assert.ok(e1r)
170
171
  assert.equal(e1r.key, e1.key)
171
172
  assert.equal(e1r.kind, DomainEntityKind)
172
173
  assert.equal(e1r.type, 'delete')
173
174
  assert.equal(e1r.impact, `The e1 entity will be deleted.`)
174
- assert.isFalse(e1r.blocking)
175
+ assert.equal(e1r.severity, 'info')
175
176
 
176
177
  assert.ok(p1r)
177
178
  assert.equal(p1r.key, p1.key)
178
179
  assert.equal(p1r.kind, DomainPropertyKind)
179
180
  assert.equal(p1r.type, 'delete')
180
181
  assert.equal(p1r.impact, `The p1 property will be deleted.`)
181
- assert.isFalse(p1r.blocking)
182
+ assert.equal(p1r.severity, 'info')
182
183
 
183
184
  assert.ok(a1r)
184
185
  assert.equal(a1r.key, a1.key)
185
186
  assert.equal(a1r.kind, DomainAssociationKind)
186
187
  assert.equal(a1r.type, 'delete')
187
188
  assert.equal(a1r.impact, `The a1 association will be deleted.`)
188
- assert.isFalse(a1r.blocking)
189
+ assert.equal(a1r.severity, 'info')
189
190
 
190
191
  assert.ok(e3r)
191
192
  assert.equal(e3r.key, e3.key)
@@ -193,7 +194,7 @@ test.group('DomainImpactAnalysis', (group) => {
193
194
  assert.equal(e3r.type, 'delete')
194
195
  assert.equal(e3r.impact, `The "e3" entity will become an orphan because it is a child of the "e1" entity.`)
195
196
  assert.equal(e3r.resolution, `The "e1" entity will be removed as the parent of the "e3" entity.`)
196
- assert.isTrue(e3r.blocking)
197
+ assert.equal(e3r.severity, 'error')
197
198
  assert.equal(e3r.relationship, 'child')
198
199
  })
199
200
 
@@ -216,21 +217,21 @@ test.group('DomainImpactAnalysis', (group) => {
216
217
  assert.equal(e1r.kind, DomainEntityKind)
217
218
  assert.equal(e1r.type, 'delete')
218
219
  assert.equal(e1r.impact, `The e1 entity will be deleted.`)
219
- assert.isFalse(e1r.blocking)
220
+ assert.equal(e1r.severity, 'info')
220
221
 
221
222
  assert.ok(p1r)
222
223
  assert.equal(p1r.key, p1.key)
223
224
  assert.equal(p1r.kind, DomainPropertyKind)
224
225
  assert.equal(p1r.type, 'delete')
225
226
  assert.equal(p1r.impact, `The p1 property will be deleted.`)
226
- assert.isFalse(p1r.blocking)
227
+ assert.equal(p1r.severity, 'info')
227
228
 
228
229
  assert.ok(a1r)
229
230
  assert.equal(a1r.key, a1.key)
230
231
  assert.equal(a1r.kind, DomainAssociationKind)
231
232
  assert.equal(a1r.type, 'delete')
232
233
  assert.equal(a1r.impact, `The a1 association will be deleted.`)
233
- assert.isFalse(a1r.blocking)
234
+ assert.equal(a1r.severity, 'info')
234
235
 
235
236
  assert.ok(e3r)
236
237
  assert.equal(e3r.key, e3.key)
@@ -238,7 +239,7 @@ test.group('DomainImpactAnalysis', (group) => {
238
239
  assert.equal(e3r.type, 'delete')
239
240
  assert.equal(e3r.impact, `The "e3" entity will become an orphan because it is a child of the "e1" entity.`)
240
241
  assert.equal(e3r.resolution, `The "e1" entity will be removed as the parent of the "e3" entity.`)
241
- assert.isTrue(e3r.blocking)
242
+ assert.equal(e3r.severity, 'error')
242
243
  assert.equal(e3r.relationship, 'child')
243
244
  })
244
245
 
@@ -259,7 +260,7 @@ test.group('DomainImpactAnalysis', (group) => {
259
260
  assert.equal(p1r.kind, DomainPropertyKind)
260
261
  assert.equal(p1r.type, 'delete')
261
262
  assert.equal(p1r.impact, `The p1 property will be deleted.`)
262
- assert.isFalse(p1r.blocking)
263
+ assert.equal(p1r.severity, 'info')
263
264
  })
264
265
 
265
266
  test('returns a report for deleting an association', ({ assert }) => {
@@ -279,7 +280,7 @@ test.group('DomainImpactAnalysis', (group) => {
279
280
  assert.equal(a1r.kind, DomainAssociationKind)
280
281
  assert.equal(a1r.type, 'delete')
281
282
  assert.equal(a1r.impact, `The a1 association will be deleted.`)
282
- assert.isFalse(a1r.blocking)
283
+ assert.equal(a1r.severity, 'info')
283
284
  })
284
285
 
285
286
  test('handles circular dependencies', ({ assert }) => {
@@ -300,7 +301,7 @@ test.group('DomainImpactAnalysis', (group) => {
300
301
  assert.equal(e3r.kind, DomainEntityKind)
301
302
  assert.equal(e3r.type, 'delete')
302
303
  assert.equal(e3r.impact, `The e3 entity will be deleted.`)
303
- assert.isFalse(e3r.blocking)
304
+ assert.equal(e3r.severity, 'info')
304
305
 
305
306
  assert.ok(e2r)
306
307
  assert.equal(e2r.key, e2.key)
@@ -308,7 +309,7 @@ test.group('DomainImpactAnalysis', (group) => {
308
309
  assert.equal(e2r.type, 'delete')
309
310
  assert.equal(e2r.impact, `The "e2" entity will become an orphan because it is a child of the "e3" entity.`)
310
311
  assert.equal(e2r.resolution, `The "e3" entity will be removed as the parent of the "e2" entity.`)
311
- assert.isTrue(e2r.blocking)
312
+ assert.equal(e2r.severity, 'error')
312
313
  assert.equal(e2r.relationship, 'child')
313
314
 
314
315
  assert.ok(e4r)
@@ -317,7 +318,7 @@ test.group('DomainImpactAnalysis', (group) => {
317
318
  assert.equal(e4r.type, 'delete')
318
319
  assert.equal(e4r.impact, `The "e4" entity will become an orphan because it is a child of the "e3" entity.`)
319
320
  assert.equal(e4r.resolution, `The "e3" entity will be removed as the parent of the "e4" entity.`)
320
- assert.isTrue(e4r.blocking)
321
+ assert.equal(e4r.severity, 'error')
321
322
  assert.equal(e4r.relationship, 'child')
322
323
  })
323
324
 
@@ -330,7 +331,6 @@ test.group('DomainImpactAnalysis', (group) => {
330
331
  a1.addTarget(fe1)
331
332
 
332
333
  const report = analyzer.deleteAnalysis(e1.key, DomainEntityKind)
333
- // console.log(JSON.stringify(report.impact, null, 2))
334
334
  assert.equal(report.key, e1.key)
335
335
  assert.equal(report.kind, DomainEntityKind)
336
336
  assert.isFalse(report.canProceed, 'operation should not be able to proceed')
@@ -348,21 +348,21 @@ test.group('DomainImpactAnalysis', (group) => {
348
348
  assert.equal(e1r.kind, DomainEntityKind)
349
349
  assert.equal(e1r.type, 'delete')
350
350
  assert.equal(e1r.impact, `The e1 entity will be deleted.`)
351
- assert.isFalse(e1r.blocking)
351
+ assert.equal(e1r.severity, 'info')
352
352
 
353
353
  assert.ok(p1r)
354
354
  assert.equal(p1r.key, p1.key)
355
355
  assert.equal(p1r.kind, DomainPropertyKind)
356
356
  assert.equal(p1r.type, 'delete')
357
357
  assert.equal(p1r.impact, `The p1 property will be deleted.`)
358
- assert.isFalse(p1r.blocking)
358
+ assert.equal(p1r.severity, 'info')
359
359
 
360
360
  assert.ok(a1r)
361
361
  assert.equal(a1r.key, a1.key)
362
362
  assert.equal(a1r.kind, DomainAssociationKind)
363
363
  assert.equal(a1r.type, 'delete')
364
364
  assert.equal(a1r.impact, `The a1 association will be deleted.`)
365
- assert.isFalse(a1r.blocking)
365
+ assert.equal(a1r.severity, 'info')
366
366
 
367
367
  assert.ok(e3r)
368
368
  assert.equal(e3r.key, e3.key)
@@ -370,7 +370,7 @@ test.group('DomainImpactAnalysis', (group) => {
370
370
  assert.equal(e3r.type, 'delete')
371
371
  assert.equal(e3r.impact, `The "e3" entity will become an orphan because it is a child of the "e1" entity.`)
372
372
  assert.equal(e3r.resolution, `The "e1" entity will be removed as the parent of the "e3" entity.`)
373
- assert.isTrue(e3r.blocking)
373
+ assert.equal(e3r.severity, 'error')
374
374
  assert.equal(e3r.relationship, 'child')
375
375
  })
376
376
 
@@ -401,7 +401,7 @@ test.group('DomainImpactAnalysis', (group) => {
401
401
  `The "e1" entity will become an orphan because its parent "fe1" is in the foreign namespace "${f1.key}".`
402
402
  )
403
403
  assert.equal(e1r.resolution, `The "fe1" entity will be removed as the parent of the "e1" entity.`)
404
- assert.isTrue(e1r.blocking)
404
+ assert.equal(e1r.severity, 'error')
405
405
  assert.equal(e1r.relationship, 'child')
406
406
  })
407
407
 
@@ -432,7 +432,7 @@ test.group('DomainImpactAnalysis', (group) => {
432
432
  `The "a1" association from "e1" will be broken because it targets "fe1" in the foreign namespace "${f1.key}".`
433
433
  )
434
434
  assert.equal(a1r.resolution, `The "a1" association will be removed from "e1".`)
435
- assert.isTrue(a1r.blocking)
435
+ assert.equal(a1r.severity, 'error')
436
436
  })
437
437
 
438
438
  test('removeForeignNamespaceAnalysis() handles no foreign entities', ({ assert }) => {
@@ -450,3 +450,112 @@ test.group('DomainImpactAnalysis', (group) => {
450
450
  assert.lengthOf(report.impact, 0, 'has all items')
451
451
  })
452
452
  })
453
+
454
+ test.group('DomainImpactAnalysis.publishAnalysis()', (group) => {
455
+ let domain: DataDomain
456
+ let analysis: DomainImpactAnalysis
457
+
458
+ group.each.setup(() => {
459
+ domain = new DataDomain()
460
+ analysis = new DomainImpactAnalysis(domain)
461
+ })
462
+
463
+ test('publishAnalysis() should return an empty report when the domain is empty', ({ assert }) => {
464
+ const report = analysis.publishAnalysis()
465
+ assert.deepEqual(report, {
466
+ key: '',
467
+ kind: DataDomainKind,
468
+ impact: [],
469
+ canProceed: true,
470
+ })
471
+ })
472
+
473
+ test('publishAnalysis() should return validation errors for entities', ({ assert }) => {
474
+ const model = domain.addModel({ key: 'model' })
475
+ const entity = model.addEntity({ key: 'entity', info: { name: 'Invalid-Name' } }) // Invalid name
476
+
477
+ const report = analysis.publishAnalysis()
478
+ // no key
479
+ // no properties
480
+ // invalid name
481
+ // name is not a snake case
482
+ assert.lengthOf(report.impact, 4)
483
+ assert.equal(report.impact[0].key, 'entity')
484
+ assert.equal(report.impact[0].kind, entity.kind)
485
+ assert.equal(report.impact[0].type, 'publish')
486
+ assert.equal(report.impact[0].severity, 'error')
487
+ assert.equal(report.canProceed, false)
488
+ })
489
+
490
+ test('publishAnalysis() should return validation errors for properties', ({ assert }) => {
491
+ const model = domain.addModel({ key: 'model' })
492
+ const entity = model.addEntity({ key: 'entity', info: { name: 'entity' } })
493
+ const property = entity.addProperty({ key: 'invalid-property', type: 'string', info: { name: 'invalid-property' } })
494
+
495
+ const report = analysis.publishAnalysis()
496
+ // no key (entity)
497
+ // invalid name (property)
498
+ assert.lengthOf(report.impact, 2)
499
+ assert.equal(report.impact[1].key, property.key)
500
+ assert.equal(report.impact[1].kind, property.kind)
501
+ assert.equal(report.impact[1].type, 'publish')
502
+ assert.equal(report.impact[1].severity, 'error')
503
+ assert.equal(report.canProceed, false)
504
+ })
505
+
506
+ test('publishAnalysis() should return validation errors for associations', ({ assert }) => {
507
+ const model = domain.addModel({ key: 'model' })
508
+ const entity1 = model.addEntity({ key: 'entity1', info: { name: 'entity1' } })
509
+ const entity2 = model.addEntity({ key: 'entity2', info: { name: 'entity2' } })
510
+ const association = entity1.addAssociation({ key: entity2.key }, { info: { name: 'Invalid-Name' } })
511
+
512
+ const report = analysis.publishAnalysis()
513
+ // no key (entity1)
514
+ // invalid name (association)
515
+ // snake case (association)
516
+ // no key (entity2)
517
+ // no properties (entity2)
518
+ assert.lengthOf(report.impact, 5)
519
+ assert.equal(report.impact[1].key, association.key)
520
+ assert.equal(report.impact[1].kind, association.kind)
521
+ assert.equal(report.impact[1].type, 'publish')
522
+ assert.equal(report.impact[1].severity, 'error')
523
+ assert.equal(report.canProceed, false)
524
+ })
525
+
526
+ test('publishAnalysis() should return multiple validation errors', ({ assert }) => {
527
+ const model = domain.addModel({ key: 'model' })
528
+ const entity1 = model.addEntity({ key: 'invalid-entity', info: { name: 'Invalid-Entity' } })
529
+ entity1.addProperty({ key: 'invalid-property', type: 'string', info: { name: 'Invalid-Property' } })
530
+ const entity2 = model.addEntity({ key: 'entity2', info: { name: 'entity2' } })
531
+ entity1.addAssociation({ key: entity2.key }, { info: { name: 'Invalid-Name' } })
532
+
533
+ const report = analysis.publishAnalysis()
534
+ // entity1 - no key
535
+ // entity1 - invalid name
536
+ // entity1 - snake case
537
+ // property - invalid name
538
+ // property - snake case
539
+ // association - invalid name
540
+ // association - snake case
541
+ // entity2 - no key
542
+ // entity2 - no properties
543
+ assert.lengthOf(report.impact, 9)
544
+ assert.equal(report.canProceed, false)
545
+ })
546
+
547
+ test('publishAnalysis() should return no errors for a valid domain', ({ assert }) => {
548
+ const model = domain.addModel({ key: 'model' })
549
+ const entity1 = model.addEntity({ key: 'entity1', info: { name: 'entity1' } })
550
+ entity1.addProperty({ key: 'p1', type: 'string', info: { name: 'property1' } })
551
+ entity1.addProperty({ key: 'p2', type: 'string', primary: true, info: { name: 'property2' } })
552
+ const entity2 = model.addEntity({ key: 'entity2', info: { name: 'entity2' } })
553
+ entity2.addProperty({ key: 'p3', type: 'number', info: { name: 'property3' } })
554
+ entity2.addProperty({ key: 'p4', type: 'string', primary: true, info: { name: 'property4' } })
555
+ entity1.addAssociation({ key: entity2.key }, { info: { name: 'name' } })
556
+
557
+ const report = analysis.publishAnalysis()
558
+ assert.lengthOf(report.impact, 0)
559
+ assert.equal(report.canProceed, true)
560
+ })
561
+ })
@@ -0,0 +1,157 @@
1
+ import { test } from '@japa/runner'
2
+ import { DataDomain, AssociationValidation } from '../../../../src/index.js'
3
+
4
+ test.group('AssociationValidation', (group) => {
5
+ let domain: DataDomain
6
+ let validation: AssociationValidation
7
+
8
+ group.each.setup(() => {
9
+ domain = new DataDomain()
10
+ validation = new AssociationValidation(domain)
11
+ })
12
+
13
+ test('validate() should return an error when the association does not exist', ({ assert }) => {
14
+ const results = validation.validate('nonExistentAssociation')
15
+ assert.lengthOf(results, 1)
16
+ assert.equal(results[0].rule, 'exists')
17
+ assert.equal(results[0].severity, 'error')
18
+ })
19
+
20
+ test('validate() should call other validation methods', ({ assert, sinon }) => {
21
+ const model = domain.addModel({ key: 'model' })
22
+ const entity1 = model.addEntity({ key: 'entity1', info: { name: 'Entity1' } })
23
+ const entity2 = model.addEntity({ key: 'entity2', info: { name: 'Entity2' } })
24
+ const association = entity1.addAssociation(
25
+ { key: entity2.key },
26
+ {
27
+ key: 'association',
28
+ info: { name: 'Association' },
29
+ }
30
+ )
31
+ const validateNameSpy = sinon.spy(validation, 'validateName')
32
+ const validateTargetsSpy = sinon.spy(validation, 'validateTargets')
33
+
34
+ validation.validate(association)
35
+
36
+ assert.calledWith(validateNameSpy, association)
37
+ assert.calledWith(validateTargetsSpy, association)
38
+ sinon.restore()
39
+ })
40
+
41
+ test('validateName() should return an error when the association has no name', ({ assert }) => {
42
+ const model = domain.addModel({ key: 'model' })
43
+ const entity1 = model.addEntity({ key: 'entity1', info: { name: 'Entity1' } })
44
+ const entity2 = model.addEntity({ key: 'entity2', info: { name: 'Entity2' } })
45
+ const association = entity1.addAssociation(
46
+ { key: entity2.key },
47
+ {
48
+ key: 'association',
49
+ info: { name: 'association' },
50
+ }
51
+ )
52
+ association.info.name = undefined
53
+ const results = validation.validateName(association)
54
+ assert.lengthOf(results, 1)
55
+ assert.equal(results[0].rule, 'required')
56
+ assert.equal(results[0].severity, 'error')
57
+ })
58
+
59
+ test('validateName() should return an error when the association name starts with a number', ({ assert }) => {
60
+ const model = domain.addModel({ key: 'model' })
61
+ const entity1 = model.addEntity({ key: 'entity1', info: { name: 'Entity1' } })
62
+ const entity2 = model.addEntity({ key: 'entity2', info: { name: 'Entity2' } })
63
+ const association = entity1.addAssociation(
64
+ { key: entity2.key },
65
+ {
66
+ key: '1association',
67
+ info: { name: '1association' },
68
+ }
69
+ )
70
+ const results = validation.validateName(association)
71
+ assert.lengthOf(results, 1)
72
+ assert.equal(results[0].rule, 'format')
73
+ assert.equal(results[0].severity, 'error')
74
+ })
75
+
76
+ test('validateName() should return an error when the association name contains invalid characters', ({ assert }) => {
77
+ const model = domain.addModel({ key: 'model' })
78
+ const entity1 = model.addEntity({ key: 'entity1', info: { name: 'Entity1' } })
79
+ const entity2 = model.addEntity({ key: 'entity2', info: { name: 'Entity2' } })
80
+ const association = entity1.addAssociation(
81
+ { key: entity2.key },
82
+ {
83
+ key: 'invalid-association!',
84
+ info: { name: 'invalid-association!' },
85
+ }
86
+ )
87
+ const results = validation.validateName(association)
88
+ assert.lengthOf(results, 1)
89
+ assert.equal(results[0].rule, 'format')
90
+ assert.equal(results[0].severity, 'error')
91
+ })
92
+
93
+ test('validateName() should return an error when the association name is too short', ({ assert }) => {
94
+ const model = domain.addModel({ key: 'model' })
95
+ const entity1 = model.addEntity({ key: 'entity1', info: { name: 'Entity1' } })
96
+ const entity2 = model.addEntity({ key: 'entity2', info: { name: 'Entity2' } })
97
+ const association = entity1.addAssociation(
98
+ { key: entity2.key },
99
+ {
100
+ key: 'a',
101
+ info: { name: 'a' },
102
+ }
103
+ )
104
+ const results = validation.validateName(association)
105
+ assert.lengthOf(results, 1)
106
+ assert.equal(results[0].rule, 'length')
107
+ assert.equal(results[0].severity, 'error')
108
+ })
109
+
110
+ test('validateName() should return an error when the association name is too long', ({ assert }) => {
111
+ const model = domain.addModel({ key: 'model' })
112
+ const entity1 = model.addEntity({ key: 'entity1', info: { name: 'Entity1' } })
113
+ const entity2 = model.addEntity({ key: 'entity2', info: { name: 'Entity2' } })
114
+ const association = entity1.addAssociation(
115
+ { key: entity2.key },
116
+ {
117
+ key: 'a'.repeat(60),
118
+ info: { name: 'a'.repeat(60) },
119
+ }
120
+ )
121
+ const results = validation.validateName(association)
122
+ assert.lengthOf(results, 1)
123
+ assert.equal(results[0].rule, 'length')
124
+ assert.equal(results[0].severity, 'error')
125
+ })
126
+
127
+ test('validateName() should return no errors when the association name is valid', ({ assert }) => {
128
+ const model = domain.addModel({ key: 'model' })
129
+ const entity1 = model.addEntity({ key: 'entity1', info: { name: 'Entity1' } })
130
+ const entity2 = model.addEntity({ key: 'entity2', info: { name: 'Entity2' } })
131
+ const association = entity1.addAssociation(
132
+ { key: entity2.key },
133
+ {
134
+ key: 'valid_association123',
135
+ info: { name: 'valid_association123' },
136
+ }
137
+ )
138
+ const results = validation.validateName(association)
139
+ assert.lengthOf(results, 0)
140
+ })
141
+
142
+ test('validateEntities() should return an error when the target entity does not exist', ({ assert }) => {
143
+ const model = domain.addModel({ key: 'model' })
144
+ const entity1 = model.addEntity({ key: 'entity1', info: { name: 'Entity1' } })
145
+ const association = entity1.addAssociation(
146
+ {},
147
+ {
148
+ key: 'association',
149
+ info: { name: 'association' },
150
+ }
151
+ )
152
+ const results = validation.validateTargets(association)
153
+ assert.lengthOf(results, 1)
154
+ assert.equal(results[0].rule, 'required')
155
+ assert.equal(results[0].severity, 'error')
156
+ })
157
+ })