ree_lib 1.0.93 → 1.0.94

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -0
  3. data/Gemfile.lock +3 -1
  4. data/lib/ree_lib/packages/ree_dao/package/ree_dao/wrappers/pg_array.rb +34 -26
  5. data/lib/ree_lib/packages/ree_dao/package/ree_dao/wrappers/pg_jsonb.rb +35 -25
  6. data/lib/ree_lib/packages/ree_enum/package/ree_enum/base_enum_mapper.rb +6 -18
  7. data/lib/ree_lib/packages/ree_enum/package/ree_enum/integer_value_enum_mapper.rb +6 -18
  8. data/lib/ree_lib/packages/ree_enum/package/ree_enum/string_value_enum_mapper.rb +6 -18
  9. data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/errors/error_with_location.rb +47 -14
  10. data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/field.rb +1 -1
  11. data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/fields_filter.rb +11 -20
  12. data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/mapper.rb +36 -48
  13. data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/types/abstract_type.rb +2 -2
  14. data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/types/any.rb +8 -8
  15. data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/types/bool.rb +12 -12
  16. data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/types/date.rb +14 -14
  17. data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/types/date_time.rb +13 -13
  18. data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/types/float.rb +14 -14
  19. data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/types/integer.rb +13 -13
  20. data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/types/rational.rb +14 -14
  21. data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/types/string.rb +12 -12
  22. data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/types/time.rb +13 -13
  23. data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/wrappers/array.rb +88 -80
  24. data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/benchmarks/mapper_benchmark_spec.rb +41 -1
  25. data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/mapper_factory_spec.rb +17 -6
  26. data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/types/hash_spec.rb +1 -1
  27. data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/types/type_options_spec.rb +7 -26
  28. data/lib/ree_lib/packages/ree_swagger/Package.schema.json +3 -0
  29. data/lib/ree_lib/packages/ree_swagger/package/ree_swagger/functions/build_parameters.rb +2 -1
  30. data/lib/ree_lib/packages/ree_swagger/package/ree_swagger/functions/build_request_body_schema.rb +12 -5
  31. data/lib/ree_lib/packages/ree_swagger/package/ree_swagger/functions/build_serializer_schema.rb +12 -5
  32. data/lib/ree_lib/packages/ree_swagger/package/ree_swagger.rb +1 -0
  33. data/lib/ree_lib/packages/ree_swagger/schemas/ree_swagger/functions/build_parameters.schema.json +8 -0
  34. data/lib/ree_lib/packages/ree_swagger/schemas/ree_swagger/functions/build_request_body_schema.schema.json +1 -1
  35. data/lib/ree_lib/packages/ree_swagger/schemas/ree_swagger/functions/build_serializer_schema.schema.json +1 -1
  36. data/lib/ree_lib/version.rb +1 -1
  37. metadata +2 -2
@@ -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') { 1000.times { mapper.cast(obj) } }
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, name:, location: nil, **opts)
85
+ def serialize(value, **opts)
86
86
  if !value.is_a?(Numeric)
87
- raise ReeMapper::TypeError.new("`#{name}` should be a number, got `#{truncate(value.inspect)}`", location)
87
+ raise ReeMapper::TypeError.new("should be a number, got `#{truncate(value.inspect)}`")
88
88
  end
89
89
 
90
- subject.type.serialize(value.round, name: name, location: subject.location, **opts)
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, name:, location: nil, **opts)
106
- value = subject.type.cast(value, name: name, location: subject.location, **opts)
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("`#{name}` should be a number, got `#{truncate(value.inspect)}`", location)
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, /Missing required field `x` for `point`/)
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 'with invalid only' do
119
+ context "with empty nested filter" do
120
120
  let(:mapper) {
121
121
  mapper_factory.call.use(:cast) {
122
- point :point
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
- mapper.cast({}, except: {})
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, /Missing required field `number` for `root`/)
177
+ expect { mapper.cast({}) }.to raise_error(ReeMapper::TypeError, /`number` is missing required field/)
197
178
  }
