rom 2.0.2 → 4.2.1

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 (203) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +35 -430
  3. data/LICENSE +1 -1
  4. data/README.md +83 -11
  5. data/lib/rom/version.rb +1 -1
  6. data/lib/rom.rb +3 -46
  7. metadata +30 -236
  8. data/.gitignore +0 -24
  9. data/.rspec +0 -3
  10. data/.rubocop.yml +0 -87
  11. data/.rubocop_todo.yml +0 -46
  12. data/.travis.yml +0 -28
  13. data/CODE_OF_CONDUCT.md +0 -13
  14. data/CONTRIBUTING.md +0 -1
  15. data/Gemfile +0 -41
  16. data/Guardfile +0 -24
  17. data/Rakefile +0 -22
  18. data/lib/rom/association_set.rb +0 -26
  19. data/lib/rom/command.rb +0 -173
  20. data/lib/rom/command_registry.rb +0 -153
  21. data/lib/rom/commands/class_interface.rb +0 -148
  22. data/lib/rom/commands/composite.rb +0 -54
  23. data/lib/rom/commands/create.rb +0 -13
  24. data/lib/rom/commands/delete.rb +0 -14
  25. data/lib/rom/commands/graph/builder.rb +0 -176
  26. data/lib/rom/commands/graph/class_interface.rb +0 -62
  27. data/lib/rom/commands/graph/input_evaluator.rb +0 -62
  28. data/lib/rom/commands/graph.rb +0 -103
  29. data/lib/rom/commands/lazy/create.rb +0 -23
  30. data/lib/rom/commands/lazy/delete.rb +0 -27
  31. data/lib/rom/commands/lazy/update.rb +0 -34
  32. data/lib/rom/commands/lazy.rb +0 -99
  33. data/lib/rom/commands/result.rb +0 -96
  34. data/lib/rom/commands/update.rb +0 -14
  35. data/lib/rom/commands.rb +0 -3
  36. data/lib/rom/configuration.rb +0 -88
  37. data/lib/rom/configuration_dsl/command.rb +0 -43
  38. data/lib/rom/configuration_dsl/command_dsl.rb +0 -35
  39. data/lib/rom/configuration_dsl/mapper.rb +0 -37
  40. data/lib/rom/configuration_dsl/mapper_dsl.rb +0 -44
  41. data/lib/rom/configuration_dsl/relation.rb +0 -26
  42. data/lib/rom/configuration_dsl.rb +0 -78
  43. data/lib/rom/configuration_plugin.rb +0 -17
  44. data/lib/rom/constants.rb +0 -30
  45. data/lib/rom/container.rb +0 -231
  46. data/lib/rom/create_container.rb +0 -61
  47. data/lib/rom/environment.rb +0 -70
  48. data/lib/rom/gateway.rb +0 -154
  49. data/lib/rom/global/plugin_dsl.rb +0 -49
  50. data/lib/rom/global.rb +0 -60
  51. data/lib/rom/lint/enumerable_dataset.rb +0 -54
  52. data/lib/rom/lint/gateway.rb +0 -94
  53. data/lib/rom/lint/linter.rb +0 -78
  54. data/lib/rom/lint/spec.rb +0 -20
  55. data/lib/rom/lint/test.rb +0 -98
  56. data/lib/rom/mapper_registry.rb +0 -35
  57. data/lib/rom/memory/commands.rb +0 -58
  58. data/lib/rom/memory/dataset.rb +0 -98
  59. data/lib/rom/memory/gateway.rb +0 -64
  60. data/lib/rom/memory/relation.rb +0 -49
  61. data/lib/rom/memory/storage.rb +0 -59
  62. data/lib/rom/memory/types.rb +0 -9
  63. data/lib/rom/memory.rb +0 -4
  64. data/lib/rom/pipeline.rb +0 -106
  65. data/lib/rom/plugin.rb +0 -17
  66. data/lib/rom/plugin_base.rb +0 -31
  67. data/lib/rom/plugin_registry.rb +0 -173
  68. data/lib/rom/plugins/command/schema.rb +0 -37
  69. data/lib/rom/plugins/configuration/configuration_dsl.rb +0 -17
  70. data/lib/rom/plugins/relation/key_inference.rb +0 -46
  71. data/lib/rom/plugins/relation/registry_reader.rb +0 -32
  72. data/lib/rom/plugins/relation/view/dsl.rb +0 -32
  73. data/lib/rom/plugins/relation/view.rb +0 -95
  74. data/lib/rom/relation/class_interface.rb +0 -230
  75. data/lib/rom/relation/composite.rb +0 -46
  76. data/lib/rom/relation/curried.rb +0 -104
  77. data/lib/rom/relation/graph.rb +0 -115
  78. data/lib/rom/relation/loaded.rb +0 -118
  79. data/lib/rom/relation/materializable.rb +0 -66
  80. data/lib/rom/relation/name.rb +0 -102
  81. data/lib/rom/relation.rb +0 -172
  82. data/lib/rom/relation_registry.rb +0 -9
  83. data/lib/rom/schema/dsl.rb +0 -58
  84. data/lib/rom/schema.rb +0 -89
  85. data/lib/rom/setup/auto_registration.rb +0 -69
  86. data/lib/rom/setup/auto_registration_strategies/base.rb +0 -11
  87. data/lib/rom/setup/auto_registration_strategies/custom_namespace.rb +0 -22
  88. data/lib/rom/setup/auto_registration_strategies/no_namespace.rb +0 -19
  89. data/lib/rom/setup/auto_registration_strategies/with_namespace.rb +0 -18
  90. data/lib/rom/setup/finalize/finalize_commands.rb +0 -47
  91. data/lib/rom/setup/finalize/finalize_mappers.rb +0 -36
  92. data/lib/rom/setup/finalize/finalize_relations.rb +0 -60
  93. data/lib/rom/setup/finalize.rb +0 -146
  94. data/lib/rom/setup.rb +0 -55
  95. data/lib/rom/support/configurable.rb +0 -80
  96. data/lib/rom/types.rb +0 -18
  97. data/log/.gitkeep +0 -0
  98. data/rakelib/benchmark.rake +0 -15
  99. data/rakelib/mutant.rake +0 -19
  100. data/rakelib/rubocop.rake +0 -18
  101. data/rom.gemspec +0 -26
  102. data/spec/fixtures/app/commands/create_user.rb +0 -2
  103. data/spec/fixtures/app/mappers/user_list.rb +0 -2
  104. data/spec/fixtures/app/my_commands/create_user.rb +0 -2
  105. data/spec/fixtures/app/my_mappers/user_list.rb +0 -2
  106. data/spec/fixtures/app/my_relations/users.rb +0 -2
  107. data/spec/fixtures/app/relations/users.rb +0 -2
  108. data/spec/fixtures/custom/commands/create_user.rb +0 -6
  109. data/spec/fixtures/custom/mappers/user_list.rb +0 -6
  110. data/spec/fixtures/custom/relations/users.rb +0 -6
  111. data/spec/fixtures/lib/persistence/commands/create_user.rb +0 -6
  112. data/spec/fixtures/lib/persistence/mappers/user_list.rb +0 -6
  113. data/spec/fixtures/lib/persistence/my_commands/create_user.rb +0 -6
  114. data/spec/fixtures/lib/persistence/my_mappers/user_list.rb +0 -6
  115. data/spec/fixtures/lib/persistence/my_relations/users.rb +0 -6
  116. data/spec/fixtures/lib/persistence/relations/users.rb +0 -6
  117. data/spec/integration/command_registry_spec.rb +0 -60
  118. data/spec/integration/commands/create_spec.rb +0 -177
  119. data/spec/integration/commands/delete_spec.rb +0 -67
  120. data/spec/integration/commands/error_handling_spec.rb +0 -25
  121. data/spec/integration/commands/graph_builder_spec.rb +0 -213
  122. data/spec/integration/commands/graph_spec.rb +0 -288
  123. data/spec/integration/commands/update_spec.rb +0 -109
  124. data/spec/integration/commands_spec.rb +0 -67
  125. data/spec/integration/mappers/combine_spec.rb +0 -117
  126. data/spec/integration/mappers/deep_embedded_spec.rb +0 -44
  127. data/spec/integration/mappers/definition_dsl_spec.rb +0 -206
  128. data/spec/integration/mappers/embedded_spec.rb +0 -62
  129. data/spec/integration/mappers/exclude_spec.rb +0 -27
  130. data/spec/integration/mappers/fold_spec.rb +0 -71
  131. data/spec/integration/mappers/group_spec.rb +0 -163
  132. data/spec/integration/mappers/overwrite_attributes_value_spec.rb +0 -51
  133. data/spec/integration/mappers/prefix_separator_spec.rb +0 -52
  134. data/spec/integration/mappers/prefix_spec.rb +0 -48
  135. data/spec/integration/mappers/prefixing_attributes_spec.rb +0 -37
  136. data/spec/integration/mappers/registering_custom_mappers_spec.rb +0 -28
  137. data/spec/integration/mappers/renaming_attributes_spec.rb +0 -125
  138. data/spec/integration/mappers/reusing_mappers_spec.rb +0 -43
  139. data/spec/integration/mappers/step_spec.rb +0 -119
  140. data/spec/integration/mappers/symbolizing_attributes_spec.rb +0 -77
  141. data/spec/integration/mappers/unfold_spec.rb +0 -92
  142. data/spec/integration/mappers/ungroup_spec.rb +0 -126
  143. data/spec/integration/mappers/unwrap_spec.rb +0 -93
  144. data/spec/integration/mappers/wrap_spec.rb +0 -155
  145. data/spec/integration/memory/commands/create_spec.rb +0 -23
  146. data/spec/integration/memory/commands/delete_spec.rb +0 -23
  147. data/spec/integration/memory/commands/update_spec.rb +0 -23
  148. data/spec/integration/multi_env_spec.rb +0 -69
  149. data/spec/integration/multi_repo_spec.rb +0 -46
  150. data/spec/integration/relations/default_dataset_spec.rb +0 -38
  151. data/spec/integration/relations/inheritance_spec.rb +0 -37
  152. data/spec/integration/relations/reading_spec.rb +0 -169
  153. data/spec/integration/relations/registry_dsl_spec.rb +0 -45
  154. data/spec/integration/repositories/extending_relations_spec.rb +0 -58
  155. data/spec/integration/repositories/setting_logger_spec.rb +0 -34
  156. data/spec/integration/setup_spec.rb +0 -160
  157. data/spec/shared/command_behavior.rb +0 -28
  158. data/spec/shared/command_graph.rb +0 -50
  159. data/spec/shared/container.rb +0 -9
  160. data/spec/shared/enumerable_dataset.rb +0 -52
  161. data/spec/shared/gateway_only.rb +0 -6
  162. data/spec/shared/materializable.rb +0 -36
  163. data/spec/shared/no_container.rb +0 -16
  164. data/spec/shared/one_behavior.rb +0 -26
  165. data/spec/shared/proxy.rb +0 -0
  166. data/spec/shared/users_and_tasks.rb +0 -10
  167. data/spec/spec_helper.rb +0 -52
  168. data/spec/support/constant_leak_finder.rb +0 -14
  169. data/spec/support/mutant.rb +0 -10
  170. data/spec/support/types.rb +0 -5
  171. data/spec/test/memory_repository_lint_test.rb +0 -27
  172. data/spec/unit/rom/association_set_spec.rb +0 -23
  173. data/spec/unit/rom/commands/graph_spec.rb +0 -191
  174. data/spec/unit/rom/commands/lazy_spec.rb +0 -307
  175. data/spec/unit/rom/commands/result_spec.rb +0 -70
  176. data/spec/unit/rom/commands_spec.rb +0 -165
  177. data/spec/unit/rom/configurable_spec.rb +0 -49
  178. data/spec/unit/rom/configuration_spec.rb +0 -61
  179. data/spec/unit/rom/container_spec.rb +0 -99
  180. data/spec/unit/rom/create_container_spec.rb +0 -151
  181. data/spec/unit/rom/environment_spec.rb +0 -123
  182. data/spec/unit/rom/gateway_spec.rb +0 -146
  183. data/spec/unit/rom/mapper_registry_spec.rb +0 -25
  184. data/spec/unit/rom/memory/commands_spec.rb +0 -43
  185. data/spec/unit/rom/memory/dataset_spec.rb +0 -31
  186. data/spec/unit/rom/memory/relation_spec.rb +0 -109
  187. data/spec/unit/rom/memory/repository_spec.rb +0 -12
  188. data/spec/unit/rom/memory/storage_spec.rb +0 -45
  189. data/spec/unit/rom/plugin_spec.rb +0 -150
  190. data/spec/unit/rom/plugins/command/schema_spec.rb +0 -66
  191. data/spec/unit/rom/plugins/relation/key_inference_spec.rb +0 -85
  192. data/spec/unit/rom/plugins/relation/view_spec.rb +0 -51
  193. data/spec/unit/rom/relation/composite_spec.rb +0 -89
  194. data/spec/unit/rom/relation/curried_spec.rb +0 -52
  195. data/spec/unit/rom/relation/graph_spec.rb +0 -92
  196. data/spec/unit/rom/relation/lazy/combine_spec.rb +0 -165
  197. data/spec/unit/rom/relation/lazy_spec.rb +0 -214
  198. data/spec/unit/rom/relation/loaded_spec.rb +0 -53
  199. data/spec/unit/rom/relation/name_spec.rb +0 -58
  200. data/spec/unit/rom/relation/schema_spec.rb +0 -117
  201. data/spec/unit/rom/relation_spec.rb +0 -237
  202. data/spec/unit/rom/schema_spec.rb +0 -10
  203. data/spec/unit/rom/setup/auto_registration_spec.rb +0 -152
