@api-client/core 0.11.10 → 0.12.0

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 (252) hide show
  1. package/Testing.md +1 -1
  2. package/bin/plugins/events/EventPlugin.ts +61 -0
  3. package/bin/plugins/events/assert.ts +193 -0
  4. package/bin/plugins/events/types.ts +6 -0
  5. package/bin/test.ts +8 -1
  6. package/build/src/amf/AmfShapeGenerator.d.ts +6 -3
  7. package/build/src/amf/AmfShapeGenerator.d.ts.map +1 -1
  8. package/build/src/amf/AmfShapeGenerator.js +4 -1
  9. package/build/src/amf/AmfShapeGenerator.js.map +1 -1
  10. package/build/src/amf/AmfTypes.d.ts +2 -2
  11. package/build/src/amf/AmfTypes.d.ts.map +1 -1
  12. package/build/src/amf/AmfTypes.js.map +1 -1
  13. package/build/src/amf/DataValueGenerator.d.ts +15 -15
  14. package/build/src/amf/DataValueGenerator.d.ts.map +1 -1
  15. package/build/src/amf/DataValueGenerator.js +14 -14
  16. package/build/src/amf/DataValueGenerator.js.map +1 -1
  17. package/build/src/browser.d.ts +12 -9
  18. package/build/src/browser.d.ts.map +1 -1
  19. package/build/src/browser.js +11 -8
  20. package/build/src/browser.js.map +1 -1
  21. package/build/src/exceptions/attach_exception.d.ts +11 -0
  22. package/build/src/exceptions/attach_exception.d.ts.map +1 -0
  23. package/build/src/exceptions/attach_exception.js +11 -0
  24. package/build/src/exceptions/attach_exception.js.map +1 -0
  25. package/build/src/exceptions/detach_exception.d.ts +11 -0
  26. package/build/src/exceptions/detach_exception.d.ts.map +1 -0
  27. package/build/src/exceptions/detach_exception.js +11 -0
  28. package/build/src/exceptions/detach_exception.js.map +1 -0
  29. package/build/src/exceptions/remove_model_exception.d.ts +8 -0
  30. package/build/src/exceptions/remove_model_exception.d.ts.map +1 -0
  31. package/build/src/exceptions/remove_model_exception.js +8 -0
  32. package/build/src/exceptions/remove_model_exception.js.map +1 -0
  33. package/build/src/exceptions/remove_namespace_exception.d.ts +8 -0
  34. package/build/src/exceptions/remove_namespace_exception.d.ts.map +1 -0
  35. package/build/src/exceptions/remove_namespace_exception.js +8 -0
  36. package/build/src/exceptions/remove_namespace_exception.js.map +1 -0
  37. package/build/src/index.d.ts +12 -9
  38. package/build/src/index.d.ts.map +1 -1
  39. package/build/src/index.js +11 -8
  40. package/build/src/index.js.map +1 -1
  41. package/build/src/legacy.d.ts +8 -0
  42. package/build/src/legacy.d.ts.map +1 -1
  43. package/build/src/legacy.js +9 -0
  44. package/build/src/legacy.js.map +1 -1
  45. package/build/src/modeling/Bindings.d.ts +2 -2
  46. package/build/src/modeling/Bindings.d.ts.map +1 -1
  47. package/build/src/modeling/Bindings.js.map +1 -1
  48. package/build/src/modeling/DataDomain.d.ts +601 -0
  49. package/build/src/modeling/DataDomain.d.ts.map +1 -0
  50. package/build/src/modeling/DataDomain.js +1142 -0
  51. package/build/src/modeling/DataDomain.js.map +1 -0
  52. package/build/src/modeling/DataFormat.d.ts +42 -41
  53. package/build/src/modeling/DataFormat.d.ts.map +1 -1
  54. package/build/src/modeling/DataFormat.js +30 -131
  55. package/build/src/modeling/DataFormat.js.map +1 -1
  56. package/build/src/modeling/DomainAssociation.d.ts +281 -0
  57. package/build/src/modeling/DomainAssociation.d.ts.map +1 -0
  58. package/build/src/modeling/DomainAssociation.js +440 -0
  59. package/build/src/modeling/DomainAssociation.js.map +1 -0
  60. package/build/src/modeling/DomainElement.d.ts +33 -0
  61. package/build/src/modeling/DomainElement.d.ts.map +1 -0
  62. package/build/src/modeling/DomainElement.js +32 -0
  63. package/build/src/modeling/DomainElement.js.map +1 -0
  64. package/build/src/modeling/DomainEntity.d.ts +383 -0
  65. package/build/src/modeling/DomainEntity.d.ts.map +1 -0
  66. package/build/src/modeling/DomainEntity.js +718 -0
  67. package/build/src/modeling/DomainEntity.js.map +1 -0
  68. package/build/src/modeling/DomainFile.d.ts +25 -0
  69. package/build/src/modeling/DomainFile.d.ts.map +1 -0
  70. package/build/src/modeling/DomainFile.js +86 -0
  71. package/build/src/modeling/DomainFile.js.map +1 -0
  72. package/build/src/modeling/DomainImpactAnalysis.d.ts +60 -47
  73. package/build/src/modeling/DomainImpactAnalysis.d.ts.map +1 -1
  74. package/build/src/modeling/DomainImpactAnalysis.js +201 -132
  75. package/build/src/modeling/DomainImpactAnalysis.js.map +1 -1
  76. package/build/src/modeling/DomainModel.d.ts +226 -0
  77. package/build/src/modeling/DomainModel.d.ts.map +1 -0
  78. package/build/src/modeling/DomainModel.js +401 -0
  79. package/build/src/modeling/DomainModel.js.map +1 -0
  80. package/build/src/modeling/DomainNamespace.d.ts +268 -0
  81. package/build/src/modeling/DomainNamespace.d.ts.map +1 -0
  82. package/build/src/modeling/DomainNamespace.js +512 -0
  83. package/build/src/modeling/DomainNamespace.js.map +1 -0
  84. package/build/src/modeling/DomainProperty.d.ts +281 -0
  85. package/build/src/modeling/DomainProperty.d.ts.map +1 -0
  86. package/build/src/modeling/DomainProperty.js +560 -0
  87. package/build/src/modeling/DomainProperty.js.map +1 -0
  88. package/build/src/modeling/DomainSerialization.d.ts +40 -0
  89. package/build/src/modeling/DomainSerialization.d.ts.map +1 -0
  90. package/build/src/modeling/DomainSerialization.js +288 -0
  91. package/build/src/modeling/DomainSerialization.js.map +1 -0
  92. package/build/src/modeling/DomainVersioning.d.ts +17 -0
  93. package/build/src/modeling/DomainVersioning.d.ts.map +1 -0
  94. package/build/src/modeling/DomainVersioning.js +124 -0
  95. package/build/src/modeling/DomainVersioning.js.map +1 -0
  96. package/build/src/modeling/GraphUtils.d.ts +8 -0
  97. package/build/src/modeling/GraphUtils.d.ts.map +1 -0
  98. package/build/src/modeling/GraphUtils.js +26 -0
  99. package/build/src/modeling/GraphUtils.js.map +1 -0
  100. package/build/src/modeling/amf/ShapeGenerator.d.ts +164 -0
  101. package/build/src/modeling/amf/ShapeGenerator.d.ts.map +1 -0
  102. package/build/src/modeling/amf/ShapeGenerator.js +492 -0
  103. package/build/src/modeling/amf/ShapeGenerator.js.map +1 -0
  104. package/build/src/modeling/{DataAssociation.d.ts → legacy/DataAssociation.d.ts} +10 -5
  105. package/build/src/modeling/legacy/DataAssociation.d.ts.map +1 -0
  106. package/build/src/modeling/{DataAssociation.js → legacy/DataAssociation.js} +9 -6
  107. package/build/src/modeling/legacy/DataAssociation.js.map +1 -0
  108. package/build/src/modeling/{DataEntity.d.ts → legacy/DataEntity.d.ts} +12 -7
  109. package/build/src/modeling/legacy/DataEntity.d.ts.map +1 -0
  110. package/build/src/modeling/{DataEntity.js → legacy/DataEntity.js} +19 -18
  111. package/build/src/modeling/legacy/DataEntity.js.map +1 -0
  112. package/build/src/modeling/{DataEntityBuilder.d.ts → legacy/DataEntityBuilder.d.ts} +3 -2
  113. package/build/src/modeling/legacy/DataEntityBuilder.d.ts.map +1 -0
  114. package/build/src/modeling/{DataEntityBuilder.js → legacy/DataEntityBuilder.js} +3 -2
  115. package/build/src/modeling/legacy/DataEntityBuilder.js.map +1 -0
  116. package/build/src/modeling/legacy/DataImpactAnalysis.d.ts +298 -0
  117. package/build/src/modeling/legacy/DataImpactAnalysis.d.ts.map +1 -0
  118. package/build/src/modeling/legacy/DataImpactAnalysis.js +441 -0
  119. package/build/src/modeling/legacy/DataImpactAnalysis.js.map +1 -0
  120. package/build/src/modeling/{DataModel.d.ts → legacy/DataModel.d.ts} +6 -4
  121. package/build/src/modeling/legacy/DataModel.d.ts.map +1 -0
  122. package/build/src/modeling/{DataModel.js → legacy/DataModel.js} +7 -6
  123. package/build/src/modeling/legacy/DataModel.js.map +1 -0
  124. package/build/src/modeling/{DataNamespace.d.ts → legacy/DataNamespace.d.ts} +22 -3
  125. package/build/src/modeling/legacy/DataNamespace.d.ts.map +1 -0
  126. package/build/src/modeling/{DataNamespace.js → legacy/DataNamespace.js} +7 -3
  127. package/build/src/modeling/legacy/DataNamespace.js.map +1 -0
  128. package/build/src/modeling/{DataProperty.d.ts → legacy/DataProperty.d.ts} +13 -5
  129. package/build/src/modeling/legacy/DataProperty.d.ts.map +1 -0
  130. package/build/src/modeling/{DataProperty.js → legacy/DataProperty.js} +8 -5
  131. package/build/src/modeling/legacy/DataProperty.js.map +1 -0
  132. package/build/src/modeling/observed.d.ts +67 -0
  133. package/build/src/modeling/observed.d.ts.map +1 -0
  134. package/build/src/modeling/observed.js +230 -0
  135. package/build/src/modeling/observed.js.map +1 -0
  136. package/build/src/modeling/types.d.ts +165 -1
  137. package/build/src/modeling/types.d.ts.map +1 -1
  138. package/build/src/modeling/types.js.map +1 -1
  139. package/build/src/models/Thing.d.ts +26 -5
  140. package/build/src/models/Thing.d.ts.map +1 -1
  141. package/build/src/models/Thing.js +193 -91
  142. package/build/src/models/Thing.js.map +1 -1
  143. package/build/src/models/kinds.d.ts +31 -6
  144. package/build/src/models/kinds.d.ts.map +1 -1
  145. package/build/src/models/kinds.js +31 -6
  146. package/build/src/models/kinds.js.map +1 -1
  147. package/build/src/models/store/DataFile.d.ts +3 -1
  148. package/build/src/models/store/DataFile.d.ts.map +1 -1
  149. package/build/src/models/store/DataFile.js +2 -0
  150. package/build/src/models/store/DataFile.js.map +1 -1
  151. package/build/src/models/types.d.ts +12 -0
  152. package/build/src/models/types.d.ts.map +1 -0
  153. package/build/src/models/types.js +2 -0
  154. package/build/src/models/types.js.map +1 -0
  155. package/build/src/runtime/store/FilesSdk.d.ts +2 -2
  156. package/build/src/runtime/store/FilesSdk.d.ts.map +1 -1
  157. package/build/src/runtime/store/FilesSdk.js.map +1 -1
  158. package/data/models/example-generator-api.json +26 -26
  159. package/package.json +20 -6
  160. package/readme.md +1 -1
  161. package/src/amf/AmfShapeGenerator.ts +7 -4
  162. package/src/amf/AmfTypes.ts +2 -2
  163. package/src/amf/DataValueGenerator.ts +21 -21
  164. package/src/exceptions/attach_exception.ts +11 -0
  165. package/src/exceptions/detach_exception.ts +11 -0
  166. package/src/exceptions/remove_model_exception.ts +8 -0
  167. package/src/exceptions/remove_namespace_exception.ts +8 -0
  168. package/src/modeling/Bindings.ts +2 -2
  169. package/src/modeling/DataDomain.ts +1221 -0
  170. package/src/modeling/DataFormat.ts +54 -163
  171. package/src/modeling/DomainAssociation.ts +476 -0
  172. package/src/modeling/DomainElement.ts +50 -0
  173. package/src/modeling/DomainEntity.ts +769 -0
  174. package/src/modeling/DomainFile.ts +94 -0
  175. package/src/modeling/DomainImpactAnalysis.ts +218 -144
  176. package/src/modeling/DomainModel.ts +421 -0
  177. package/src/modeling/DomainNamespace.ts +537 -0
  178. package/src/modeling/DomainProperty.ts +548 -0
  179. package/src/modeling/DomainSerialization.ts +312 -0
  180. package/src/modeling/DomainVersioning.ts +144 -0
  181. package/src/modeling/GraphUtils.ts +28 -0
  182. package/src/modeling/amf/ShapeGenerator.ts +552 -0
  183. package/src/modeling/graph.md +115 -0
  184. package/src/modeling/{DataAssociation.ts → legacy/DataAssociation.ts} +13 -8
  185. package/src/modeling/{DataEntity.ts → legacy/DataEntity.ts} +28 -23
  186. package/src/modeling/{DataEntityBuilder.ts → legacy/DataEntityBuilder.ts} +4 -3
  187. package/src/modeling/legacy/DataImpactAnalysis.ts +530 -0
  188. package/src/modeling/{DataModel.ts → legacy/DataModel.ts} +10 -8
  189. package/src/modeling/{DataNamespace.ts → legacy/DataNamespace.ts} +23 -5
  190. package/src/modeling/{DataProperty.ts → legacy/DataProperty.ts} +15 -7
  191. package/src/modeling/observed.ts +267 -0
  192. package/src/modeling/types.ts +174 -1
  193. package/src/models/Thing.ts +70 -5
  194. package/src/models/kinds.ts +32 -6
  195. package/src/models/store/DataFile.ts +3 -1
  196. package/src/models/types.ts +11 -0
  197. package/src/runtime/store/FilesSdk.ts +2 -6
  198. package/tests/unit/amf/data_value_generator.spec.ts +15 -15
  199. package/tests/unit/legacy-transformers/ARC-legacy-import.spec.ts +1 -1
  200. package/tests/unit/modeling/amf/shape_generator.spec.ts +1174 -0
  201. package/tests/unit/modeling/data_domain.spec.ts +444 -0
  202. package/tests/unit/modeling/data_domain_associations.spec.ts +279 -0
  203. package/tests/unit/modeling/data_domain_change_observers.spec.ts +681 -0
  204. package/tests/unit/modeling/data_domain_entities.spec.ts +449 -0
  205. package/tests/unit/modeling/data_domain_foreign.spec.ts +355 -0
  206. package/tests/unit/modeling/data_domain_models.spec.ts +658 -0
  207. package/tests/unit/modeling/data_domain_namespaces.spec.ts +668 -0
  208. package/tests/unit/modeling/data_domain_property.spec.ts +264 -0
  209. package/tests/unit/modeling/data_domain_serialization.spec.ts +294 -0
  210. package/tests/unit/modeling/domain.property.spec.ts +822 -0
  211. package/tests/unit/modeling/domain_asociation.spec.ts +643 -0
  212. package/tests/unit/modeling/domain_asociation_targets.spec.ts +350 -0
  213. package/tests/unit/modeling/domain_entity.spec.ts +730 -0
  214. package/tests/unit/modeling/domain_entity_associations.spec.ts +330 -0
  215. package/tests/unit/modeling/domain_entity_example_generator_json.spec.ts +988 -0
  216. package/tests/unit/modeling/domain_entity_example_generator_xml.spec.ts +1451 -0
  217. package/tests/unit/modeling/domain_entity_fields.spec.ts +113 -0
  218. package/tests/unit/modeling/domain_entity_generators.spec.ts +20 -0
  219. package/tests/unit/modeling/domain_entity_parents.spec.ts +291 -0
  220. package/tests/unit/modeling/domain_entity_properties.spec.ts +305 -0
  221. package/tests/unit/modeling/{data_file.spec.ts → domain_file.spec.ts} +29 -85
  222. package/tests/unit/modeling/domain_impact_analysis.spec.ts +452 -0
  223. package/tests/unit/modeling/domain_model.spec.ts +568 -0
  224. package/tests/unit/modeling/domain_model_entities.spec.ts +408 -0
  225. package/tests/unit/modeling/domain_namespace.spec.ts +514 -0
  226. package/tests/unit/modeling/domain_namespace_models.spec.ts +324 -0
  227. package/tests/unit/modeling/domain_namespace_namespaces.spec.ts +404 -0
  228. package/tests/unit/modeling/domain_versioning.spec.ts +140 -0
  229. package/tests/unit/{amf → modeling/legacy}/amf_shape_generator.spec.ts +11 -11
  230. package/tests/unit/modeling/{data_association.spec.ts → legacy/data_association.spec.ts} +3 -11
  231. package/tests/unit/modeling/{data_entity.spec.ts → legacy/data_entity.spec.ts} +10 -8
  232. package/tests/unit/modeling/{data_entity_generator_json.spec.ts → legacy/data_entity_generator_json.spec.ts} +1 -1
  233. package/tests/unit/modeling/{data_entity_generator_xml.spec.ts → legacy/data_entity_generator_xml.spec.ts} +1 -1
  234. package/tests/unit/modeling/{data_model.spec.ts → legacy/data_model.spec.ts} +3 -3
  235. package/tests/unit/modeling/{data_namespace.spec.ts → legacy/data_namespace.spec.ts} +3 -10
  236. package/tests/unit/modeling/{data_property.spec.ts → legacy/data_property.spec.ts} +3 -6
  237. package/tests/unit/modeling/{impact_analysis.spec.ts → legacy/impact_analysis.spec.ts} +9 -9
  238. package/tests/unit/models/File/new.spec.ts +1 -1
  239. package/tests/unit/models/HttpProject.spec.ts +3 -3
  240. package/tsconfig.node.json +35 -0
  241. package/build/src/modeling/DataAssociation.d.ts.map +0 -1
  242. package/build/src/modeling/DataAssociation.js.map +0 -1
  243. package/build/src/modeling/DataEntity.d.ts.map +0 -1
  244. package/build/src/modeling/DataEntity.js.map +0 -1
  245. package/build/src/modeling/DataEntityBuilder.d.ts.map +0 -1
  246. package/build/src/modeling/DataEntityBuilder.js.map +0 -1
  247. package/build/src/modeling/DataModel.d.ts.map +0 -1
  248. package/build/src/modeling/DataModel.js.map +0 -1
  249. package/build/src/modeling/DataNamespace.d.ts.map +0 -1
  250. package/build/src/modeling/DataNamespace.js.map +0 -1
  251. package/build/src/modeling/DataProperty.d.ts.map +0 -1
  252. package/build/src/modeling/DataProperty.js.map +0 -1
