lutaml-model 0.8.146 → 0.8.147
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/lib/lutaml/model/version.rb +1 -1
- data/lib/lutaml/xml/leptris/plan_hydrator.rb +53 -21
- data/lib/lutaml/xml/schema/xsd/schema.rb +3 -1
- data/spec/lutaml/xml/leptris/plan_hydrator_ns_snapshot_spec.rb +61 -0
- data/spec/lutaml/xml/schema/xsd/import_without_namespace_spec.rb +61 -0
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 73297b741e0c6f033811660bef32b0bcd51529d9ebd517ec3c67cd386e7134e6
|
|
4
|
+
data.tar.gz: a8fd9b7f9f0d6d95fd40441a116dc8e81639b8ef8e79c5c9c026c7d82691a7bf
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 24717f565b570a808908949176ba5b006fc1b176018776a85f62df04d63e152bb8fc6e5c88badca9d7ede0911cffe79b65c908de9fec356af56f4fc7ba0a7b2e
|
|
7
|
+
data.tar.gz: a3203db4195bf6f4a5d32529febd708ab574c07e0d7b93dfdb64674d1e0bdd37c5a2d5965e8506d023ea90c70d620622c38d43b3a02072f1fc4c014483b65590
|
data/lib/lutaml/model/version.rb
CHANGED
|
@@ -94,6 +94,50 @@ module Lutaml
|
|
|
94
94
|
instance
|
|
95
95
|
end
|
|
96
96
|
|
|
97
|
+
# leptris#1874: snapshot rows -> the ns_data hash
|
|
98
|
+
# ({path => {prefix_key => {uri:, prefix:, format:}}}), the
|
|
99
|
+
# exact shape the recursion builds. Public: it is the
|
|
100
|
+
# contract the binding's snapshot rows must satisfy.
|
|
101
|
+
def ns_data_from_snapshot_rows(rows)
|
|
102
|
+
rows.each_with_object({}) do |row, result|
|
|
103
|
+
prefix = row[:prefix]
|
|
104
|
+
# One element carrying several declarations emits one
|
|
105
|
+
# row PER declaration with the same path — merge them,
|
|
106
|
+
# exactly as the recursion accumulates per path.
|
|
107
|
+
(result[row[:path]] ||= {})[row[:prefix] || :default] = {
|
|
108
|
+
uri: row[:href], prefix: prefix,
|
|
109
|
+
format: prefix ? :prefix : :default
|
|
110
|
+
}
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def collect_native_namespaces(element, path = [], result = {})
|
|
115
|
+
if element.respond_to?(:namespace_declarations_snapshot)
|
|
116
|
+
return ns_data_from_snapshot_rows(
|
|
117
|
+
element.namespace_declarations_snapshot,
|
|
118
|
+
)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
own = element.namespace_definitions
|
|
122
|
+
unless own.empty?
|
|
123
|
+
namespaces = {}
|
|
124
|
+
own.each do |ns|
|
|
125
|
+
key = ns.prefix || :default
|
|
126
|
+
namespaces[key] = { uri: ns.href, prefix: ns.prefix,
|
|
127
|
+
format: ns.prefix ? :prefix : :default }
|
|
128
|
+
end
|
|
129
|
+
result[path.dup] = namespaces
|
|
130
|
+
end
|
|
131
|
+
element.children.each do |child|
|
|
132
|
+
next unless child.is_a?(::Leptris::XML::Element)
|
|
133
|
+
|
|
134
|
+
path.push(child.name)
|
|
135
|
+
collect_native_namespaces(child, path, result)
|
|
136
|
+
path.pop
|
|
137
|
+
end
|
|
138
|
+
result
|
|
139
|
+
end
|
|
140
|
+
|
|
97
141
|
private
|
|
98
142
|
|
|
99
143
|
def record_declaration_plan(instance, node, model_class)
|
|
@@ -123,27 +167,15 @@ module Lutaml
|
|
|
123
167
|
# Iterates children with an inline element filter:
|
|
124
168
|
# element_children materializes a filtered array per node,
|
|
125
169
|
# which the niso allocation gate caught at scale.
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
result[path.dup] = namespaces
|
|
136
|
-
end
|
|
137
|
-
element.children.each do |child|
|
|
138
|
-
next unless child.is_a?(::Leptris::XML::Element)
|
|
139
|
-
|
|
140
|
-
path.push(child.name)
|
|
141
|
-
collect_native_namespaces(child, path, result)
|
|
142
|
-
path.pop
|
|
143
|
-
end
|
|
144
|
-
result
|
|
145
|
-
end
|
|
146
|
-
|
|
170
|
+
#
|
|
171
|
+
# leptris#1874: when the binding exposes the bulk snapshot
|
|
172
|
+
# face (namespace_declarations_snapshot — one FFI crossing
|
|
173
|
+
# for the whole subtree; shipped engine-side in 1.9.387),
|
|
174
|
+
# the whole-subtree Ruby recursion collapses into a single
|
|
175
|
+
# call. Rows: {path: [names...], prefix: String|nil,
|
|
176
|
+
# href: String} in pre-order, paths relative to the
|
|
177
|
+
# receiver. The face probe keeps older bindings on the
|
|
178
|
+
# recursion unchanged.
|
|
147
179
|
def register
|
|
148
180
|
Lutaml::Model::Config.default_register
|
|
149
181
|
end
|
|
@@ -86,7 +86,9 @@ module Lutaml
|
|
|
86
86
|
"import",
|
|
87
87
|
model,
|
|
88
88
|
schema,
|
|
89
|
-
|
|
89
|
+
# An xs:import without a namespace attribute is legal
|
|
90
|
+
# (XSD 1.0 §3.13.2); the raw read stays nil-safe (#1051).
|
|
91
|
+
namespace: schema.attributes["namespace"]&.value,
|
|
90
92
|
)
|
|
91
93
|
end
|
|
92
94
|
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
require_relative "../../../../lib/lutaml/model"
|
|
3
|
+
|
|
4
|
+
# leptris#1874: the plan hydrator's namespace collection collapses the
|
|
5
|
+
# whole-subtree Ruby recursion (one namespace_definitions FFI crossing
|
|
6
|
+
# per node) into the engine's bulk snapshot face when the binding
|
|
7
|
+
# exposes it. These specs pin the ROW CONTRACT the binding must
|
|
8
|
+
# satisfy and the dispatch, so the binding PR can be verified without
|
|
9
|
+
# waiting for the native pin bump.
|
|
10
|
+
# A real lightweight struct standing in for the future binding
|
|
11
|
+
# element: responds to the bulk face with fixed rows, carries no
|
|
12
|
+
# behavior of its own.
|
|
13
|
+
SnapshotFaceElement = Struct.new(:rows) do
|
|
14
|
+
def namespace_declarations_snapshot
|
|
15
|
+
rows
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
RSpec.describe Lutaml::Xml::Leptris::PlanHydrator do
|
|
20
|
+
describe ".ns_data_from_snapshot_rows" do
|
|
21
|
+
it "builds the ns_data hash from pre-order snapshot rows" do
|
|
22
|
+
rows = [
|
|
23
|
+
{ path: [], prefix: nil, href: "urn:d" },
|
|
24
|
+
{ path: [], prefix: "a", href: "urn:a" },
|
|
25
|
+
{ path: ["c1"], prefix: "b", href: "urn:b" },
|
|
26
|
+
{ path: ["c2"], prefix: nil, href: "urn:d2" },
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
result = described_class.ns_data_from_snapshot_rows(rows)
|
|
30
|
+
|
|
31
|
+
expect(result).to eq(
|
|
32
|
+
[] => { default: { uri: "urn:d", prefix: nil,
|
|
33
|
+
format: :default },
|
|
34
|
+
"a" => { uri: "urn:a", prefix: "a", format: :prefix } },
|
|
35
|
+
["c1"] => { "b" => { uri: "urn:b", prefix: "b",
|
|
36
|
+
format: :prefix } },
|
|
37
|
+
["c2"] => { default: { uri: "urn:d2", prefix: nil,
|
|
38
|
+
format: :default } },
|
|
39
|
+
)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "returns an empty hash for a declaration-free subtree" do
|
|
43
|
+
expect(described_class.ns_data_from_snapshot_rows([])).to eq({})
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
describe "the snapshot face probe in collect_native_namespaces" do
|
|
48
|
+
it "prefers the bulk face when the binding exposes it" do
|
|
49
|
+
element = SnapshotFaceElement.new(
|
|
50
|
+
[{ path: ["x"], prefix: "p", href: "urn:p" }],
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
result = described_class.collect_native_namespaces(element)
|
|
54
|
+
|
|
55
|
+
expect(result).to eq(
|
|
56
|
+
["x"] => { "p" => { uri: "urn:p", prefix: "p",
|
|
57
|
+
format: :prefix } },
|
|
58
|
+
)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "tmpdir"
|
|
4
|
+
require "fileutils"
|
|
5
|
+
require_relative "../../../../spec_helper"
|
|
6
|
+
require "lutaml/xml/schema/xsd"
|
|
7
|
+
|
|
8
|
+
# #1051: an xs:import without a namespace attribute is legal
|
|
9
|
+
# (XSD 1.0 §3.13.2 — it imports a schema document with no target
|
|
10
|
+
# namespace). The schema walk read the attribute store unguarded, so
|
|
11
|
+
# a follow-up schema document carrying such an import crashed the
|
|
12
|
+
# parse with "undefined method 'value' for nil".
|
|
13
|
+
RSpec.describe "Xsd import without a namespace attribute" do
|
|
14
|
+
let(:dir) { Dir.mktmpdir }
|
|
15
|
+
|
|
16
|
+
before do
|
|
17
|
+
File.write(File.join(dir, "a.xsd"), <<~XSD)
|
|
18
|
+
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
|
19
|
+
<xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="b.xsd"/>
|
|
20
|
+
<xs:element name="root"/>
|
|
21
|
+
</xs:schema>
|
|
22
|
+
XSD
|
|
23
|
+
File.write(File.join(dir, "b.xsd"), <<~XSD)
|
|
24
|
+
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
|
25
|
+
<xs:import schemaLocation="c.xsd"/>
|
|
26
|
+
<xs:attribute name="lang" type="xs:language"/>
|
|
27
|
+
</xs:schema>
|
|
28
|
+
XSD
|
|
29
|
+
File.write(File.join(dir, "c.xsd"), <<~XSD)
|
|
30
|
+
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
|
31
|
+
<xs:element name="helper"/>
|
|
32
|
+
</xs:schema>
|
|
33
|
+
XSD
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
after { FileUtils.remove_entry(dir) }
|
|
37
|
+
|
|
38
|
+
it "parses the whole chain" do
|
|
39
|
+
parsed = Lutaml::Xml::Schema::Xsd.parse(
|
|
40
|
+
File.read(File.join(dir, "a.xsd")),
|
|
41
|
+
location: dir,
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
expect(parsed).to be_a(Lutaml::Xml::Schema::Xsd::Schema)
|
|
45
|
+
expect(parsed.imports.first.schema_path).to eq("b.xsd")
|
|
46
|
+
expect(parsed.import.first).to be_a(Lutaml::Xml::Schema::Xsd::Schema)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "keeps the namespace-less import unnamed" do
|
|
50
|
+
parsed = Lutaml::Xml::Schema::Xsd.parse(
|
|
51
|
+
<<~XSD,
|
|
52
|
+
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
|
53
|
+
<xs:import schemaLocation="c.xsd"/>
|
|
54
|
+
</xs:schema>
|
|
55
|
+
XSD
|
|
56
|
+
location: dir,
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
expect(parsed.imports.first.namespace).to be_nil
|
|
60
|
+
end
|
|
61
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lutaml-model
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.8.
|
|
4
|
+
version: 0.8.147
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
@@ -1990,6 +1990,7 @@ files:
|
|
|
1990
1990
|
- spec/lutaml/xml/general_namespace_spec.rb
|
|
1991
1991
|
- spec/lutaml/xml/html_entities_spec.rb
|
|
1992
1992
|
- spec/lutaml/xml/indent_spec.rb
|
|
1993
|
+
- spec/lutaml/xml/leptris/plan_hydrator_ns_snapshot_spec.rb
|
|
1993
1994
|
- spec/lutaml/xml/leptris_string_encoding_spec.rb
|
|
1994
1995
|
- spec/lutaml/xml/line_ending_spec.rb
|
|
1995
1996
|
- spec/lutaml/xml/mapping_finalization_guard_spec.rb
|
|
@@ -2054,6 +2055,7 @@ files:
|
|
|
2054
2055
|
- spec/lutaml/xml/schema/xsd/errors/suggestion_spec.rb
|
|
2055
2056
|
- spec/lutaml/xml/schema/xsd/file_validation_result_spec.rb
|
|
2056
2057
|
- spec/lutaml/xml/schema/xsd/glob_spec.rb
|
|
2058
|
+
- spec/lutaml/xml/schema/xsd/import_without_namespace_spec.rb
|
|
2057
2059
|
- spec/lutaml/xml/schema/xsd/keyref_refer_spec.rb
|
|
2058
2060
|
- spec/lutaml/xml/schema/xsd/liquid_methods/attribute_and_group_spec.rb
|
|
2059
2061
|
- spec/lutaml/xml/schema/xsd/liquid_methods/complex_type_spec.rb
|