ree_lib 1.0.39 → 1.0.40

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.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +4 -1
  3. data/lib/ree_lib/.vscode-ree/templates/spec_template.rb +1 -1
  4. data/lib/ree_lib/Packages.schema.json +4 -0
  5. data/lib/ree_lib/packages/.vscode-ree/templates/spec_template.rb +1 -1
  6. data/lib/ree_lib/packages/ree_actions/package/ree_actions/dsl.rb +28 -70
  7. data/lib/ree_lib/packages/ree_actions/package/ree_actions.rb +1 -2
  8. data/lib/ree_lib/packages/ree_actions/spec/ree_actions/dsl_spec.rb +34 -65
  9. data/lib/ree_lib/packages/ree_array/spec/ree_array/functions/group_by_spec.rb +1 -1
  10. data/lib/ree_lib/packages/ree_array/spec/ree_array/functions/index_by_spec.rb +1 -1
  11. data/lib/ree_lib/packages/ree_dao/package/ree_dao/wrappers/pg_array.rb +53 -0
  12. data/lib/ree_lib/packages/ree_dao/package/ree_dao/wrappers/pg_jsonb.rb +73 -0
  13. data/lib/ree_lib/packages/ree_dao/spec/ree_dao/functions/build_sqlite_connection_spec.rb +1 -1
  14. data/lib/ree_lib/packages/ree_dao/spec/ree_dao/functions/one_to_many_spec.rb +2 -2
  15. data/lib/ree_lib/packages/ree_dao/spec/ree_dao/functions/one_to_one_spec.rb +2 -2
  16. data/lib/ree_lib/packages/ree_dao/spec/ree_dao/functions/persist_assoc_spec.rb +2 -2
  17. data/lib/ree_lib/packages/ree_dao/spec/ree_dao/wrappers/pg_array_spec.rb +64 -0
  18. data/lib/ree_lib/packages/ree_dao/spec/ree_dao/wrappers/pg_jsonb_spec.rb +94 -0
  19. data/lib/ree_lib/packages/ree_datetime/spec/ree_datetime/functions/in_default_time_zone_spec.rb +1 -1
  20. data/lib/ree_lib/packages/ree_dto/spec/ree_dto/entity_dsl_spec.rb +1 -1
  21. data/lib/ree_lib/packages/ree_hash/spec/ree_hash/functions/transform_values_spec.rb +1 -1
  22. data/lib/ree_lib/packages/ree_json/spec/ree_json/functions/from_json_spec.rb +1 -1
  23. data/lib/ree_lib/packages/ree_json/spec/ree_json/functions/to_json_spec.rb +1 -1
  24. data/lib/ree_lib/packages/ree_logger/spec/ree_logger/appenders/appender_spec.rb +1 -1
  25. data/lib/ree_lib/packages/ree_logger/spec/ree_logger/appenders/file_appender_spec.rb +3 -3
  26. data/lib/ree_lib/packages/ree_logger/spec/ree_logger/appenders/rollbar_appender_spec.rb +1 -1
  27. data/lib/ree_lib/packages/ree_logger/spec/ree_logger/appenders/stdout_appender_spec.rb +1 -1
  28. data/lib/ree_lib/packages/ree_logger/spec/ree_logger/beans/logger_spec.rb +2 -2
  29. data/lib/ree_lib/packages/ree_logger/spec/ree_logger/formatters/colorized_formatter_spec.rb +10 -7
  30. data/lib/ree_lib/packages/ree_logger/spec/ree_logger/formatters/default_formatter_spec.rb +1 -1
  31. data/lib/ree_lib/packages/ree_logger/spec/ree_logger/formatters/formatter_spec.rb +1 -1
  32. data/lib/ree_lib/packages/ree_logger/spec/ree_logger/multi_logger_spec.rb +1 -1
  33. data/lib/ree_lib/packages/ree_migrator/spec/ree_migrator/functions/apply_migration_spec.rb +1 -1
  34. data/lib/ree_lib/packages/ree_migrator/spec/ree_migrator/functions/apply_migrations_spec.rb +1 -1
  35. data/lib/ree_lib/packages/ree_migrator/spec/ree_migrator/functions/migrate_db_spec.rb +1 -1
  36. data/lib/ree_lib/packages/ree_object/spec/ree_object/functions/deep_dup_spec.rb +2 -2
  37. data/lib/ree_lib/packages/ree_object/spec/ree_object/functions/deep_freeze_spec.rb +1 -1
  38. data/lib/ree_lib/packages/ree_object/spec/ree_object/functions/dump_as_json_spec.rb +1 -1
  39. data/lib/ree_lib/packages/ree_object/spec/ree_object/functions/is_blank_spec.rb +1 -1
  40. data/lib/ree_lib/packages/ree_object/spec/ree_object/functions/not_blank_spec.rb +1 -1
  41. data/lib/ree_lib/packages/ree_object/spec/ree_object/functions/to_hash_spec.rb +1 -1
  42. data/lib/ree_lib/packages/ree_object/spec/ree_object/functions/to_obj_spec.rb +8 -8
  43. data/lib/ree_lib/packages/ree_roda/Package.schema.json +14 -7
  44. data/lib/ree_lib/packages/ree_roda/package/ree_roda/plugins/ree_routes.rb +231 -0
  45. data/lib/ree_lib/packages/ree_roda/package/ree_roda/services/{build_action_errors.rb → build_route_errors.rb} +5 -5
  46. data/lib/ree_lib/packages/ree_roda/package/ree_roda/services/build_routing_tree.rb +144 -0
  47. data/lib/ree_lib/packages/ree_roda/package/ree_roda/services/build_swagger_from_routes.rb +54 -0
  48. data/lib/ree_lib/packages/ree_roda/package/ree_roda.rb +2 -2
  49. data/lib/ree_lib/packages/ree_roda/schemas/ree_roda/services/{build_action_errors.schema.json → build_route_errors.schema.json} +5 -5
  50. data/lib/ree_lib/packages/ree_roda/schemas/ree_roda/services/build_routing_tree.schema.json +28 -0
  51. data/lib/ree_lib/packages/ree_roda/schemas/ree_roda/services/{build_swagger_from_actions.schema.json → build_swagger_from_routes.schema.json} +7 -7
  52. data/lib/ree_lib/packages/ree_roda/spec/ree_roda/app_spec.rb +141 -7
  53. data/lib/ree_lib/packages/ree_roda/spec/ree_roda/services/build_routing_tree_spec.rb +261 -0
  54. data/lib/ree_lib/packages/ree_routes/.gitignore +0 -0
  55. data/lib/ree_lib/packages/ree_routes/.rspec +2 -0
  56. data/lib/ree_lib/packages/ree_routes/Package.schema.json +20 -0
  57. data/lib/ree_lib/packages/ree_routes/bin/console +5 -0
  58. data/lib/ree_lib/packages/ree_routes/package/ree_routes/dsl.rb +102 -0
  59. data/lib/ree_lib/packages/ree_routes/package/ree_routes/route.rb +10 -0
  60. data/lib/ree_lib/packages/{ree_actions/package/ree_actions/action_builder.rb → ree_routes/package/ree_routes/route_builder.rb} +15 -15
  61. data/lib/ree_lib/packages/ree_routes/package/ree_routes.rb +9 -0
  62. data/lib/ree_lib/packages/ree_routes/spec/package_schema_spec.rb +14 -0
  63. data/lib/ree_lib/packages/ree_routes/spec/ree_routes/dsl_spec.rb +93 -0
  64. data/lib/ree_lib/packages/ree_routes/spec/spec_helper.rb +3 -0
  65. data/lib/ree_lib/packages/ree_text/spec/ree_text/functions/safe_join_spec.rb +1 -1
  66. data/lib/ree_lib/packages/ree_text/spec/ree_text/functions/to_sentence_spec.rb +1 -1
  67. data/lib/ree_lib/packages/ree_validator/spec/ree_validator/functions/validate_password_spec.rb +1 -1
  68. data/lib/ree_lib/version.rb +1 -1
  69. metadata +39 -11
  70. data/lib/ree_lib/packages/ree_actions/package/ree_actions/action.rb +0 -10
  71. data/lib/ree_lib/packages/ree_actions/package/ree_actions/action_dsl.rb +0 -60
  72. data/lib/ree_lib/packages/ree_actions/spec/ree_actions/action_dsl_spec.rb +0 -62
  73. data/lib/ree_lib/packages/ree_roda/package/ree_roda/plugins/ree_actions.rb +0 -150
  74. data/lib/ree_lib/packages/ree_roda/package/ree_roda/services/build_swagger_from_actions.rb +0 -55
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 941b77c681e1913693fd1d61bbdb31f80a58a28c57d0449572326c00168d08f5
4
- data.tar.gz: 618a3a1cb779993f53b089b53c701da7152bbc668a0e482687e44fbb5527ac57
3
+ metadata.gz: 312cc35a258130ad44e9158b53cf46c47309a9e835d25c0447f8596b1c3a3f99
4
+ data.tar.gz: b0af834f7406b9858cb278bd78f3d9e6015b7fc16a8211a72abc3b50ff64ac16
5
5
  SHA512:
