@curly-message/conformance 1.0.0-next.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/LICENSE +21 -0
- package/README.md +266 -0
- package/bin/conformance.js +37 -0
- package/bin/manifest.js +24 -0
- package/dist/index.d.ts +225 -0
- package/dist/index.js +4 -0
- package/fixtures/comparisons.json +916 -0
- package/fixtures/conversion.json +231 -0
- package/fixtures/escaping-extensions.json +84 -0
- package/fixtures/escaping.json +546 -0
- package/fixtures/extensions.json +826 -0
- package/fixtures/fallback-intl.json +51 -0
- package/fixtures/fallback.json +774 -0
- package/fixtures/grammar.json +875 -0
- package/fixtures/intl.json +3057 -0
- package/fixtures/limits.json +63 -0
- package/fixtures/nesting.json +251 -0
- package/fixtures/reports.json +512 -0
- package/fixtures/resolution.json +742 -0
- package/fixtures/security-extensions.json +52 -0
- package/fixtures/security.json +246 -0
- package/fixtures/whitespace.json +1000 -0
- package/index.json +102 -0
- package/package.json +76 -0
- package/schema/fixture.schema.json +264 -0
package/index.json
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "curly-message-1",
|
|
3
|
+
"version": "1.0.0-next.0",
|
|
4
|
+
"files": [
|
|
5
|
+
{
|
|
6
|
+
"path": "fixtures/comparisons.json",
|
|
7
|
+
"level": "core",
|
|
8
|
+
"section": "11.1",
|
|
9
|
+
"cases": 76
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"path": "fixtures/conversion.json",
|
|
13
|
+
"level": "core",
|
|
14
|
+
"section": "4",
|
|
15
|
+
"cases": 15
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"path": "fixtures/escaping-extensions.json",
|
|
19
|
+
"level": "extensions",
|
|
20
|
+
"section": "7",
|
|
21
|
+
"cases": 5
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"path": "fixtures/escaping.json",
|
|
25
|
+
"level": "core",
|
|
26
|
+
"section": "7",
|
|
27
|
+
"cases": 46
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"path": "fixtures/extensions.json",
|
|
31
|
+
"level": "extensions",
|
|
32
|
+
"section": "11.3",
|
|
33
|
+
"cases": 43
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"path": "fixtures/fallback-intl.json",
|
|
37
|
+
"level": "intl",
|
|
38
|
+
"section": "10",
|
|
39
|
+
"cases": 2
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"path": "fixtures/fallback.json",
|
|
43
|
+
"level": "core",
|
|
44
|
+
"section": "10",
|
|
45
|
+
"cases": 47
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"path": "fixtures/grammar.json",
|
|
49
|
+
"level": "core",
|
|
50
|
+
"section": "6",
|
|
51
|
+
"cases": 70
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"path": "fixtures/intl.json",
|
|
55
|
+
"level": "intl",
|
|
56
|
+
"section": "11.2",
|
|
57
|
+
"cases": 126
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"path": "fixtures/limits.json",
|
|
61
|
+
"level": "core",
|
|
62
|
+
"section": "13",
|
|
63
|
+
"cases": 7
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"path": "fixtures/nesting.json",
|
|
67
|
+
"level": "core",
|
|
68
|
+
"section": "12",
|
|
69
|
+
"cases": 18
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"path": "fixtures/reports.json",
|
|
73
|
+
"level": "core",
|
|
74
|
+
"section": "14",
|
|
75
|
+
"cases": 24
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"path": "fixtures/resolution.json",
|
|
79
|
+
"level": "core",
|
|
80
|
+
"section": "9",
|
|
81
|
+
"cases": 57
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"path": "fixtures/security-extensions.json",
|
|
85
|
+
"level": "extensions",
|
|
86
|
+
"section": "14.1",
|
|
87
|
+
"cases": 3
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"path": "fixtures/security.json",
|
|
91
|
+
"level": "core",
|
|
92
|
+
"section": "14.1",
|
|
93
|
+
"cases": 18
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"path": "fixtures/whitespace.json",
|
|
97
|
+
"level": "core",
|
|
98
|
+
"section": "8",
|
|
99
|
+
"cases": 88
|
|
100
|
+
}
|
|
101
|
+
]
|
|
102
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@curly-message/conformance",
|
|
3
|
+
"version": "1.0.0-next.0",
|
|
4
|
+
"description": "Conformance fixtures and runner for the Curly Message Format.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"default": "./dist/index.js"
|
|
11
|
+
},
|
|
12
|
+
"./index.json": "./index.json",
|
|
13
|
+
"./fixtures/*.json": "./fixtures/*.json",
|
|
14
|
+
"./schema/fixture.schema.json": "./schema/fixture.schema.json",
|
|
15
|
+
"./package.json": "./package.json"
|
|
16
|
+
},
|
|
17
|
+
"bin": {
|
|
18
|
+
"curly-message-conformance": "./bin/conformance.js"
|
|
19
|
+
},
|
|
20
|
+
"engines": {
|
|
21
|
+
"node": ">=22"
|
|
22
|
+
},
|
|
23
|
+
"scripts": {
|
|
24
|
+
"dev": "tsup --watch",
|
|
25
|
+
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
26
|
+
"pretest": "npm run build && npm run typecheck && npm run lint",
|
|
27
|
+
"test": "vitest run",
|
|
28
|
+
"build": "tsup",
|
|
29
|
+
"prepack": "npm run build",
|
|
30
|
+
"lint": "eslint . --max-warnings=0",
|
|
31
|
+
"lint:fix": "eslint --fix .",
|
|
32
|
+
"manifest": "node ./bin/manifest.js",
|
|
33
|
+
"prepare": "cd .. && simple-git-hooks conformance/.simple-git-hooks.json"
|
|
34
|
+
},
|
|
35
|
+
"files": [
|
|
36
|
+
"bin",
|
|
37
|
+
"dist",
|
|
38
|
+
"fixtures",
|
|
39
|
+
"index.json",
|
|
40
|
+
"schema"
|
|
41
|
+
],
|
|
42
|
+
"repository": {
|
|
43
|
+
"type": "git",
|
|
44
|
+
"url": "git+ssh://git@github.com/curly-message/spec.git",
|
|
45
|
+
"directory": "conformance"
|
|
46
|
+
},
|
|
47
|
+
"keywords": [
|
|
48
|
+
"curly-message",
|
|
49
|
+
"conformance",
|
|
50
|
+
"fixtures",
|
|
51
|
+
"i18n",
|
|
52
|
+
"internationalization",
|
|
53
|
+
"translations",
|
|
54
|
+
"interpolation"
|
|
55
|
+
],
|
|
56
|
+
"author": "Jarda Svoboda",
|
|
57
|
+
"license": "MIT",
|
|
58
|
+
"bugs": {
|
|
59
|
+
"url": "https://github.com/curly-message/spec/issues"
|
|
60
|
+
},
|
|
61
|
+
"homepage": "https://github.com/curly-message/spec/tree/main/conformance#readme",
|
|
62
|
+
"devDependencies": {
|
|
63
|
+
"@eslint/js": "^10.0.1",
|
|
64
|
+
"@stylistic/eslint-plugin": "^5.10.0",
|
|
65
|
+
"@types/node": "^22.20.1",
|
|
66
|
+
"ajv": "^8.20.0",
|
|
67
|
+
"eslint": "^10.8.1",
|
|
68
|
+
"eslint-plugin-import-x": "^4.17.1",
|
|
69
|
+
"globals": "^17.11.0",
|
|
70
|
+
"simple-git-hooks": "^2.13.1",
|
|
71
|
+
"tsup": "^8.0.1",
|
|
72
|
+
"typescript": "^5.1.6",
|
|
73
|
+
"typescript-eslint": "^8.67.0",
|
|
74
|
+
"vitest": "^4.1.10"
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "urn:curly-message:conformance:fixture",
|
|
4
|
+
"title": "Curly Message Format conformance fixture file",
|
|
5
|
+
"description": "One file of the conformance set: cases pinning one section of the specification at one conformance level. README.md in this package states what each field means.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": [
|
|
8
|
+
"format",
|
|
9
|
+
"level",
|
|
10
|
+
"section",
|
|
11
|
+
"cases"
|
|
12
|
+
],
|
|
13
|
+
"additionalProperties": false,
|
|
14
|
+
"properties": {
|
|
15
|
+
"format": {
|
|
16
|
+
"description": "The versioned identifier of the format the file targets.",
|
|
17
|
+
"const": "curly-message-1"
|
|
18
|
+
},
|
|
19
|
+
"level": {
|
|
20
|
+
"description": "The conformance level (section 2) that requires every case in the file.",
|
|
21
|
+
"$ref": "#/$defs/level"
|
|
22
|
+
},
|
|
23
|
+
"section": {
|
|
24
|
+
"description": "The section of SPEC.md the file pins; a case may name a more specific one.",
|
|
25
|
+
"$ref": "#/$defs/section"
|
|
26
|
+
},
|
|
27
|
+
"cases": {
|
|
28
|
+
"type": "array",
|
|
29
|
+
"minItems": 1,
|
|
30
|
+
"items": {
|
|
31
|
+
"$ref": "#/$defs/case"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"$defs": {
|
|
36
|
+
"level": {
|
|
37
|
+
"enum": [
|
|
38
|
+
"core",
|
|
39
|
+
"intl",
|
|
40
|
+
"extensions"
|
|
41
|
+
]
|
|
42
|
+
},
|
|
43
|
+
"section": {
|
|
44
|
+
"description": "A heading number of SPEC.md: a section (\"7\"), a subsection (\"9.2\") or an appendix entry (\"A.4\").",
|
|
45
|
+
"type": "string",
|
|
46
|
+
"pattern": "^([0-9]+(\\.[0-9]+)?|A\\.[0-9]+)$"
|
|
47
|
+
},
|
|
48
|
+
"identifier": {
|
|
49
|
+
"description": "Unique across the whole set: the file's group, a slash, and a slug.",
|
|
50
|
+
"type": "string",
|
|
51
|
+
"pattern": "^[a-z0-9]+(-[a-z0-9]+)*/[a-z0-9]+(-[a-z0-9]+)*$"
|
|
52
|
+
},
|
|
53
|
+
"case": {
|
|
54
|
+
"oneOf": [
|
|
55
|
+
{
|
|
56
|
+
"$ref": "#/$defs/concrete"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"$ref": "#/$defs/generated"
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
},
|
|
63
|
+
"concrete": {
|
|
64
|
+
"description": "A resolution written out: its inputs and what they must produce.",
|
|
65
|
+
"type": "object",
|
|
66
|
+
"required": [
|
|
67
|
+
"id",
|
|
68
|
+
"description",
|
|
69
|
+
"message",
|
|
70
|
+
"expected"
|
|
71
|
+
],
|
|
72
|
+
"additionalProperties": false,
|
|
73
|
+
"properties": {
|
|
74
|
+
"id": {
|
|
75
|
+
"$ref": "#/$defs/identifier"
|
|
76
|
+
},
|
|
77
|
+
"description": {
|
|
78
|
+
"$ref": "#/$defs/description"
|
|
79
|
+
},
|
|
80
|
+
"section": {
|
|
81
|
+
"$ref": "#/$defs/section"
|
|
82
|
+
},
|
|
83
|
+
"message": {
|
|
84
|
+
"description": "The message, usually text. Any other JSON value is a message a host wrote as something else (section 4); the undefined tag is a message the caller did not supply (section 10)."
|
|
85
|
+
},
|
|
86
|
+
"payload": {
|
|
87
|
+
"description": "The payload (section 3). Entries hold values, wrappers (section 4.1) or tagged values.",
|
|
88
|
+
"type": "object"
|
|
89
|
+
},
|
|
90
|
+
"props": {
|
|
91
|
+
"description": "The caller's formatting properties, grouped by modifier name (section 11.2).",
|
|
92
|
+
"type": "object"
|
|
93
|
+
},
|
|
94
|
+
"locale": {
|
|
95
|
+
"type": "string"
|
|
96
|
+
},
|
|
97
|
+
"key": {
|
|
98
|
+
"description": "The message's key (section 4). Any JSON value: a key a host wrote as something other than text is echoed as the text it converts to (section 10)."
|
|
99
|
+
},
|
|
100
|
+
"modifiers": {
|
|
101
|
+
"description": "Host-defined modifiers to register (section 11.3), each the name of a behaviour from the catalogue.",
|
|
102
|
+
"type": "object",
|
|
103
|
+
"propertyNames": {
|
|
104
|
+
"minLength": 1
|
|
105
|
+
},
|
|
106
|
+
"additionalProperties": {
|
|
107
|
+
"$ref": "#/$defs/behaviour"
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
"defaults": {
|
|
111
|
+
"description": "The implementation-configured defaults: the bottom formatting layer of section 11.2, grouped by modifier name.",
|
|
112
|
+
"type": "object"
|
|
113
|
+
},
|
|
114
|
+
"expected": {
|
|
115
|
+
"$ref": "#/$defs/expected"
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
"generated": {
|
|
120
|
+
"description": "A case the runner builds from the limits the adapter declares (section 13); the README states each construction.",
|
|
121
|
+
"type": "object",
|
|
122
|
+
"required": [
|
|
123
|
+
"id",
|
|
124
|
+
"description",
|
|
125
|
+
"generate"
|
|
126
|
+
],
|
|
127
|
+
"additionalProperties": false,
|
|
128
|
+
"properties": {
|
|
129
|
+
"id": {
|
|
130
|
+
"$ref": "#/$defs/identifier"
|
|
131
|
+
},
|
|
132
|
+
"description": {
|
|
133
|
+
"$ref": "#/$defs/description"
|
|
134
|
+
},
|
|
135
|
+
"section": {
|
|
136
|
+
"$ref": "#/$defs/section"
|
|
137
|
+
},
|
|
138
|
+
"generate": {
|
|
139
|
+
"enum": [
|
|
140
|
+
"passes-at-limit",
|
|
141
|
+
"passes-over-limit",
|
|
142
|
+
"output-at-limit",
|
|
143
|
+
"output-over-limit",
|
|
144
|
+
"output-over-limit-stops",
|
|
145
|
+
"conversion-over-limit"
|
|
146
|
+
]
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
"description": {
|
|
151
|
+
"description": "One sentence naming what the case pins, for the failure it would print.",
|
|
152
|
+
"type": "string",
|
|
153
|
+
"minLength": 1
|
|
154
|
+
},
|
|
155
|
+
"behaviour": {
|
|
156
|
+
"enum": [
|
|
157
|
+
"upper",
|
|
158
|
+
"echo",
|
|
159
|
+
"empty",
|
|
160
|
+
"nothing",
|
|
161
|
+
"raise",
|
|
162
|
+
"default",
|
|
163
|
+
"options",
|
|
164
|
+
"props",
|
|
165
|
+
"locale",
|
|
166
|
+
"object"
|
|
167
|
+
]
|
|
168
|
+
},
|
|
169
|
+
"expected": {
|
|
170
|
+
"type": "object",
|
|
171
|
+
"additionalProperties": false,
|
|
172
|
+
"properties": {
|
|
173
|
+
"output": {
|
|
174
|
+
"description": "The text the resolution must produce.",
|
|
175
|
+
"type": "string"
|
|
176
|
+
},
|
|
177
|
+
"format": {
|
|
178
|
+
"description": "For a locale-dependent output: the formatting request whose result on the running host is the text the resolution must produce. The message is then the placeholder alone.",
|
|
179
|
+
"$ref": "#/$defs/format"
|
|
180
|
+
},
|
|
181
|
+
"reports": {
|
|
182
|
+
"description": "The reports the resolution must emit, in the order it emits them. Omitted, none are expected.",
|
|
183
|
+
"type": "array",
|
|
184
|
+
"items": {
|
|
185
|
+
"$ref": "#/$defs/report"
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
"oneOf": [
|
|
190
|
+
{
|
|
191
|
+
"required": [
|
|
192
|
+
"output"
|
|
193
|
+
],
|
|
194
|
+
"properties": {
|
|
195
|
+
"output": true
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
"required": [
|
|
200
|
+
"format"
|
|
201
|
+
],
|
|
202
|
+
"properties": {
|
|
203
|
+
"format": true
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
]
|
|
207
|
+
},
|
|
208
|
+
"format": {
|
|
209
|
+
"type": "object",
|
|
210
|
+
"required": [
|
|
211
|
+
"api",
|
|
212
|
+
"input"
|
|
213
|
+
],
|
|
214
|
+
"additionalProperties": false,
|
|
215
|
+
"properties": {
|
|
216
|
+
"api": {
|
|
217
|
+
"enum": [
|
|
218
|
+
"NumberFormat",
|
|
219
|
+
"DateTimeFormat",
|
|
220
|
+
"RelativeTimeFormat"
|
|
221
|
+
]
|
|
222
|
+
},
|
|
223
|
+
"options": {
|
|
224
|
+
"description": "The options the request is constructed with: the properties the facility reads, as the layers of section 11.2 compose them and the modifier pins them, without the format's own ratio and format, which the input already reflects.",
|
|
225
|
+
"type": "object"
|
|
226
|
+
},
|
|
227
|
+
"input": {
|
|
228
|
+
"description": "What the request formats: a number for NumberFormat, milliseconds since the epoch for DateTimeFormat, a [value, unit] pair for RelativeTimeFormat."
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
},
|
|
232
|
+
"report": {
|
|
233
|
+
"type": "object",
|
|
234
|
+
"required": [
|
|
235
|
+
"code",
|
|
236
|
+
"origin"
|
|
237
|
+
],
|
|
238
|
+
"additionalProperties": false,
|
|
239
|
+
"properties": {
|
|
240
|
+
"code": {
|
|
241
|
+
"enum": [
|
|
242
|
+
"unknown-modifier",
|
|
243
|
+
"failed-modifier",
|
|
244
|
+
"missing-options",
|
|
245
|
+
"unserializable-value",
|
|
246
|
+
"missing-locale",
|
|
247
|
+
"pass-limit",
|
|
248
|
+
"output-limit"
|
|
249
|
+
]
|
|
250
|
+
},
|
|
251
|
+
"origin": {
|
|
252
|
+
"enum": [
|
|
253
|
+
"message",
|
|
254
|
+
"payload",
|
|
255
|
+
"limit"
|
|
256
|
+
]
|
|
257
|
+
},
|
|
258
|
+
"key": {
|
|
259
|
+
"description": "The key the report must name, where the adapter's reports carry one."
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|