198
179
 
199
180
  it {
@@ -7,6 +7,9 @@
7
7
  "ree_swagger"
8
8
  ],
9
9
  "depends_on": [
10
+ {
11
+ "name": "ree_array"
12
+ },
10
13
  {
11
14
  "name": "ree_dto"
12
15
  },
@@ -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, [], [field.fields_filter]) || {}
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?
@@ -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.map { _1.filter_for(field.name) }
38
- nested_fields_filters += [field.fields_filter]
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
 
@@ -7,14 +7,14 @@ class ReeSwagger::BuildSerializerSchema
7
7
  link :get_serializer_definition
8
8
  end
9
9
 
10
- contract(ReeMapper::Mapper, ArrayOf[ReeMapper::FieldsFilter] => Nilor[Hash])
11
- def call(mapper, fields_filters = [])
10
+ contract(ReeMapper::Mapper, Nilor[ArrayOf[ReeMapper::FieldsFilter]] => Nilor[Hash])
11
+ def call(mapper, fields_filters = nil)
12
12
  if mapper.type
13
13
  return get_serializer_definition(mapper.type, method(:call).to_proc)
14
14
  end
15
15
 
16
16
  properties = mapper.fields.each_with_object({}) do |(_name, field), acc|
17
- next unless fields_filters.all? { _1.allow?(field.name) }
17
+ next unless fields_filters.nil? || fields_filters.all? { _1.allow?(field.name) }
18
18
 
19
19
  if field.type == mapper
20
20
  acc[field.name] = {}
@@ -25,8 +25,15 @@ class ReeSwagger::BuildSerializerSchema
25
25
 
26
26
  field_mapper = field.type
27
27
 
28
- nested_fields_filters = fields_filters.map { _1.filter_for(field.name) }
29
- nested_fields_filters += [field.fields_filter]
28
+ nested_fields_filters = fields_filters&.filter_map { _1.filter_for(field.name) }
29
+
30
+ if field.fields_filter
31
+ nested_fields_filters = if nested_fields_filters
32
+ nested_fields_filters + [field.fields_filter]
33
+ else
34
+ [field.fields_filter]
35
+ end
36
+ end
30
37
 
31
38
  swagger_type = call(field_mapper, nested_fields_filters)
32
39
 
@@ -2,6 +2,7 @@ module ReeSwagger
2
2
  include Ree::PackageDSL
3
3
 
4
4
  package do
5
+ depends_on :ree_array
5
6
  depends_on :ree_mapper
6
7
  depends_on :ree_dto
7
8
  depends_on :ree_hash
@@ -47,6 +47,14 @@
47
47
  "as": "get_caster_definition",
48
48
  "imports": [
49
49
 
50
+ ]
51
+ },
52
+ {
53
+ "target": "wrap",
54
+ "package_name": "ree_array",
55
+ "as": "wrap",
56
+ "imports": [
57
+
50
58
  ]
51
59
  }
52
60
  ]
@@ -27,7 +27,7 @@
27
27
  {
28
28
  "arg": "fields_filters",
29
29
  "arg_type": "opt",
30
- "type": "ArrayOf[ReeMapper::FieldsFilter]"
30
+ "type": "Nilor[ArrayOf[ReeMapper::FieldsFilter]]"
31
31
  }
32
32
  ]
33
33
  }
@@ -22,7 +22,7 @@
22
22
  {
23
23
  "arg": "fields_filters",
24
24
  "arg_type": "opt",
25
- "type": "ArrayOf[ReeMapper::FieldsFilter]"
25
+ "type": "Nilor[ArrayOf[ReeMapper::FieldsFilter]]"
26
26
  }
27
27
  ]
28
28
  }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ReeLib
4
- VERSION = "1.0.93"
4
+ VERSION = "1.0.94"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ree_lib
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.93
4
+ version: 1.0.94
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ruslan Gatiyatov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-05-29 00:00:00.000000000 Z
11
+ date: 2024-07-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ree