lutaml-model 0.8.60 → 0.8.61

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: 0b57929b74102c6555ab5cc9a03246dbb3ebd4b59952bf09b6add75b8c9f067f
4
- data.tar.gz: c0e7e209ab27a89d83b63deeefa042f721c02d8077aff94f686b53550ef8ea8f
3
+ metadata.gz: 60d029c4eab58efd3741553bd22cc4f689164143f6f1fed87d4c6956cf341cfd
4
+ data.tar.gz: aefb886903788a07439e416b2a92ec7a5fe295f231aa6c137b606e6e9621b048
5
5
  SHA512:
6
- metadata.gz: 5198b96f62132b22ead982492ca82cbb5291956ca4d508242d779957f4f89a54eaeef44935fae3260c108abab0e90c03c51259e2dac9c18c5c8b98c0a82b4d65
7
- data.tar.gz: cf919daaea830dea7b44a59cf36b9c8dfb28c67d750137d5130c072c9ac297d1a78c37cd6d6d9a29be85c1819c485f1290e0d730b0c79fdb8da762ea9a1508d4
6
+ metadata.gz: 82a30dcc2a930524ebb5d3d8cdcd9c9eb712f5425105b61101263501af2b66e93e5395e2455925e57d87e9a10689b8dbd1b816e9e0f302e4472ba68f084ed365
7
+ data.tar.gz: 76625bdefe2dde62258b0ec3da4ca257679fa16a9b669ca0a4453108097e9d670109e9b4f77f5b67c0cf76f95e18164edd2b477a885bb3ed5cc73c928174d6a8
@@ -18,14 +18,15 @@ jobs:
18
18
  benchmark:
19
19
  runs-on: ubuntu-latest
20
20
  timeout-minutes: 60
21
- # Serializes the corpus legs: concurrent legs on shared runners
22
- # produce contention measurements that misfire the absolute gates
23
- # (lutaml-model#834: niso 0.921s vs a 0.25s main-passing gate).
24
- concurrency:
25
- group: downstream-benchmark
26
- cancel-in-progress: false
27
21
  strategy:
28
22
  fail-fast: false
23
+ # Serializes the corpus legs: concurrent legs on shared runners
24
+ # produce contention measurements that misfire the absolute gates
25
+ # (lutaml-model#834: niso 0.921s vs a 0.25s main-passing gate).
26
+ # max-parallel, NOT a job-level concurrency group: with a
27
+ # matrix, every leg lands in the same group and GitHub cancels
28
+ # four of the five at start.
29
+ max-parallel: 1
29
30
  matrix:
30
31
  include:
31
32
  - downstream: xmi
@@ -23,10 +23,13 @@ jobs:
23
23
  os: [ubuntu-latest, macos-latest, windows-latest]
24
24
  ruby: ["3.3", "3.4", "4.0"]
25
25
  experimental: [false]
26
- include:
26
+ # ruby head runs on ubuntu/macos only: windows-head cannot build
27
+ # the released ruby-ll C extension (and the vendored forks exist
28
+ # for Opal), so that cell was permanently red with zero signal
29
+ # (#832 follow-up).
30
+ exclude:
27
31
  - os: windows-latest
28
32
  ruby: head
29
- experimental: true
30
33
  steps:
31
34
  - uses: actions/checkout@v6
32
35
  with:
@@ -49,7 +49,10 @@ jobs:
49
49
  ruby-version: "3.4"
50
50
  - name: Resolve the released version
51
51
  id: version
52
- run: echo "version=$(git describe --tags --abbrev=0 | sed 's/^v//')" >> "$GITHUB_OUTPUT"
52
+ # From the version file, not git describe: the default checkout
53
+ # is shallow with no tags, so git describe failed and the empty
54
+ # version produced `gem install "lutaml-model:"`.
55
+ run: echo "version=$(ruby -e 'print File.read(%q{lib/lutaml/model/version.rb})[/VERSION\s*=\s*"([^"]+)"/, 1]')" >> "$GITHUB_OUTPUT"
53
56
  - name: Install and smoke the released gem
54
57
  run: |
55
58
  gem install "lutaml-model:${{ steps.version.outputs.version }}" --no-document
@@ -250,8 +250,9 @@ module Lutaml
250
250
  adapter, type)