@@ -1,288 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'Building up a command graph for nested input' do
4
- include_context 'command graph'
5
-
6
- it 'creates a command graph for nested input :one result as root' do
7
- configuration.commands(:tasks) do
8
- define(:create) do
9
- result :one
10
-
11
- def execute(tuple, user)
12
- super(tuple.merge(user: user.fetch(:name)))
13
- end
14
- end
15
- end
16
-
17
- input = {
18
- user: {
19
- name: 'Jane',
20
- task: {
21
- title: 'Task One',
22
- tags: [
23
- { name: 'red' }, { name: 'green' }, { name: 'blue' }
24
- ]
25
- },
26
- books: [
27
- { title: 'Book One' },
28
- { title: 'Book Two' }
29
- ]
30
- }
31
- }
32
-
33
- options = [
34
- { user: :users }, [
35
- :create, [
36
- [{ task: :tasks }, [:create, [:tags, [:create]]]],
37
- [:books, [:create]]
38
- ]
39
- ]
40
- ]
41
-
42
- command = container.command(options)
43
-
44
- command.call(input)
45
-
46
- expect(container.relation(:users)).to match_array([
47
- { name: 'Jane' }
48
- ])
49
-
50
- expect(container.relation(:tasks)).to match_array([
51
- { title: 'Task One', user: 'Jane' }
52
- ])
53
-
54
- expect(container.relation(:books)).to match_array([
55
- { title: 'Book One', user: 'Jane' },
56
- { title: 'Book Two', user: 'Jane' }
57
- ])
58
-
59
- expect(container.relation(:tags)).to match_array([
60
- { name: 'red', task: 'Task One' },
61
- { name: 'green', task: 'Task One' },
62
- { name: 'blue', task: 'Task One' }
63
- ])
64
- end
65
-
66
- it 'creates a command graph for nested input with :many results as root' do
67
- configuration.commands(:tasks) do
68
- define(:create) do
69
- def execute(tuples, user)
70
- super(tuples.map { |t| t.merge(user: user.fetch(:name)) })
71
- end
72
- end
73
- end
74
-
75
- input = {
76
- user: {
77
- name: 'Jane',
78
- tasks: [
79
- {
80
- title: 'Task One',
81
- tags: [{ name: 'red' }, { name: 'green' }]
82
- },
83
- {
84
- title: 'Task Two',
85
- tags: [{ name: 'blue' }]
86
- }
87
- ]
88
- }
89
- }
90
-
91
- options = [
92
- { user: :users }, [
93
- :create, [
94
- [:tasks, [:create, [:tags, [:create]]]]
95
- ]
96
- ]
97
- ]
98
-
99
- command = container.command(options)
100
-
101
- command.call(input)
102
-
103
- expect(container.relation(:users)).to match_array([
104
- { name: 'Jane' }
105
- ])
106
-
107
- expect(container.relation(:tasks)).to match_array([
108
- { title: 'Task One', user: 'Jane' },
109
- { title: 'Task Two', user: 'Jane' }
110
- ])
111
-
112
- expect(container.relation(:tags)).to match_array([
113
- { name: 'red', task: 'Task One' },
114
- { name: 'green', task: 'Task One' },
115
- { name: 'blue', task: 'Task Two' }
116
- ])
117
- end
118
-
119
-
120
- it 'updates graph elements cleanly' do
121
- configuration.commands(:tasks) do
122
- define(:create) do
123
- def execute(tuples, user)
124
- super(tuples.map { |t| t.merge(user: user.fetch(:name)) })
125
- end
126
- end
127
-
128
- define(:update) do
129
- result :one
130
-
131
- def execute(tuple, user)
132
- super(tuple.merge(user: user.fetch(:name)))
133
- end
134
- end
135
-
136
- define(:delete) do
137
- register_as :complete
138
- result :one
139
- end
140
- end
141
-
142
- configuration.commands(:users) do
143
- define(:update) do
144
- result :one
145
- end
146
- end
147
-
148
- initial = {
149
- user: {
150
- name: 'Johnny',
151
- email: 'johnny@doe.org',
152
- tasks: [
153
- { title: 'Change Name' },
154
- { title: 'Finish that novel' }
155
- ]
156
- }
157
- }
158
-
159
- updated = {
160
- user: {
161
- name: 'Johnny',
162
- email: 'johnathan@doe.org',
163
- completed: [{ title: 'Change Name' }],
164
- tasks: [{ title: 'Finish that novel', priority: 1 }]
165
- }
166
- }
167
-
168
- create = container.command([{ user: :users }, [:create, [:tasks, [:create]]]])
169
-
170
- update = container.command([
171
- { user: :users },
172
- [
173
- { update: -> cmd, user { cmd.by_name(user[:name]) } },
174
- [
175
- [
176
- { completed: :tasks },
177
- [{ complete: -> cmd, user, task { cmd.by_user_and_title(user[:name], task[:title]) } }]
178
- ],
179
- [
180
- :tasks,
181
- [{ update: -> cmd, user, task { cmd.by_user_and_title(user[:name], task[:title]) } }]
182
- ]
183
- ]
184
- ]
185
- ])
186
-
187
- create.call(initial)
188
-
189
- container.command(:tasks).create.call(
190
- [{ title: 'Task One'}], { name: 'Jane' }
191
- )
192
-
193
- expect(container.relation(:tasks)).to match_array([
194
- { title: 'Change Name', user: 'Johnny' },
195
- { title: 'Finish that novel', user: 'Johnny' },
196
- { title: 'Task One', user: 'Jane' }
197
- ])
198
-
199
- update.call(updated)
200
-
201
- expect(container.relation(:users)).to match_array([
202
- { name: 'Johnny', email: 'johnathan@doe.org' }
203
- ])
204
-
205
- expect(container.relation(:tasks)).to match_array([
206
- { title: 'Task One', user: 'Jane' },
207
- { title: 'Finish that novel', priority: 1, user: 'Johnny' }
208
- ])
209
- end
210
-
211
-
212
- it 'works with auto-mapping' do
213
- configuration.mappers do
214
- define(:users) do
215
- register_as :entity
216
- reject_keys true
217
-
218
- model name: 'Test::User'
219
-
220
- attribute :name
221
-
222
- combine :tasks, on: { name: :user } do
223
- model name: 'Test::Task'
224
- attribute :title
225
-
226
- combine :tags, on: { title: :task } do
227
- model name: 'Test::Tag'
228
- attribute :name
229
- end
230
- end
231
- end
232
- end
233
-
234
- configuration.commands(:tasks) do
235
- define(:create) do
236
- def execute(tuples, user)
237
- super(tuples.map { |t| t.merge(user: user.fetch(:name)) })
238
- end
239
- end
240
- end
241
-
242
- input = {
243
- user: {
244
- name: 'Jane',
245
- tasks: [
246
- {
247
- title: 'Task One',
248
- tags: [{ name: 'red' }, { name: 'green' }]
249
- },
250
- {
251
- title: 'Task Two',
252
- tags: [{ name: 'blue' }]
253
- }
254
- ]
255
- }
256
- }
257
-
258
- options = [
259
- { user: :users }, [
260
- :create, [
261
- [:tasks, [:create, [:tags, [:create]]]]
262
- ]
263
- ]
264
- ]
265
-
266
- command = container.command(options).as(:entity)
267
-
268
- result = command.call(input)
269
-
270
- expect(result).to be_instance_of(Test::User)
271
- expect(result.tasks.first).to be_instance_of(Test::Task)
272
- expect(result.tasks.first.tags.first).to be_instance_of(Test::Tag)
273
- end
274
-
275
- it 'raises a proper error when the input has invalid structure' do
276
- input = { user: { name: 'Jane' } }
277
-
278
- options = [
279
- { user: :users }, [:create, [{ book: :books }, [:create]]]
280
- ]
281
-
282
- command = container.command(options)
283
-
284
- expect {
285
- command.call(input)
286
- }.to raise_error(ROM::KeyMissing, /book/)
287
- end
288
- end
@@ -1,109 +0,0 @@
1
- require 'spec_helper'
2
- require 'dry-struct'
3
-
4
- describe 'Commands / Update' do
5
- include_context 'container'
6
- include_context 'users and tasks'
7
-
8
- subject(:users) { container.commands.users }
9
-
10
- before do
11
- module Test
12
- UserValidator = Class.new do
13
- ValidationError = Class.new(ROM::CommandError)
14
-
15
- def self.call(params)
16
- raise ValidationError, ":email is required" unless params[:email]
17
- end
18
- end
19
- end
20
-
21
- configuration.relation(:users) do
22
- register_as :users
23
-
24
- def all(criteria)
25
- restrict(criteria)
26
- end
27
-
28
- def by_name(name)
29
- restrict(name: name)
30
- end
31
- end
32
-
33
- configuration.commands(:users) do
34
- define(:update) do
35
- validator Test::UserValidator
36
- end
37
- end
38
- end
39
-
40
- it 'update tuples on successful validation' do
41
- result = users.try {
42
- users.update.all(name: 'Jane').call(email: 'jane.doe@test.com')
43
- }
44
-
45
- expect(result)
46
- .to match_array([{ name: 'Jane', email: 'jane.doe@test.com' }])
47
- end
48
-
49
- it 'returns validation object with errors on failed validation' do
50
- result = users.try { users.update.all(name: 'Jane').call(email: nil) }
51
-
52
- expect(result.error).to be_instance_of(Test::ValidationError)
53
- expect(result.error.message).to eql(':email is required')
54
-
55
- expect(container.relations.users.restrict(name: 'Jane')).to match_array([
56
- { name: 'Jane', email: 'jane@doe.org' }
57
- ])
58
- end
59
-
60
- describe '"result" option' do
61
- it 'returns a single tuple when set to :one' do
62
- configuration.commands(:users) do
63
- define(:update_one, type: :update) do
64
- result :one
65
- end
66
- end
67
-
68
- result = users.try {
69
- users.update_one.by_name('Jane').call(email: 'jane.doe@test.com')
70
- }
71
-
72
- expect(result.value).to eql(name: 'Jane', email: 'jane.doe@test.com')
73
- end
74
-
75
- it 'allows only valid result types' do
76
- expect {
77
- configuration.commands(:users) do
78
- define(:create_one, type: :create) do
79
- result :invalid_type
80
- end
81
- end
82
- container
83
- }.to raise_error(ROM::Options::InvalidOptionValueError)
84
- end
85
- end
86
-
87
- describe 'piping results through mappers' do
88
- it 'allows scoping to a virtual relation' do
89
- user_model = Class.new(Dry::Struct) {
90
- attribute :name, Types::String
91
- attribute :email, Types::String
92
- }
93
-
94
- configuration.mappers do
95
- define(:users) do
96
- model user_model
97
- register_as :entity
98
- end
99
- end
100
-
101
- command = container.command(:users).as(:entity).update.by_name('Jane')
102
-
103
- attributes = { name: 'Jane Doe', email: 'jane@doe.org' }
104
- result = command[attributes]
105
-
106
- expect(result).to eql([user_model.new(attributes)])
107
- end
108
- end
109
- end
@@ -1,67 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'Commands' do
4
- include_context 'container'
5
- include_context 'users and tasks'
6
-
7
- before do
8
- configuration.relation(:users) do
9
- def by_id(id)
10
- restrict(id: id)
11
- end
12
- end
13
-
14
- configuration.commands(:users) do
15
- define(:update)
16
- define(:create)
17
- end
18
- end
19
-
20
- let(:create) { container.command(:users)[:create] }
21
- let(:update) { container.command(:users)[:update] }
22
-
23
- describe '#method_missing' do
24
- it 'forwards known relation view methods' do
25
- expect(update.by_id(1).relation).to eql(users_relation.by_id(1))
26
- end
27
-
28
- it 'raises no-method error when a non-view relation method was sent' do
29
- expect { update.as(:foo) }.to raise_error(NoMethodError, /as/)
30
- end
31
-
32
- it 'does not forward relation view methods to non-restrictable commands' do
33
- expect { create.by_id(1) }.to raise_error(NoMethodError, /by_id/)
34
- end
35
- end
36
-
37
- describe 'extending command with a db-specific behavior' do
38
- before do
39
- gateway.instance_exec do
40
- def extend_command_class(klass, _)
41
- klass.class_eval do
42
- def super_command?
43
- true
44
- end
45
- end
46
- klass
47
- end
48
- end
49
- end
50
-
51
- it 'applies to defined classes' do
52
- klass = Class.new(ROM::Commands::Create[:memory]) { relation :users }
53
- configuration.register_command(klass)
54
- container
55
- command = klass.build(users_relation)
56
- expect(command).to be_super_command
57
- end
58
-
59
- it 'applies to generated classes' do
60
- klass = ROM::ConfigurationDSL::Command.build_class(:create, :users, adapter: :memory)
61
- configuration.register_command(klass)
62
- container
63
- command = klass.build(users_relation)
64
- expect(command).to be_super_command
65
- end
66
- end
67
- end
@@ -1,117 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'Mapper definition DSL' do
4
- include_context 'container'
5
- include_context 'users and tasks'
6
-
7
- describe 'combine' do
8
- before do
9
- configuration.relation(:tasks) do
10
- def for_users(users)
11
- names = users.map { |user| user[:name] }
12
- restrict { |task| names.include?(task[:name]) }
13
- end
14
-
15
- def tags(_tasks)
16
- [{ name: 'blue', task: 'be cool' }]
17
- end
18
- end
19
-
20
- configuration.relation(:users) do
21
- def addresses(_users)
22
- [{ city: 'NYC', user: 'Jane' }, { city: 'Boston', user: 'Joe' }]
23
- end
24
-
25
- def books(_users)
26
- [{ title: 'Book One', user: 'Jane' }, { title: 'Book Two', user: 'Joe' }]
27
- end
28
- end
29
-
30
- configuration.mappers do
31
- define(:users) do
32
- register_as :entity
33
-
34
- model name: 'Test::User'
35
-
36
- attribute :name
37
- attribute :email
38
-
39
- combine :tasks, on: { name: :name } do
40
- model name: 'Test::Task'
41
-
42
- attribute :title
43
-
44
- wrap :meta do
45
- attribute :user, from: :name
46
- attribute :priority
47
- end
48
-
49
- combine :tags, on: { title: :task } do
50
- model name: 'Test::Tag'
51
-
52
- attribute :name
53
- end
54
- end
55
-
56
- combine :address, on: { name: :user }, type: :hash do
57
- model name: 'Test::Address'
58
-
59
- attribute :city
60
- end
61
-
62
- combine :book, on: { name: :user }, type: :hash
63
- end
64
- end
65
- end
66
-
67
- let(:users) { container.relation(:users) }
68
- let(:tasks) { container.relation(:tasks) }
69
-
70
- let(:joe) {
71
- Test::User.new(
72
- name: 'Joe',
73
- email: 'joe@doe.org',
74
- tasks: [
75
- Test::Task.new(title: 'be nice', meta: { user: 'Joe', priority: 1 },
76
- tags: []),
77
- Test::Task.new(title: 'sleep well', meta: { user: 'Joe', priority: 2 },
78
- tags: [])
79
- ],
80
- address: Test::Address.new(city: 'Boston'),
81
- book: { title: 'Book Two', user: 'Joe' }
82
- )
83
- }
84
-
85
- let(:jane) {
86
- Test::User.new(
87
- name: 'Jane',
88
- email: 'jane@doe.org',
89
- tasks: [
90
- Test::Task.new(
91
- title: 'be cool',
92
- meta: { user: 'Jane', priority: 2 },
93
- tags: [Test::Tag.new(name: 'blue')]
94
- )
95
- ],
96
- address: Test::Address.new(city: 'NYC'),
97
- book: { title: 'Book One', user: 'Jane' }
98
- )
99
- }
100
-
101
- it 'works' do
102
- container
103
-
104
- Test::User.send(:include, Dry::Equalizer(:name, :email, :tasks, :address, :book))
105
- Test::Task.send(:include, Dry::Equalizer(:title, :meta))
106
- Test::Address.send(:include, Dry::Equalizer(:city))
107
-
108
- result = users.combine(
109
- tasks.for_users.combine(tasks.tags),
110
- users.addresses,
111
- users.books
112
- ).as(:entity)
113
-
114
- expect(result).to match_array([joe, jane])
115
- end
116
- end
117
- end
@@ -1,44 +0,0 @@
1
- require 'spec_helper'
2
- require 'rom/memory'
3
-
4
- describe 'Mappers / deeply embedded tuples' do
5
- include_context 'container'
6
-
7
- it 'allows mapping embedded tuples' do
8
- configuration.relation(:users)
9
-
10
- configuration.mappers do
11
- define(:users) do
12
- model name: 'Test::User'
13
-
14
- attribute :name, from: 'name'
15
-
16
- embedded :tasks, from: 'tasks' do
17
- attribute :title, from: 'title'
18
-
19
- embedded :priority, from: 'priority', type: :hash do
20
- attribute :value, from: 'value'
21
- attribute :desc, from: 'desc'
22
- end
23
- end
24
- end
25
- end
26
-
27
- container.relations.users << {
28
- 'name' => 'Jane',
29
- 'tasks' => [
30
- { 'title' => 'Task One', 'priority' => { 'value' => 1, 'desc' => 'high' } },
31
- { 'title' => 'Task Two', 'priority' => { 'value' => 3, 'desc' => 'low' } }
32
- ]
33
- }
34
-
35
- jane = container.relation(:users).as(:users).first
36
-
37
- expect(jane.name).to eql('Jane')
38
-
39
- expect(jane.tasks).to eql([
40
- { title: 'Task One', priority: { value: 1, desc: 'high' } },
41
- { title: 'Task Two', priority: { value: 3, desc: 'low' } }
42
- ])
43
- end
44
- end