lutaml-model 0.8.103 → 0.8.104
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/lib/lutaml/model/cached_type_resolver.rb +13 -6
- data/lib/lutaml/model/type_resolver.rb +7 -5
- data/lib/lutaml/model/version.rb +1 -1
- data/lib/lutaml/xml/adapter/xml_parser.rb +5 -2
- data/spec/lutaml/model/unregistered_context_resolution_spec.rb +34 -0
- data/spec/lutaml/xml/adapter/empty_document_diagnostics_spec.rb +41 -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: bd4d3ab0b184df92ad1d6ef04af5e1e1af9d483d34902f36d94b010477c54841
|
|
4
|
+
data.tar.gz: 6e5eee3bebcf1b9557b1cf635253b322a5dffc31fcbe1c7e3b07a76143a2100f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 761158fee8d42f919236179a76b90116183afde1cc7e8beb6921c958c27d03c96a6ada9a04abc0959417e34f1ca7677e99b33c00ef38326fe10cf196c0010e4f
|
|
7
|
+
data.tar.gz: 96f3e592216d1f0fe4bc6274ea92006e8db8fb67d77b31dbe79868175d1a42cfa17145ea9ac981d2ba6aaecf9cf9888260a1a33675f6aa7b735667d275270e23
|
|
@@ -59,14 +59,14 @@ module Lutaml
|
|
|
59
59
|
# updates so recursive type resolution can populate related keys.
|
|
60
60
|
#
|
|
61
61
|
# @param name [Symbol, String, Class] The type name or class to resolve
|
|
62
|
-
# @param context [TypeContext] The resolution context
|
|
62
|
+
# @param context [TypeContext, nil] The resolution context
|
|
63
63
|
# @return [Class] The resolved type class
|
|
64
64
|
# @raise [UnknownTypeError] If type cannot be resolved
|
|
65
65
|
def resolve(name, context, materialize: true)
|
|
66
66
|
return @delegate.resolve(name, context, materialize: false) unless materialize
|
|
67
67
|
|
|
68
68
|
cache_key = if name.is_a?(Class)
|
|
69
|
-
[context
|
|
69
|
+
[context_id_for(context), name]
|
|
70
70
|
else
|
|
71
71
|
build_cache_key(name, context)
|
|
72
72
|
end
|
|
@@ -79,11 +79,11 @@ module Lutaml
|
|
|
79
79
|
# Check if a type can be resolved, using cache if available.
|
|
80
80
|
#
|
|
81
81
|
# @param name [Symbol, String, Class] The type name or class to check
|
|
82
|
-
# @param context [TypeContext] The resolution context
|
|
82
|
+
# @param context [TypeContext, nil] The resolution context
|
|
83
83
|
# @return [Boolean] true if type can be resolved
|
|
84
84
|
def resolvable?(name, context)
|
|
85
85
|
cache_key = if name.is_a?(Class)
|
|
86
|
-
[context
|
|
86
|
+
[context_id_for(context), name]
|
|
87
87
|
else
|
|
88
88
|
build_cache_key(name, context)
|
|
89
89
|
end
|
|
@@ -137,10 +137,17 @@ module Lutaml
|
|
|
137
137
|
# Uses array for faster comparison than string concatenation.
|
|
138
138
|
#
|
|
139
139
|
# @param name [Symbol, String] The type name
|
|
140
|
-
# @param context [TypeContext] The resolution context
|
|
140
|
+
# @param context [TypeContext, nil] The resolution context
|
|
141
141
|
# @return [Array] The cache key (faster than string)
|
|
142
142
|
def build_cache_key(name, context)
|
|
143
|
-
[context
|
|
143
|
+
[context_id_for(context), name.to_sym]
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# A nil context (e.g. a register ID that has no registered type
|
|
147
|
+
# context) is a legitimate "no namespace" resolution; the cache
|
|
148
|
+
# key just forgoes the namespace slot.
|
|
149
|
+
def context_id_for(context)
|
|
150
|
+
context&.id
|
|
144
151
|
end
|
|
145
152
|
end
|
|
146
153
|
end
|
|
@@ -44,7 +44,9 @@ module Lutaml
|
|
|
44
44
|
# 5. Raise UnknownTypeError if not found anywhere
|
|
45
45
|
#
|
|
46
46
|
# @param name [Symbol, String, Class] The type name or class to resolve
|
|
47
|
-
# @param context [TypeContext] The resolution context
|
|
47
|
+
# @param context [TypeContext, nil] The resolution context (nil means
|
|
48
|
+
# no primary registry and no fallbacks — an id registered in the
|
|
49
|
+
# Register namespace but not as a type context)
|
|
48
50
|
# @return [Class] The resolved type class
|
|
49
51
|
# @raise [UnknownTypeError] If type cannot be resolved
|
|
50
52
|
#
|
|
@@ -66,11 +68,11 @@ module Lutaml
|
|
|
66
68
|
type_name = name.to_sym
|
|
67
69
|
|
|
68
70
|
# 1. Check primary registry
|
|
69
|
-
type = context
|
|
71
|
+
type = context&.lookup_local(type_name)
|
|
70
72
|
return apply_substitutions(type, context) if type
|
|
71
73
|
|
|
72
74
|
# 2. Check fallback contexts in order
|
|
73
|
-
if context
|
|
75
|
+
if context&.has_fallbacks?
|
|
74
76
|
context.fallback_contexts.each do |fallback_context|
|
|
75
77
|
type = resolve_from_fallback(type_name, fallback_context)
|
|
76
78
|
return apply_substitutions(type, context) if type
|
|
@@ -97,8 +99,8 @@ module Lutaml
|
|
|
97
99
|
# 5. Type not found - raise error
|
|
98
100
|
raise UnknownTypeError.new(
|
|
99
101
|
type_name,
|
|
100
|
-
context_id: context
|
|
101
|
-
available_types: available_type_names(context),
|
|
102
|
+
context_id: context&.id,
|
|
103
|
+
available_types: context ? available_type_names(context) : [],
|
|
102
104
|
)
|
|
103
105
|
end
|
|
104
106
|
|
data/lib/lutaml/model/version.rb
CHANGED
|
@@ -23,7 +23,7 @@ module Lutaml
|
|
|
23
23
|
assert_no_truncated_recovered_parse!(parsed)
|
|
24
24
|
root_element = parsed.root
|
|
25
25
|
|
|
26
|
-
raise_empty_document_error if root_element.nil?
|
|
26
|
+
raise_empty_document_error(parsed.parse_errors) if root_element.nil?
|
|
27
27
|
|
|
28
28
|
root = self::PARSED_ELEMENT_CLASS.new(root_element)
|
|
29
29
|
doc_pis = extract_document_processing_instructions(parsed)
|
|
@@ -112,8 +112,11 @@ module Lutaml
|
|
|
112
112
|
}
|
|
113
113
|
end
|
|
114
114
|
|
|
115
|
-
def raise_empty_document_error
|
|
115
|
+
def raise_empty_document_error(parse_errors = nil)
|
|
116
116
|
message = self::EMPTY_DOCUMENT_ERROR_MESSAGE
|
|
117
|
+
if parse_errors && !parse_errors.empty?
|
|
118
|
+
message += " (the XML engine reported: #{parse_errors.join('; ')})"
|
|
119
|
+
end
|
|
117
120
|
|
|
118
121
|
case self::EMPTY_DOCUMENT_ERROR_TYPE
|
|
119
122
|
when :parse_exception
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
|
|
5
|
+
# Register ids and type-context ids are two namespaces that
|
|
6
|
+
# GlobalContext#resolve_type bridges implicitly: an id present only in the
|
|
7
|
+
# Register namespace (a flavor's `lutaml_default_register`) resolves to a
|
|
8
|
+
# nil type context, and every resolution shape must treat that as a
|
|
9
|
+
# legitimate "no namespace" input instead of crashing (metanorma-jis#531).
|
|
10
|
+
RSpec.describe "type resolution through a register id with no registered type context" do
|
|
11
|
+
let(:collection_class) do
|
|
12
|
+
Class.new(Lutaml::Model::Collection) do
|
|
13
|
+
instances :entries, :string
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "resolves collection instance types under a nil context" do
|
|
18
|
+
collection = collection_class.new(["a"], lutaml_register: :jis_document)
|
|
19
|
+
|
|
20
|
+
expect(collection.entries).to eq(["a"])
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "resolves built-in symbol names under a nil context" do
|
|
24
|
+
resolved = Lutaml::Model::GlobalContext.resolve_type(:string, :jis_document)
|
|
25
|
+
|
|
26
|
+
expect(resolved).to eq(Lutaml::Model::Type::String)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "raises UnknownTypeError for unknown names under a nil context" do
|
|
30
|
+
expect do
|
|
31
|
+
Lutaml::Model::GlobalContext.resolve_type(:no_such_type, :jis_document)
|
|
32
|
+
end.to raise_error(Lutaml::Model::UnknownTypeError)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
require "lutaml/xml/adapter/leptris_adapter"
|
|
5
|
+
require "lutaml/xml/adapter/nokogiri_adapter"
|
|
6
|
+
|
|
7
|
+
# A failed parse reaches the empty-document guard as a document with no
|
|
8
|
+
# root, indistinguishable from genuinely empty input. The engine's parse
|
|
9
|
+
# diagnostics ride the document (moxml attachments :parse_errors) and
|
|
10
|
+
# must surface in the raised message — otherwise the error names the
|
|
11
|
+
# input's emptiness while the input is neither empty nor the problem
|
|
12
|
+
# (lutaml-model#956).
|
|
13
|
+
RSpec.describe "empty-document errors surface engine parse diagnostics" do
|
|
14
|
+
describe Lutaml::Xml::Adapter::LeptrisAdapter do
|
|
15
|
+
it "appends the engine diagnostic when the parse failed" do
|
|
16
|
+
expect do
|
|
17
|
+
described_class.parse("<root><a>x</b></root>")
|
|
18
|
+
end.to raise_error(Lutaml::Model::InvalidFormatError) do |error|
|
|
19
|
+
expect(error.message).to include("the XML engine reported:")
|
|
20
|
+
expect(error.message).to include("XML parse error at byte 14")
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "reports the engine diagnostic for whitespace-only input" do
|
|
25
|
+
expect do
|
|
26
|
+
described_class.parse(" ")
|
|
27
|
+
end.to raise_error(Lutaml::Model::InvalidFormatError, /the XML engine reported:/)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
describe Lutaml::Xml::Adapter::NokogiriAdapter do
|
|
32
|
+
it "keeps the plain empty-document message when the engine reported nothing" do
|
|
33
|
+
expect do
|
|
34
|
+
described_class.parse("")
|
|
35
|
+
end.to raise_error(Lutaml::Model::InvalidFormatError) do |error|
|
|
36
|
+
expect(error.message).to include("The XML may be empty")
|
|
37
|
+
expect(error.message).not_to include("the XML engine reported:")
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
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.104
|
|
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-12 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: base64
|
|
@@ -1863,6 +1863,7 @@ files:
|
|
|
1863
1863
|
- spec/lutaml/model/uninitialized_class_spec.rb
|
|
1864
1864
|
- spec/lutaml/model/union_attribute_spec.rb
|
|
1865
1865
|
- spec/lutaml/model/union_spec.rb
|
|
1866
|
+
- spec/lutaml/model/unregistered_context_resolution_spec.rb
|
|
1866
1867
|
- spec/lutaml/model/utils_spec.rb
|
|
1867
1868
|
- spec/lutaml/model/validation/concerns/has_issues_spec.rb
|
|
1868
1869
|
- spec/lutaml/model/validation/context_spec.rb
|
|
@@ -1913,6 +1914,7 @@ files:
|
|
|
1913
1914
|
- spec/lutaml/turtle/mapping_spec.rb
|
|
1914
1915
|
- spec/lutaml/turtle/transform_spec.rb
|
|
1915
1916
|
- spec/lutaml/xml/adapter/base_adapter_regression_spec.rb
|
|
1917
|
+
- spec/lutaml/xml/adapter/empty_document_diagnostics_spec.rb
|
|
1916
1918
|
- spec/lutaml/xml/adapter/nokogiri_adapter_spec.rb
|
|
1917
1919
|
- spec/lutaml/xml/adapter/oga_adapter_spec.rb
|
|
1918
1920
|
- spec/lutaml/xml/adapter/order_spec.rb
|