6
- metadata.gz: 62b8cd78d133570a809a7c7c1ecec96223f9b92ffe018fb126891b016ede11f02d2efda8d50fea34323679d621544a83422100bf075e17fe97a6360c297fd2dd
7
- data.tar.gz: 321b3a88a7d74b08bd5c9ebfc7820916fede0d196c0687615033fb4d8e08b198c013502fb8b88ae131ee963f578315986c12c779b782a38e7fb6d7d242c2fb9a
6
+ metadata.gz: 9a8af706ff26335b51cbb87593bbe590163d425b94107317780ecf9c60176cca4c135e5ccc7c885db6065df0e4ed5215dd6a76e97f3f4e54fd03c8bcd45d482c
7
+ data.tar.gz: 1e477dc9a10421cdb5e8fb9b96b7068a322af007c562d8703e178330b0538f5b1006dd3fe225c029a292055990c54e644bc13ce08350b02420ea84f716cf98e4
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ree_lib (1.0.39)
4
+ ree_lib (1.0.40)
5
5
  binding_of_caller (~> 1.0.0)
6
6
  i18n (~> 1.12.0)
7
7
  loofah (~> 2.18.0)
@@ -73,6 +73,8 @@ GEM
73
73
  timecop (0.9.6)
74
74
  tzinfo (2.0.6)
