ree_lib 1.0.85 → 1.0.87
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/Gemfile.lock +31 -26
- data/lib/ree_lib/packages/ree_actions/package/ree_actions/dsl.rb +11 -3
- data/lib/ree_lib/packages/ree_actions/package/ree_actions/errors.rb +3 -0
- data/lib/ree_lib/packages/ree_actions/package/ree_actions.rb +1 -0
- data/lib/ree_lib/packages/ree_actions/spec/ree_actions/dsl_spec.rb +5 -1
- data/lib/ree_lib/packages/ree_dao/package/ree_dao/wrappers/pg_array.rb +12 -8
- data/lib/ree_lib/packages/ree_dao/package/ree_dao/wrappers/pg_jsonb.rb +12 -8
- data/lib/ree_lib/packages/ree_dao/spec/ree_dao/wrappers/pg_array_spec.rb +3 -3
- data/lib/ree_lib/packages/ree_dao/spec/ree_dao/wrappers/pg_jsonb_spec.rb +8 -6
- data/lib/ree_lib/packages/ree_enum/package/ree_enum/base_enum_mapper.rb +5 -10
- data/lib/ree_lib/packages/ree_enum/package/ree_enum/integer_value_enum_mapper.rb +5 -5
- data/lib/ree_lib/packages/ree_enum/package/ree_enum/string_value_enum_mapper.rb +5 -5
- data/lib/ree_lib/packages/ree_enum/spec/ree_enum/dsl_spec.rb +10 -2
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/errors/coercion_error.rb +1 -1
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/errors/error_with_location.rb +25 -0
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/errors/type_error.rb +1 -1
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/field.rb +12 -4
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/mapper.rb +12 -6
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/mapper_factory.rb +17 -4
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/types/abstract_type.rb +6 -0
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/types/any.rb +8 -8
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/types/bool.rb +12 -12
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/types/date.rb +13 -13
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/types/date_time.rb +13 -13
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/types/float.rb +13 -13
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/types/integer.rb +16 -16
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/types/rational.rb +13 -13
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/types/string.rb +12 -12
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/types/time.rb +13 -13
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/wrappers/abstract_wrapper.rb +7 -0
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/wrappers/array.rb +73 -21
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper.rb +2 -0
- data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/mapper_factory_spec.rb +10 -6
- data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/mapper_spec.rb +7 -0
- data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/types/bool_spec.rb +10 -8
- data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/types/date_spec.rb +12 -10
- data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/types/date_time_spec.rb +20 -16
- data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/types/float_spec.rb +17 -13
- data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/types/hash_spec.rb +1 -1
- data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/types/integer_spec.rb +14 -14
- data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/types/rational_spec.rb +16 -12
- data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/types/string_spec.rb +24 -12
- data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/types/time_spec.rb +21 -16
- data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/types/type_options_spec.rb +4 -4
- data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/wrappers/array_spec.rb +6 -6
- data/lib/ree_lib/packages/ree_roda/package/ree_roda/app.rb +3 -2
- data/lib/ree_lib/packages/ree_roda/spec/ree_roda/app_spec.rb +28 -0
- data/lib/ree_lib/spec.init.rb +3 -1
- data/lib/ree_lib/version.rb +1 -1
- metadata +19 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b5c70eda05d58f496b0eca7cbc95f853dd51c8b9e33b23c1fa1b51a74eb58104
|
4
|
+
data.tar.gz: bf15e2be0aa79c7696ec9bfb074c3748c7061a5aec1079c5fa208aa1cbc16f1c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c068ce8ba9567eab38bd06c0bdc01731f223f1f4126ac70f5d49c9fc40a9e5034cb7e3cfb2fd84ef578018a31dd5934b6c9283b9a72b3d58e69bdf265af481ca
|
7
|
+
data.tar.gz: e2f1b8a4428e46d27e40f98d9134d47139c5de080eef52eeee63cf5cf9eb86fb76fdc54b6d437c810f8a8d5b71889e180903ee8dce4463e82ec2f2769c3bffdf
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.
|
1
|
+
3.3.0
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
ree_lib (1.0.
|
4
|
+
ree_lib (1.0.87)
|
5
|
+
bigdecimal (~> 3.1.6)
|
5
6
|
binding_of_caller (~> 1.0.0)
|
6
7
|
i18n (~> 1.12.0)
|
7
8
|
loofah (~> 2.18.0)
|
@@ -14,46 +15,49 @@ PATH
|
|
14
15
|
GEM
|
15
16
|
remote: https://rubygems.org/
|
16
17
|
specs:
|
17
|
-
|
18
|
+
abbrev (0.1.2)
|
19
|
+
addressable (2.8.6)
|
18
20
|
public_suffix (>= 2.0.2, < 6.0)
|
21
|
+
bigdecimal (3.1.6)
|
19
22
|
binding_of_caller (1.0.0)
|
20
23
|
debug_inspector (>= 0.0.1)
|
21
|
-
bootsnap (1.
|
24
|
+
bootsnap (1.17.0)
|
22
25
|
msgpack (~> 1.2)
|
23
|
-
commander (
|
24
|
-
highline (~>
|
26
|
+
commander (5.0.0)
|
27
|
+
highline (~> 3.0.0)
|
25
28
|
concurrent-ruby (1.2.2)
|
26
29
|
crack (0.4.5)
|
27
30
|
rexml
|
28
31
|
crass (1.0.6)
|
29
|
-
debug_inspector (1.
|
32
|
+
debug_inspector (1.2.0)
|
30
33
|
diff-lcs (1.5.0)
|
31
|
-
faker (3.2.
|
34
|
+
faker (3.2.2)
|
32
35
|
i18n (>= 1.8.11, < 2)
|
33
|
-
hashdiff (1.0
|
34
|
-
highline (
|
36
|
+
hashdiff (1.1.0)
|
37
|
+
highline (3.0.0)
|
38
|
+
abbrev
|
35
39
|
i18n (1.12.0)
|
36
40
|
concurrent-ruby (~> 1.0)
|
37
41
|
loofah (2.18.0)
|
38
42
|
crass (~> 1.0.2)
|
39
43
|
nokogiri (>= 1.5.9)
|
40
|
-
msgpack (1.
|
41
|
-
nokogiri (1.
|
44
|
+
msgpack (1.7.2)
|
45
|
+
nokogiri (1.16.0-x86_64-darwin)
|
42
46
|
racc (~> 1.4)
|
43
|
-
nokogiri (1.
|
47
|
+
nokogiri (1.16.0-x86_64-linux)
|
44
48
|
racc (~> 1.4)
|
45
49
|
oj (3.13.23)
|
46
50
|
pg (1.4.6)
|
47
|
-
public_suffix (5.0.
|
51
|
+
public_suffix (5.0.4)
|
48
52
|
racc (1.7.3)
|
49
|
-
rack (3.0.
|
50
|
-
rack-test (2.0
|
53
|
+
rack (3.0.8)
|
54
|
+
rack-test (2.1.0)
|
51
55
|
rack (>= 1.3)
|
52
56
|
rainbow (3.1.1)
|
53
|
-
rake (13.0
|
54
|
-
ree (1.0.
|
55
|
-
commander (~>
|
56
|
-
rexml (3.2.
|
57
|
+
rake (13.1.0)
|
58
|
+
ree (1.0.34)
|
59
|
+
commander (~> 5.0.0)
|
60
|
+
rexml (3.2.6)
|
57
61
|
roda (3.58.0)
|
58
62
|
rack
|
59
63
|
rollbar (3.3.3)
|
@@ -61,23 +65,23 @@ GEM
|
|
61
65
|
rspec-core (~> 3.12.0)
|
62
66
|
rspec-expectations (~> 3.12.0)
|
63
67
|
rspec-mocks (~> 3.12.0)
|
64
|
-
rspec-core (3.12.
|
68
|
+
rspec-core (3.12.2)
|
65
69
|
rspec-support (~> 3.12.0)
|
66
|
-
rspec-expectations (3.12.
|
70
|
+
rspec-expectations (3.12.3)
|
67
71
|
diff-lcs (>= 1.2.0, < 2.0)
|
68
72
|
rspec-support (~> 3.12.0)
|
69
|
-
rspec-mocks (3.12.
|
73
|
+
rspec-mocks (3.12.6)
|
70
74
|
diff-lcs (>= 1.2.0, < 2.0)
|
71
75
|
rspec-support (~> 3.12.0)
|
72
|
-
rspec-support (3.12.
|
76
|
+
rspec-support (3.12.1)
|
73
77
|
sequel (5.58.0)
|
74
78
|
sqlite3 (1.4.4)
|
75
|
-
timecop (0.9.
|
79
|
+
timecop (0.9.8)
|
76
80
|
tzinfo (2.0.6)
|
77
81
|
concurrent-ruby (~> 1.0)
|
78
82
|
warden (1.2.9)
|
79
83
|
rack (>= 2.0.9)
|
80
|
-
webmock (3.
|
84
|
+
webmock (3.19.1)
|
81
85
|
addressable (>= 2.8.0)
|
82
86
|
crack (>= 0.3.2)
|
83
87
|
hashdiff (>= 0.4.0, < 2.0.0)
|
@@ -85,6 +89,7 @@ GEM
|
|
85
89
|
PLATFORMS
|
86
90
|
x86_64-darwin-19
|
87
91
|
x86_64-darwin-21
|
92
|
+
x86_64-darwin-22
|
88
93
|
x86_64-linux
|
89
94
|
|
90
95
|
DEPENDENCIES
|
@@ -103,4 +108,4 @@ DEPENDENCIES
|
|
103
108
|
webmock
|
104
109
|
|
105
110
|
BUNDLED WITH
|
106
|
-
2.
|
111
|
+
2.5.4
|
@@ -1,3 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
package_require("ree_mapper/errors/type_error")
|
3
|
+
package_require("ree_mapper/errors/coercion_error")
|
4
|
+
|
1
5
|
module ReeActions
|
2
6
|
module DSL
|
3
7
|
def self.included(base)
|
@@ -57,10 +61,14 @@ module ReeActions
|
|
57
61
|
raise ArgumentError.new("ActionCaster does not respond to `cast` method")
|
58
62
|
end
|
59
63
|
|
60
|
-
|
61
|
-
|
62
|
-
|
64
|
+
attrs = begin
|
65
|
+
caster.cast(attrs)
|
66
|
+
rescue ReeMapper::TypeError, ReeMapper::CoercionError => e
|
67
|
+
raise ReeActions::ParamError, e.message
|
68
|
+
end
|
63
69
|
end
|
70
|
+
|
71
|
+
__original_call(user_access, attrs)
|
64
72
|
ensure
|
65
73
|
__ree_dao_drop_cache
|
66
74
|
end
|
@@ -59,6 +59,10 @@ RSpec.describe ReeActions::DSL, type: [:autoclean] do
|
|
59
59
|
|
60
60
|
result = ReeActionsTest::TestAction.new.call('user_access', {user_id: 1})
|
61
61
|
expect(result).to eq(1)
|
62
|
+
|
63
|
+
expect {
|
64
|
+
ReeActionsTest::TestAction.new.call('user_access', {user_id: 'not integer'})
|
65
|
+
}.to raise_error(ReeActions::ParamError)
|
62
66
|
}
|
63
67
|
|
64
68
|
it {
|
@@ -161,7 +165,7 @@ RSpec.describe ReeActions::DSL, type: [:autoclean] do
|
|
161
165
|
users_dao.put(ReeActionsTest::User.new(name: 'Sam', age: 19))
|
162
166
|
end.join
|
163
167
|
end.join
|
164
|
-
|
168
|
+
|
165
169
|
$thread_cache = ReeDao::DaoCache.new.get(:users, $user.id)
|
166
170
|
|
167
171
|
attrs[:user_id]
|
@@ -8,12 +8,13 @@ class ReeDao::PgArray < ReeMapper::AbstractWrapper
|
|
8
8
|
Kwargs[
|
9
9
|
name: String,
|
10
10
|
role: Nilor[Symbol, ArrayOf[Symbol]],
|
11
|
-
fields_filters: ArrayOf[ReeMapper::FieldsFilter]
|
11
|
+
fields_filters: ArrayOf[ReeMapper::FieldsFilter],
|
12
|
+
location: Nilor[String],
|
12
13
|
] => Or[Sequel::Postgres::PGArray, String]
|
13
14
|
)
|
14
|
-
def db_dump(value, name:, role: nil, fields_filters: [])
|
15
|
+
def db_dump(value, name:, role: nil, fields_filters: [], location: nil)
|
15
16
|
if !value.is_a?(Array)
|
16
|
-
raise ReeMapper::TypeError
|
17
|
+
raise ReeMapper::TypeError.new("`#{name}` should be an array, got `#{truncate(value.inspect)}`", location)
|
17
18
|
end
|
18
19
|
|
19
20
|
value = value.map.with_index do |el, index|
|
@@ -21,7 +22,8 @@ class ReeDao::PgArray < ReeMapper::AbstractWrapper
|
|
21
22
|
el,
|
22
23
|
name: "#{name}[#{index}]",
|
23
24
|
role: role,
|
24
|
-
fields_filters: fields_filters + [subject.fields_filter]
|
25
|
+
fields_filters: fields_filters + [subject.fields_filter],
|
26
|
+
location: subject.location,
|
25
27
|
)
|
26
28
|
end
|
27
29
|
|
@@ -37,12 +39,13 @@ class ReeDao::PgArray < ReeMapper::AbstractWrapper
|
|
37
39
|
Kwargs[
|
38
40
|
name: String,
|
39
41
|
role: Nilor[Symbol, ArrayOf[Symbol]],
|
40
|
-
fields_filters: ArrayOf[ReeMapper::FieldsFilter]
|
42
|
+
fields_filters: ArrayOf[ReeMapper::FieldsFilter],
|
43
|
+
location: Nilor[String],
|
41
44
|
] => Array
|
42
45
|
).throws(ReeMapper::TypeError)
|
43
|
-
def db_load(value, name:, role: nil, fields_filters: [])
|
46
|
+
def db_load(value, name:, role: nil, fields_filters: [], location: nil)
|
44
47
|
if !value.is_a?(Sequel::Postgres::PGArray)
|
45
|
-
raise ReeMapper::TypeError
|
48
|
+
raise ReeMapper::TypeError.new("`#{name}` should be a Sequel::Postgres::PGArray, got `#{truncate(value.inspect)}`", location)
|
46
49
|
end
|
47
50
|
|
48
51
|
value.map.with_index do |val, index|
|
@@ -50,7 +53,8 @@ class ReeDao::PgArray < ReeMapper::AbstractWrapper
|
|
50
53
|
val,
|
51
54
|
name: "#{name}[#{index}]",
|
52
55
|
role: role,
|
53
|
-
fields_filters: fields_filters + [subject.fields_filter]
|
56
|
+
fields_filters: fields_filters + [subject.fields_filter],
|
57
|
+
location: subject.location,
|
54
58
|
)
|
55
59
|
end
|
56
60
|
end
|
@@ -8,7 +8,8 @@ class ReeDao::PgJsonb < ReeMapper::AbstractWrapper
|
|
8
8
|
Kwargs[
|
9
9
|
name: String,
|
10
10
|
role: Nilor[Symbol, ArrayOf[Symbol]],
|
11
|
-
fields_filters: ArrayOf[ReeMapper::FieldsFilter]
|
11
|
+
fields_filters: ArrayOf[ReeMapper::FieldsFilter],
|
12
|
+
location: Nilor[String],
|
12
13
|
] => Or[
|
13
14
|
Sequel::Postgres::JSONBHash,
|
14
15
|
Sequel::Postgres::JSONBArray,
|
@@ -20,18 +21,19 @@ class ReeDao::PgJsonb < ReeMapper::AbstractWrapper
|
|
20
21
|
Sequel::Postgres::JSONBNull
|
21
22
|
]
|
22
23
|
).throws(ReeMapper::TypeError)
|
23
|
-
def db_dump(value, name:, role: nil, fields_filters: [])
|
24
|
+
def db_dump(value, name:, role: nil, fields_filters: [], location: nil)
|
24
25
|
value = subject.type.db_dump(
|
25
26
|
value,
|
26
27
|
name: name,
|
27
28
|
role: role,
|
28
|
-
fields_filters: fields_filters + [subject.fields_filter]
|
29
|
+
fields_filters: fields_filters + [subject.fields_filter],
|
30
|
+
location: subject.location,
|
29
31
|
)
|
30
32
|
|
31
33
|
begin
|
32
34
|
Sequel.pg_jsonb_wrap(value)
|
33
35
|
rescue Sequel::Error
|
34
|
-
raise ReeMapper::TypeError
|
36
|
+
raise ReeMapper::TypeError.new("`#{name}` should be an jsonb primitive, got `#{truncate(value.inspect)}`", location)
|
35
37
|
end
|
36
38
|
end
|
37
39
|
|
@@ -40,7 +42,8 @@ class ReeDao::PgJsonb < ReeMapper::AbstractWrapper
|
|
40
42
|
Kwargs[
|
41
43
|
name: String,
|
42
44
|
role: Nilor[Symbol, ArrayOf[Symbol]],
|
43
|
-
fields_filters: ArrayOf[ReeMapper::FieldsFilter]
|
45
|
+
fields_filters: ArrayOf[ReeMapper::FieldsFilter],
|
46
|
+
location: Nilor[String],
|
44
47
|
] => Or[
|
45
48
|
Hash,
|
46
49
|
Array,
|
@@ -52,7 +55,7 @@ class ReeDao::PgJsonb < ReeMapper::AbstractWrapper
|
|
52
55
|
Rational,
|
53
56
|
]
|
54
57
|
).throws(ReeMapper::TypeError)
|
55
|
-
def db_load(value, name:, role: nil, fields_filters: [])
|
58
|
+
def db_load(value, name:, role: nil, fields_filters: [], location: nil)
|
56
59
|
value = case value
|
57
60
|
when Sequel::Postgres::JSONBHash
|
58
61
|
ReeObject::ToHash.new.call(value.to_h)
|
@@ -61,14 +64,15 @@ class ReeDao::PgJsonb < ReeMapper::AbstractWrapper
|
|
61
64
|
when Numeric, String, TrueClass, FalseClass, NilClass
|
62
65
|
value
|
63
66
|
else
|
64
|
-
raise ReeMapper::TypeError
|
67
|
+
raise ReeMapper::TypeError.new("`#{name}` should be a Sequel::Postgres::JSONB, got `#{truncate(value.inspect)}`", location)
|
65
68
|
end
|
66
69
|
|
67
70
|
subject.type.db_load(
|
68
71
|
value,
|
69
72
|
name: name,
|
70
73
|
role: role,
|
71
|
-
fields_filters: fields_filters + [subject.fields_filter]
|
74
|
+
fields_filters: fields_filters + [subject.fields_filter],
|
75
|
+
location: subject.location,
|
72
76
|
)
|
73
77
|
end
|
74
78
|
end
|
@@ -46,7 +46,7 @@ RSpec.describe 'ReeDao::PgArray' do
|
|
46
46
|
it {
|
47
47
|
expect {
|
48
48
|
mapper.db_dump({ tags: 1 })
|
49
|
-
}.to raise_error(ReeMapper::TypeError,
|
49
|
+
}.to raise_error(ReeMapper::TypeError, /`tags` should be an array, got `1`/)
|
50
50
|
}
|
51
51
|
end
|
52
52
|
|
@@ -66,7 +66,7 @@ RSpec.describe 'ReeDao::PgArray' do
|
|
66
66
|
mapper.db_load({
|
67
67
|
tags: 1
|
68
68
|
})
|
69
|
-
}.to raise_error(ReeMapper::TypeError,
|
69
|
+
}.to raise_error(ReeMapper::TypeError, /`tags` should be a Sequel::Postgres::PGArray, got `1`/)
|
70
70
|
}
|
71
71
|
end
|
72
|
-
end
|
72
|
+
end
|
@@ -55,13 +55,14 @@ RSpec.describe 'ReeDao::PgJsonb' do
|
|
55
55
|
it {
|
56
56
|
expect {
|
57
57
|
mapper.db_dump({ numbers: ['1'] })
|
58
|
-
}.to raise_error(ReeMapper::TypeError,
|
58
|
+
}.to raise_error(ReeMapper::TypeError, /`numbers\[0\]` should be an integer, got `\"1\"`/)
|
59
59
|
}
|
60
60
|
|
61
61
|
it {
|
62
|
+
object = Object.new
|
62
63
|
expect {
|
63
|
-
mapper.db_dump({ any:
|
64
|
-
}.to raise_error(ReeMapper::TypeError,
|
64
|
+
mapper.db_dump({ any: object })
|
65
|
+
}.to raise_error(ReeMapper::TypeError, /`any` should be an jsonb primitive, got `#{object.inspect}`/)
|
65
66
|
}
|
66
67
|
end
|
67
68
|
|
@@ -87,13 +88,14 @@ RSpec.describe 'ReeDao::PgJsonb' do
|
|
87
88
|
it {
|
88
89
|
expect {
|
89
90
|
mapper.db_load({ numbers: Sequel::Postgres::JSONBArray.new([1.1]) })
|
90
|
-
}.to raise_error(ReeMapper::TypeError,
|
91
|
+
}.to raise_error(ReeMapper::TypeError, /`numbers\[0\]` should be an integer, got `1.1`/)
|
91
92
|
}
|
92
93
|
|
93
94
|
it {
|
95
|
+
object = Object.new
|
94
96
|
expect {
|
95
|
-
mapper.db_load({ numbers:
|
96
|
-
}.to raise_error(ReeMapper::TypeError,
|
97
|
+
mapper.db_load({ numbers: object })
|
98
|
+
}.to raise_error(ReeMapper::TypeError, /`numbers` should be a Sequel::Postgres::JSONB, got `#{object.inspect}`/)
|
97
99
|
}
|
98
100
|
end
|
99
101
|
end
|
@@ -12,10 +12,10 @@ class ReeEnum::BaseEnumMapper < ReeMapper::AbstractType
|
|
12
12
|
ReeEnum::Value,
|
13
13
|
Kwargs[
|
14
14
|
name: String,
|
15
|
-
|
15
|
+
location: Nilor[String],
|
16
16
|
] => Or[Integer, String]
|
17
17
|
)
|
18
|
-
def db_dump(value, name:,
|
18
|
+
def db_dump(value, name:, location: nil)
|
19
19
|
value.mapped_value
|
20
20
|
end
|
21
21
|
|
@@ -23,14 +23,14 @@ class ReeEnum::BaseEnumMapper < ReeMapper::AbstractType
|
|
23
23
|
Or[Integer, String],
|
24
24
|
Kwargs[
|
25
25
|
name: String,
|
26
|
-
|
26
|
+
location: Nilor[String],
|
27
27
|
] => ReeEnum::Value
|
28
28
|
).throws(ReeMapper::CoercionError)
|
29
|
-
def db_load(value, name:,
|
29
|
+
def db_load(value, name:, location: nil)
|
30
30
|
enum_val = @enum.get_values.by_mapped_value(value)
|
31
31
|
|
32
32
|
if !enum_val
|
33
|
-
raise ReeMapper::CoercionError
|
33
|
+
raise ReeMapper::CoercionError.new("`#{name}` should be one of #{enum_inspection}, got `#{truncate(value.inspect)}`", location)
|
34
34
|
end
|
35
35
|
|
36
36
|
enum_val
|
@@ -41,9 +41,4 @@ class ReeEnum::BaseEnumMapper < ReeMapper::AbstractType
|
|
41
41
|
def enum_inspection
|
42
42
|
@enum_inspection ||= truncate(@enum.get_values.each.map(&:to_s).inspect)
|
43
43
|
end
|
44
|
-
|
45
|
-
def truncate(str, limit = 180)
|
46
|
-
return str if str.length <= limit
|
47
|
-
"#{str[0..limit]}..."
|
48
|
-
end
|
49
44
|
end
|
@@ -6,10 +6,10 @@ class ReeEnum::IntegerValueEnumMapper < ReeEnum::BaseEnumMapper
|
|
6
6
|
ReeEnum::Value,
|
7
7
|
Kwargs[
|
8
8
|
name: String,
|
9
|
-
|
9
|
+
location: Nilor[String],
|
10
10
|
] => Integer
|
11
11
|
)
|
12
|
-
def serialize(value, name:,
|
12
|
+
def serialize(value, name:, location: nil)
|
13
13
|
value.value
|
14
14
|
end
|
15
15
|
|
@@ -17,10 +17,10 @@ class ReeEnum::IntegerValueEnumMapper < ReeEnum::BaseEnumMapper
|
|
17
17
|
Any,
|
18
18
|
Kwargs[
|
19
19
|
name: String,
|
20
|
-
|
20
|
+
location: Nilor[String],
|
21
21
|
] => ReeEnum::Value
|
22
22
|
).throws(ReeMapper::CoercionError)
|
23
|
-
def cast(value, name:,
|
23
|
+
def cast(value, name:, location: nil)
|
24
24
|
enum_value = case value
|
25
25
|
when Integer
|
26
26
|
@enum.get_values.by_value(value)
|
@@ -34,7 +34,7 @@ class ReeEnum::IntegerValueEnumMapper < ReeEnum::BaseEnumMapper
|
|
34
34
|
end
|
35
35
|
|
36
36
|
if enum_value.nil?
|
37
|
-
raise ReeMapper::CoercionError
|
37
|
+
raise ReeMapper::CoercionError.new("`#{name}` should be one of #{enum_inspection}, got `#{truncate(value.inspect)}`", location)
|
38
38
|
end
|
39
39
|
|
40
40
|
enum_value
|
@@ -6,10 +6,10 @@ class ReeEnum::StringValueEnumMapper < ReeEnum::BaseEnumMapper
|
|
6
6
|
ReeEnum::Value,
|
7
7
|
Kwargs[
|
8
8
|
name: String,
|
9
|
-
|
9
|
+
location: Nilor[String],
|
10
10
|
] => String
|
11
11
|
)
|
12
|
-
def serialize(value, name:,
|
12
|
+
def serialize(value, name:, location: nil)
|
13
13
|
value.value
|
14
14
|
end
|
15
15
|
|
@@ -17,10 +17,10 @@ class ReeEnum::StringValueEnumMapper < ReeEnum::BaseEnumMapper
|
|
17
17
|
Any,
|
18
18
|
Kwargs[
|
19
19
|
name: String,
|
20
|
-
|
20
|
+
location: Nilor[String],
|
21
21
|
] => ReeEnum::Value
|
22
22
|
).throws(ReeMapper::CoercionError)
|
23
|
-
def cast(value, name:,
|
23
|
+
def cast(value, name:, location: nil)
|
24
24
|
enum_value = case value
|
25
25
|
when String
|
26
26
|
@enum.get_values.by_value(value)
|
@@ -29,7 +29,7 @@ class ReeEnum::StringValueEnumMapper < ReeEnum::BaseEnumMapper
|
|
29
29
|
end
|
30
30
|
|
31
31
|
if enum_value.nil?
|
32
|
-
raise ReeMapper::CoercionError
|
32
|
+
raise ReeMapper::CoercionError.new("`#{name}` should be one of #{enum_inspection}, got `#{truncate(value.inspect)}`", location)
|
33
33
|
end
|
34
34
|
|
35
35
|
enum_value
|
@@ -152,7 +152,15 @@ RSpec.describe ReeEnum::DSL do
|
|
152
152
|
type: 'invalid',
|
153
153
|
number: 0,
|
154
154
|
})
|
155
|
-
|
155
|
+
}.to raise_error(ReeMapper::CoercionError, /`type` should be one of \["account"\], got `"invalid"`/)
|
156
|
+
|
157
|
+
expect {
|
158
|
+
mapper.db_load({
|
159
|
+
state: 'first',
|
160
|
+
type: 'invalid',
|
161
|
+
number: 0,
|
162
|
+
})
|
163
|
+
}.to raise_error(ReeMapper::CoercionError, /`type` should be one of \["account"\], got `"invalid"`/)
|
156
164
|
|
157
165
|
expect(
|
158
166
|
mapper.cast({
|
@@ -234,4 +242,4 @@ RSpec.describe ReeEnum::DSL do
|
|
234
242
|
swagger_definition_fetcher.call(TestReeEnum::ContentTypes.type_for_mapper, -> {})
|
235
243
|
)
|
236
244
|
}
|
237
|
-
end
|
245
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class ReeMapper::ErrorWithLocation < ReeMapper::Error
|
4
|
+
attr_reader :location
|
5
|
+
|
6
|
+
def initialize(message, location = nil)
|
7
|
+
if message.is_a?(String) && location && ENV["RUBY_ENV"] == "test"
|
8
|
+
message = "#{message}, located at #{location}"
|
9
|
+
end
|
10
|
+
|
11
|
+
super(message)
|
12
|
+
@location = location
|
13
|
+
end
|
14
|
+
|
15
|
+
def full_message(...)
|
16
|
+
msg = super
|
17
|
+
return msg if location.nil?
|
18
|
+
|
19
|
+
idx = msg.index(/\).*\n/)
|
20
|
+
return msg if idx.nil?
|
21
|
+
return msg if ENV["RUBY_ENV"] == "test"
|
22
|
+
|
23
|
+
msg.insert(idx + 1, ", located at #{location}")
|
24
|
+
end
|
25
|
+
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
class ReeMapper::Field
|
4
4
|
attr_reader :type, :name, :from, :doc, :optional, :null, :roles, :default,
|
5
5
|
:name_as_str, :name_as_instance_var_name, :from_as_str,
|
6
|
-
:fields_filter
|
6
|
+
:fields_filter, :location
|
7
7
|
|
8
8
|
NO_DEFAULT = Object.new.freeze
|
9
9
|
|
@@ -18,11 +18,12 @@ class ReeMapper::Field
|
|
18
18
|
role: Nilor[ArrayOf[Symbol], Symbol],
|
19
19
|
default: Any,
|
20
20
|
only: Nilor[ReeMapper::FilterFieldsContract],
|
21
|
-
except: Nilor[ReeMapper::FilterFieldsContract]
|
21
|
+
except: Nilor[ReeMapper::FilterFieldsContract],
|
22
|
+
location: Nilor[String],
|
22
23
|
] => Any
|
23
24
|
).throws(ArgumentError)
|
24
|
-
def initialize(type, name = nil, from: nil, doc: nil, optional: false, null: false, role: nil, default: NO_DEFAULT,
|
25
|
-
only: nil, except: nil)
|
25
|
+
def initialize(type, name = nil, from: nil, doc: nil, optional: false, null: false, role: nil, default: NO_DEFAULT,
|
26
|
+
only: nil, except: nil, location: nil)
|
26
27
|
@type = type
|
27
28
|
@name = name
|
28
29
|
@from = from || name
|
@@ -38,6 +39,13 @@ class ReeMapper::Field
|
|
38
39
|
@name_as_instance_var_name = :"@#{@name}"
|
39
40
|
@from_as_str = @from.to_s
|
40
41
|
|
42
|
+
@location = location
|
43
|
+
if @location
|
44
|
+
@location = @location
|
45
|
+
.sub(Ree.root_dir, ".")
|
46
|
+
.sub(/:in.+/, "")
|
47
|
+
end
|
48
|
+
|
41
49
|
raise ArgumentError, 'required fields do not support defaults' if has_default? && !optional
|
42
50
|
end
|
43
51
|
|
@@ -23,19 +23,19 @@ class ReeMapper::Mapper
|
|
23
23
|
|
24
24
|
if type
|
25
25
|
class_eval(<<~RUBY, __FILE__, __LINE__ + 1)
|
26
|
-
def #{method}(obj, name: nil, role: nil, only: nil, except: nil, fields_filters: [])
|
26
|
+
def #{method}(obj, name: nil, role: nil, only: nil, except: nil, fields_filters: [], location: nil)
|
27
27
|
#{
|
28
28
|
if type.is_a?(ReeMapper::AbstractWrapper)
|
29
|
-
"@type.#{method}(obj, name: name, role: role, fields_filters: fields_filters)"
|
29
|
+
"@type.#{method}(obj, name: name, role: role, fields_filters: fields_filters, location: location)"
|
30
30
|
else
|
31
|
-
"@type.#{method}(obj, name: name,
|
31
|
+
"@type.#{method}(obj, name: name, location: location)"
|
32
32
|
end
|
33
33
|
}
|
34
34
|
end
|
35
35
|
RUBY
|
36
36
|
else
|
37
37
|
class_eval(<<~RUBY, __FILE__, __LINE__ + 1)
|
38
|
-
def #{method}(obj, name: nil, role: nil, only: nil, except: nil, fields_filters: [])
|
38
|
+
def #{method}(obj, name: nil, role: nil, only: nil, except: nil, fields_filters: [], location: nil)
|
39
39
|
if only && !ReeMapper::FilterFieldsContract.valid?(only)
|
40
40
|
raise ReeMapper::ArgumentError, "Invalid `only` format"
|
41
41
|
end
|
@@ -56,7 +56,7 @@ class ReeMapper::Mapper
|
|
56
56
|
is_optional = field.optional || @#{method}_strategy.always_optional
|
57
57
|
|
58
58
|
if !is_with_value && !is_optional
|
59
|
-
raise ReeMapper::TypeError
|
59
|
+
raise ReeMapper::TypeError.new("Missing required field `\#{field.from_as_str}` for `\#{name || 'root'}`", field.location)
|
60
60
|
end
|
61
61
|
|
62
62
|
next if !is_with_value && !field.has_default?
|
@@ -73,7 +73,13 @@ class ReeMapper::Mapper
|
|
73
73
|
nested_fields_filters = field_fields_filters.map { _1.filter_for(field.name) }
|
74
74
|
nested_fields_filters += [field.fields_filter]
|
75
75
|
|
76
|
-
value = field.type.#{method}(
|
76
|
+
value = field.type.#{method}(
|
77
|
+
value,
|
78
|
+
name: nested_name,
|
79
|
+
role: role,
|
80
|
+
fields_filters: nested_fields_filters,
|
81
|
+
location: field.location,
|
82
|
+
)
|
77
83
|
end
|
78
84
|
|
79
85
|
@#{method}_strategy.assign_value(acc, field, value)
|