ree_lib 1.0.93 → 1.0.95
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/Gemfile +1 -0
- data/Gemfile.lock +41 -36
- data/lib/ree_lib/packages/ree_dao/package/ree_dao/wrappers/pg_array.rb +34 -26
- data/lib/ree_lib/packages/ree_dao/package/ree_dao/wrappers/pg_jsonb.rb +35 -25
- data/lib/ree_lib/packages/ree_enum/package/ree_enum/base_enum_mapper.rb +6 -18
- data/lib/ree_lib/packages/ree_enum/package/ree_enum/integer_value_enum_mapper.rb +6 -18
- data/lib/ree_lib/packages/ree_enum/package/ree_enum/string_value_enum_mapper.rb +6 -18
- data/lib/ree_lib/packages/ree_errors/Package.schema.json +10 -7
- data/lib/ree_lib/packages/ree_errors/package/ree_errors/auth_error.rb +8 -8
- data/lib/ree_lib/packages/ree_errors/package/ree_errors/build_error.rb +4 -2
- data/lib/ree_lib/packages/ree_errors/package/ree_errors/conflict_error.rb +8 -8
- data/lib/ree_lib/packages/ree_errors/package/ree_errors/error.rb +89 -6
- data/lib/ree_lib/packages/ree_errors/package/ree_errors/invalid_param_error.rb +9 -9
- data/lib/ree_lib/packages/ree_errors/package/ree_errors/not_found_error.rb +8 -8
- data/lib/ree_lib/packages/ree_errors/package/ree_errors/payment_required_error.rb +8 -8
- data/lib/ree_lib/packages/ree_errors/package/ree_errors/permission_error.rb +8 -8
- data/lib/ree_lib/packages/ree_errors/package/ree_errors/validation_error.rb +8 -8
- data/lib/ree_lib/packages/ree_errors/package/ree_errors.rb +1 -0
- data/lib/ree_lib/packages/ree_errors/schemas/ree_errors/auth_error.schema.json +24 -1
- data/lib/ree_lib/packages/ree_errors/schemas/ree_errors/build_error.schema.json +10 -0
- data/lib/ree_lib/packages/ree_errors/schemas/ree_errors/conflict_error.schema.json +24 -1
- data/lib/ree_lib/packages/ree_errors/schemas/ree_errors/invalid_param_error.schema.json +24 -1
- data/lib/ree_lib/packages/ree_errors/schemas/ree_errors/not_found_error.schema.json +24 -1
- data/lib/ree_lib/packages/ree_errors/schemas/ree_errors/payment_required_error.schema.json +24 -1
- data/lib/ree_lib/packages/ree_errors/schemas/ree_errors/permission_error.schema.json +24 -1
- data/lib/ree_lib/packages/ree_errors/schemas/ree_errors/validation_error.schema.json +24 -1
- data/lib/ree_lib/packages/ree_errors/spec/ree_errors/auth_error_spec.rb +22 -8
- data/lib/ree_lib/packages/ree_errors/spec/ree_errors/invalid_param_error_spec.rb +3 -1
- data/lib/ree_lib/packages/ree_errors/spec/ree_errors/locales/en.yml +6 -1
- data/lib/ree_lib/packages/ree_errors/spec/ree_errors/not_found_error_spec.rb +3 -1
- data/lib/ree_lib/packages/ree_errors/spec/ree_errors/payment_required_error_spec.rb +3 -1
- data/lib/ree_lib/packages/ree_errors/spec/ree_errors/permission_error_spec.rb +3 -1
- data/lib/ree_lib/packages/ree_errors/spec/ree_errors/validation_error_spec.rb +3 -1
- data/lib/ree_lib/packages/ree_i18n/Package.schema.json +7 -0
- data/lib/ree_lib/packages/ree_i18n/package/ree_i18n/functions/check_locale_exists.rb +12 -0
- data/lib/ree_lib/packages/ree_i18n/schemas/ree_i18n/functions/check_locale_exists.schema.json +33 -0
- data/lib/ree_lib/packages/ree_i18n/spec/ree_i18n/functions/check_locale_exists.rb +16 -0
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/errors/error_with_location.rb +47 -14
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/field.rb +1 -1
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/fields_filter.rb +11 -20
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/mapper.rb +36 -48
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/types/abstract_type.rb +2 -2
- 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 +14 -14
- 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 +14 -14
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/types/integer.rb +13 -13
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/types/rational.rb +14 -14
- 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/array.rb +88 -80
- data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/benchmarks/mapper_benchmark_spec.rb +41 -1
- data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/mapper_factory_spec.rb +17 -6
- 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/type_options_spec.rb +7 -26
- data/lib/ree_lib/packages/ree_roda/spec/ree_roda/services/build_swagger_from_routes_spec.rb +7 -4
- data/lib/ree_lib/packages/ree_roda/spec/ree_roda/services/locales/en.yml +3 -1
- data/lib/ree_lib/packages/ree_string/package/ree_string/functions/deconstantize.rb +1 -1
- data/lib/ree_lib/packages/ree_swagger/Package.schema.json +3 -0
- data/lib/ree_lib/packages/ree_swagger/package/ree_swagger/functions/build_parameters.rb +2 -1
- data/lib/ree_lib/packages/ree_swagger/package/ree_swagger/functions/build_request_body_schema.rb +12 -5
- data/lib/ree_lib/packages/ree_swagger/package/ree_swagger/functions/build_serializer_schema.rb +12 -5
- data/lib/ree_lib/packages/ree_swagger/package/ree_swagger.rb +1 -0
- data/lib/ree_lib/packages/ree_swagger/schemas/ree_swagger/functions/build_parameters.schema.json +8 -0
- data/lib/ree_lib/packages/ree_swagger/schemas/ree_swagger/functions/build_request_body_schema.schema.json +1 -1
- data/lib/ree_lib/packages/ree_swagger/schemas/ree_swagger/functions/build_serializer_schema.schema.json +1 -1
- data/lib/ree_lib/version.rb +1 -1
- metadata +5 -3
- data/lib/ree_lib/packages/ree_errors/package/ree_errors/error_factory.rb +0 -15
|
@@ -1,39 +1,39 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class ReeMapper::Rational < ReeMapper::AbstractType
|
|
4
|
-
contract(Any
|
|
5
|
-
def serialize(value
|
|
4
|
+
contract(Any => Rational).throws(ReeMapper::TypeError)
|
|
5
|
+
def serialize(value)
|
|
6
6
|
if value.is_a?(Rational)
|
|
7
7
|
value
|
|
8
8
|
else
|
|
9
|
-
raise ReeMapper::TypeError.new("
|
|
9
|
+
raise ReeMapper::TypeError.new("should be a rational, got `#{truncate(value.inspect)}`")
|
|
10
10
|
end
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
contract(Any
|
|
14
|
-
def cast(value
|
|
13
|
+
contract(Any => Rational).throws(ReeMapper::CoercionError, ReeMapper::TypeError)
|
|
14
|
+
def cast(value)
|
|
15
15
|
if value.is_a?(Rational)
|
|
16
16
|
value
|
|
17
17
|
elsif value.is_a?(String)
|
|
18
18
|
begin
|
|
19
19
|
Rational(value)
|
|
20
|
-
rescue ArgumentError, ZeroDivisionError
|
|
21
|
-
raise ReeMapper::CoercionError.new("
|
|
20
|
+
rescue ArgumentError, ZeroDivisionError
|
|
21
|
+
raise ReeMapper::CoercionError.new("is invalid rational, got `#{truncate(value.inspect)}`")
|
|
22
22
|
end
|
|
23
23
|
elsif value.is_a?(Numeric)
|
|
24
24
|
Rational(value)
|
|
25
25
|
else
|
|
26
|
-
raise ReeMapper::TypeError.new("
|
|
26
|
+
raise ReeMapper::TypeError.new("should be a rational, got `#{truncate(value.inspect)}`")
|
|
27
27
|
end
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
-
contract(Any
|
|
31
|
-
def db_dump(value
|
|
32
|
-
serialize(value
|
|
30
|
+
contract(Any => String)
|
|
31
|
+
def db_dump(value)
|
|
32
|
+
serialize(value).to_s
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
-
contract(Any
|
|
36
|
-
def db_load(value
|
|
37
|
-
cast(value
|
|
35
|
+
contract(Any => Rational)
|
|
36
|
+
def db_load(value)
|
|
37
|
+
cast(value)
|
|
38
38
|
end
|
|
39
39
|
end
|
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class ReeMapper::String < ReeMapper::AbstractType
|
|
4
|
-
contract(Any
|
|
5
|
-
def serialize(value
|
|
4
|
+
contract(Any => String).throws(ReeMapper::TypeError)
|
|
5
|
+
def serialize(value)
|
|
6
6
|
if value.is_a? String
|
|
7
7
|
value
|
|
8
8
|
else
|
|
9
|
-
raise ReeMapper::TypeError.new("
|
|
9
|
+
raise ReeMapper::TypeError.new("should be a string, got `#{truncate(value.inspect)}`")
|
|
10
10
|
end
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
contract(Any
|
|
14
|
-
def cast(value
|
|
15
|
-
serialize(value
|
|
13
|
+
contract(Any => String).throws(ReeMapper::TypeError)
|
|
14
|
+
def cast(value)
|
|
15
|
+
serialize(value)
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
contract(Any
|
|
19
|
-
def db_dump(value
|
|
20
|
-
serialize(value
|
|
18
|
+
contract(Any => String).throws(ReeMapper::TypeError)
|
|
19
|
+
def db_dump(value)
|
|
20
|
+
serialize(value)
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
contract(Any
|
|
24
|
-
def db_load(value
|
|
25
|
-
serialize(value
|
|
23
|
+
contract(Any => String).throws(ReeMapper::TypeError)
|
|
24
|
+
def db_load(value)
|
|
25
|
+
serialize(value)
|
|
26
26
|
end
|
|
27
27
|
end
|
|
@@ -3,17 +3,17 @@
|
|
|
3
3
|
require 'time'
|
|
4
4
|
|
|
5
5
|
class ReeMapper::Time < ReeMapper::AbstractType
|
|
6
|
-
contract(Any
|
|
7
|
-
def serialize(value
|
|
6
|
+
contract(Any => Time).throws(ReeMapper::TypeError)
|
|
7
|
+
def serialize(value)
|
|
8
8
|
if value.class == Time
|
|
9
9
|
value
|
|
10
10
|
else
|
|
11
|
-
raise ReeMapper::TypeError.new("
|
|
11
|
+
raise ReeMapper::TypeError.new("should be a time, got `#{truncate(value.inspect)}`")
|
|
12
12
|
end
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
contract(Any
|
|
16
|
-
def cast(value
|
|
15
|
+
contract(Any => Time).throws(ReeMapper::CoercionError, ReeMapper::TypeError)
|
|
16
|
+
def cast(value)
|
|
17
17
|
if value.class == Time
|
|
18
18
|
value
|
|
19
19
|
elsif value.class == DateTime
|
|
@@ -22,20 +22,20 @@ class ReeMapper::Time < ReeMapper::AbstractType
|
|
|
22
22
|
begin
|
|
23
23
|
Time.parse(value)
|
|
24
24
|
rescue ArgumentError
|
|
25
|
-
raise ReeMapper::CoercionError.new("
|
|
25
|
+
raise ReeMapper::CoercionError.new("is invalid time, got `#{truncate(value.inspect)}`")
|
|
26
26
|
end
|
|
27
27
|
else
|
|
28
|
-
raise ReeMapper::TypeError.new("
|
|
28
|
+
raise ReeMapper::TypeError.new("should be a time, got `#{truncate(value.inspect)}`")
|
|
29
29
|
end
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
-
contract(Any
|
|
33
|
-
def db_dump(value
|
|
34
|
-
serialize(value
|
|
32
|
+
contract(Any => Time).throws(ReeMapper::TypeError)
|
|
33
|
+
def db_dump(value)
|
|
34
|
+
serialize(value)
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
-
contract(Any
|
|
38
|
-
def db_load(value
|
|
39
|
-
cast(value
|
|
37
|
+
contract(Any => Time).throws(ReeMapper::CoercionError, ReeMapper::TypeError)
|
|
38
|
+
def db_load(value)
|
|
39
|
+
cast(value)
|
|
40
40
|
end
|
|
41
41
|
end
|
|
@@ -4,116 +4,124 @@ class ReeMapper::Array < ReeMapper::AbstractWrapper
|
|
|
4
4
|
contract(
|
|
5
5
|
Any,
|
|
6
6
|
Kwargs[
|
|
7
|
-
name: String,
|
|
8
7
|
role: Nilor[Symbol, ArrayOf[Symbol]],
|
|
9
|
-
fields_filters: ArrayOf[ReeMapper::FieldsFilter],
|
|
10
|
-
location: Nilor[String],
|
|
8
|
+
fields_filters: Nilor[ArrayOf[ReeMapper::FieldsFilter]],
|
|
11
9
|
] => Array
|
|
12
10
|
).throws(ReeMapper::TypeError)
|
|
13
|
-
def serialize(value,
|
|
14
|
-
if value.is_a?(Array)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
11
|
+
def serialize(value, role: nil, fields_filters: nil)
|
|
12
|
+
if !value.is_a?(Array)
|
|
13
|
+
raise ReeMapper::TypeError.new("should be an array, got `#{truncate(value.inspect)}`")
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
if subject.fields_filter
|
|
17
|
+
fields_filters = if fields_filters
|
|
18
|
+
fields_filters + [subject.fields_filter]
|
|
19
|
+
else
|
|
20
|
+
[subject.fields_filter]
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
value.map.with_index do |item, idx|
|
|
25
|
+
next nil if item.nil? && subject.null
|
|
26
|
+
|
|
27
|
+
subject.type.serialize(item, role:, fields_filters:)
|
|
28
|
+
rescue ReeMapper::ErrorWithLocation => e
|
|
29
|
+
e.prepend_field_name(idx.to_s)
|
|
30
|
+
e.location ||= subject.location
|
|
31
|
+
raise e
|
|
30
32
|
end
|
|
31
33
|
end
|
|
32
34
|
|
|
33
35
|
contract(
|
|
34
36
|
Any,
|
|
35
37
|
Kwargs[
|
|
36
|
-
name: String,
|
|
37
38
|
role: Nilor[Symbol, ArrayOf[Symbol]],
|
|
38
|
-
fields_filters: ArrayOf[ReeMapper::FieldsFilter],
|
|
39
|
-
location: Nilor[String],
|
|
39
|
+
fields_filters: Nilor[ArrayOf[ReeMapper::FieldsFilter]],
|
|
40
40
|
] => Array
|
|
41
41
|
).throws(ReeMapper::TypeError)
|
|
42
|
-
def cast(value,
|
|
43
|
-
if value.is_a?(Array)
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
42
|
+
def cast(value, role: nil, fields_filters: nil)
|
|
43
|
+
if !value.is_a?(Array)
|
|
44
|
+
raise ReeMapper::TypeError.new("should be an array, got `#{truncate(value.inspect)}`")
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
if subject.fields_filter
|
|
48
|
+
fields_filters = if fields_filters
|
|
49
|
+
fields_filters + [subject.fields_filter]
|
|
50
|
+
else
|
|
51
|
+
[subject.fields_filter]
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
value.map.with_index do |item, idx|
|
|
56
|
+
next nil if item.nil? && subject.null
|
|
57
|
+
|
|
58
|
+
subject.type.cast(item, role:, fields_filters:)
|
|
59
|
+
rescue ReeMapper::ErrorWithLocation => e
|
|
60
|
+
e.prepend_field_name(idx.to_s)
|
|
61
|
+
e.location ||= subject.location
|
|
62
|
+
raise e
|
|
59
63
|
end
|
|
60
64
|
end
|
|
61
65
|
|
|
62
66
|
contract(
|
|
63
67
|
Any,
|
|
64
68
|
Kwargs[
|
|
65
|
-
name: String,
|
|
66
69
|
role: Nilor[Symbol, ArrayOf[Symbol]],
|
|
67
|
-
fields_filters: ArrayOf[ReeMapper::FieldsFilter],
|
|
68
|
-
location: Nilor[String],
|
|
70
|
+
fields_filters: Nilor[ArrayOf[ReeMapper::FieldsFilter]],
|
|
69
71
|
] => Array
|
|
70
72
|
).throws(ReeMapper::TypeError)
|
|
71
|
-
def db_dump(value,
|
|
72
|
-
if value.is_a?(Array)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
73
|
+
def db_dump(value, role: nil, fields_filters: nil)
|
|
74
|
+
if !value.is_a?(Array)
|
|
75
|
+
raise ReeMapper::TypeError.new("should be an array, got `#{truncate(value.inspect)}`")
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
if subject.fields_filter
|
|
79
|
+
fields_filters = if fields_filters
|
|
80
|
+
fields_filters + [subject.fields_filter]
|
|
81
|
+
else
|
|
82
|
+
[subject.fields_filter]
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
value.map.with_index do |item, idx|
|
|
87
|
+
next nil if item.nil? && subject.null
|
|
88
|
+
|
|
89
|
+
subject.type.db_dump(item, role:, fields_filters:)
|
|
90
|
+
rescue ReeMapper::ErrorWithLocation => e
|
|
91
|
+
e.prepend_field_name(idx.to_s)
|
|
92
|
+
e.location ||= subject.location
|
|
93
|
+
raise e
|
|
88
94
|
end
|
|
89
95
|
end
|
|
90
96
|
|
|
91
97
|
contract(
|
|
92
98
|
Any,
|
|
93
99
|
Kwargs[
|
|
94
|
-
name: String,
|
|
95
100
|
role: Nilor[Symbol, ArrayOf[Symbol]],
|
|
96
|
-
fields_filters: ArrayOf[ReeMapper::FieldsFilter],
|
|
97
|
-
location: Nilor[String],
|
|
101
|
+
fields_filters: Nilor[ArrayOf[ReeMapper::FieldsFilter]],
|
|
98
102
|
] => Array
|
|
99
103
|
).throws(ReeMapper::TypeError)
|
|
100
|
-
def db_load(value,
|
|
101
|
-
if value.is_a?(Array)
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
104
|
+
def db_load(value, role: nil, fields_filters: nil)
|
|
105
|
+
if !value.is_a?(Array)
|
|
106
|
+
raise ReeMapper::TypeError.new("should be an array, got `#{truncate(value.inspect)}`")
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
if subject.fields_filter
|
|
110
|
+
fields_filters = if fields_filters
|
|
111
|
+
fields_filters + [subject.fields_filter]
|
|
112
|
+
else
|
|
113
|
+
[subject.fields_filter]
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
value.map.with_index do |item, idx|
|
|
118
|
+
next nil if item.nil? && subject.null
|
|
119
|
+
|
|
120
|
+
subject.type.db_load(item, role:, fields_filters:)
|
|
121
|
+
rescue ReeMapper::ErrorWithLocation => e
|
|
122
|
+
e.prepend_field_name(idx.to_s)
|
|
123
|
+
e.location ||= subject.location
|
|
124
|
+
raise e
|
|
117
125
|
end
|
|
118
126
|
end
|
|
119
127
|
end
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
require 'benchmark'
|
|
3
3
|
|
|
4
|
+
no_contracts = Ree::Contracts.no_contracts?
|
|
5
|
+
Ree.disable_contracts
|
|
6
|
+
|
|
4
7
|
package_require "ree_mapper"
|
|
5
8
|
|
|
6
9
|
RSpec.xdescribe 'Mapper Benchmark' do
|
|
@@ -25,7 +28,44 @@ RSpec.xdescribe 'Mapper Benchmark' do
|
|
|
25
28
|
obj = { my_field: { my_field: { my_field: 1 } } }
|
|
26
29
|
|
|
27
30
|
_benchmark_res = Benchmark.bmbm do |x|
|
|
28
|
-
x.report('cast') {
|
|
31
|
+
x.report('cast') { 100000.times { mapper.cast(obj) } }
|
|
29
32
|
end
|
|
30
33
|
end
|
|
34
|
+
|
|
35
|
+
xit do
|
|
36
|
+
Ree.disable_contracts
|
|
37
|
+
require "ruby-prof"
|
|
38
|
+
package_require "ree_mapper"
|
|
39
|
+
|
|
40
|
+
mapper = ReeMapper::BuildMapperFactory.new.call(
|
|
41
|
+
strategies: [
|
|
42
|
+
ReeMapper::BuildMapperStrategy.new.call(method: :cast, dto: Hash),
|
|
43
|
+
]
|
|
44
|
+
).call.use(:cast) do
|
|
45
|
+
hash :my_field do
|
|
46
|
+
hash :my_field do
|
|
47
|
+
integer :my_field
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
obj = { my_field: { my_field: { my_field: 1 } } }
|
|
53
|
+
|
|
54
|
+
result = RubyProf::Profile.profile do
|
|
55
|
+
mapper.cast(obj)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
RubyProf::FlatPrinter.new(result).print(STDOUT)
|
|
59
|
+
end
|
|
31
60
|
end
|
|
61
|
+
|
|
62
|
+
if !no_contracts
|
|
63
|
+
Ree.enable_contracts
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# version main
|
|
67
|
+
# cast 0.369019 0.001180 0.370199 ( 0.370515)
|
|
68
|
+
# cast 0.356124 0.001060 0.357184 ( 0.357502)
|
|
69
|
+
# version 1.0.93
|
|
70
|
+
# cast 0.791664 0.004125 0.795789 ( 0.796938)
|
|
71
|
+
# cast 0.782544 0.016745 0.799289 ( 0.799759)
|
|
@@ -82,12 +82,17 @@ RSpec.describe ReeMapper::MapperFactory do
|
|
|
82
82
|
describe '.register_wrapper' do
|
|
83
83
|
let(:round_wrapper) {
|
|
84
84
|
Class.new(ReeMapper::AbstractWrapper) do
|
|
85
|
-
def serialize(value,
|
|
85
|
+
def serialize(value, **opts)
|
|
86
86
|
if !value.is_a?(Numeric)
|
|
87
|
-
raise ReeMapper::TypeError.new("
|
|
87
|
+
raise ReeMapper::TypeError.new("should be a number, got `#{truncate(value.inspect)}`")
|
|
88
88
|
end
|
|
89
89
|
|
|
90
|
-
|
|
90
|
+
begin
|
|
91
|
+
subject.type.serialize(value.round, **opts)
|
|
92
|
+
rescue ReeMapper::ErrorWithLocation => e
|
|
93
|
+
e.location ||= subject.location
|
|
94
|
+
raise e
|
|
95
|
+
end
|
|
91
96
|
end
|
|
92
97
|
end
|
|
93
98
|
}
|
|
@@ -102,12 +107,18 @@ RSpec.describe ReeMapper::MapperFactory do
|
|
|
102
107
|
|
|
103
108
|
it 'allow to register caster and serializer with the same name' do
|
|
104
109
|
caster_round_wrapper = Class.new(ReeMapper::AbstractWrapper) do
|
|
105
|
-
def cast(value,
|
|
106
|
-
value =
|
|
110
|
+
def cast(value, **opts)
|
|
111
|
+
value = begin
|
|
112
|
+
subject.type.cast(value, **opts)
|
|
113
|
+
rescue ReeMapper::ErrorWithLocation => e
|
|
114
|
+
e.location ||= subject.location
|
|
115
|
+
raise e
|
|
116
|
+
end
|
|
107
117
|
|
|
108
118
|
if !value.is_a?(Numeric)
|
|
109
|
-
raise ReeMapper::TypeError.new("
|
|
119
|
+
raise ReeMapper::TypeError.new("should be a number, got `#{truncate(value.inspect)}`")
|
|
110
120
|
end
|
|
121
|
+
|
|
111
122
|
value.round
|
|
112
123
|
end
|
|
113
124
|
end
|
|
@@ -27,7 +27,7 @@ RSpec.describe 'Mapper Hash' do
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
it {
|
|
30
|
-
expect { mapper.cast({ point: 1 }) }.to raise_error(ReeMapper::TypeError,
|
|
30
|
+
expect { mapper.cast({ point: 1 }) }.to raise_error(ReeMapper::TypeError, /`point\[x\]` is missing required field/)
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
it {
|
|
@@ -116,37 +116,18 @@ RSpec.describe 'ReeMapper::MapperFactory type options' do
|
|
|
116
116
|
}
|
|
117
117
|
end
|
|
118
118
|
|
|
119
|
-
context
|
|
119
|
+
context "with empty nested filter" do
|
|
120
120
|
let(:mapper) {
|
|
121
121
|
mapper_factory.call.use(:cast) {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
it {
|
|
127
|
-
expect {
|
|
128
|
-
mapper.cast({}, only: {})
|
|
129
|
-
}.to raise_error(
|
|
130
|
-
ReeMapper::ArgumentError,
|
|
131
|
-
"Invalid `only` format"
|
|
132
|
-
)
|
|
133
|
-
}
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
context 'with invalid except' do
|
|
137
|
-
let(:mapper) {
|
|
138
|
-
mapper_factory.call.use(:cast) {
|
|
139
|
-
point :point
|
|
122
|
+
hash :point_wrap do
|
|
123
|
+
point :point
|
|
124
|
+
end
|
|
140
125
|
}
|
|
141
126
|
}
|
|
142
127
|
|
|
143
128
|
it {
|
|
144
|
-
expect {
|
|
145
|
-
|
|
146
|
-
}.to raise_error(
|
|
147
|
-
ReeMapper::ArgumentError,
|
|
148
|
-
"Invalid `except` format"
|
|
149
|
-
)
|
|
129
|
+
expect(mapper.cast({ point_wrap: { point: { x: 1, y: 1, z: 1 } } }, only: [point_wrap: [:point]]))
|
|
130
|
+
.to eq({ point_wrap: { point: { x: 1, y: 1, z: 1 } } })
|
|
150
131
|
}
|
|
151
132
|
end
|
|
152
133
|
end
|
|
@@ -193,7 +174,7 @@ RSpec.describe 'ReeMapper::MapperFactory type options' do
|
|
|
193
174
|
}
|
|
194
175
|
|
|
195
176
|
it {
|
|
196
|
-
expect { mapper.cast({}) }.to raise_error(ReeMapper::TypeError,
|
|
177
|
+
expect { mapper.cast({}) }.to raise_error(ReeMapper::TypeError, /`number` is missing required field/)
|
|
197
178
|
}
|
|
198
179
|
|
|
199
180
|
it {
|
|
@@ -17,19 +17,22 @@ RSpec.describe :build_swagger_from_routes do
|
|
|
17
17
|
package do
|
|
18
18
|
depends_on :ree_actions
|
|
19
19
|
depends_on :ree_dao
|
|
20
|
+
depends_on :ree_errors
|
|
20
21
|
end
|
|
21
22
|
end
|
|
22
23
|
|
|
23
24
|
class ReeRodaTestSwagger::Cmd
|
|
24
25
|
include ReeActions::DSL
|
|
25
26
|
|
|
26
|
-
action :cmd
|
|
27
|
+
action :cmd do
|
|
28
|
+
link :invalid_param_error, from: :ree_errors
|
|
29
|
+
end
|
|
27
30
|
|
|
28
31
|
ActionCaster = build_mapper.use(:cast) do
|
|
29
32
|
integer :id
|
|
30
33
|
end
|
|
31
34
|
|
|
32
|
-
InvalidErr =
|
|
35
|
+
InvalidErr = invalid_param_error(:invalid, "invalid")
|
|
33
36
|
|
|
34
37
|
contract(Any, Any => Any).throws(InvalidErr)
|
|
35
38
|
def call(access, attrs)
|
|
@@ -71,7 +74,7 @@ RSpec.describe :build_swagger_from_routes do
|
|
|
71
74
|
it {
|
|
72
75
|
swagger = build_swagger_from_routes(routes, "test", "test", "1.0", "https://example.com")
|
|
73
76
|
|
|
74
|
-
expect(swagger.dig(:paths, "/api/actions", :post, :responses,
|
|
75
|
-
.to eq("- type: **
|
|
77
|
+
expect(swagger.dig(:paths, "/api/actions", :post, :responses, 400, :description))
|
|
78
|
+
.to eq("- type: **invalid_param**, code: **invalid**, message: **invalid param**")
|
|
76
79
|
}
|
|
77
80
|
end
|
|
@@ -6,6 +6,7 @@ class ReeSwagger::BuildParameters
|
|
|
6
6
|
fn :build_parameters do
|
|
7
7
|
link :get_caster_definition
|
|
8
8
|
link :build_request_body_schema
|
|
9
|
+
link :wrap, from: :ree_array
|
|
9
10
|
end
|
|
10
11
|
|
|
11
12
|
ObjectPathParamError = Class.new(StandardError)
|
|
@@ -36,7 +37,7 @@ class ReeSwagger::BuildParameters
|
|
|
36
37
|
name: field.name_as_str,
|
|
37
38
|
in: is_path_param ? 'path' : 'query',
|
|
38
39
|
required: is_path_param || !field.optional,
|
|
39
|
-
schema: build_request_body_schema(field.type, [],
|
|
40
|
+
schema: build_request_body_schema(field.type, [], wrap(field.fields_filter)) || {}
|
|
40
41
|
}
|
|
41
42
|
|
|
42
43
|
schema[:style] = 'deepObject' if field.type.type.nil?
|
data/lib/ree_lib/packages/ree_swagger/package/ree_swagger/functions/build_request_body_schema.rb
CHANGED
|
@@ -10,9 +10,9 @@ class ReeSwagger::BuildRequestBodySchema
|
|
|
10
10
|
contract(
|
|
11
11
|
ReeMapper::Mapper,
|
|
12
12
|
ArrayOf[Symbol],
|
|
13
|
-
ArrayOf[ReeMapper::FieldsFilter] => Nilor[Hash]
|
|
13
|
+
Nilor[ArrayOf[ReeMapper::FieldsFilter]] => Nilor[Hash]
|
|
14
14
|
)
|
|
15
|
-
def call(mapper, path_params = [], fields_filters =
|
|
15
|
+
def call(mapper, path_params = [], fields_filters = nil)
|
|
16
16
|
if mapper.type
|
|
17
17
|
return get_caster_definition(mapper.type, method(:call).to_proc)
|
|
18
18
|
end
|
|
@@ -20,7 +20,7 @@ class ReeSwagger::BuildRequestBodySchema
|
|
|
20
20
|
required_fields = []
|
|
21
21
|
|
|
22
22
|
properties = mapper.fields.each_with_object({}) do |(_name, field), acc|
|
|
23
|
-
next unless fields_filters.all? { _1.allow?(field.name) }
|
|
23
|
+
next unless fields_filters.nil? || fields_filters.all? { _1.allow?(field.name) }
|
|
24
24
|
|
|
25
25
|
next if path_params.include?(field.name)
|
|
26
26
|
|
|
@@ -34,8 +34,15 @@ class ReeSwagger::BuildRequestBodySchema
|
|
|
34
34
|
required_fields << field.name.to_s if !field.optional
|
|
35
35
|
field_mapper = field.type
|
|
36
36
|
|
|
37
|
-
nested_fields_filters = fields_filters
|
|
38
|
-
|
|
37
|
+
nested_fields_filters = fields_filters&.filter_map { _1.filter_for(field.name) }
|
|
38
|
+
|
|
39
|
+
if field.fields_filter
|
|
40
|
+
nested_fields_filters = if nested_fields_filters
|
|
41
|
+
nested_fields_filters + [field.fields_filter]
|
|
42
|
+
else
|
|
43
|
+
[field.fields_filter]
|
|
44
|
+
end
|
|
45
|
+
end
|
|
39
46
|
|
|
40
47
|
swagger_type = call(field_mapper, [], nested_fields_filters)
|
|
41
48
|
|