rom 0.9.1 → 1.0.0.beta1

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 (143) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +30 -12
  3. data/.travis.yml +1 -1
  4. data/CHANGELOG.md +24 -0
  5. data/Gemfile +7 -3
  6. data/README.md +24 -11
  7. data/lib/rom.rb +9 -26
  8. data/lib/rom/command.rb +113 -75
  9. data/lib/rom/commands/class_interface.rb +115 -0
  10. data/lib/rom/commands/graph.rb +17 -23
  11. data/lib/rom/commands/graph/builder.rb +176 -0
  12. data/lib/rom/commands/graph/class_interface.rb +8 -2
  13. data/lib/rom/commands/graph/input_evaluator.rb +13 -9
  14. data/lib/rom/commands/lazy.rb +23 -17
  15. data/lib/rom/commands/lazy/create.rb +23 -0
  16. data/lib/rom/commands/lazy/delete.rb +27 -0
  17. data/lib/rom/commands/lazy/update.rb +34 -0
  18. data/lib/rom/commands/result.rb +14 -0
  19. data/lib/rom/commands/update.rb +0 -4
  20. data/lib/rom/configuration.rb +86 -0
  21. data/lib/rom/{setup_dsl/setup.rb → configuration_dsl.rb} +9 -7
  22. data/lib/rom/configuration_dsl/command.rb +43 -0
  23. data/lib/rom/{setup_dsl → configuration_dsl}/command_dsl.rb +5 -4
  24. data/lib/rom/configuration_dsl/mapper.rb +37 -0
  25. data/lib/rom/{setup_dsl → configuration_dsl}/mapper_dsl.rb +11 -5
  26. data/lib/rom/configuration_dsl/relation.rb +26 -0
  27. data/lib/rom/configuration_plugin.rb +17 -0
  28. data/lib/rom/constants.rb +5 -12
  29. data/lib/rom/container.rb +11 -8
  30. data/lib/rom/create_container.rb +61 -0
  31. data/lib/rom/environment.rb +27 -241
  32. data/lib/rom/gateway.rb +18 -2
  33. data/lib/rom/global.rb +24 -0
  34. data/lib/rom/global/plugin_dsl.rb +2 -0
  35. data/lib/rom/lint/spec.rb +0 -12
  36. data/lib/rom/lint/test.rb +0 -31
  37. data/lib/rom/memory/commands.rb +2 -2
  38. data/lib/rom/memory/gateway.rb +2 -0
  39. data/lib/rom/pipeline.rb +1 -1
  40. data/lib/rom/plugin_base.rb +1 -1
  41. data/lib/rom/plugin_registry.rb +12 -10
  42. data/lib/rom/plugins/configuration/configuration_dsl.rb +16 -0
  43. data/lib/rom/plugins/relation/key_inference.rb +31 -0
  44. data/lib/rom/plugins/relation/view.rb +90 -0
  45. data/lib/rom/plugins/relation/view/dsl.rb +32 -0
  46. data/lib/rom/relation.rb +1 -11
  47. data/lib/rom/relation/class_interface.rb +37 -50
  48. data/lib/rom/setup.rb +13 -104
  49. data/lib/rom/setup/auto_registration.rb +55 -0
  50. data/lib/rom/setup/finalize.rb +113 -127
  51. data/lib/rom/setup/finalize/commands.rb +67 -0
  52. data/lib/rom/setup/finalize/mappers.rb +36 -0
  53. data/lib/rom/setup/finalize/relations.rb +53 -0
  54. data/lib/rom/support/configurable.rb +21 -7
  55. data/lib/rom/version.rb +1 -1
  56. data/rakelib/mutant.rake +4 -1
  57. data/rom.gemspec +3 -4
  58. data/spec/fixtures/app/commands/create_user.rb +2 -0
  59. data/spec/fixtures/app/mappers/user_list.rb +2 -0
  60. data/spec/fixtures/app/relations/users.rb +2 -0
  61. data/spec/fixtures/lib/persistence/commands/create_user.rb +6 -0
  62. data/spec/fixtures/lib/persistence/mappers/user_list.rb +6 -0
  63. data/spec/fixtures/lib/persistence/relations/users.rb +6 -0
  64. data/spec/{unit/rom → integration}/command_registry_spec.rb +8 -9
  65. data/spec/integration/commands/create_spec.rb +17 -13
  66. data/spec/integration/commands/delete_spec.rb +12 -11
  67. data/spec/integration/commands/error_handling_spec.rb +5 -4
  68. data/spec/integration/commands/graph_builder_spec.rb +213 -0
  69. data/spec/integration/commands/graph_spec.rb +112 -49
  70. data/spec/integration/commands/update_spec.rb +14 -11
  71. data/spec/integration/commands_spec.rb +60 -0
  72. data/spec/integration/mappers/combine_spec.rb +7 -6
  73. data/spec/integration/mappers/deep_embedded_spec.rb +5 -6
  74. data/spec/integration/mappers/definition_dsl_spec.rb +19 -18
  75. data/spec/integration/mappers/embedded_spec.rb +11 -12
  76. data/spec/integration/mappers/exclude_spec.rb +5 -6
  77. data/spec/integration/mappers/fold_spec.rb +8 -7
  78. data/spec/integration/mappers/group_spec.rb +16 -15
  79. data/spec/integration/mappers/overwrite_attributes_value_spec.rb +5 -5
  80. data/spec/integration/mappers/prefix_separator_spec.rb +5 -7
  81. data/spec/integration/mappers/prefix_spec.rb +5 -7
  82. data/spec/integration/mappers/prefixing_attributes_spec.rb +7 -7
  83. data/spec/integration/mappers/registering_custom_mappers_spec.rb +4 -5
  84. data/spec/integration/mappers/renaming_attributes_spec.rb +18 -18
  85. data/spec/integration/mappers/step_spec.rb +11 -12
  86. data/spec/integration/mappers/symbolizing_attributes_spec.rb +11 -8
  87. data/spec/integration/mappers/unfold_spec.rb +9 -10
  88. data/spec/integration/mappers/ungroup_spec.rb +10 -11
  89. data/spec/integration/mappers/unwrap_spec.rb +10 -15
  90. data/spec/integration/mappers/wrap_spec.rb +16 -15
  91. data/spec/{unit/rom → integration}/memory/commands/create_spec.rb +7 -5
  92. data/spec/{unit/rom → integration}/memory/commands/delete_spec.rb +7 -5
  93. data/spec/{unit/rom → integration}/memory/commands/update_spec.rb +7 -5
  94. data/spec/integration/multi_env_spec.rb +16 -124
  95. data/spec/integration/multi_repo_spec.rb +9 -9
  96. data/spec/integration/relations/default_dataset_spec.rb +15 -0
  97. data/spec/integration/relations/inheritance_spec.rb +5 -7
  98. data/spec/integration/relations/reading_spec.rb +32 -65
  99. data/spec/integration/relations/registry_dsl_spec.rb +5 -4
  100. data/spec/integration/repositories/extending_relations_spec.rb +6 -7
  101. data/spec/integration/repositories/setting_logger_spec.rb +5 -7
  102. data/spec/integration/setup_spec.rb +49 -61
  103. data/spec/shared/command_graph.rb +50 -0
  104. data/spec/shared/container.rb +9 -0
  105. data/spec/shared/gateway_only.rb +6 -0
  106. data/spec/shared/no_container.rb +16 -0
  107. data/spec/shared/one_behavior.rb +4 -4
  108. data/spec/shared/users_and_tasks.rb +5 -17
  109. data/spec/spec_helper.rb +5 -3
  110. data/spec/test/memory_repository_lint_test.rb +1 -1
  111. data/spec/unit/rom/auto_registration_spec.rb +54 -0
  112. data/spec/unit/rom/commands/graph_spec.rb +18 -44
  113. data/spec/unit/rom/commands/lazy_spec.rb +246 -35
  114. data/spec/unit/rom/commands/result_spec.rb +56 -0
  115. data/spec/unit/rom/commands_spec.rb +9 -73
  116. data/spec/unit/rom/configurable_spec.rb +49 -0
  117. data/spec/unit/rom/configuration_spec.rb +61 -0
  118. data/spec/unit/rom/container_spec.rb +39 -33
  119. data/spec/unit/rom/create_container_spec.rb +151 -0
  120. data/spec/unit/rom/environment_spec.rb +123 -0
  121. data/spec/unit/rom/gateway_spec.rb +58 -2
  122. data/spec/unit/rom/global_spec.rb +10 -7
  123. data/spec/unit/rom/plugin_spec.rb +44 -25
  124. data/spec/unit/rom/plugins/relation/key_inference_spec.rb +27 -0
  125. data/spec/unit/rom/plugins/relation/view_spec.rb +47 -0
  126. data/spec/unit/rom/relation/composite_spec.rb +20 -20
  127. data/spec/unit/rom/relation/curried_spec.rb +10 -11
  128. data/spec/unit/rom/relation/graph_spec.rb +27 -27
  129. data/spec/unit/rom/relation/lazy/combine_spec.rb +26 -20
  130. data/spec/unit/rom/relation/lazy_spec.rb +38 -38
  131. data/spec/unit/rom/relation/loaded_spec.rb +2 -3
  132. data/spec/unit/rom/relation_spec.rb +39 -2
  133. metadata +58 -66
  134. data/lib/rom/commands/abstract.rb +0 -184
  135. data/lib/rom/environment_plugin.rb +0 -17
  136. data/lib/rom/environment_plugins/auto_registration.rb +0 -38
  137. data/lib/rom/repository.rb +0 -16
  138. data/lib/rom/setup_dsl/command.rb +0 -36
  139. data/lib/rom/setup_dsl/mapper.rb +0 -32
  140. data/lib/rom/setup_dsl/relation.rb +0 -30
  141. data/spec/integration/inline_setup_spec.rb +0 -65
  142. data/spec/unit/rom/repository_spec.rb +0 -12
  143. data/spec/unit/rom/setup_spec.rb +0 -253
