lutaml-model 0.8.16 → 0.8.18
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/.github/workflows/downstream-performance.yml +27 -1
- data/.github/workflows/js-pr-check.yml +102 -0
- data/.github/workflows/js-sync.yml +51 -0
- data/.github/workflows/opal.yml +26 -6
- data/.github/workflows/performance.yml +32 -7
- data/.github/workflows/rake.yml +78 -32
- data/.github/workflows/release.yml +0 -3
- data/.gitmodules +6 -0
- data/.rubocop_todo.yml +76 -12
- data/Gemfile +16 -1
- data/README.adoc +267 -0
- data/Rakefile +166 -4
- data/docs/_guides/schema-import.adoc +42 -0
- data/docs/_guides/xml/namespace-semantics.adoc +2 -0
- data/docs/_guides/xml-mapping.adoc +21 -0
- data/docs/_guides/xml-namespace-qualification.adoc +142 -0
- data/docs/_pages/validation.adoc +65 -0
- data/docs/_tutorials/xml-element-attribute-namespace-guide.adoc +2 -0
- data/docs/_tutorials/xml-schema-primer-style-guide.adoc +2 -0
- data/docs/namespace-management.adoc +2 -0
- data/docs/xml-schema-qualification.md +6 -0
- data/lib/compat/opal/generate_boot.rb +123 -0
- data/lib/compat/opal/js_bundle_entry.rb +42 -0
- data/lib/compat/opal/lutaml_model_boot.rb +497 -0
- data/lib/compat/opal/moxml_boot.rb +68 -0
- data/lib/compat/opal/yaml_compat.rb +32 -0
- data/lib/lutaml/json.rb +1 -1
- data/lib/lutaml/jsonld.rb +1 -4
- data/lib/lutaml/key_value/transform.rb +3 -8
- data/lib/lutaml/key_value/transformation/value_serializer.rb +14 -1
- data/lib/lutaml/key_value/transformation.rb +17 -5
- data/lib/lutaml/model/adapter_resolver.rb +2 -2
- data/lib/lutaml/model/attribute.rb +88 -11
- data/lib/lutaml/model/cached_type_resolver.rb +1 -1
- data/lib/lutaml/model/choice.rb +34 -0
- data/lib/lutaml/model/compiled_rule.rb +7 -0
- data/lib/lutaml/model/error/union_schema_unsupported_error.rb +11 -0
- data/lib/lutaml/model/global_context.rb +11 -8
- data/lib/lutaml/model/instrumentation.rb +2 -2
- data/lib/lutaml/model/mapping/mapping_rule.rb +0 -6
- data/lib/lutaml/model/register.rb +2 -2
- data/lib/lutaml/model/runtime_compatibility.rb +50 -0
- data/lib/lutaml/model/schema/class_loader.rb +58 -0
- data/lib/lutaml/model/schema/compiled_output.rb +83 -0
- data/lib/lutaml/model/schema/definitions/attribute.rb +32 -0
- data/lib/lutaml/model/schema/definitions/choice.rb +20 -0
- data/lib/lutaml/model/schema/definitions/facet.rb +40 -0
- data/lib/lutaml/model/schema/definitions/group_import.rb +22 -0
- data/lib/lutaml/model/schema/definitions/member_walk.rb +33 -0
- data/lib/lutaml/model/schema/definitions/model.rb +40 -0
- data/lib/lutaml/model/schema/definitions/namespace.rb +23 -0
- data/lib/lutaml/model/schema/definitions/restricted_type.rb +30 -0
- data/lib/lutaml/model/schema/definitions/sequence.rb +19 -0
- data/lib/lutaml/model/schema/definitions/simple_content.rb +22 -0
- data/lib/lutaml/model/schema/definitions/transform_facet.rb +21 -0
- data/lib/lutaml/model/schema/definitions/type_ref.rb +20 -0
- data/lib/lutaml/model/schema/definitions/union_type.rb +28 -0
- data/lib/lutaml/model/schema/definitions/xml_root.rb +20 -0
- data/lib/lutaml/model/schema/definitions.rb +24 -0
- data/lib/lutaml/model/schema/file_writer.rb +70 -0
- data/lib/lutaml/model/schema/generator/definitions_collection.rb +16 -2
- data/lib/lutaml/model/schema/generator/property.rb +21 -4
- data/lib/lutaml/model/schema/module_nesting.rb +31 -0
- data/lib/lutaml/model/schema/namespace_naming.rb +46 -0
- data/lib/lutaml/model/schema/registry_generator.rb +115 -0
- data/lib/lutaml/model/schema/renderers/base.rb +40 -0
- data/lib/lutaml/model/schema/renderers/mappings.rb +72 -0
- data/lib/lutaml/model/schema/renderers/member_decls.rb +115 -0
- data/lib/lutaml/model/schema/renderers/model.rb +121 -0
- data/lib/lutaml/model/schema/renderers/namespace.rb +30 -0
- data/lib/lutaml/model/schema/renderers/registration.rb +64 -0
- data/lib/lutaml/model/schema/renderers/required_files_calculator.rb +93 -0
- data/lib/lutaml/model/schema/renderers/restricted_type.rb +88 -0
- data/lib/lutaml/model/schema/renderers/union.rb +83 -0
- data/lib/lutaml/model/schema/renderers.rb +19 -0
- data/lib/lutaml/model/schema/rnc_compiler/source_resolver.rb +47 -0
- data/lib/lutaml/model/schema/rnc_compiler.rb +62 -0
- data/lib/lutaml/model/schema/rng_compiler/define_classifier.rb +91 -0
- data/lib/lutaml/model/schema/rng_compiler/element_visitor.rb +392 -0
- data/lib/lutaml/model/schema/rng_compiler/member_collector.rb +30 -0
- data/lib/lutaml/model/schema/rng_compiler/rng_helpers.rb +152 -0
- data/lib/lutaml/model/schema/rng_compiler/value_type_resolver.rb +125 -0
- data/lib/lutaml/model/schema/rng_compiler.rb +220 -0
- data/lib/lutaml/model/schema/templates.rb +162 -0
- data/lib/lutaml/model/schema/xml_compiler/element_order.rb +41 -0
- data/lib/lutaml/model/schema/xml_compiler/registry_generator.rb +31 -107
- data/lib/lutaml/model/schema/xml_compiler/spec_builder/complex_types.rb +191 -0
- data/lib/lutaml/model/schema/xml_compiler/spec_builder/members.rb +216 -0
- data/lib/lutaml/model/schema/xml_compiler/spec_builder/simple_types.rb +153 -0
- data/lib/lutaml/model/schema/xml_compiler/spec_builder.rb +167 -0
- data/lib/lutaml/model/schema/xml_compiler/supported_data_types.rb +87 -0
- data/lib/lutaml/model/schema/xml_compiler.rb +38 -517
- data/lib/lutaml/model/schema.rb +19 -0
- data/lib/lutaml/model/serialize/attribute_definition.rb +14 -2
- data/lib/lutaml/model/serialize/builder.rb +15 -2
- data/lib/lutaml/model/serialize/value_mapping.rb +9 -57
- data/lib/lutaml/model/serialize.rb +6 -9
- data/lib/lutaml/model/services/rule_value_extractor.rb +2 -3
- data/lib/lutaml/model/services.rb +0 -2
- data/lib/lutaml/model/store.rb +2 -1
- data/lib/lutaml/model/toml.rb +1 -1
- data/lib/lutaml/model/transform.rb +17 -39
- data/lib/lutaml/model/transformation_registry.rb +1 -1
- data/lib/lutaml/model/type.rb +1 -0
- data/lib/lutaml/model/union.rb +320 -0
- data/lib/lutaml/model/utils.rb +6 -0
- data/lib/lutaml/model/validation.rb +1 -4
- data/lib/lutaml/model/version.rb +1 -1
- data/lib/lutaml/model.rb +19 -0
- data/lib/lutaml/{jsonld → rdf}/context.rb +1 -1
- data/lib/lutaml/{jsonld/transform.rb → rdf/linked_data_transform.rb} +33 -35
- data/lib/lutaml/{jsonld → rdf}/term_definition.rb +1 -1
- data/lib/lutaml/rdf.rb +3 -0
- data/lib/lutaml/toml.rb +1 -1
- data/lib/lutaml/xml/adapter.rb +1 -1
- data/lib/lutaml/xml/adapter_element.rb +2 -2
- data/lib/lutaml/xml/adapter_loader.rb +1 -1
- data/lib/lutaml/xml/builder/base.rb +1 -1
- data/lib/lutaml/xml/builder.rb +1 -1
- data/lib/lutaml/xml/error/schema_validation_error.rb +25 -0
- data/lib/lutaml/xml/model_transform.rb +5 -1
- data/lib/lutaml/xml/schema/relaxng_schema.rb +5 -0
- data/lib/lutaml/xml/schema/xsd_schema.rb +4 -0
- data/lib/lutaml/xml/serialization/format_conversion.rb +48 -0
- data/lib/lutaml/xml/serialization/instance_methods.rb +13 -0
- data/lib/lutaml/xml/transformation/element_builder.rb +59 -31
- data/lib/lutaml/xml/transformation/ordered_applier.rb +6 -0
- data/lib/lutaml/xml/xsd_validator.rb +66 -0
- data/lib/lutaml/xml.rb +53 -12
- data/lib/lutaml/yamlld/adapter.rb +25 -0
- data/lib/lutaml/yamlld.rb +25 -0
- data/lutaml-model.gemspec +4 -2
- data/spec/fixtures/xml/schema/rnc/address_book.rnc +15 -0
- data/spec/fixtures/xml/schema/rnc/book_features.rnc +18 -0
- data/spec/fixtures/xml/schema/rnc/includes/book.rnc +6 -0
- data/spec/fixtures/xml/schema/rnc/includes/circular_a.rnc +8 -0
- data/spec/fixtures/xml/schema/rnc/includes/circular_b.rnc +8 -0
- data/spec/fixtures/xml/schema/rnc/includes/library.rnc +8 -0
- data/spec/fixtures/xml/schema/rng/address_book.rng +16 -0
- data/spec/fixtures/xml/schema/rng/book.rng +27 -0
- data/spec/fixtures/xml/schema/rng/fixed_value.rng +11 -0
- data/spec/fixtures/xml/schema/rng/fragment_in_choice.rng +30 -0
- data/spec/fixtures/xml/schema/rng/full_name.rng +39 -0
- data/spec/fixtures/xml/schema/rng/integer_range.rng +32 -0
- data/spec/fixtures/xml/schema/rng/list_type.rng +12 -0
- data/spec/fixtures/xml/schema/rng/namespaced.rng +9 -0
- data/spec/fixtures/xml/schema/rng/paragraph.rng +13 -0
- data/spec/fixtures/xml/schema/rng/person.rng +23 -0
- data/spec/fixtures/xml/schema/rng/union.rng +14 -0
- data/spec/fixtures/xml/validate_xml_with_address.xsd +13 -0
- data/spec/fixtures/xml/validate_xml_with_contact.xsd +11 -0
- data/spec/fixtures/xml/validate_xml_with_person.xsd +11 -0
- data/spec/fixtures/xml/validate_xml_with_person_strict.xsd +17 -0
- data/spec/fixtures/xml/validate_xml_with_product.xsd +37 -0
- data/spec/lutaml/integration/multi_format_spec.rb +23 -0
- data/spec/lutaml/model/attribute_apply_value_map_spec.rb +134 -0
- data/spec/lutaml/model/attribute_spec.rb +177 -13
- data/spec/lutaml/model/boot_manifest_spec.rb +30 -0
- data/spec/lutaml/model/choice_restrict_spec.rb +225 -0
- data/spec/lutaml/model/collection_spec.rb +18 -0
- data/spec/lutaml/model/custom_model_spec.rb +4 -4
- data/spec/lutaml/model/mixed_content_spec.rb +173 -2
- data/spec/lutaml/model/multiple_mapping_spec.rb +4 -4
- data/spec/lutaml/model/opal_smoke_spec.rb +67 -2
- data/spec/lutaml/model/ordered_content_spec.rb +33 -3
- data/spec/lutaml/model/raw_element_spec.rb +125 -0
- data/spec/lutaml/model/rule_value_extractor_spec.rb +7 -14
- data/spec/lutaml/model/runtime_compatibility_spec.rb +25 -0
- data/spec/lutaml/model/schema/renderers/model_spec.rb +149 -0
- data/spec/lutaml/model/schema/renderers/namespace_spec.rb +36 -0
- data/spec/lutaml/model/schema/renderers/restricted_type_spec.rb +75 -0
- data/spec/lutaml/model/schema/renderers/union_spec.rb +58 -0
- data/spec/lutaml/model/transform_apply_value_map_spec.rb +64 -0
- data/spec/lutaml/model/uninitialized_class_spec.rb +1 -1
- data/spec/lutaml/model/union_attribute_spec.rb +658 -0
- data/spec/lutaml/model/union_spec.rb +257 -0
- data/spec/lutaml/model/utils_spec.rb +14 -0
- data/spec/lutaml/model/xsd_form_default_patterns_spec.rb +2 -2
- data/spec/lutaml/model/xsd_patterns_spec.rb +4 -4
- data/spec/lutaml/{jsonld → rdf}/context_spec.rb +2 -2
- data/spec/lutaml/{jsonld/transform_spec.rb → rdf/linked_data_transform_spec.rb} +15 -1
- data/spec/lutaml/{jsonld → rdf}/term_definition_spec.rb +2 -2
- data/spec/lutaml/turtle/transform_spec.rb +2 -2
- data/spec/lutaml/xml/enhanced_mapping_spec.rb +230 -1
- data/spec/lutaml/xml/mapping_spec.rb +4 -4
- data/spec/lutaml/xml/namespace_placement_spec.rb +11 -8
- data/spec/lutaml/xml/namespace_three_phase_spec.rb +1 -1
- data/spec/lutaml/xml/opal_xml_spec.rb +22 -20
- data/spec/lutaml/xml/prefix_control_spec.rb +4 -4
- data/spec/lutaml/xml/schema/compiler_spec.rb +21 -4
- data/spec/lutaml/xml/schema/rnc_compiler_spec.rb +404 -0
- data/spec/lutaml/xml/schema/rng_compiler_spec.rb +893 -0
- data/spec/lutaml/xml/serializable_namespace_spec.rb +6 -6
- data/spec/lutaml/xml/type_namespace_examples_spec.rb +1 -1
- data/spec/lutaml/xml/type_namespace_integration_spec.rb +3 -3
- data/spec/lutaml/xml/validate_xml_with_constructs_spec.rb +222 -0
- data/spec/lutaml/xml/validate_xml_with_spec.rb +186 -0
- data/spec/lutaml/yamlld/adapter_spec.rb +56 -0
- data/spec/lutaml/yamlld/registration_spec.rb +33 -0
- data/spec/spec_helper.rb +28 -11
- data/spec/support/opal.rb +5 -2
- metadata +108 -37
- data/lib/lutaml/model/schema/xml_compiler/attribute.rb +0 -106
- data/lib/lutaml/model/schema/xml_compiler/attribute_group.rb +0 -47
- data/lib/lutaml/model/schema/xml_compiler/choice.rb +0 -67
- data/lib/lutaml/model/schema/xml_compiler/complex_content.rb +0 -27
- data/lib/lutaml/model/schema/xml_compiler/complex_content_restriction.rb +0 -34
- data/lib/lutaml/model/schema/xml_compiler/complex_type.rb +0 -173
- data/lib/lutaml/model/schema/xml_compiler/element.rb +0 -121
- data/lib/lutaml/model/schema/xml_compiler/group.rb +0 -113
- data/lib/lutaml/model/schema/xml_compiler/restriction.rb +0 -104
- data/lib/lutaml/model/schema/xml_compiler/sequence.rb +0 -52
- data/lib/lutaml/model/schema/xml_compiler/simple_content.rb +0 -40
- data/lib/lutaml/model/schema/xml_compiler/simple_type.rb +0 -265
- data/lib/lutaml/model/schema/xml_compiler/xml_namespace_class.rb +0 -110
- data/lib/lutaml/model/services/default_value_resolver.rb +0 -60
- data/spec/lutaml/model/services/default_value_resolver_spec.rb +0 -162
- data/spec/lutaml/xml/schema/compiler/attribute_group_spec.rb +0 -71
- data/spec/lutaml/xml/schema/compiler/attribute_spec.rb +0 -67
- data/spec/lutaml/xml/schema/compiler/choice_spec.rb +0 -74
- data/spec/lutaml/xml/schema/compiler/complex_content_restriction_spec.rb +0 -60
- data/spec/lutaml/xml/schema/compiler/complex_content_spec.rb +0 -41
- data/spec/lutaml/xml/schema/compiler/complex_type_spec.rb +0 -202
- data/spec/lutaml/xml/schema/compiler/element_spec.rb +0 -68
- data/spec/lutaml/xml/schema/compiler/group_spec.rb +0 -90
- data/spec/lutaml/xml/schema/compiler/restriction_spec.rb +0 -77
- data/spec/lutaml/xml/schema/compiler/sequence_spec.rb +0 -65
- data/spec/lutaml/xml/schema/compiler/simple_content_spec.rb +0 -61
- data/spec/lutaml/xml/schema/compiler/simple_type_spec.rb +0 -184
|
@@ -22,7 +22,7 @@ RSpec.describe Lutaml::Model::Serializable, "namespace directive" do
|
|
|
22
22
|
model_class = Class.new do
|
|
23
23
|
include Lutaml::Model::Serialize
|
|
24
24
|
end
|
|
25
|
-
model_class.namespace(test_namespace)
|
|
25
|
+
expect { model_class.namespace(test_namespace) }.to output.to_stderr
|
|
26
26
|
|
|
27
27
|
expect(model_class.namespace).to eq(test_namespace)
|
|
28
28
|
end
|
|
@@ -49,7 +49,7 @@ RSpec.describe Lutaml::Model::Serializable, "namespace directive" do
|
|
|
49
49
|
model_class = Class.new do
|
|
50
50
|
include Lutaml::Model::Serialize
|
|
51
51
|
end
|
|
52
|
-
model_class.namespace(test_namespace)
|
|
52
|
+
expect { model_class.namespace(test_namespace) }.to output.to_stderr
|
|
53
53
|
model_class.namespace(other_namespace)
|
|
54
54
|
|
|
55
55
|
expect(model_class.namespace).to eq(other_namespace)
|
|
@@ -61,7 +61,7 @@ RSpec.describe Lutaml::Model::Serializable, "namespace directive" do
|
|
|
61
61
|
model_class = Class.new do
|
|
62
62
|
include Lutaml::Model::Serialize
|
|
63
63
|
end
|
|
64
|
-
model_class.namespace(test_namespace)
|
|
64
|
+
expect { model_class.namespace(test_namespace) }.to output.to_stderr
|
|
65
65
|
|
|
66
66
|
expect(model_class.namespace_uri).to eq("https://example.com/model")
|
|
67
67
|
end
|
|
@@ -80,7 +80,7 @@ RSpec.describe Lutaml::Model::Serializable, "namespace directive" do
|
|
|
80
80
|
model_class = Class.new do
|
|
81
81
|
include Lutaml::Model::Serialize
|
|
82
82
|
end
|
|
83
|
-
model_class.namespace(test_namespace)
|
|
83
|
+
expect { model_class.namespace(test_namespace) }.to output.to_stderr
|
|
84
84
|
|
|
85
85
|
expect(model_class.namespace_prefix).to eq("model")
|
|
86
86
|
end
|
|
@@ -103,7 +103,7 @@ RSpec.describe Lutaml::Model::Serializable, "namespace directive" do
|
|
|
103
103
|
attribute :value, :integer
|
|
104
104
|
end
|
|
105
105
|
|
|
106
|
-
model_class.namespace(test_namespace)
|
|
106
|
+
expect { model_class.namespace(test_namespace) }.to output.to_stderr
|
|
107
107
|
|
|
108
108
|
expect(model_class.namespace).to eq(test_namespace)
|
|
109
109
|
expect(model_class.attributes.keys).to include(:name, :value)
|
|
@@ -113,7 +113,7 @@ RSpec.describe Lutaml::Model::Serializable, "namespace directive" do
|
|
|
113
113
|
parent_class = Class.new do
|
|
114
114
|
include Lutaml::Model::Serialize
|
|
115
115
|
end
|
|
116
|
-
parent_class.namespace(test_namespace)
|
|
116
|
+
expect { parent_class.namespace(test_namespace) }.to output.to_stderr
|
|
117
117
|
|
|
118
118
|
child_class = Class.new(parent_class)
|
|
119
119
|
|
|
@@ -453,7 +453,7 @@ RSpec.describe "Type Namespace Examples" do
|
|
|
453
453
|
serialized = props.to_xml
|
|
454
454
|
|
|
455
455
|
# xsi:type attribute should use xsi: namespace from XsiTypeType
|
|
456
|
-
expect(serialized).to
|
|
456
|
+
expect(serialized).to include('xsi:type="dcterms:W3CDTF"')
|
|
457
457
|
end
|
|
458
458
|
|
|
459
459
|
it "handles multiple Type namespaces in single document" do
|
|
@@ -189,8 +189,8 @@ RSpec.describe "Type-level namespace integration" do
|
|
|
189
189
|
expect(xml).to include('id="doc1"')
|
|
190
190
|
expect(xml).to include('title="Test"')
|
|
191
191
|
# Should not have any namespace prefix
|
|
192
|
-
expect(xml).not_to
|
|
193
|
-
expect(xml).not_to
|
|
192
|
+
expect(xml).not_to include(":id=")
|
|
193
|
+
expect(xml).not_to include(":title=")
|
|
194
194
|
end
|
|
195
195
|
end
|
|
196
196
|
|
|
@@ -268,11 +268,11 @@ RSpec.describe "Type-level namespace integration" do
|
|
|
268
268
|
document_class = Class.new do
|
|
269
269
|
include Lutaml::Model::Serialize
|
|
270
270
|
|
|
271
|
-
namespace model_namespace
|
|
272
271
|
attribute :special_field, special_type
|
|
273
272
|
|
|
274
273
|
xml do
|
|
275
274
|
element "document"
|
|
275
|
+
namespace model_namespace
|
|
276
276
|
map_element "special_field", to: :special_field
|
|
277
277
|
end
|
|
278
278
|
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
|
|
5
|
+
RSpec.describe "validate_xml_with XSD constructs" do
|
|
6
|
+
def fixture_path(name)
|
|
7
|
+
File.expand_path("../../fixtures/xml/#{name}", __dir__)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
describe "kitchen-sink schema (pattern, enumeration, attributes, " \
|
|
11
|
+
"types, occurrence, nested complex type)" do
|
|
12
|
+
before do
|
|
13
|
+
path = fixture_path("validate_xml_with_product.xsd")
|
|
14
|
+
|
|
15
|
+
stub_const("XsdDimensions", Class.new(Lutaml::Model::Serializable) do
|
|
16
|
+
attribute :width, :string
|
|
17
|
+
attribute :height, :string
|
|
18
|
+
|
|
19
|
+
xml do
|
|
20
|
+
element "dimensions"
|
|
21
|
+
map_element "width", to: :width
|
|
22
|
+
map_element "height", to: :height
|
|
23
|
+
end
|
|
24
|
+
end)
|
|
25
|
+
|
|
26
|
+
stub_const("XsdProduct", Class.new(Lutaml::Model::Serializable) do
|
|
27
|
+
attribute :id, :string
|
|
28
|
+
attribute :status, :string
|
|
29
|
+
attribute :sku, :string
|
|
30
|
+
attribute :price, :string
|
|
31
|
+
attribute :released, :string
|
|
32
|
+
attribute :tags, :string, collection: true
|
|
33
|
+
attribute :note, :string
|
|
34
|
+
attribute :dimensions, XsdDimensions
|
|
35
|
+
|
|
36
|
+
xml do
|
|
37
|
+
element "product"
|
|
38
|
+
map_attribute "id", to: :id
|
|
39
|
+
map_attribute "status", to: :status
|
|
40
|
+
map_element "sku", to: :sku
|
|
41
|
+
map_element "price", to: :price
|
|
42
|
+
map_element "released", to: :released
|
|
43
|
+
map_element "tag", to: :tags
|
|
44
|
+
map_element "note", to: :note
|
|
45
|
+
map_element "dimensions", to: :dimensions
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
validate_xml_with path
|
|
49
|
+
end)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
let(:valid_attributes) do
|
|
53
|
+
{
|
|
54
|
+
id: "p1",
|
|
55
|
+
status: "published",
|
|
56
|
+
sku: "ABC-1234",
|
|
57
|
+
price: "9.99",
|
|
58
|
+
released: "2026-06-11",
|
|
59
|
+
tags: %w[a b c],
|
|
60
|
+
note: "boundary case: three tags is maxOccurs",
|
|
61
|
+
dimensions: XsdDimensions.new(width: "10", height: "20"),
|
|
62
|
+
}
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def product(**overrides)
|
|
66
|
+
XsdProduct.new(valid_attributes.merge(overrides))
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it "accepts a document satisfying every construct" do
|
|
70
|
+
expect(product.validate).to be_empty
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it "accepts a document omitting all optional parts" do
|
|
74
|
+
minimal = product(status: nil, tags: [], note: nil, dimensions: nil)
|
|
75
|
+
|
|
76
|
+
expect(minimal.validate).to be_empty
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it "collects xs:pattern violations" do
|
|
80
|
+
errors = product(sku: "bad-sku").validate
|
|
81
|
+
|
|
82
|
+
expect(errors.map(&:message)).to include(a_string_including("sku"))
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it "collects xs:enumeration violations" do
|
|
86
|
+
errors = product(status: "archived").validate
|
|
87
|
+
|
|
88
|
+
expect(errors.map(&:message)).to include(a_string_including("status"))
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it "collects missing required attribute violations" do
|
|
92
|
+
errors = product(id: nil).validate
|
|
93
|
+
|
|
94
|
+
expect(errors.map(&:message)).to include(
|
|
95
|
+
a_string_including("attribute 'id' is required"),
|
|
96
|
+
)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it "collects xs:decimal lexical violations" do
|
|
100
|
+
errors = product(price: "free").validate
|
|
101
|
+
|
|
102
|
+
expect(errors.map(&:message)).to include(a_string_including("price"))
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it "collects xs:date lexical violations" do
|
|
106
|
+
errors = product(released: "tomorrow").validate
|
|
107
|
+
|
|
108
|
+
expect(errors.map(&:message)).to include(a_string_including("released"))
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it "collects maxOccurs violations" do
|
|
112
|
+
errors = product(tags: %w[a b c d]).validate
|
|
113
|
+
|
|
114
|
+
expect(errors.map(&:message)).to include(a_string_including("tag"))
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
it "collects violations inside nested complex types" do
|
|
118
|
+
bad_nested = XsdDimensions.new(width: "wide", height: "20")
|
|
119
|
+
errors = product(dimensions: bad_nested).validate
|
|
120
|
+
|
|
121
|
+
expect(errors.map(&:message)).to include(a_string_including("width"))
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
describe "multiple schema paths" do
|
|
126
|
+
before do
|
|
127
|
+
base = fixture_path("validate_xml_with_person.xsd")
|
|
128
|
+
strict = fixture_path("validate_xml_with_person_strict.xsd")
|
|
129
|
+
|
|
130
|
+
stub_const("XsdDualSchemaPerson",
|
|
131
|
+
Class.new(Lutaml::Model::Serializable) do
|
|
132
|
+
attribute :name, :string
|
|
133
|
+
attribute :age, :string
|
|
134
|
+
|
|
135
|
+
xml do
|
|
136
|
+
element "person"
|
|
137
|
+
map_element "name", to: :name
|
|
138
|
+
map_element "age", to: :age
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
validate_xml_with base, strict
|
|
142
|
+
end)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
it "passes when the document conforms to every schema" do
|
|
146
|
+
person = XsdDualSchemaPerson.new(name: "Alice", age: "30")
|
|
147
|
+
|
|
148
|
+
expect(person.validate).to be_empty
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
it "attributes violations to the schema that rejected the document" do
|
|
152
|
+
person = XsdDualSchemaPerson.new(name: "Old", age: "200")
|
|
153
|
+
errors = person.validate
|
|
154
|
+
|
|
155
|
+
expect(errors.size).to eq(1)
|
|
156
|
+
expect(errors.first.schema_path).to eq(
|
|
157
|
+
fixture_path("validate_xml_with_person_strict.xsd"),
|
|
158
|
+
)
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
describe "targetNamespace with qualified elements" do
|
|
163
|
+
let(:schema_path) { fixture_path("validate_xml_with_address.xsd") }
|
|
164
|
+
|
|
165
|
+
before do
|
|
166
|
+
path = schema_path
|
|
167
|
+
stub_const("XsdNamespacedDoc",
|
|
168
|
+
Class.new(Lutaml::Model::Serializable) do
|
|
169
|
+
attribute :city, :string
|
|
170
|
+
|
|
171
|
+
xml do
|
|
172
|
+
element "address"
|
|
173
|
+
map_element "city", to: :city
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
validate_xml_with path
|
|
177
|
+
end)
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
it "accepts a document in the target namespace" do
|
|
181
|
+
xml = '<address xmlns="http://example.com/address">' \
|
|
182
|
+
"<city>Berlin</city></address>"
|
|
183
|
+
|
|
184
|
+
expect(XsdNamespacedDoc.validate_xml(xml)).to be_empty
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
it "rejects a document missing the target namespace" do
|
|
188
|
+
xml = "<address><city>Berlin</city></address>"
|
|
189
|
+
|
|
190
|
+
expect(XsdNamespacedDoc.validate_xml(xml)).not_to be_empty
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
describe "xs:choice" do
|
|
195
|
+
before do
|
|
196
|
+
path = fixture_path("validate_xml_with_contact.xsd")
|
|
197
|
+
stub_const("XsdChoiceDoc",
|
|
198
|
+
Class.new(Lutaml::Model::Serializable) do
|
|
199
|
+
attribute :email, :string
|
|
200
|
+
|
|
201
|
+
xml do
|
|
202
|
+
element "contact"
|
|
203
|
+
map_element "email", to: :email
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
validate_xml_with path
|
|
207
|
+
end)
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
it "accepts a document using exactly one branch" do
|
|
211
|
+
xml = "<contact><email>a@b.c</email></contact>"
|
|
212
|
+
|
|
213
|
+
expect(XsdChoiceDoc.validate_xml(xml)).to be_empty
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
it "rejects a document using both branches" do
|
|
217
|
+
xml = "<contact><email>a@b.c</email><phone>123</phone></contact>"
|
|
218
|
+
|
|
219
|
+
expect(XsdChoiceDoc.validate_xml(xml)).not_to be_empty
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
end
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
require "tmpdir"
|
|
5
|
+
|
|
6
|
+
RSpec.describe "validate_xml_with" do
|
|
7
|
+
let(:schema_path) do
|
|
8
|
+
File.expand_path("../../fixtures/xml/validate_xml_with_person.xsd",
|
|
9
|
+
__dir__)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
before do
|
|
13
|
+
path = schema_path
|
|
14
|
+
stub_const("XsdValidatedPerson",
|
|
15
|
+
Class.new(Lutaml::Model::Serializable) do
|
|
16
|
+
attribute :name, :string
|
|
17
|
+
attribute :age, :string
|
|
18
|
+
|
|
19
|
+
xml do
|
|
20
|
+
element "person"
|
|
21
|
+
map_element "name", to: :name
|
|
22
|
+
map_element "age", to: :age
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
validate_xml_with path
|
|
26
|
+
end)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
context "when the generated XML conforms to the schema" do
|
|
30
|
+
let(:person) { XsdValidatedPerson.new(name: "Alice", age: "30") }
|
|
31
|
+
|
|
32
|
+
it "returns no errors from validate" do
|
|
33
|
+
expect(person.validate).to be_empty
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "does not raise on validate!" do
|
|
37
|
+
expect { person.validate! }.not_to raise_error
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
context "when the generated XML violates the schema" do
|
|
42
|
+
let(:person) { XsdValidatedPerson.new(name: "Alice", age: "abc") }
|
|
43
|
+
|
|
44
|
+
it "collects schema validation errors" do
|
|
45
|
+
errors = person.validate
|
|
46
|
+
|
|
47
|
+
expect(errors).to all(
|
|
48
|
+
be_a(Lutaml::Xml::Error::SchemaValidationError),
|
|
49
|
+
)
|
|
50
|
+
expect(errors.first.message).to include(schema_path)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it "raises ValidationError with the schema message on validate!" do
|
|
54
|
+
expect { person.validate! }.to raise_error(
|
|
55
|
+
Lutaml::Model::ValidationError,
|
|
56
|
+
/age/,
|
|
57
|
+
)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
describe ".validate_xml / .validate_xml!" do
|
|
62
|
+
let(:valid_xml) do
|
|
63
|
+
"<person><name>Alice</name><age>30</age></person>"
|
|
64
|
+
end
|
|
65
|
+
let(:invalid_xml) do
|
|
66
|
+
"<person><name>Alice</name><age>abc</age></person>"
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it "returns no errors for a conforming raw XML string" do
|
|
70
|
+
expect(XsdValidatedPerson.validate_xml(valid_xml)).to be_empty
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it "collects errors for a non-conforming raw XML string" do
|
|
74
|
+
errors = XsdValidatedPerson.validate_xml(invalid_xml)
|
|
75
|
+
|
|
76
|
+
expect(errors).to all(
|
|
77
|
+
be_a(Lutaml::Xml::Error::SchemaValidationError),
|
|
78
|
+
)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it "raises ValidationError for a non-conforming raw XML string" do
|
|
82
|
+
expect do
|
|
83
|
+
XsdValidatedPerson.validate_xml!(invalid_xml)
|
|
84
|
+
end.to raise_error(Lutaml::Model::ValidationError, /age/)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it "raises a parse error for malformed XML instead of recovering" do
|
|
88
|
+
expect do
|
|
89
|
+
XsdValidatedPerson.validate_xml("<person><name>Alice</name>")
|
|
90
|
+
end.to raise_error(Nokogiri::XML::SyntaxError)
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
context "with schema path inheritance" do
|
|
95
|
+
before do
|
|
96
|
+
stub_const("XsdValidatedEmployee", Class.new(XsdValidatedPerson))
|
|
97
|
+
stub_const("XsdAugmentedEmployee",
|
|
98
|
+
Class.new(XsdValidatedPerson) do
|
|
99
|
+
validate_xml_with "extra/employee.xsd"
|
|
100
|
+
end)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it "subclasses inherit the parent's schema" do
|
|
104
|
+
employee = XsdValidatedEmployee.new(name: "Bob", age: "abc")
|
|
105
|
+
|
|
106
|
+
expect(employee.validate).not_to be_empty
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
it "a subclass macro call appends parent-first" do
|
|
110
|
+
expect(XsdAugmentedEmployee.xml_schema_paths).to eq(
|
|
111
|
+
[schema_path, File.expand_path("extra/employee.xsd", __dir__)],
|
|
112
|
+
)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
it "does not leak child paths back to the parent" do
|
|
116
|
+
expect(XsdValidatedPerson.xml_schema_paths).to eq([schema_path])
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
context "with a schema path relative to the declaring file" do
|
|
121
|
+
before do
|
|
122
|
+
stub_const("RelativeSchemaPerson",
|
|
123
|
+
Class.new(Lutaml::Model::Serializable) do
|
|
124
|
+
attribute :name, :string
|
|
125
|
+
attribute :age, :string
|
|
126
|
+
|
|
127
|
+
xml do
|
|
128
|
+
element "person"
|
|
129
|
+
map_element "name", to: :name
|
|
130
|
+
map_element "age", to: :age
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
validate_xml_with(
|
|
134
|
+
"../../fixtures/xml/validate_xml_with_person.xsd",
|
|
135
|
+
)
|
|
136
|
+
end)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
it "resolves the schema next to the declaring file, not the CWD" do
|
|
140
|
+
Dir.chdir(Dir.tmpdir) do
|
|
141
|
+
person = RelativeSchemaPerson.new(name: "Alice", age: "abc")
|
|
142
|
+
|
|
143
|
+
expect(person.validate).not_to be_empty
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
context "when no schema is configured" do
|
|
149
|
+
before do
|
|
150
|
+
stub_const("PlainPerson", Class.new(Lutaml::Model::Serializable) do
|
|
151
|
+
attribute :name, :string
|
|
152
|
+
|
|
153
|
+
xml do
|
|
154
|
+
element "person"
|
|
155
|
+
map_element "name", to: :name
|
|
156
|
+
end
|
|
157
|
+
end)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
it "validates without touching XSD machinery" do
|
|
161
|
+
expect(PlainPerson.new(name: "Alice").validate).to be_empty
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
context "when the schema file does not exist" do
|
|
166
|
+
before do
|
|
167
|
+
stub_const("MissingSchemaPerson",
|
|
168
|
+
Class.new(Lutaml::Model::Serializable) do
|
|
169
|
+
attribute :name, :string
|
|
170
|
+
|
|
171
|
+
xml do
|
|
172
|
+
element "person"
|
|
173
|
+
map_element "name", to: :name
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
validate_xml_with "nonexistent/schema.xsd"
|
|
177
|
+
end)
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
it "raises a configuration-level error" do
|
|
181
|
+
expect do
|
|
182
|
+
MissingSchemaPerson.new(name: "Alice").validate
|
|
183
|
+
end.to raise_error(Errno::ENOENT)
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
require "lutaml/yamlld"
|
|
5
|
+
|
|
6
|
+
RSpec.describe Lutaml::YamlLd::Adapter do
|
|
7
|
+
let(:yamlld_hash) do
|
|
8
|
+
{
|
|
9
|
+
"@context" => { "name" => "http://example.org/name" },
|
|
10
|
+
"@type" => "Thing",
|
|
11
|
+
"name" => "test",
|
|
12
|
+
}
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
describe ".parse" do
|
|
16
|
+
it "parses valid YAML-LD string to hash" do
|
|
17
|
+
yaml = YAML.dump(yamlld_hash)
|
|
18
|
+
result = described_class.parse(yaml)
|
|
19
|
+
expect(result).to eq(yamlld_hash)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe "#to_yamlld" do
|
|
24
|
+
it "generates YAML-LD string from hash" do
|
|
25
|
+
adapter = described_class.new(yamlld_hash)
|
|
26
|
+
result = adapter.to_yamlld
|
|
27
|
+
parsed = YAML.safe_load(result)
|
|
28
|
+
expect(parsed["@context"]).to eq({ "name" => "http://example.org/name" })
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "round-trips parse → generate" do
|
|
33
|
+
yaml = YAML.dump(yamlld_hash)
|
|
34
|
+
parsed = described_class.parse(yaml)
|
|
35
|
+
adapter = described_class.new(parsed)
|
|
36
|
+
result = adapter.to_yamlld
|
|
37
|
+
round_tripped = YAML.safe_load(result)
|
|
38
|
+
expect(round_tripped).to eq(yamlld_hash)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
describe "safe_load enforcement" do
|
|
42
|
+
it "rejects YAML with disallowed class tags" do
|
|
43
|
+
unsafe = "--- !ruby/object:Object {}\n"
|
|
44
|
+
expect do
|
|
45
|
+
described_class.parse(unsafe)
|
|
46
|
+
end.to raise_error(Psych::DisallowedClass)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "rejects malformed YAML with Psych::SyntaxError" do
|
|
50
|
+
malformed = "@context: [unterminated"
|
|
51
|
+
expect do
|
|
52
|
+
described_class.parse(malformed)
|
|
53
|
+
end.to raise_error(Psych::SyntaxError)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
require "lutaml/jsonld"
|
|
5
|
+
require "lutaml/yamlld"
|
|
6
|
+
|
|
7
|
+
RSpec.describe ":yamlld format registration" do
|
|
8
|
+
it "is registered with FormatRegistry as an RDF format" do
|
|
9
|
+
expect(Lutaml::Model::FormatRegistry.rdf_formats).to include(:yamlld)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "uses Rdf::Mapping as the mapping class" do
|
|
13
|
+
expect(Lutaml::Model::FormatRegistry.mappings_class_for(:yamlld))
|
|
14
|
+
.to eq(Lutaml::Rdf::Mapping)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "uses YamlLd::Adapter as the adapter class" do
|
|
18
|
+
expect(Lutaml::Model::FormatRegistry.adapter_class_for(:yamlld))
|
|
19
|
+
.to eq(Lutaml::YamlLd::Adapter)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "shares LinkedDataTransform with :jsonld" do
|
|
23
|
+
expect(Lutaml::Model::FormatRegistry.transformer_for(:yamlld))
|
|
24
|
+
.to eq(Lutaml::Rdf::LinkedDataTransform)
|
|
25
|
+
expect(Lutaml::Model::FormatRegistry.transformer_for(:yamlld))
|
|
26
|
+
.to eq(Lutaml::Model::FormatRegistry.transformer_for(:jsonld))
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "declares Psych::SyntaxError as a parse error type" do
|
|
30
|
+
expect(Lutaml::Model::FormatRegistry.error_types_for(:yamlld))
|
|
31
|
+
.to include("Psych::SyntaxError")
|
|
32
|
+
end
|
|
33
|
+
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "liquid"
|
|
3
|
+
require "liquid" unless RUBY_ENGINE == "opal"
|
|
4
4
|
require "rspec/matchers"
|
|
5
|
-
require "canon"
|
|
5
|
+
require "canon" unless RUBY_ENGINE == "opal"
|
|
6
6
|
|
|
7
7
|
RSpec.configure do |config|
|
|
8
8
|
# Enable flags like --only-failures and --next-failure
|
|
@@ -71,11 +71,27 @@ RSpec.configure do |config|
|
|
|
71
71
|
|
|
72
72
|
end
|
|
73
73
|
end
|
|
74
|
+
|
|
75
|
+
# Under Opal, exclude specs that require native-only adapters,
|
|
76
|
+
# filesystem, subprocess, schema compilation, or liquid templates.
|
|
77
|
+
if RUBY_ENGINE == "opal"
|
|
78
|
+
config.filter_run_excluding(
|
|
79
|
+
:native_adapter,
|
|
80
|
+
:native_fs,
|
|
81
|
+
:subprocess,
|
|
82
|
+
:performance,
|
|
83
|
+
:examples,
|
|
84
|
+
:consistency,
|
|
85
|
+
:xsd_schema,
|
|
86
|
+
:relaxng,
|
|
87
|
+
:liquid,
|
|
88
|
+
)
|
|
89
|
+
end
|
|
74
90
|
end
|
|
75
91
|
|
|
76
92
|
# configuration example
|
|
77
|
-
|
|
78
|
-
|
|
93
|
+
require "lutaml/model"
|
|
94
|
+
require "lutaml/xml"
|
|
79
95
|
require_relative "support/test_namespaces"
|
|
80
96
|
require_relative "support/test_adapter_config"
|
|
81
97
|
# require_relative "../lib/lutaml/xml/adapter/nokogiri_adapter"
|
|
@@ -83,16 +99,17 @@ require_relative "support/test_adapter_config"
|
|
|
83
99
|
# require_relative "../lib/lutaml/model/toml_adapter/toml_rb_adapter"
|
|
84
100
|
|
|
85
101
|
Lutaml::Model::Config.configure do |config|
|
|
86
|
-
config.xml_adapter_type
|
|
102
|
+
config.xml_adapter_type = RUBY_ENGINE == "opal" ? :oga : :nokogiri
|
|
87
103
|
config.hash_adapter_type = :standard
|
|
88
104
|
config.json_adapter_type = :standard
|
|
89
105
|
config.yaml_adapter_type = :standard
|
|
90
|
-
|
|
106
|
+
# toml_rb uses native ext; not registered as a lutaml format under Opal.
|
|
107
|
+
config.toml_adapter_type = :toml_rb unless RUBY_ENGINE == "opal"
|
|
91
108
|
end
|
|
92
109
|
|
|
93
|
-
# Configure Canon for XML equivalence testing
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
110
|
+
# Configure Canon for XML equivalence testing (Canon is not loaded under Opal)
|
|
111
|
+
if defined?(Canon::Config)
|
|
112
|
+
Canon::Config.configure do |config|
|
|
113
|
+
config.xml.match.profile = :spec_friendly
|
|
114
|
+
end
|
|
98
115
|
end
|
data/spec/support/opal.rb
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# Opal runtime patches for lutaml-model specs
|
|
3
|
+
# Opal runtime patches for lutaml-model specs.
|
|
4
|
+
# Oga (via moxml's vendored opal-oga fork) is the default XML adapter
|
|
5
|
+
# under Opal; REXML (bundled stdlib gem, pure Ruby) is also available.
|
|
6
|
+
# Smoke specs parameterize over both — see spec/lutaml/xml/opal_xml_spec.rb.
|
|
4
7
|
if RUBY_ENGINE == "opal"
|
|
5
|
-
Lutaml::Model::Config.xml_adapter_type = :
|
|
8
|
+
Lutaml::Model::Config.xml_adapter_type = :oga
|
|
6
9
|
end
|