Skip to content
This repository has been archived by the owner on Oct 6, 2019. It is now read-only.

Commit

Permalink
Added missing integration tests from ROM project
Browse files Browse the repository at this point in the history
  • Loading branch information
GustavoCaso committed Apr 27, 2017
1 parent 486d2ca commit f4174dc
Show file tree
Hide file tree
Showing 23 changed files with 1,754 additions and 9 deletions.
117 changes: 117 additions & 0 deletions spec/integration/combine_spec.rb
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
43 changes: 43 additions & 0 deletions spec/integration/deep_embedded_spec.rb
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
206 changes: 206 additions & 0 deletions spec/integration/definition_dsl_spec.rb
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
Loading

0 comments on commit f4174dc

Please sign in to comment.