75
75
  concurrent-ruby (~> 1.0)
76
+ warden (1.2.9)
77
+ rack (>= 2.0.9)
76
78
  webmock (3.18.1)
77
79
  addressable (>= 2.8.0)
78
80
  crack (>= 0.3.2)
@@ -94,6 +96,7 @@ DEPENDENCIES
94
96
  rspec
95
97
  sqlite3 (~> 1.4.4)
96
98
  timecop (~> 0.9.5)
99
+ warden (~> 1.2.9)
97
100
  webmock
98
101
 
99
102
  BUNDLED WITH
@@ -1,4 +1,4 @@
1
- # frozen_string_literal = true
1
+ # frozen_string_literal: true
2
2
 
3
3
  RSpec.describe :OBJECT_NAME do
4
4
  link :OBJECT_NAME, from: :PACKAGE_NAME
@@ -74,6 +74,10 @@
74
74
  "name": "ree_roda",
75
75
  "schema": "packages/ree_roda/Package.schema.json"
76
76
  },
77
+ {
78
+ "name": "ree_routes",
79
+ "schema": "packages/ree_routes/Package.schema.json"
80
+ },
77
81
  {
78
82
  "name": "ree_string",
79
83
  "schema": "packages/ree_string/Package.schema.json"
@@ -1,4 +1,4 @@
1
- # frozen_string_literal = true
1
+ # frozen_string_literal: true
2
2
 
3
3
  package_require('RELATIVE_FILE_PATH')
4
4
 
@@ -1,101 +1,59 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "action_builder"
4
- require "uri"
5
-
6
1
  module ReeActions
7
2
  module DSL
8
3
  def self.included(base)
9
4
  base.extend(ClassMethods)
5
+ base.include(ReeMapper::DSL)
10
6
  end
11
7
 
12
8
  def self.extended(base)
13
9
  base.extend(ClassMethods)
14
- end
15
-
16
- module FactoryMethod
17
- def build
18
- self.class.instance_variable_get(:@actions) || []
19
- end
10
+ base.include(ReeMapper::DSL)
20
11
  end
21
12
 
22
13
  module ClassMethods
23
14
  include Ree::Contracts::Core
24
15
  include Ree::Contracts::ArgContracts
25
16
 
26
- def actions(name, &proc)
27
- raise ArgumentError.new("block is required") if !block_given?
28
-
29
- @dsl = Ree::ObjectDsl.new(
30
- Ree.container.packages_facade, name, self, :object
17
+ def action(name, &proc)
18
+ dsl = Ree::ObjectDsl.new(
19
+ Ree.container.packages_facade, name, self, :fn
31
20
  )
32
21
 
33
- @dsl.singleton
34
- @dsl.factory(:build)
35
- @dsl.tags(["actions"])
22
+ dsl.instance_exec(&proc) if block_given?
23
+ dsl.tags(["action"])
24
+ dsl.freeze(false)
25
+ dsl.object.set_as_compiled(false)
36
26
 
37
- instance_exec(&proc)
38
-
39
- klass = @dsl.object.klass
40
- klass.send(:include, FactoryMethod)
41
-
42
-
43
- Ree.container.compile(@dsl.package, name)
27
+ Ree.container.compile(dsl.package, name)
44
28
  end
45
29
 
46
- def default_warden_scope(method_name)
47
- @default_warden_scope = method_name
48
- end
30
+ def method_added(method_name)
31
+ return super if method_name != :call
49
32
 
50
- [:get, :post, :put, :delete, :patch, :head, :options].each do |request_method|
51
- define_method request_method do |path, &proc|
52
- define_action(request_method, path, &proc)
33
+ if @__original_call_defined
34
+ remove_instance_variable(:@__original_call_defined)
35
+ return
53
36
  end
54
- end
55
-
56
- private
57
37
 
58
- contract Symbol, String, Block => ReeActions::Action
59
- def define_action(request_method, path, &proc)
60
- raise ArgumentError.new("actions should be called") if !@dsl
61
- raise ArgumentError.new("block is required") if !block_given?
38
+ @__original_call_defined = true
62
39
 
63
- @actions ||= []
64
-
65
- builder = ReeActions::ActionBuilder.new
66
- builder.instance_exec(&proc)
67
-
68
- if @default_warden_scope && !builder.get_action.warden_scope
69
- builder.warden_scope(@default_warden_scope)
70
- end
71
-
72
- uri = URI.parse(path) rescue nil
73
-
74
- if uri.nil? || uri.path != path
75
- raise ArgumentError.new("invalid path provided #{path}")
76
- end
77
-
78
- if uri.query && !uri.query.empty?
79
- raise ArgumentError.new("action path should not include query params: #{path}")
80
- end
81
-
82
- builder.get_action.path = path
83
- builder.get_action.request_method = request_method
84
-
85
- if !builder.get_action.valid?
86
- raise ArgumentError.new("action, summary and auth scope should be provider for #{builder.get_action.inspect}")
87
- end
40
+ alias_method(:__original_call, :call)
88
41
 
89
- action = builder.get_action
42
+ define_method :call do |user_access, attrs|
43
+ if self.class.const_defined?(:ActionCaster)
44
+ caster = self.class.const_get(:ActionCaster)
90
45
 
91
- @dsl.link(action.action.name, from: action.action.package_name)
46
+ if !caster.respond_to?(:cast)
47
+ raise ArgumentError.new("ActionCaster does not respond to `cast` method")
48
+ end
92
49
 
93
- if action.serializer
94
- @dsl.link(action.serializer.name, from: action.serializer.package_name)
50
+ __original_call(user_access, caster.cast(attrs))
51
+ else
52
+ __original_call(user_access, attrs)
53
+ end
95
54
  end
96
55
 
97
- @actions << action
98
- action
56
+ nil
99
57
  end
100
58
  end
101
59
  end
@@ -8,5 +8,4 @@ module ReeActions
8
8
  end
9
9
  end
10
10
 
11
- require_relative "ree_actions/dsl"
12
- require_relative "ree_actions/action_dsl"
11
+ require_relative "ree_actions/dsl"
@@ -1,93 +1,62 @@
1
1
  package_require("ree_actions/dsl")
2
2
 
3
3
  RSpec.describe ReeActions::DSL, type: [:autoclean] do
4
- before :all do
4
+ before do
5
5
  Ree.enable_irb_mode
6
+ end
6
7
 
8
+ after do
9
+ Ree.disable_irb_mode
10
+ end
11
+
12
+ it {
7
13
  module ReeActionsTest
8
14
  include Ree::PackageDSL
9
15
 
10
- package
11
- end
12
-
13
- class ReeActionsTest::EmptyActions
14
- include ReeActions::DSL
15
-
16
- actions :empty_actions do
16
+ package do
17
+ depends_on :ree_mapper
17
18
  end
18
- end
19
19
 
20
- class ReeActionsTest::Cmd
21
- include Ree::FnDSL
20
+ class TestAction
21
+ include ReeActions::DSL
22
22
 
23
- fn :cmd
23
+ action :test_action
24
24
 
25
- def call
26
- end
27
- end
28
-
29
- class ReeActionsTest::Serializer
30
- include ReeMapper::DSL
31
-
32
- mapper :serializer
25
+ ActionCaster = build_mapper.use(:cast) do
26
+ integer :user_id
27
+ end
33
28
 
34
- build_mapper.use(:serialize) do
35
- integer :id
29
+ contract Any, ActionCaster.dto(:cast) => Integer
30
+ def call(user_access, attrs)
31
+ attrs[:user_id]
32
+ end
36
33
  end
37
34
  end
38
35
 
39
- class ReeActionsTest::Caster
40
- include ReeMapper::DSL
36
+ result = ReeActionsTest::TestAction.new.call('user_access', {user_id: 1})
37
+ expect(result).to eq(1)
38
+ }
41
39
 
42
- mapper :caster
40
+ it {
41
+ module ReeActionsTest
42
+ include Ree::PackageDSL
43
43
 
44
- build_mapper.use(:cast) do
45
- integer :id
44
+ package do
46
45
  end
47
- end
48
46
 
49
- class ReeActionsTest::Actions
50
- include ReeActions::DSL
47
+ class TestAction2
48
+ include ReeActions::DSL
51
49
 
52
- actions :actions do
53
- default_warden_scope :user
54
-
55
- post "users" do
56
- summary "Test action"
57
- action :cmd, from: :ree_actions_test
58
- serializer :serializer, from: :ree_actions_test
59
- respond_to :json
60
- end
50
+ action :test_action2
61
51
 
62
- get "files.csv" do
63
- summary "Test action"
64
- action :cmd, from: :ree_actions_test
65
- respond_to :csv
52
+ contract Any, Hash => Integer
53
+ def call(user_access, attrs)
54
+ attrs[:user_id]
66
55
  end
67
56
  end
68
57
  end
69
- end
70
-
71
- after :all do
72
- Ree.disable_irb_mode
73
- end
74
-
75
- it {
76
- expect(ReeActionsTest::EmptyActions.new).to eq([])
77
- }
78
-
79
- it {
80
- actions = ReeActionsTest::Actions.new
81
-
82
- expect(actions.size).to eq(2)
83
-
84
- post_action = actions.first
85
- csv_action = actions.last
86
-
87
- expect(post_action.serializer.name).to eq(:serializer)
88
- expect(post_action.action.name).to eq(:cmd)
89
- expect(post_action.respond_to).to eq(:json)
90
58
 
91
- expect(csv_action.respond_to).to eq(:csv)
59
+ result = ReeActionsTest::TestAction2.new.call('user_access', {user_id: 1})
60
+ expect(result).to eq(1)
92
61
  }
93
62
  end
@@ -1,4 +1,4 @@
1
- # frozen_string_literal = true
1
+ # frozen_string_literal: true
2
2
 
3
3
  package_require('ree_array/functions/group_by')
4
4
 
@@ -1,4 +1,4 @@
1
- # frozen_string_literal = true
1
+ # frozen_string_literal: true
2
2
 
3
3
  RSpec.describe :index_by do
4
4
  link :index_by, from: :ree_array
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "sequel/extensions/pg_array"
4
+
5
+ class ReeDao::PgArray < ReeMapper::AbstractWrapper
6
+ contract(
7
+ Any,
8
+ Kwargs[
9
+ name: String,
10
+ role: Nilor[Symbol, ArrayOf[Symbol]],
11
+ fields_filters: ArrayOf[ReeMapper::FieldsFilter]
12
+ ] => Or[Sequel::Postgres::PGArray, String]
13
+ )
14
+ def db_dump(value, name:, role: nil, fields_filters: [])
15
+ if !value.is_a?(Array)
16
+ raise ReeMapper::TypeError, "`#{name}` should be an array"
17
+ end
18
+
19
+ value = value.map.with_index do |el, index|
20
+ subject.type.db_dump(
21
+ el,
22
+ name: "#{name}[#{index}]",
23
+ role: role,
24
+ fields_filters: fields_filters + [subject.fields_filter]
25
+ )
26
+ end
27
+
28
+ Sequel.pg_array(value)
29
+ end
30
+
31
+ contract(
32
+ Any,
33
+ Kwargs[
34
+ name: String,
35
+ role: Nilor[Symbol, ArrayOf[Symbol]],
36
+ fields_filters: ArrayOf[ReeMapper::FieldsFilter]
37
+ ] => Array
38
+ ).throws(ReeMapper::TypeError)
39
+ def db_load(value, name:, role: nil, fields_filters: [])
40
+ if !value.is_a?(Sequel::Postgres::PGArray)
41
+ raise ReeMapper::TypeError, "`#{name}` is not Sequel::Postgres::PGArray"
42
+ end
43
+
44
+ value.map.with_index do |val, index|
45
+ subject.type.db_load(
46
+ val,
47
+ name: "#{name}[#{index}]",
48
+ role: role,
49
+ fields_filters: fields_filters + [subject.fields_filter]
50
+ )
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,73 @@
1
+ require "sequel/extensions/pg_json"
2
+
3
+ package_require("ree_object/functions/to_hash")
4
+
5
+ class ReeDao::PgJsonb < ReeMapper::AbstractWrapper
6
+ contract(
7
+ Any,
8
+ Kwargs[
9
+ name: String,
10
+ role: Nilor[Symbol, ArrayOf[Symbol]],
11
+ fields_filters: ArrayOf[ReeMapper::FieldsFilter]
12
+ ] => Or[
13
+ Sequel::Postgres::JSONBHash,
14
+ Sequel::Postgres::JSONBArray,
15
+ Sequel::Postgres::JSONBInteger,
16
+ Sequel::Postgres::JSONBTrue,
17
+ Sequel::Postgres::JSONBFalse,
18
+ Sequel::Postgres::JSONBString,
19
+ Sequel::Postgres::JSONBFloat,
20
+ Sequel::Postgres::JSONBNull
21
+ ]
22
+ ).throws(ReeMapper::TypeError)
23
+ def db_dump(value, name:, role: nil, fields_filters: [])
24
+ value = subject.type.db_dump(
25
+ value,
26
+ name: name,
27
+ role: role,
28
+ fields_filters: fields_filters + [subject.fields_filter]
29
+ )
30
+
31
+ begin
32
+ Sequel.pg_jsonb_wrap(value)
33
+ rescue Sequel::Error
34
+ raise ReeMapper::TypeError, "`#{name}` should be an jsonb primitive"
35
+ end
36
+ end
37
+
38
+ contract(
39
+ Any,
40
+ Kwargs[
41
+ name: String,
42
+ role: Nilor[Symbol, ArrayOf[Symbol]],
43
+ fields_filters: ArrayOf[ReeMapper::FieldsFilter]
44
+ ] => Or[
45
+ Hash,
46
+ Array,
47
+ Integer,
48
+ Float,
49
+ String,
50
+ Bool,
51
+ NilClass
52
+ ]
53
+ ).throws(ReeMapper::TypeError)
54
+ def db_load(value, name:, role: nil, fields_filters: [])
55
+ value = case value
56
+ when Sequel::Postgres::JSONBHash
57
+ ReeObject::ToHash.new.call(value.to_h)
58
+ when Sequel::Postgres::JSONBArray
59
+ ReeObject::ToHash.new.call(value.to_a)
60
+ when Numeric, String, TrueClass, FalseClass, NilClass
61
+ value
62
+ else
63
+ raise ReeMapper::TypeError, "`#{name}` is not Sequel::Postgres::JSONB"
64
+ end
65
+
66
+ subject.type.db_load(
67
+ value,
68
+ name: name,
69
+ role: role,
70
+ fields_filters: fields_filters + [subject.fields_filter]
71
+ )
72
+ end
73
+ end
@@ -1,4 +1,4 @@
1
- # frozen_string_literal = true
1
+ # frozen_string_literal: true
2
2
 
3
3
  package_require('ree_dao')
4
4
  package_require('ree_dto/entity_dsl')
@@ -1,9 +1,9 @@
1
- # frozen_string_literal = true
1
+ # frozen_string_literal: true
2
2
 
3
3
  RSpec.describe :one_to_many do
4
+ link :build_sqlite_connection, from: :ree_dao
4
5
  link :one_to_many, from: :ree_dao
5
6
  link :persist_assoc, from: :ree_dao
6
- link :build_sqlite_connection, from: :ree_dao
7
7
 
8
8
  let(:connection) { build_sqlite_connection({database: 'sqlite_db'}) }
9
9
 
@@ -1,9 +1,9 @@
1
- # frozen_string_literal = true
1
+ # frozen_string_literal: true
2
2
 
3
3
  RSpec.describe :one_to_one do
4
+ link :build_sqlite_connection, from: :ree_dao
4
5
  link :one_to_one, from: :ree_dao
5
6
  link :persist_assoc, from: :ree_dao
6
- link :build_sqlite_connection, from: :ree_dao
7
7
 
8
8
  let(:connection) { build_sqlite_connection({database: 'sqlite_db'}) }
9
9
 
@@ -1,8 +1,8 @@
1
- # frozen_string_literal = true
1
+ # frozen_string_literal: true
2
2
 
3
3
  RSpec.describe :persist_assoc do
4
- link :persist_assoc, from: :ree_dao
5
4
  link :build_sqlite_connection, from: :ree_dao
5
+ link :persist_assoc, from: :ree_dao
6
6
 
7
7
  let(:connection) { build_sqlite_connection({database: 'sqlite_db'}) }
8
8
 
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ package_require("ree_dao/wrappers/pg_array")
4
+
5
+ RSpec.describe 'ReeDao::PgArray' do
6
+ link :build_mapper_factory, from: :ree_mapper
7
+ link :build_mapper_strategy, from: :ree_mapper
8
+
9
+ let(:mapper_factory) {
10
+ build_mapper_factory(
11
+ strategies: [
12
+ build_mapper_strategy(method: :cast),
13
+ build_mapper_strategy(method: :serialize),
14
+ build_mapper_strategy(method: :db_dump, dto: Hash),
15
+ build_mapper_strategy(method: :db_load, dto: Hash, always_optional: true)
16
+ ]
17
+ ).register_wrapper(:pg_array, ReeDao::PgArray)
18
+ }
19
+
20
+ let(:mapper) {
21
+ mapper_factory.call.use(:db_dump).use(:db_load) do
22
+ pg_array? :tags, integer
23
+ pg_array? :keys, string
24
+ end
25
+ }
26
+
27
+ describe '#db_dump' do
28
+ it {
29
+ expect(mapper.db_dump({
30
+ tags: [1, 2],
31
+ keys: ["a", "b"]
32
+ })).to eq({
33
+ tags: [1, 2],
34
+ keys: ["a", "b"]
35
+ })
36
+ }
37
+
38
+ it {
39
+ expect {
40
+ mapper.db_dump({ tags: 1 })
41
+ }.to raise_error(ReeMapper::TypeError, "`tags` should be an array")
42
+ }
43
+ end
44
+
45
+ describe '#db_load' do
46
+ it {
47
+ expect(mapper.db_load({
48
+ tags: Sequel::Postgres::PGArray.new([1, 2]),
49
+ keys: Sequel::Postgres::PGArray.new(["a", "b"])
50
+ })).to eq({
51
+ tags: [1, 2],
52
+ keys: ["a", "b"]
53
+ })
54
+ }
55
+
56
+ it {
57
+ expect {
58
+ mapper.db_load({
59
+ tags: 1
60
+ })
61
+ }.to raise_error(ReeMapper::TypeError, "`tags` is not Sequel::Postgres::PGArray")
62
+ }
63
+ end
64
+ end
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ package_require("ree_dao/wrappers/pg_jsonb")
4
+
5
+ RSpec.describe 'ReeDao::PgJsonb' do
6
+ link :build_mapper_factory, from: :ree_mapper
7
+ link :build_mapper_strategy, from: :ree_mapper
8
+
9
+ let(:mapper_factory) {
10
+ build_mapper_factory(
11
+ strategies: [
12
+ build_mapper_strategy(method: :cast),
13
+ build_mapper_strategy(method: :serialize),
14
+ build_mapper_strategy(method: :db_dump, dto: Hash),
15
+ build_mapper_strategy(method: :db_load, dto: Hash, always_optional: true)
16
+ ]
17
+ ).register_wrapper(:pg_jsonb, ReeDao::PgJsonb)
18
+ }
19
+
20
+ let(:mapper) {
21
+ mapper_factory.call.use(:db_dump).use(:db_load) do
22
+ pg_jsonb? :payload do
23
+ string :key
24
+ end
25
+ pg_jsonb? :numbers, array(integer)
26
+ pg_jsonb? :figures, (array do
27
+ string :coords
28
+ end)
29
+ pg_jsonb? :number, integer
30
+ pg_jsonb? :boolean, bool
31
+ pg_jsonb? :any, any
32
+ end
33
+ }
34
+
35
+ describe '#db_dump' do
36
+ it {
37
+ expect(mapper.db_dump({
38
+ payload: { key: 'key' },
39
+ numbers: [1, 2],
40
+ figures: [{ coords: 'x=1,y=1' }],
41
+ number: 1,
42
+ boolean: true
43
+ })).to eq({
44
+ payload: { key: 'key' },
45
+ numbers: [1, 2],
46
+ figures: [{ coords: 'x=1,y=1' }],
47
+ number: 1,
48
+ boolean: true
49
+ })
50
+ }
51
+
52
+ it {
53
+ expect {
54
+ mapper.db_dump({ numbers: ['1'] })
55
+ }.to raise_error(ReeMapper::TypeError, "`numbers[0]` should be an integer")
56
+ }
57
+
58
+ it {
59
+ expect {
60
+ mapper.db_dump({ any: Object.new })
61
+ }.to raise_error(ReeMapper::TypeError, "`any` should be an jsonb primitive")
62
+ }
63
+ end
64
+
65
+ describe '#db_load' do
66
+ it {
67
+ expect(mapper.db_load({
68
+ payload: Sequel::Postgres::JSONBHash.new({ key: 'key' }),
69
+ numbers: Sequel::Postgres::JSONBArray.new([1, 2]),
70
+ figures: Sequel::Postgres::JSONBArray.new([{ coords: 'x=1,y=1' }]),
71
+ number: 1,
72
+ boolean: true
73
+ })).to eq({
74
+ payload: { key: 'key' },
75
+ numbers: [1, 2],
76
+ figures: [{ coords: 'x=1,y=1' }],
77
+ number: 1,
78
+ boolean: true
79
+ })
80
+ }
81
+
82
+ it {
83
+ expect {
84
+ mapper.db_load({ numbers: Sequel::Postgres::JSONBArray.new([1.1]) })
85
+ }.to raise_error(ReeMapper::TypeError, "`numbers[0]` should be an integer")
86
+ }
87
+
88
+ it {
89
+ expect {
90
+ mapper.db_load({ numbers: Object.new })
91
+ }.to raise_error(ReeMapper::TypeError, "`numbers` is not Sequel::Postgres::JSONB")
92
+ }
93
+ end
94
+ end
@@ -1,4 +1,4 @@
1
- # frozen_string_literal = true
1
+ # frozen_string_literal: true
2
2
 
3
3
  RSpec.describe :in_default_time_zone do
4
4
  link :in_default_time_zone, from: :ree_datetime