rom 2.0.2 → 3.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +4 -4
- data/CHANGELOG.md +34 -1
- data/Gemfile +16 -2
- data/Rakefile +7 -2
- data/lib/rom/array_dataset.rb +44 -0
- data/lib/rom/association_set.rb +11 -5
- data/lib/rom/auto_curry.rb +55 -0
- data/lib/rom/command.rb +70 -41
- data/lib/rom/command_registry.rb +7 -18
- data/lib/rom/commands/class_interface.rb +7 -6
- data/lib/rom/commands/composite.rb +0 -1
- data/lib/rom/commands/graph.rb +7 -15
- data/lib/rom/commands/lazy/update.rb +1 -1
- data/lib/rom/configuration_dsl/command.rb +6 -8
- data/lib/rom/configuration_dsl/mapper.rb +2 -3
- data/lib/rom/configuration_dsl/mapper_dsl.rb +0 -1
- data/lib/rom/configuration_dsl/relation.rb +4 -4
- data/lib/rom/configuration_dsl.rb +0 -4
- data/lib/rom/constants.rb +1 -1
- data/lib/rom/container.rb +0 -2
- data/lib/rom/create_container.rb +0 -2
- data/lib/rom/data_proxy.rb +94 -0
- data/lib/rom/enumerable_dataset.rb +68 -0
- data/lib/rom/gateway.rb +23 -6
- data/lib/rom/global/plugin_dsl.rb +0 -2
- data/lib/rom/global.rb +0 -2
- data/lib/rom/initializer.rb +26 -0
- data/lib/rom/lint/gateway.rb +17 -0
- data/lib/rom/mapper_registry.rb +1 -1
- data/lib/rom/memory/commands.rb +0 -2
- data/lib/rom/memory/dataset.rb +1 -2
- data/lib/rom/memory/relation.rb +14 -1
- data/lib/rom/memory/schema.rb +13 -0
- data/lib/rom/plugin_registry.rb +1 -1
- data/lib/rom/plugins/configuration/configuration_dsl.rb +6 -2
- data/lib/rom/plugins/relation/key_inference.rb +4 -2
- data/lib/rom/plugins/relation/registry_reader.rb +5 -1
- data/lib/rom/registry.rb +50 -0
- data/lib/rom/relation/class_interface.rb +94 -26
- data/lib/rom/relation/curried.rb +15 -15
- data/lib/rom/relation/view_dsl.rb +31 -0
- data/lib/rom/relation.rb +49 -34
- data/lib/rom/schema/dsl.rb +7 -9
- data/lib/rom/schema/type.rb +115 -0
- data/lib/rom/schema.rb +218 -18
- data/lib/rom/setup/auto_registration.rb +20 -17
- data/lib/rom/setup/auto_registration_strategies/base.rb +8 -3
- data/lib/rom/setup/auto_registration_strategies/custom_namespace.rb +4 -3
- data/lib/rom/setup/auto_registration_strategies/no_namespace.rb +5 -4
- data/lib/rom/setup/auto_registration_strategies/with_namespace.rb +3 -3
- data/lib/rom/setup/finalize/finalize_commands.rb +1 -1
- data/lib/rom/setup/finalize/finalize_mappers.rb +1 -1
- data/lib/rom/setup/finalize/finalize_relations.rb +3 -1
- data/lib/rom/setup/finalize.rb +1 -1
- data/lib/rom/transaction.rb +24 -0
- data/lib/rom/types.rb +9 -1
- data/lib/rom/version.rb +1 -1
- data/lib/rom.rb +4 -8
- data/rom.gemspec +4 -3
- data/spec/integration/command_registry_spec.rb +1 -14
- data/spec/integration/commands/create_spec.rb +5 -25
- data/spec/integration/commands/delete_spec.rb +1 -1
- data/spec/integration/commands/error_handling_spec.rb +1 -1
- data/spec/integration/commands/graph_spec.rb +20 -14
- data/spec/integration/commands/update_spec.rb +4 -27
- data/spec/integration/commands_spec.rb +1 -1
- data/spec/integration/{repositories → gateways}/extending_relations_spec.rb +1 -1
- data/spec/integration/{repositories → gateways}/setting_logger_spec.rb +2 -2
- data/spec/integration/mappers/combine_spec.rb +1 -1
- data/spec/integration/mappers/deep_embedded_spec.rb +1 -1
- data/spec/integration/mappers/definition_dsl_spec.rb +1 -1
- data/spec/integration/mappers/embedded_spec.rb +1 -1
- data/spec/integration/mappers/exclude_spec.rb +1 -1
- data/spec/integration/mappers/fold_spec.rb +1 -1
- data/spec/integration/mappers/group_spec.rb +1 -1
- data/spec/integration/mappers/overwrite_attributes_value_spec.rb +1 -1
- data/spec/integration/mappers/prefix_separator_spec.rb +1 -1
- data/spec/integration/mappers/prefix_spec.rb +1 -1
- data/spec/integration/mappers/prefixing_attributes_spec.rb +1 -1
- data/spec/integration/mappers/registering_custom_mappers_spec.rb +1 -1
- data/spec/integration/mappers/renaming_attributes_spec.rb +1 -1
- data/spec/integration/mappers/reusing_mappers_spec.rb +1 -1
- data/spec/integration/mappers/step_spec.rb +1 -1
- data/spec/integration/mappers/symbolizing_attributes_spec.rb +1 -1
- data/spec/integration/mappers/unfold_spec.rb +1 -1
- data/spec/integration/mappers/ungroup_spec.rb +1 -1
- data/spec/integration/mappers/unwrap_spec.rb +2 -2
- data/spec/integration/mappers/wrap_spec.rb +1 -1
- data/spec/integration/memory/commands/create_spec.rb +1 -1
- data/spec/integration/memory/commands/delete_spec.rb +1 -1
- data/spec/integration/memory/commands/update_spec.rb +1 -1
- data/spec/integration/multi_env_spec.rb +1 -1
- data/spec/integration/multi_repo_spec.rb +1 -1
- data/spec/integration/relations/default_dataset_spec.rb +1 -1
- data/spec/integration/relations/reading_spec.rb +1 -1
- data/spec/integration/relations/registry_dsl_spec.rb +1 -1
- data/spec/integration/setup_spec.rb +10 -4
- data/spec/shared/command_graph.rb +8 -4
- data/spec/shared/enumerable_dataset.rb +1 -1
- data/spec/spec_helper.rb +7 -9
- data/spec/support/schema.rb +14 -0
- data/spec/unit/rom/array_dataset_spec.rb +59 -0
- data/spec/unit/rom/association_set_spec.rb +4 -0
- data/spec/unit/rom/auto_curry_spec.rb +63 -0
- data/spec/unit/rom/commands/graph_spec.rb +12 -11
- data/spec/unit/rom/commands/lazy_spec.rb +8 -5
- data/spec/unit/rom/commands/pre_and_post_processors_spec.rb +269 -0
- data/spec/unit/rom/commands/result_spec.rb +1 -1
- data/spec/unit/rom/commands_spec.rb +9 -3
- data/spec/unit/rom/configuration_spec.rb +1 -1
- data/spec/unit/rom/container_spec.rb +11 -5
- data/spec/unit/rom/create_container_spec.rb +1 -1
- data/spec/unit/rom/enumerable_dataset_spec.rb +15 -0
- data/spec/unit/rom/gateway_spec.rb +1 -1
- data/spec/unit/rom/mapper_registry_spec.rb +1 -1
- data/spec/unit/rom/memory/commands_spec.rb +1 -1
- data/spec/unit/rom/memory/dataset_spec.rb +1 -1
- data/spec/unit/rom/memory/{repository_spec.rb → gateway_spec.rb} +1 -1
- data/spec/unit/rom/memory/inheritance_spec.rb +32 -0
- data/spec/unit/rom/memory/relation_spec.rb +15 -3
- data/spec/unit/rom/memory/storage_spec.rb +1 -1
- data/spec/unit/rom/plugin_spec.rb +1 -1
- data/spec/unit/rom/plugins/relation/key_inference_spec.rb +1 -1
- data/spec/unit/rom/registry_spec.rb +86 -0
- data/spec/unit/rom/relation/attribute_reader_spec.rb +17 -0
- data/spec/unit/rom/relation/composite_spec.rb +1 -1
- data/spec/unit/rom/relation/graph_spec.rb +1 -1
- data/spec/unit/rom/relation/lazy/combine_spec.rb +1 -1
- data/spec/unit/rom/relation/lazy_spec.rb +1 -1
- data/spec/unit/rom/relation/loaded_spec.rb +1 -1
- data/spec/unit/rom/relation/schema_spec.rb +10 -6
- data/spec/unit/rom/relation/view_spec.rb +112 -0
- data/spec/unit/rom/relation_spec.rb +16 -2
- data/spec/unit/rom/schema/accessing_attributes_spec.rb +52 -0
- data/spec/unit/rom/schema/exclude_spec.rb +15 -0
- data/spec/unit/rom/schema/finalize_spec.rb +59 -0
- data/spec/unit/rom/schema/key_predicate_spec.rb +15 -0
- data/spec/unit/rom/schema/merge_spec.rb +17 -0
- data/spec/unit/rom/schema/prefix_spec.rb +16 -0
- data/spec/unit/rom/schema/project_spec.rb +15 -0
- data/spec/unit/rom/schema/rename_spec.rb +22 -0
- data/spec/unit/rom/schema/type_spec.rb +49 -0
- data/spec/unit/rom/schema/wrap_spec.rb +17 -0
- data/spec/unit/rom/schema_spec.rb +2 -2
- metadata +69 -17
- data/lib/rom/plugins/relation/view/dsl.rb +0 -32
- data/lib/rom/plugins/relation/view.rb +0 -95
- data/spec/unit/rom/plugins/relation/view_spec.rb +0 -51
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'rom/registry'
|
2
|
+
|
3
|
+
RSpec.shared_examples_for 'registry fetch' do
|
4
|
+
it 'raises an ArgumentError when nil is used as a key' do
|
5
|
+
expect {
|
6
|
+
registry.public_send(fetch_method, nil)
|
7
|
+
}.to raise_error(ArgumentError, "key cannot be nil")
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'returns registered element identified by name' do
|
11
|
+
expect(registry.public_send(fetch_method, :mars)).to be(mars)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'raises error when element is not found' do
|
15
|
+
expect { registry.public_send(fetch_method, :twix) }.to raise_error(
|
16
|
+
ROM::Registry::ElementNotFoundError,
|
17
|
+
":twix doesn't exist in Candy registry"
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'returns the value from an optional block when key is not found' do
|
22
|
+
value = registry.public_send(fetch_method, :candy) { :twix }
|
23
|
+
|
24
|
+
expect(value).to eq(:twix)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'calls #to_sym on a key before fetching' do
|
28
|
+
expect(registry.public_send(fetch_method, double(to_sym: :mars))).to be(mars)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
RSpec.describe ROM::Registry do
|
33
|
+
subject(:registry) { registry_class.new(mars: mars) }
|
34
|
+
|
35
|
+
let(:mars) { double('mars') }
|
36
|
+
|
37
|
+
let(:registry_class) do
|
38
|
+
Class.new(ROM::Registry) do
|
39
|
+
def self.name
|
40
|
+
'Candy'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe '#fetch' do
|
46
|
+
let(:fetch_method) { :fetch }
|
47
|
+
|
48
|
+
it_behaves_like 'registry fetch'
|
49
|
+
end
|
50
|
+
|
51
|
+
describe '#[]' do
|
52
|
+
let(:fetch_method) { :[] }
|
53
|
+
|
54
|
+
it_behaves_like 'registry fetch'
|
55
|
+
end
|
56
|
+
|
57
|
+
describe '#method_missing' do
|
58
|
+
it 'returns registered element identified by name' do
|
59
|
+
expect(registry.mars).to be(mars)
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'raises no-method error when element is not there' do
|
63
|
+
expect { registry.twix }.to raise_error(NoMethodError)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe '#key?' do
|
68
|
+
let(:mars) { double(to_sym: :mars) }
|
69
|
+
|
70
|
+
it 'calls #to_sym on a key before checking if it exists' do
|
71
|
+
registry.key?(:mars)
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'returns true for an existing key' do
|
75
|
+
expect(registry.key?(:mars)).to be(true)
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'returns false for a non-existing key' do
|
79
|
+
expect(registry.key?(:twix)).to be(false)
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'returns false for a nil key' do
|
83
|
+
expect(registry.key?(nil)).to be(false)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rom/memory'
|
2
|
+
|
3
|
+
RSpec.describe ROM::Relation, '#[]' do
|
4
|
+
it 'defines a canonical schema for a relation' do
|
5
|
+
class Test::Users < ROM::Relation[:memory]
|
6
|
+
schema do
|
7
|
+
attribute :id, Types::Int
|
8
|
+
attribute :name, Types::String
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
relation = Test::Users.new([])
|
13
|
+
|
14
|
+
expect(relation[:id]).to be(Test::Users.schema[:id])
|
15
|
+
expect(relation[:name]).to be(Test::Users.schema[:name])
|
16
|
+
end
|
17
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'rom/memory'
|
3
3
|
|
4
|
-
describe ROM::Relation, '.schema' do
|
4
|
+
RSpec.describe ROM::Relation, '.schema' do
|
5
5
|
it 'defines a canonical schema for a relation' do
|
6
6
|
class Test::Users < ROM::Relation[:memory]
|
7
7
|
schema do
|
@@ -13,11 +13,15 @@ describe ROM::Relation, '.schema' do
|
|
13
13
|
|
14
14
|
Test::Users.schema.finalize!
|
15
15
|
|
16
|
-
|
16
|
+
relation_name = ROM::Relation::Name[:test_users]
|
17
|
+
|
18
|
+
schema = ROM::Memory::Schema.define(
|
17
19
|
ROM::Relation::Name.new(:test_users),
|
18
|
-
|
19
|
-
|
20
|
-
|
20
|
+
attributes: [
|
21
|
+
ROM::Memory::Types::Int.meta(primary_key: true, name: :id, source: relation_name),
|
22
|
+
ROM::Memory::Types::String.meta(name: :name, source: relation_name),
|
23
|
+
ROM::Memory::Types::Bool.meta(name: :admin, source: relation_name)
|
24
|
+
]
|
21
25
|
).finalize!
|
22
26
|
|
23
27
|
expect(Test::Users.schema.primary_key).to eql([Test::Users.schema[:id]])
|
@@ -111,7 +115,7 @@ describe ROM::Relation, '.schema' do
|
|
111
115
|
end
|
112
116
|
end
|
113
117
|
|
114
|
-
expect(Test::Users.schema[:admin]).to eql(ROM::Types::Bool.meta(name: :admin))
|
118
|
+
expect(Test::Users.schema[:admin]).to eql(ROM::Types::Bool.meta(name: :admin, source: ROM::Relation::Name[:test_users]))
|
115
119
|
end
|
116
120
|
end
|
117
121
|
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'rom'
|
2
|
+
require 'rom/memory'
|
3
|
+
|
4
|
+
RSpec.describe ROM::Relation do
|
5
|
+
subject(:relation) { relation_class.new(ROM::Memory::Dataset.new([])) }
|
6
|
+
|
7
|
+
shared_context 'relation with views' do
|
8
|
+
before do
|
9
|
+
relation << { id: 1, name: 'Joe' }
|
10
|
+
relation << { id: 2, name: 'Jane' }
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'uses projected schema for view schema' do
|
14
|
+
expect(relation.schemas[:names].map(&:name)).to eql(%i[name])
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'auto-projects the relation via schema' do
|
18
|
+
new_rel = relation_class.new([{ name: 'Jane' }, { name: 'Joe' }])
|
19
|
+
names_schema = relation_class.schemas[:names]
|
20
|
+
|
21
|
+
expect(names_schema).to receive(:call).with(relation).and_return(new_rel)
|
22
|
+
expect(relation.names).to eql(new_rel)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'auto-projects a restricted relation via schema' do
|
26
|
+
new_rel = relation_class.new([{ id: 2 }])
|
27
|
+
ids_schema = relation_class.schemas[:ids_for_names]
|
28
|
+
|
29
|
+
expect(ids_schema).to receive(:call).with(relation.restrict(name: ['Jane'])).and_return(new_rel)
|
30
|
+
expect(relation.ids_for_names(['Jane'])).to eql(new_rel)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'with an explicit schema' do
|
35
|
+
before do
|
36
|
+
# this is normally called automatically during setup
|
37
|
+
relation_class.finalize({}, relation)
|
38
|
+
end
|
39
|
+
|
40
|
+
include_context 'relation with views' do
|
41
|
+
let(:relation_class) do
|
42
|
+
Class.new(ROM::Memory::Relation) do
|
43
|
+
schema(:users) do
|
44
|
+
attribute :id, ROM::Types::Int
|
45
|
+
attribute :name, ROM::Types::String
|
46
|
+
end
|
47
|
+
|
48
|
+
view(:names) do
|
49
|
+
schema do
|
50
|
+
project(:name)
|
51
|
+
end
|
52
|
+
|
53
|
+
relation do
|
54
|
+
self
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
view(:ids_for_names) do
|
59
|
+
schema do
|
60
|
+
project(:id)
|
61
|
+
end
|
62
|
+
|
63
|
+
relation do |names|
|
64
|
+
restrict(name: names)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'with an inferred schema' do
|
73
|
+
before do
|
74
|
+
# this is normally called automatically during setup
|
75
|
+
relation_class.schema.finalize!
|
76
|
+
relation_class.finalize({}, relation)
|
77
|
+
end
|
78
|
+
|
79
|
+
include_context 'relation with views' do
|
80
|
+
let(:relation_class) do
|
81
|
+
Class.new(ROM::Memory::Relation) do
|
82
|
+
schema_inferrer -> dataset, gateway {
|
83
|
+
[[ROM::Types::Int.meta(name: :id, source: :users),
|
84
|
+
ROM::Types::String.meta(name: :name, source: :users)], []]
|
85
|
+
}
|
86
|
+
|
87
|
+
schema(:users, infer: true)
|
88
|
+
|
89
|
+
view(:names) do
|
90
|
+
schema do
|
91
|
+
project(:name)
|
92
|
+
end
|
93
|
+
|
94
|
+
relation do
|
95
|
+
self
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
view(:ids_for_names) do
|
100
|
+
schema do
|
101
|
+
project(:id)
|
102
|
+
end
|
103
|
+
|
104
|
+
relation do |names|
|
105
|
+
restrict(name: names)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'rom/memory'
|
2
2
|
|
3
|
-
describe ROM::Relation do
|
3
|
+
RSpec.describe ROM::Relation do
|
4
4
|
subject(:relation) { Class.new(ROM::Relation).new(dataset) }
|
5
5
|
|
6
6
|
let(:dataset) { ROM::Memory::Dataset.new([jane, joe]) }
|
@@ -196,7 +196,7 @@ describe ROM::Relation do
|
|
196
196
|
|
197
197
|
describe "#with" do
|
198
198
|
it "returns a new instance with the original dataset and given custom options" do
|
199
|
-
relation = Class.new(ROM::Relation) { option :custom }.new([])
|
199
|
+
relation = Class.new(ROM::Relation) { option :custom }.new([], custom: true)
|
200
200
|
|
201
201
|
custom_opts = { mappers: "Custom Mapper Registry" }
|
202
202
|
new_relation = relation.with(custom_opts).with(custom: true)
|
@@ -217,6 +217,20 @@ describe ROM::Relation do
|
|
217
217
|
end
|
218
218
|
end
|
219
219
|
|
220
|
+
describe '#schema' do
|
221
|
+
it 'returns an empty schema by default' do
|
222
|
+
relation = Class.new(ROM::Relation[:memory]) {
|
223
|
+
def self.name
|
224
|
+
'SomeRelation'
|
225
|
+
end
|
226
|
+
}.new([])
|
227
|
+
|
228
|
+
expect(relation.schema).to be_empty
|
229
|
+
expect(relation.schema.name).to be(:some_relation)
|
230
|
+
expect(relation.schema?).to be(false)
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
220
234
|
describe '#schema_hash' do
|
221
235
|
it 'returns a schema hash type' do
|
222
236
|
relation = Class.new(ROM::Relation[:memory]) do
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'rom/schema'
|
2
|
+
|
3
|
+
RSpec.describe ROM::Schema, '#[]' do
|
4
|
+
context 'with a schema' do
|
5
|
+
subject(:schema) do
|
6
|
+
define_schema(:users, id: :Int, name: :String, email: :String)
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'returns an attribute identified by its canonical name' do
|
10
|
+
expect(schema[:email]).to eql(define_type(:email, :String, source: :users))
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'returns an aliased attribute identified by its canonical name' do
|
14
|
+
expect(schema.rename(id: :user_id)[:id]).to eql(define_type(:id, :Int, source: :users, alias: :user_id))
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'raises KeyError when attribute is not found' do
|
18
|
+
expect { schema[:not_here] }.to raise_error(KeyError, /not_here/)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'with a merged schema' do
|
23
|
+
subject(:schema) do
|
24
|
+
left.merge(right.__send__(:new, right.map { |attr| attr.meta(source: :tasks) }))
|
25
|
+
end
|
26
|
+
|
27
|
+
let(:left) do
|
28
|
+
define_schema(:users, id: :Int, name: :String)
|
29
|
+
end
|
30
|
+
|
31
|
+
let(:right) do
|
32
|
+
define_schema(:tasks, id: :Int, title: :String)
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'returns an attribute identified by its canonical name' do
|
36
|
+
expect(schema[:id]).to eql(define_type(:id, :Int, source: :users))
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'returns an attribute identified by its canonical name when its unique' do
|
40
|
+
expect(schema[:title]).to eql(define_type(:title, :String, source: :tasks))
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'returns an attribute identified by its canonical name and its source' do
|
44
|
+
expect(schema[:id, :tasks]).to eql(define_type(:id, :Int, source: :tasks))
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'raises KeyError when attribute is not found' do
|
48
|
+
expect { schema[:not_here] }.to raise_error(KeyError, /not_here/)
|
49
|
+
expect { schema[:not_here, :tasks] }.to raise_error(KeyError, /not_here/)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rom/schema'
|
2
|
+
|
3
|
+
RSpec.describe ROM::Schema, '#exclude' do
|
4
|
+
subject(:schema) do
|
5
|
+
define_schema(:users, id: :Int, name: :String, email: :String)
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:excluded) do
|
9
|
+
schema.exclude(:id, :name)
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'returns projected schema with renamed attributes using provided prefix' do
|
13
|
+
expect(excluded.map(&:name)).to eql(%i[email])
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'rom/schema'
|
2
|
+
|
3
|
+
RSpec.describe ROM::Schema, '#finalize!' do
|
4
|
+
context 'without inferrer' do
|
5
|
+
subject(:schema) do
|
6
|
+
define_schema(:users, id: :Int, name: :String)
|
7
|
+
end
|
8
|
+
|
9
|
+
before { schema.finalize! }
|
10
|
+
|
11
|
+
it 'returns a frozen canonical schema' do
|
12
|
+
expect(schema).to be_frozen
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'with inferrer' do
|
17
|
+
subject(:schema) do
|
18
|
+
ROM::Schema.define(:users, attributes: attributes, inferrer: inferrer)
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:inferrer) do
|
22
|
+
proc { [[define_type(:name, :String)], [:id, :age]]}
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'when all required attributes are present' do
|
26
|
+
let(:attributes) do
|
27
|
+
[define_type(:id, :Int), define_type(:age, :Int)]
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'concats defined attributes with inferred attributes' do
|
31
|
+
expect(schema.finalize!.map(&:name)).to eql(%i[id age name])
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'when inferred attributes are overridden' do
|
36
|
+
let(:attributes) do
|
37
|
+
[define_type(:id, :Int),
|
38
|
+
define_type(:age, :Int),
|
39
|
+
define_type(:name, :String).meta(custom: true)]
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'respects overridden attributes' do
|
43
|
+
expect(schema.finalize!.map(&:name)).to eql(%i[id age name])
|
44
|
+
expect(schema[:name].meta[:custom]).to be(true)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'when some attributes are missing' do
|
49
|
+
let(:attributes) do
|
50
|
+
[]
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'raises error' do
|
54
|
+
expect { schema.finalize! }.
|
55
|
+
to raise_error(ROM::Schema::MissingAttributesError, /missing attributes in :users schema: :id, :age/)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rom/schema'
|
2
|
+
|
3
|
+
RSpec.describe ROM::Schema, '#key?' do
|
4
|
+
subject(:schema) do
|
5
|
+
define_schema(:users, name: :String)
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'returns true when an attribute exists' do
|
9
|
+
expect(schema.key?(:name)).to be(true)
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'returns false when an attribute does not exist' do
|
13
|
+
expect(schema.key?(:foo)).to be(false)
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rom/schema'
|
2
|
+
|
3
|
+
RSpec.describe ROM::Schema, '#merge' do
|
4
|
+
subject(:schema) { left.merge(right) }
|
5
|
+
|
6
|
+
let(:left) do
|
7
|
+
define_schema(:users, id: :Int, name: :String)
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:right) do
|
11
|
+
define_schema(:tasks, user_id: :Int)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'returns a new schema with attributes from two schemas' do
|
15
|
+
expect(schema.map(&:name)).to eql(%i[id name user_id])
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rom/schema'
|
2
|
+
|
3
|
+
RSpec.describe ROM::Schema, '#prefix' do
|
4
|
+
subject(:schema) do
|
5
|
+
define_schema(:users, id: :Int, name: :String)
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:prefixed) do
|
9
|
+
schema.prefix(:user)
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'returns projected schema with renamed attributes using provided prefix' do
|
13
|
+
expect(prefixed.map(&:alias)).to eql(%i[user_id user_name])
|
14
|
+
expect(prefixed.map { |attr| attr.meta[:name] }).to eql(%i[id name])
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rom/schema'
|
2
|
+
|
3
|
+
RSpec.describe ROM::Schema, '#project' do
|
4
|
+
subject(:schema) do
|
5
|
+
define_schema(:users, id: :Int, name: :String, age: :Int)
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'projects provided attribute names' do
|
9
|
+
expect(schema.project(:name, :age).map(&:name)).to eql(%i[name age])
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'projects provided attributes' do
|
13
|
+
expect(schema.project(schema[:name], schema[:age]).map(&:name)).to eql(%i[name age])
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rom/schema'
|
2
|
+
|
3
|
+
RSpec.describe ROM::Schema, '#rename' do
|
4
|
+
subject(:schema) do
|
5
|
+
define_schema(
|
6
|
+
:users,
|
7
|
+
user_id: :Int, user_name: :String, user_email: :String
|
8
|
+
)
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:renamed) do
|
12
|
+
schema.rename(user_id: :id, user_name: :name)
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'returns projected schema with renamed attributes' do
|
16
|
+
expect(renamed.map(&:name)).to eql(%i[user_id user_name user_email])
|
17
|
+
expect(renamed.map(&:alias)).to eql([:id, :name, nil])
|
18
|
+
expect(renamed.all?(&:aliased?)).to be(false)
|
19
|
+
expect(renamed[:user_id]).to be_aliased
|
20
|
+
expect(renamed[:user_name]).to be_aliased
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'rom/schema/type'
|
2
|
+
|
3
|
+
RSpec.describe ROM::Schema::Type do
|
4
|
+
describe '#inspect' do
|
5
|
+
context 'with a primitive definition' do
|
6
|
+
subject(:type) do
|
7
|
+
ROM::Schema::Type.new(ROM::Types::Int).meta(name: :id, primary_key: true)
|
8
|
+
end
|
9
|
+
|
10
|
+
specify do
|
11
|
+
expect(type.inspect).to eql("#<ROM::Schema::Type[Integer] name=:id primary_key=true>")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'with a sum' do
|
16
|
+
subject(:type) do
|
17
|
+
ROM::Schema::Type.new(ROM::Types::Bool).meta(name: :admin)
|
18
|
+
end
|
19
|
+
|
20
|
+
specify do
|
21
|
+
expect(type.inspect).to eql("#<ROM::Schema::Type[TrueClass | FalseClass] name=:admin>")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#aliased' do
|
27
|
+
subject(:type) do
|
28
|
+
ROM::Schema::Type.new(ROM::Types::String).meta(name: :user_name)
|
29
|
+
end
|
30
|
+
|
31
|
+
specify do
|
32
|
+
expect(type.as(:name).meta[:alias]).to eql(:name)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#method_missing' do
|
37
|
+
subject(:type) do
|
38
|
+
ROM::Schema::Type.new(ROM::Types::Int).meta(name: :id, primary_key: true)
|
39
|
+
end
|
40
|
+
|
41
|
+
specify do
|
42
|
+
expect(type.meta).to eql(name: :id, primary_key: true)
|
43
|
+
end
|
44
|
+
|
45
|
+
specify do
|
46
|
+
expect { type.not_here }.to raise_error(NoMethodError, /not_here/)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rom/schema'
|
2
|
+
|
3
|
+
RSpec.describe ROM::Schema, '#wrap' do
|
4
|
+
subject(:schema) do
|
5
|
+
define_schema(:users, id: :Int, name: :String)
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:wrapped) do
|
9
|
+
schema.wrap(:users)
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'returns projected schema with renamed attributes using provided prefix' do
|
13
|
+
expect(wrapped.map(&:alias)).to eql(%i[users_id users_name])
|
14
|
+
expect(wrapped.map { |attr| attr.meta[:name] }).to eql(%i[id name])
|
15
|
+
expect(wrapped.all?(&:wrapped?)).to be(true)
|
16
|
+
end
|
17
|
+
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
RSpec.describe ROM::Schema do
|
2
2
|
describe '#to_h' do
|
3
3
|
it 'returns hash with attributes' do
|
4
|
-
attrs = { id: ROM::Types::Int, name: ROM::Types::String }
|
5
|
-
schema = ROM::Schema.
|
4
|
+
attrs = { id: ROM::Types::Int.meta(name: :id), name: ROM::Types::String.meta(name: :name) }
|
5
|
+
schema = ROM::Schema.define(:name, attributes: attrs.values)
|
6
6
|
|
7
7
|
expect(schema.to_h).to eql(attrs)
|
8
8
|
end
|