251
251
  end
252
252
  require adapter_path
253
- rescue LoadError
254
- raise UnknownAdapterTypeError.new(adapter, type), cause: nil
253
+ rescue LoadError => e
254
+ # Chain the cause so a missing engine gem is named, not masked.
255
+ raise UnknownAdapterTypeError.new(adapter, type), cause: e
255
256
  end
256
257
 
257
258
  # Load the Moxml adapter for XML and similar formats.
@@ -23,9 +23,20 @@ module Lutaml
23
23
  },
24
24
  }
25
25
 
26
- # Add choice validation if present
26
+ # Choice validation: each choice is its own group. Independent
27
+ # choices combine conjunctively (allOf), so a document may
28
+ # satisfy every group at once; a single choice renders its
29
+ # group directly. Nested choices render as a nested group
30
+ # schema, which a document satisfies through its own
31
+ # oneOf/anyOf (#864, #865).
27
32
  if type.choice_attributes.any?
28
- @schema[name]["oneOf"] = generate_choice_attributes(type)
33
+ if type.choice_attributes.one?
34
+ @schema[name].merge!(choice_schema(type.choice_attributes.first))
35
+ else
36
+ @schema[name]["allOf"] = type.choice_attributes.map do |choice|
37
+ choice_schema(choice)
38
+ end
39
+ end
29
40
  end
30
41
 
31
42
  @schema
@@ -33,14 +44,27 @@ module Lutaml
33
44
 
34
45
  private
35
46
 
36
- def generate_choice_attributes(type)
37
- type.choice_attributes.map do |choice|
38
- {
39
- "type" => "object",
40
- "properties" => PropertiesCollection.from_attributes(
41
- choice.attributes, extract_register_from(type)
42
- ).to_schema,
43
- }
47
+ # min == max == 1 makes the members mutually exclusive (oneOf);
48
+ # any other range admits several members together (anyOf with
49
+ # per-member requirement).
50
+ def choice_schema(choice)
51
+ key = choice.min == 1 && choice.max == 1 ? "oneOf" : "anyOf"
52
+ { key => choice_branches(choice) }
53
+ end
54
+
55
+ def choice_branches(choice)
56
+ choice.attributes.map do |member|
57
+ if member.is_a?(Lutaml::Model::Choice)
58
+ choice_schema(member)
59
+ else
60
+ {
61
+ "type" => "object",
62
+ "properties" => PropertiesCollection.from_attributes(
63
+ [member], extract_register_from(type)
64
+ ).to_schema,
65
+ "required" => [member.name.to_s],
66
+ }
67
+ end
44
68
  end
45
69
  end
46
70
 
@@ -9,20 +9,18 @@ module Lutaml
9
9
  include SharedMethods
10
10
 
11
11
  def from_class(klass)
12
- new.tap do |collection|
13
- collection << Definition.new(klass)
14
-
15
- process_attributes(collection, klass)
16
- end
12
+ collection = new
13
+ register_definition(collection, klass)
14
+ collection
17
15
  end
18
16
 
19
- def process_attributes(collection, klass)
17
+ def process_attributes(collection, klass, seen = {})
20
18
  register = extract_register_from(klass)
21
19
  klass.attributes.each_value do |attribute|
22
20
  if attribute.union?
23
- process_union_members(collection, attribute)
21
+ process_union_members(collection, attribute, seen)
24
22
  elsif attribute.serializable?(register)
25
- process_attribute(collection, attribute, register)
23
+ process_attribute(collection, attribute, register, seen)
26
24
  end
27
25
  end
28
26
  end
@@ -30,31 +28,44 @@ module Lutaml
30
28
  # A union attribute's type is Type::Union, not a model, so collect
31
29
  # definitions for each of its Serializable members directly (a
32
30
  # union schema emits a $ref per model member).
33
- def process_union_members(collection, attribute)
31
+ def process_union_members(collection, attribute, seen = {})
34
32
  attribute.union_member_types.each do |member|
35
33
  next unless member.is_a?(::Class) &&
36
34
  member.include?(Lutaml::Model::Serialize)
37
35
 