@@ -11,4 +11,60 @@ describe ROM::Commands::Result do
11
11
  expect(r.value).to eq(data)
12
12
  end
13
13
  end
14
+
15
+ describe '#success?' do
16
+ context 'not launched command' do
17
+ subject(:command) { ROM::Commands::Result }
18
+
19
+ it 'returns false' do
20
+ expect(command.new.success?).to eq(false)
21
+ end
22
+ end
23
+
24
+ context 'successful command' do
25
+ subject(:result) { ROM::Commands::Result::Success }
26
+
27
+ it 'returns true' do
28
+ data = double(to_ary: ['foo'])
29
+ expect(result.new(data).success?).to eq(true)
30
+ end
31
+ end
32
+
33
+ context 'failed command' do
34
+ subject(:result) { ROM::Commands::Result::Failure }
35
+
36
+ it 'returns false' do
37
+ error = double(:error)
38
+ expect(result.new(error).success?).to eq(false)
39
+ end
40
+ end
41
+ end
42
+
43
+ describe '#failure?' do
44
+ context 'not launched command' do
45
+ subject(:command) { ROM::Commands::Result }
46
+
47
+ it 'returns false' do
48
+ expect(command.new.success?).to eq(false)
49
+ end
50
+ end
51
+
52
+ context 'successful command' do
53
+ subject(:result) { ROM::Commands::Result::Success }
54
+
55
+ it 'returns false' do
56
+ data = double(to_ary: ['foo'])
57
+ expect(result.new(data).failure?).to eq(false)
58
+ end
59
+ end
60
+
61
+ context 'failed command' do
62
+ subject(:result) { ROM::Commands::Result::Failure }
63
+
64
+ it 'returns true' do
65
+ error = double(:error)
66
+ expect(result.new(error).failure?).to eq(true)
67
+ end
68
+ end
69
+ end
14
70
  end
