lutaml-model 0.8.112 → 0.8.113
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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: be72639a2ee2fd3c23219f19141d43386c4126fbef9fa79fdff322f90bb58660
|
|
4
|
+
data.tar.gz: 8c88a30cdda640eba02043ba87859a3cda864dcc23addf6a60aeccda63600dff
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c5bfd563e53d7664d038da01d677152f3143c510cb1fa2cc56e13d20d5f6f9009251c618091258d58f7b25c45b70ab7c53e6a1fdafdb3a91213da871e3fde875
|
|
7
|
+
data.tar.gz: a29144bc6c8cc8a3cf466e911b766df00718db916ddd3fc7127de00679f009ebe322407b9b74b509bf8fd4362005c7d85ce6076497d4b1676ab06648ab2a8213
|
|
@@ -47,6 +47,7 @@ module Lutaml
|
|
|
47
47
|
min_length
|
|
48
48
|
max_length
|
|
49
49
|
desc
|
|
50
|
+
singular_tolerance
|
|
50
51
|
].freeze
|
|
51
52
|
|
|
52
53
|
# Per-type-class memo of the custom from_xml/from_json probe used by #cast.
|
|
@@ -827,6 +828,17 @@ instance_object = nil)
|
|
|
827
828
|
end
|
|
828
829
|
end
|
|
829
830
|
|
|
831
|
+
# Singular-overflow tolerance (#971): ingest can hand a singular
|
|
832
|
+
# attribute a collection — relaton's upstream documents carry
|
|
833
|
+
# multiple <formattedref> elements per bibitem. With
|
|
834
|
+
# singular_tolerance: :first the leading value is kept instead of
|
|
835
|
+
# raising CollectionTrueMissingError; the default stays strict.
|
|
836
|
+
def tolerates_singular_overflow?(value)
|
|
837
|
+
!collection? && @options[:singular_tolerance] == :first &&
|
|
838
|
+
collection_instance?(value) &&
|
|
839
|
+
!value_policy.whole_value?(unresolved_type)
|
|
840
|
+
end
|
|
841
|
+
|
|
830
842
|
def valid_collection!(value, caller)
|
|
831
843
|
if collection_instance?(value) && !collection? &&
|
|
832
844
|
!value_policy.whole_value?(unresolved_type)
|
|
@@ -1041,6 +1053,12 @@ instance_object = nil)
|
|
|
1041
1053
|
"Use map_element \"name\", to: :#{name}, raw: :content instead."
|
|
1042
1054
|
end
|
|
1043
1055
|
@validations = @options[:validations]
|
|
1056
|
+
tolerance = @options[:singular_tolerance]
|
|
1057
|
+
unless tolerance.nil? || tolerance == :first
|
|
1058
|
+
raise ArgumentError,
|
|
1059
|
+
"Invalid singular_tolerance: #{tolerance.inspect} for " \
|
|
1060
|
+
"attribute '#{name}'. Supported: :first"
|
|
1061
|
+
end
|
|
1044
1062
|
set_default_for_collection if collection?
|
|
1045
1063
|
end
|
|
1046
1064
|
|
data/lib/lutaml/model/version.rb
CHANGED
|
@@ -479,6 +479,11 @@ module Lutaml
|
|
|
479
479
|
# violation entirely — check it while there is still someone to tell.
|
|
480
480
|
if !instance_is_serialize && attr && !attr.collection? &&
|
|
481
481
|
!rule.content_mapping?
|
|
482
|
+
# singular_tolerance: :first collapses an over-ingested
|
|
483
|
+
# collection to its leading value before the writer sees it
|
|
484
|
+
# (#971) — the reduced scalar then flows through
|
|
485
|
+
# deserialize and serializes as a single element.
|
|
486
|
+
value = value.first if attr.tolerates_singular_overflow?(value)
|
|
482
487
|
attr.valid_collection!(value, context)
|
|
483
488
|
end
|
|
484
489
|
rule.deserialize(instance, value, deserialize_attributes, context,
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
|
|
5
|
+
# #971: a singular attribute may ask ingest to keep the leading value
|
|
6
|
+
# when the mapper collects more than one element (relaton's upstream
|
|
7
|
+
# bibitems carry multiple <formattedref> elements). Default stays
|
|
8
|
+
# strict: the over-count remains a CollectionTrueMissingError.
|
|
9
|
+
RSpec.describe "singular_tolerance attribute option" do
|
|
10
|
+
let(:item_class) do
|
|
11
|
+
Class.new(Lutaml::Model::Serializable) do
|
|
12
|
+
attribute :content, :string
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
before do
|
|
17
|
+
stub_const("ToleranceItem", item_class)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
describe "option validation" do
|
|
21
|
+
it "accepts :first" do
|
|
22
|
+
expect do
|
|
23
|
+
Lutaml::Model::Attribute.new(:ref, "ToleranceItem",
|
|
24
|
+
singular_tolerance: :first)
|
|
25
|
+
end.not_to raise_error
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "accepts omission (strict default)" do
|
|
29
|
+
expect do
|
|
30
|
+
Lutaml::Model::Attribute.new(:ref, "ToleranceItem")
|
|
31
|
+
end.not_to raise_error
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "rejects unsupported tolerances" do
|
|
35
|
+
expect do
|
|
36
|
+
Lutaml::Model::Attribute.new(:ref, "ToleranceItem",
|
|
37
|
+
singular_tolerance: :last)
|
|
38
|
+
end.to raise_error(ArgumentError, /singular_tolerance: :last/)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
describe "#tolerates_singular_overflow?" do
|
|
43
|
+
let(:tolerant) do
|
|
44
|
+
Lutaml::Model::Attribute.new(:ref, "ToleranceItem",
|
|
45
|
+
singular_tolerance: :first)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
let(:strict) { Lutaml::Model::Attribute.new(:ref, "ToleranceItem") }
|
|
49
|
+
|
|
50
|
+
let(:collection_attr) do
|
|
51
|
+
Lutaml::Model::Attribute.new(:refs, "ToleranceItem",
|
|
52
|
+
collection: true,
|
|
53
|
+
singular_tolerance: :first)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "is true for an over-ingested collection on a tolerant singular" do
|
|
57
|
+
expect(tolerant.tolerates_singular_overflow?([1, 2])).to be(true)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it "is false without the option" do
|
|
61
|
+
expect(strict.tolerates_singular_overflow?([1, 2])).to be(false)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it "is false for a scalar on a tolerant singular" do
|
|
65
|
+
expect(tolerant.tolerates_singular_overflow?(1)).to be(false)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it "is false for a collection attribute — the option does not apply" do
|
|
69
|
+
expect(collection_attr.tolerates_singular_overflow?([1, 2])).to be(false)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
describe "strict default" do
|
|
74
|
+
it "still raises CollectionTrueMissingError on over-ingest" do
|
|
75
|
+
attr = Lutaml::Model::Attribute.new(:ref, "ToleranceItem")
|
|
76
|
+
|
|
77
|
+
expect do
|
|
78
|
+
attr.valid_collection!([item_class.new, item_class.new], String)
|
|
79
|
+
end.to raise_error(Lutaml::Model::CollectionTrueMissingError)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
describe "tolerant ingest" do
|
|
84
|
+
it "lets valid_collection! pass after the transform reduces to first" do
|
|
85
|
+
attr = Lutaml::Model::Attribute.new(:ref, "ToleranceItem",
|
|
86
|
+
singular_tolerance: :first)
|
|
87
|
+
value = [item_class.new, item_class.new]
|
|
88
|
+
|
|
89
|
+
reduced = value.first if attr.tolerates_singular_overflow?(value)
|
|
90
|
+
expect(attr.valid_collection!(reduced, String)).to be(true)
|
|
91
|
+
expect(reduced).to eq(value.first)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
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.113
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-10-
|
|
11
|
+
date: 2026-10-18 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: base64
|
|
@@ -1824,6 +1824,7 @@ files:
|
|
|
1824
1824
|
- spec/lutaml/model/serialize_perf_guard_spec.rb
|
|
1825
1825
|
- spec/lutaml/model/services/transformer_spec.rb
|
|
1826
1826
|
- spec/lutaml/model/simple_model_spec.rb
|
|
1827
|
+
- spec/lutaml/model/singular_tolerance_spec.rb
|
|
1827
1828
|
- spec/lutaml/model/store_spec.rb
|
|
1828
1829
|
- spec/lutaml/model/toml_adapter_spec.rb
|
|
1829
1830
|
- spec/lutaml/model/toml_spec.rb
|