38
- collection.merge(DefinitionsCollection.from_class(member))
36
+ register_definition(collection, member, seen)
39
37
  end
40
38
  end
41
39
 
42
- def process_attribute(collection, attribute, register)
40
+ def process_attribute(collection, attribute, register, seen = {})
43
41
  attr_type = Lutaml::Model::GlobalContext.resolve_type(
44
42
  attribute.type, register
45
43
  )
46
- collection.merge(DefinitionsCollection.from_class(attr_type))
44
+ register_definition(collection, attr_type, seen)
47
45
 
48
- process_polymorphic_types(collection, attribute)
46
+ process_polymorphic_types(collection, attribute, seen)
49
47
  end
50
48
 
51
- def process_polymorphic_types(collection, attribute)
49
+ def process_polymorphic_types(collection, attribute, seen = {})
52
50
  return unless attribute.options&.[](:polymorphic)
53
51
 
54
52
  attribute.options[:polymorphic].each do |child|
55
- collection.merge(DefinitionsCollection.from_class(child))
53
+ register_definition(collection, child, seen)
56
54
  end
57
55
  end
56
+
57
+ # Recursive models (Node#child → Node, or longer include
58
+ # cycles) are valid; the seen-set registers each class once
59
+ # and lets property references point at the shared $defs
60
+ # entry instead of recursing (#863).
61
+ def register_definition(collection, klass, seen = {})
62
+ return collection if seen[klass]
63
+
64
+ seen[klass] = true
65
+ collection << Definition.new(klass)
66
+ process_attributes(collection, klass, seen)
67
+ collection
68
+ end
58
69
  end
59
70
 
60
71
  attr_reader :definitions
@@ -52,11 +52,13 @@ module Lutaml
52
52
  end
53
53
 
54
54
  def self.to_json(klass, options = {})
55
- JsonSchema.generate(klass, options)
55
+ # The generator signatures are keyword-only; splat so callers may
56
+ # pass an options hash positionally (#866).
57
+ JsonSchema.generate(klass, **options)
56
58
  end
57
59
 
58
60
  def self.to_yaml(klass, options = {})
59
- YamlSchema.generate(klass, options)
61
+ YamlSchema.generate(klass, **options)
60
62
  end
61
63
 
62
64
  # XML-specific methods (to_xsd, to_relaxng, from_xml) are registered
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Lutaml
4
4
  module Model
5
- VERSION = "0.8.60"
5
+ VERSION = "0.8.61"
6
6
  end
7
7
  end
@@ -19,9 +19,12 @@ module Lutaml
19
19
  File.join(File.dirname(__FILE__), "adapter", type)
20
20
  end
21
21
  require adapter_path
22
- rescue LoadError
22
+ rescue LoadError => e
23
+ # Chain the cause: a known adapter whose underlying engine gem is
24
+ # missing (e.g. no nokogiri in the Gemfile) must not present as a
25
+ # bare unknown-type error — the LoadError names the real gap.
23
26
  raise Lutaml::Model::UnknownAdapterTypeError.new("xml", type),
24
- cause: nil
27
+ cause: e
25
28
  end
26
29
 
27
30
  # Load the Moxml adapter for XML
@@ -200,7 +200,15 @@ module Lutaml
200
200
  case kind
201
201
  when :content_deferred
202
202
  runs = content_runs(value)
203
- next if runs.empty?
203
+ if runs.empty?
204
+ # The interpretive pipeline marks every applied rule's
205
+ # attribute set (model_transform apply). Skipping the
206
+ # mark leaves using_default? true, so the serializer's
207
+ # render gate suppresses a mapped reader that derives
208
+ # content from other attributes (#856).
209
+ instance.value_set_for(attr.name)
210
+ next
211
+ end
204
212
 
205
213
  # Non-collection content attrs hold the joined text
