lutaml-model 0.8.108 → 0.8.110
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/attribute.rb +16 -0
- data/lib/lutaml/model/configuration.rb +5 -5
- data/lib/lutaml/model/serialize/format_conversion.rb +16 -1
- data/lib/lutaml/model/version.rb +1 -1
- data/lib/lutaml/xml/adapter/leptris_adapter.rb +1 -0
- data/spec/lutaml/model/adapter_resolver_configured_spec.rb +7 -7
- data/spec/lutaml/model/collection_strict_assignment_spec.rb +55 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a49c2cdf5702fe7400d2cc4439632340cf8abe4ed214219d9d53a3bbacff6943
|
|
4
|
+
data.tar.gz: 887431c911fa16aff6372c9c7c7addb034d0722f1ba11b0dfd28fb71bb4fb982
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f9c79f442e8be909743b4ecd1eaca9537d61be0d5925336507aa1869907c6795d68aac1a66b67c3fb2cedc0dab86bcab798b7850c3c41d7393a1f9301b862104
|
|
7
|
+
data.tar.gz: d03289efc62a1b6c3cd9c66b6114879a3e68dc05883f20aab395264c2db7c7f0487da4baf2cce95d40493485f238e914b9acb88d974b7638e54efca43f678a30
|
|
@@ -398,11 +398,27 @@ module Lutaml
|
|
|
398
398
|
# cast_items already returns a fresh array, so the plain-Array
|
|
399
399
|
# collection needs no re-wrap — build_collection's
|
|
400
400
|
# collection_class.new would copy it again.
|
|
401
|
+
assert_flat_collection_items!(items)
|
|
401
402
|
return items if !custom_collection? && collection_class == ::Array
|
|
402
403
|
|
|
403
404
|
build_collection(items, register: register)
|
|
404
405
|
end
|
|
405
406
|
|
|
407
|
+
# Fail loudly on nested arrays. A collection's declared element
|
|
408
|
+
# type never admits an Array as an item; the legacy
|
|
409
|
+
# build_collection flatten silently absorbed mis-spliced builder
|
|
410
|
+
# output (expressir#506 surfaced it three frames away in a
|
|
411
|
+
# formatter). The error must land at the assignment boundary.
|
|
412
|
+
def assert_flat_collection_items!(items)
|
|
413
|
+
return unless items.any?(::Array)
|
|
414
|
+
|
|
415
|
+
raise TypeError,
|
|
416
|
+
"collection '#{name}': item " \
|
|
417
|
+
"#{items.index { |item| item.is_a?(::Array) }} is an Array " \
|
|
418
|
+
"where the declared element type is expected; nested arrays " \
|
|
419
|
+
"are not flattened — splice list results before assignment"
|
|
420
|
+
end
|
|
421
|
+
|
|
406
422
|
# Plain Arrays count as list input. On singular attributes
|
|
407
423
|
# collection_instance? matches Arrays too (their collection class is
|
|
408
424
|
# Array), preserving the Array so strict cardinality can flag it.
|
|
@@ -37,11 +37,11 @@ module Lutaml
|
|
|
37
37
|
@conversion_cache = nil
|
|
38
38
|
@configured = false
|
|
39
39
|
@xml_plan_fast_path = true
|
|
40
|
-
# Opt-in until leptris#1743 lands: the native ordered lane
|
|
41
|
-
# runs away (28+ CPU-min / 14GB RSS on sts-ruby's
|
|
42
|
-
# ISO_13849-1 document) — flipping this on by default regressed
|
|
43
|
-
# the sts bench cell from 4m41s to a 10-minute kill.
|
|
44
|
-
@xml_plan_ordered_path = false
|
|
40
|
+
# Opt-in until leptris#1743 lands: the native ordered lane
|
|
41
|
+
# runs away (28+ CPU-min / 14GB RSS on sts-ruby's
|
|
42
|
+
# ISO_13849-1 document) — flipping this on by default regressed
|
|
43
|
+
# the sts bench cell from 4m41s to a 10-minute kill.
|
|
44
|
+
@xml_plan_ordered_path = false
|
|
45
45
|
@element_order_tracking = true
|
|
46
46
|
end
|
|
47
47
|
|
|
@@ -139,7 +139,13 @@ module Lutaml
|
|
|
139
139
|
plan = Lutaml::Xml::Leptris::PlanCompiler.compile(self, register)
|
|
140
140
|
return nil unless plan
|
|
141
141
|
|
|
142
|
-
|
|
142
|
+
# strict: the from_xml contract raises on malformed input —
|
|
143
|
+
# the FFI lane parses leniently by default and would answer a
|
|
144
|
+
# best-effort tree where every other adapter raises. The
|
|
145
|
+
# kwarg spellings vary by engine vintage (strict: landed
|
|
146
|
+
# after 1.9.353, recover: on 1.9.344+), so probe the resolved
|
|
147
|
+
# parse method and pass the strictest spelling it accepts.
|
|
148
|
+
root = ::Leptris::XML.parse(data.to_s, **leptris_strict_kwargs).root
|
|
143
149
|
return nil if root.nil?
|
|
144
150
|
return nil unless root.name == plan[:tree][:name]
|
|
145
151
|
|
|
@@ -154,6 +160,15 @@ module Lutaml
|
|
|
154
160
|
raise Lutaml::Model::InvalidFormatError.new(:xml, e.message)
|
|
155
161
|
end
|
|
156
162
|
|
|
163
|
+
def leptris_strict_kwargs
|
|
164
|
+
params = ::Leptris::XML.method(:parse).parameters
|
|
165
|
+
.map { |_, key| key }
|
|
166
|
+
kwargs = {}
|
|
167
|
+
kwargs[:recover] = false if params.include?(:recover)
|
|
168
|
+
kwargs[:strict] = true if params.include?(:strict)
|
|
169
|
+
kwargs
|
|
170
|
+
end
|
|
171
|
+
|
|
157
172
|
# Get list of error types that can be raised during format parsing.
|
|
158
173
|
# Core errors are always included; format-specific errors come from
|
|
159
174
|
# FormatRegistry registrations.
|
data/lib/lutaml/model/version.rb
CHANGED
|
@@ -49,13 +49,13 @@ RSpec.describe Lutaml::Model::AdapterResolver, ".adapter_for with a configured t
|
|
|
49
49
|
_stdout, stderr, status = Open3.capture3(RbConfig.ruby, "-I", "lib", "-e", probe)
|
|
50
50
|
expect(status).to be_success, stderr
|
|
51
51
|
end
|
|
52
|
-
end
|
|
53
52
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
53
|
+
describe "plan lane defaults" do
|
|
54
|
+
it "ships the ordered plan lane opt-in until leptris#1743 is fixed" do
|
|
55
|
+
# The native ordered lane runs away on sts-ruby's ISO_13849-1
|
|
56
|
+
# document (leptris#1743): 28+ CPU-min / 14 GB RSS vs 6.36s on the
|
|
57
|
+
# same parse with the lane off. Opt-in until the engine fix ships.
|
|
58
|
+
expect(Lutaml::Model::Config.instance.xml_plan_ordered_path).to be(false)
|
|
59
|
+
end
|
|
60
60
|
end
|
|
61
61
|
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
|
|
5
|
+
RSpec.describe "strict collection assignment" do
|
|
6
|
+
let(:node_class) do
|
|
7
|
+
Class.new(Lutaml::Model::Serializable) do
|
|
8
|
+
attribute :id, :string
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
let(:holder_class) do
|
|
13
|
+
Class.new(Lutaml::Model::Serializable) do
|
|
14
|
+
attribute :items, "Node", collection: true
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
before do
|
|
19
|
+
stub_const("Node", node_class)
|
|
20
|
+
stub_const("Holder", holder_class)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "raises at the constructor boundary" do
|
|
24
|
+
expect do
|
|
25
|
+
Holder.new(items: [[Node.new(id: "a")], Node.new(id: "b")])
|
|
26
|
+
end.to raise_error(Lutaml::Model::TypeError, /item 0 is an Array/)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "raises at the writer boundary" do
|
|
30
|
+
holder = Holder.new
|
|
31
|
+
expect do
|
|
32
|
+
holder.items = [Node.new, [Node.new]]
|
|
33
|
+
end.to raise_error(Lutaml::Model::TypeError, /item 1 is an Array/)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "raises for a custom collection class" do
|
|
37
|
+
custom = Class.new(Lutaml::Model::Collection) do
|
|
38
|
+
instances :node, "Node"
|
|
39
|
+
end
|
|
40
|
+
stub_const("NodeBag", custom)
|
|
41
|
+
wrapper = Class.new(Lutaml::Model::Serializable) do
|
|
42
|
+
attribute :bag, "NodeBag"
|
|
43
|
+
end
|
|
44
|
+
stub_const("BagHolder", wrapper)
|
|
45
|
+
|
|
46
|
+
expect do
|
|
47
|
+
BagHolder.new(bag: [[Node.new]])
|
|
48
|
+
end.to raise_error(Lutaml::Model::TypeError, /nested arrays are not flattened/)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "keeps flat assignment untouched" do
|
|
52
|
+
holder = Holder.new(items: [Node.new(id: "x")])
|
|
53
|
+
expect(holder.items.map(&:id)).to eq(["x"])
|
|
54
|
+
end
|
|
55
|
+
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.110
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
@@ -1724,6 +1724,7 @@ files:
|
|
|
1724
1724
|
- spec/lutaml/model/collection_single_value_coercion_spec.rb
|
|
1725
1725
|
- spec/lutaml/model/collection_spec.rb
|
|
1726
1726
|
- spec/lutaml/model/collection_state_nesting_spec.rb
|
|
1727
|
+
- spec/lutaml/model/collection_strict_assignment_spec.rb
|
|
1727
1728
|
- spec/lutaml/model/collection_validation_spec.rb
|
|
1728
1729
|
- spec/lutaml/model/comparable_model_spec.rb
|
|
1729
1730
|
- spec/lutaml/model/comparison_family_spec.rb
|