lutaml-model 0.8.12 → 0.8.13
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/README.adoc +116 -103
- data/RELEASE_NOTES.adoc +3 -3
- data/benchmark/quick_benchmark.rb +2 -2
- data/benchmark/serialization_benchmark.rb +4 -4
- data/docs/_guides/advanced-mapping.adoc +1 -1
- data/docs/_guides/character-encoding.adoc +3 -3
- data/docs/_guides/missing-values-handling.adoc +6 -6
- data/docs/_guides/ooxml-examples.adoc +7 -7
- data/docs/_guides/opal.adoc +1 -1
- data/docs/_guides/value-transformations.adoc +7 -7
- data/docs/_guides/xml/namespace-presentation.adoc +1 -1
- data/docs/_guides/xml/namespace-semantics.adoc +15 -15
- data/docs/_guides/xml/type-namespaces.adoc +9 -9
- data/docs/_guides/xml-mapping.adoc +32 -26
- data/docs/_guides/xml-namespace-qualification.adoc +4 -4
- data/docs/_guides/xml-namespaces.adoc +2 -2
- data/docs/_guides/xml_mappings/04_xml_namespace_class.adoc +18 -18
- data/docs/_guides/xml_mappings/05_common_patterns.adoc +16 -16
- data/docs/_guides/xml_mappings/06_migration_guide.adoc +5 -5
- data/docs/_guides/xml_mappings/07_best_practices.adoc +11 -11
- data/docs/_migrations/0-8-0-namespace-restructuring.adoc +2 -2
- data/docs/_pages/attributes.adoc +2 -2
- data/docs/_pages/collections.adoc +26 -20
- data/docs/_pages/consolidation-mapping.adoc +4 -4
- data/docs/_pages/importable_models.adoc +14 -13
- data/docs/_pages/quick-start.adoc +1 -1
- data/docs/_pages/value_types.adoc +10 -10
- data/docs/_references/custom_registers.adoc +7 -7
- data/docs/_references/format-independent-features.adoc +4 -4
- data/docs/_references/instance-serialization.adoc +1 -1
- data/docs/_references/parent-root-context.adoc +3 -3
- data/docs/_tutorials/basic-model-definition.adoc +1 -1
- data/docs/_tutorials/first-xml-serialization.adoc +4 -4
- data/docs/_tutorials/lutaml-xml-architecture.adoc +4 -4
- data/docs/_tutorials/validation-basics.adoc +1 -1
- data/docs/_tutorials/working-with-collections.adoc +2 -2
- data/docs/_tutorials/xml-namespaces-basics.adoc +1 -1
- data/docs/_tutorials/xml-schema-primer-style-guide.adoc +29 -29
- data/docs/cli_compare.adoc +1 -1
- data/docs/index.adoc +1 -1
- data/docs/namespace-management.adoc +14 -14
- data/lib/lutaml/key_value/mapping.rb +31 -6
- data/lib/lutaml/model/collection.rb +11 -11
- data/lib/lutaml/model/error/no_root_mapping_error.rb +6 -5
- data/lib/lutaml/model/error/no_root_namespace_error.rb +6 -5
- data/lib/lutaml/model/error/type_only_mapping_error.rb +13 -0
- data/lib/lutaml/model/error/type_only_namespace_error.rb +12 -0
- data/lib/lutaml/model/version.rb +1 -1
- data/lib/lutaml/model.rb +3 -0
- data/lib/lutaml/xml/adapter/base_adapter.rb +0 -9
- data/lib/lutaml/xml/adapter/nokogiri_adapter.rb +0 -1
- data/lib/lutaml/xml/adapter/oga_adapter.rb +0 -1
- data/lib/lutaml/xml/adapter/ox_adapter.rb +0 -1
- data/lib/lutaml/xml/adapter/rexml_adapter.rb +0 -1
- data/lib/lutaml/xml/adapter/xml_serializer.rb +42 -22
- data/lib/lutaml/xml/adapter.rb +4 -0
- data/lib/lutaml/xml/builder/base.rb +64 -25
- data/lib/lutaml/xml/builder/nokogiri.rb +0 -2
- data/lib/lutaml/xml/builder/oga.rb +0 -2
- data/lib/lutaml/xml/builder/ox.rb +0 -2
- data/lib/lutaml/xml/builder/rexml.rb +0 -2
- data/lib/lutaml/xml/builder.rb +1 -0
- data/lib/lutaml/xml/configurable.rb +2 -2
- data/lib/lutaml/xml/declaration_handler.rb +3 -105
- data/lib/lutaml/xml/mapping.rb +3 -3
- data/lib/lutaml/xml/schema/xsd/documentation.rb +1 -1
- data/lib/lutaml/xml/serialization/collection_ext.rb +7 -7
- data/lib/lutaml/xml/serialization/format_conversion.rb +1 -1
- data/lib/lutaml/xml/serialization/instance_methods.rb +1 -1
- data/lib/lutaml/xml.rb +1 -2
- data/lib/tasks/memory_profile.rb +2 -2
- data/lib/tasks/performance_benchmark.rb +5 -5
- data/spec/lutaml/key_value/transformation/rule_compiler_spec.rb +1 -1
- data/spec/lutaml/key_value/transformation/value_serializer_spec.rb +1 -1
- data/spec/lutaml/model/attribute_collection_spec.rb +1 -1
- data/spec/lutaml/model/cli_spec.rb +1 -1
- data/spec/lutaml/model/collection_spec.rb +1 -1
- data/spec/lutaml/model/collection_validation_spec.rb +6 -6
- data/spec/lutaml/model/consolidation_spec.rb +8 -8
- data/spec/lutaml/model/custom_collection_spec.rb +3 -3
- data/spec/lutaml/model/default_register_spec.rb +23 -23
- data/spec/lutaml/model/delegation_spec.rb +3 -10
- data/spec/lutaml/model/derived_attribute_serialization_spec.rb +1 -1
- data/spec/lutaml/model/dynamic_attribute_spec.rb +2 -2
- data/spec/lutaml/model/enum_spec.rb +1 -1
- data/spec/lutaml/model/group_spec.rb +12 -12
- data/spec/lutaml/model/lazy_collection_spec.rb +4 -4
- data/spec/lutaml/model/mixed_content_spec.rb +2 -2
- data/spec/lutaml/model/namespace_versioning_spec.rb +4 -4
- data/spec/lutaml/model/processing_instruction_spec.rb +11 -11
- data/spec/lutaml/model/register_methods_spec.rb +2 -2
- data/spec/lutaml/model/render_empty_spec.rb +1 -1
- data/spec/lutaml/model/serialize_perf_guard_spec.rb +1 -1
- data/spec/lutaml/model/transform_dynamic_attributes_spec.rb +1 -1
- data/spec/lutaml/model/transformation_builder_spec.rb +2 -2
- data/spec/lutaml/model/xml_decoupling_spec.rb +3 -3
- data/spec/lutaml/model/xsd_patterns_spec.rb +2 -3
- data/spec/lutaml/xml/adapter/order_spec.rb +1 -1
- data/spec/lutaml/xml/clear_parse_state_spec.rb +1 -1
- data/spec/lutaml/xml/content_model_validation_spec.rb +4 -2
- data/spec/lutaml/xml/doubly_defined_namespace_spec.rb +5 -5
- data/spec/lutaml/xml/enhanced_mapping_spec.rb +2 -1
- data/spec/lutaml/xml/entity_fragmentation_spec.rb +5 -5
- data/spec/lutaml/xml/indent_spec.rb +109 -0
- data/spec/lutaml/xml/line_ending_spec.rb +66 -0
- data/spec/lutaml/xml/mapping_finalization_guard_spec.rb +2 -2
- data/spec/lutaml/xml/model_transform_guard_spec.rb +4 -4
- data/spec/lutaml/xml/namespace_alias_spec.rb +4 -4
- data/spec/lutaml/xml/namespace_aware_parsing_spec.rb +3 -3
- data/spec/lutaml/xml/namespace_bound_element_roundtrip_spec.rb +2 -2
- data/spec/lutaml/xml/namespace_format_preservation_spec.rb +1 -1
- data/spec/lutaml/xml/namespace_inheritance_spec.rb +3 -3
- data/spec/lutaml/xml/namespace_preservation_spec.rb +5 -5
- data/spec/lutaml/xml/opal_xml_spec.rb +8 -8
- data/spec/lutaml/xml/pipeline_integration_spec.rb +145 -0
- data/spec/lutaml/xml/schema_primer_spec.rb +5 -5
- data/spec/lutaml/xml/transformation_spec.rb +20 -20
- data/spec/lutaml/xml/type_namespace/collector_spec.rb +1 -1
- data/spec/lutaml/xml/type_namespace/planner_spec.rb +3 -3
- metadata +7 -2
|
@@ -13,7 +13,7 @@ RSpec.describe "Register-specific attribute methods" do
|
|
|
13
13
|
attribute :name, :string
|
|
14
14
|
|
|
15
15
|
xml do
|
|
16
|
-
|
|
16
|
+
element "Base"
|
|
17
17
|
map_element "Name", to: :name
|
|
18
18
|
end
|
|
19
19
|
end
|
|
@@ -25,7 +25,7 @@ RSpec.describe "Register-specific attribute methods" do
|
|
|
25
25
|
attribute :priority, :integer
|
|
26
26
|
|
|
27
27
|
xml do
|
|
28
|
-
|
|
28
|
+
element "Extension"
|
|
29
29
|
map_element "Version", to: :version
|
|
30
30
|
map_element "Priority", to: :priority
|
|
31
31
|
end
|
|
@@ -63,7 +63,7 @@ RSpec.describe Lutaml::Xml::TransformationBuilder do
|
|
|
63
63
|
attribute :name, :string
|
|
64
64
|
|
|
65
65
|
xml do
|
|
66
|
-
|
|
66
|
+
element "person"
|
|
67
67
|
map_element "name", to: :name
|
|
68
68
|
end
|
|
69
69
|
end
|
|
@@ -222,7 +222,7 @@ RSpec.describe "TransformationRegistry Builder Pattern" do
|
|
|
222
222
|
attribute :name, :string
|
|
223
223
|
|
|
224
224
|
xml do
|
|
225
|
-
|
|
225
|
+
element "person"
|
|
226
226
|
map_element "name", to: :name
|
|
227
227
|
end
|
|
228
228
|
|
|
@@ -55,7 +55,7 @@ RSpec.describe "XML decoupling from core model" do
|
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
xml do
|
|
58
|
-
|
|
58
|
+
element "item"
|
|
59
59
|
map_element "title", to: :title
|
|
60
60
|
map_element "count", to: :count
|
|
61
61
|
end
|
|
@@ -328,8 +328,8 @@ RSpec.describe "XML decoupling from core model" do
|
|
|
328
328
|
expect(Lutaml::Model::Collection).to respond_to(:collection_structured_format?)
|
|
329
329
|
end
|
|
330
330
|
|
|
331
|
-
it "Collection has
|
|
332
|
-
expect(Lutaml::Model::Collection).to respond_to(:
|
|
331
|
+
it "Collection has collection_unwrapped_to? hook" do
|
|
332
|
+
expect(Lutaml::Model::Collection).to respond_to(:collection_unwrapped_to?)
|
|
333
333
|
end
|
|
334
334
|
|
|
335
335
|
it "collection_structured_format? returns true for XML" do
|
|
@@ -196,7 +196,7 @@ RSpec.describe "XSD Three Pattern Architecture" do
|
|
|
196
196
|
expect(xsd1).to include('<complexType name="TestType">')
|
|
197
197
|
end
|
|
198
198
|
|
|
199
|
-
it "xsd_type does NOT auto-set
|
|
199
|
+
it "xsd_type does NOT auto-set type-only (NO MAGIC)" do
|
|
200
200
|
klass = Class.new(Lutaml::Model::Serializable) do
|
|
201
201
|
attribute :name, :string
|
|
202
202
|
|
|
@@ -208,9 +208,8 @@ RSpec.describe "XSD Three Pattern Architecture" do
|
|
|
208
208
|
end
|
|
209
209
|
|
|
210
210
|
mapping = klass.mappings_for(:xml)
|
|
211
|
-
# NO MAGIC: xsd_type doesn't set @no_root
|
|
212
|
-
expect(mapping.instance_variable_get(:@no_root)).to be_nil
|
|
213
211
|
# Model is a root model because element is declared
|
|
212
|
+
expect(mapping.no_element?).to be false
|
|
214
213
|
expect(mapping.no_root?).to be false
|
|
215
214
|
# Type name is still set
|
|
216
215
|
expect(mapping.type_name_value).to eq("TestType")
|
|
@@ -32,7 +32,8 @@ RSpec.describe "Content model validation" do
|
|
|
32
32
|
attribute :content, :string
|
|
33
33
|
|
|
34
34
|
xml do
|
|
35
|
-
|
|
35
|
+
element "test"
|
|
36
|
+
ordered
|
|
36
37
|
map_content to: :content
|
|
37
38
|
end
|
|
38
39
|
|
|
@@ -85,7 +86,8 @@ RSpec.describe "Content model validation" do
|
|
|
85
86
|
attribute :content, :string, collection: true
|
|
86
87
|
|
|
87
88
|
xml do
|
|
88
|
-
|
|
89
|
+
element "test"
|
|
90
|
+
mixed_content
|
|
89
91
|
map_content to: :content
|
|
90
92
|
end
|
|
91
93
|
|
|
@@ -22,7 +22,7 @@ RSpec.describe "Doubly-defined namespace prefixes" do
|
|
|
22
22
|
attribute :item, :string
|
|
23
23
|
|
|
24
24
|
xml do
|
|
25
|
-
|
|
25
|
+
element "root"
|
|
26
26
|
namespace ns
|
|
27
27
|
map_element "item", to: :item
|
|
28
28
|
end
|
|
@@ -171,7 +171,7 @@ RSpec.describe "Doubly-defined namespace prefixes" do
|
|
|
171
171
|
attribute :name, :string
|
|
172
172
|
|
|
173
173
|
xml do
|
|
174
|
-
|
|
174
|
+
element "Inner"
|
|
175
175
|
namespace ns
|
|
176
176
|
map_element "name", to: :name
|
|
177
177
|
end
|
|
@@ -185,7 +185,7 @@ RSpec.describe "Doubly-defined namespace prefixes" do
|
|
|
185
185
|
attribute :child, ic
|
|
186
186
|
|
|
187
187
|
xml do
|
|
188
|
-
|
|
188
|
+
element "Outer"
|
|
189
189
|
namespace ns
|
|
190
190
|
map_element "Inner", to: :child
|
|
191
191
|
end
|
|
@@ -269,7 +269,7 @@ RSpec.describe "Doubly-defined namespace prefixes" do
|
|
|
269
269
|
attribute :value, :string
|
|
270
270
|
|
|
271
271
|
xml do
|
|
272
|
-
|
|
272
|
+
element "child"
|
|
273
273
|
namespace ns
|
|
274
274
|
map_content to: :value
|
|
275
275
|
end
|
|
@@ -284,7 +284,7 @@ RSpec.describe "Doubly-defined namespace prefixes" do
|
|
|
284
284
|
attribute :child, cm
|
|
285
285
|
|
|
286
286
|
xml do
|
|
287
|
-
|
|
287
|
+
element "parent"
|
|
288
288
|
namespace ns
|
|
289
289
|
map_element "name", to: :name
|
|
290
290
|
map_element "child", to: :child
|
|
@@ -54,8 +54,9 @@ RSpec.describe "Enhanced XML Mapping Features" do
|
|
|
54
54
|
expect(mapping.root?).to be false
|
|
55
55
|
end
|
|
56
56
|
|
|
57
|
-
it "has
|
|
57
|
+
it "has no_element? return true for type-only models" do
|
|
58
58
|
mapping = model_class.mappings_for(:xml)
|
|
59
|
+
expect(mapping.no_element?).to be true
|
|
59
60
|
expect(mapping.no_root?).to be true
|
|
60
61
|
end
|
|
61
62
|
end
|
|
@@ -10,7 +10,7 @@ module EntityFragmentationSpec
|
|
|
10
10
|
attribute :content, :string
|
|
11
11
|
|
|
12
12
|
xml do
|
|
13
|
-
|
|
13
|
+
element "t"
|
|
14
14
|
namespace OfficeMathNamespace
|
|
15
15
|
map_content to: :content
|
|
16
16
|
end
|
|
@@ -20,7 +20,7 @@ module EntityFragmentationSpec
|
|
|
20
20
|
attribute :t, MathT
|
|
21
21
|
|
|
22
22
|
xml do
|
|
23
|
-
|
|
23
|
+
element "r"
|
|
24
24
|
namespace OfficeMathNamespace
|
|
25
25
|
map_element :t, to: :t
|
|
26
26
|
end
|
|
@@ -30,7 +30,7 @@ module EntityFragmentationSpec
|
|
|
30
30
|
attribute :r, MathR
|
|
31
31
|
|
|
32
32
|
xml do
|
|
33
|
-
|
|
33
|
+
element "oMathPara"
|
|
34
34
|
namespace OfficeMathNamespace
|
|
35
35
|
map_element :r, to: :r
|
|
36
36
|
end
|
|
@@ -219,7 +219,7 @@ RSpec.shared_examples "XML entity preservation" do |adapter_name|
|
|
|
219
219
|
element "paragraph"
|
|
220
220
|
mixed_content
|
|
221
221
|
|
|
222
|
-
map_content to: :content
|
|
222
|
+
map_content to: :content
|
|
223
223
|
map_element "em", to: :emphasis
|
|
224
224
|
end
|
|
225
225
|
end
|
|
@@ -496,7 +496,7 @@ RSpec.describe "XML Entity Fragmentation Issue #5" do
|
|
|
496
496
|
attribute :content, :string
|
|
497
497
|
|
|
498
498
|
xml do
|
|
499
|
-
|
|
499
|
+
element "text"
|
|
500
500
|
map_content to: :content
|
|
501
501
|
end
|
|
502
502
|
end
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
|
|
5
|
+
RSpec.describe "Indent configuration" do
|
|
6
|
+
before do
|
|
7
|
+
item_class = Class.new do
|
|
8
|
+
include Lutaml::Model::Serialize
|
|
9
|
+
|
|
10
|
+
attribute :name, :string
|
|
11
|
+
|
|
12
|
+
xml do
|
|
13
|
+
element "item"
|
|
14
|
+
map_element "name", to: :name
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
stub_const("IndentItem", item_class)
|
|
19
|
+
|
|
20
|
+
test_class = Class.new do
|
|
21
|
+
include Lutaml::Model::Serialize
|
|
22
|
+
|
|
23
|
+
attribute :title, :string
|
|
24
|
+
attribute :items, IndentItem, collection: true
|
|
25
|
+
|
|
26
|
+
xml do
|
|
27
|
+
element "container"
|
|
28
|
+
map_element "title", to: :title
|
|
29
|
+
map_element "item", to: :items
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
stub_const("IndentContainer", test_class)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
let(:model) do
|
|
37
|
+
IndentContainer.new(
|
|
38
|
+
title: "Test",
|
|
39
|
+
items: [IndentItem.new(name: "a"), IndentItem.new(name: "b")],
|
|
40
|
+
)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "uses default indent of 2 spaces" do
|
|
44
|
+
xml = model.to_xml
|
|
45
|
+
expect(xml).to include(" <title>Test</title>")
|
|
46
|
+
expect(xml).to include(" <item>")
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "produces compact output with indent: 0" do
|
|
50
|
+
xml = model.to_xml(indent: 0)
|
|
51
|
+
expect(xml).not_to include("\n ")
|
|
52
|
+
expect(xml).not_to include("\n ")
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it "uses 4-space indent when indent: 4" do
|
|
56
|
+
xml = model.to_xml(indent: 4)
|
|
57
|
+
expect(xml).to include(" <title>Test</title>")
|
|
58
|
+
expect(xml).to include(" <item>")
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it "nests consistently at multiple levels with indent: 4" do
|
|
62
|
+
nested_class = Class.new do
|
|
63
|
+
include Lutaml::Model::Serialize
|
|
64
|
+
|
|
65
|
+
attribute :label, :string
|
|
66
|
+
attribute :child, IndentItem
|
|
67
|
+
|
|
68
|
+
xml do
|
|
69
|
+
element "nested"
|
|
70
|
+
map_element "label", to: :label
|
|
71
|
+
map_element "item", to: :child
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
stub_const("IndentNested", nested_class)
|
|
76
|
+
|
|
77
|
+
container = Class.new do
|
|
78
|
+
include Lutaml::Model::Serialize
|
|
79
|
+
|
|
80
|
+
attribute :nested, IndentNested
|
|
81
|
+
|
|
82
|
+
xml do
|
|
83
|
+
element "root"
|
|
84
|
+
map_element "nested", to: :nested
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
stub_const("IndentRoot", container)
|
|
89
|
+
|
|
90
|
+
instance = IndentRoot.new(
|
|
91
|
+
nested: IndentNested.new(
|
|
92
|
+
label: "outer",
|
|
93
|
+
child: IndentItem.new(name: "inner"),
|
|
94
|
+
),
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
xml = instance.to_xml(indent: 4)
|
|
98
|
+
expect(xml).to include(" <nested>")
|
|
99
|
+
expect(xml).to include(" <label>outer</label>")
|
|
100
|
+
expect(xml).to include(" <item>")
|
|
101
|
+
expect(xml).to include(" <name>inner</name>")
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
it "preserves text content without extra whitespace" do
|
|
105
|
+
xml = model.to_xml
|
|
106
|
+
expect(xml).to include("<title>Test</title>")
|
|
107
|
+
expect(xml).to include("<name>a</name>")
|
|
108
|
+
end
|
|
109
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
|
|
5
|
+
RSpec.describe "Line ending configuration" do
|
|
6
|
+
before do
|
|
7
|
+
test_class = Class.new do
|
|
8
|
+
include Lutaml::Model::Serialize
|
|
9
|
+
|
|
10
|
+
attribute :title, :string
|
|
11
|
+
attribute :body, :string
|
|
12
|
+
|
|
13
|
+
xml do
|
|
14
|
+
element "article"
|
|
15
|
+
map_element "title", to: :title
|
|
16
|
+
map_element "body", to: :body
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
stub_const("LineEndingArticle", test_class)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
let(:model) { LineEndingArticle.new(title: "Test", body: "Content") }
|
|
24
|
+
|
|
25
|
+
it "uses LF (\\n) line endings by default" do
|
|
26
|
+
xml = model.to_xml
|
|
27
|
+
expect(xml).not_to include("\r\n")
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "produces CRLF when line_ending: CRLF is specified" do
|
|
31
|
+
xml = model.to_xml(line_ending: "\r\n")
|
|
32
|
+
lines = xml.split("\n", -1)
|
|
33
|
+
crlf_count = lines.count { |l| l.end_with?("\r") }
|
|
34
|
+
expect(crlf_count).to be > 0
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "applies line endings consistently across declaration and body" do
|
|
38
|
+
xml = model.to_xml(line_ending: "\r\n", declaration: true)
|
|
39
|
+
expect(xml.lines).to all(end_with("\r\n"))
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "preserves LF in round-trip" do
|
|
43
|
+
xml_in = "<article><title>Test</title><body>Content</body></article>"
|
|
44
|
+
parsed = LineEndingArticle.from_xml(xml_in)
|
|
45
|
+
xml_out = parsed.to_xml
|
|
46
|
+
expect(xml_out).not_to include("\r\n")
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "does not produce mixed line endings" do
|
|
50
|
+
xml = model.to_xml(line_ending: "\r\n")
|
|
51
|
+
crlf_positions = []
|
|
52
|
+
lf_only_positions = []
|
|
53
|
+
xml.each_char.with_index do |c, i|
|
|
54
|
+
next unless c == "\n"
|
|
55
|
+
|
|
56
|
+
prev = i > 0 ? xml[i - 1] : nil
|
|
57
|
+
if prev == "\r"
|
|
58
|
+
crlf_positions << i
|
|
59
|
+
else
|
|
60
|
+
lf_only_positions << i
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
# Either all newlines are CRLF or none are — no mixing
|
|
64
|
+
expect(lf_only_positions).to be_empty, "Mixed line endings found"
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -10,7 +10,7 @@ RSpec.describe "Mapping finalization cache guard specs" do
|
|
|
10
10
|
attribute :age, :integer
|
|
11
11
|
|
|
12
12
|
xml do
|
|
13
|
-
|
|
13
|
+
element "person"
|
|
14
14
|
map_element "name", to: :name
|
|
15
15
|
map_attribute "age", to: :age
|
|
16
16
|
end
|
|
@@ -52,7 +52,7 @@ RSpec.describe "Mapping finalization cache guard specs" do
|
|
|
52
52
|
attribute :email, :string
|
|
53
53
|
|
|
54
54
|
xml do
|
|
55
|
-
|
|
55
|
+
element "person"
|
|
56
56
|
map_element "email", to: :email
|
|
57
57
|
end
|
|
58
58
|
|
|
@@ -10,7 +10,7 @@ RSpec.describe "ModelTransform name conversion guard specs" do
|
|
|
10
10
|
attribute :ns_attr, :string
|
|
11
11
|
|
|
12
12
|
xml do
|
|
13
|
-
|
|
13
|
+
element "root"
|
|
14
14
|
map_element "name", to: :name
|
|
15
15
|
map_attribute "ex:attr", to: :ns_attr
|
|
16
16
|
end
|
|
@@ -53,7 +53,7 @@ RSpec.describe "ModelTransform name conversion guard specs" do
|
|
|
53
53
|
attribute :value, :string
|
|
54
54
|
|
|
55
55
|
xml do
|
|
56
|
-
|
|
56
|
+
element "nested"
|
|
57
57
|
map_content to: :value
|
|
58
58
|
end
|
|
59
59
|
|
|
@@ -66,7 +66,7 @@ RSpec.describe "ModelTransform name conversion guard specs" do
|
|
|
66
66
|
attribute :child, nested_class
|
|
67
67
|
|
|
68
68
|
xml do
|
|
69
|
-
|
|
69
|
+
element "parent"
|
|
70
70
|
map_element "child", to: :child
|
|
71
71
|
end
|
|
72
72
|
|
|
@@ -104,7 +104,7 @@ RSpec.describe "ModelTransform name conversion guard specs" do
|
|
|
104
104
|
attribute :b, :string
|
|
105
105
|
|
|
106
106
|
xml do
|
|
107
|
-
|
|
107
|
+
element "root"
|
|
108
108
|
map_attribute "ns:a", to: :a
|
|
109
109
|
map_attribute "ns:b", to: :b
|
|
110
110
|
end
|
|
@@ -99,7 +99,7 @@ RSpec.describe "Namespace alias support" do
|
|
|
99
99
|
attribute :item, :string
|
|
100
100
|
|
|
101
101
|
xml do
|
|
102
|
-
|
|
102
|
+
element "root"
|
|
103
103
|
namespace ns
|
|
104
104
|
map_element "item", to: :item
|
|
105
105
|
end
|
|
@@ -170,7 +170,7 @@ RSpec.describe "Namespace alias support" do
|
|
|
170
170
|
attribute :name, :string
|
|
171
171
|
|
|
172
172
|
xml do
|
|
173
|
-
|
|
173
|
+
element "Inner"
|
|
174
174
|
namespace ns
|
|
175
175
|
map_element "name", to: :name
|
|
176
176
|
end
|
|
@@ -184,7 +184,7 @@ RSpec.describe "Namespace alias support" do
|
|
|
184
184
|
attribute :child, ic
|
|
185
185
|
|
|
186
186
|
xml do
|
|
187
|
-
|
|
187
|
+
element "Outer"
|
|
188
188
|
namespace ns
|
|
189
189
|
map_element "Inner", to: :child
|
|
190
190
|
end
|
|
@@ -236,7 +236,7 @@ RSpec.describe "Namespace alias support" do
|
|
|
236
236
|
attribute :child_name, :string
|
|
237
237
|
|
|
238
238
|
xml do
|
|
239
|
-
|
|
239
|
+
element "Parent"
|
|
240
240
|
namespace pns
|
|
241
241
|
map_element "childName", to: :child_name
|
|
242
242
|
namespace cns
|
|
@@ -34,7 +34,7 @@ RSpec.describe "Namespace-Aware XML Parsing" do
|
|
|
34
34
|
|
|
35
35
|
xml do
|
|
36
36
|
namespace ns
|
|
37
|
-
|
|
37
|
+
element "Model"
|
|
38
38
|
map_element "Name", to: :name
|
|
39
39
|
map_element "Version", to: :version
|
|
40
40
|
end
|
|
@@ -49,7 +49,7 @@ RSpec.describe "Namespace-Aware XML Parsing" do
|
|
|
49
49
|
|
|
50
50
|
xml do
|
|
51
51
|
namespace ns
|
|
52
|
-
|
|
52
|
+
element "Model"
|
|
53
53
|
map_element "Title", to: :title
|
|
54
54
|
map_element "Version", to: :version
|
|
55
55
|
end
|
|
@@ -63,7 +63,7 @@ RSpec.describe "Namespace-Aware XML Parsing" do
|
|
|
63
63
|
|
|
64
64
|
xml do
|
|
65
65
|
namespace ns
|
|
66
|
-
|
|
66
|
+
element "Common"
|
|
67
67
|
map_element "Id", to: :id
|
|
68
68
|
end
|
|
69
69
|
end
|
|
@@ -107,7 +107,7 @@ RSpec.describe "Namespace-Aware Round-Trip Serialization" do
|
|
|
107
107
|
attribute :write_protection, :boolean
|
|
108
108
|
|
|
109
109
|
xml do
|
|
110
|
-
|
|
110
|
+
element "settings"
|
|
111
111
|
namespace w_ns
|
|
112
112
|
namespace_scope [w14_ns, w15_ns]
|
|
113
113
|
|
|
@@ -364,7 +364,7 @@ RSpec.describe "Namespace-Aware Round-Trip Serialization" do
|
|
|
364
364
|
attribute :author, :string
|
|
365
365
|
|
|
366
366
|
xml do
|
|
367
|
-
|
|
367
|
+
element "document"
|
|
368
368
|
namespace simple_ns
|
|
369
369
|
|
|
370
370
|
map_element "title", to: :title
|
|
@@ -234,7 +234,7 @@ RSpec.describe "XML namespace inheritance" do
|
|
|
234
234
|
# - Child's parent_ns_attr is in PARENT namespace (different from child) → MUST have prefix
|
|
235
235
|
# - Child's child_ns_attr is in CHILD namespace (same as child) → NO prefix (unqualified)
|
|
236
236
|
expected = <<~XML.chomp
|
|
237
|
-
<parent:parent xmlns:
|
|
237
|
+
<parent:parent xmlns:child="http://example.com/child" xmlns:parent="http://example.com/parent" child:child_ns_attr="value">
|
|
238
238
|
<child:child parent:parent_ns_attr="value" child_ns_attr="value">test</child:child>
|
|
239
239
|
</parent:parent>
|
|
240
240
|
XML
|
|
@@ -926,7 +926,7 @@ RSpec.describe "XML namespace inheritance" do
|
|
|
926
926
|
# have NO prefix (inherit from element's namespace context)
|
|
927
927
|
# Type namespace (child_ns_attr) is declared on root for efficiency
|
|
928
928
|
expected = <<~XML.chomp
|
|
929
|
-
<parent:collection xmlns:
|
|
929
|
+
<parent:collection xmlns:child="http://example.com/child" xmlns:parent="http://example.com/parent">
|
|
930
930
|
<parent:item parent_ns_attr="value1" child:child_ns_attr="value1">first</parent:item>
|
|
931
931
|
<parent:item parent_ns_attr="value2" child:child_ns_attr="value2">second</parent:item>
|
|
932
932
|
<parent:item parent_ns_attr="value3" child:child_ns_attr="value3">third</parent:item>
|
|
@@ -953,7 +953,7 @@ RSpec.describe "XML namespace inheritance" do
|
|
|
953
953
|
# W3C attributeFormDefault="unqualified": attributes in same namespace as element
|
|
954
954
|
# have NO prefix (inherit from element's namespace context)
|
|
955
955
|
expected = <<~XML.chomp
|
|
956
|
-
<parent:collection xmlns:
|
|
956
|
+
<parent:collection xmlns:child="http://example.com/child" xmlns:parent="http://example.com/parent">
|
|
957
957
|
<parent:item parent_ns_attr="value1" child:child_ns_attr="value1">first</parent:item>
|
|
958
958
|
<parent:item parent_ns_attr="value2" child:child_ns_attr="value2">second</parent:item>
|
|
959
959
|
<parent:item parent_ns_attr="value3" child:child_ns_attr="value3">third</parent:item>
|
|
@@ -256,7 +256,7 @@ RSpec.describe "Namespace Preservation Issue #3" do
|
|
|
256
256
|
attribute :title, :string
|
|
257
257
|
|
|
258
258
|
xml do
|
|
259
|
-
|
|
259
|
+
element "article"
|
|
260
260
|
namespace article_ns
|
|
261
261
|
map_element "title", to: :title
|
|
262
262
|
end
|
|
@@ -299,7 +299,7 @@ RSpec.describe "Namespace Preservation Issue #3" do
|
|
|
299
299
|
attribute :title, :string
|
|
300
300
|
|
|
301
301
|
xml do
|
|
302
|
-
|
|
302
|
+
element "article"
|
|
303
303
|
namespace article_ns
|
|
304
304
|
map_element "title", to: :title
|
|
305
305
|
end
|
|
@@ -340,7 +340,7 @@ RSpec.describe "Namespace Preservation Issue #3" do
|
|
|
340
340
|
attribute :exterior, :string
|
|
341
341
|
|
|
342
342
|
xml do
|
|
343
|
-
|
|
343
|
+
element "Polygon"
|
|
344
344
|
namespace gml_ns
|
|
345
345
|
map_element "exterior", to: :exterior
|
|
346
346
|
end
|
|
@@ -383,7 +383,7 @@ RSpec.describe "Namespace Preservation Issue #3" do
|
|
|
383
383
|
attribute :content, :string
|
|
384
384
|
|
|
385
385
|
xml do
|
|
386
|
-
|
|
386
|
+
element "child"
|
|
387
387
|
namespace child_ns
|
|
388
388
|
map_content to: :content
|
|
389
389
|
end
|
|
@@ -399,7 +399,7 @@ RSpec.describe "Namespace Preservation Issue #3" do
|
|
|
399
399
|
attribute :child, child_class
|
|
400
400
|
|
|
401
401
|
xml do
|
|
402
|
-
|
|
402
|
+
element "parent"
|
|
403
403
|
map_element "title", to: :title
|
|
404
404
|
map_element "child", to: :child
|
|
405
405
|
end
|