206
214
  # (the interpretive path assigns element text, the runs
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+ require "yaml"
5
+
6
+ require "spec_helper"
7
+
8
+ RSpec.describe "JSON/YAML schema generation regressions (#863, #864, #865, #866)" do
9
+ before do
10
+ stub_const("SchemaRepro::Node", node_class)
11
+ stub_const("SchemaRepro::Outer", outer_class)
12
+ stub_const("SchemaRepro::Relation", relation_class)
13
+ stub_const("SchemaRepro::Simple", simple_class)
14
+ end
15
+
16
+ let(:node_class) do
17
+ klass = Class.new(Lutaml::Model::Serializable) do
18
+ attribute :name, :string
19
+ xml { element "Node" }
20
+ end
21
+ klass.attribute :child, klass
22
+ klass
23
+ end
24
+
25
+ let(:outer_class) do
26
+ Class.new(Lutaml::Model::Serializable) do
27
+ choice(min: 1, max: 1) do
28
+ choice(min: 1, max: 1) do
29
+ attribute :from, :string
30
+ attribute :to, :string
31
+ end
32
+ attribute :at, :string
33
+ end
34
+ xml { element "Outer" }
35
+ end
36
+ end
37
+
38
+ let(:relation_class) do
39
+ Class.new(Lutaml::Model::Serializable) do
40
+ attribute :type, :string
41
+ choice(min: 1, max: 1) do
42
+ attribute :locality, :string, collection: true, initialize_empty: true
43
+ attribute :locality_stack, :string, collection: true, initialize_empty: true
44
+ end
45
+ choice(min: 1, max: 1) do
46
+ attribute :source_locality, :string, collection: true, initialize_empty: true
47
+ attribute :source_locality_stack, :string, collection: true, initialize_empty: true
48
+ end
49
+ xml { element "Relation" }
50
+ end
51
+ end
52
+
53
+ let(:simple_class) do
54
+ Class.new(Lutaml::Model::Serializable) do
55
+ attribute :x, :string
56
+ xml { element "Simple" }
57
+ end
58
+ end
59
+
60
+ describe "#863: recursive models" do
61
+ it "terminates and emits one definition per class" do
62
+ schema = JSON.parse(Lutaml::Model::Schema.to_json(SchemaRepro::Node))
63
+ expect(schema["$defs"].keys).to contain_exactly("SchemaRepro_Node")
64
+ end
65
+
66
+ it "generates through the YAML path" do
67
+ yaml = Lutaml::Model::Schema.to_yaml(SchemaRepro::Node)
68
+ expect(YAML.safe_load(yaml)).to include("$defs")
69
+ end
70
+ end
71
+
72
+ describe "#864: nested choice blocks" do
73
+ it "renders the nested group as its own oneOf" do
74
+ schema = JSON.parse(Lutaml::Model::Schema.to_json(SchemaRepro::Outer))
75
+ one_of = schema["$defs"]["SchemaRepro_Outer"]["oneOf"]
76
+ at_branch = one_of.find { |b| b["required"] == %w[at] }
77
+ inner = one_of.find { |b| b["oneOf"] }
78
+ expect(at_branch).to be_truthy
79
+ expect(inner["oneOf"].map { |b| b["required"] })
80
+ .to contain_exactly(%w[from], %w[to])
81
+ end
82
+ end
83
+
84
+ describe "#865: independent choices combine conjunctively" do
85
+ it "renders an allOf of oneOf groups with discriminating required keys" do
86
+ schema = JSON.parse(Lutaml::Model::Schema.to_json(SchemaRepro::Relation))
87
+ all_of = schema["$defs"]["SchemaRepro_Relation"]["allOf"]
88
+ expect(all_of.length).to eq(2)
89
+ all_of.each do |group|
90
+ expect(group).to have_key("oneOf")
91
+ group["oneOf"].each { |branch| expect(branch["required"]).to be_truthy }
92
+ end
93
+ end
94
+ end
95
+
96
+ describe "#866: Schema.to_json / to_yaml delegation" do
97
+ it "accepts a positional options hash" do
98
+ expect { Lutaml::Model::Schema.to_json(SchemaRepro::Simple) }
99
+ .not_to raise_error
100
+ expect { Lutaml::Model::Schema.to_yaml(SchemaRepro::Simple) }
101
+ .not_to raise_error
102
+ end
103
+ end
104
+ end
@@ -161,17 +161,24 @@ RSpec.describe Lutaml::Model::Schema::JsonSchema do
161
161
  "type" => ["string", "null"],
162
162
  },
163
163
  },
