lutaml-model 0.8.118 → 0.8.120
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/dependent-repos-tools.json +9 -0
- data/.github/workflows/dependent-repos.json +1 -6
- data/.github/workflows/dependent-tests.yml +19 -0
- data/lib/lutaml/json/adapter/yeptris_adapter.rb +23 -4
- data/lib/lutaml/model/adapter_resolver.rb +13 -5
- data/lib/lutaml/model/union.rb +10 -7
- data/lib/lutaml/model/version.rb +1 -1
- data/lib/lutaml/yaml/adapter/yeptris_adapter.rb +24 -4
- data/spec/lutaml/model/union_attribute_spec.rb +51 -0
- data/spec/lutaml/model/yeptris_error_parity_spec.rb +11 -1
- data/spec/lutaml/model/yeptris_native_detection_spec.rb +87 -0
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5a2f85724acebb5e00bf61091dfd3da178b087700420af1f9c8168ea1eb7e579
|
|
4
|
+
data.tar.gz: 0220370237df57218c474fdc97f72dda7ca0e7183eff0d3aecea6397e7d56232
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6c2dfe1999803b5a232318a871fe71c07ccf7bb8050aa31691918e405b67d1b9bfdd41661f6ec6e7a9e3764c0d6124ed3e1d8d84dc0627dab28698d3f6ce615f
|
|
7
|
+
data.tar.gz: dc85cfcf2a10c301e80b533a679877f43df5e018428a5b1e19c8e2f50f545064088a955956bbbb6bd19462da5db995e16052ea6b4268fda05b8805a1f3ccb0d6
|
|
@@ -14,22 +14,17 @@
|
|
|
14
14
|
"lutaml/unibuf",
|
|
15
15
|
"lutaml/xmi",
|
|
16
16
|
"metanorma/atmospheric",
|
|
17
|
-
"metanorma/docbook",
|
|
18
|
-
"metanorma/metanorma-cli",
|
|
19
17
|
"metanorma/modspec-ruby",
|
|
20
18
|
"metanorma/niso-jats",
|
|
21
19
|
"metanorma/prosereflect",
|
|
22
20
|
"metanorma/revix",
|
|
23
|
-
"metanorma/rfcxml",
|
|
24
21
|
"metanorma/sts-ruby",
|
|
25
|
-
"metanorma/uniword",
|
|
26
22
|
"plurimath/mml",
|
|
27
23
|
"plurimath/plurimath",
|
|
28
24
|
"relaton/ieee-idams",
|
|
29
25
|
"relaton/loc_mods",
|
|
30
26
|
"relaton/w3c_api",
|
|
31
|
-
"ukiryu/ukiryu",
|
|
32
27
|
"unitsml/unitsdb-ruby",
|
|
33
28
|
"unitsml/unitsml-ruby"
|
|
34
29
|
]
|
|
35
|
-
}
|
|
30
|
+
}
|
|
@@ -18,10 +18,29 @@ on:
|
|
|
18
18
|
types: [ release-passed ]
|
|
19
19
|
|
|
20
20
|
jobs:
|
|
21
|
+
# Most dependents are pure data/format gems: their suites invoke no
|
|
22
|
+
# external tools, so skipping the tool install removes the Windows
|
|
23
|
+
# Chocolatey flake surface (choco CDN 504s killed cells pre-rspec,
|
|
24
|
+
# e.g. the ukiryu Windows leg) for the majority of the matrix.
|
|
21
25
|
rake:
|
|
22
26
|
uses: metanorma/ci/.github/workflows/dependent-rake.yml@main
|
|
23
27
|
with:
|
|
24
28
|
command: bundle exec rspec
|
|
29
|
+
repos-json-file: .github/workflows/dependent-repos.json
|
|
30
|
+
after-setup-ruby: |
|
|
31
|
+
if [ -f frontend/package.json ]; then cd frontend && npm install && npm run build; fi
|
|
32
|
+
secrets:
|
|
33
|
+
pat_token: ${{ secrets.LUTAML_CI_PAT_TOKEN }}
|
|
34
|
+
|
|
35
|
+
# Dependents whose suites invoke the tools: ukiryu wraps
|
|
36
|
+
# inkscape/imagemagick/ghostscript and raises if absent, and its
|
|
37
|
+
# smoke suite exercises exiftool, yq and ffmpeg too; the metanorma
|
|
38
|
+
# renderers run full document renders.
|
|
39
|
+
rake-with-tools:
|
|
40
|
+
uses: metanorma/ci/.github/workflows/dependent-rake.yml@main
|
|
41
|
+
with:
|
|
42
|
+
command: bundle exec rspec
|
|
43
|
+
repos-json-file: .github/workflows/dependent-repos-tools.json
|
|
25
44
|
setup-tools: 'inkscape,ghostscript,exiftool,ffmpeg,imagemagick,yq'
|
|
26
45
|
after-setup-ruby: |
|
|
27
46
|
if [ -f frontend/package.json ]; then cd frontend && npm install && npm run build; fi
|
|
@@ -27,16 +27,35 @@ module Lutaml
|
|
|
27
27
|
private_class_method :require_engine
|
|
28
28
|
|
|
29
29
|
# True where the yeptris engine loads (libyeptris present for
|
|
30
|
-
# this platform)
|
|
31
|
-
#
|
|
32
|
-
#
|
|
30
|
+
# this platform) AND answers a probe parse. A require alone
|
|
31
|
+
# does not prove the engine: a half-initialized Yeptris
|
|
32
|
+
# constant (the poison-process state the gem documents)
|
|
33
|
+
# passes const_defined? and require while every parse fails,
|
|
34
|
+
# and the native parse error then surfaces on valid input.
|
|
35
|
+
# Any failure — missing native, engine error, or a binding and
|
|
36
|
+
# native binary out of sync (NameError on a missing FFI surface,
|
|
37
|
+
# yeptris 0.6.34.2 x64-mingw-ucrt) — reports false instead of
|
|
38
|
+
# raising, so optional-engine callers (detection) gate on it and
|
|
39
|
+
# fall back to the standard lane.
|
|
33
40
|
def self.available?
|
|
34
41
|
require_engine
|
|
35
|
-
|
|
42
|
+
native_ready?
|
|
36
43
|
rescue LoadError
|
|
37
44
|
false
|
|
38
45
|
end
|
|
39
46
|
|
|
47
|
+
def self.native_ready?
|
|
48
|
+
return @native_ready unless @native_ready.nil?
|
|
49
|
+
|
|
50
|
+
@native_ready = begin
|
|
51
|
+
::Yeptris::JSON.load('{"native_probe": 1}')
|
|
52
|
+
true
|
|
53
|
+
rescue StandardError
|
|
54
|
+
false
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
private_class_method :native_ready?
|
|
58
|
+
|
|
40
59
|
# The parse-error contract is the standard adapter's: invalid
|
|
41
60
|
# input raises JSON::ParserError regardless of the engine, so
|
|
42
61
|
# consumers' rescue ladders (and this gem's own
|
|
@@ -387,13 +387,21 @@ module Lutaml
|
|
|
387
387
|
end
|
|
388
388
|
|
|
389
389
|
# Native key-value engine preference: yeptris (libyeptris C11)
|
|
390
|
-
# when its gem is in the bundle
|
|
391
|
-
# adapter. Opt-in by bundle
|
|
392
|
-
# consumers that do not add
|
|
390
|
+
# when its gem is in the bundle AND the native engine answers a
|
|
391
|
+
# probe, else the format's standard adapter. Opt-in by bundle
|
|
392
|
+
# contents — nothing is required of consumers that do not add
|
|
393
|
+
# yeptris. The probe matters because a half-initialized Yeptris
|
|
394
|
+
# constant (the poison-process state the gem documents) passes
|
|
395
|
+
# const_defined? and require while every parse fails; without
|
|
396
|
+
# it the lane selection flips with process load order and the
|
|
397
|
+
# failure surfaces as a native parse error on valid input
|
|
398
|
+
# instead of a clean standard-lane parse (#978).
|
|
393
399
|
def detect_yeptris_kv_adapter(format)
|
|
394
|
-
|
|
400
|
+
default = metadata.dig(format, :default)
|
|
401
|
+
return default if Lutaml::Model.opal?
|
|
402
|
+
return default unless Utils.safe_load("yeptris", :Yeptris)
|
|
395
403
|
|
|
396
|
-
|
|
404
|
+
load_adapter(format, :yeptris).available? ? :yeptris : default
|
|
397
405
|
end
|
|
398
406
|
|
|
399
407
|
# Detect available XML adapter.
|
data/lib/lutaml/model/union.rb
CHANGED
|
@@ -154,12 +154,15 @@ module Lutaml
|
|
|
154
154
|
member.is_a?(::Class) && member.include?(Serialize)
|
|
155
155
|
end
|
|
156
156
|
|
|
157
|
-
# Structural
|
|
158
|
-
#
|
|
159
|
-
#
|
|
160
|
-
#
|
|
161
|
-
#
|
|
162
|
-
#
|
|
157
|
+
# Structural selection: at least one input key maps to one of the
|
|
158
|
+
# member's mapped fields. Keys no rule claims are ignored exactly
|
|
159
|
+
# as they are when the same hash reaches the model outside a
|
|
160
|
+
# union — extension keys (x-** vendor keywords, forward-compatible
|
|
161
|
+
# vocabularies) must not defeat dispatch (#987). Once selected,
|
|
162
|
+
# field values cast leniently via the member's normal path. An
|
|
163
|
+
# existing member instance conforms as-is, keeping conformance
|
|
164
|
+
# idempotent — values can re-enter casting (e.g. a value
|
|
165
|
+
# transformer builds the member before the cast runs).
|
|
163
166
|
def conform_model(member, value, format, register)
|
|
164
167
|
return value if value.is_a?(member)
|
|
165
168
|
|
|
@@ -167,7 +170,7 @@ module Lutaml
|
|
|
167
170
|
return :no_match if keys.nil? || keys.empty?
|
|
168
171
|
|
|
169
172
|
field_names = member_field_names(member, format, register)
|
|
170
|
-
return :no_match unless keys.
|
|
173
|
+
return :no_match unless keys.any? do |key|
|
|
171
174
|
field_names.include?(key)
|
|
172
175
|
end
|
|
173
176
|
|
data/lib/lutaml/model/version.rb
CHANGED
|
@@ -41,16 +41,36 @@ module Lutaml
|
|
|
41
41
|
private_class_method :require_engine
|
|
42
42
|
|
|
43
43
|
# True where the yeptris engine loads (libyeptris present for
|
|
44
|
-
# this platform)
|
|
45
|
-
#
|
|
46
|
-
#
|
|
44
|
+
# this platform) AND answers a probe parse. A require alone
|
|
45
|
+
# does not prove the engine: a half-initialized Yeptris
|
|
46
|
+
# constant (the poison-process state the gem documents)
|
|
47
|
+
# passes const_defined? and require while every parse fails,
|
|
48
|
+
# and the native parse error then surfaces on valid input.
|
|
49
|
+
# Any failure — missing native, engine error, or a binding and
|
|
50
|
+
# native binary out of sync (NameError on a missing FFI surface,
|
|
51
|
+
# yeptris 0.6.34.2 x64-mingw-ucrt) — reports false instead of
|
|
52
|
+
# raising, so optional-engine callers (detection) gate on it and
|
|
53
|
+
# fall back to the standard lane.
|
|
47
54
|
def self.available?
|
|
48
55
|
require_engine
|
|
49
|
-
|
|
56
|
+
native_ready?
|
|
50
57
|
rescue LoadError
|
|
51
58
|
false
|
|
52
59
|
end
|
|
53
60
|
|
|
61
|
+
def self.native_ready?
|
|
62
|
+
return @native_ready unless @native_ready.nil?
|
|
63
|
+
|
|
64
|
+
@native_ready = begin
|
|
65
|
+
# rubocop:disable-next Naming/VariableNumber -- upstream schema literal
|
|
66
|
+
::Yeptris::YAML.load("native_probe: 1", schema: :compat_11)
|
|
67
|
+
true
|
|
68
|
+
rescue StandardError
|
|
69
|
+
false
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
private_class_method :native_ready?
|
|
73
|
+
|
|
54
74
|
# The parse-error contract is the standard adapter's: invalid
|
|
55
75
|
# input raises Psych::SyntaxError regardless of the engine, so
|
|
56
76
|
# consumers' rescue ladders (and this gem's own
|
|
@@ -214,6 +214,25 @@ module UnionAttributeSpec
|
|
|
214
214
|
end
|
|
215
215
|
end
|
|
216
216
|
|
|
217
|
+
# Union members for the #987 dispatch contract: an extension-carrying
|
|
218
|
+
# model (keys no rule maps must not defeat dispatch) and a holder
|
|
219
|
+
# mixing it with a scalar member.
|
|
220
|
+
class ExtendedShape < Lutaml::Model::Serializable
|
|
221
|
+
attribute :type, :string
|
|
222
|
+
|
|
223
|
+
key_value do
|
|
224
|
+
map "type", to: :type
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
class ExtendedHolder < Lutaml::Model::Serializable
|
|
229
|
+
attribute :value, [ExtendedShape, :boolean]
|
|
230
|
+
|
|
231
|
+
key_value do
|
|
232
|
+
map "value", to: :value
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
|
|
217
236
|
RSpec.describe "Union-typed attributes (issue #190)" do
|
|
218
237
|
describe "deserialization — member resolution by shape" do
|
|
219
238
|
it "resolves a scalar string to the :string member" do
|
|
@@ -646,6 +665,38 @@ RSpec.describe "Union-typed attributes (issue #190)" do
|
|
|
646
665
|
end
|
|
647
666
|
end
|
|
648
667
|
|
|
668
|
+
describe "unmapped keys do not defeat model dispatch (#987)" do
|
|
669
|
+
# ExtendedShape / ExtendedHolder: extension-carrying objects (JSON
|
|
670
|
+
# Schema vocabularies, OpenAPI x-** keywords) carry keys no rule
|
|
671
|
+
# maps; the same hash reaches the model member fine outside a
|
|
672
|
+
# union, so it must inside one too.
|
|
673
|
+
|
|
674
|
+
it "selects the model member when mapped and unmapped keys mix" do
|
|
675
|
+
parsed = ExtendedHolder.from_json(
|
|
676
|
+
'{"value":{"type":"string","x-ext":1}}',
|
|
677
|
+
)
|
|
678
|
+
|
|
679
|
+
expect(parsed.value).to be_a(ExtendedShape)
|
|
680
|
+
expect(parsed.value.type).to eq("string")
|
|
681
|
+
end
|
|
682
|
+
|
|
683
|
+
it "still falls through when no key maps to any model member" do
|
|
684
|
+
parsed = ExtendedHolder.from_json('{"value":true}')
|
|
685
|
+
|
|
686
|
+
expect(parsed.value).to be(true)
|
|
687
|
+
end
|
|
688
|
+
|
|
689
|
+
it "returns nil only when no member conforms at all" do
|
|
690
|
+
holder = Class.new(Lutaml::Model::Serializable) do
|
|
691
|
+
attribute :value, [ExtendedShape, :boolean]
|
|
692
|
+
key_value { map "value", to: :value }
|
|
693
|
+
end
|
|
694
|
+
stub_const("ExtendedHolderNinetyEight", holder)
|
|
695
|
+
|
|
696
|
+
expect(holder.from_json('{"value":{"unrelated":1}}').value).to be_nil
|
|
697
|
+
end
|
|
698
|
+
end
|
|
699
|
+
|
|
649
700
|
describe "value transformers (cast idempotence)" do
|
|
650
701
|
it "keeps a model member built by transform: before the cast runs" do
|
|
651
702
|
reading = UnionAttributeSpec::TransformedReading.from_yaml(<<~YAML)
|
|
@@ -70,7 +70,17 @@ RSpec.describe "yeptris adapter error parity" do
|
|
|
70
70
|
RUBY
|
|
71
71
|
end
|
|
72
72
|
|
|
73
|
-
|
|
73
|
+
# Installed is not enough: a binding/native desync (yeptris
|
|
74
|
+
# 0.6.34.2 x64-mingw-ucrt) leaves the gem resolvable while every
|
|
75
|
+
# parse raises. The parity contract only holds when the engines
|
|
76
|
+
# actually answer a probe — detection then selects them.
|
|
77
|
+
def yeptris_usable?
|
|
78
|
+
yeptris_installed? &&
|
|
79
|
+
Lutaml::Json::Adapter::YeptrisAdapter.available? &&
|
|
80
|
+
Lutaml::Yaml::Adapter::YeptrisAdapter.available?
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
before { skip "yeptris is not usable on this platform" unless yeptris_usable? }
|
|
74
84
|
|
|
75
85
|
it "prefers the yeptris adapters when the engine is installed" do
|
|
76
86
|
expect(outcomes).to include("yaml-adapter: Lutaml::Yaml::Adapter::YeptrisAdapter")
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
require "open3"
|
|
5
|
+
require "lutaml/json/adapter/yeptris_adapter"
|
|
6
|
+
|
|
7
|
+
# Surface 1 of #978: the yeptris lane was selected from a bare
|
|
8
|
+
# constant check, so a process holding a half-initialized Yeptris
|
|
9
|
+
# module (the poison-process state the gem documents) committed to
|
|
10
|
+
# the native lane and failed pre-mapping on valid JSON — while other
|
|
11
|
+
# processes fell back to the standard lane, flipping the adapter
|
|
12
|
+
# choice across runs. Detection now probes the native engine; a
|
|
13
|
+
# broken native deterministically rides the standard lane.
|
|
14
|
+
RSpec.describe Lutaml::Model::AdapterResolver, ".adapter_for yeptris native detection" do
|
|
15
|
+
let(:parse_probe) do
|
|
16
|
+
<<~RUBY
|
|
17
|
+
require "lutaml/model"
|
|
18
|
+
|
|
19
|
+
klass = Class.new(Lutaml::Model::Serializable) do
|
|
20
|
+
attribute :v, :string
|
|
21
|
+
key_value { map "v", to: :v }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
model = klass.from_json('{"v": "scalar"}')
|
|
25
|
+
adapter = Lutaml::Model::AdapterResolver.adapter_for(:json)
|
|
26
|
+
puts "ADAPTER=\#{adapter.name.split('::').last} PARSED=\#{model.v}"
|
|
27
|
+
RUBY
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# The gem resolving is not enough: a binding/native desync leaves
|
|
31
|
+
# yeptris loadable while every parse raises. The healthy-lane spec
|
|
32
|
+
# is only meaningful where the native answers a probe.
|
|
33
|
+
def subprocess_yeptris_capable?
|
|
34
|
+
probe = <<~RUBY
|
|
35
|
+
begin
|
|
36
|
+
require "yeptris"
|
|
37
|
+
require "lutaml/json/adapter/yeptris_adapter"
|
|
38
|
+
exit(Lutaml::Json::Adapter::YeptrisAdapter.available? ? 0 : 1)
|
|
39
|
+
rescue LoadError, StandardError
|
|
40
|
+
exit(1)
|
|
41
|
+
end
|
|
42
|
+
RUBY
|
|
43
|
+
_out, _err, status = Open3.capture3(RbConfig.ruby, "-I", "lib", "-e", probe)
|
|
44
|
+
status.success?
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "resolves the yeptris lane when the native engine answers a probe" do
|
|
48
|
+
skip "optional yeptris engine not resolvable outside the bundle" unless subprocess_yeptris_capable?
|
|
49
|
+
|
|
50
|
+
stdout, stderr, status = Open3.capture3(RbConfig.ruby, "-I", "lib", "-e", parse_probe)
|
|
51
|
+
expect(status).to be_success, stderr
|
|
52
|
+
expect(stdout).to include("ADAPTER=YeptrisAdapter")
|
|
53
|
+
expect(stdout).to include("PARSED=scalar")
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "falls back to the standard lane when the native engine cannot parse" do
|
|
57
|
+
poison = <<~RUBY
|
|
58
|
+
require "lutaml/model"
|
|
59
|
+
require "yeptris"
|
|
60
|
+
require "lutaml/json/adapter/yeptris_adapter"
|
|
61
|
+
|
|
62
|
+
# The poison state: the module is defined and require succeeds,
|
|
63
|
+
# but every native parse fails. Whatever the cause (a stale
|
|
64
|
+
# libyeptris, a half-initialized load), the lane must not be
|
|
65
|
+
# selected.
|
|
66
|
+
Lutaml::Json::Adapter::YeptrisAdapter
|
|
67
|
+
.define_singleton_method(:native_ready?) { false }
|
|
68
|
+
|
|
69
|
+
#{parse_probe}
|
|
70
|
+
RUBY
|
|
71
|
+
|
|
72
|
+
stdout, stderr, status = Open3.capture3(RbConfig.ruby, "-I", "lib", "-e", poison)
|
|
73
|
+
expect(status).to be_success, stderr
|
|
74
|
+
expect(stdout).to include("ADAPTER=StandardAdapter")
|
|
75
|
+
expect(stdout).to include("PARSED=scalar")
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it "reports the adapter unavailable when the native probe fails" do
|
|
79
|
+
allow(Lutaml::Json::Adapter::YeptrisAdapter)
|
|
80
|
+
.to receive(:native_ready?).and_return(false)
|
|
81
|
+
|
|
82
|
+
expect(Lutaml::Json::Adapter::YeptrisAdapter.available?).to be(false)
|
|
83
|
+
ensure
|
|
84
|
+
allow(Lutaml::Json::Adapter::YeptrisAdapter)
|
|
85
|
+
.to receive(:native_ready?).and_call_original
|
|
86
|
+
end
|
|
87
|
+
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.120
|
|
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-21 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: base64
|
|
@@ -155,6 +155,7 @@ files:
|
|
|
155
155
|
- ".envrc"
|
|
156
156
|
- ".github/scripts/test_installed_gem.rb"
|
|
157
157
|
- ".github/workflows/dependent-repos-todo.json"
|
|
158
|
+
- ".github/workflows/dependent-repos-tools.json"
|
|
158
159
|
- ".github/workflows/dependent-repos.json"
|
|
159
160
|
- ".github/workflows/dependent-tests.yml"
|
|
160
161
|
- ".github/workflows/docs.yml"
|
|
@@ -1900,6 +1901,7 @@ files:
|
|
|
1900
1901
|
- spec/lutaml/model/yamls_sequence_spec.rb
|
|
1901
1902
|
- spec/lutaml/model/yamls_spec.rb
|
|
1902
1903
|
- spec/lutaml/model/yeptris_error_parity_spec.rb
|
|
1904
|
+
- spec/lutaml/model/yeptris_native_detection_spec.rb
|
|
1903
1905
|
- spec/lutaml/model_spec.rb
|
|
1904
1906
|
- spec/lutaml/rdf/context_spec.rb
|
|
1905
1907
|
- spec/lutaml/rdf/graph_serialization_spec.rb
|