@@ -0,0 +1,1174 @@
1
+ import { test } from '@japa/runner'
2
+ import {
3
+ IApiArrayShape,
4
+ IApiDataExample,
5
+ IApiFileShape,
6
+ IApiNodeShape,
7
+ IApiScalarNode,
8
+ IApiScalarShape,
9
+ IApiUnionShape,
10
+ IApiXmlSerializer,
11
+ IShapeUnion,
12
+ } from '../../../../src/amf/definitions/Shapes.js'
13
+ import {
14
+ IAmfAnyTypes,
15
+ IAmfArrayTypes,
16
+ IAmfExampleTypes,
17
+ IAmfFileTypes,
18
+ IAmfNodeTypes,
19
+ IAmfPropertyTypes,
20
+ IAmfScalarTypes,
21
+ IAmfUnionTypes,
22
+ } from '../../../../src/amf/AmfTypes.js'
23
+ import { AmfNamespace } from '../../../../src/amf/definitions/Namespace.js'
24
+ import { ShapeGenerator } from '../../../../src/modeling/amf/ShapeGenerator.js'
25
+ import {
26
+ type PropertyWebBindings,
27
+ DataDomain,
28
+ DomainEntity,
29
+ DomainModel,
30
+ DomainAssociation,
31
+ DomainProperty,
32
+ } from '../../../../src/index.js'
33
+
34
+ test.group('entity()', (group) => {
35
+ let root: DataDomain
36
+ let m1: DomainModel
37
+ let e1: DomainEntity
38
+
39
+ group.each.setup(() => {
40
+ root = new DataDomain()
41
+ m1 = root.addModel({ key: 'm1' })
42
+ e1 = m1.addEntity({ key: 'e1', info: { name: 'e1' } })
43
+ })
44
+
45
+ test('returns the basic shape', ({ assert }) => {
46
+ const result = e1.toApiShape() as IApiNodeShape
47
+
48
+ assert.equal(result.id, e1.key, 'has the id')
49
+ assert.deepEqual(result.types, IAmfNodeTypes, 'has the types')
50
+ assert.deepEqual(result.values, [], 'has the values')
51
+ assert.deepEqual(result.inherits, [], 'has the inherits')
52
+ assert.deepEqual(result.or, [], 'has the or')
53
+ assert.deepEqual(result.and, [], 'has the and')
54
+ assert.deepEqual(result.xone, [], 'has the xone')
55
+ assert.deepEqual(result.examples, [], 'has the examples')
56
+ assert.deepEqual(result.properties, [], 'has the properties')
57
+ assert.typeOf(result.xmlSerialization, 'object', 'has the xmlSerialization')
58
+ assert.equal(result.name, 'e1', 'has the name')
59
+ })
60
+
61
+ test('returns the display name', ({ assert }) => {
62
+ e1.info.displayName = 'e 1 name'
63
+ const result = e1.toApiShape() as IApiNodeShape
64
+
65
+ assert.equal(result.displayName, 'e 1 name')
66
+ })
67
+
68
+ test('returns the description', ({ assert }) => {
69
+ e1.info.description = 'e 1 description'
70
+ const result = e1.toApiShape() as IApiNodeShape
71
+
72
+ assert.equal(result.description, 'e 1 description')
73
+ })
74
+
75
+ test('returns the deprecated', ({ assert }) => {
76
+ e1.deprecated = true
77
+ const result = e1.toApiShape() as IApiNodeShape
78
+
79
+ assert.isTrue(result.deprecated)
80
+ })
81
+
82
+ test('returns empty properties', ({ assert }) => {
83
+ e1.info.description = 'e 1 description'
84
+ const result = e1.toApiShape() as IApiNodeShape
85
+
86
+ assert.deepEqual(result.properties, [])
87
+ })
88
+
89
+ test('returns defined properties', ({ assert }) => {
90
+ e1.addProperty({ key: 'test', info: { name: 'test' } })
91
+ const result = e1.toApiShape() as IApiNodeShape
92
+
93
+ assert.lengthOf(result.properties, 1)
94
+ })
95
+
96
+ test('adds associations to the properties', ({ assert }) => {
97
+ e1.addProperty({ key: 'test', info: { name: 'test' } })
98
+ e1.addAssociation({}, { info: { name: 'test association' } })
99
+ const result = e1.toApiShape() as IApiNodeShape
100
+
101
+ assert.lengthOf(result.properties, 2)
102
+ assert.equal(result.properties[1].name, 'test association')
103
+ })
104
+
105
+ test('adds parents to the inherits', ({ assert }) => {
106
+ const e2 = m1.addEntity({ key: 'e2', info: { name: 'e2' } })
107
+ e1.addParent(e2.key)
108
+ const result = e1.toApiShape() as IApiNodeShape
109
+
110
+ assert.lengthOf(result.inherits, 1)
111
+ assert.equal(result.inherits[0].name, 'e2')
112
+ })
113
+ })
114
+
115
+ test.group('property() / just data model', (group) => {
116
+ let root: DataDomain
117
+ let m1: DomainModel
118
+ let e1: DomainEntity
119
+ let p1: DomainProperty
120
+
121
+ group.each.setup(() => {
122
+ root = new DataDomain()
123
+ m1 = root.addModel({ key: 'm1' })
124
+ e1 = m1.addEntity({ key: 'e1', info: { name: 'e1' } })
125
+ p1 = e1.addProperty({ key: 'p1', info: { name: 'p1' } })
126
+ })
127
+
128
+ test('returns the basic shape', ({ assert }) => {
129
+ const result = p1.toApiShape()
130
+ assert.equal(result.id, p1.key, 'has the id')
131
+ assert.deepEqual(result.types, IAmfPropertyTypes, 'has the types')
132
+ assert.deepEqual(result.values, [], 'has the values')
133
+ assert.deepEqual(result.inherits, [], 'has the inherits')
134
+ assert.deepEqual(result.or, [], 'has the or')
135
+ assert.deepEqual(result.and, [], 'has the and')
136
+ assert.deepEqual(result.xone, [], 'has the xone')
137
+ assert.equal(result.path, AmfNamespace.aml.vocabularies.data.key + 'p1', 'has the path')
138
+ assert.equal(result.name, 'p1', 'has the name')
139
+ })
140
+
141
+ test('sets the minCount', ({ assert }) => {
142
+ p1.required = true
143
+ const result = p1.toApiShape()
144
+
145
+ assert.equal(result.minCount, 1)
146
+ })
147
+
148
+ test('has the default range for a string', ({ assert }) => {
149
+ p1.info.displayName = 'string dn'
150
+ p1.info.description = 'string desc'
151
+ const result = p1.toApiShape()
152
+ const range = result.range as IApiScalarShape
153
+
154
+ assert.typeOf(range, 'object', 'has the range')
155
+ assert.equal(range.id, `scalar-shape-${p1.key}`, 'has the id')
156
+ assert.deepEqual(range.types, IAmfScalarTypes, 'has the types')
157
+ assert.equal(range.dataType, AmfNamespace.w3.xmlSchema.string, 'has the dataType')
158
+ assert.equal(range.name, 'p1', 'has the name')
159
+ assert.equal(range.displayName, 'string dn', 'has the displayName')
160
+ assert.equal(range.description, 'string desc', 'has the description')
161
+ })
162
+
163
+ test('handles examples', ({ assert }) => {
164
+ p1.schema = { examples: ['example1', 'example2'] }
165
+ const result = p1.toApiShape()
166
+ const range = result.range as IApiScalarShape
167
+ assert.lengthOf(range.examples, 2)
168
+ assert.property(range.examples[0], 'structuredValue')
169
+ assert.property(range.examples[1], 'structuredValue')
170
+ })
171
+
172
+ test('handles defaultValue', ({ assert }) => {
173
+ p1.schema = { defaultValue: { value: 'defaultValue', type: 'literal' } }
174
+ const result = p1.toApiShape()
175
+ const range = result.range as IApiScalarShape
176
+ assert.property(range, 'defaultValue')
177
+ assert.containsSubset(range.defaultValue, {
178
+ value: 'defaultValue',
179
+ })
180
+ })
181
+
182
+ test('handles enum', ({ assert }) => {
183
+ p1.schema = { enum: ['enum1', 'enum2'] }
184
+ const result = p1.toApiShape()
185
+ const range = result.range as IApiScalarShape
186
+ assert.lengthOf(range.values, 2)
187
+ assert.containsSubset(range.values[0], {
188
+ dataType: AmfNamespace.w3.xmlSchema.string,
189
+ value: `enum1`,
190
+ })
191
+ assert.containsSubset(range.values[1], {
192
+ dataType: AmfNamespace.w3.xmlSchema.string,
193
+ value: `enum2`,
194
+ })
195
+ })
196
+
197
+ test('has the default range for a number', ({ assert }) => {
198
+ p1.type = 'number'
199
+ const result = p1.toApiShape()
200
+ const range = result.range as IApiScalarShape
201
+
202
+ assert.typeOf(range, 'object', 'has the range')
203
+ assert.equal(range.dataType, AmfNamespace.w3.xmlSchema.number, 'has the dataType')
204
+ })
205
+
206
+ test('handles readOnly and writeOnly', ({ assert }) => {
207
+ p1.readOnly = true
208
+ p1.writeOnly = true
209
+ const result = p1.toApiShape()
210
+ assert.isTrue(result.range?.readOnly)
211
+ assert.isTrue(result.range?.writeOnly)
212
+ })
213
+
214
+ test('handles deprecated', ({ assert }) => {
215
+ p1.deprecated = true
216
+ const result = p1.toApiShape()
217
+ assert.isTrue(result.deprecated)
218
+ })
219
+
220
+ test('handles multiple properties', ({ assert }) => {
221
+ p1.multiple = true
222
+ const result = p1.toApiShape()
223
+ const range = result.range as IApiArrayShape
224
+ assert.property(range, 'items')
225
+ })
226
+
227
+ test('handles binary base64 format', ({ assert }) => {
228
+ p1.type = 'binary'
229
+ const bindings = p1.getWebBinding() as PropertyWebBindings
230
+ bindings.format = 'base64'
231
+ const result = p1.toApiShape()
232
+ const range = result.range as IApiFileShape
233
+ assert.equal(range.format, AmfNamespace.w3.xmlSchema.base64Binary)
234
+ })
235
+
236
+ test('has the default range for an int32 format', ({ assert }) => {
237
+ p1.type = 'number'
238
+ const bindings = p1.getWebBinding()
239
+ bindings.format = 'int32'
240
+ const result = p1.toApiShape()
241
+ const range = result.range as IApiScalarShape
242
+
243
+ assert.typeOf(range, 'object', 'has the range')
244
+ assert.equal(range.dataType, AmfNamespace.w3.xmlSchema.integer, 'has the dataType')
245
+ })
246
+
247
+ test('has the default range for an int64 format', ({ assert }) => {
248
+ p1.type = 'number'
249
+ const bindings = p1.getWebBinding()
250
+ bindings.format = 'int64'
251
+ const result = p1.toApiShape()
252
+ const range = result.range as IApiScalarShape
253
+
254
+ assert.typeOf(range, 'object', 'has the range')
255
+ assert.equal(range.dataType, AmfNamespace.w3.xmlSchema.integer, 'has the dataType')
256
+ })
257
+
258
+ test('has the default range for a date', ({ assert }) => {
259
+ p1.type = 'date'
260
+ const result = p1.toApiShape()
261
+ const range = result.range as IApiScalarShape
262
+
263
+ assert.typeOf(range, 'object', 'has the range')
264
+ assert.equal(range.dataType, AmfNamespace.w3.xmlSchema.date, 'has the dataType')
265
+ })
266
+
267
+ test('has the default range for a datetime', ({ assert }) => {
268
+ p1.type = 'datetime'
269
+ const result = p1.toApiShape()
270
+ const range = result.range as IApiScalarShape
271
+
272
+ assert.typeOf(range, 'object', 'has the range')
273
+ assert.equal(range.dataType, AmfNamespace.w3.xmlSchema.dateTime, 'has the dataType')
274
+ })
275
+
276
+ test('has the default range for a time', ({ assert }) => {
277
+ p1.type = 'time'
278
+ const result = p1.toApiShape()
279
+ const range = result.range as IApiScalarShape
280
+
281
+ assert.typeOf(range, 'object', 'has the range')
282
+ assert.equal(range.dataType, AmfNamespace.aml.vocabularies.shapes.dateTimeOnly, 'has the dataType')
283
+ })
284
+
285
+ // test('has the default range for a nil', ({ assert }) => {
286
+ // p1.type = 'nil'
287
+ // const result = p1.toApiShape()
288
+ // const range = result.range as IApiScalarShape
289
+
290
+ // assert.typeOf(range, 'object', 'has the range')
291
+ // assert.equal(range.dataType, AmfNamespace.aml.vocabularies.shapes.nil, 'has the dataType')
292
+ // })
293
+
294
+ test('has the default range for a boolean', ({ assert }) => {
295
+ p1.type = 'boolean'
296
+ const result = p1.toApiShape()
297
+ const range = result.range as IApiScalarShape
298
+
299
+ assert.typeOf(range, 'object', 'has the range')
300
+ assert.equal(range.dataType, AmfNamespace.aml.vocabularies.shapes.boolean, 'has the dataType')
301
+ })
302
+
303
+ // test('has the default range for an any', ({ assert }) => {
304
+ // p1.type = 'any'
305
+ // const result = p1.toApiShape()
306
+ // const range = result.range as IApiScalarShape
307
+
308
+ // assert.typeOf(range, 'object', 'has the range')
309
+ // assert.equal(range.dataType, AmfNamespace.aml.vocabularies.shapes.AnyShape, 'has the dataType')
310
+ // })
311
+
312
+ test('has the default range for a file', ({ assert }) => {
313
+ p1.type = 'binary'
314
+ p1.info.displayName = 'string dn'
315
+ p1.info.description = 'string desc'
316
+ const result = p1.toApiShape()
317
+ const range = result.range as IApiFileShape
318
+
319
+ assert.typeOf(range, 'object', 'has the range')
320
+ assert.equal(range.id, `file-shape-${p1.key}`, 'has the id')
321
+ assert.deepEqual(range.types, IAmfFileTypes, 'has the types')
322
+ assert.equal(range.name, 'p1', 'has the name')
323
+ assert.equal(range.displayName, 'string dn', 'has the displayName')
324
+ assert.equal(range.description, 'string desc', 'has the description')
325
+ })
326
+
327
+ test('has the default range for a string when a multiple', ({ assert }) => {
328
+ p1.multiple = true
329
+ p1.info.displayName = 'string dn'
330
+ p1.info.description = 'string desc'
331
+ const result = p1.toApiShape()
332
+ const range = result.range as IApiArrayShape
333
+
334
+ assert.typeOf(range, 'object', 'has the range')
335
+ assert.equal(range.id, `array-shape-${p1.key}`, 'has the id')
336
+ assert.deepEqual(range.types, IAmfArrayTypes, 'has the types')
337
+
338
+ const items = range.items as IApiScalarShape
339
+
340
+ assert.typeOf(items, 'object', 'has the items')
341
+ assert.equal(items.id, `scalar-shape-${p1.key}`, 'has the id')
342
+ assert.deepEqual(items.types, IAmfScalarTypes, 'has the types')
343
+
344
+ assert.equal(items.name, 'p1', 'has the name')
345
+ assert.equal(items.displayName, 'string dn', 'has the displayName')
346
+ assert.equal(items.description, 'string desc', 'has the description')
347
+ })
348
+
349
+ test('has the default range for a file when a multiple', ({ assert }) => {
350
+ p1.multiple = true
351
+ p1.type = 'binary'
352
+ p1.info.displayName = 'string dn'
353
+ p1.info.description = 'string desc'
354
+ const result = p1.toApiShape()
355
+ const range = result.range as IApiArrayShape
356
+
357
+ assert.typeOf(range, 'object', 'has the range')
358
+ assert.equal(range.id, `array-shape-${p1.key}`, 'has the id')
359
+ assert.deepEqual(range.types, IAmfArrayTypes, 'has the types')
360
+
361
+ const items = range.items as IApiFileShape
362
+
363
+ assert.typeOf(items, 'object', 'has the items')
364
+ assert.equal(items.id, `file-shape-${p1.key}`, 'has the id')
365
+ assert.deepEqual(items.types, IAmfFileTypes, 'has the types')
366
+
367
+ assert.equal(items.name, 'p1', 'has the name')
368
+ assert.equal(items.displayName, 'string dn', 'has the displayName')
369
+ assert.equal(items.description, 'string desc', 'has the description')
370
+ })
371
+ })
372
+
373
+ test.group('property() / with web bindings', (group) => {
374
+ let root: DataDomain
375
+ let m1: DomainModel
376
+ let e1: DomainEntity
377
+
378
+ group.each.setup(() => {
379
+ root = new DataDomain()
380
+ m1 = root.addModel({ key: 'm1' })
381
+ e1 = m1.addEntity({ key: 'e1', info: { name: 'e1' } })
382
+ })
383
+
384
+ test('updates the name when changed', ({ assert }) => {
385
+ const p1 = e1.addProperty({ key: 'p1', type: 'string', info: { name: 'p1' } })
386
+ p1.bindings = [
387
+ {
388
+ type: 'web',
389
+ schema: {
390
+ name: 'other',
391
+ },
392
+ },
393
+ ]
394
+ const result = p1.toApiShape()
395
+ const string = result.range as IApiScalarShape
396
+
397
+ assert.equal(string.name, 'other', 'the range has the changed name')
398
+ assert.equal(result.name, 'other', 'the property has the changed name')
399
+ })
400
+
401
+ // test('sets the dataType', ({ assert }) => {
402
+ // const p1 = e1.addProperty({ key: 'p1', type: 'string', info: { name: 'p1' } })
403
+ // p1.bindings = [
404
+ // {
405
+ // type: 'web',
406
+ // schema: {
407
+ // // dataType: AmfNamespace.w3.xmlSchema.date,
408
+ // },
409
+ // },
410
+ // ]
411
+ // const result = p1.toApiShape()
412
+ // const string = result.range as IApiScalarShape
413
+ // assert.equal(string.dataType, AmfNamespace.w3.xmlSchema.date)
414
+ // })
415
+
416
+ test('sets the xml serialization', ({ assert }) => {
417
+ const p1 = e1.addProperty({ key: 'p1', type: 'string', info: { name: 'p1' } })
418
+ const value: IApiXmlSerializer = {
419
+ id: '',
420
+ types: [],
421
+ customDomainProperties: [],
422
+ name: 'test',
423
+ }
424
+ p1.bindings = [
425
+ {
426
+ type: 'web',
427
+ schema: {
428
+ xml: value,
429
+ },
430
+ },
431
+ ]
432
+ const result = p1.toApiShape()
433
+ const string = result.range as IApiScalarShape
434
+ assert.deepEqual(string.xmlSerialization, value)
435
+ })
436
+
437
+ test('sets the file types', ({ assert }) => {
438
+ const p1 = e1.addProperty({ key: 'p1', type: 'binary', info: { name: 'p1' } })
439
+ const value: string[] = ['a']
440
+ p1.bindings = [
441
+ {
442
+ type: 'web',
443
+ schema: {
444
+ fileTypes: value,
445
+ },
446
+ },
447
+ ]
448
+ const result = p1.toApiShape()
449
+ const file = result.range as IApiFileShape
450
+ assert.deepEqual(file.fileTypes, value)
451
+ })
452
+
453
+ test('sets the pattern', ({ assert }) => {
454
+ const p1 = e1.addProperty({ key: 'p1', type: 'string', info: { name: 'p1' } })
455
+ p1.bindings = [
456
+ {
457
+ type: 'web',
458
+ schema: {
459
+ pattern: 'a-z',
460
+ },
461
+ },
462
+ ]
463
+ const result = p1.toApiShape()
464
+ const string = result.range as IApiScalarShape
465
+ assert.equal(string.pattern, 'a-z')
466
+ })
467
+
468
+ test('sets the minLength', ({ assert }) => {
469
+ const p1 = e1.addProperty({ key: 'p1', type: 'string', info: { name: 'p1' } })
470
+ p1.schema = {
471
+ minimum: 1,
472
+ }
473
+ const result = p1.toApiShape()
474
+ const string = result.range as IApiScalarShape
475
+ assert.equal(string.minLength, 1)
476
+ })
477
+
478
+ test('sets the maxLength', ({ assert }) => {
479
+ const p1 = e1.addProperty({ key: 'p1', type: 'string', info: { name: 'p1' } })
480
+ p1.schema = {
481
+ maximum: 1,
482
+ }
483
+ const result = p1.toApiShape()
484
+ const string = result.range as IApiScalarShape
485
+ assert.equal(string.maxLength, 1)
486
+ })
487
+
488
+ test('sets the minimum', ({ assert }) => {
489
+ const p1 = e1.addProperty({ key: 'p1', type: 'number', info: { name: 'p1' } })
490
+ p1.schema = {
491
+ minimum: 1,
492
+ }
493
+ const result = p1.toApiShape()
494
+ const string = result.range as IApiScalarShape
495
+ assert.equal(string.minimum, 1)
496
+ })
497
+
498
+ test('sets the maximum', ({ assert }) => {
499
+ const p1 = e1.addProperty({ key: 'p1', type: 'number', info: { name: 'p1' } })
500
+ p1.schema = {
501
+ maximum: 1,
502
+ }
503
+ const result = p1.toApiShape()
504
+ const string = result.range as IApiScalarShape
505
+ assert.equal(string.maximum, 1)
506
+ })
507
+
508
+ test('sets the multipleOf', ({ assert }) => {
509
+ const p1 = e1.addProperty({ key: 'p1', type: 'number', info: { name: 'p1' } })
510
+ p1.schema = {
511
+ multipleOf: 1,
512
+ }
513
+ const result = p1.toApiShape()
514
+ const string = result.range as IApiScalarShape
515
+ assert.equal(string.multipleOf, 1)
516
+ })
517
+
518
+ test('sets the exclusiveMinimum', ({ assert }) => {
519
+ const p1 = e1.addProperty({ key: 'p1', type: 'number', info: { name: 'p1' } })
520
+ p1.schema = {
521
+ exclusiveMinimum: true,
522
+ }
523
+ const result = p1.toApiShape()
524
+ const string = result.range as IApiScalarShape
525
+ assert.isTrue(string.exclusiveMinimum)
526
+ })
527
+
528
+ test('sets the exclusiveMaximum to false', ({ assert }) => {
529
+ const p1 = e1.addProperty({ key: 'p1', type: 'number', info: { name: 'p1' } })
530
+ p1.schema = {
531
+ exclusiveMaximum: false,
532
+ }
533
+ const result = p1.toApiShape()
534
+ const string = result.range as IApiScalarShape
535
+ assert.isFalse(string.exclusiveMaximum)
536
+ })
537
+
538
+ test('sets the exclusiveMaximum to true', ({ assert }) => {
539
+ const p1 = e1.addProperty({ key: 'p1', type: 'number', info: { name: 'p1' } })
540
+ p1.schema = {
541
+ exclusiveMaximum: true,
542
+ }
543
+ const result = p1.toApiShape()
544
+ const string = result.range as IApiScalarShape
545
+ assert.isTrue(string.exclusiveMaximum)
546
+ })
547
+
548
+ test('sets the format', ({ assert }) => {
549
+ const p1 = e1.addProperty({ key: 'p1', type: 'number', info: { name: 'p1' } })
550
+ p1.bindings = [
551
+ {
552
+ type: 'web',
553
+ schema: {
554
+ format: 'float',
555
+ },
556
+ },
557
+ ]
558
+ const result = p1.toApiShape()
559
+ const string = result.range as IApiScalarShape
560
+ assert.equal(string.format, AmfNamespace.w3.xmlSchema.float)
561
+ })
562
+ })
563
+
564
+ test.group('property() / with schema', (group) => {
565
+ let root: DataDomain
566
+ let m1: DomainModel
567
+ let e1: DomainEntity
568
+
569
+ group.each.setup(() => {
570
+ root = new DataDomain()
571
+ m1 = root.addModel({ key: 'm1' })
572
+ e1 = m1.addEntity({ key: 'e1', info: { name: 'e1' } })
573
+ })
574
+
575
+ test('sets the default value', ({ assert }) => {
576
+ const p1 = e1.addProperty({ key: 'p1', type: 'number', info: { name: 'p1' } })
577
+ p1.schema = {
578
+ defaultValue: { value: '123', type: 'literal' },
579
+ }
580
+ const result = p1.toApiShape()
581
+ const range = result.range as IApiScalarShape
582
+ assert.typeOf(range.defaultValue, 'object', 'has the defaultValue')
583
+ const value = range.defaultValue as IApiScalarNode
584
+ assert.strictEqual(value.value, '123', 'has the value')
585
+ assert.equal(value.dataType, AmfNamespace.w3.xmlSchema.number, 'has the range data type')
586
+ })
587
+
588
+ test('sets the enum value', ({ assert }) => {
589
+ const p1 = e1.addProperty({ key: 'p1', type: 'number', info: { name: 'p1' } })
590
+ p1.schema = {
591
+ enum: ['123'],
592
+ }
593
+ const result = p1.toApiShape()
594
+ const range = result.range as IApiScalarShape
595
+ assert.typeOf(range.values, 'array', 'has the values')
596
+ const value = range.values[0] as IApiScalarNode
597
+ assert.strictEqual(value.value, '123', 'has the value')
598
+ assert.equal(value.dataType, AmfNamespace.w3.xmlSchema.number, 'has the range data type')
599
+ })
600
+
601
+ test('sets the examples value', ({ assert }) => {
602
+ const p1 = e1.addProperty({ key: 'p1', type: 'string', info: { name: 'p1' } })
603
+ p1.schema = {
604
+ examples: ['123'],
605
+ }
606
+ const result = p1.toApiShape()
607
+ const range = result.range as IApiScalarShape
608
+ assert.typeOf(range.examples, 'array', 'has the examples')
609
+ const example = range.examples[0] as IApiDataExample
610
+
611
+ assert.typeOf(example.id, 'string', 'has the example.id')
612
+ assert.isNotEmpty(example.id, 'the example.id is not empty')
613
+ assert.deepEqual(example.types, IAmfExampleTypes, 'the example.types')
614
+ assert.typeOf(example.structuredValue, 'object', 'has the example.structuredValue')
615
+
616
+ const value = example.structuredValue as IApiScalarNode
617
+ assert.strictEqual(value.value, '123', 'has the value')
618
+ assert.equal(value.dataType, AmfNamespace.w3.xmlSchema.string, 'has the range data type')
619
+ })
620
+ })
621
+
622
+ test.group('property() / default value functions', (group) => {
623
+ let root: DataDomain
624
+ let m1: DomainModel
625
+ let e1: DomainEntity
626
+ let p1: DomainProperty
627
+
628
+ group.each.setup(() => {
629
+ root = new DataDomain()
630
+ m1 = root.addModel({ key: 'm1' })
631
+ e1 = m1.addEntity({ key: 'e1', info: { name: 'e1' } })
632
+ p1 = e1.addProperty({ key: 'p1', info: { name: 'p1' } })
633
+ })
634
+
635
+ test('generates random string for "random" function', ({ assert }) => {
636
+ p1.schema = { defaultValue: { value: 'random', type: 'function' } }
637
+ const generator = new ShapeGenerator()
638
+ const result = generator.property(p1)
639
+ const range = result.range as IApiScalarShape
640
+ assert.typeOf(range.defaultValue, 'object')
641
+ const value = range.defaultValue as IApiScalarNode
642
+ assert.typeOf(value.value, 'string')
643
+ assert.lengthOf(value.value as string, 8)
644
+ })
645
+
646
+ test('generates uuid for "uuid-v4" function', ({ assert }) => {
647
+ p1.schema = { defaultValue: { value: 'uuid-v4', type: 'function' } }
648
+ const generator = new ShapeGenerator()
649
+ const result = generator.property(p1)
650
+ const range = result.range as IApiScalarShape
651
+ assert.typeOf(range.defaultValue, 'object')
652
+ const value = range.defaultValue as IApiScalarNode
653
+ assert.typeOf(value.value, 'string')
654
+ assert.lengthOf(value.value as string, 36)
655
+ assert.match(value.value as string, /^[0-9a-f-]+$/)
656
+ })
657
+
658
+ test('generates incremental number for "incremental" function', ({ assert }) => {
659
+ p1.type = 'number'
660
+ p1.schema = { defaultValue: { value: 'incremental', type: 'function' } }
661
+ const generator = new ShapeGenerator()
662
+ const result1 = generator.property(p1)
663
+ const range1 = result1.range as IApiScalarShape
664
+ assert.typeOf(range1.defaultValue, 'object')
665
+ const value1 = range1.defaultValue as IApiScalarNode
666
+ assert.typeOf(value1.value, 'string')
667
+ assert.equal(parseInt(value1.value as string), 0)
668
+
669
+ const result2 = generator.property(p1)
670
+ const range2 = result2.range as IApiScalarShape
671
+ assert.typeOf(range2.defaultValue, 'object')
672
+ const value2 = range2.defaultValue as IApiScalarNode
673
+ assert.typeOf(value2.value, 'string')
674
+ assert.equal(parseInt(value2.value as string), 1)
675
+ })
676
+
677
+ test('generates current date for "now" function (date type)', ({ assert }) => {
678
+ p1.type = 'date'
679
+ p1.schema = { defaultValue: { value: 'now', type: 'function' } }
680
+ const generator = new ShapeGenerator()
681
+ const result = generator.property(p1)
682
+ const range = result.range as IApiScalarShape
683
+ assert.typeOf(range.defaultValue, 'object')
684
+ const value = range.defaultValue as IApiScalarNode
685
+ assert.typeOf(value.value, 'string')
686
+ assert.match(value.value as string, /^\d{4}-\d{2}-\d{2}$/)
687
+ })
688
+
689
+ test('generates current time for "now" function (time type)', ({ assert }) => {
690
+ p1.type = 'time'
691
+ p1.schema = { defaultValue: { value: 'now', type: 'function' } }
692
+ const generator = new ShapeGenerator()
693
+ const result = generator.property(p1)
694
+ const range = result.range as IApiScalarShape
695
+ assert.typeOf(range.defaultValue, 'object')
696
+ const value = range.defaultValue as IApiScalarNode
697
+ assert.typeOf(value.value, 'string')
698
+ assert.match(value.value as string, /^\d{2}:\d{2}:\d{2}$/)
699
+ })
700
+
701
+ test('generates current datetime for "now" function (datetime type)', ({ assert }) => {
702
+ p1.type = 'datetime'
703
+ p1.schema = { defaultValue: { value: 'now', type: 'function' } }
704
+ const generator = new ShapeGenerator()
705
+ const result = generator.property(p1)
706
+ const range = result.range as IApiScalarShape
707
+ assert.typeOf(range.defaultValue, 'object')
708
+ const value = range.defaultValue as IApiScalarNode
709
+ assert.typeOf(value.value, 'string')
710
+ assert.match(value.value as string, /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$/)
711
+ })
712
+
713
+ test('returns "noValue" for unsupported function', ({ assert }) => {
714
+ p1.schema = { defaultValue: { value: 'unsupported', type: 'function' } }
715
+ const generator = new ShapeGenerator()
716
+ const result = generator.property(p1)
717
+ const range = result.range as IApiScalarShape
718
+ assert.isUndefined(range.defaultValue)
719
+ })
720
+ })
721
+
722
+ test.group('refactorArrayToShape()', (group) => {
723
+ let root: DataDomain
724
+ let m1: DomainModel
725
+ let e1: DomainEntity
726
+ let p1: DomainProperty
727
+
728
+ group.each.setup(() => {
729
+ root = new DataDomain()
730
+ m1 = root.addModel({ key: 'm1' })
731
+ e1 = m1.addEntity({ key: 'e1', info: { name: 'e1' } })
732
+ p1 = e1.addProperty({ key: 'p1', info: { name: 'p1' } })
733
+ })
734
+
735
+ test('returns the array items', ({ assert }) => {
736
+ p1.multiple = true
737
+ const parameter = p1.toApiShape()
738
+ const range = parameter.range as IApiArrayShape
739
+ const shape = range.items as IApiScalarShape
740
+ assert.deepEqual(range.items, shape)
741
+ })
742
+ })
743
+
744
+ test.group('refactorShapeToArray()', (group) => {
745
+ let root: DataDomain
746
+ let m1: DomainModel
747
+ let e1: DomainEntity
748
+ let p1: DomainProperty
749
+
750
+ group.each.setup(() => {
751
+ root = new DataDomain()
752
+ m1 = root.addModel({ key: 'm1' })
753
+ e1 = m1.addEntity({ key: 'e1', info: { name: 'e1' } })
754
+ p1 = e1.addProperty({ key: 'p1', info: { name: 'p1' } })
755
+ })
756
+
757
+ test('returns the array items', ({ assert }) => {
758
+ const parameter = p1.toApiShape()
759
+ const range = parameter.range as IApiScalarShape
760
+ const generator = new ShapeGenerator()
761
+ const result = generator['refactorShapeToArray'](p1.key, range)
762
+
763
+ assert.typeOf(result, 'object', 'has the range')
764
+ assert.equal(result.id, `array-shape-${p1.key}`, 'has the id')
765
+ assert.deepEqual(result.types, IAmfArrayTypes, 'has the types')
766
+
767
+ const items = result.items as IApiScalarShape
768
+ assert.deepEqual(items, range)
769
+ })
770
+ })
771
+
772
+ test.group('associationProperty()', (group) => {
773
+ let root: DataDomain
774
+ let m1: DomainModel
775
+ let e1: DomainEntity
776
+ let e2: DomainEntity
777
+ let a1: DomainAssociation
778
+ let p2: DomainProperty
779
+
780
+ group.each.setup(() => {
781
+ root = new DataDomain()
782
+ m1 = root.addModel({ key: 'm1' })
783
+ e1 = m1.addEntity({ key: 'e1', info: { name: 'e1' } })
784
+ e2 = m1.addEntity({ key: 'e2', info: { name: 'e2' } })
785
+ a1 = e1.addAssociation({ key: e2.key }, { key: 'a1', info: { name: 'a1' } })
786
+ e1.addProperty({ key: 'p1', type: 'boolean', info: { name: 'p1' } })
787
+ p2 = e2.addProperty({ key: 'p2', type: 'number', info: { name: 'p2' } })
788
+ })
789
+
790
+ test('returns basic shape definition', ({ assert }) => {
791
+ const result = a1.toApiShape()
792
+ assert.typeOf(result, 'object')
793
+
794
+ assert.equal(result.id, a1.key, 'has the id')
795
+ assert.deepEqual(result.types, IAmfPropertyTypes, 'has the types')
796
+ assert.deepEqual(result.values, [], 'has the values')
797
+ assert.deepEqual(result.inherits, [], 'has the inherits')
798
+ assert.deepEqual(result.or, [], 'has the or')
799
+ assert.deepEqual(result.and, [], 'has the and')
800
+ assert.deepEqual(result.xone, [], 'has the xone')
801
+ assert.equal(result.path, AmfNamespace.aml.vocabularies.data.key + 'a1', 'has the path')
802
+
803
+ const range = result.range as IApiNodeShape
804
+ assert.typeOf(range, 'object', 'has the range')
805
+ assert.deepEqual(range.types, IAmfNodeTypes, 'range has the types')
806
+ assert.equal(range.name, 'e2', 'range has the name')
807
+ assert.lengthOf(range.properties, 1, 'range has the properties')
808
+
809
+ const [prop] = range.properties
810
+ assert.equal(prop.id, p2.key, 'property has the id')
811
+ assert.deepEqual(prop.types, IAmfPropertyTypes, 'property has the types')
812
+
813
+ const pRange = prop.range as IApiScalarShape
814
+ assert.typeOf(pRange, 'object', 'property range is an object')
815
+ assert.deepEqual(pRange.types, IAmfScalarTypes, 'property range has the types')
816
+ assert.equal(pRange.name, 'p2', 'property range has the name')
817
+ assert.equal(pRange.dataType, AmfNamespace.w3.xmlSchema.number, 'property range has the dataType')
818
+ })
819
+
820
+ test('sets property description', ({ assert }) => {
821
+ a1.info.displayName = 'dn a1'
822
+ a1.info.description = 'desc a1'
823
+ const result = a1.toApiShape()
824
+ assert.equal(result.name, 'a1')
825
+ assert.equal(result.displayName, 'dn a1')
826
+ assert.equal(result.description, 'desc a1')
827
+ })
828
+
829
+ test('sets the minCount', ({ assert }) => {
830
+ a1.required = true
831
+ const result = a1.toApiShape()
832
+ assert.equal(result.minCount, 1)
833
+ })
834
+
835
+ test('sets the path', ({ assert }) => {
836
+ a1.required = true
837
+ const result = a1.toApiShape()
838
+ assert.equal(result.path, AmfNamespace.aml.vocabularies.data.key + 'a1', 'has the path')
839
+ })
840
+
841
+ test('returns a link definition when created on the schema', ({ assert }) => {
842
+ a1.schema = { linked: true }
843
+ const result = a1.toApiShape()
844
+ const range = result.range as IApiScalarShape
845
+ assert.equal(range.id, `link-${a1.key}`)
846
+ assert.deepEqual(range.types, IAmfScalarTypes)
847
+ assert.equal(range.dataType, AmfNamespace.w3.xmlSchema.string)
848
+ })
849
+
850
+ test('returns a default union type', ({ assert }) => {
851
+ const e3 = m1.addEntity({ key: 'e3', info: { name: 'e3' } })
852
+ a1.addTarget(e3)
853
+ const result = a1.toApiShape()
854
+ const range = result.range as IApiUnionShape
855
+
856
+ assert.typeOf(range, 'object', 'has the range')
857
+ assert.equal(range.id, `union-shape-${a1.key}`, 'the range has the id')
858
+ assert.deepEqual(range.types, IAmfUnionTypes, 'the range has the types')
859
+ assert.lengthOf(range.anyOf, 2, 'has the anyOf array')
860
+ const [p1, p2] = range.anyOf as IApiNodeShape[]
861
+
862
+ assert.deepEqual(p1.types, IAmfNodeTypes, 'p1 has the types')
863
+ assert.deepEqual(p2.types, IAmfNodeTypes, 'p2 has the types')
864
+ assert.lengthOf(p1.properties, 1, 'p1 has the properties')
865
+ assert.lengthOf(p2.properties, 0, 'p2 has the properties')
866
+ })
867
+
868
+ test('has no range when no associations', ({ assert }) => {
869
+ a1.removeTarget(e2)
870
+ const result = a1.toApiShape()
871
+ assert.isUndefined(result.range)
872
+ })
873
+
874
+ test('returns an array shape when multiple', ({ assert }) => {
875
+ a1.multiple = true
876
+ const result = a1.toApiShape()
877
+ const range = result.range as IApiArrayShape
878
+ assert.deepEqual(range.types, IAmfArrayTypes)
879
+
880
+ const arrayRange = range.items as IApiNodeShape
881
+ assert.typeOf(arrayRange, 'object', 'has the range')
882
+ assert.deepEqual(arrayRange.types, IAmfNodeTypes, 'range has the types')
883
+ assert.equal(arrayRange.name, 'e2', 'range has the name')
884
+ assert.lengthOf(arrayRange.properties, 1, 'range has the properties')
885
+ })
886
+
887
+ test('creates the "anyOf" union', ({ assert }) => {
888
+ a1.schema = { unionType: 'anyOf' }
889
+
890
+ const e3 = m1.addEntity({ key: 'e3', info: { name: 'e3' } })
891
+ a1.addTarget(e3)
892
+ const result = a1.toApiShape()
893
+ const range = result.range as IApiUnionShape
894
+
895
+ assert.typeOf(range, 'object', 'has the range')
896
+ assert.equal(range.id, `union-shape-${a1.key}`, 'the range has the id')
897
+ assert.deepEqual(range.types, IAmfUnionTypes, 'the range has the types')
898
+ assert.lengthOf(range.anyOf, 2, 'has the anyOf array')
899
+ const [p1, p2] = range.anyOf as IApiNodeShape[]
900
+
901
+ assert.deepEqual(p1.types, IAmfNodeTypes, 'p1 has the types')
902
+ assert.deepEqual(p2.types, IAmfNodeTypes, 'p2 has the types')
903
+ assert.lengthOf(p1.properties, 1, 'p1 has the properties')
904
+ assert.lengthOf(p2.properties, 0, 'p2 has the properties')
905
+ })
906
+
907
+ test('creates the "allOf" union', ({ assert }) => {
908
+ a1.schema = { unionType: 'allOf' }
909
+
910
+ const e3 = m1.addEntity({ key: 'e3', info: { name: 'e3' } })
911
+ a1.addTarget(e3)
912
+ const result = a1.toApiShape()
913
+ const range = result.range as IApiUnionShape
914
+
915
+ assert.typeOf(range, 'object', 'has the range')
916
+ assert.equal(range.id, `union-shape-${a1.key}`, 'the range has the id')
917
+ assert.deepEqual(range.types, IAmfUnionTypes, 'the range has the types')
918
+ assert.lengthOf(range.and, 2, 'has the anyOf array')
919
+ const [p1, p2] = range.and as IApiNodeShape[]
920
+
921
+ assert.deepEqual(p1.types, IAmfNodeTypes, 'p1 has the types')
922
+ assert.deepEqual(p2.types, IAmfNodeTypes, 'p2 has the types')
923
+ assert.lengthOf(p1.properties, 1, 'p1 has the properties')
924
+ assert.lengthOf(p2.properties, 0, 'p2 has the properties')
925
+ })
926
+
927
+ test('creates the "oneOf" union', ({ assert }) => {
928
+ a1.schema = { unionType: 'oneOf' }
929
+
930
+ const e3 = m1.addEntity({ key: 'e3', info: { name: 'e3' } })
931
+ a1.addTarget(e3)
932
+ const result = a1.toApiShape()
933
+ const range = result.range as IApiUnionShape
934
+
935
+ assert.typeOf(range, 'object', 'has the range')
936
+ assert.equal(range.id, `union-shape-${a1.key}`, 'the range has the id')
937
+ assert.deepEqual(range.types, IAmfUnionTypes, 'the range has the types')
938
+ assert.lengthOf(range.xone, 2, 'has the oneOf array')
939
+ const [p1, p2] = range.xone as IApiNodeShape[]
940
+
941
+ assert.deepEqual(p1.types, IAmfNodeTypes, 'p1 has the types')
942
+ assert.deepEqual(p2.types, IAmfNodeTypes, 'p2 has the types')
943
+ assert.lengthOf(p1.properties, 1, 'p1 has the properties')
944
+ assert.lengthOf(p2.properties, 0, 'p2 has the properties')
945
+ })
946
+
947
+ test('creates the "not" union', ({ assert }) => {
948
+ a1.schema = { unionType: 'not' }
949
+
950
+ const e3 = m1.addEntity({ key: 'e3', info: { name: 'e3' } })
951
+ a1.addTarget(e3)
952
+ const result = a1.toApiShape()
953
+ const range = result.range as IApiUnionShape
954
+
955
+ assert.typeOf(range, 'object', 'has the range')
956
+ assert.equal(range.id, `union-shape-${a1.key}`, 'the range has the id')
957
+ assert.deepEqual(range.types, IAmfUnionTypes, 'the range has the types')
958
+ assert.typeOf(range.not, 'object', 'has the not object')
959
+
960
+ const not = range.not as IApiNodeShape
961
+ assert.deepEqual(not.types, IAmfNodeTypes, 'p1 has the types')
962
+ assert.deepEqual(not.types, IAmfNodeTypes, 'p2 has the types')
963
+ assert.lengthOf(not.properties, 1, 'p1 has the properties')
964
+ })
965
+
966
+ test('creates the "not" shape', ({ assert }) => {
967
+ a1.schema = { unionType: 'not' }
968
+
969
+ const result = a1.toApiShape()
970
+ const range = result.range as IApiUnionShape
971
+
972
+ assert.typeOf(range, 'object', 'has the range')
973
+ assert.equal(range.id, `not-shape-${a1.key}`, 'the range has the id')
974
+ assert.deepEqual(range.types, IAmfAnyTypes, 'the range has the types')
975
+ assert.typeOf(range.not, 'object', 'has the not object')
976
+
977
+ const not = range.not as IApiNodeShape
978
+ assert.deepEqual(not.types, IAmfNodeTypes, 'p1 has the types')
979
+ assert.deepEqual(not.types, IAmfNodeTypes, 'p2 has the types')
980
+ assert.lengthOf(not.properties, 1, 'p1 has the properties')
981
+ })
982
+
983
+ test('wraps the union in the array shape', ({ assert }) => {
984
+ a1.multiple = true
985
+ a1.schema = { unionType: 'anyOf' }
986
+
987
+ const e3 = m1.addEntity({ key: 'e3', info: { name: 'e3' } })
988
+ a1.addTarget(e3)
989
+ const result = a1.toApiShape()
990
+ const range = result.range as IApiArrayShape
991
+
992
+ assert.typeOf(range, 'object', 'has the range')
993
+ assert.equal(range.id, `array-shape-${a1.key}`, 'the range has the id')
994
+ assert.deepEqual(range.types, IAmfArrayTypes, 'the range has the types')
995
+
996
+ const items = range.items as IApiUnionShape
997
+
998
+ assert.lengthOf(items.anyOf, 2, 'has the anyOf array')
999
+ const [p1, p2] = items.anyOf as IApiNodeShape[]
1000
+
1001
+ assert.deepEqual(p1.types, IAmfNodeTypes, 'p1 has the types')
1002
+ assert.deepEqual(p2.types, IAmfNodeTypes, 'p2 has the types')
1003
+ assert.lengthOf(p1.properties, 1, 'p1 has the properties')
1004
+ assert.lengthOf(p2.properties, 0, 'p2 has the properties')
1005
+ })
1006
+
1007
+ test('handles linked schema', ({ assert }) => {
1008
+ a1.schema = { linked: true }
1009
+ const result = a1.toApiShape()
1010
+ const range = result.range as IApiScalarShape
1011
+ assert.equal(range.dataType, AmfNamespace.w3.xmlSchema.string)
1012
+ })
1013
+
1014
+ test('handles multiple associations', ({ assert }) => {
1015
+ const e3 = m1.addEntity({ key: 'e3', info: { name: 'e3' } })
1016
+ a1.addTarget(e3)
1017
+ const result = a1.toApiShape()
1018
+ const range = result.range as IApiUnionShape
1019
+ assert.lengthOf(range.anyOf, 2)
1020
+ })
1021
+
1022
+ test('handles unionType', ({ assert }) => {
1023
+ a1.schema = { unionType: 'allOf' }
1024
+ const e3 = m1.addEntity({ key: 'e3', info: { name: 'e3' } })
1025
+ a1.addTarget(e3)
1026
+ const result = a1.toApiShape()
1027
+ const range = result.range as IApiUnionShape
1028
+ assert.lengthOf(range.and, 2)
1029
+ })
1030
+
1031
+ test('handles multiple and unionType', ({ assert }) => {
1032
+ a1.multiple = true
1033
+ a1.schema = { unionType: 'allOf' }
1034
+ const e3 = m1.addEntity({ key: 'e3', info: { name: 'e3' } })
1035
+ a1.addTarget(e3)
1036
+ const result = a1.toApiShape()
1037
+ const range = result.range as IApiArrayShape
1038
+ const items = range.items as IShapeUnion
1039
+ assert.lengthOf(items.and, 2)
1040
+ })
1041
+ })
1042
+
1043
+ test.group('AI Generated tests', (group) => {
1044
+ let root: DataDomain
1045
+ let m1: DomainModel
1046
+ let e1: DomainEntity
1047
+ let e2: DomainEntity
1048
+ let a1: DomainAssociation
1049
+ let p1: DomainProperty
1050
+
1051
+ group.each.setup(() => {
1052
+ root = new DataDomain()
1053
+ m1 = root.addModel({ key: 'm1' })
1054
+ e1 = m1.addEntity({ key: 'e1', info: { name: 'e1' } })
1055
+ e2 = m1.addEntity({ key: 'e2', info: { name: 'e2' } })
1056
+ a1 = e1.addAssociation({ key: e2.key }, { key: 'a1', info: { name: 'a1' } })
1057
+ p1 = e1.addProperty({ key: 'p1', info: { name: 'p1' } })
1058
+ })
1059
+
1060
+ test('does not add hidden properties to the properties array', ({ assert }) => {
1061
+ const p3 = e1.addProperty({ key: 'p3', info: { name: 'p3' } })
1062
+ const bindings = p3.getWebBinding()
1063
+ bindings.hidden = true
1064
+ const result = e1.toApiShape() as IApiNodeShape
1065
+ assert.lengthOf(result.properties, 2)
1066
+ assert.isFalse(result.properties.some((prop) => prop.id === p3.key))
1067
+ })
1068
+
1069
+ test('handles foreign namespaces', ({ assert }) => {
1070
+ const fd1 = new DataDomain()
1071
+ const m2 = fd1.addModel({ key: 'm2' })
1072
+ const e3 = m2.addEntity({ key: 'e3', info: { name: 'e3' } })
1073
+ fd1.info.version = '1.0.0'
1074
+ root.registerForeignDomain(fd1)
1075
+ const a2 = e1.addAssociation({ key: e3.key, domain: fd1.key }, { key: 'a2', info: { name: 'a2' } })
1076
+ const result = e1.toApiShape() as IApiNodeShape
1077
+ assert.lengthOf(result.properties, 3)
1078
+ assert.isTrue(result.properties.some((prop) => prop.id === a2.key))
1079
+ })
1080
+
1081
+ test('handles multiple properties with examples', ({ assert }) => {
1082
+ p1.multiple = true
1083
+ p1.schema = { examples: ['example1', 'example2'] }
1084
+ const result = p1.toApiShape()
1085
+ const range = result.range as IApiArrayShape
1086
+ assert.include(range.types, AmfNamespace.aml.vocabularies.shapes.ArrayShape)
1087
+ assert.lengthOf(range.examples, 1)
1088
+ assert.property(range.examples[0], 'structuredValue')
1089
+ })
1090
+
1091
+ test('handles multiple properties with default values', ({ assert }) => {
1092
+ p1.multiple = true
1093
+ p1.schema = { defaultValue: { value: 'defaultValue', type: 'literal' } }
1094
+ const result = p1.toApiShape()
1095
+ const range = result.range as IApiArrayShape
1096
+ assert.include(range.types, AmfNamespace.aml.vocabularies.shapes.ArrayShape)
1097
+ assert.property(range, 'defaultValue')
1098
+ assert.containsSubset(range.defaultValue, {
1099
+ value: 'defaultValue',
1100
+ })
1101
+ })
1102
+
1103
+ test('handles multiple properties with enum', ({ assert }) => {
1104
+ p1.multiple = true
1105
+ p1.schema = { enum: ['enum1', 'enum2'] }
1106
+ const result = p1.toApiShape()
1107
+ const range = result.range as IApiArrayShape
1108
+ assert.include(range.types, AmfNamespace.aml.vocabularies.shapes.ArrayShape)
1109
+ assert.lengthOf(range.values, 2)
1110
+ assert.containsSubset(range.values[0], {
1111
+ dataType: AmfNamespace.w3.xmlSchema.string,
1112
+ value: `enum1`,
1113
+ })
1114
+ assert.containsSubset(range.values[1], {
1115
+ dataType: AmfNamespace.w3.xmlSchema.string,
1116
+ value: `enum2`,
1117
+ })
1118
+ })
1119
+
1120
+ test('handles multiple properties with schema', ({ assert }) => {
1121
+ p1.multiple = true
1122
+ p1.schema = { minimum: 1, maximum: 10 }
1123
+ const result = p1.toApiShape()
1124
+ const range = result.range as IApiArrayShape
1125
+ assert.include(range.types, AmfNamespace.aml.vocabularies.shapes.ArrayShape)
1126
+ const items = range.items as IApiScalarShape
1127
+ assert.equal(items.minLength, 1)
1128
+ assert.equal(items.maxLength, 10)
1129
+ })
1130
+
1131
+ test('handles multiple properties with bindings', ({ assert }) => {
1132
+ p1.multiple = true
1133
+ p1.bindings = [
1134
+ {
1135
+ type: 'web',
1136
+ schema: {
1137
+ format: 'int32',
1138
+ },
1139
+ },
1140
+ ]
1141
+ const result = p1.toApiShape()
1142
+ const range = result.range as IApiArrayShape
1143
+ const items = range.items as IApiScalarShape
1144
+ assert.include(range.types, AmfNamespace.aml.vocabularies.shapes.ArrayShape)
1145
+ assert.equal(items.format, AmfNamespace.w3.xmlSchema.integer)
1146
+ })
1147
+
1148
+ test('handles multiple associations with schema', ({ assert }) => {
1149
+ a1.multiple = true
1150
+ a1.schema = { linked: false }
1151
+ const result = a1.toApiShape()
1152
+ const range = result.range as IApiArrayShape
1153
+ assert.include(range.types, AmfNamespace.aml.vocabularies.shapes.ArrayShape)
1154
+ const items = range.items as IApiScalarShape
1155
+ assert.ok(items)
1156
+ })
1157
+
1158
+ test('handles multiple associations with bindings', ({ assert }) => {
1159
+ a1.multiple = true
1160
+ a1.bindings = [
1161
+ {
1162
+ type: 'web',
1163
+ schema: {
1164
+ hidden: false,
1165
+ },
1166
+ },
1167
+ ]
1168
+ const result = a1.toApiShape()
1169
+ const range = result.range as IApiArrayShape
1170
+ assert.include(range.types, AmfNamespace.aml.vocabularies.shapes.ArrayShape)
1171
+ const items = range.items as IApiNodeShape
1172
+ assert.ok(items.properties)
1173
+ })
1174
+ })