164
- "oneOf" => [
164
+ "anyOf" => [
165
165
  {
166
166
  "type" => "object",
167
167
  "properties" => {
168
168
  "email" => {
169
169
  "type" => ["string", "null"],
170
170
  },
171
+ },
172
+ "required" => ["email"],
173
+ },
174
+ {
175
+ "type" => "object",
176
+ "properties" => {
171
177
  "phone" => {
172
178
  "type" => ["string", "null"],
173
179
  },
174
180
  },
181
+ "required" => ["phone"],
175
182
  },
176
183
  ],
177
184
  },
@@ -136,17 +136,23 @@ RSpec.describe Lutaml::Model::Schema::YamlSchema do
136
136
  type:
137
137
  - string
138
138
  - 'null'
139
- oneOf:
139
+ anyOf:
140
140
  - type: object
141
141
  properties:
142
142
  email:
143
143
  type:
144
144
  - string
145
145
  - 'null'
146
+ required:
147
+ - email
148
+ - type: object
149
+ properties:
146
150
  phone:
147
151
  type:
148
152
  - string
149
153
  - 'null'
154
+ required:
155
+ - phone
150
156
  YAML
151
157
  end
152
158
 
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ RSpec.describe Lutaml::Xml::AdapterLoader do
6
+ it "chains the LoadError cause instead of masking it" do
7
+ expect do
8
+ described_class.load_adapter_file("xml", "bogus_adapter")
9
+ end.to raise_error(Lutaml::Model::UnknownAdapterTypeError) do |error|
10
+ expect(error.cause).to be_a(LoadError)
11
+ expect(error.cause.message).to include("bogus_adapter")
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ # lutaml-model#858: leptris hydrates :string values as ASCII-8BIT
6
+ # (FFI's :string return tag) while nokogiri returns UTF-8. Values are
7
+ # character data; both adapters must agree on the encoding.
8
+ RSpec.describe "leptris string encoding parity with nokogiri",
9
+ if: defined?(Leptris::XML::Document) do
10
+ let(:xml) do
11
+ <<~XML
12
+ <Relationship Id="rId5" Target="http://example.com/x"/>
13
+ XML
14
+ end
15
+
16
+ let(:klass) do
17
+ Class.new(Lutaml::Model::Serializable) do
18
+ attribute :id, :string
19
+ attribute :target, :string
20
+
21
+ xml do
22
+ element "Relationship"
23
+ map_attribute "Id", to: :id
24
+ map_attribute "Target", to: :target
25
+ end
26
+ end
27
+ end
28
+
29
+ before do
30
+ stub_const("LeptrisEncoding::Rel", klass)
31
+ end
32
+
33
+ it "hydrates attribute values as UTF-8" do
34
+ Lutaml::Model::Config.with_adapter(xml: :nokogiri) do
35
+ parsed = klass.from_xml(xml)
36
+ expect(parsed.id.encoding).to eq(Encoding::UTF_8)
37
+ expect(parsed.target.encoding).to eq(Encoding::UTF_8)
38
+ end
39
+
40
+ Lutaml::Model::Config.with_adapter(xml: :leptris) do
41
+ parsed = klass.from_xml(xml)
42
+ expect(parsed.id.encoding).to eq(Encoding::UTF_8)
43
+ expect(parsed.target.encoding).to eq(Encoding::UTF_8)
44
+ end
45
+ end
46
+
47
+ it "hydrates element text as UTF-8" do
48
+ doc = "<Note>café – naïve</Note>"
49
+ text_class = Class.new(Lutaml::Model::Serializable) do
50
+ attribute :text, :string
51
+
52
+ xml do
53
+ element "Note"
54
+ map_content to: :text
55
+ end
56
+ end
57
+ stub_const("LeptrisEncoding::Note", text_class)
58
+
59
+ Lutaml::Model::Config.with_adapter(xml: :leptris) do
60
+ parsed = text_class.from_xml(doc)
61
+ expect(parsed.text.encoding).to eq(Encoding::UTF_8)
62
+ expect(parsed.text).to eq("café – naïve")
63
+ end
64
+ end
65
+ end
@@ -740,4 +740,53 @@ RSpec.describe "XML plan fast path" do
740
740
  %(<b xmlns="http://example.com/w" val="false"/>),
