Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

502 lines (393 sloc) 13.762 kb
require 'spec_helper'
shared_examples 'something fabricatable' do
subject { fabricated_object }
let(:fabricated_object) { Fabricate(fabricator_name, placeholder: 'dynamic content') }
context 'defaults from fabricator' do
its(:dynamic_field) { should == 'dynamic content' }
its(:nil_field) { should be_nil }
its(:number_field) { should == 5 }
its(:string_field) { should == 'content' }
its(:false_field) { should == false }
end
context 'model callbacks are fired' do
its(:before_save_value) { should == 11 }
end
context 'overriding at fabricate time' do
let(:fabricated_object) do
Fabricate(
"#{fabricator_name}_with_children",
string_field: 'new content',
number_field: 10,
nil_field: nil,
placeholder: 'is not invoked'
) do
dynamic_field { 'new dynamic content' }
end
end
its(:dynamic_field) { should == 'new dynamic content' }
its(:nil_field) { should be_nil }
its(:number_field) { should == 10 }
its(:string_field) { should == 'new content' }
context 'child collections' do
subject { fabricated_object.send(collection_field) }
its(:size) { should == 2 }
its(:first) { should be_persisted }
its("first.number_field") { should == 10 }
its(:last) { should be_persisted }
its("last.number_field") { should == 10 }
end
end
context 'state of the object' do
it 'generates a fresh object every time' do
Fabricate(fabricator_name).should_not == subject
end
it { should be_persisted }
end
context 'transient attributes' do
it { should_not respond_to(:placeholder) }
end
context 'build' do
subject { Fabricate.build("#{fabricator_name}_with_children") }
it { should_not be_persisted }
it 'cascades to child records' do
subject.send(collection_field).each do |o|
o.should_not be_persisted
end
end
end
context 'attributes for' do
subject { Fabricate.attributes_for(fabricator_name) }
it { should be_kind_of(HashWithIndifferentAccess) }
it 'serializes the attributes' do
should include({
:dynamic_field => nil,
:nil_field => nil,
:number_field => 5,
:string_field => 'content'
})
end
end
context 'belongs_to associations' do
subject { Fabricate("#{collection_field.to_s.singularize}_with_parent") }
it 'sets the parent association' do
subject.send(fabricator_name).should be
end
it 'sets the id of the associated object' do
subject.send("#{fabricator_name}_id").should == subject.send(fabricator_name).id
end
end
end
describe Fabrication do
context 'plain old ruby objects' do
let(:fabricator_name) { :parent_ruby_object }
let(:collection_field) { :child_ruby_objects }
it_should_behave_like 'something fabricatable'
end
context 'active_record models' do
let(:fabricator_name) { :parent_active_record_model }
let(:collection_field) { :child_active_record_models }
it_should_behave_like 'something fabricatable'
context 'associations in attributes_for' do
let(:parent_model) { Fabricate(:parent_active_record_model) }
subject do
Fabricate.attributes_for(:child_active_record_model, parent_active_record_model: parent_model)
end
it 'serializes the belongs_to as an id' do
should include({ parent_active_record_model_id: parent_model.id })
end
end
context 'association proxies' do
subject { parent_model.child_active_record_models.build }
let(:parent_model) { Fabricate(:parent_active_record_model_with_children) }
it { should be_kind_of(ChildActiveRecordModel) }
end
end
context 'data_mapper models' do
let(:fabricator_name) { :parent_data_mapper_model }
let(:collection_field) { :child_data_mapper_models }
it_should_behave_like 'something fabricatable'
context 'associations in attributes_for' do
let(:parent_model) { Fabricate(:parent_data_mapper_model) }
subject do
Fabricate.attributes_for(
:child_data_mapper_model, parent_data_mapper_model: parent_model
)
end
it 'serializes the belongs_to as an id' do
should include({ parent_data_mapper_model_id: parent_model.id })
end
end
end
context 'referenced mongoid documents' do
let(:fabricator_name) { :parent_mongoid_document }
let(:collection_field) { :referenced_mongoid_documents }
it_should_behave_like 'something fabricatable'
end
context 'embedded mongoid documents' do
let(:fabricator_name) { :parent_mongoid_document }
let(:collection_field) { :embedded_mongoid_documents }
it_should_behave_like 'something fabricatable'
end
context 'sequel models' do
let(:fabricator_name) { :parent_sequel_model }
let(:collection_field) { :child_sequel_models }
it_should_behave_like 'something fabricatable'
end
context 'keymaker models' do
let(:fabricator_name) { :parent_keymaker_node }
subject { fabricated_object }
let(:fabricated_object) { Fabricate(fabricator_name, placeholder: 'dynamic content') }
context 'defaults from fabricator' do
its(:dynamic_field) { should == 'dynamic content' }
its(:nil_field) { should be_nil }
its(:number_field) { should == 5 }
its(:string_field) { should == 'content' }
its(:false_field) { should == false }
end
context 'model callbacks are fired' do
its(:before_save_value) { should == 11 }
end
context 'overriding at fabricate time' do
let(:fabricated_object) do
Fabricate(
fabricator_name,
string_field: 'new content',
number_field: 10,
nil_field: nil,
placeholder: 'is not invoked'
) do
dynamic_field { 'new dynamic content' }
end
end
its(:dynamic_field) { should == 'new dynamic content' }
its(:nil_field) { should be_nil }
its(:number_field) { should == 10 }
its(:string_field) { should == 'new content' }
end
context 'state of the object' do
it 'generates a fresh object every time' do
Fabricate(fabricator_name).should_not == subject
end
it { should be_persisted }
end
context 'transient attributes' do
it { should_not respond_to(:placeholder) }
end
context 'build' do
subject { Fabricate.build(fabricator_name) }
it { should_not be_persisted }
end
context 'attributes for' do
subject { Fabricate.attributes_for(fabricator_name) }
it { should be_kind_of(HashWithIndifferentAccess) }
it 'serializes the attributes' do
should include({
:dynamic_field => nil,
:nil_field => nil,
:number_field => 5,
:string_field => 'content'
})
end
end
end
context 'when the class requires a constructor' do
subject do
Fabricate(:city) do
on_init { init_with('Jacksonville Beach', 'FL') }
end
end
its(:city) { should == 'Jacksonville Beach' }
its(:state) { should == 'FL' }
end
context 'with a class in a module' do
subject { Fabricate("Something::Amazing", :stuff => "things") }
its(:stuff) { should == "things" }
end
context 'with the generation parameter' do
let(:person) do
Fabricate(:person, :first_name => "Paul") do
last_name { |attrs| "#{attrs[:first_name]}#{attrs[:age]}" }
age 50
end
end
it 'evaluates the fields in order of declaration' do
person.last_name.should == "Paul"
end
end
context 'multiple instance' do
let(:person1) { Fabricate(:person, :first_name => 'Jane') }
let(:person2) { Fabricate(:person, :first_name => 'John') }
it 'person1 is named Jane' do
person1.first_name.should == 'Jane'
end
it 'person2 is named John' do
person2.first_name.should == 'John'
end
it 'they have different last names' do
person1.last_name.should_not == person2.last_name
end
end
context 'with a specified class name' do
let(:someone) { Fabricate(:someone) }
before do
Fabricator(:someone, :class_name => :person) do
first_name "Paul"
end
end
it 'generates the person as someone' do
someone.first_name.should == "Paul"
end
end
context 'with an active record object' do
before { TestMigration.up }
after { TestMigration.down }
before(:all) do
Fabricator(:main_company, :from => :company) do
name { Faker::Company.name }
divisions(:count => 4)
non_field { "hi" }
after_create { |o| o.update_attributes(city: "Jacksonville Beach") }
end
Fabricator(:other_company, :from => :main_company) do
divisions(:count => 2)
after_build { |o| o.name = "Crazysauce" }
end
end
let(:company) { Fabricate(:main_company, :name => "Hashrocket") }
let(:other_company) { Fabricate(:other_company) }
it 'generates field blocks immediately' do
company.name.should == "Hashrocket"
end
it 'generates associations immediately when forced' do
Division.find_all_by_company_id(company.id).count.should == 4
end
it 'generates non-database backed fields immediately' do
company.instance_variable_get(:@non_field).should == 'hi'
end
it 'executes after build blocks' do
other_company.name.should == 'Crazysauce'
end
it 'executes after create blocks' do
company.city.should == 'Jacksonville Beach'
end
it 'overrides associations' do
Fabricate(:company, :divisions => []).divisions.should == []
end
it 'overrides inherited associations' do
other_company.divisions.count.should == 2
Division.count.should == 2
end
end
context 'with a mongoid document' do
let(:author) { Fabricate(:author) }
it "sets the author name" do
author.name.should == "George Orwell"
end
it 'generates four books' do
author.books.map(&:title).should == (1..4).map { |i| "book title #{i}" }
end
it "sets dynamic fields" do
Fabricate(:special_author).mongoid_dynamic_field.should == 50
end
it "sets lazy dynamic fields" do
Fabricate(:special_author).lazy_dynamic_field.should == "foo"
end
context "with disabled dynamic fields" do
before { Mongoid.allow_dynamic_fields = false }
after { Mongoid.allow_dynamic_fields = true }
it "raises NoMethodError for mongoid_dynamic_field=" do
expect { Fabricate(:special_author) }.to raise_error(Mongoid::Errors::UnknownAttribute, /mongoid_dynamic_field=/)
end
end
end
context 'with multiple callbacks' do
let(:child) { Fabricate(:child) }
it "runs the first callback" do
child.first_name.should == "Johnny"
end
it "runs the second callback" do
child.age.should == 10
end
end
context 'with multiple, inherited callbacks' do
let(:senior) { Fabricate(:senior) }
it "runs the parent callbacks first" do
senior.age.should == 70
end
end
context 'with a parent fabricator' do
context 'and a previously defined parent' do
let(:ernie) { Fabricate(:hemingway) }
it 'has the values from the parent' do
ernie.books.count.should == 4
end
it 'overrides specified values from the parent' do
ernie.name.should == 'Ernest Hemingway'
end
end
context 'and a class name as a parent' do
let(:greyhound) { Fabricate(:greyhound) }
it 'has the breed defined' do
greyhound.breed.should == 'greyhound'
end
it 'does not have a name' do
greyhound.name.should be_nil
end
end
end
describe '.clear_definitions' do
before { Fabrication.clear_definitions }
after { Fabrication::Support.find_definitions }
it 'should not generate authors' do
Fabrication.schematics[:author].should be_nil
end
end
context 'when defining a fabricator twice' do
it 'throws an error' do
lambda { Fabricator(:author) {} }.should raise_error(Fabrication::DuplicateFabricatorError)
end
end
context "when defining a fabricator for a class that doesn't exist" do
it 'throws an error' do
lambda { Fabricator(:your_mom) }.should raise_error(Fabrication::UnfabricatableError)
end
end
context 'when generating from a non-existant fabricator' do
it 'throws an error' do
lambda { Fabricate(:your_mom) }.should raise_error(Fabrication::UnknownFabricatorError)
end
end
context 'defining a fabricator' do
context 'without a block' do
before(:all) do
class Widget; end
Fabricator(:widget)
end
it 'works fine' do
Fabricate(:widget).should be
end
end
context 'for a non-existant class' do
it "raises an error if the class cannot be located" do
lambda { Fabricator(:somenonexistantclass) }.should raise_error(Fabrication::UnfabricatableError)
end
end
end
describe "Fabricate with a sequence" do
subject { Fabricate(:sequencer) }
its(:simple_iterator) { should == 0 }
its(:param_iterator) { should == 10 }
its(:block_iterator) { should == "block2" }
context "when namespaced" do
subject { Fabricate("Sequencer::Namespaced") }
its(:iterator) { should == 0 }
end
end
describe 'Fabricating while initializing' do
before { Fabrication.schematics.preinitialize }
after { Fabrication.schematics.freeze }
it 'throws an error' do
lambda { Fabricate(:your_mom) }.should raise_error(Fabrication::MisplacedFabricateError)
end
end
end
Jump to Line
Something went wrong with that request. Please try again.