moxml 0.5.171 → 0.5.172
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.
- checksums.yaml +4 -4
- data/Rakefile +23 -0
- data/conformance/moxml-conformance.json +413 -0
- data/lib/moxml/adapter/customized_leptris/declaration.rb +9 -0
- data/lib/moxml/adapter/customized_leptris/doctype.rb +8 -0
- data/lib/moxml/adapter/customized_leptris/entity_reference.rb +8 -0
- data/lib/moxml/adapter/customized_leptris/text_segment.rb +8 -0
- data/lib/moxml/adapter/customized_leptris.rb +5 -0
- data/lib/moxml/adapter/customized_libxml/cdata.rb +2 -0
- data/lib/moxml/adapter/customized_libxml/comment.rb +2 -0
- data/lib/moxml/adapter/customized_libxml/declaration.rb +2 -0
- data/lib/moxml/adapter/customized_libxml/element.rb +2 -0
- data/lib/moxml/adapter/customized_libxml/entity_reference.rb +2 -0
- data/lib/moxml/adapter/customized_libxml/node.rb +2 -0
- data/lib/moxml/adapter/customized_libxml/processing_instruction.rb +2 -0
- data/lib/moxml/adapter/customized_libxml/text.rb +2 -0
- data/lib/moxml/adapter/customized_libxml.rb +3 -0
- data/lib/moxml/adapter/customized_oga/entity_decoder.rb +8 -0
- data/lib/moxml/adapter/customized_oga/raw_value_override.rb +8 -0
- data/lib/moxml/adapter/customized_oga/xml_declaration.rb +8 -0
- data/lib/moxml/adapter/customized_oga/xml_generator.rb +1 -1
- data/lib/moxml/adapter/customized_oga.rb +4 -0
- data/lib/moxml/adapter/customized_ox/attribute.rb +5 -0
- data/lib/moxml/adapter/customized_ox/entity_reference.rb +5 -0
- data/lib/moxml/adapter/customized_ox/namespace.rb +5 -0
- data/lib/moxml/adapter/customized_ox/text.rb +6 -0
- data/lib/moxml/adapter/customized_ox.rb +3 -0
- data/lib/moxml/adapter/customized_rexml/entity_reference.rb +5 -0
- data/lib/moxml/adapter/customized_rexml/formatter.rb +6 -0
- data/lib/moxml/adapter/customized_rexml.rb +4 -0
- data/lib/moxml/adapter.rb +13 -0
- data/lib/moxml/version.rb +1 -1
- data/lib/moxml/xsd/builtin_lexical.rb +100 -0
- data/spec/moxml/adapter/customized_lifecycle_audit_spec.rb +49 -0
- data/spec/moxml/adapter_registry_spec.rb +44 -0
- data/spec/moxml/customized_lifecycle_spec.rb +47 -0
- data/spec/moxml/xsd_conformance_cases_spec.rb +37 -0
- metadata +6 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f8719e57bb76ceb63baa171d151028d8aff538fc351be7397b6ec5a492c8bdf1
|
|
4
|
+
data.tar.gz: 8fa85d23570f0588da0eb5d4ce5f83d59fb28e325d587f7210d3380a8afd5e33
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b93fc457a9d7435e2a55cb4fb5e3320d37b5949e77b184c640dd65a8b21954aab9987f204c8916411d9bfe6e11f7f0e358faa78f1ee9cfe3477f52b2d209e857
|
|
7
|
+
data.tar.gz: 78c66d6b3bdbb800b8cf23dde851235ab3a621bbb30fd0c413db06f9f856ba245b56f9a2c4a4d8220ca313b3bb2ef447d5737733387052bd82f2151cfd7bcdc5
|
data/Rakefile
CHANGED
|
@@ -350,4 +350,27 @@ namespace :docs do
|
|
|
350
350
|
end
|
|
351
351
|
end
|
|
352
352
|
|
|
353
|
+
namespace :conformance do
|
|
354
|
+
desc "Export the cross-language conformance dataset to JSON (#496)"
|
|
355
|
+
task :export do
|
|
356
|
+
require "json"
|
|
357
|
+
require_relative "lib/moxml"
|
|
358
|
+
dataset = Moxml::XSD::BuiltinLexical::CONFORMANCE_CASES
|
|
359
|
+
payload = {
|
|
360
|
+
schema: 1,
|
|
361
|
+
generator: "moxml #{Moxml::VERSION}",
|
|
362
|
+
cases: {
|
|
363
|
+
"builtin_lexical" => dataset.map do |type, lexical, expected|
|
|
364
|
+
{ "type" => type, "lexical" => lexical, "valid" => expected }
|
|
365
|
+
end,
|
|
366
|
+
},
|
|
367
|
+
}
|
|
368
|
+
dir = File.expand_path("conformance", __dir__)
|
|
369
|
+
FileUtils.mkdir_p(dir)
|
|
370
|
+
target = File.join(dir, "moxml-conformance.json")
|
|
371
|
+
File.write(target, "#{JSON.pretty_generate(payload)}\n")
|
|
372
|
+
puts "conformance: exported #{dataset.size} cases to #{target}"
|
|
373
|
+
end
|
|
374
|
+
end
|
|
375
|
+
|
|
353
376
|
task default: :spec
|
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema": 1,
|
|
3
|
+
"generator": "moxml 0.5.171",
|
|
4
|
+
"cases": {
|
|
5
|
+
"builtin_lexical": [
|
|
6
|
+
{
|
|
7
|
+
"type": "xs:token",
|
|
8
|
+
"lexical": "a b",
|
|
9
|
+
"valid": true
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"type": "xs:ID",
|
|
13
|
+
"lexical": " id ",
|
|
14
|
+
"valid": true
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"type": "xs:NMTOKEN",
|
|
18
|
+
"lexical": "\tx ",
|
|
19
|
+
"valid": true
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"type": "xs:ID",
|
|
23
|
+
"lexical": "1d",
|
|
24
|
+
"valid": false
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"type": "xs:integer",
|
|
28
|
+
"lexical": "11111111111111111111111111111",
|
|
29
|
+
"valid": true
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"type": "xs:positiveInteger",
|
|
33
|
+
"lexical": "11111111111111111111111111111",
|
|
34
|
+
"valid": true
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"type": "xs:nonNegativeInteger",
|
|
38
|
+
"lexical": "11111111111111111111111111111",
|
|
39
|
+
"valid": true
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"type": "xs:negativeInteger",
|
|
43
|
+
"lexical": "-100000000000000000000",
|
|
44
|
+
"valid": true
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"type": "xs:nonPositiveInteger",
|
|
48
|
+
"lexical": "0",
|
|
49
|
+
"valid": true
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"type": "xs:nonPositiveInteger",
|
|
53
|
+
"lexical": "-0",
|
|
54
|
+
"valid": true
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"type": "xs:long",
|
|
58
|
+
"lexical": "9223372036854775807",
|
|
59
|
+
"valid": true
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"type": "xs:long",
|
|
63
|
+
"lexical": "9223372036854775808",
|
|
64
|
+
"valid": false
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"type": "xs:unsignedLong",
|
|
68
|
+
"lexical": "18446744073709551615",
|
|
69
|
+
"valid": true
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"type": "xs:unsignedLong",
|
|
73
|
+
"lexical": "18446744073709551616",
|
|
74
|
+
"valid": false
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"type": "xs:byte",
|
|
78
|
+
"lexical": "128",
|
|
79
|
+
"valid": false
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"type": "xs:unsignedByte",
|
|
83
|
+
"lexical": "256",
|
|
84
|
+
"valid": false
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"type": "xs:float",
|
|
88
|
+
"lexical": "+INF",
|
|
89
|
+
"valid": true
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"type": "xs:double",
|
|
93
|
+
"lexical": "-INF",
|
|
94
|
+
"valid": true
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"type": "xs:float",
|
|
98
|
+
"lexical": "NaN",
|
|
99
|
+
"valid": true
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"type": "xs:float",
|
|
103
|
+
"lexical": "1.5E-3",
|
|
104
|
+
"valid": true
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"type": "xs:decimal",
|
|
108
|
+
"lexical": "5.",
|
|
109
|
+
"valid": true
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"type": "xs:decimal",
|
|
113
|
+
"lexical": ".5",
|
|
114
|
+
"valid": true
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"type": "xs:decimal",
|
|
118
|
+
"lexical": "1e3",
|
|
119
|
+
"valid": false
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"type": "xs:date",
|
|
123
|
+
"lexical": "2024-02-29",
|
|
124
|
+
"valid": true
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"type": "xs:date",
|
|
128
|
+
"lexical": "1999-02-29",
|
|
129
|
+
"valid": false
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
"type": "xs:date",
|
|
133
|
+
"lexical": "2024-04-31",
|
|
134
|
+
"valid": false
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"type": "xs:date",
|
|
138
|
+
"lexical": "2024-13-01",
|
|
139
|
+
"valid": false
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
"type": "xs:date",
|
|
143
|
+
"lexical": "not-a-date",
|
|
144
|
+
"valid": false
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"type": "xs:dateTime",
|
|
148
|
+
"lexical": "2024-02-29T23:59:59Z",
|
|
149
|
+
"valid": true
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"type": "xs:dateTime",
|
|
153
|
+
"lexical": "1999-02-29T00:00:00",
|
|
154
|
+
"valid": false
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"type": "xs:dateTime",
|
|
158
|
+
"lexical": "not-a-date",
|
|
159
|
+
"valid": false
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
"type": "xs:dateTimeStamp",
|
|
163
|
+
"lexical": "2024-02-29T00:00:00Z",
|
|
164
|
+
"valid": true
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
"type": "xs:dateTimeStamp",
|
|
168
|
+
"lexical": "2024-02-29T00:00:00",
|
|
169
|
+
"valid": false
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
"type": "xs:time",
|
|
173
|
+
"lexical": "23:59:59.999+05:30",
|
|
174
|
+
"valid": true
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
"type": "xs:time",
|
|
178
|
+
"lexical": "24:00:00",
|
|
179
|
+
"valid": false
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
"type": "xs:time",
|
|
183
|
+
"lexical": "25:20:00",
|
|
184
|
+
"valid": false
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
"type": "xs:time",
|
|
188
|
+
"lexical": "13:20:60",
|
|
189
|
+
"valid": false
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
"type": "xs:gYearMonth",
|
|
193
|
+
"lexical": "2024-02Z",
|
|
194
|
+
"valid": true
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
"type": "xs:gYearMonth",
|
|
198
|
+
"lexical": "2024-13",
|
|
199
|
+
"valid": false
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
"type": "xs:gMonthDay",
|
|
203
|
+
"lexical": "--02-29",
|
|
204
|
+
"valid": true
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
"type": "xs:gMonthDay",
|
|
208
|
+
"lexical": "--02-30",
|
|
209
|
+
"valid": false
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
"type": "xs:gDay",
|
|
213
|
+
"lexical": "---31",
|
|
214
|
+
"valid": true
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
"type": "xs:gDay",
|
|
218
|
+
"lexical": "---32",
|
|
219
|
+
"valid": false
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
"type": "xs:duration",
|
|
223
|
+
"lexical": "P1Y2M3DT4H5M6.5S",
|
|
224
|
+
"valid": true
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
"type": "xs:duration",
|
|
228
|
+
"lexical": "PT0S",
|
|
229
|
+
"valid": true
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
"type": "xs:duration",
|
|
233
|
+
"lexical": "-P1D",
|
|
234
|
+
"valid": true
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
"type": "xs:duration",
|
|
238
|
+
"lexical": "P",
|
|
239
|
+
"valid": false
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
"type": "xs:duration",
|
|
243
|
+
"lexical": "PT",
|
|
244
|
+
"valid": false
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
"type": "xs:duration",
|
|
248
|
+
"lexical": "P1Y2MT",
|
|
249
|
+
"valid": false
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
"type": "xs:duration",
|
|
253
|
+
"lexical": "P200.5Y",
|
|
254
|
+
"valid": false
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
"type": "xs:dayTimeDuration",
|
|
258
|
+
"lexical": "P1DT2H",
|
|
259
|
+
"valid": true
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
"type": "xs:dayTimeDuration",
|
|
263
|
+
"lexical": "P1Y",
|
|
264
|
+
"valid": false
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
"type": "xs:yearMonthDuration",
|
|
268
|
+
"lexical": "P1Y2M",
|
|
269
|
+
"valid": true
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
"type": "xs:yearMonthDuration",
|
|
273
|
+
"lexical": "P1D",
|
|
274
|
+
"valid": false
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
"type": "xs:yearMonthDuration",
|
|
278
|
+
"lexical": "P1YT1H",
|
|
279
|
+
"valid": false
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
"type": "xs:base64Binary",
|
|
283
|
+
"lexical": "aGVsbG8=",
|
|
284
|
+
"valid": true
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
"type": "xs:base64Binary",
|
|
288
|
+
"lexical": "abcd",
|
|
289
|
+
"valid": true
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
"type": "xs:base64Binary",
|
|
293
|
+
"lexical": "abcde",
|
|
294
|
+
"valid": false
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
"type": "xs:base64Binary",
|
|
298
|
+
"lexical": "a b",
|
|
299
|
+
"valid": false
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
"type": "xs:hexBinary",
|
|
303
|
+
"lexical": "0A",
|
|
304
|
+
"valid": true
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
"type": "xs:hexBinary",
|
|
308
|
+
"lexical": "0AB",
|
|
309
|
+
"valid": false
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
"type": "xs:QName",
|
|
313
|
+
"lexical": "foo",
|
|
314
|
+
"valid": true
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
"type": "xs:QName",
|
|
318
|
+
"lexical": "ns:foo",
|
|
319
|
+
"valid": true
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
"type": "xs:QName",
|
|
323
|
+
"lexical": "xmlns:xsi",
|
|
324
|
+
"valid": false
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
"type": "xs:QName",
|
|
328
|
+
"lexical": ":foo",
|
|
329
|
+
"valid": false
|
|
330
|
+
},
|
|
331
|
+
{
|
|
332
|
+
"type": "xs:QName",
|
|
333
|
+
"lexical": "a:b:c",
|
|
334
|
+
"valid": false
|
|
335
|
+
},
|
|
336
|
+
{
|
|
337
|
+
"type": "xs:NOTATION",
|
|
338
|
+
"lexical": "foo",
|
|
339
|
+
"valid": true
|
|
340
|
+
},
|
|
341
|
+
{
|
|
342
|
+
"type": "xs:IDREFS",
|
|
343
|
+
"lexical": "a b",
|
|
344
|
+
"valid": true
|
|
345
|
+
},
|
|
346
|
+
{
|
|
347
|
+
"type": "xs:IDREFS",
|
|
348
|
+
"lexical": "a",
|
|
349
|
+
"valid": true
|
|
350
|
+
},
|
|
351
|
+
{
|
|
352
|
+
"type": "xs:IDREFS",
|
|
353
|
+
"lexical": "",
|
|
354
|
+
"valid": false
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
"type": "xs:NMTOKENS",
|
|
358
|
+
"lexical": "a.b-c:d e",
|
|
359
|
+
"valid": true
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
"type": "xs:ENTITIES",
|
|
363
|
+
"lexical": "a 1",
|
|
364
|
+
"valid": false
|
|
365
|
+
},
|
|
366
|
+
{
|
|
367
|
+
"type": "xs:string",
|
|
368
|
+
"lexical": "anything <>&",
|
|
369
|
+
"valid": true
|
|
370
|
+
},
|
|
371
|
+
{
|
|
372
|
+
"type": "xs:anyURI",
|
|
373
|
+
"lexical": "http://example.com/a b",
|
|
374
|
+
"valid": true
|
|
375
|
+
},
|
|
376
|
+
{
|
|
377
|
+
"type": "xs:boolean",
|
|
378
|
+
"lexical": "true",
|
|
379
|
+
"valid": true
|
|
380
|
+
},
|
|
381
|
+
{
|
|
382
|
+
"type": "xs:boolean",
|
|
383
|
+
"lexical": "0",
|
|
384
|
+
"valid": true
|
|
385
|
+
},
|
|
386
|
+
{
|
|
387
|
+
"type": "xs:boolean",
|
|
388
|
+
"lexical": "TRUE",
|
|
389
|
+
"valid": false
|
|
390
|
+
},
|
|
391
|
+
{
|
|
392
|
+
"type": "xs:language",
|
|
393
|
+
"lexical": "en-US",
|
|
394
|
+
"valid": true
|
|
395
|
+
},
|
|
396
|
+
{
|
|
397
|
+
"type": "xs:language",
|
|
398
|
+
"lexical": "en_US",
|
|
399
|
+
"valid": false
|
|
400
|
+
},
|
|
401
|
+
{
|
|
402
|
+
"type": "xs:Name",
|
|
403
|
+
"lexical": "a:b",
|
|
404
|
+
"valid": true
|
|
405
|
+
},
|
|
406
|
+
{
|
|
407
|
+
"type": "xs:NCName",
|
|
408
|
+
"lexical": "a:b",
|
|
409
|
+
"valid": false
|
|
410
|
+
}
|
|
411
|
+
]
|
|
412
|
+
}
|
|
413
|
+
}
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
# Wrapper for an XML declaration.
|
|
4
|
+
#
|
|
5
|
+
# Lifecycle record: libleptris models the declaration as document-state
|
|
6
|
+
# flags — setters shipped (leptris#1094) and clear shipped
|
|
7
|
+
# (leptris#1229, binding 1.9.204.0) — but there is still no first-class
|
|
8
|
+
# declaration NODE, so the facade keeps this mutable, removable value
|
|
9
|
+
# object as the node stand-in. Dissolves when libleptris exposes
|
|
10
|
+
# declaration node identity (leptris#1904's successor surface).
|
|
11
|
+
|
|
3
12
|
module Moxml
|
|
4
13
|
module Adapter
|
|
5
14
|
module CustomizedLeptris
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
# Wrapper for a programmatic DOCTYPE.
|
|
4
|
+
#
|
|
5
|
+
# Lifecycle record: set shipped (leptris#212, binding 1.9.176) and unset
|
|
6
|
+
# shipped (leptris#1229, binding 1.9.204.0 remove_doctype), but there is
|
|
7
|
+
# still no first-class DOCTYPE NODE — the facade keeps this value object
|
|
8
|
+
# as the node stand-in in the document's attachments. Dissolves with
|
|
9
|
+
# declaration node identity (see customized_leptris/declaration.rb).
|
|
10
|
+
|
|
3
11
|
module Moxml
|
|
4
12
|
module Adapter
|
|
5
13
|
module CustomizedLeptris
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
# Parse-path face: libleptris expands the five built-in entities at
|
|
4
|
+
# parse time and has no custom ones, so parsed references are carried
|
|
5
|
+
# as Moxml::Entity::Reference values over marker-bearing text.
|
|
6
|
+
# Programmatic creation is native (NATIVE_ENTITY_REFS, binding >= 1.9.177).
|
|
7
|
+
#
|
|
8
|
+
# Lifecycle record: dissolves when parse-time entity reference retention
|
|
9
|
+
# ships — leptris#1904 (references as nodes or bulk positions).
|
|
10
|
+
|
|
3
11
|
module Moxml
|
|
4
12
|
module Adapter
|
|
5
13
|
module CustomizedLeptris
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
# A text run split out of a native text node that carried entity
|
|
4
|
+
# markers. Value object: the moxml contract exposes text nodes as
|
|
5
|
+
# separate children around entity references, while libleptris stores
|
|
6
|
+
# them as one marker-bearing text node.
|
|
7
|
+
#
|
|
8
|
+
# Lifecycle record: dissolves with entity reference retention —
|
|
9
|
+
# leptris#1904 (see customized_leptris/entity_reference.rb).
|
|
10
|
+
|
|
3
11
|
module Moxml
|
|
4
12
|
module Adapter
|
|
5
13
|
module CustomizedLeptris
|
|
@@ -7,6 +7,11 @@ module Moxml
|
|
|
7
7
|
# and document-level processing instructions.
|
|
8
8
|
# The adapter stores them via NativeAttachment and serializes them
|
|
9
9
|
# from #to_xml.
|
|
10
|
+
#
|
|
11
|
+
# Lifecycle record (#495): a tracked shim, not an adapter-fate
|
|
12
|
+
# case — the parse-time entity-retention gap is the last engine
|
|
13
|
+
# ask of the #275 mutation-completion round; when the engine ships
|
|
14
|
+
# native retention these classes dissolve into Base.
|
|
10
15
|
module CustomizedLeptris
|
|
11
16
|
autoload :Declaration, "moxml/adapter/customized_leptris/declaration"
|
|
12
17
|
autoload :Doctype, "moxml/adapter/customized_leptris/doctype"
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
module Moxml
|
|
4
4
|
module Adapter
|
|
5
|
+
# Lifecycle record (#495): engine-gap shims for the :libxml
|
|
6
|
+
# adapter, deprecated in moxml#491 -- removed with it after the
|
|
7
|
+
# cycle. No separate upstream ask; the adapter's fate governs.
|
|
5
8
|
module CustomizedLibxml
|
|
6
9
|
autoload :Cdata, "moxml/adapter/customized_libxml/cdata"
|
|
7
10
|
autoload :Comment, "moxml/adapter/customized_libxml/comment"
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
# Override Oga::EntityDecoder.decode for XML inputs.
|
|
4
|
+
#
|
|
5
|
+
# Engine gap (upstream oga): Oga 3.4's stock Oga::XML::Entities.decode
|
|
6
|
+
# runs multiple passes, turning the well-formed "&#38;" into "&"
|
|
7
|
+
# rather than the correct "&". Upstream tracker:
|
|
8
|
+
# https://github.com/yorickpeterse/oga — the override stays until oga
|
|
9
|
+
# fixes the decoder or the adapter is retired.
|
|
10
|
+
|
|
3
11
|
require "oga"
|
|
4
12
|
|
|
5
13
|
module Moxml
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
# Bypass Oga's lazy decoder for user-authored values.
|
|
4
|
+
#
|
|
5
|
+
# Engine gap (upstream oga): Oga::XML::Attribute#value and
|
|
6
|
+
# Oga::XML::Text#text decode @value/@text on first read via
|
|
7
|
+
# Oga::EntityDecoder; EntityDecoderOverride (this directory) must hold
|
|
8
|
+
# user-authored raw values. Upstream tracker:
|
|
9
|
+
# https://github.com/yorickpeterse/oga
|
|
10
|
+
|
|
3
11
|
require "oga"
|
|
4
12
|
|
|
5
13
|
module Moxml
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
# Stand-in XML declaration node.
|
|
4
|
+
#
|
|
5
|
+
# Engine gap (upstream oga): Oga::XML::XmlDeclaration is not writable —
|
|
6
|
+
# version/encoding/standalone cannot be set on an instance the way the
|
|
7
|
+
# facade contract requires, so this subclass owns the state and renders
|
|
8
|
+
# the declaration itself. Upstream tracker:
|
|
9
|
+
# https://github.com/yorickpeterse/oga
|
|
10
|
+
|
|
3
11
|
require "oga"
|
|
4
12
|
|
|
5
13
|
module Moxml
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# rubocop:disable Style/FrozenStringLiteralComment
|
|
2
2
|
|
|
3
|
-
require "oga"
|
|
3
|
+
# Lifecycle record: engine gap (upstream oga); see the patched-class URL below.require "oga"
|
|
4
4
|
|
|
5
5
|
# monkey patch the Oga generator because it's not configurable
|
|
6
6
|
# https://github.com/yorickpeterse/oga/blob/main/lib/oga/xml/generator.rb
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
module Moxml
|
|
4
4
|
module Adapter
|
|
5
|
+
# Lifecycle record (#495): every override serves the :oga adapter,
|
|
6
|
+
# deprecated in moxml#491 and deleted with the Opal surface in
|
|
7
|
+
# moxml#489 phase 4. No separate upstream ask -- the adapter's
|
|
8
|
+
# fate governs this file.
|
|
5
9
|
module CustomizedOga
|
|
6
10
|
autoload :EntityDecoderOverride, "moxml/adapter/customized_oga/entity_decoder"
|
|
7
11
|
autoload :RawValueOverride, "moxml/adapter/customized_oga/raw_value_override"
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
# Engine gap (upstream ox): an ::Ox::Attribute carries no parent
|
|
4
|
+
# back-reference and no prefix slots, so the facade's attribute node
|
|
5
|
+
# contract needs this Node subclass. Upstream tracker:
|
|
6
|
+
# https://github.com/ohler55/ox
|
|
7
|
+
|
|
3
8
|
module Moxml
|
|
4
9
|
module Adapter
|
|
5
10
|
module CustomizedOx
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
# Parse-path alias: ox expands the built-in entities at parse time and
|
|
4
|
+
# has no reference nodes, so parsed references are the facade's
|
|
5
|
+
# Moxml::Entity::Reference values. Lifecycle: the :ox adapter is
|
|
6
|
+
# deprecated (#491) — this record dies with it.
|
|
7
|
+
|
|
3
8
|
module Moxml
|
|
4
9
|
module Adapter
|
|
5
10
|
module CustomizedOx
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
# Engine gap (upstream ox): ox has no Namespace node class — prefixes
|
|
4
|
+
# live as attribute spellings — so the facade's namespace node contract
|
|
5
|
+
# needs this value object. Upstream tracker:
|
|
6
|
+
# https://github.com/ohler55/ox
|
|
7
|
+
|
|
3
8
|
module Moxml
|
|
4
9
|
module Adapter
|
|
5
10
|
module CustomizedOx
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
# Engine gap (upstream ox): Ox uses Strings for text content, but a
|
|
4
|
+
# String cannot carry a @parent back-reference; this ::Ox::Node subclass
|
|
5
|
+
# gives text nodes node identity. NOTE: an ::Ox::Node subclass that is
|
|
6
|
+
# neither ::Ox::Element nor ::Ox::Document changes Ox's dump behavior.
|
|
7
|
+
# Upstream tracker: https://github.com/ohler55/ox
|
|
8
|
+
|
|
3
9
|
module Moxml
|
|
4
10
|
module Adapter
|
|
5
11
|
module CustomizedOx
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
module Moxml
|
|
4
4
|
module Adapter
|
|
5
|
+
# Lifecycle record (#495): engine-gap shims for the :ox adapter,
|
|
6
|
+
# deprecated in moxml#491 -- removed with it after the cycle.
|
|
7
|
+
# No separate upstream ask; the adapter's fate governs.
|
|
5
8
|
module CustomizedOx
|
|
6
9
|
autoload :Attribute, "moxml/adapter/customized_ox/attribute"
|
|
7
10
|
autoload :EntityReference, "moxml/adapter/customized_ox/entity_reference"
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
# Parse-path alias: rexml expands the built-in entities at parse time,
|
|
4
|
+
# so parsed references are the facade's Moxml::Entity::Reference values.
|
|
5
|
+
# Lifecycle: the :rexml adapter is Opal-only and dies with the Opal
|
|
6
|
+
# surface (#489 phase 4); third-party engine, no upstream ask.
|
|
7
|
+
|
|
3
8
|
module Moxml
|
|
4
9
|
module Adapter
|
|
5
10
|
module CustomizedRexml
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
# Custom REXML formatter that fixes indentation and wrapping issues.
|
|
4
|
+
# Engine gap (upstream rexml): REXML's Formatters::Pretty cannot be
|
|
5
|
+
# configured to the facade's whitespace contract. Third-party engine,
|
|
6
|
+
# no upstream ask; the :rexml adapter is Opal-only and dies with the
|
|
7
|
+
# Opal surface (#489 phase 4).
|
|
8
|
+
|
|
3
9
|
require "rexml/formatters/pretty"
|
|
4
10
|
|
|
5
11
|
module Moxml
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
module Moxml
|
|
4
4
|
module Adapter
|
|
5
|
+
# Lifecycle record (#495): engine-gap shims for the :rexml
|
|
6
|
+
# adapter (Opal fallback; deleted with the Opal surface in
|
|
7
|
+
# moxml#489 phase 4). No separate upstream ask; the adapter's
|
|
8
|
+
# fate governs this file.
|
|
5
9
|
module CustomizedRexml
|
|
6
10
|
autoload :EntityReference,
|
|
7
11
|
"moxml/adapter/customized_rexml/entity_reference"
|
data/lib/moxml/adapter.rb
CHANGED
|
@@ -2,6 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
module Moxml
|
|
4
4
|
module Adapter
|
|
5
|
+
# Extension contract (#494): adding an adapter is exactly the trio
|
|
6
|
+
# below — nothing else, anywhere. The dispatch is open for
|
|
7
|
+
# extension and closed against edit: registration is data, the
|
|
8
|
+
# load path is generic, and spec/moxml/adapter_registry_spec.rb
|
|
9
|
+
# walks the registry mechanically so a skipped leg fails there.
|
|
10
|
+
#
|
|
11
|
+
# 1. one entry in AVAILABLE_ADAPTERS,
|
|
12
|
+
# 2. a requireable file at moxml/adapter/<name> (a
|
|
13
|
+
# `Customized<Name>` namespace module is optional),
|
|
14
|
+
# 3. a subclass of Adapter::Base in that file.
|
|
15
|
+
#
|
|
16
|
+
# Deprecated adapters live in DEPRECATED_ADAPTERS (still fully
|
|
17
|
+
# registered and loadable) until their removal milestone.
|
|
5
18
|
autoload :Base, "moxml/adapter/base"
|
|
6
19
|
autoload :CustomizedOga, "moxml/adapter/customized_oga"
|
|
7
20
|
autoload :CustomizedOx, "moxml/adapter/customized_ox"
|
data/lib/moxml/version.rb
CHANGED
|
@@ -255,6 +255,106 @@ module Moxml
|
|
|
255
255
|
"xs:NOTATION" => ->(lexical) { qname?(collapsed(lexical)) },
|
|
256
256
|
}.freeze
|
|
257
257
|
|
|
258
|
+
# The cross-language conformance dataset (#496): the model's
|
|
259
|
+
# builtin-lexical answers as data, pinned BY the Ruby suite
|
|
260
|
+
# (spec/moxml/xsd_conformance_cases_spec.rb) and exported to
|
|
261
|
+
# conformance/moxml-conformance.json by `rake conformance:export`
|
|
262
|
+
# — moxml-rs and moxml-ts run the same rows. Each row:
|
|
263
|
+
# [type, lexical, expected].
|
|
264
|
+
CONFORMANCE_CASES = [
|
|
265
|
+
# token family / collapse
|
|
266
|
+
["xs:token", "a b", true],
|
|
267
|
+
["xs:ID", " id ", true],
|
|
268
|
+
["xs:NMTOKEN", "\tx ", true],
|
|
269
|
+
["xs:ID", "1d", false],
|
|
270
|
+
# unbounded integers
|
|
271
|
+
["xs:integer", "1" * 29, true],
|
|
272
|
+
["xs:positiveInteger", "1" * 29, true],
|
|
273
|
+
["xs:nonNegativeInteger", "1" * 29, true],
|
|
274
|
+
["xs:negativeInteger", "-1#{'0' * 20}", true],
|
|
275
|
+
["xs:nonPositiveInteger", "0", true],
|
|
276
|
+
["xs:nonPositiveInteger", "-0", true],
|
|
277
|
+
# bounded integers
|
|
278
|
+
["xs:long", "9223372036854775807", true],
|
|
279
|
+
["xs:long", "9223372036854775808", false],
|
|
280
|
+
["xs:unsignedLong", "18446744073709551615", true],
|
|
281
|
+
["xs:unsignedLong", "18446744073709551616", false],
|
|
282
|
+
["xs:byte", "128", false],
|
|
283
|
+
["xs:unsignedByte", "256", false],
|
|
284
|
+
# float/decimal spellings
|
|
285
|
+
["xs:float", "+INF", true],
|
|
286
|
+
["xs:double", "-INF", true],
|
|
287
|
+
["xs:float", "NaN", true],
|
|
288
|
+
["xs:float", "1.5E-3", true],
|
|
289
|
+
["xs:decimal", "5.", true],
|
|
290
|
+
["xs:decimal", ".5", true],
|
|
291
|
+
["xs:decimal", "1e3", false],
|
|
292
|
+
# calendar
|
|
293
|
+
["xs:date", "2024-02-29", true],
|
|
294
|
+
["xs:date", "1999-02-29", false],
|
|
295
|
+
["xs:date", "2024-04-31", false],
|
|
296
|
+
["xs:date", "2024-13-01", false],
|
|
297
|
+
["xs:date", "not-a-date", false],
|
|
298
|
+
["xs:dateTime", "2024-02-29T23:59:59Z", true],
|
|
299
|
+
["xs:dateTime", "1999-02-29T00:00:00", false],
|
|
300
|
+
["xs:dateTime", "not-a-date", false],
|
|
301
|
+
["xs:dateTimeStamp", "2024-02-29T00:00:00Z", true],
|
|
302
|
+
["xs:dateTimeStamp", "2024-02-29T00:00:00", false],
|
|
303
|
+
["xs:time", "23:59:59.999+05:30", true],
|
|
304
|
+
["xs:time", "24:00:00", false],
|
|
305
|
+
["xs:time", "25:20:00", false],
|
|
306
|
+
["xs:time", "13:20:60", false],
|
|
307
|
+
["xs:gYearMonth", "2024-02Z", true],
|
|
308
|
+
["xs:gYearMonth", "2024-13", false],
|
|
309
|
+
["xs:gMonthDay", "--02-29", true],
|
|
310
|
+
["xs:gMonthDay", "--02-30", false],
|
|
311
|
+
["xs:gDay", "---31", true],
|
|
312
|
+
["xs:gDay", "---32", false],
|
|
313
|
+
# duration
|
|
314
|
+
["xs:duration", "P1Y2M3DT4H5M6.5S", true],
|
|
315
|
+
["xs:duration", "PT0S", true],
|
|
316
|
+
["xs:duration", "-P1D", true],
|
|
317
|
+
["xs:duration", "P", false],
|
|
318
|
+
["xs:duration", "PT", false],
|
|
319
|
+
["xs:duration", "P1Y2MT", false],
|
|
320
|
+
["xs:duration", "P200.5Y", false],
|
|
321
|
+
["xs:dayTimeDuration", "P1DT2H", true],
|
|
322
|
+
["xs:dayTimeDuration", "P1Y", false],
|
|
323
|
+
["xs:yearMonthDuration", "P1Y2M", true],
|
|
324
|
+
["xs:yearMonthDuration", "P1D", false],
|
|
325
|
+
["xs:yearMonthDuration", "P1YT1H", false],
|
|
326
|
+
# binary
|
|
327
|
+
["xs:base64Binary", "aGVsbG8=", true],
|
|
328
|
+
["xs:base64Binary", "abcd", true],
|
|
329
|
+
["xs:base64Binary", "abcde", false],
|
|
330
|
+
["xs:base64Binary", "a b", false],
|
|
331
|
+
["xs:hexBinary", "0A", true],
|
|
332
|
+
["xs:hexBinary", "0AB", false],
|
|
333
|
+
# QName family
|
|
334
|
+
["xs:QName", "foo", true],
|
|
335
|
+
["xs:QName", "ns:foo", true],
|
|
336
|
+
["xs:QName", "xmlns:xsi", false],
|
|
337
|
+
["xs:QName", ":foo", false],
|
|
338
|
+
["xs:QName", "a:b:c", false],
|
|
339
|
+
["xs:NOTATION", "foo", true],
|
|
340
|
+
# lists: items, not characters
|
|
341
|
+
["xs:IDREFS", "a b", true],
|
|
342
|
+
["xs:IDREFS", "a", true],
|
|
343
|
+
["xs:IDREFS", "", false],
|
|
344
|
+
["xs:NMTOKENS", "a.b-c:d e", true],
|
|
345
|
+
["xs:ENTITIES", "a 1", false],
|
|
346
|
+
# open lexical spaces
|
|
347
|
+
["xs:string", "anything <>&", true],
|
|
348
|
+
["xs:anyURI", "http://example.com/a b", true],
|
|
349
|
+
["xs:boolean", "true", true],
|
|
350
|
+
["xs:boolean", "0", true],
|
|
351
|
+
["xs:boolean", "TRUE", false],
|
|
352
|
+
["xs:language", "en-US", true],
|
|
353
|
+
["xs:language", "en_US", false],
|
|
354
|
+
["xs:Name", "a:b", true],
|
|
355
|
+
["xs:NCName", "a:b", false],
|
|
356
|
+
].map(&:freeze).freeze
|
|
357
|
+
|
|
258
358
|
private_constant :CHECKERS
|
|
259
359
|
end
|
|
260
360
|
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
|
|
5
|
+
# #495: the Customized* adapter layer is either a removable-lifecycle
|
|
6
|
+
# record (an engine gap with a tracked upstream issue) or it dissolves
|
|
7
|
+
# into Base. This audit makes the lifecycle record checkable instead of
|
|
8
|
+
# folklore: every override file must cite its issue (an #NNN reference
|
|
9
|
+
# for our engines, or an upstream tracker URL for third-party engines
|
|
10
|
+
# we do not file against), and every Customized module must be wired
|
|
11
|
+
# into exactly its adapter (no dead records).
|
|
12
|
+
RSpec.describe "Customized adapter lifecycle audit" do
|
|
13
|
+
let(:override_files) do
|
|
14
|
+
Dir[File.expand_path("../../lib/moxml/adapter/customized_*/*.rb", __dir__)].sort
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "cites a tracked issue or upstream tracker in every override file" do
|
|
18
|
+
broken = override_files.reject do |file|
|
|
19
|
+
head = File.readlines(file).first(25).join
|
|
20
|
+
head.match?(/#\s*#\d{2,5}\b/) || head.include?("github.com/")
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
expect(broken).to be_empty, <<~MSG
|
|
24
|
+
Customized* override files without a lifecycle citation:
|
|
25
|
+
#{broken.join("\n")}
|
|
26
|
+
Each file's header must cite the open upstream issue that explains
|
|
27
|
+
why the override exists (#NNN for leptris; the upstream tracker URL
|
|
28
|
+
for third-party engines), or the #491 deprecation that retires it.
|
|
29
|
+
MSG
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "wires every Customized module into exactly its adapter" do
|
|
33
|
+
shims = Dir[File.expand_path("../../lib/moxml/adapter/customized_*.rb", __dir__)]
|
|
34
|
+
|
|
35
|
+
shims.each do |shim|
|
|
36
|
+
module_name = File.read(shim)[/module (Customized\w+)/, 1]
|
|
37
|
+
adapter_file = File.expand_path(
|
|
38
|
+
"../../lib/moxml/adapter/#{module_name.delete_prefix('Customized').downcase}.rb",
|
|
39
|
+
__dir__,
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
expect(File).to exist(adapter_file),
|
|
43
|
+
"#{module_name} has no #{adapter_file} to customize"
|
|
44
|
+
|
|
45
|
+
expect(File.read(adapter_file)).to include(module_name),
|
|
46
|
+
"#{module_name} is not wired into its adapter"
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
|
|
5
|
+
# The registry's extension contract (#494): adding an adapter is the
|
|
6
|
+
# documented trio — one AVAILABLE_ADAPTERS entry, one requireable
|
|
7
|
+
# adapter file, one Base subclass. The dispatch is open for extension:
|
|
8
|
+
# this spec walks the registry mechanically so a new adapter that
|
|
9
|
+
# skips any leg fails here, not in a consumer.
|
|
10
|
+
RSpec.describe "Adapter registry extension contract" do
|
|
11
|
+
it "loads every registered adapter through the public face" do
|
|
12
|
+
Moxml::Adapter::AVAILABLE_ADAPTERS.each do |name|
|
|
13
|
+
adapter = Moxml::Adapter.load(name)
|
|
14
|
+
expect(adapter).not_to be_nil
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "resolves every registered adapter to an Adapter::Base subclass" do
|
|
19
|
+
Moxml::Adapter::AVAILABLE_ADAPTERS.each do |name|
|
|
20
|
+
adapter = Moxml::Adapter.load(name)
|
|
21
|
+
expect(adapter).to be <= Moxml::Adapter::Base
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "answers available? truthfully for every registered adapter" do
|
|
26
|
+
Moxml::Adapter::AVAILABLE_ADAPTERS.each do |name|
|
|
27
|
+
expect(Moxml::Adapter.available?(name)).to be(true)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "rejects unregistered names before any require runs" do
|
|
32
|
+
expect do
|
|
33
|
+
Moxml::Adapter.load(:definitely_not_an_adapter)
|
|
34
|
+
end.to raise_error(Moxml::AdapterError, /not available on this platform/)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "keeps the deprecated adapters inside the registry with guidance" do
|
|
38
|
+
described = Moxml::Adapter::DEPRECATED_ADAPTERS
|
|
39
|
+
expect(described.keys).to all(satisfy { |name| Moxml::Adapter::AVAILABLE_ADAPTERS.include?(name) })
|
|
40
|
+
described.each_value do |guidance|
|
|
41
|
+
expect(guidance).to match(/:nokogiri|:leptris/)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
|
|
5
|
+
# The customized_* layer's doctrine (#495): each namespace module is
|
|
6
|
+
# either a tracked shim (an engine gap with a stated resolution) or an
|
|
7
|
+
# adapter-fate case (dies with its deprecated adapter). A Customized*
|
|
8
|
+
# file exists only when its header says which — the record is
|
|
9
|
+
# checkable, not folklore.
|
|
10
|
+
RSpec.describe "customized adapter layer lifecycle" do
|
|
11
|
+
def customized_files
|
|
12
|
+
Dir["lib/moxml/adapter/customized_*.rb"]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "has customized namespaces to govern" do
|
|
16
|
+
expect(customized_files).not_to be_empty
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "cites its lifecycle in every module header" do
|
|
20
|
+
customized_files.each do |path|
|
|
21
|
+
header = File.readlines(path).first(30).join
|
|
22
|
+
expect(header).to match(/#\d{3}/),
|
|
23
|
+
"#{path} carries no lifecycle citation (#495)"
|
|
24
|
+
expect(header).to match(/Lifecycle record|no native representation/),
|
|
25
|
+
"#{path} header does not state its lifecycle"
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "marks adapter-fate cases as deprecated or Opal-bound" do
|
|
30
|
+
adapter_fate = customized_files.reject { |p| p.include?("leptris") }
|
|
31
|
+
expect(adapter_fate).not_to be_empty
|
|
32
|
+
adapter_fate.each do |path|
|
|
33
|
+
header = File.readlines(path).first(30).join
|
|
34
|
+
expect(header).to match(/moxml#491|moxml#489/),
|
|
35
|
+
"#{path} is an adapter-fate case but cites neither " \
|
|
36
|
+
"its deprecation (#491) nor the Opal removal (#489)"
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "keeps the tracked shim pointed at its resolution" do
|
|
41
|
+
header = File.readlines("lib/moxml/adapter/customized_leptris.rb")
|
|
42
|
+
.first(30).join
|
|
43
|
+
expect(header).to include("tracked shim"), "the leptris shim must say so"
|
|
44
|
+
expect(header).to include("dissolve into Base"),
|
|
45
|
+
"the leptris shim must state its end state"
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Processing model §Validation (normative): pinned here.
|
|
4
|
+
|
|
5
|
+
require "spec_helper"
|
|
6
|
+
|
|
7
|
+
# The conformance dataset is the model's builtin-lexical answers AS
|
|
8
|
+
# DATA (#496): the Ruby suite pins every row here, and the exported
|
|
9
|
+
# JSON (rake conformance:export) is what moxml-rs and moxml-ts run.
|
|
10
|
+
# A row that fails here breaks the cross-language contract, not just
|
|
11
|
+
# this implementation.
|
|
12
|
+
RSpec.describe "builtin lexical conformance dataset" do
|
|
13
|
+
def valid_lexical?(type, lexical)
|
|
14
|
+
Moxml::XSD.builtin_valid?(Moxml.new(:leptris), type, lexical)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "carries the dataset" do
|
|
18
|
+
expect(Moxml::XSD::BuiltinLexical::CONFORMANCE_CASES.size).to be >= 80
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "answers every row exactly as the dataset expects" do
|
|
22
|
+
Moxml::XSD::BuiltinLexical::CONFORMANCE_CASES.each do |type, lexical, expected|
|
|
23
|
+
answer = valid_lexical?(type, lexical)
|
|
24
|
+
expect(answer).to eql(expected),
|
|
25
|
+
"#{type} #{lexical.inspect}: got #{answer.inspect}, " \
|
|
26
|
+
"dataset expects #{expected.inspect}"
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "keeps every dataset type in the table" do
|
|
31
|
+
Moxml::XSD::BuiltinLexical::CONFORMANCE_CASES.each do |type, _lexical, _expected|
|
|
32
|
+
expect do
|
|
33
|
+
valid_lexical?(type, "")
|
|
34
|
+
end.not_to raise_error
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: moxml
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.172
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
@@ -53,6 +53,7 @@ files:
|
|
|
53
53
|
- bin/console
|
|
54
54
|
- bin/generate-model-coverage
|
|
55
55
|
- bin/setup
|
|
56
|
+
- conformance/moxml-conformance.json
|
|
56
57
|
- data/w3c_entities.json
|
|
57
58
|
- docs/ENTITY_SUPPORT_FOR_LUTAML_MODEL.md
|
|
58
59
|
- docs/Gemfile
|
|
@@ -479,6 +480,7 @@ files:
|
|
|
479
480
|
- spec/moxml/adapter/README.md
|
|
480
481
|
- spec/moxml/adapter/base_spec.rb
|
|
481
482
|
- spec/moxml/adapter/columnar_invalidation_spec.rb
|
|
483
|
+
- spec/moxml/adapter/customized_lifecycle_audit_spec.rb
|
|
482
484
|
- spec/moxml/adapter/entity_restoration_spec.rb
|
|
483
485
|
- spec/moxml/adapter/headed_ox_spec.rb
|
|
484
486
|
- spec/moxml/adapter/leptris_adoption_spec.rb
|
|
@@ -513,6 +515,7 @@ files:
|
|
|
513
515
|
- spec/moxml/adapter/shared_examples/.gitkeep
|
|
514
516
|
- spec/moxml/adapter/shared_examples/adapter_contract.rb
|
|
515
517
|
- spec/moxml/adapter_deprecation_spec.rb
|
|
518
|
+
- spec/moxml/adapter_registry_spec.rb
|
|
516
519
|
- spec/moxml/adapter_spec.rb
|
|
517
520
|
- spec/moxml/allocation_benchmark_spec.rb
|
|
518
521
|
- spec/moxml/allocation_guard_spec.rb
|
|
@@ -538,6 +541,7 @@ files:
|
|
|
538
541
|
- spec/moxml/config_spec.rb
|
|
539
542
|
- spec/moxml/context_spec.rb
|
|
540
543
|
- spec/moxml/css_spec.rb
|
|
544
|
+
- spec/moxml/customized_lifecycle_spec.rb
|
|
541
545
|
- spec/moxml/cycle_rejection_spec.rb
|
|
542
546
|
- spec/moxml/declaration_preservation_spec.rb
|
|
543
547
|
- spec/moxml/declaration_spec.rb
|
|
@@ -634,6 +638,7 @@ files:
|
|
|
634
638
|
- spec/moxml/xpath_capabilities_spec.rb
|
|
635
639
|
- spec/moxml/xpath_spec.rb
|
|
636
640
|
- spec/moxml/xsd_builtin_lexical_spec.rb
|
|
641
|
+
- spec/moxml/xsd_conformance_cases_spec.rb
|
|
637
642
|
- spec/moxml/xsd_engine_meta_spec.rb
|
|
638
643
|
- spec/moxml/xsd_error_contract_spec.rb
|
|
639
644
|
- spec/moxml/xsd_handle_mismatch_spec.rb
|