lutaml-xsd 1.2.109 → 1.2.111
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/TODO.conformance.md +36 -14
- data/lib/lutaml/xsd/validation/content_model_matcher.rb +14 -1
- data/lib/lutaml/xsd/validation/rules/content_model_validation_rule.rb +21 -4
- data/lib/lutaml/xsd/validation/schema_definition_resolver.rb +14 -15
- data/lib/lutaml/xsd/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c211adda1289222691ae1cd3d77ee6482ed88f3076e036fbaaf0937124906669
|
|
4
|
+
data.tar.gz: ad8339c42573c9152a1a94ef409aad142b2db3a2f13d98975f8b70f650fb2f1a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f51b044be371db36a1df22a0dc961dfca6f3e4742407d21ca277329ddebc8df51e80313376aea4389b8773fc6dde346ce7be7a4a086ae54c49498a6f0bda5f58
|
|
7
|
+
data.tar.gz: 8ed8f68bc2de75248980a699b0a022216b6a328e55ebc3829d721dc63c9a7db079db22fefa4d42803b6b3d3d6563ac07c6b3ce531a7825d7f86dcb58c6c4f1e0
|
data/TODO.conformance.md
CHANGED
|
@@ -546,26 +546,48 @@ tuple keys, node-set field violations and absent-field rows handled, cross-eleme
|
|
|
546
546
|
and the schG1/G4/G7 drift (fail in fresh isolation on origin/main
|
|
547
547
|
stash-verified — inputs/gems/ruby verified identical to the 4641
|
|
548
548
|
era; mechanism not isolated in-round; owner follow-up).
|
|
549
|
-
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
549
|
+
- NESTED-TYPE-CANDIDATES ROUND (2026-11-11): +2 (schG2 — a baseline
|
|
550
|
+
parked failure — and the schG1/G4/G7 "drift" trio resolved as REAL
|
|
551
|
+
DEFECTS, not environment: named_type_candidates appended only ONE
|
|
552
|
+
nested candidate per root schema — find_nested_named_type returned
|
|
553
|
+
the first depth-first match and stopped, so a composition importing
|
|
554
|
+
same-named types two levels deep (schG1: a→b→c) NEVER listed the
|
|
555
|
+
deepest candidate; the owner-ns preference missed and list.first
|
|
556
|
+
(ns-a's ct-A) typed the ns-c element — the '123'-is-not-boolean
|
|
557
|
+
swap. find_nested_named_types now collects EVERY match across the
|
|
558
|
+
whole nested tree in document order). SUITE 4637/4696 measured +
|
|
559
|
+
5 budget exclusions (reZ nested-repeat, unchanged), ZERO
|
|
560
|
+
regressions (stash-attributed per row), rspec 1663 green,
|
|
561
|
+
rubocop clean. schR2 stack-overflow note unchanged (crash masked
|
|
562
|
+
by expected-invalid, counted per convention).
|
|
563
|
+
- SCH R2 STACK OVERFLOW FIXED (2026-11-12, round shipped): the
|
|
564
|
+
SystemStackError on Schema_w3c/schR2/schR2.i (expected invalid;
|
|
565
|
+
masked as pass by the crash-as-invalid convention) is OURS, not
|
|
566
|
+
lutaml-model's — the infinite recursion cycles between the
|
|
567
|
+
§4.2.2 redefined group body and the redefine TARGET (two DISTINCT
|
|
568
|
+
objects reachable by the same group name b-g2), so an OBJECT-keyed
|
|
569
|
+
guard misses it; the cut is NAME-keyed and PATH-scoped in both
|
|
570
|
+
walkers: leaf_particles marks the group name on its ancestry
|
|
571
|
+
(same name cannot expand within its own ancestry; sibling reuse
|
|
572
|
+
still expands fresh) and ContentModelMatcher#compile_group keeps
|
|
573
|
+
the same path discipline over resolved containers. LEDGER vs the
|
|
574
|
+
1.2.110 baseline: 4637/4696 measured + the same 5 reZ budget
|
|
575
|
+
exclusions, ZERO regressions, and batch 4450's crash list is
|
|
576
|
+
EMPTY (schR2.i now assesses honestly to invalid instead of
|
|
577
|
+
overflowing). PROVENANCE: batch 03000 was carried over from the
|
|
578
|
+
1.2.110 ledger — regex-pattern-only cases whose walk never
|
|
579
|
+
touches the guards (the batch's reI003 quadratic tax made a
|
|
580
|
+
re-run cost-prohibitive on the contended machine). Also filed
|
|
581
|
+
lutaml/moxml#540 this round (the 0.6.4 attribute char-ref
|
|
582
|
+
regression below; repro included).
|
|
563
583
|
- TRAIN ADOPTION REGRESSION — CHARACTER REFERENCES (2026-11-11):
|
|
564
584
|
the 2026-11-10 adoption verdict ("conformance-IDENTICAL") was
|
|
565
585
|
WRONG for one class: moxml 0.6.4 stopped decoding numeric
|
|
566
586
|
character references in attribute values. Minimal repro:
|
|
567
587
|
`Moxml::Context.new.parse('<x a="←"/>').root.attributes.
|
|
568
588
|
first.value` → "←" on moxml 0.6.2, literal "←" on 0.6.4.
|
|
589
|
+
FILED lutaml/moxml#540 (2026-11-12; repro: attribute values keep
|
|
590
|
+
the reference literal while element text decodes on 0.6.4).
|
|
569
591
|
Downstream this breaks the whole UNICODE-BLOCK pattern-facet
|
|
570
592
|
class — Regex_w3c Arrows/MathematicalOperators/
|
|
571
593
|
ArabicPresentationForms-A/CJKCompatibilityForms/
|
|
@@ -225,7 +225,20 @@ module Lutaml
|
|
|
225
225
|
container = Array(@group_particles.call(particle)).first
|
|
226
226
|
return empty_fragment unless container
|
|
227
227
|
|
|
228
|
-
|
|
228
|
+
# §4.2.2 redefine bodies self-reference by name; the body and
|
|
229
|
+
# the redefine target are distinct objects, so the compile
|
|
230
|
+
# path set keys on the resolved container's identity — a
|
|
231
|
+
# container may not compile within its own ancestry, while
|
|
232
|
+
# sibling reuse still compiles fresh.
|
|
233
|
+
@group_path ||= []
|
|
234
|
+
return empty_fragment if @group_path.include?(container)
|
|
235
|
+
|
|
236
|
+
@group_path.push(container)
|
|
237
|
+
fragment = with_occurrence(particle) do
|
|
238
|
+
compile_container_body(container)
|
|
239
|
+
end
|
|
240
|
+
@group_path.pop
|
|
241
|
+
fragment
|
|
229
242
|
end
|
|
230
243
|
|
|
231
244
|
# A group ref expands to its declaration's container, whose own
|
|
@@ -368,14 +368,31 @@ module Lutaml
|
|
|
368
368
|
end
|
|
369
369
|
end
|
|
370
370
|
|
|
371
|
-
def leaf_particles(particles, repository)
|
|
371
|
+
def leaf_particles(particles, repository, ancestors = nil)
|
|
372
|
+
ancestors ||= {}
|
|
372
373
|
particles.flat_map do |particle|
|
|
373
374
|
case particle
|
|
374
375
|
when Lutaml::Xml::Schema::Xsd::Group
|
|
375
|
-
|
|
376
|
-
|
|
376
|
+
# §4.2.2 redefine bodies self-reference by NAME; the
|
|
377
|
+
# body and the redefine target are DISTINCT objects, so
|
|
378
|
+
# the path set keys on the group name — the same name
|
|
379
|
+
# cannot expand within its own ancestry, while sibling
|
|
380
|
+
# reuse still expands fresh.
|
|
381
|
+
group_name = if particle.name.to_s.empty?
|
|
382
|
+
particle.ref.to_s
|
|
383
|
+
else
|
|
384
|
+
particle.name.to_s
|
|
385
|
+
end
|
|
386
|
+
next [] if group_name.empty? || ancestors.key?(group_name)
|
|
387
|
+
|
|
388
|
+
ancestors[group_name] = true
|
|
389
|
+
body = expand_group_container(particle, repository)
|
|
390
|
+
leaves = body.nil? ? [] : leaf_particles(body, repository, ancestors)
|
|
391
|
+
ancestors.delete(group_name)
|
|
392
|
+
leaves
|
|
377
393
|
when Lutaml::Xsd::Sequence, Lutaml::Xsd::Choice, Lutaml::Xsd::All
|
|
378
|
-
leaf_particles(collect_particles(particle), repository
|
|
394
|
+
leaf_particles(collect_particles(particle), repository,
|
|
395
|
+
ancestors)
|
|
379
396
|
else
|
|
380
397
|
[particle]
|
|
381
398
|
end
|
|
@@ -290,8 +290,8 @@ module Lutaml
|
|
|
290
290
|
end
|
|
291
291
|
list << found if found
|
|
292
292
|
|
|
293
|
-
nested =
|
|
294
|
-
list
|
|
293
|
+
nested = find_nested_named_types(local_name, schema)
|
|
294
|
+
list.concat(nested)
|
|
295
295
|
end
|
|
296
296
|
unless @redefined_body_names.include?(local_name)
|
|
297
297
|
@redefined_targets.each do |schema|
|
|
@@ -307,16 +307,18 @@ module Lutaml
|
|
|
307
307
|
cache[local_name] = list.uniq
|
|
308
308
|
end
|
|
309
309
|
|
|
310
|
-
#
|
|
311
|
-
#
|
|
312
|
-
#
|
|
310
|
+
# EVERY same-named type across the whole nested include/import
|
|
311
|
+
# tree, in document order. The single-match walk stopped at the
|
|
312
|
+
# FIRST hit (schG1: ns-b's ct-A shadowed ns-c's two imports
|
|
313
|
+
# deep, so the owner-ns preference missed and ns-a's type won
|
|
314
|
+
# for the ns-c element — a same-local-name swap).
|
|
313
315
|
#
|
|
314
|
-
# @return [Object
|
|
315
|
-
def
|
|
316
|
-
return
|
|
316
|
+
# @return [Array<Object>]
|
|
317
|
+
def find_nested_named_types(local_name, schema, depth = 0)
|
|
318
|
+
return [] if depth > 8
|
|
317
319
|
|
|
318
|
-
(Array(schema.include) + Array(schema.import)).
|
|
319
|
-
next unless nested.is_a?(Lutaml::Xml::Schema::Xsd::Schema)
|
|
320
|
+
(Array(schema.include) + Array(schema.import)).flat_map do |nested|
|
|
321
|
+
next [] unless nested.is_a?(Lutaml::Xml::Schema::Xsd::Schema)
|
|
320
322
|
|
|
321
323
|
found = Array(nested.complex_type).find do |ct|
|
|
322
324
|
ct.name == local_name
|
|
@@ -324,12 +326,9 @@ module Lutaml
|
|
|
324
326
|
found ||= Array(nested.simple_type).find do |st|
|
|
325
327
|
st.name == local_name
|
|
326
328
|
end
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
found = find_nested_named_type(local_name, nested, depth + 1)
|
|
330
|
-
return found if found
|
|
329
|
+
[found, *find_nested_named_types(local_name, nested, depth + 1)]
|
|
330
|
+
.compact
|
|
331
331
|
end
|
|
332
|
-
nil
|
|
333
332
|
end
|
|
334
333
|
|
|
335
334
|
# Builtin numeric types: values compare in the numeric value
|
data/lib/lutaml/xsd/version.rb
CHANGED