rom 0.1.2 → 0.2.0
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.
- data/.rspec +2 -0
- data/.travis.yml +22 -0
- data/Changelog.md +16 -0
- data/Gemfile +13 -6
- data/Gemfile.devtools +71 -0
- data/Guardfile +19 -0
- data/LICENSE +1 -1
- data/README.md +52 -30
- data/Rakefile +3 -0
- data/config/devtools.yml +4 -0
- data/config/flay.yml +3 -0
- data/config/flog.yml +2 -0
- data/config/mutant.yml +5 -0
- data/config/reek.yml +103 -0
- data/config/rubocop.yml +62 -0
- data/config/yardstick.yml +2 -0
- data/lib/rom.rb +13 -5
- data/lib/rom/constants.rb +16 -0
- data/lib/rom/environment.rb +105 -0
- data/lib/rom/environment/builder.rb +71 -0
- data/lib/rom/mapper.rb +176 -0
- data/lib/rom/mapper/attribute.rb +108 -0
- data/lib/rom/mapper/builder.rb +58 -0
- data/lib/rom/mapper/builder/definition.rb +162 -0
- data/lib/rom/mapper/header.rb +103 -0
- data/lib/rom/mapper/loader_builder.rb +26 -0
- data/lib/rom/relation.rb +375 -0
- data/lib/rom/repository.rb +71 -0
- data/lib/rom/schema.rb +21 -0
- data/lib/rom/schema/builder.rb +59 -0
- data/lib/rom/schema/definition.rb +84 -0
- data/lib/rom/schema/definition/relation.rb +80 -0
- data/lib/rom/schema/definition/relation/base.rb +27 -0
- data/lib/rom/session.rb +111 -0
- data/lib/rom/session/environment.rb +67 -0
- data/lib/rom/session/identity_map.rb +43 -0
- data/lib/rom/session/mapper.rb +62 -0
- data/lib/rom/session/relation.rb +140 -0
- data/lib/rom/session/state.rb +59 -0
- data/lib/rom/session/state/created.rb +22 -0
- data/lib/rom/session/state/deleted.rb +25 -0
- data/lib/rom/session/state/persisted.rb +34 -0
- data/lib/rom/session/state/transient.rb +20 -0
- data/lib/rom/session/state/updated.rb +29 -0
- data/lib/rom/session/tracker.rb +62 -0
- data/lib/rom/support/axiom/adapter.rb +111 -0
- data/lib/rom/support/axiom/adapter/data_objects.rb +38 -0
- data/lib/rom/support/axiom/adapter/memory.rb +25 -0
- data/lib/rom/support/axiom/adapter/postgres.rb +19 -0
- data/lib/rom/support/axiom/adapter/sqlite3.rb +20 -0
- data/lib/version.rb +1 -1
- data/rom.gemspec +7 -3
- data/spec/integration/environment_setup_spec.rb +24 -0
- data/spec/integration/grouped_mappers_spec.rb +87 -0
- data/spec/integration/join_and_group_spec.rb +76 -0
- data/spec/integration/join_and_wrap_spec.rb +68 -0
- data/spec/integration/mapping_embedded_relations_spec.rb +73 -0
- data/spec/integration/mapping_relations_spec.rb +120 -0
- data/spec/integration/schema_definition_spec.rb +152 -0
- data/spec/integration/session_spec.rb +87 -0
- data/spec/integration/wrapped_mappers_spec.rb +73 -0
- data/spec/shared/unit/environment_context.rb +6 -0
- data/spec/shared/unit/loader.rb +11 -0
- data/spec/shared/unit/loader_identity.rb +13 -0
- data/spec/shared/unit/mapper_context.rb +11 -0
- data/spec/shared/unit/relation_context.rb +82 -0
- data/spec/shared/unit/session_environment_context.rb +11 -0
- data/spec/shared/unit/session_relation_context.rb +18 -0
- data/spec/spec_helper.rb +49 -0
- data/spec/support/helper.rb +34 -0
- data/spec/support/ice_nine_config.rb +10 -0
- data/spec/support/test_mapper.rb +110 -0
- data/spec/unit/rom/environment/builder/mapping_spec.rb +24 -0
- data/spec/unit/rom/environment/builder/schema_spec.rb +33 -0
- data/spec/unit/rom/environment/class_methods/setup_spec.rb +18 -0
- data/spec/unit/rom/environment/repository_spec.rb +21 -0
- data/spec/unit/rom/mapper/attribute/embedded_collection/to_ast_spec.rb +18 -0
- data/spec/unit/rom/mapper/attribute/embedded_value/to_ast_spec.rb +16 -0
- data/spec/unit/rom/mapper/attribute/rename_spec.rb +9 -0
- data/spec/unit/rom/mapper/attribute/to_ast_spec.rb +9 -0
- data/spec/unit/rom/mapper/builder/class_methods/call_spec.rb +61 -0
- data/spec/unit/rom/mapper/class_methods/build_spec.rb +55 -0
- data/spec/unit/rom/mapper/dump_spec.rb +11 -0
- data/spec/unit/rom/mapper/group_spec.rb +35 -0
- data/spec/unit/rom/mapper/header/each_spec.rb +26 -0
- data/spec/unit/rom/mapper/header/element_reader_spec.rb +21 -0
- data/spec/unit/rom/mapper/header/group_spec.rb +18 -0
- data/spec/unit/rom/mapper/header/join_spec.rb +14 -0
- data/spec/unit/rom/mapper/header/keys_spec.rb +29 -0
- data/spec/unit/rom/mapper/header/project_spec.rb +13 -0
- data/spec/unit/rom/mapper/header/rename_spec.rb +11 -0
- data/spec/unit/rom/mapper/header/to_ast_spec.rb +11 -0
- data/spec/unit/rom/mapper/header/wrap_spec.rb +18 -0
- data/spec/unit/rom/mapper/identity_from_tuple_spec.rb +11 -0
- data/spec/unit/rom/mapper/identity_spec.rb +11 -0
- data/spec/unit/rom/mapper/join_spec.rb +15 -0
- data/spec/unit/rom/mapper/load_spec.rb +11 -0
- data/spec/unit/rom/mapper/new_object_spec.rb +14 -0
- data/spec/unit/rom/mapper/project_spec.rb +11 -0
- data/spec/unit/rom/mapper/rename_spec.rb +16 -0
- data/spec/unit/rom/mapper/wrap_spec.rb +35 -0
- data/spec/unit/rom/relation/delete_spec.rb +15 -0
- data/spec/unit/rom/relation/drop_spec.rb +11 -0
- data/spec/unit/rom/relation/each_spec.rb +23 -0
- data/spec/unit/rom/relation/first_spec.rb +19 -0
- data/spec/unit/rom/relation/group_spec.rb +29 -0
- data/spec/unit/rom/relation/inject_mapper_spec.rb +17 -0
- data/spec/unit/rom/relation/insert_spec.rb +13 -0
- data/spec/unit/rom/relation/last_spec.rb +19 -0
- data/spec/unit/rom/relation/one_spec.rb +49 -0
- data/spec/unit/rom/relation/rename_spec.rb +21 -0
- data/spec/unit/rom/relation/replace_spec.rb +13 -0
- data/spec/unit/rom/relation/restrict_spec.rb +25 -0
- data/spec/unit/rom/relation/sort_by_spec.rb +25 -0
- data/spec/unit/rom/relation/take_spec.rb +11 -0
- data/spec/unit/rom/relation/to_a_spec.rb +20 -0
- data/spec/unit/rom/relation/update_spec.rb +25 -0
- data/spec/unit/rom/relation/wrap_spec.rb +29 -0
- data/spec/unit/rom/repository/class_methods/build_spec.rb +27 -0
- data/spec/unit/rom/repository/element_reader_spec.rb +21 -0
- data/spec/unit/rom/repository/element_writer_spec.rb +18 -0
- data/spec/unit/rom/schema/builder/class_methods/build_spec.rb +103 -0
- data/spec/unit/rom/schema/element_reader_spec.rb +15 -0
- data/spec/unit/rom/session/class_methods/start_spec.rb +23 -0
- data/spec/unit/rom/session/clean_predicate_spec.rb +21 -0
- data/spec/unit/rom/session/environment/element_reader_spec.rb +13 -0
- data/spec/unit/rom/session/flush_spec.rb +58 -0
- data/spec/unit/rom/session/mapper/load_spec.rb +47 -0
- data/spec/unit/rom/session/relation/delete_spec.rb +28 -0
- data/spec/unit/rom/session/relation/dirty_predicate_spec.rb +35 -0
- data/spec/unit/rom/session/relation/identity_spec.rb +11 -0
- data/spec/unit/rom/session/relation/new_spec.rb +50 -0
- data/spec/unit/rom/session/relation/save_spec.rb +50 -0
- data/spec/unit/rom/session/relation/state_spec.rb +23 -0
- data/spec/unit/rom/session/relation/track_spec.rb +23 -0
- data/spec/unit/rom/session/relation/tracking_predicate_spec.rb +23 -0
- data/spec/unit/rom/session/relation/update_attributes_spec.rb +45 -0
- data/spec/unit/rom/session/state_spec.rb +79 -0
- metadata +212 -11
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe Environment::Builder, '#mapping' do
|
|
6
|
+
subject(:builder) { Environment::Builder.call(test: "memory://test") }
|
|
7
|
+
|
|
8
|
+
let!(:schema) do
|
|
9
|
+
builder.schema do
|
|
10
|
+
base_relation(:users) do
|
|
11
|
+
repository :test
|
|
12
|
+
attribute :name, String
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'sets up rom mapper' do
|
|
18
|
+
builder.mapping do
|
|
19
|
+
relation(:users) { map :name }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
expect(builder.mappers[:users]).to be_instance_of(Mapper)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe Environment::Builder, '#schema' do
|
|
6
|
+
let(:repositories) { Hash.new }
|
|
7
|
+
let(:object) { Environment::Builder.call(test: "memory://test") }
|
|
8
|
+
let(:block) { -> { } }
|
|
9
|
+
|
|
10
|
+
fake(:builder) { Schema::Builder }
|
|
11
|
+
|
|
12
|
+
before do
|
|
13
|
+
fake_class(Schema::Builder, build: -> { builder })
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
describe 'with a block' do
|
|
17
|
+
subject { object.schema(&block) }
|
|
18
|
+
|
|
19
|
+
it 'calls the schema' do
|
|
20
|
+
expect(subject).to be(builder)
|
|
21
|
+
expect(builder).to have_received.call
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
describe 'without a block' do
|
|
26
|
+
subject { object.schema }
|
|
27
|
+
|
|
28
|
+
it 'calls the schema' do
|
|
29
|
+
expect(subject).to be(builder)
|
|
30
|
+
expect(builder).not_to have_received.call
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe Environment, '.setup' do
|
|
6
|
+
subject { described_class.setup(config).finalize }
|
|
7
|
+
|
|
8
|
+
context 'when a repository config hash is passed' do
|
|
9
|
+
let(:config) { { name => uri } }
|
|
10
|
+
let(:name) { :test }
|
|
11
|
+
let(:uri) { 'memory://test' }
|
|
12
|
+
|
|
13
|
+
let(:coerced_config) { Hash[test: Repository.build(name, coerced_uri)] }
|
|
14
|
+
let(:coerced_uri) { Addressable::URI.parse(uri) }
|
|
15
|
+
|
|
16
|
+
its(:repositories) { should eql(described_class.new(coerced_config, {}, {}, {}).repositories) }
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe Environment, '#repository' do
|
|
6
|
+
include_context 'Environment'
|
|
7
|
+
|
|
8
|
+
subject { object.repository(name) }
|
|
9
|
+
|
|
10
|
+
context 'when repository exists' do
|
|
11
|
+
let(:name) { :test }
|
|
12
|
+
|
|
13
|
+
it { should be_instance_of(Repository) }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
context 'when is not known' do
|
|
17
|
+
let(:name) { :not_here }
|
|
18
|
+
|
|
19
|
+
it { should be(nil) }
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe Mapper::Attribute::EmbeddedCollection, '#to_ast' do
|
|
4
|
+
subject(:attribute) { Mapper::Attribute::EmbeddedCollection.build(:tasks, node: mapper.loader.node) }
|
|
5
|
+
|
|
6
|
+
let(:mapper) { Mapper.build([[:id]], model: model) }
|
|
7
|
+
let(:model) { mock_model(:id) }
|
|
8
|
+
|
|
9
|
+
it 'returns a morpher transformer node' do
|
|
10
|
+
loader = Morpher.compile(attribute.to_ast)
|
|
11
|
+
|
|
12
|
+
task1 = model.new(id: 1)
|
|
13
|
+
task2 = model.new(id: 1)
|
|
14
|
+
tuple = { tasks: [{ id: 1 }, { id: 1 }] }
|
|
15
|
+
|
|
16
|
+
expect(loader.call(tuple)).to eql([:tasks, [task1, task2]])
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe Mapper::Attribute::EmbeddedValue, '#to_ast' do
|
|
4
|
+
subject(:attribute) { Mapper::Attribute::EmbeddedValue.build(:model, node: mapper.loader.node) }
|
|
5
|
+
|
|
6
|
+
let(:mapper) { Mapper.build([[:id]], model: model) }
|
|
7
|
+
let(:model) { mock_model(:id) }
|
|
8
|
+
|
|
9
|
+
it 'returns a morpher transformer node' do
|
|
10
|
+
loader = Morpher.compile(attribute.to_ast)
|
|
11
|
+
object = model.new(id: 1)
|
|
12
|
+
tuple = { model: { id: 1 } }
|
|
13
|
+
|
|
14
|
+
expect(loader.call(tuple)).to eql([:model, object])
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe Mapper::Attribute, '#rename' do
|
|
4
|
+
subject(:attribute) { Mapper::Attribute.build(:title) }
|
|
5
|
+
|
|
6
|
+
it 'returns a new attribute with changed name' do
|
|
7
|
+
expect(attribute.rename(:book_title)).to eql(Mapper::Attribute.build(:book_title))
|
|
8
|
+
end
|
|
9
|
+
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe Mapper::Attribute, '#to_ast' do
|
|
4
|
+
subject(:attribute) { Mapper::Attribute.build(:title) }
|
|
5
|
+
|
|
6
|
+
it 'returns a morpher transformer node' do
|
|
7
|
+
expect(Morpher.compile(attribute.to_ast).call(title: 'Title', other: 'Foo')).to eql([:title, 'Title'])
|
|
8
|
+
end
|
|
9
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe Mapper::Builder, '.call' do
|
|
6
|
+
let(:header) { [[:id, Integer], [:user_name, String], [:age, Integer], [:email, String]] }
|
|
7
|
+
let(:relation) { Axiom::Relation::Base.new(:users, header) }
|
|
8
|
+
let(:model) { mock_model(:id, :name, :email) }
|
|
9
|
+
let(:env) { Environment.setup(test: 'memory://test') }
|
|
10
|
+
let(:schema) { Hash[users: relation] }
|
|
11
|
+
|
|
12
|
+
context 'when attribute mapping is used' do
|
|
13
|
+
let(:mapper) { subject.mappers[:users] }
|
|
14
|
+
|
|
15
|
+
subject do
|
|
16
|
+
user_model = model
|
|
17
|
+
|
|
18
|
+
Mapper::Builder.call(schema) do
|
|
19
|
+
relation(:users) do
|
|
20
|
+
model user_model
|
|
21
|
+
|
|
22
|
+
map :id, :email
|
|
23
|
+
map :name, from: :user_name
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'builds rom mapper' do
|
|
29
|
+
expect(mapper.header.map(&:name)).to eql([:id, :email, :name])
|
|
30
|
+
expect(mapper.header.map(&:type)).to eql([Integer, String, String])
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it 'sets up the model' do
|
|
34
|
+
object = mapper.new_object(id: 1, name: 'Jane', email: 'jane@rom.org')
|
|
35
|
+
expect(object).to be_instance_of(model)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
context 'when custom mapper is injected' do
|
|
40
|
+
subject do
|
|
41
|
+
custom_mapper = test_mapper
|
|
42
|
+
Mapper::Builder.call(schema) { relation(:users) { mapper(custom_mapper) } }
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
let(:test_mapper) { TestMapper.new(header, model) }
|
|
46
|
+
|
|
47
|
+
it 'sets the custom mapper' do
|
|
48
|
+
expect(subject.mappers[:users]).to be(test_mapper)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
context 'when unknown relation name is used' do
|
|
53
|
+
subject { described_class.call(schema) { not_here(1, 'a') {} } }
|
|
54
|
+
|
|
55
|
+
it 'raises error' do
|
|
56
|
+
expect { subject }.to raise_error(
|
|
57
|
+
NoMethodError, /undefined method `not_here'/
|
|
58
|
+
)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe Mapper, '.build' do
|
|
6
|
+
subject { described_class.build(header, model: model) }
|
|
7
|
+
|
|
8
|
+
let(:model) { mock_model(:name) }
|
|
9
|
+
let(:attributes) { [[:name, type: String, from: :user_name]] }
|
|
10
|
+
|
|
11
|
+
describe 'when header is a primitive' do
|
|
12
|
+
let(:header) { attributes }
|
|
13
|
+
|
|
14
|
+
its(:model) { should be(model) }
|
|
15
|
+
|
|
16
|
+
it 'builds correct header' do
|
|
17
|
+
expect(subject.header.mapping).to eql(user_name: :name)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
let(:object) { model.new(name: 'Jane') }
|
|
21
|
+
let(:params) { Hash[user_name: 'Jane'] }
|
|
22
|
+
|
|
23
|
+
specify do
|
|
24
|
+
expect(subject.load(params)).to eq(object)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
specify do
|
|
28
|
+
expect(subject.dump(object)).to eq(params.values)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
describe 'when header is a mapper header instance' do
|
|
33
|
+
let(:header) { Mapper::Header.build(attributes) }
|
|
34
|
+
let(:options) { Hash.new }
|
|
35
|
+
|
|
36
|
+
its(:model) { should be(model) }
|
|
37
|
+
its(:header) { should eql(header) }
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
describe 'when options has custom loader' do
|
|
41
|
+
let(:header) { Mapper::Header.build(attributes) }
|
|
42
|
+
let(:options) { Hash[loader: :load_attribute_hash] }
|
|
43
|
+
|
|
44
|
+
its(:model) { should be(model) }
|
|
45
|
+
its(:header) { should eql(header) }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
describe 'loader is set to :load_attribute_accessors' do
|
|
49
|
+
let(:header) { Mapper::Header.build(attributes) }
|
|
50
|
+
let(:options) { Hash[loader: :load_attribute_accessors] }
|
|
51
|
+
|
|
52
|
+
its(:model) { should be(model) }
|
|
53
|
+
its(:header) { should eql(header) }
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe Mapper, "#group" do
|
|
4
|
+
subject(:mapper) { user.group(tasks: task) }
|
|
5
|
+
|
|
6
|
+
let(:user) { Mapper.build([[:name]], model: user_model) }
|
|
7
|
+
let(:task) { Mapper.build([[:title]], model: task_model) }
|
|
8
|
+
|
|
9
|
+
let(:user_model) { mock_model(:name, :tasks) }
|
|
10
|
+
let(:task_model) { mock_model(:title) }
|
|
11
|
+
|
|
12
|
+
let(:loader_transformer) do
|
|
13
|
+
Morpher.compile(
|
|
14
|
+
s(:block,
|
|
15
|
+
s(:hash_transform,
|
|
16
|
+
s(:block, s(:key_fetch, :name), s(:key_dump, :name)),
|
|
17
|
+
s(:key_transform, :tasks, :tasks, s(:map, task.loader.node))
|
|
18
|
+
),
|
|
19
|
+
s(:load_instance_variables, s(:param, user_model, :name, :tasks))
|
|
20
|
+
)
|
|
21
|
+
)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
let(:dumper_transformer) do
|
|
25
|
+
loader_transformer.inverse
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "returns a mapper that can load wrapped tuples" do
|
|
29
|
+
expect(mapper.loader).to eq(loader_transformer)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "returns a mapper that can dump wrapped objects" do
|
|
33
|
+
expect(mapper.dumper).to eq(dumper_transformer)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe Mapper::Header, '#each' do
|
|
6
|
+
subject(:header) { Mapper::Header.build([[:id], [:name]]) }
|
|
7
|
+
|
|
8
|
+
let(:id) { header[:id] }
|
|
9
|
+
let(:name) { header[:name] }
|
|
10
|
+
|
|
11
|
+
context 'with a block' do
|
|
12
|
+
it 'yields attributes' do
|
|
13
|
+
result = []
|
|
14
|
+
|
|
15
|
+
header.each { |attribute| result << attribute }
|
|
16
|
+
|
|
17
|
+
expect(result).to eql([id, name])
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
context 'without a block' do
|
|
22
|
+
subject { header.each }
|
|
23
|
+
|
|
24
|
+
it { should be_instance_of(Enumerator) }
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe Mapper::Header, '#[]' do
|
|
6
|
+
subject(:header) { Mapper::Header.build([[:id]]) }
|
|
7
|
+
|
|
8
|
+
context 'when attribute exists' do
|
|
9
|
+
subject { header[:id] }
|
|
10
|
+
|
|
11
|
+
let(:id) { Mapper::Attribute.build(:id) }
|
|
12
|
+
|
|
13
|
+
it { should eql(id) }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
context 'when attribute does not exist' do
|
|
17
|
+
specify do
|
|
18
|
+
expect { header[:not_here] }.to raise_error(KeyError)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe Mapper::Header, '#group' do
|
|
6
|
+
subject(:header) { left.group(models: mapper) }
|
|
7
|
+
|
|
8
|
+
let(:left) { Mapper::Header.build([[:id], [:name]]) }
|
|
9
|
+
let(:mapper) { Mapper.build([[:id], [:title]]) }
|
|
10
|
+
|
|
11
|
+
it 'returns a header with embedded collection attribute' do
|
|
12
|
+
expected = Mapper::Header.build([
|
|
13
|
+
[:id], [:name], mapper.attribute(Mapper::Attribute::EmbeddedCollection, :models)
|
|
14
|
+
])
|
|
15
|
+
|
|
16
|
+
expect(header).to eq(expected)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe Mapper::Header, '#join' do
|
|
6
|
+
subject(:header) { left.join(right) }
|
|
7
|
+
|
|
8
|
+
let(:left) { Mapper::Header.build([[:id], [:name]]) }
|
|
9
|
+
let(:right) { Mapper::Header.build([[:id], [:title]]) }
|
|
10
|
+
|
|
11
|
+
it 'returns a joined header with uniq attributes' do
|
|
12
|
+
expect(header).to eql(Mapper::Header.build([[:id], [:name], [:title]]))
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe Mapper::Header, '#keys' do
|
|
6
|
+
subject { object.keys }
|
|
7
|
+
|
|
8
|
+
let(:object) { Mapper::Header.build(attributes) }
|
|
9
|
+
let(:id) { object[:id] }
|
|
10
|
+
let(:name) { object[:name] }
|
|
11
|
+
|
|
12
|
+
context 'without mapping' do
|
|
13
|
+
let(:attributes) { [[:id], [:name]] }
|
|
14
|
+
|
|
15
|
+
it { should eql([]) }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
context 'with mapping' do
|
|
19
|
+
let(:attributes) { [[:id, from: :user_id, key: true], [:name]] }
|
|
20
|
+
|
|
21
|
+
it { should eql([id]) }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
context 'with multiple keys' do
|
|
25
|
+
let(:attributes) { [[:id, key: true], [:name, key: true]] }
|
|
26
|
+
|
|
27
|
+
it { should eql([id, name]) }
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe Mapper::Header, '#project' do
|
|
6
|
+
subject(:header) { other.project([:id]) }
|
|
7
|
+
|
|
8
|
+
let(:other) { Mapper::Header.build([[:id], [:name]]) }
|
|
9
|
+
|
|
10
|
+
it 'returns a header with projected attributes' do
|
|
11
|
+
expect(header).to eql(Mapper::Header.build([[:id]]))
|
|
12
|
+
end
|
|
13
|
+
end
|