741
741
  ).value).to be(false)
742
742
  end
743
+
744
+ # lutaml-model#856: a deferred content row with no captured runs
745
+ # must still mark its attribute set — the interpretive pipeline
746
+ # marks every applied rule (model_transform apply). Without the
747
+ # mark, the serializer's default-suppression drops a mapped reader
748
+ # that derives content from other attributes.
749
+ it "renders derived content readers when no text was captured" do
750
+ klass = Class.new(Lutaml::Model::Serializable) do
751
+ attribute :content, :string
752
+ attribute :revision_date, :string
753
+ attribute :draft, :string
754
+
755
+ xml do
756
+ element "version"
757
+ map_content to: :content
758
+ map_element "revision-date", to: :revision_date
759
+ map_element "draft", to: :draft
760
+ end
761
+
762
+ define_method(:content) do
763
+ return @content if @content && !@content.empty?
764
+
765
+ parts = [@draft, @revision_date].compact
766
+ case parts.size
767
+ when 2 then "#{@draft} (#{@revision_date})"
768
+ when 1 then parts.first
769
+ end
770
+ end
771
+ end
772
+ stub_const("PlanFastPath::DerivedContent856", klass)
773
+
774
+ parsed = nil
775
+ Lutaml::Model::Config.with_adapter(xml: :leptris) do
776
+ parsed = klass.from_xml(
777
+ "<version><revision-date>1994-01-01</revision-date><draft>PD</draft></version>",
778
+ )
779
+ expect(parsed.using_default?(:content)).to be(false)
780
+ expect(parsed.to_xml).to eq(
781
+ "<version><revision-date>1994-01-01</revision-date>" \
782
+ "<draft>PD</draft>PD (1994-01-01)</version>",
783
+ )
784
+ end
785
+ Lutaml::Model::Config.with_adapter(xml: :nokogiri) do
786
+ expect(parsed.to_xml).to eq(
787
+ "<version><revision-date>1994-01-01</revision-date>" \
788
+ "<draft>PD</draft>PD (1994-01-01)</version>",
789
+ )
790
+ end
791
+ end
743
792
  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.60
4
+ version: 0.8.61
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-09-24 00:00:00.000000000 Z
11
+ date: 2026-09-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: base64
@@ -1789,6 +1789,7 @@ files:
1789
1789
  - spec/lutaml/model/root_mappings_spec.rb
1790
1790
  - spec/lutaml/model/rule_value_extractor_spec.rb
1791
1791
  - spec/lutaml/model/runtime_compatibility_spec.rb
1792
+ - spec/lutaml/model/schema/generation_regressions_spec.rb
1792
1793
  - spec/lutaml/model/schema/generator/definitions_collection_spec.rb
1793
1794
  - spec/lutaml/model/schema/json_schema_spec.rb
1794
1795
  - spec/lutaml/model/schema/json_schema_to_models_spec.rb
@@ -1903,6 +1904,7 @@ files:
1903
1904
  - spec/lutaml/xml/adapter/ox_adapter_spec.rb
1904
1905
  - spec/lutaml/xml/adapter/rexml_adapter_spec.rb
1905
1906
  - spec/lutaml/xml/adapter/xml_namespace_spec.rb
1907
+ - spec/lutaml/xml/adapter_loader_spec.rb
1906
1908
  - spec/lutaml/xml/attribute_ambiguity_surface_spec.rb
1907
1909
  - spec/lutaml/xml/attribute_element_namespace_disjoint_spec.rb
1908
1910
  - spec/lutaml/xml/attribute_namespace_disjointness_spec.rb
@@ -1932,6 +1934,7 @@ files:
1932
1934
  - spec/lutaml/xml/general_namespace_spec.rb
1933
1935
  - spec/lutaml/xml/html_entities_spec.rb
1934
1936
  - spec/lutaml/xml/indent_spec.rb
1937
+ - spec/lutaml/xml/leptris_string_encoding_spec.rb
1935
1938
  - spec/lutaml/xml/line_ending_spec.rb
1936
1939
  - spec/lutaml/xml/mapping_finalization_guard_spec.rb
1937
1940
  - spec/lutaml/xml/mapping_rule_spec.rb