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,85 +0,0 @@
1
- require 'rom'
2
- require 'rom/memory'
3
- require 'rom/plugins/relation/key_inference'
4
-
5
- RSpec.describe ROM::Plugins::Relation::KeyInference do
6
- subject(:relation) do
7
- relation_class.new(
8
- [],
9
- __registry__: ROM::RelationRegistry.new(posts: posts, users: users, tags: tags)
10
- )
11
- end
12
-
13
- let(:posts) { double(foreign_key: :post_id) }
14
- let(:tags_name) { ROM::Relation::Name[:tags] }
15
- let(:tags) { double(foreign_key: :tag_id) }
16
- let(:users_name) { ROM::Relation::Name[:users] }
17
- let(:users) { double(base_name: users_name) }
18
-
19
- describe 'without a schema' do
20
- let(:relation_class) do
21
- Class.new(ROM::Memory::Relation) do
22
- use :key_inference
23
-
24
- dataset :users
25
- end
26
- end
27
-
28
- describe '#base_name' do
29
- it 'returns dataset name by default' do
30
- expect(relation.base_name).to eql(ROM::Relation::Name[:users])
31
- end
32
- end
33
-
34
- describe '#foreign_key' do
35
- it 'returns default value' do
36
- expect(relation.foreign_key).to be(:user_id)
37
- end
38
-
39
- it 'returns default value for another relation' do
40
- expect(relation.foreign_key(:posts)).to be(:post_id)
41
- expect(relation.foreign_key(posts)).to be(:post_id)
42
- end
43
-
44
- it 'returns default value for Relation::Name' do
45
- expect(relation.foreign_key(ROM::Relation::Name[:posts])).to be(:post_id)
46
- end
47
-
48
- it 'supports objects responding to to_sym' do
49
- external_name = double(to_sym: :tags)
50
- expect(relation.foreign_key(external_name)).to be(:tag_id)
51
- end
52
- end
53
- end
54
-
55
- describe 'with a schema' do
56
- let(:relation_class) do
57
- Class.new(ROM::Memory::Relation) do
58
- use :key_inference
59
-
60
- schema :posts do
61
- attribute :author_id, ROM::Types::Int.meta(foreign_key: true, relation: :users)
62
- end
63
- end
64
- end
65
-
66
- describe '#foreign_key' do
67
- it 'returns configured value' do
68
- expect(relation.foreign_key(ROM::Relation::Name[:users])).to be(:author_id)
69
- expect(relation.foreign_key(:users)).to be(:author_id)
70
- expect(relation.foreign_key(users)).to be(:author_id)
71
- expect(relation.foreign_key(users_name)).to be(:author_id)
72
- end
73
-
74
- it 'falls back to default when schema has no fk specified' do
75
- expect(relation.foreign_key(:tags)).to be(:tag_id)
76
- expect(relation.foreign_key(tags_name)).to be(:tag_id)
77
- end
78
-
79
- it 'supports objects responding to to_sym' do
80
- external_name = double(to_sym: :tags)
81
- expect(relation.foreign_key(external_name)).to be(:tag_id)
82
- end
83
- end
84
- end
85
- end
@@ -1,51 +0,0 @@
1
- require 'rom'
2
- require 'rom/memory'
3
- require 'rom/plugins/relation/view'
4
-
5
- RSpec.describe ROM::Plugins::Relation::View do
6
- subject(:relation) { relation_class.new([]) }
7
-
8
- let(:relation_class) do
9
- Class.new(ROM::Memory::Relation) do
10
- use :view
11
-
12
- view(:base, [:id, :name]) do
13
- self
14
- end
15
-
16
- view(:ids, [:id]) do
17
- self
18
- end
19
-
20
- view(:names, [:name]) do |id|
21
- self
22
- end
23
- end
24
- end
25
-
26
- describe '#attributes' do
27
- it 'returns base view attributes by default' do
28
- expect(relation.attributes).to eql([:id, :name])
29
- end
30
-
31
- it 'returns attributes for a view' do
32
- expect(relation.ids.attributes).to eql([:id])
33
- end
34
-
35
- it 'returns attributes for a view with args' do
36
- expect(relation.names(1).attributes).to eql([:name])
37
- end
38
-
39
- it 'returns attributes for a curried view' do
40
- expect(relation.names.attributes).to eql([:name])
41
- end
42
-
43
- it 'returns correct arity for a curried view' do
44
- expect(relation.names.arity).to be(1)
45
- end
46
-
47
- it 'returns explicitly set attributes' do
48
- expect(relation.with(attributes: [:foo, :bar]).attributes).to eql([:foo, :bar])
49
- end
50
- end
51
- end
@@ -1,89 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ROM::Relation::Composite do
4
- include_context 'gateway only'
5
- include_context 'users and tasks'
6
-
7
- let(:users_relation) do
8
- Class.new(ROM::Memory::Relation) do
9
- def by_name(name)
10
- restrict(name: name)
11
- end
12
-
13
- def sorted(other)
14
- other.source.order(:name)
15
- end
16
- end.new(users_dataset)
17
- end
18
-
19
- let(:tasks_relation) do
20
- Class.new(ROM::Memory::Relation) do
21
- def for_users(users)
22
- restrict(name: users.map { |u| u[:name] })
23
- end
24
- end.new(tasks_dataset)
25
- end
26
-
27
- let(:name_list) { proc { |r| r.map { |t| t[:name] } } }
28
- let(:upcaser) { proc { |r| r.map(&:upcase) } }
29
-
30
- describe '#call' do
31
- it 'sends a relation through mappers' do
32
- relation = users_relation >> name_list >> upcaser
33
- loaded = relation.call
34
-
35
- expect(loaded.source).to eql(users_relation)
36
-
37
- expect(loaded).to match_array(%w(JANE JOE))
38
- end
39
-
40
- it 'sends a relation through another relation' do
41
- relation = users_relation >> users_relation.sorted
42
- loaded = relation.call
43
-
44
- expect(loaded.source).to eql(users_relation.sorted(users_relation.call))
45
-
46
- expect(loaded).to match_array([
47
- { name: 'Jane', email: 'jane@doe.org' },
48
- { name: 'Joe', email: 'joe@doe.org' }
49
- ])
50
- end
51
-
52
- it 'sends a relation through another composite relation' do
53
- task_mapper = -> tasks_relation { tasks_relation }
54
- relation = users_relation.by_name('Jane') >> (tasks_relation.for_users >> task_mapper)
55
-
56
- loaded = relation.call
57
-
58
- expect(loaded.source).to eql(tasks_relation.for_users(users_relation.by_name('Jane')))
59
-
60
- expect(loaded).to match_array([
61
- { name: 'Jane', title: 'be cool', priority: 2 }
62
- ])
63
- end
64
- end
65
-
66
- describe '#each' do
67
- let(:relation) { users_relation >> name_list >> upcaser }
68
-
69
- it 'calls and iterates' do
70
- result = []
71
- relation.each do |object|
72
- result << object
73
- end
74
- expect(result).to match_array(%w(JANE JOE))
75
- end
76
-
77
- it 'returns enumerator if block is not provided' do
78
- expect(relation.each.to_a).to match_array(%w(JANE JOE))
79
- end
80
- end
81
-
82
- describe '#first' do
83
- let(:relation) { users_relation >> name_list >> upcaser }
84
-
85
- it 'calls and returns the first object' do
86
- expect(relation.first).to eql('JOE')
87
- end
88
- end
89
- end
@@ -1,52 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe ROM::Relation::Curried do
4
- include_context 'gateway only'
5
- include_context 'users and tasks'
6
-
7
- let(:users_relation) do
8
- Class.new(ROM::Memory::Relation) do
9
- def by_name(name)
10
- restrict(name: name)
11
- end
12
-
13
- def find(criteria)
14
- restrict(criteria)
15
- end
16
- end.new(users_dataset)
17
- end
18
-
19
- describe '#call' do
20
- let(:relation) { users_relation.by_name.call('Jane') }
21
-
22
- it 'materializes a relation' do
23
- expect(relation).to match_array([
24
- name: 'Jane', email: 'jane@doe.org'
25
- ])
26
- end
27
-
28
- it 'returns a loaded relation' do
29
- expect(relation.source).to eql(users_relation.by_name('Jane'))
30
- end
31
- end
32
-
33
- describe '#respond_to?' do
34
- it 'returns true if wrapped relation responds to a method' do
35
- expect(users_relation.by_name).to respond_to(:dataset)
36
- end
37
-
38
- it 'returns false if wrapped relation does not respond to a method' do
39
- expect(users_relation.by_name).not_to respond_to(:not_here)
40
- end
41
- end
42
-
43
- describe '#method_missing' do
44
- it 'forwards to the relation' do
45
- expect(users_relation.by_name.dataset).to eql(users_relation.dataset)
46
- end
47
-
48
- it 'does not forward to the relation when method is auto-curried' do
49
- expect { users_relation.by_name.find }.to raise_error(NoMethodError, /find/)
50
- end
51
- end
52
- end
@@ -1,92 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ROM::Relation::Graph do
4
- include_context 'gateway only'
5
- include_context 'users and tasks'
6
-
7
- let(:users_relation) do
8
- Class.new(ROM::Memory::Relation) do
9
- def by_name(name)
10
- restrict(name: name)
11
- end
12
- end.new(users_dataset)
13
- end
14
-
15
- let(:tasks_relation) do
16
- Class.new(ROM::Memory::Relation) do
17
- def for_users(_users)
18
- self
19
- end
20
- end.new(tasks_dataset)
21
- end
22
-
23
- subject(:graph) { ROM::Relation::Graph.new(users_relation, [tasks_relation.for_users]) }
24
-
25
- describe '#graph?' do
26
- it 'returns true' do
27
- expect(graph.graph?).to be(true)
28
- end
29
-
30
- it 'returns true when curried' do
31
- expect(graph.by_name.graph?).to be(true)
32
- end
33
- end
34
-
35
- it_behaves_like 'materializable relation' do
36
- let(:mapper) do
37
- T(:combine, [[:tasks, name: :name]])
38
- end
39
-
40
- let(:relation) do
41
- ROM::Relation::Graph.new(users_relation.by_name('Jane'), [tasks_relation.for_users]) >> mapper
42
- end
43
- end
44
-
45
- describe '#method_missing' do
46
- it 'responds to the root methods' do
47
- expect(graph).to respond_to(:by_name)
48
- end
49
-
50
- it 'forwards methods to the root and decorates response' do
51
- expect(graph.by_name('Jane')).to be_instance_of(ROM::Relation::Graph)
52
- end
53
-
54
- it 'forwards methods to the root and decorates curried response' do
55
- expect((users_relation.combine(tasks_relation.for_users)).by_name).to be_instance_of(ROM::Relation::Graph)
56
- end
57
-
58
- it 'returns original response from the root' do
59
- expect(graph.mappers).to eql(users_relation.mappers)
60
- end
61
-
62
- it 'raises method error' do
63
- expect { graph.not_here }.to raise_error(NoMethodError, /not_here/)
64
- end
65
- end
66
-
67
- describe '#call' do
68
- it 'materializes relations' do
69
- expect(graph.call).to match_array([
70
- users_relation,
71
- [tasks_relation]
72
- ])
73
- end
74
- end
75
-
76
- describe '#to_a' do
77
- it 'coerces to an array' do
78
- expect(graph).to match_array([
79
- users_relation.to_a,
80
- [tasks_relation.for_users(users_relation).to_a]
81
- ])
82
- end
83
-
84
- it 'returns empty arrays when left was empty' do
85
- graph = ROM::Relation::Graph.new(users_relation.by_name('Not here'), [tasks_relation.for_users])
86
-
87
- expect(graph).to match_array([
88
- [], [ROM::Relation::Loaded.new(tasks_relation.for_users, [])]
89
- ])
90
- end
91
- end
92
- end
@@ -1,165 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ROM::Relation, '#combine' do
4
- include_context 'gateway only'
5
- include_context 'users and tasks'
6
-
7
- let(:tags_dataset) { gateway.dataset(:tags) }
8
-
9
- let(:users_relation) do
10
- Class.new(ROM::Memory::Relation) do
11
- def by_name(name)
12
- restrict(name: name)
13
- end
14
- end.new(users_dataset)
15
- end
16
-
17
- let(:tasks_relation) do
18
- Class.new(ROM::Memory::Relation) do
19
- def for_users(users)
20
- names = users.map { |user| user[:name] }
21
- restrict { |task| names.include?(task[:name]) }
22
- end
23
- end.new(tasks_dataset)
24
- end
25
-
26
- let(:tags_relation) do
27
- Class.new(ROM::Memory::Relation) do
28
- attr_accessor :tasks
29
- forward :map
30
-
31
- def for_tasks(tasks)
32
- titles = tasks.map { |task| task[:title] }
33
- restrict { |tag| titles.include?(tag[:task]) }
34
- end
35
-
36
- def for_users(users)
37
- user_tasks = tasks.for_users(users)
38
-
39
- for_tasks(user_tasks).map { |tag|
40
- tag.merge(user: user_tasks.detect { |task|
41
- task[:title] == tag[:task]
42
- } [:name])
43
- }
44
- end
45
- end.new(tags_dataset).tap { |r| r.tasks = tasks_relation }
46
- end
47
-
48
- before do
49
- tags_dataset.insert(task: 'be cool', name: 'red')
50
- tags_dataset.insert(task: 'be cool', name: 'green')
51
- end
52
-
53
- let(:map_users) {
54
- proc { |users, tasks|
55
- users.map { |user|
56
- user.merge(tasks: tasks.select { |task| task[:name] == user[:name] })
57
- }
58
- }
59
- }
60
-
61
- let(:map_tasks) {
62
- proc { |(tasks, children)|
63
- tags = children.first
64
-
65
- tasks.map { |task|
66
- task.merge(tags: tags.select { |tag| tag[:task] == task[:title] })
67
- }
68
- }
69
- }
70
-
71
- let(:map_user_with_tasks_and_tags) {
72
- proc { |users, (tasks, tags)|
73
- users.map { |user|
74
- user_tasks = tasks.select { |task| task[:name] == user[:name] }
75
-
76
- user_tags = tasks.flat_map { |task|
77
- tags.select { |tag| tag[:task] == task[:title] }
78
- }
79
-
80
- user.merge(
81
- tasks: user_tasks,
82
- tags: user_tags
83
- )
84
- }
85
- }
86
- }
87
-
88
- let(:map_user_with_tasks) {
89
- proc { |users, children|
90
- map_users[users, map_tasks[children.first]]
91
- }
92
- }
93
-
94
- it 'raises error when composite relation is passed as a node' do
95
- expect {
96
- users_relation.combine(tasks_relation >> proc {})
97
- }.to raise_error(ROM::UnsupportedRelationError)
98
- end
99
-
100
- it 'supports more than one eagerly-loaded relation' do
101
- expected = [
102
- {
103
- name: 'Jane',
104
- email: 'jane@doe.org',
105
- tasks: [
106
- { name: 'Jane', title: 'be cool', priority: 2 }
107
- ],
108
- tags: [
109
- { task: 'be cool', name: 'red' },
110
- { task: 'be cool', name: 'green' }
111
- ]
112
- }
113
- ]
114
-
115
- user_with_tasks_and_tags = users_relation.by_name('Jane')
116
- .combine(tasks_relation.for_users, tags_relation.for_users)
117
-
118
- result = user_with_tasks_and_tags >> map_user_with_tasks_and_tags
119
-
120
- expect(result.to_a).to eql(expected)
121
- end
122
-
123
- it 'supports more than one eagerly-loaded relation via chaining' do
124
- expected = [
125
- {
126
- name: 'Jane',
127
- email: 'jane@doe.org',
128
- tasks: [
129
- { name: 'Jane', title: 'be cool', priority: 2 }
130
- ],
131
- tags: [
132
- { task: 'be cool', name: 'red' },
133
- { task: 'be cool', name: 'green' }
134
- ]
135
- }
136
- ]
137
-
138
- user_with_tasks_and_tags = users_relation.by_name('Jane')
139
- .combine(tasks_relation.for_users).combine(tags_relation.for_users)
140
-
141
- result = user_with_tasks_and_tags >> map_user_with_tasks_and_tags
142
-
143
- expect(result).to match_array(expected)
144
- end
145
-
146
- it 'supports nested eager-loading' do
147
- expected = [
148
- {
149
- name: 'Jane', email: 'jane@doe.org', tasks: [
150
- { name: 'Jane', title: 'be cool', priority: 2, tags: [
151
- { task: 'be cool', name: 'red' },
152
- { task: 'be cool', name: 'green' }
153
- ] }
154
- ]
155
- }
156
- ]
157
-
158
- user_with_tasks = users_relation.by_name('Jane')
159
- .combine(tasks_relation.for_users.combine(tags_relation.for_tasks))
160
-
161
- result = user_with_tasks >> map_user_with_tasks
162
-
163
- expect(result).to match_array(expected)
164
- end
165
- end