@api-client/core 0.15.1 → 0.16.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.
- package/TESTING_READY.md +114 -0
- package/TESTING_SETUP.md +198 -0
- package/build/src/modeling/Semantics.d.ts +126 -2
- package/build/src/modeling/Semantics.d.ts.map +1 -1
- package/build/src/modeling/Semantics.js +281 -13
- package/build/src/modeling/Semantics.js.map +1 -1
- package/build/src/modeling/definitions/Calculated.d.ts +54 -0
- package/build/src/modeling/definitions/Calculated.d.ts.map +1 -0
- package/build/src/modeling/definitions/Calculated.js +31 -0
- package/build/src/modeling/definitions/Calculated.js.map +1 -0
- package/build/src/modeling/definitions/Categories.d.ts +60 -0
- package/build/src/modeling/definitions/Categories.d.ts.map +1 -0
- package/build/src/modeling/definitions/Categories.js +33 -0
- package/build/src/modeling/definitions/Categories.js.map +1 -0
- package/build/src/modeling/definitions/Derived.d.ts +54 -0
- package/build/src/modeling/definitions/Derived.d.ts.map +1 -0
- package/build/src/modeling/definitions/Derived.js +31 -0
- package/build/src/modeling/definitions/Derived.js.map +1 -0
- package/build/src/modeling/definitions/Description.d.ts +36 -0
- package/build/src/modeling/definitions/Description.d.ts.map +1 -0
- package/build/src/modeling/definitions/Description.js +28 -0
- package/build/src/modeling/definitions/Description.js.map +1 -0
- package/build/src/modeling/definitions/Email.d.ts +66 -0
- package/build/src/modeling/definitions/Email.d.ts.map +1 -0
- package/build/src/modeling/definitions/Email.js +33 -0
- package/build/src/modeling/definitions/Email.js.map +1 -0
- package/build/src/modeling/definitions/GeospatialCoordinates.d.ts +212 -0
- package/build/src/modeling/definitions/GeospatialCoordinates.d.ts.map +1 -0
- package/build/src/modeling/definitions/GeospatialCoordinates.js +129 -0
- package/build/src/modeling/definitions/GeospatialCoordinates.js.map +1 -0
- package/build/src/modeling/definitions/HTML.d.ts +88 -0
- package/build/src/modeling/definitions/HTML.d.ts.map +1 -0
- package/build/src/modeling/definitions/HTML.js +42 -0
- package/build/src/modeling/definitions/HTML.js.map +1 -0
- package/build/src/modeling/definitions/Markdown.d.ts +84 -0
- package/build/src/modeling/definitions/Markdown.d.ts.map +1 -0
- package/build/src/modeling/definitions/Markdown.js +41 -0
- package/build/src/modeling/definitions/Markdown.js.map +1 -0
- package/build/src/modeling/definitions/Password.d.ts +112 -0
- package/build/src/modeling/definitions/Password.d.ts.map +1 -0
- package/build/src/modeling/definitions/Password.js +57 -0
- package/build/src/modeling/definitions/Password.js.map +1 -0
- package/build/src/modeling/definitions/Phone.d.ts +83 -0
- package/build/src/modeling/definitions/Phone.d.ts.map +1 -0
- package/build/src/modeling/definitions/Phone.js +39 -0
- package/build/src/modeling/definitions/Phone.js.map +1 -0
- package/build/src/modeling/definitions/Price.d.ts +102 -0
- package/build/src/modeling/definitions/Price.d.ts.map +1 -0
- package/build/src/modeling/definitions/Price.js +99 -0
- package/build/src/modeling/definitions/Price.js.map +1 -0
- package/build/src/modeling/definitions/PublicUniqueName.d.ts +69 -0
- package/build/src/modeling/definitions/PublicUniqueName.d.ts.map +1 -0
- package/build/src/modeling/definitions/PublicUniqueName.js +34 -0
- package/build/src/modeling/definitions/PublicUniqueName.js.map +1 -0
- package/build/src/modeling/definitions/SKU.d.ts +127 -0
- package/build/src/modeling/definitions/SKU.d.ts.map +1 -0
- package/build/src/modeling/definitions/SKU.js +142 -0
- package/build/src/modeling/definitions/SKU.js.map +1 -0
- package/build/src/modeling/definitions/Status.d.ts +150 -0
- package/build/src/modeling/definitions/Status.d.ts.map +1 -0
- package/build/src/modeling/definitions/Status.js +60 -0
- package/build/src/modeling/definitions/Status.js.map +1 -0
- package/build/src/modeling/definitions/Summary.d.ts +53 -0
- package/build/src/modeling/definitions/Summary.d.ts.map +1 -0
- package/build/src/modeling/definitions/Summary.js +50 -0
- package/build/src/modeling/definitions/Summary.js.map +1 -0
- package/build/src/modeling/definitions/Tags.d.ts +52 -0
- package/build/src/modeling/definitions/Tags.d.ts.map +1 -0
- package/build/src/modeling/definitions/Tags.js +32 -0
- package/build/src/modeling/definitions/Tags.js.map +1 -0
- package/build/src/modeling/definitions/URL.d.ts +68 -0
- package/build/src/modeling/definitions/URL.d.ts.map +1 -0
- package/build/src/modeling/definitions/URL.js +37 -0
- package/build/src/modeling/definitions/URL.js.map +1 -0
- package/build/src/modeling/validation/semantic_validation.d.ts +4 -0
- package/build/src/modeling/validation/semantic_validation.d.ts.map +1 -1
- package/build/src/modeling/validation/semantic_validation.js +32 -1
- package/build/src/modeling/validation/semantic_validation.js.map +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/data/models/example-generator-api.json +11 -11
- package/package.json +1 -1
- package/src/modeling/Semantics.ts +297 -14
- package/src/modeling/definitions/Calculated.ts +76 -0
- package/src/modeling/definitions/Categories.ts +84 -0
- package/src/modeling/definitions/Derived.ts +76 -0
- package/src/modeling/definitions/Description.ts +55 -0
- package/src/modeling/definitions/Email.ts +90 -0
- package/src/modeling/definitions/GeospatialCoordinates.ts +274 -0
- package/src/modeling/definitions/HTML.ts +121 -0
- package/src/modeling/definitions/Markdown.ts +116 -0
- package/src/modeling/definitions/Password.ts +156 -0
- package/src/modeling/definitions/Phone.ts +116 -0
- package/src/modeling/definitions/Price.examples.md +158 -0
- package/src/modeling/definitions/Price.ts +180 -0
- package/src/modeling/definitions/PublicUniqueName.ts +98 -0
- package/src/modeling/definitions/SKU.examples.md +230 -0
- package/src/modeling/definitions/SKU.ts +254 -0
- package/src/modeling/definitions/Status.ts +227 -0
- package/src/modeling/definitions/Summary.ts +73 -0
- package/src/modeling/definitions/Tags.ts +75 -0
- package/src/modeling/definitions/URL.ts +96 -0
- package/src/modeling/validation/semantic_validation.ts +35 -1
- package/tests/example-test-setup.ts +133 -0
- package/tests/template-node.spec.ts +75 -0
- package/tests/test-utils.ts +293 -0
- package/tests/unit/modeling/definitions/calculated.spec.ts +33 -0
- package/tests/unit/modeling/definitions/categories.spec.ts +38 -0
- package/tests/unit/modeling/definitions/derived.spec.ts +34 -0
- package/tests/unit/modeling/definitions/description.spec.ts +38 -0
- package/tests/unit/modeling/definitions/email.spec.ts +38 -0
- package/tests/unit/modeling/definitions/geospatial-coordinates.spec.ts +41 -0
- package/tests/unit/modeling/definitions/html.spec.ts +38 -0
- package/tests/unit/modeling/definitions/markdown.spec.ts +38 -0
- package/tests/unit/modeling/definitions/password.spec.ts +347 -0
- package/tests/unit/modeling/definitions/phone.spec.ts +38 -0
- package/tests/unit/modeling/definitions/price.spec.ts +465 -0
- package/tests/unit/modeling/definitions/public-unique-name.spec.ts +38 -0
- package/tests/unit/modeling/definitions/sku.spec.ts +240 -0
- package/tests/unit/modeling/definitions/status.spec.ts +37 -0
- package/tests/unit/modeling/definitions/summary.spec.ts +36 -0
- package/tests/unit/modeling/definitions/tags.spec.ts +38 -0
- package/tests/unit/modeling/definitions/url.spec.ts +38 -0
- package/tests/unit/modeling/domain_property.spec.ts +106 -0
- package/tests/unit/modeling/domain_validation.spec.ts +5 -5
- package/tests/unit/modeling/semantic-configs.spec.ts +569 -0
- package/tests/unit/modeling/semantics.spec.ts +52 -0
|
@@ -0,0 +1,569 @@
|
|
|
1
|
+
import { test } from '@japa/runner'
|
|
2
|
+
import { SemanticType } from '../../../src/modeling/Semantics.js'
|
|
3
|
+
|
|
4
|
+
// Import semantic configuration modules that exist
|
|
5
|
+
import {
|
|
6
|
+
createGeospatialCoordinatesSemantic,
|
|
7
|
+
isGeospatialCoordinatesSemantic,
|
|
8
|
+
type GeospatialCoordinatesConfig,
|
|
9
|
+
DEFAULT_GEOSPATIAL_CONFIG,
|
|
10
|
+
GeospatialCoordinateFormat,
|
|
11
|
+
GeospatialDistanceUnit,
|
|
12
|
+
GeospatialSpatialReferenceSystem,
|
|
13
|
+
} from '../../../src/modeling/definitions/GeospatialCoordinates.js'
|
|
14
|
+
|
|
15
|
+
import {
|
|
16
|
+
createPasswordSemantic,
|
|
17
|
+
isPasswordSemantic,
|
|
18
|
+
type PasswordConfig,
|
|
19
|
+
DEFAULT_PASSWORD_CONFIG,
|
|
20
|
+
} from '../../../src/modeling/definitions/Password.js'
|
|
21
|
+
|
|
22
|
+
import {
|
|
23
|
+
createStatusSemantic,
|
|
24
|
+
isStatusSemantic,
|
|
25
|
+
type StatusConfig,
|
|
26
|
+
DEFAULT_STATUS_CONFIG,
|
|
27
|
+
} from '../../../src/modeling/definitions/Status.js'
|
|
28
|
+
|
|
29
|
+
import {
|
|
30
|
+
createPublicUniqueNameSemantic,
|
|
31
|
+
isPublicUniqueNameSemantic,
|
|
32
|
+
type PublicUniqueNameConfig,
|
|
33
|
+
DEFAULT_PUBLIC_UNIQUE_NAME_CONFIG,
|
|
34
|
+
} from '../../../src/modeling/definitions/PublicUniqueName.js'
|
|
35
|
+
|
|
36
|
+
import {
|
|
37
|
+
createMarkdownSemantic,
|
|
38
|
+
isMarkdownSemantic,
|
|
39
|
+
type MarkdownConfig,
|
|
40
|
+
DEFAULT_MARKDOWN_CONFIG,
|
|
41
|
+
} from '../../../src/modeling/definitions/Markdown.js'
|
|
42
|
+
|
|
43
|
+
import {
|
|
44
|
+
createHTMLSemantic,
|
|
45
|
+
isHTMLSemantic,
|
|
46
|
+
type HTMLConfig,
|
|
47
|
+
DEFAULT_HTML_CONFIG,
|
|
48
|
+
} from '../../../src/modeling/definitions/HTML.js'
|
|
49
|
+
|
|
50
|
+
import {
|
|
51
|
+
createEmailSemantic,
|
|
52
|
+
isEmailSemantic,
|
|
53
|
+
type EmailConfig,
|
|
54
|
+
DEFAULT_EMAIL_CONFIG,
|
|
55
|
+
} from '../../../src/modeling/definitions/Email.js'
|
|
56
|
+
|
|
57
|
+
import {
|
|
58
|
+
createPhoneSemantic,
|
|
59
|
+
isPhoneSemantic,
|
|
60
|
+
type PhoneConfig,
|
|
61
|
+
DEFAULT_PHONE_CONFIG,
|
|
62
|
+
} from '../../../src/modeling/definitions/Phone.js'
|
|
63
|
+
|
|
64
|
+
import {
|
|
65
|
+
createURLSemantic,
|
|
66
|
+
isURLSemantic,
|
|
67
|
+
type URLConfig,
|
|
68
|
+
DEFAULT_URL_CONFIG,
|
|
69
|
+
} from '../../../src/modeling/definitions/URL.js'
|
|
70
|
+
|
|
71
|
+
import {
|
|
72
|
+
createPriceSemantic,
|
|
73
|
+
isPriceSemantic,
|
|
74
|
+
type PriceConfig,
|
|
75
|
+
DEFAULT_PRICE_CONFIG,
|
|
76
|
+
PRICE_PRESETS,
|
|
77
|
+
} from '../../../src/modeling/definitions/Price.js'
|
|
78
|
+
|
|
79
|
+
import {
|
|
80
|
+
createSKUSemantic,
|
|
81
|
+
isSKUSemantic,
|
|
82
|
+
type SKUConfig,
|
|
83
|
+
DEFAULT_SKU_CONFIG,
|
|
84
|
+
SKU_PRESETS,
|
|
85
|
+
} from '../../../src/modeling/definitions/SKU.js'
|
|
86
|
+
|
|
87
|
+
import {
|
|
88
|
+
createDescriptionSemantic,
|
|
89
|
+
isDescriptionSemantic,
|
|
90
|
+
type DescriptionConfig,
|
|
91
|
+
DEFAULT_DESCRIPTION_CONFIG,
|
|
92
|
+
} from '../../../src/modeling/definitions/Description.js'
|
|
93
|
+
|
|
94
|
+
import {
|
|
95
|
+
createSummarySemantic,
|
|
96
|
+
isSummarySemantic,
|
|
97
|
+
type SummaryConfig,
|
|
98
|
+
DEFAULT_SUMMARY_CONFIG,
|
|
99
|
+
} from '../../../src/modeling/definitions/Summary.js'
|
|
100
|
+
|
|
101
|
+
import {
|
|
102
|
+
createCalculatedSemantic,
|
|
103
|
+
isCalculatedSemantic,
|
|
104
|
+
type CalculatedConfig,
|
|
105
|
+
} from '../../../src/modeling/definitions/Calculated.js'
|
|
106
|
+
|
|
107
|
+
import {
|
|
108
|
+
createDerivedSemantic,
|
|
109
|
+
isDerivedSemantic,
|
|
110
|
+
type DerivedConfig,
|
|
111
|
+
} from '../../../src/modeling/definitions/Derived.js'
|
|
112
|
+
|
|
113
|
+
import {
|
|
114
|
+
createTagsSemantic,
|
|
115
|
+
isTagsSemantic,
|
|
116
|
+
type TagsConfig,
|
|
117
|
+
DEFAULT_TAGS_CONFIG,
|
|
118
|
+
} from '../../../src/modeling/definitions/Tags.js'
|
|
119
|
+
|
|
120
|
+
import {
|
|
121
|
+
createCategoriesSemantic,
|
|
122
|
+
isCategoriesSemantic,
|
|
123
|
+
type CategoriesConfig,
|
|
124
|
+
DEFAULT_CATEGORIES_CONFIG,
|
|
125
|
+
} from '../../../src/modeling/definitions/Categories.js'
|
|
126
|
+
|
|
127
|
+
test.group('Semantic Configurations', () => {
|
|
128
|
+
test('GeospatialCoordinates: should create semantic with default config', ({ assert }) => {
|
|
129
|
+
const semantic = createGeospatialCoordinatesSemantic()
|
|
130
|
+
assert.equal(semantic.id, SemanticType.GeospatialCoordinates)
|
|
131
|
+
assert.deepEqual(semantic.config, DEFAULT_GEOSPATIAL_CONFIG)
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
test('GeospatialCoordinates: should create semantic with custom config', ({ assert }) => {
|
|
135
|
+
const config: GeospatialCoordinatesConfig = {
|
|
136
|
+
format: GeospatialCoordinateFormat.LatLon,
|
|
137
|
+
defaultDistanceUnit: GeospatialDistanceUnit.Kilometers,
|
|
138
|
+
spatialReferenceSystem: GeospatialSpatialReferenceSystem.WGS84,
|
|
139
|
+
}
|
|
140
|
+
const semantic = createGeospatialCoordinatesSemantic(config)
|
|
141
|
+
assert.equal(semantic.id, SemanticType.GeospatialCoordinates)
|
|
142
|
+
assert.deepEqual(semantic.config, { ...DEFAULT_GEOSPATIAL_CONFIG, ...config })
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
test('GeospatialCoordinates: should identify geospatial semantic', ({ assert }) => {
|
|
146
|
+
const semantic = createGeospatialCoordinatesSemantic()
|
|
147
|
+
assert.isTrue(isGeospatialCoordinatesSemantic(semantic))
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
test('Password: should create semantic with default config', ({ assert }) => {
|
|
151
|
+
const semantic = createPasswordSemantic()
|
|
152
|
+
assert.equal(semantic.id, SemanticType.Password)
|
|
153
|
+
assert.deepEqual(semantic.config, DEFAULT_PASSWORD_CONFIG)
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
test('Password: should create semantic with custom config', ({ assert }) => {
|
|
157
|
+
const config: PasswordConfig = {
|
|
158
|
+
minLength: 12,
|
|
159
|
+
requireUppercase: true,
|
|
160
|
+
requireNumbers: true,
|
|
161
|
+
}
|
|
162
|
+
const semantic = createPasswordSemantic(config)
|
|
163
|
+
assert.equal(semantic.id, SemanticType.Password)
|
|
164
|
+
assert.deepEqual(semantic.config, { ...DEFAULT_PASSWORD_CONFIG, ...config })
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
test('Password: should identify password semantic', ({ assert }) => {
|
|
168
|
+
const semantic = createPasswordSemantic()
|
|
169
|
+
assert.isTrue(isPasswordSemantic(semantic))
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
test('Status: should create semantic with default config', ({ assert }) => {
|
|
173
|
+
const semantic = createStatusSemantic()
|
|
174
|
+
assert.equal(semantic.id, SemanticType.Status)
|
|
175
|
+
assert.deepEqual(semantic.config, DEFAULT_STATUS_CONFIG)
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
test('Status: should create semantic with custom config', ({ assert }) => {
|
|
179
|
+
const config: StatusConfig = {
|
|
180
|
+
allowedStates: ['active', 'inactive'],
|
|
181
|
+
defaultState: 'active',
|
|
182
|
+
}
|
|
183
|
+
const semantic = createStatusSemantic(config)
|
|
184
|
+
assert.equal(semantic.id, SemanticType.Status)
|
|
185
|
+
assert.deepEqual(semantic.config, { ...DEFAULT_STATUS_CONFIG, ...config })
|
|
186
|
+
})
|
|
187
|
+
|
|
188
|
+
test('Status: should identify status semantic', ({ assert }) => {
|
|
189
|
+
const semantic = createStatusSemantic()
|
|
190
|
+
assert.isTrue(isStatusSemantic(semantic))
|
|
191
|
+
})
|
|
192
|
+
|
|
193
|
+
test('PublicUniqueName: should create semantic with default config', ({ assert }) => {
|
|
194
|
+
const semantic = createPublicUniqueNameSemantic()
|
|
195
|
+
assert.equal(semantic.id, SemanticType.PublicUniqueName)
|
|
196
|
+
assert.deepEqual(semantic.config, DEFAULT_PUBLIC_UNIQUE_NAME_CONFIG)
|
|
197
|
+
})
|
|
198
|
+
|
|
199
|
+
test('PublicUniqueName: should create semantic with custom config', ({ assert }) => {
|
|
200
|
+
const config: PublicUniqueNameConfig = {
|
|
201
|
+
sourceField: 'title',
|
|
202
|
+
separator: '-',
|
|
203
|
+
maxLength: 50,
|
|
204
|
+
}
|
|
205
|
+
const semantic = createPublicUniqueNameSemantic(config)
|
|
206
|
+
assert.equal(semantic.id, SemanticType.PublicUniqueName)
|
|
207
|
+
assert.deepEqual(semantic.config, { ...DEFAULT_PUBLIC_UNIQUE_NAME_CONFIG, ...config })
|
|
208
|
+
})
|
|
209
|
+
|
|
210
|
+
test('PublicUniqueName: should identify public unique name semantic', ({ assert }) => {
|
|
211
|
+
const semantic = createPublicUniqueNameSemantic()
|
|
212
|
+
assert.isTrue(isPublicUniqueNameSemantic(semantic))
|
|
213
|
+
})
|
|
214
|
+
|
|
215
|
+
test('Markdown: should create semantic with default config', ({ assert }) => {
|
|
216
|
+
const semantic = createMarkdownSemantic()
|
|
217
|
+
assert.equal(semantic.id, SemanticType.Markdown)
|
|
218
|
+
assert.deepEqual(semantic.config, DEFAULT_MARKDOWN_CONFIG)
|
|
219
|
+
})
|
|
220
|
+
|
|
221
|
+
test('Markdown: should create semantic with custom config', ({ assert }) => {
|
|
222
|
+
const config: MarkdownConfig = {
|
|
223
|
+
renderToHTML: true,
|
|
224
|
+
allowedTags: ['p', 'h1', 'h2'],
|
|
225
|
+
sanitize: true,
|
|
226
|
+
}
|
|
227
|
+
const semantic = createMarkdownSemantic(config)
|
|
228
|
+
assert.equal(semantic.id, SemanticType.Markdown)
|
|
229
|
+
assert.deepEqual(semantic.config, { ...DEFAULT_MARKDOWN_CONFIG, ...config })
|
|
230
|
+
})
|
|
231
|
+
|
|
232
|
+
test('Markdown: should identify markdown semantic', ({ assert }) => {
|
|
233
|
+
const semantic = createMarkdownSemantic()
|
|
234
|
+
assert.isTrue(isMarkdownSemantic(semantic))
|
|
235
|
+
})
|
|
236
|
+
|
|
237
|
+
test('HTML: should create semantic with default config', ({ assert }) => {
|
|
238
|
+
const semantic = createHTMLSemantic()
|
|
239
|
+
assert.equal(semantic.id, SemanticType.HTML)
|
|
240
|
+
assert.deepEqual(semantic.config, DEFAULT_HTML_CONFIG)
|
|
241
|
+
})
|
|
242
|
+
|
|
243
|
+
test('HTML: should create semantic with custom config', ({ assert }) => {
|
|
244
|
+
const config: HTMLConfig = {
|
|
245
|
+
renderAsHTML: true,
|
|
246
|
+
allowedTags: ['p', 'div', 'span'],
|
|
247
|
+
sanitize: true,
|
|
248
|
+
}
|
|
249
|
+
const semantic = createHTMLSemantic(config)
|
|
250
|
+
assert.equal(semantic.id, SemanticType.HTML)
|
|
251
|
+
assert.deepEqual(semantic.config, { ...DEFAULT_HTML_CONFIG, ...config })
|
|
252
|
+
})
|
|
253
|
+
|
|
254
|
+
test('HTML: should identify HTML semantic', ({ assert }) => {
|
|
255
|
+
const semantic = createHTMLSemantic()
|
|
256
|
+
assert.isTrue(isHTMLSemantic(semantic))
|
|
257
|
+
})
|
|
258
|
+
|
|
259
|
+
test('Email: should create semantic with default config', ({ assert }) => {
|
|
260
|
+
const semantic = createEmailSemantic()
|
|
261
|
+
assert.equal(semantic.id, SemanticType.Email)
|
|
262
|
+
assert.deepEqual(semantic.config, DEFAULT_EMAIL_CONFIG)
|
|
263
|
+
})
|
|
264
|
+
|
|
265
|
+
test('Email: should create semantic with custom config', ({ assert }) => {
|
|
266
|
+
const config: EmailConfig = {
|
|
267
|
+
allowedDomains: ['example.com'],
|
|
268
|
+
requireVerification: true,
|
|
269
|
+
verificationMethod: 'email',
|
|
270
|
+
}
|
|
271
|
+
const semantic = createEmailSemantic(config)
|
|
272
|
+
assert.equal(semantic.id, SemanticType.Email)
|
|
273
|
+
assert.deepEqual(semantic.config, { ...DEFAULT_EMAIL_CONFIG, ...config })
|
|
274
|
+
})
|
|
275
|
+
|
|
276
|
+
test('Email: should identify email semantic', ({ assert }) => {
|
|
277
|
+
const semantic = createEmailSemantic()
|
|
278
|
+
assert.isTrue(isEmailSemantic(semantic))
|
|
279
|
+
})
|
|
280
|
+
|
|
281
|
+
test('Phone: should create semantic with default config', ({ assert }) => {
|
|
282
|
+
const semantic = createPhoneSemantic()
|
|
283
|
+
assert.equal(semantic.id, SemanticType.Phone)
|
|
284
|
+
assert.deepEqual(semantic.config, DEFAULT_PHONE_CONFIG)
|
|
285
|
+
})
|
|
286
|
+
|
|
287
|
+
test('Phone: should create semantic with custom config', ({ assert }) => {
|
|
288
|
+
const config: PhoneConfig = {
|
|
289
|
+
allowedCountries: ['US', 'CA'],
|
|
290
|
+
format: 'E.164',
|
|
291
|
+
requireVerification: true,
|
|
292
|
+
}
|
|
293
|
+
const semantic = createPhoneSemantic(config)
|
|
294
|
+
assert.equal(semantic.id, SemanticType.Phone)
|
|
295
|
+
assert.deepEqual(semantic.config, { ...DEFAULT_PHONE_CONFIG, ...config })
|
|
296
|
+
})
|
|
297
|
+
|
|
298
|
+
test('Phone: should identify phone semantic', ({ assert }) => {
|
|
299
|
+
const semantic = createPhoneSemantic()
|
|
300
|
+
assert.isTrue(isPhoneSemantic(semantic))
|
|
301
|
+
})
|
|
302
|
+
|
|
303
|
+
test('URL: should create semantic with default config', ({ assert }) => {
|
|
304
|
+
const semantic = createURLSemantic()
|
|
305
|
+
assert.equal(semantic.id, SemanticType.URL)
|
|
306
|
+
assert.deepEqual(semantic.config, DEFAULT_URL_CONFIG)
|
|
307
|
+
})
|
|
308
|
+
|
|
309
|
+
test('URL: should create semantic with custom config', ({ assert }) => {
|
|
310
|
+
const config: URLConfig = {
|
|
311
|
+
allowedProtocols: ['https'],
|
|
312
|
+
allowedDomains: ['example.com'],
|
|
313
|
+
requireHTTPS: true,
|
|
314
|
+
}
|
|
315
|
+
const semantic = createURLSemantic(config)
|
|
316
|
+
assert.equal(semantic.id, SemanticType.URL)
|
|
317
|
+
assert.deepEqual(semantic.config, { ...DEFAULT_URL_CONFIG, ...config })
|
|
318
|
+
})
|
|
319
|
+
|
|
320
|
+
test('URL: should identify URL semantic', ({ assert }) => {
|
|
321
|
+
const semantic = createURLSemantic()
|
|
322
|
+
assert.isTrue(isURLSemantic(semantic))
|
|
323
|
+
})
|
|
324
|
+
|
|
325
|
+
test('Price: should create semantic with default config', ({ assert }) => {
|
|
326
|
+
const semantic = createPriceSemantic()
|
|
327
|
+
assert.equal(semantic.id, SemanticType.Price)
|
|
328
|
+
assert.deepEqual(semantic.config, DEFAULT_PRICE_CONFIG)
|
|
329
|
+
})
|
|
330
|
+
|
|
331
|
+
test('Price: should create semantic with custom config', ({ assert }) => {
|
|
332
|
+
const config: PriceConfig = {
|
|
333
|
+
storageFormat: 'complex_object',
|
|
334
|
+
allowedCurrencies: ['USD', 'EUR'],
|
|
335
|
+
decimalPlaces: 4,
|
|
336
|
+
allowNegative: true,
|
|
337
|
+
}
|
|
338
|
+
const semantic = createPriceSemantic(config)
|
|
339
|
+
assert.equal(semantic.id, SemanticType.Price)
|
|
340
|
+
assert.deepEqual(semantic.config, { ...DEFAULT_PRICE_CONFIG, ...config })
|
|
341
|
+
})
|
|
342
|
+
|
|
343
|
+
test('Price: should identify price semantic', ({ assert }) => {
|
|
344
|
+
const semantic = createPriceSemantic()
|
|
345
|
+
assert.isTrue(isPriceSemantic(semantic))
|
|
346
|
+
})
|
|
347
|
+
|
|
348
|
+
test('SKU: should create semantic with default config', ({ assert }) => {
|
|
349
|
+
const semantic = createSKUSemantic()
|
|
350
|
+
assert.equal(semantic.id, SemanticType.SKU)
|
|
351
|
+
assert.deepEqual(semantic.config, DEFAULT_SKU_CONFIG)
|
|
352
|
+
})
|
|
353
|
+
|
|
354
|
+
test('SKU: should create semantic with custom config', ({ assert }) => {
|
|
355
|
+
const config: SKUConfig = {
|
|
356
|
+
validationMode: 'lenient',
|
|
357
|
+
caseMode: 'lowercase',
|
|
358
|
+
prefix: 'SKU-',
|
|
359
|
+
enforceUniqueness: false,
|
|
360
|
+
}
|
|
361
|
+
const semantic = createSKUSemantic(config)
|
|
362
|
+
assert.equal(semantic.id, SemanticType.SKU)
|
|
363
|
+
assert.deepEqual(semantic.config, { ...DEFAULT_SKU_CONFIG, ...config })
|
|
364
|
+
})
|
|
365
|
+
|
|
366
|
+
test('SKU: should identify SKU semantic', ({ assert }) => {
|
|
367
|
+
const semantic = createSKUSemantic()
|
|
368
|
+
assert.isTrue(isSKUSemantic(semantic))
|
|
369
|
+
})
|
|
370
|
+
|
|
371
|
+
test('Description: should create semantic with default config', ({ assert }) => {
|
|
372
|
+
const semantic = createDescriptionSemantic()
|
|
373
|
+
assert.equal(semantic.id, SemanticType.Description)
|
|
374
|
+
assert.deepEqual(semantic.config, DEFAULT_DESCRIPTION_CONFIG)
|
|
375
|
+
})
|
|
376
|
+
|
|
377
|
+
test('Description: should create semantic with custom config', ({ assert }) => {
|
|
378
|
+
const config: DescriptionConfig = {
|
|
379
|
+
minLength: 10,
|
|
380
|
+
maxLength: 1000,
|
|
381
|
+
allowMarkdown: true,
|
|
382
|
+
}
|
|
383
|
+
const semantic = createDescriptionSemantic(config)
|
|
384
|
+
assert.equal(semantic.id, SemanticType.Description)
|
|
385
|
+
assert.deepEqual(semantic.config, { ...DEFAULT_DESCRIPTION_CONFIG, ...config })
|
|
386
|
+
})
|
|
387
|
+
|
|
388
|
+
test('Description: should identify description semantic', ({ assert }) => {
|
|
389
|
+
const semantic = createDescriptionSemantic()
|
|
390
|
+
assert.isTrue(isDescriptionSemantic(semantic))
|
|
391
|
+
})
|
|
392
|
+
|
|
393
|
+
test('Summary: should create semantic with default config', ({ assert }) => {
|
|
394
|
+
const semantic = createSummarySemantic()
|
|
395
|
+
assert.equal(semantic.id, SemanticType.Summary)
|
|
396
|
+
assert.deepEqual(semantic.config, DEFAULT_SUMMARY_CONFIG)
|
|
397
|
+
})
|
|
398
|
+
|
|
399
|
+
test('Summary: should create semantic with custom config', ({ assert }) => {
|
|
400
|
+
const config: SummaryConfig = {
|
|
401
|
+
metadata: { customField: 'value' },
|
|
402
|
+
}
|
|
403
|
+
const semantic = createSummarySemantic(config)
|
|
404
|
+
assert.equal(semantic.id, SemanticType.Summary)
|
|
405
|
+
assert.deepEqual(semantic.config, { ...DEFAULT_SUMMARY_CONFIG, ...config })
|
|
406
|
+
})
|
|
407
|
+
|
|
408
|
+
test('Summary: should identify summary semantic', ({ assert }) => {
|
|
409
|
+
const semantic = createSummarySemantic()
|
|
410
|
+
assert.isTrue(isSummarySemantic(semantic))
|
|
411
|
+
})
|
|
412
|
+
|
|
413
|
+
test('Calculated: should create semantic with custom config', ({ assert }) => {
|
|
414
|
+
const config: CalculatedConfig = {
|
|
415
|
+
formula: 'price * quantity',
|
|
416
|
+
dependencies: ['price', 'quantity'],
|
|
417
|
+
recalculateOnUpdate: true,
|
|
418
|
+
allowManualOverride: true,
|
|
419
|
+
}
|
|
420
|
+
const semantic = createCalculatedSemantic(config)
|
|
421
|
+
assert.equal(semantic.id, SemanticType.Calculated)
|
|
422
|
+
assert.deepEqual(semantic.config, config)
|
|
423
|
+
})
|
|
424
|
+
|
|
425
|
+
test('Calculated: should identify calculated semantic', ({ assert }) => {
|
|
426
|
+
const config: CalculatedConfig = { formula: 'price * quantity' }
|
|
427
|
+
const semantic = createCalculatedSemantic(config)
|
|
428
|
+
assert.isTrue(isCalculatedSemantic(semantic))
|
|
429
|
+
})
|
|
430
|
+
|
|
431
|
+
test('Derived: should create semantic with custom config', ({ assert }) => {
|
|
432
|
+
const config: DerivedConfig = {
|
|
433
|
+
sourceFields: ['firstName', 'lastName'],
|
|
434
|
+
derivationRule: 'concat',
|
|
435
|
+
updateOnChange: true,
|
|
436
|
+
allowManualOverride: true,
|
|
437
|
+
recalculateOnUpdate: false,
|
|
438
|
+
}
|
|
439
|
+
const semantic = createDerivedSemantic(config)
|
|
440
|
+
assert.equal(semantic.id, SemanticType.Derived)
|
|
441
|
+
assert.deepEqual(semantic.config, config)
|
|
442
|
+
})
|
|
443
|
+
|
|
444
|
+
test('Derived: should identify derived semantic', ({ assert }) => {
|
|
445
|
+
const config: DerivedConfig = { sourceFields: ['firstName', 'lastName'] }
|
|
446
|
+
const semantic = createDerivedSemantic(config)
|
|
447
|
+
assert.isTrue(isDerivedSemantic(semantic))
|
|
448
|
+
})
|
|
449
|
+
|
|
450
|
+
test('Tags: should create semantic with default config', ({ assert }) => {
|
|
451
|
+
const semantic = createTagsSemantic()
|
|
452
|
+
assert.equal(semantic.id, SemanticType.Tags)
|
|
453
|
+
assert.deepEqual(semantic.config, DEFAULT_TAGS_CONFIG)
|
|
454
|
+
})
|
|
455
|
+
|
|
456
|
+
test('Tags: should create semantic with custom config', ({ assert }) => {
|
|
457
|
+
const config: TagsConfig = {
|
|
458
|
+
maxTags: 10,
|
|
459
|
+
allowCustomTags: true,
|
|
460
|
+
predefinedTags: ['urgent', 'important'],
|
|
461
|
+
}
|
|
462
|
+
const semantic = createTagsSemantic(config)
|
|
463
|
+
assert.equal(semantic.id, SemanticType.Tags)
|
|
464
|
+
assert.deepEqual(semantic.config, { ...DEFAULT_TAGS_CONFIG, ...config })
|
|
465
|
+
})
|
|
466
|
+
|
|
467
|
+
test('Tags: should identify tags semantic', ({ assert }) => {
|
|
468
|
+
const semantic = createTagsSemantic()
|
|
469
|
+
assert.isTrue(isTagsSemantic(semantic))
|
|
470
|
+
})
|
|
471
|
+
|
|
472
|
+
test('Categories: should create semantic with default config', ({ assert }) => {
|
|
473
|
+
const semantic = createCategoriesSemantic()
|
|
474
|
+
assert.equal(semantic.id, SemanticType.Categories)
|
|
475
|
+
assert.deepEqual(semantic.config, DEFAULT_CATEGORIES_CONFIG)
|
|
476
|
+
})
|
|
477
|
+
|
|
478
|
+
test('Categories: should create semantic with custom config', ({ assert }) => {
|
|
479
|
+
const config: CategoriesConfig = {
|
|
480
|
+
maxCategories: 5,
|
|
481
|
+
allowMultiple: true,
|
|
482
|
+
predefinedCategories: ['feature', 'bug', 'enhancement'],
|
|
483
|
+
}
|
|
484
|
+
const semantic = createCategoriesSemantic(config)
|
|
485
|
+
assert.equal(semantic.id, SemanticType.Categories)
|
|
486
|
+
assert.deepEqual(semantic.config, { ...DEFAULT_CATEGORIES_CONFIG, ...config })
|
|
487
|
+
})
|
|
488
|
+
|
|
489
|
+
test('Categories: should identify categories semantic', ({ assert }) => {
|
|
490
|
+
const semantic = createCategoriesSemantic()
|
|
491
|
+
assert.isTrue(isCategoriesSemantic(semantic))
|
|
492
|
+
})
|
|
493
|
+
|
|
494
|
+
test('Price: should create semantic with default config', ({ assert }) => {
|
|
495
|
+
const semantic = createPriceSemantic()
|
|
496
|
+
assert.equal(semantic.id, SemanticType.Price)
|
|
497
|
+
assert.deepEqual(semantic.config, DEFAULT_PRICE_CONFIG)
|
|
498
|
+
})
|
|
499
|
+
|
|
500
|
+
test('Price: should create semantic with custom config', ({ assert }) => {
|
|
501
|
+
const config: PriceConfig = {
|
|
502
|
+
storageFormat: 'complex_object',
|
|
503
|
+
allowedCurrencies: ['USD', 'EUR'],
|
|
504
|
+
decimalPlaces: 4,
|
|
505
|
+
allowNegative: true,
|
|
506
|
+
}
|
|
507
|
+
const semantic = createPriceSemantic(config)
|
|
508
|
+
assert.equal(semantic.id, SemanticType.Price)
|
|
509
|
+
assert.deepEqual(semantic.config, { ...DEFAULT_PRICE_CONFIG, ...config })
|
|
510
|
+
})
|
|
511
|
+
|
|
512
|
+
test('Price: should identify price semantic', ({ assert }) => {
|
|
513
|
+
const semantic = createPriceSemantic()
|
|
514
|
+
assert.isTrue(isPriceSemantic(semantic))
|
|
515
|
+
})
|
|
516
|
+
|
|
517
|
+
test('Price: presets should be valid', ({ assert }) => {
|
|
518
|
+
Object.values(PRICE_PRESETS).forEach((preset) => {
|
|
519
|
+
assert.isTrue(isPriceSemantic(preset))
|
|
520
|
+
assert.equal(preset.id, SemanticType.Price)
|
|
521
|
+
})
|
|
522
|
+
})
|
|
523
|
+
|
|
524
|
+
test('SKU: presets should be valid', ({ assert }) => {
|
|
525
|
+
Object.values(SKU_PRESETS).forEach((preset) => {
|
|
526
|
+
assert.isTrue(isSKUSemantic(preset))
|
|
527
|
+
assert.equal(preset.id, SemanticType.SKU)
|
|
528
|
+
})
|
|
529
|
+
})
|
|
530
|
+
|
|
531
|
+
test('Cross-semantic type guards: should correctly identify different semantic types', ({ assert }) => {
|
|
532
|
+
const emailSemantic = createEmailSemantic()
|
|
533
|
+
const phoneSemantic = createPhoneSemantic()
|
|
534
|
+
const statusSemantic = createStatusSemantic()
|
|
535
|
+
const priceSemantic = createPriceSemantic()
|
|
536
|
+
const skuSemantic = createSKUSemantic()
|
|
537
|
+
|
|
538
|
+
// Each should only be identified as its own type
|
|
539
|
+
assert.isTrue(isEmailSemantic(emailSemantic))
|
|
540
|
+
assert.isFalse(isEmailSemantic(phoneSemantic))
|
|
541
|
+
assert.isFalse(isEmailSemantic(statusSemantic))
|
|
542
|
+
assert.isFalse(isEmailSemantic(priceSemantic))
|
|
543
|
+
assert.isFalse(isEmailSemantic(skuSemantic))
|
|
544
|
+
|
|
545
|
+
assert.isFalse(isPhoneSemantic(emailSemantic))
|
|
546
|
+
assert.isTrue(isPhoneSemantic(phoneSemantic))
|
|
547
|
+
assert.isFalse(isPhoneSemantic(statusSemantic))
|
|
548
|
+
assert.isFalse(isPhoneSemantic(priceSemantic))
|
|
549
|
+
assert.isFalse(isPhoneSemantic(skuSemantic))
|
|
550
|
+
|
|
551
|
+
assert.isFalse(isStatusSemantic(emailSemantic))
|
|
552
|
+
assert.isFalse(isStatusSemantic(phoneSemantic))
|
|
553
|
+
assert.isTrue(isStatusSemantic(statusSemantic))
|
|
554
|
+
assert.isFalse(isStatusSemantic(priceSemantic))
|
|
555
|
+
assert.isFalse(isStatusSemantic(skuSemantic))
|
|
556
|
+
|
|
557
|
+
assert.isFalse(isPriceSemantic(emailSemantic))
|
|
558
|
+
assert.isFalse(isPriceSemantic(phoneSemantic))
|
|
559
|
+
assert.isFalse(isPriceSemantic(statusSemantic))
|
|
560
|
+
assert.isTrue(isPriceSemantic(priceSemantic))
|
|
561
|
+
assert.isFalse(isPriceSemantic(skuSemantic))
|
|
562
|
+
|
|
563
|
+
assert.isFalse(isSKUSemantic(emailSemantic))
|
|
564
|
+
assert.isFalse(isSKUSemantic(phoneSemantic))
|
|
565
|
+
assert.isFalse(isSKUSemantic(statusSemantic))
|
|
566
|
+
assert.isFalse(isSKUSemantic(priceSemantic))
|
|
567
|
+
assert.isTrue(isSKUSemantic(skuSemantic))
|
|
568
|
+
})
|
|
569
|
+
})
|
|
@@ -20,8 +20,17 @@ test.group('Semantics', () => {
|
|
|
20
20
|
assert.equal(SemanticType.DeletedTimestamp, 'Semantic#DeletedTimestamp')
|
|
21
21
|
assert.equal(SemanticType.DeletedFlag, 'Semantic#DeletedFlag')
|
|
22
22
|
assert.equal(SemanticType.PublicUniqueName, 'Semantic#PublicUniqueName')
|
|
23
|
+
assert.equal(SemanticType.Title, 'Semantic#Title')
|
|
23
24
|
assert.equal(SemanticType.UserRole, 'Semantic#UserRole')
|
|
25
|
+
assert.equal(SemanticType.Status, 'Semantic#Status')
|
|
26
|
+
assert.equal(SemanticType.Version, 'Semantic#Version')
|
|
27
|
+
assert.equal(SemanticType.ImageURL, 'Semantic#ImageURL')
|
|
28
|
+
assert.equal(SemanticType.FileURL, 'Semantic#FileURL')
|
|
29
|
+
assert.equal(SemanticType.Markdown, 'Semantic#Markdown')
|
|
30
|
+
assert.equal(SemanticType.GeospatialCoordinates, 'Semantic#GeospatialCoordinates')
|
|
31
|
+
assert.equal(SemanticType.Price, 'Semantic#Price')
|
|
24
32
|
assert.equal(SemanticType.ResourceOwnerIdentifier, 'Semantic#ResourceOwnerIdentifier')
|
|
33
|
+
assert.equal(SemanticType.SKU, 'Semantic#SKU')
|
|
25
34
|
})
|
|
26
35
|
|
|
27
36
|
test('SemanticScope enum should have correct values', ({ assert }) => {
|
|
@@ -143,4 +152,47 @@ test.group('Semantics', () => {
|
|
|
143
152
|
const resourceOwnerSemantic = DataSemantics[SemanticType.ResourceOwnerIdentifier]
|
|
144
153
|
assert.equal(resourceOwnerSemantic.scope, SemanticScope.Association)
|
|
145
154
|
})
|
|
155
|
+
|
|
156
|
+
test('GeospatialCoordinates semantic should have correct definition', ({ assert }) => {
|
|
157
|
+
const geospatialSemantic = DataSemantics[SemanticType.GeospatialCoordinates]
|
|
158
|
+
|
|
159
|
+
// Check basic properties
|
|
160
|
+
assert.equal(geospatialSemantic.id, SemanticType.GeospatialCoordinates)
|
|
161
|
+
assert.equal(geospatialSemantic.displayName, 'Geospatial Coordinates')
|
|
162
|
+
assert.equal(geospatialSemantic.scope, SemanticScope.Property)
|
|
163
|
+
assert.isString(geospatialSemantic.description)
|
|
164
|
+
assert.isNotEmpty(geospatialSemantic.description)
|
|
165
|
+
|
|
166
|
+
// Check that it's a PropertySemantic
|
|
167
|
+
assert.isTrue(isPropertySemantic(geospatialSemantic))
|
|
168
|
+
|
|
169
|
+
// Check applicable data types
|
|
170
|
+
if (isPropertySemantic(geospatialSemantic)) {
|
|
171
|
+
assert.isDefined(geospatialSemantic.applicableDataTypes)
|
|
172
|
+
assert.isArray(geospatialSemantic.applicableDataTypes)
|
|
173
|
+
assert.deepEqual(geospatialSemantic.applicableDataTypes, ['string'])
|
|
174
|
+
}
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
test('GeospatialCoordinates should work with type guards', ({ assert }) => {
|
|
178
|
+
const geospatialSemantic = DataSemantics[SemanticType.GeospatialCoordinates]
|
|
179
|
+
|
|
180
|
+
// Should be identified as a PropertySemantic
|
|
181
|
+
assert.isTrue(isPropertySemantic(geospatialSemantic))
|
|
182
|
+
assert.isFalse(isEntitySemantic(geospatialSemantic))
|
|
183
|
+
assert.isFalse(isAssociationSemantic(geospatialSemantic))
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
test('GeospatialCoordinates should be included in all semantic types', ({ assert }) => {
|
|
187
|
+
const semanticTypes = Object.values(SemanticType)
|
|
188
|
+
assert.include(semanticTypes, SemanticType.GeospatialCoordinates)
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
test('GeospatialCoordinates should have comprehensive description', ({ assert }) => {
|
|
192
|
+
const geospatialSemantic = DataSemantics[SemanticType.GeospatialCoordinates]
|
|
193
|
+
const description = geospatialSemantic.description
|
|
194
|
+
|
|
195
|
+
// Check that the description mentions key features
|
|
196
|
+
assert.equal(description, 'Annotates a field that holds geospatial coordinate data (latitude/longitude).')
|
|
197
|
+
})
|
|
146
198
|
})
|