ree_lib 1.0.39 → 1.0.40

Sign up to get free protection for your applications and to get access to all the features.
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