lutaml-xsd 1.2.83 → 1.2.85

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: efe4fbd2d864e7cbe9218faaf7f67fc879c4e20cc32c54e04761fcee59d2d1dc
4
- data.tar.gz: 3b5618daa924a8a493645bab5ea7f0408d3b9245c32695306131c1cb9a0cfeb8
3
+ metadata.gz: dbc20030f5533a3b759ce3584c4e5c03fcaf67394c146d4bf10583ae277ceabd
4
+ data.tar.gz: 5cf4f72605a149ddb8d7cac841853f7b9e62fb6452df280468e2f74d112d8f8e
5
5
  SHA512:
6
- metadata.gz: 909c81244dd126cbbb8843fcd3a010f5da4a3c70bd325b71ed5865496cc390d101fecb6d6a4c38069b350abad064c4837328f5ee28cdcb583b4ec5e439c629da
7
- data.tar.gz: 34a60915d85511b36be444dc6903e8f3f221e6740d3d6147fd5966c0fe82a852896dffb20fbf6253376bb78abeaa4a2717da83b4b44e644739acda1e85105c33
6
+ metadata.gz: 96eb9fb8a632b65f8db59fe80d56daef13defa57c9650961bb42a08d43850377245eb4cc36a254a75d56de10fb6fb71f551771e74fb195605ecbe30ca800cced
7
+ data.tar.gz: f16796622093f4eff1a965ef73a9d8e054711774d523b72c95f2ef76e55f107c54e6e7a3f232cdbf0f6400a4b194dce5d45729fe82893645db8422dbcb86bcb2
data/TODO.conformance.md CHANGED
@@ -120,7 +120,7 @@ pinned commit) is measured via `rake conformance:w3c`:
120
120
 
121
121
  | mode | pass-rate |
122
122
  |---|---|