@@ -1,21 +1,20 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe 'Commands' do
4
+ include_context 'gateway only'
4
5
  include_context 'users and tasks'
5
6
 
6
- let(:users) { rom.relations.users }
7
-
8
- before do
9
- setup.relation(:users) do
7
+ let(:users_relation) do
8
+ Class.new(ROM::Memory::Relation) do
10
9
  def by_id(id)
11
10
  restrict(id: id)
12
11
  end
13
- end
12
+ end.new(users_dataset)
14
13
  end
15
14
 
16
15
  describe '.build_class' do
17
16
  it 'creates a command class constant' do
18
- klass = ROM::Command.build_class(:create, :users, adapter: :memory) {
17
+ klass = ROM::ConfigurationDSL::Command.build_class(:create, :users, adapter: :memory) {
19
18
  def super?
20
19
  true
21
20
  end
@@ -24,7 +23,7 @@ describe 'Commands' do
24
23
  expect(klass.name).to eql('ROM::Memory::Commands::Create[Users]')
25
24
  expect(klass.register_as).to eql(:create)
26
25
 
27
- command = klass.build(rom.relations.users)
26
+ command = klass.build(users_relation)
28
27
 
29
28
  expect(command).to be_a(ROM::Memory::Commands::Create)
30
29
  expect(command).to be_super
@@ -37,7 +36,7 @@ describe 'Commands' do
37
36
  relation :users
38
37
  end
39
38
 
40
- command = klass.build(users)
39
+ command = klass.build(users_relation)
41
40
 
42
41
  expect(command).to be_kind_of(ROM::Memory::Commands::Create)
43
42
  end
@@ -47,7 +46,7 @@ describe 'Commands' do
47
46
  relation :users
48
47
  end
49
48
 
50
- command = klass.build(users)
49
+ command = klass.build(users_relation)
51
50
 
52
51
  expect(command).to be_kind_of(ROM::Memory::Commands::Update)
53
52
  end
@@ -57,63 +56,10 @@ describe 'Commands' do
57
56
  relation :users
58
57
  end
59
58
 
60
- command = klass.build(users)
59
+ command = klass.build(users_relation)
61
60
 
62
61
  expect(command).to be_kind_of(ROM::Memory::Commands::Delete)
63
62
  end
64
-
65
- describe 'extending command with a db-specific behavior' do
66
- before do
67
- setup.gateways[:default].instance_exec do
68
- def extend_command_class(klass, _)
69
- klass.class_eval do
70
- def super_command?
71
- true
72
- end
73
- end
74
- klass
75
- end
76
- end
77
- end
78
-
79
- it 'applies to defined classes' do
80
- klass = Class.new(ROM::Commands::Create[:memory]) { relation :users }
81
- command = klass.build(users)
82
- expect(command).to be_super_command
83
- end
84
-
85
- it 'applies to generated classes' do
86
- klass = ROM::Command.build_class(:create, :users, adapter: :memory)
87
- command = klass.build(users)
88
- expect(command).to be_super_command
89
- end
90
- end
91
- end
92
-
93
- describe '.registry' do
94
- it 'builds a hash with commands grouped by relations' do
95
- commands = {}
96
-
97
- [:Create, :Update, :Delete].each do |command_type|
98
- klass = Class.new(ROM::Commands.const_get(command_type)) do
99
- relation :users
100
- end
101
- klass.class_eval "def self.name; 'Test::#{command_type}'; end"
102
- commands[command_type] = klass
103
- end
104
-
105
- registry = ROM::Command.registry(
106
- rom.relations, setup.gateways, commands.values
107
- )
108
-
109
- expect(registry).to eql(
110
- users: {
111
- create: commands[:Create].build(users),
112
- update: commands[:Update].build(users),
113
- delete: commands[:Delete].build(users)
114
- }
115
- )
116
- end
117
63
  end
118
64
 
119
65
  describe '#>>' do
@@ -178,14 +124,4 @@ describe 'Commands' do
178
124
  command.with(user_input).call
179
125
  end
180
126
  end
181
-
182
- describe 'access to exposed relations' do
183
- it 'exposes relation' do
184
- command = ROM::Commands::Update[:memory].build(users)
185
-
186
- users.insert(id: 1, name: 'Jane')
187
-
188
- expect(command.by_id(1).relation).to eql(users.by_id(1))
189
- end
190
- end
191
127
  end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe ROM::Configurable do
4
+ let (:klass) { Class.new { include ROM::Configurable } }
5
+ let (:object) { klass.new }
6
+ let (:config) { object.config }
7
+
8
+ it 'exposes the config property' do
9
+ expect { config }.not_to raise_error
10
+ end
11
+
12
+ it 'is configurable via block' do
13
+ object.configure do |config|
14
+ config.sql.infer_relations = false
15
+ end
16
+
17
+ expect(config.sql.infer_relations).to be(false)
18
+ end
19
+
20
+ context ROM::Configurable::Config do
21
+ it 'can be traversed via dot syntax' do
22
+ config.sql.infer_relations = false
23
+ expect(config.sql.infer_relations).to be(false)
24
+ end
25
+
26
+ it 'can be traversed via bracket syntax' do
27
+ config[:sql].infer_relations = false
28
+
29
+ expect(config[:sql][:infer_relations]).to be(false)
30
+ expect(config).to respond_to(:sql)
31
+ expect(config.sql.infer_relations).to be(false)
32
+ end
33
+
34
+ it 'freezes properly' do
35
+ config.freeze
36
+
37
+ expect { config.sql.infer_relations = false }.to raise_error(NoMethodError)
38
+ end
39
+
40
+ it 'handles unset keys when frozen' do
41
+ config.sql.infer_relations = false
42
+ config.freeze
43
+
44
+ expect(config.other).to be(nil)
45
+ expect(config.key?(:other)).to be(false)
46
+ expect(config.key?(:sql)).to be(true)
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+
3
+ describe ROM::Configuration do
4
+ it 'is configurable via settings hash' do
5
+ configuration = ROM::Configuration.new(:memory, 'something', infer_schema: false)
6
+
7
+ expect(configuration.config.gateways.default.infer_schema).to be(false)
8
+
9
+ configuration = ROM::Configuration.new(:memory, infer_schema: false)
10
+
11
+ expect(configuration.config.gateways.default.infer_schema).to be(false)
12
+
13
+ configuration = ROM::Configuration.new(default: [:memory, infer_schema: false])
14
+
15
+ expect(configuration.config.gateways.default.infer_schema).to be(false)
16
+ end
17
+
18
+ describe '#method_missing' do
19
+ it 'returns a gateway if it is defined' do
20
+ repo = double('repo')
21
+ configuration = ROM::Configuration.new(repo: repo)
22
+
23
+ expect(configuration.repo).to be(repo)
24
+ end
25
+
26
+ it 'raises error if repo is not defined' do
27
+ configuration = ROM::Configuration.new
28
+
29
+ expect { configuration.not_here }.to raise_error(NoMethodError, /not_here/)
30
+ end
31
+ end
32
+
33
+ describe '#[]' do
34
+ it 'returns a gateway if it is defined' do
35
+ repo = double('repo')
36
+ configuration = ROM::Configuration.new(repo: repo)
37
+
38
+ expect(configuration[:repo]).to be(repo)
39
+ end
40
+
41
+ it 'raises error if repo is not defined' do
42
+ configuration = ROM::Configuration.new({})
43
+
44
+ expect { configuration[:not_here] }.to raise_error(KeyError, /not_here/)
45
+ end
46
+ end
47
+
48
+ describe 'defining components when adapter was not registered' do
49
+ it 'raises error when trying to define a relation' do
50
+ expect {
51
+ Class.new(ROM::Relation[:not_here])
52
+ }.to raise_error(ROM::AdapterNotPresentError, /not_here/)
53
+ end
54
+
55
+ it 'raises error when trying to define a command' do
56
+ expect {
57
+ Class.new(ROM::Commands::Create[:not_here])
58
+ }.to raise_error(ROM::AdapterNotPresentError, /not_here/)
59
+ end
60
+ end
61
+ end
@@ -1,87 +1,93 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe ROM::Container do
4
+ include_context 'container'
4
5
  include_context 'users and tasks'
5
6
 
6
7
  before do
7
- setup.relation(:users) do
8
+ configuration
9
+
10
+ users = Class.new(ROM::Relation[:memory]) do
11
+ register_as :users
12
+ dataset :users
8
13
  def by_name(name)
9
14
  restrict(name: name).project(:name)
10
15
  end
11
16
  end
12
17
 
13
- setup.relation(:tasks)
18
+ tasks = Class.new(ROM::Relation[:memory]) do
19
+ register_as :tasks
20
+ dataset :tasks
21
+ end
14
22
 
15
- setup.commands(:users) do
16
- define(:create)
23
+ create_user = Class.new(ROM::Commands::Create[:memory]) do
24
+ relation :users
25
+ register_as :create
17
26
  end
18
27
 
19
- setup.commands(:tasks) do
20
- define(:create)
28
+ create_task = Class.new(ROM::Commands::Create[:memory]) do
29
+ relation :tasks
30
+ register_as :create
21
31
  end
22
32
 
23
- setup.mappers do
24
- define(:users) do
25
- attribute :name
26
- attribute :email
27
- end
33
+ users_mapper = Class.new(ROM::Mapper) do
34
+ register_as :users
35
+ relation :users
36
+ attribute :name
37
+ attribute :email
38
+ end
28
39
 
29
- define(:name_list, parent: :users) do
30
- attribute :name
31
- exclude :email
32
- end
40
+ name_list = Class.new(users_mapper) do
41
+ register_as :name_list
42
+ attribute :name
43
+ exclude :email
33
44
  end
45
+
46
+ configuration.register_relation(users, tasks)
47
+ configuration.register_command(create_user, create_task)
48
+ configuration.register_mapper(users_mapper, name_list)
34
49
  end
35
50
 
36
51
  describe '#command' do
37
52
  it 'returns registered command registry' do
38
- expect(rom.command(:users)).to be_instance_of(ROM::CommandRegistry)
53
+ expect(container.command(:users)).to be_instance_of(ROM::CommandRegistry)
39
54
  end
40
55
 
41
56
  it 'returns registered command' do
42
- expect(rom.command(:users).create).to be_kind_of(ROM::Commands::Create)
57
+ expect(container.command(:users).create).to be_kind_of(ROM::Commands::Create)
43
58
  end
44
59
 
45
60
  it 'accepts an array with graph options and input' do
46
- expect(rom.command([:users, [:create]])).to be_kind_of(ROM::Commands::Lazy)
61
+ expect(container.command([:users, [:create]])).to be_kind_of(ROM::Commands::Lazy)
47
62
  end
48
63
 
49
64
  it 'raises ArgumentError when unsupported arg was passed' do
50
- expect { rom.command({ oops: 'sorry' }) }.to raise_error(ArgumentError)
65
+ expect { container.command(oops: 'sorry') }.to raise_error(ArgumentError)
51
66
  end
52
67
  end
53
68
 
54
69
  describe '#relation' do
55
70
  it 'yields selected relation to the block and returns a loaded relation' do
56
- result = rom.relation(:users) { |r| r.by_name('Jane') }.as(:name_list)
71
+ result = container.relation(:users) { |r| r.by_name('Jane') }.as(:name_list)
57
72
 
58
73
  expect(result.call).to match_array([{ name: 'Jane' }])
59
74
  end
60
75
 
61
76
  it 'returns lazy-mapped relation' do
62
- by_name = rom.relation(:users).as(:name_list).by_name
77
+ by_name = container.relation(:users).as(:name_list).by_name
63
78
 
64
79
  expect(by_name['Jane']).to match_array([{ name: 'Jane' }])
65
80
  end
66
81
 
67
82
  it 'returns relation without mappers when mappers are not defined' do
68
- expect(rom.relation(:tasks)).to be_kind_of(ROM::Relation)
69
- expect(rom.relation(:tasks).mappers.elements).to be_empty
70
- end
71
- end
72
-
73
- describe '#read' do
74
- it 'returns loaded relation and display a deprecation warning' do
75
- expect {
76
- result = rom.read(:users) { |r| r.by_name('Jane') }.as(:name_list)
77
- expect(result.call).to match_array([{ name: 'Jane' }])
78
- }.to output(/^ROM::Container#read is deprecated/).to_stderr
83
+ expect(container.relation(:tasks)).to be_kind_of(ROM::Relation)
84
+ expect(container.relation(:tasks).mappers.elements).to be_empty
79
85
  end
80
86
  end
81
87
 
82
88
  describe '#mappers' do
83
89
  it 'returns mappers for all relations' do
84
- expect(rom.mappers.users[:name_list]).to_not be(nil)
90
+ expect(container.mappers.users[:name_list]).to_not be(nil)
85
91
  end
86
92
  end
87
93
  end
@@ -0,0 +1,151 @@
1
+ require 'spec_helper'
2
+
3
+ describe ROM::CreateContainer do
4
+ describe '#finalize' do
5
+ include_context 'container'
6
+
7
+ context 'with gateway that supports schema inferring' do
8
+ it 'builds relation from inferred schema' do
9
+ repo = configuration.gateways[:default]
10
+ dataset = double('dataset')
11
+
12
+ allow(repo).to receive(:schema).and_return([:users])
13
+ allow(repo).to receive(:dataset).with(:users).and_return(dataset)
14
+
15
+ expect(container.relations.users.dataset).to be(dataset)
16
+ end
17
+
18
+ it 'skips inferring a relation when there is a defined one already' do
19
+ repo = configuration.gateways[:default]
20
+ dataset_double = double('dataset')
21
+
22
+ allow(repo).to receive(:schema).and_return([:users])
23
+ allow(repo).to receive(:dataset).with(:users).and_return(dataset_double)
24
+
25
+ users = Class.new(ROM::Relation[:memory]) do
26
+ register_as :users
27
+ dataset :users
28
+ end
29
+
30
+ configuration.register_relation(users)
31
+
32
+ expect { container }.not_to raise_error
33
+
34
+ expect(container.relations.users).to be_instance_of(users)
35
+ end
36
+
37
+ it 'skips inferring when it is turned off for the adapter' do
38
+ configuration.config.gateways.default.infer_relations = false
39
+
40
+ repo = configuration.default
41
+
42
+ expect(repo).not_to receive(:schema)
43
+
44
+ container
45
+ end
46
+
47
+ it 'infers configured relations' do
48
+ configuration.config.gateways.default.inferrable_relations = [:test_tasks]
49
+
50
+ repo = configuration.default
51
+ dataset = double('dataset')
52
+
53
+ allow(repo).to receive(:schema).and_return([:test_tasks, :test_users])
54
+
55
+ expect(repo).to receive(:dataset).with(:test_tasks).and_return(dataset)
56
+ expect(repo).to_not receive(:dataset).with(:test_users)
57
+
58
+ expect(container.relations.elements.key?(:test_users)).to be(false)
59
+ expect(container.relations[:test_tasks]).to be_kind_of(ROM::Memory::Relation)
60
+ expect(container.relations[:test_tasks].dataset).to be(dataset)
61
+ end
62
+
63
+ it 'skip inferring blacklisted relations' do
64
+ configuration.config.gateways.default.not_inferrable_relations = [:test_users]
65
+
66
+ repo = configuration.default
67
+ dataset = double('dataset')
68
+
69
+ allow(repo).to receive(:schema).and_return([:test_tasks, :test_users])
70
+
71
+ expect(repo).to receive(:dataset).with(:test_tasks).and_return(dataset)
72
+ expect(repo).to_not receive(:dataset).with(:test_users)
73
+
74
+ expect(container.relations.elements.key?(:test_users)).to be(false)
75
+ expect(container.relations[:test_tasks]).to be_kind_of(ROM::Memory::Relation)
76
+ expect(container.relations[:test_tasks].dataset).to be(dataset)
77
+ end
78
+
79
+ it 'can register multiple relations with same dataset' do
80
+ configuration
81
+
82
+ apples = Class.new(ROM::Relation[:memory]) do
83
+ dataset :fruits
84
+ register_as :apples
85
+
86
+ def apple?
87
+ true
88
+ end
89
+ end
90
+
91
+ oranges = Class.new(ROM::Relation[:memory]) do
92
+ dataset :fruits
93
+ register_as :oranges
94
+
95
+ def orange?
96
+ true
97
+ end
98
+ end
99
+
100
+ configuration.register_relation(apples)
101
+ configuration.register_relation(oranges)
102
+
103
+ expect(container.relations.apples).to be_apple
104
+ expect(container.relations.oranges).to be_orange
105
+ expect(container.relations.apples).to_not eq(container.relations.oranges)
106
+ end
107
+
108
+ it "raises an error when registering relations with the same `register_as`" do
109
+ configuration
110
+
111
+ users = Class.new(ROM::Relation[:memory]) do
112
+ dataset :guests
113
+ register_as :users
114
+ end
115
+
116
+ users2 = Class.new(ROM::Relation[:memory]) do
117
+ dataset :admins
118
+ register_as :users
119
+ end
120
+
121
+ configuration.register_relation(users)
122
+ configuration.register_relation(users2)
123
+
124
+ expect { container }.to raise_error(
125
+ ROM::RelationAlreadyDefinedError, /register_as :users/
126
+ )
127
+ end
128
+ end
129
+
130
+ context 'empty setup' do
131
+ let(:configuration) { ROM::Configuration.new({}) }
132
+ let(:container) { ROM.container(configuration) }
133
+
134
+ it 'builds empty gateways' do
135
+ expect(container.gateways).to eql({})
136
+ end
137
+
138
+ it 'builds empty relations' do
139
+ expect(container.relations).to eql(ROM::RelationRegistry.new)
140
+ end
141
+
142
+ it 'builds empty mappers' do
143
+ expect(container.mappers).to eql(ROM::Registry.new)
144
+ end
145
+
146
+ it 'builds empty commands' do
147
+ expect(container.commands).to eql(ROM::Registry.new)
148
+ end
149
+ end
150
+ end
151
+ end