lutaml-model 0.8.115 → 0.8.116

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: b924b08953808c53f7f6db9f9832ffa870b11a5d2c7fe450b1340d8b2f289562
4
- data.tar.gz: 3ba1f1afe7b2a95e83f137f8d3944e56e0ba516962b261665c4c3b91de74824f
3
+ metadata.gz: bd6d747592ab333f3edefaf4af21e7db87189a39c541bd7c70dda87b544615d8
4
+ data.tar.gz: 2380f18d9b82122602c3afc60695dd2077c2cc125375032673f90721d152fa53
5
5
  SHA512:
6
- metadata.gz: 2d956aca0be2bdbae7e513391962490429057f04ca4371be1477d4bbc29e79f8ad942beffbb40debf27db64f7be7e7c301110832439a3ece8eb4ece5e6c673d9
7
- data.tar.gz: 7a384e7b06e927f9b78a129914de369c2befa23b14e84c6a9c2ba24e769c145dd0b0814fa3f92483516132020ced34c885c71872c251d41a8bdc6dff995b41db
6
+ metadata.gz: d15bea65d1270d4eda9e07bbac48cee6232da11aab2df7bcbd51e74ab1ec8d9ecf2eb217b1b9d302cfdf128a2b51b610bd1062e7bfea1a81a65f68d16f952c43
7
+ data.tar.gz: 976d507e33e4a79de59b767215279bee14aaba443a05bfb8c84918190e236faa19d4383af9a0b3b20c3743dbd95e47404967b37a0611619738bd9fe4667af6bb
@@ -977,6 +977,24 @@ instance_object = nil)
977
977
  end
978
978
 
979
979
  klass = resolve_polymorphic_class(resolved_type, value, options)
980
+ # A scalar handed to a mapped-model attribute crashed
981
+ # apply_mappings with an internal NoMethodError (key? on
982
+ # String, #978). A type declaring its own .cast owns scalar
983
+ # construction; base-cast identity types fall through to the
984
+ # legacy conversion chain, whose parse error names the token.
985
+ if serializable_type?(register) && !value.nil? &&
986
+ !value.is_a?(::Hash) && !value.is_a?(::Array) &&
987
+ !value.respond_to?(:key?) && klass.respond_to?(:cast) &&
988
+ klass.method(:cast).owner == klass.singleton_class
989
+ casted = klass.cast(value)
990
+ return casted if casted.is_a?(klass)
991
+
992
+ raise Lutaml::Model::IncorrectModelError,
993
+ "attribute '#{name}': the #{format} input for type " \
994
+ "#{klass} is a #{value.class}, and #{klass}.cast did " \
995
+ "not build one (received #{casted.class})"
996
+ end
997
+
980
998
  if can_serialize?(klass, value, format, options)
981
999
  propagated = Serialize::DeserializationContext.propagate(options)
982
1000
  klass.apply_mappings(value, format,
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Lutaml
4
4
  module Model
5
- VERSION = "0.8.115"
5
+ VERSION = "0.8.116"
6
6
  end
7
7
  end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ # #978: a JSON scalar handed to a mapped-model attribute crashed with
6
+ # an internal NoMethodError (key? on String) wrapped as
7
+ # InvalidFormatError. A type that declares its own .cast owns scalar
8
+ # construction from that scalar; a cast-less type falls through to the
9
+ # legacy conversion chain, whose parse error surfaces the offending
10
+ # token — the remedy there is declaring .cast on the type.
11
+ RSpec.describe "from_json scalar into a mapped-model attribute" do
12
+ let(:marked_class) do
13
+ Class.new(Lutaml::Model::Serializable) do
14
+ attribute :content, :string
15
+
16
+ key_value do
17
+ map "content", to: :content
18
+ end
19
+
20
+ def self.cast(value)
21
+ return value if value.is_a?(self)
22
+
23
+ new(content: value.to_s)
24
+ end
25
+ end
26
+ end
27
+
28
+ let(:plain_class) do
29
+ Class.new(Lutaml::Model::Serializable) do
30
+ attribute :content, :string
31
+
32
+ key_value do
33
+ map "content", to: :content
34
+ end
35
+ end
36
+ end
37
+
38
+ let(:holder_class) do
39
+ Class.new(Lutaml::Model::Serializable) do
40
+ attribute :description, "ScalarMarked"
41
+ attribute :plain_desc, "ScalarPlain"
42
+
43
+ key_value do
44
+ map "description", to: :description
45
+ map "plain_desc", to: :plain_desc
46
+ end
47
+ end
48
+ end
49
+
50
+ before do
51
+ stub_const("ScalarMarked", marked_class)
52
+ stub_const("ScalarPlain", plain_class)
53
+ stub_const("ScalarHolder", holder_class)
54
+ end
55
+
56
+ it "constructs the mapped value through the type's .cast" do
57
+ model = ScalarHolder.from_json('{"description": "text"}')
58
+
59
+ expect(model.description).to be_a(ScalarMarked)
60
+ expect(model.description.content).to eq("text")
61
+ end
62
+
63
+ it "falls through to the format parse error for a cast-less mapped type" do
64
+ expect { ScalarHolder.from_json('{"plain_desc": "text"}') }
65
+ .to raise_error(
66
+ Lutaml::Model::InvalidFormatError,
67
+ /unexpected token 'text'/,
68
+ )
69
+ end
70
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lutaml-model
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.115
4
+ version: 0.8.116
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
@@ -1750,6 +1750,7 @@ files:
1750
1750
  - spec/lutaml/model/enum_spec.rb
1751
1751
  - spec/lutaml/model/except_spec.rb
1752
1752
  - spec/lutaml/model/finalization_cache_spec.rb
1753
+ - spec/lutaml/model/from_json_scalar_cast_spec.rb
1753
1754
  - spec/lutaml/model/generator_defaults_spec.rb
1754
1755
  - spec/lutaml/model/global_context_spec.rb
1755
1756
  - spec/lutaml/model/global_register_spec.rb