123
- | pipeline | 4585/4696 (97.64%) |
123
+ | pipeline | 4588/4696 (97.7%; the 1.9.403 engine ride nets zero — 17 filings-confirmed flips offset by 17 new strictness regressions, filed leptris-rs#35) |
124
124
 
125
125
  (2026-11-02, bundled-stack measurement with the escape,
126
126
  hint-following, pattern-alternative, identity-crash, engine-set,
@@ -144,7 +144,7 @@ lockfile refresh) → 4411 (93.9%) → 4430 (94.3%) → 4435 (94.4%) →
144
144
  → 4557 (97.0%) → 4565 (97.2%) → 4569 (97.3%) → 4562 (drift raw) →
145
145
  4563 (97.17%, ref-namespace round) → 4573 (97.38%, group-content
146
146
  round) → 4578 (97.49%, attribute-prohibition round) → 4585 (97.64%,
147
- multi-document round), +624 net over the 1.2.43 baseline. The escapes round (PR #197 — \d→\p{Nd},
147
+ multi-document round) → 4588 (97.7%, type-binding round), +627 net over the 1.2.43 baseline. The escapes round (PR #197 — \d→\p{Nd},
148
148
  \w/\W/\s to their XSD value spaces) collapses Regex 120→69;
149
149
  same-step pattern facets now behave as alternatives and
150
150
  whitespace-only text reaches the facets intact (PR #200), Regex
@@ -234,7 +234,11 @@ corners.
234
234
 
235
235
  | Class | Cases | Filed |
236
236
  |---|---|---|
237
- | Empty content against a fixed element value rejected (1.9.402.0 regression — isDefault001/002/076, ctZ013a, elemQ019, stE065/066/096, particlesZ040; attribute leg addB104, attO006) | 15 | leptris-rs#25 (+ case-list comment) |
237
+ | Fixed-empty bare elements FIXED in 1.9.403; CHILD-element leg still flagged (isDefault005/006/025/026/060_1) | 5 | leptris-rs#35 (sub 1; #25 comment) |
238
+ | mixed="true" on a particle-less complexType rejects text (ctA033/ctA035) | 2 | leptris-rs#35 (sub 2) |
239
+ | xs:redefine composition compiles to an EMPTY content model (idF025/033/034, idG018/019/027/028) | 7 | leptris-rs#35 (sub 3) |
240
+ | Default-supplied content on an empty list-typed element (stZ072) | 1 | leptris-rs#35 (sub 4) |
241
+ | Empty content against a fixed element value — BARE leg FIXED in 1.9.403 (attribute leg addB104, attO006 still open) | 2 | leptris-rs#25 (comment) |
238
242
  | Content model enforced on NILLED elements (QFE1700g2, particlesIa002) | 2 | leptris-rs#26 |
239
243
  | dateTime enumeration rejects timezone-equal forms (dateTime_enumeration005a/b) | 2 | leptris-rs#27 |
240
244
  | "-0" rejected against nonNegativeInteger (errE002) | 1 | leptris-rs#28 |
@@ -494,6 +498,37 @@ tuple keys, node-set field violations and absent-field rows handled, cross-eleme
494
498
  lutaml-model Redefine model shape study). Remaining Schema 9:
495
499
  schA1/Q1/D10/F2 (ours), schD7/G8 (lutaml-model#1087),
496
500
  schF1/G2/G7/P2 (moxml#510 composed bindings).
501
+ - TYPE-BINDING ROUND (2026-11-03): +3 (Schema 9→8 — schQ1/schF2
502
+ flip; Particles 12→8 cumulatively with the collision round; suite
503
+ 4585→4588 = 97.7%, zero regressions, rspec green). Same-local-name
504
+ types across a composition (three documents each declaring ct-A in
505
+ ns-a/ns-b/no-namespace) resolved to the FIRST candidate; the
506
+ resolver now keeps every candidate in document order and prefers
507
+ the one declared in the OWNING declaration's namespace (type
508
+ namespaces indexed at index time), with the no-namespace owner
509
+ preferring the no-namespace candidate; xsi:type overrides and
510
+ extension-base walks thread the deriving type namespace through.
511
+ STILL OPEN: schA1/schD10 (the hinted composition's CHILD value
512
+ checks bind the no-ns int ct-A to the ns-b boolean children —
513
+ 'true' vs xsd:int — the per-child type plumbing under hint
514
+ layering), full type-redefine body semantics.
515
+ - ENGINE-403 REFRESH ROUND (2026-11-03, net zero at 4588 = 97.7%):
516
+ leptris 1.9.402.0 -> 1.9.403.0 (the ride that closed #1936 and the
517
+ rs#25-29 wave — 17 suite cases FIXED, exactly our filings:
518
+ fixed-empty elements, nilled-content, "-0", xsi:type override,
519
+ dateTime enumeration, reZ/reK88 char-reference legs, schG7).
520
+ OFFSET by 17 NEW regressions, filed leptris-rs#35 in four
521
+ subclasses: (1) fixed+empty CHILD elements still flagged
522
+ (isDefault005/006/025/026/060_1 — #25 incomplete, the child path
523
+ was missed); (2) mixed="true" on a particle-less complexType
524
+ rejects text (ctA033/ctA035); (3) xs:redefine composition compiles
525
+ to an EMPTY content model (idF025/033/034, idG018/019/027/028 —
526
+ the redefined body particles are lost); (4) default-supplied
527
+ content on an empty list-typed element (stZ072). stZ073b/ba
528
+ flipped engine-silent (Ruby queue). The attributes-any runner
529
+ fixture carried a stray text node against an empty content model —
530
+ fixed (the 403 strictness is spec-correct there).
531
+
497
532
  - REGEX SEMANTICS ROUND (2026-10-31, PR #208): \w/\W now carry their
498
533
  Appendix F complements (\w = [^\p{P}\p{Z}\p{C}], class interiors
499
534
  via the exact positive partition L/M/N/S), \I/\C complements added
@@ -247,7 +247,9 @@ module Lutaml
247
247
  xsi = repository && xsi_attribute(xml_element, "type")
248
248
  if xsi&.value.to_s.match?(/\S/)
249
249
  local = xsi.value.to_s.split(":").last
250
- named = repository.resolve_named_type(local)
250
+ named = repository.resolve_named_type(
251
+ local, repository.target_namespace_for(schema_def)
252
+ )
251
253
  return nil unless named
252
254
 
253
255
  return type_particles(named, repository, {}.compare_by_identity)
@@ -303,7 +305,9 @@ module Lutaml
303
305
  if extension
304
306
  base_local = extension.base.to_s.split(":").last
305
307
  base_type = base_local &&
306
- repository&.resolve_named_type(base_local)
308
+ repository&.resolve_named_type(
309
+ base_local, repository&.target_namespace_for(type)
310
+ )
307
311
  particles = type_particles(base_type, repository, seen) +
308
312
  particles
309
313
  COMPLEX_PARTICLE_KINDS.each do |kind|
@@ -186,6 +186,9 @@ module Lutaml
186
186
  end
187
187
 
188
188
  # Named type for an element's `type="prefix:Name"` reference.
189
+ # Same-local-name types across composed documents resolve by
190
+ # the OWNING declaration's namespace (schA1: ct-A exists in
191
+ # ns-a/ns-b/no-namespace; the reference binds its own).
189
192
  #
190
193
  # @param schema_element [Lutaml::Xml::Schema::Xsd::Element, nil]
191
194
  # @return [Object, nil]
@@ -195,40 +198,67 @@ module Lutaml
195
198
  reference = schema_element.type
196
199
  return nil if reference.nil? || reference.to_s.empty?
197
200
 
198
- resolve_named_type(reference.to_s.split(":").last)
201
+ resolve_named_type(reference.to_s.split(":").last,
202
+ target_namespace_for(schema_element))
199
203
  end
200
204
 
201
- # Named complex or simple type by local name.
205
+ # Named complex or simple type by local name, preferring a
206
+ # candidate declared in owner_ns.
202
207
  #
203
208
  # @param local_name [String]
209
+ # @param owner_ns [String, nil] the referencing declaration's
210
+ # target namespace
204
211
  # @return [Object, nil]
205
- def resolve_named_type(local_name)
212
+ def resolve_named_type(local_name, owner_ns = nil)
206
213
  return nil if local_name.nil? || local_name.empty?
207
- return @named_types[local_name] if @named_types.key?(local_name)
208
214
 
209
- result = nil
210
- schemas.each do |schema|
211
- result = named_type_in(local_name, schema)
212
- break if result
215
+ list = named_type_candidates(local_name)
216
+ return nil if list.empty?
217
+ # A nil owner means the referencing declaration lives in NO
218
+ # namespace (schA1_c): prefer the no-namespace candidate, not
219
+ # just the first.
220
+ if owner_ns.nil?
221
+ return list.find { |t| @namespaces[t].to_s.empty? } ||
222
+ list.first
213
223
  end
214
- if result.nil? && !@redefined_body_names.include?(local_name)
215
- @redefined_targets.each do |schema|
216
- result = named_type_in(local_name, schema)
217
- break if result
218
- end
219
- end
220
- @named_types[local_name] = result
224
+
225
+ list.find { |t| @namespaces[t] == owner_ns } || list.first
221
226
  end
222
227
 
223
- # @return [Object, nil]
224
- def named_type_in(local_name, schema)
225
- found = Array(schema.complex_type).find do |ct|
226
- ct.name == local_name
228
+ # Every top-level and nested declaration of the name, in
229
+ # document order: schemas first, then parsed redefine targets
230
+ # (names a redefine body redefines stay off the targets).
231
+ #
232
+ # @return [Array<Object>]
233
+ def named_type_candidates(local_name)
234
+ cache = @named_type_lists ||= {}
235
+ return cache[local_name] if cache.key?(local_name)
236
+
237
+ list = []
238
+ schemas.each do |schema|
239
+ found = Array(schema.complex_type).find do |ct|
240
+ ct.name == local_name
241
+ end
242
+ found ||= Array(schema.simple_type).find do |st|
243
+ st.name == local_name
244
+ end
245
+ list << found if found
246
+
247
+ nested = find_nested_named_type(local_name, schema)
248
+ list << nested if nested
227
249
  end
228
- found ||= Array(schema.simple_type).find do |st|
229
- st.name == local_name
250
+ unless @redefined_body_names.include?(local_name)
251
+ @redefined_targets.each do |schema|
252
+ found = Array(schema.complex_type).find do |ct|
253
+ ct.name == local_name
254
+ end
255
+ found ||= Array(schema.simple_type).find do |st|
256
+ st.name == local_name
257
+ end
258
+ list << found if found
259
+ end
230
260
  end
231
- found || find_nested_named_type(local_name, schema)
261
+ cache[local_name] = list.uniq
232
262
  end
233
263
 
234
264
  # Named types declared in documents reached through resolved
@@ -767,6 +797,7 @@ module Lutaml
767
797
  def index_type(index, complex_type, namespace, schema)
768
798
  return unless complex_type
769
799
 
800
+ @namespaces[complex_type] = namespace
770
801
  each_particle_element(complex_type, schema) do |element|
771
802
  index_element(index, element, namespace, :inline, schema)
772
803
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Lutaml
4
4
  module Xsd
5
- VERSION = "1.2.83"
5
+ VERSION = "1.2.85"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lutaml-xsd
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.83
4
+ version: 1.2.85
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.