This repository has been archived by the owner on Oct 6, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added missing integration tests from ROM project
- Loading branch information
1 parent
486d2ca
commit f4174dc
Showing
23 changed files
with
1,754 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
require 'spec_helper' | ||
|
||
RSpec.describe 'Mapper definition DSL' do | ||
include_context 'container' | ||
include_context 'users and tasks' | ||
|
||
describe 'combine' do | ||
before do | ||
configuration.relation(:tasks) do | ||
def for_users(users) | ||
names = users.map { |user| user[:name] } | ||
restrict { |task| names.include?(task[:name]) } | ||
end | ||
|
||
def tags(_tasks) | ||
[{ name: 'blue', task: 'be cool' }] | ||
end | ||
end | ||
|
||
configuration.relation(:users) do | ||
def addresses(_users) | ||
[{ city: 'NYC', user: 'Jane' }, { city: 'Boston', user: 'Joe' }] | ||
end | ||
|
||
def books(_users) | ||
[{ title: 'Book One', user: 'Jane' }, { title: 'Book Two', user: 'Joe' }] | ||
end | ||
end | ||
|
||
configuration.mappers do | ||
define(:users) do | ||
register_as :entity | ||
|
||
model name: 'Test::User' | ||
|
||
attribute :name | ||
attribute :email | ||
|
||
combine :tasks, on: { name: :name } do | ||
model name: 'Test::Task' | ||
|
||
attribute :title | ||
|
||
wrap :meta do | ||
attribute :user, from: :name | ||
attribute :priority | ||
end | ||
|
||
combine :tags, on: { title: :task } do | ||
model name: 'Test::Tag' | ||
|
||
attribute :name | ||
end | ||
end | ||
|
||
combine :address, on: { name: :user }, type: :hash do | ||
model name: 'Test::Address' | ||
|
||
attribute :city | ||
end | ||
|
||
combine :book, on: { name: :user }, type: :hash | ||
end | ||
end | ||
end | ||
|
||
let(:users) { container.relation(:users) } | ||
let(:tasks) { container.relation(:tasks) } | ||
|
||
let(:joe) { | ||
Test::User.new( | ||
name: 'Joe', | ||
email: '[email protected]', | ||
tasks: [ | ||
Test::Task.new(title: 'be nice', meta: { user: 'Joe', priority: 1 }, | ||
tags: []), | ||
Test::Task.new(title: 'sleep well', meta: { user: 'Joe', priority: 2 }, | ||
tags: []) | ||
], | ||
address: Test::Address.new(city: 'Boston'), | ||
book: { title: 'Book Two', user: 'Joe' } | ||
) | ||
} | ||
|
||
let(:jane) { | ||
Test::User.new( | ||
name: 'Jane', | ||
email: '[email protected]', | ||
tasks: [ | ||
Test::Task.new( | ||
title: 'be cool', | ||
meta: { user: 'Jane', priority: 2 }, | ||
tags: [Test::Tag.new(name: 'blue')] | ||
) | ||
], | ||
address: Test::Address.new(city: 'NYC'), | ||
book: { title: 'Book One', user: 'Jane' } | ||
) | ||
} | ||
|
||
it 'works' do | ||
container | ||
|
||
Test::User.send(:include, Dry::Equalizer(:name, :email, :tasks, :address, :book)) | ||
Test::Task.send(:include, Dry::Equalizer(:title, :meta)) | ||
Test::Address.send(:include, Dry::Equalizer(:city)) | ||
|
||
result = users.combine( | ||
tasks.for_users.combine(tasks.tags), | ||
users.addresses, | ||
users.books | ||
).as(:entity) | ||
|
||
expect(result).to match_array([joe, jane]) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
require 'spec_helper' | ||
|
||
RSpec.describe 'Mappers / deeply embedded tuples' do | ||
include_context 'container' | ||
|
||
it 'allows mapping embedded tuples' do | ||
configuration.relation(:users) | ||
|
||
configuration.mappers do | ||
define(:users) do | ||
model name: 'Test::User' | ||
|
||
attribute :name, from: 'name' | ||
|
||
embedded :tasks, from: 'tasks' do | ||
attribute :title, from: 'title' | ||
|
||
embedded :priority, from: 'priority', type: :hash do | ||
attribute :value, from: 'value' | ||
attribute :desc, from: 'desc' | ||
end | ||
end | ||
end | ||
end | ||
|
||
container.relations.users << { | ||
'name' => 'Jane', | ||
'tasks' => [ | ||
{ 'title' => 'Task One', 'priority' => { 'value' => 1, 'desc' => 'high' } }, | ||
{ 'title' => 'Task Two', 'priority' => { 'value' => 3, 'desc' => 'low' } } | ||
] | ||
} | ||
|
||
jane = container.relation(:users).as(:users).first | ||
|
||
expect(jane.name).to eql('Jane') | ||
|
||
expect(jane.tasks).to eql([ | ||
{ title: 'Task One', priority: { value: 1, desc: 'high' } }, | ||
{ title: 'Task Two', priority: { value: 3, desc: 'low' } } | ||
]) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,206 @@ | ||
require 'spec_helper' | ||
|
||
RSpec.describe 'Mapper definition DSL' do | ||
include_context 'container' | ||
include_context 'users and tasks' | ||
|
||
let(:header) { mapper.header } | ||
|
||
before do | ||
configuration.relation(:users) do | ||
def email_index | ||
project(:email) | ||
end | ||
end | ||
end | ||
|
||
describe 'default PORO mapper' do | ||
subject(:mapper) { container.mappers.users.entity } | ||
|
||
before do | ||
configuration.mappers do | ||
define(:users) do | ||
model name: 'Test::User' | ||
|
||
register_as :entity | ||
|
||
attribute :name | ||
attribute :email | ||
end | ||
end | ||
end | ||
|
||
it 'defines a constant for the model class' do | ||
expect(mapper.model).to be(Test::User) | ||
end | ||
|
||
it 'defines header with attributes' do | ||
expect(header.keys).to eql([:name, :email]) | ||
end | ||
end | ||
|
||
describe 'excluding attributes' do | ||
context 'by setting :inherit_header to false' do | ||
subject(:mapper) { container.mappers.users.email_index } | ||
|
||
before do | ||
configuration.mappers do | ||
define(:users) do | ||
model name: 'Test::User' | ||
|
||
attribute :name | ||
attribute :email | ||
end | ||
|
||
define(:email_index, parent: :users, inherit_header: false) do | ||
model name: 'Test::UserWithoutName' | ||
attribute :email | ||
end | ||
end | ||
end | ||
|
||
it 'only maps provided attributes' do | ||
expect(header.keys).to eql([:email]) | ||
end | ||
end | ||
end | ||
|
||
describe 'virtual relation mapper' do | ||
subject(:mapper) { container.mappers.users.email_index } | ||
|
||
before do | ||
configuration.mappers do | ||
define(:users) do | ||
model name: 'Test::User' | ||
|
||
attribute :name | ||
attribute :email | ||
end | ||
|
||
define(:email_index, parent: :users) do | ||
model name: 'Test::UserWithoutName' | ||
exclude :name | ||
end | ||
end | ||
end | ||
|
||
it 'inherits the attributes from the parent by default' do | ||
expect(header.keys).to eql([:name, :email]) | ||
end | ||
|
||
it 'excludes an inherited attribute when requested' do | ||
name = header.attributes[:name] | ||
expect(name).to be_kind_of ROM::Header::Exclude | ||
end | ||
|
||
it 'builds a new model' do | ||
expect(mapper.model).to be(Test::UserWithoutName) | ||
end | ||
end | ||
|
||
describe 'wrapped relation mapper' do | ||
before do | ||
configuration.relation(:tasks) do | ||
def with_user | ||
join(users) | ||
end | ||
end | ||
|
||
configuration.mappers do | ||
define(:tasks) do | ||
model name: 'Test::Task' | ||
|
||
attribute :title | ||
attribute :priority | ||
end | ||
end | ||
end | ||
|
||
it 'allows defining wrapped attributes via options hash' do | ||
configuration.mappers do | ||
define(:with_user, parent: :tasks) do | ||
model name: 'Test::TaskWithUser' | ||
|
||
attribute :title | ||
attribute :priority | ||
|
||
wrap user: [:email] | ||
end | ||
end | ||
|
||
container | ||
|
||
Test::TaskWithUser.send(:include, Dry::Equalizer(:title, :priority, :user)) | ||
|
||
jane = container.relation(:tasks).with_user.as(:with_user).to_a.last | ||
|
||
expect(jane).to eql( | ||
Test::TaskWithUser.new( | ||
title: 'be cool', | ||
priority: 2, | ||
user: { email: '[email protected]' } | ||
) | ||
) | ||
end | ||
|
||
it 'allows defining wrapped attributes via options block' do | ||
configuration.mappers do | ||
define(:with_user, parent: :tasks) do | ||
model name: 'Test::TaskWithUser' | ||
|
||
attribute :title | ||
attribute :priority | ||
|
||
wrap :user do | ||
attribute :email | ||
end | ||
end | ||
end | ||
|
||
container | ||
|
||
Test::TaskWithUser.send(:include, Dry::Equalizer(:title, :priority, :user)) | ||
|
||
jane = container.relation(:tasks).with_user.as(:with_user).to_a.last | ||
|
||
expect(jane).to eql( | ||
Test::TaskWithUser.new( | ||
title: 'be cool', | ||
priority: 2, | ||
user: { email: '[email protected]' } | ||
) | ||
) | ||
end | ||
|
||
it 'allows defining wrapped attributes mapped to a model' do | ||
configuration.mappers do | ||
define(:with_user, parent: :tasks) do | ||
model name: 'Test::TaskWithUser' | ||
|
||
attribute :title | ||
attribute :priority | ||
|
||
wrap :user do | ||
model name: 'Test::User' | ||
attribute :email | ||
end | ||
end | ||
end | ||
|
||
container | ||
|
||
Test::TaskWithUser.send(:include, Dry::Equalizer(:title, :priority, :user)) | ||
Test::User.send(:include, Dry::Equalizer(:email)) | ||
|
||
jane = container.relation(:tasks).with_user.as(:with_user).to_a.last | ||
|
||
expect(jane).to eql( | ||
Test::TaskWithUser.new( | ||
title: 'be cool', | ||
priority: 2, | ||
user: Test::User.new(email: '[email protected]') | ||
) | ||
) | ||
end | ||
end | ||
end |
Oops, something went wrong.