This commit is contained in:
Joshua Clayton 2012-04-06 14:41:13 -04:00
parent 493d424a43
commit 4ef98ff62b
8 changed files with 83 additions and 55 deletions

View File

@ -405,30 +405,30 @@ Sequences can also have aliases. The sequence aliases share the same counter:
```ruby
factory :user do
sequence(:email, 1000, :aliases => [:sender, :receiver]) {|n| "person#{n}@example.com" }
sequence(:email, 1000, aliases: [:sender, :receiver]) {|n| "person#{n}@example.com" }
end
# will increase value counter for :email which is shared by :sender and :receiver
FactoryGirl.next(:sender)
FactoryGirl.next(:sender)
```
Define aliases and use default value (=1) for the counter
Define aliases and use default value (1) for the counter
```ruby
factory :user do
sequence(:email, :aliases => [:sender, :receiver]) {|n| "person#{n}@example.com" }
sequence(:email, aliases: [:sender, :receiver]) {|n| "person#{n}@example.com" }
end
```
Setting the value using the :value option:
Setting the value:
```ruby
factory :user do
sequence(:email, :value => 'b', :aliases => [:sender, :receiver]) {|n| "person#{n}@example.com" }
sequence(:email, 'a', aliases: [:sender, :receiver]) {|n| "person#{n}@example.com" }
end
```
The value just needs to support the `#next` method. Here the next value will be 'b'.
The value just needs to support the `#next` method. Here the next value will be 'a', then 'b', etc.
Traits
------

View File

@ -108,8 +108,8 @@ module FactoryGirl
# end
#
# Except that no globally available sequence will be defined.
def sequence(name, start_value = 1, options = {}, &block)
sequence = options.empty? ? Sequence.new(name, start_value, &block) : Sequence.new(name, start_value, options, &block)
def sequence(name, *args, &block)
sequence = Sequence.new(name, *args, &block)
add_attribute(name) { sequence.next }
end

View File

@ -3,24 +3,25 @@ module FactoryGirl
# Sequences are defined using sequence within a FactoryGirl.define block.
# Sequence values are generated using next.
class Sequence
attr_reader :name, :names, :value
attr_reader :name
def initialize(name, value = 1, options = {}, &proc) #:nodoc:
@value = value
if value.kind_of?(Hash)
options = value
@value = options[:value] || 1
end
@name = name
@names = ([name] + (options[:aliases] || [])).flatten
@proc = proc
def initialize(name, *args, &proc) #:nodoc:
@name = name
@proc = proc
options = args.extract_options!
@value = args.first || 1
@aliases = options[:aliases] || []
end
# aliased sequences share the same sequence counter
def next
@proc ? @proc.call(@value) : @value
ensure
@value = @value.next
end
def names
[@name] + @aliases
end
end
end

View File

@ -29,8 +29,8 @@ module FactoryGirl
end
end
def sequence(name, start_value = 1, options = {}, &block)
FactoryGirl.register_sequence(Sequence.new(name, start_value, options, &block))
def sequence(name, *args, &block)
FactoryGirl.register_sequence(Sequence.new(name, *args, &block))
end
def trait(name, &block)

View File

@ -30,4 +30,32 @@ describe "sequences" do
another_value.should == 2
first_value.should_not == another_value
end
it "generates aliases for the sequence that reference the same block" do
FactoryGirl.define do
sequence(:size, aliases: [:count, :length]) {|n| "called-#{n}" }
end
first_value = generate(:size)
second_value = generate(:count)
third_value = generate(:length)
first_value.should == "called-1"
second_value.should == "called-2"
third_value.should == "called-3"
end
it "generates aliases for the sequence that reference the same block and retains value" do
FactoryGirl.define do
sequence(:size, "a", aliases: [:count, :length]) {|n| "called-#{n}" }
end
first_value = generate(:size)
second_value = generate(:count)
third_value = generate(:length)
first_value.should == "called-a"
second_value.should == "called-b"
third_value.should == "called-c"
end
end

View File

@ -91,7 +91,7 @@ describe FactoryGirl::DefinitionProxy, "#sequence" do
it "creates a new sequence starting at 1" do
proxy.sequence(:great)
FactoryGirl::Sequence.should have_received(:new).with(:great, 1)
FactoryGirl::Sequence.should have_received(:new).with(:great)
end
it "creates a new sequence with an overridden starting vaue" do

View File

@ -2,9 +2,6 @@ require 'spec_helper'
describe FactoryGirl::Registry do
let(:aliases) { [:thing, :widget] }
let(:sequence) { FactoryGirl::Sequence.new(:email) { |n| "somebody#{n}@example.com" } }
let(:sequences) { FactoryGirl::Sequence.new(:email, :aliases => [:sender, :receiver]) { |n| "some_one_else#{n}@example.com" } }
let(:factory) { FactoryGirl::Factory.new(:object) }
let(:other_factory) { FactoryGirl::Factory.new(:string) }
let(:factory_with_aliases) { FactoryGirl::Factory.new(:string, aliases: aliases) }
@ -58,18 +55,6 @@ describe FactoryGirl::Registry do
subject.to_a.should =~ [factory, factory_with_aliases]
end
it "registers an sequence" do
subject.add(sequence)
subject.find(:email).should == sequence
end
it "registers a multi sequences" do
subject.add(sequences)
subject.find(:email).should == sequences
subject.find(:sender).should == sequences
subject.find(:receiver).should == sequences
end
it "doesn't allow a duplicate name" do
expect { 2.times { subject.add(factory) } }.
to raise_error(FactoryGirl::DuplicateDefinitionError, "Factory already registered: object")
@ -88,3 +73,30 @@ describe FactoryGirl::Registry do
subject.count.should be_zero
end
end
describe FactoryGirl::Registry, "with sequences" do
let(:aliases) { [:sender, :receiver] }
let(:sequence) { FactoryGirl::Sequence.new(:email) { |n| "somebody#{n}@example.com" } }
let(:sequence_with_aliases) { FactoryGirl::Sequence.new(:email, aliases: aliases) { |n| "someone_else#{n}@example.com" } }
let(:registry_name) { "Sequence" }
subject { FactoryGirl::Registry.new(registry_name) }
it "registers an sequence" do
subject.add(sequence)
subject.find(:email).should == sequence
end
it "registers a sequence with aliases" do
subject.add(sequence_with_aliases)
subject.find(:email).should == sequence_with_aliases
subject.find(:sender).should == sequence_with_aliases
subject.find(:receiver).should == sequence_with_aliases
end
it "doesn't allow a duplicate name" do
expect { 2.times { subject.add(sequence_with_aliases) } }.
to raise_error(FactoryGirl::DuplicateDefinitionError, "Sequence already registered: email")
end
end

View File

@ -26,14 +26,8 @@ describe FactoryGirl::Sequence do
end
describe "a sequence with aliases using default value" do
let(:name) { :test }
let(:aliases) { [:alias, :other] }
subject { FactoryGirl::Sequence.new(name, :aliases => aliases) {|n| "=#{n}" } }
its(:name) { should == name }
its(:value) { should == 1 }
its(:names) { should == ([name] + aliases) }
its(:next) { should == "=1" }
subject { FactoryGirl::Sequence.new(:test, aliases: [:alias, :other]) { |n| "=#{n}" } }
its(:next) { should == "=1" }
describe "when incrementing" do
before { subject.next }
@ -42,15 +36,8 @@ describe FactoryGirl::Sequence do
end
describe "a sequence with custom value and aliases" do
let(:name) { :test }
let(:value) { 3 }
let(:aliases) { [:alias, :other] }
subject { FactoryGirl::Sequence.new(name, value, :aliases => aliases) {|n| "=#{n}" } }
its(:name) { should == name }
its(:value) { should == value }
its(:names) { should == ([name] + aliases) }
its(:next) { should == "=3" }
subject { FactoryGirl::Sequence.new(:test, 3, aliases: [:alias, :other]) { |n| "=#{n}" } }
its(:next) { should == "=3" }
describe "when incrementing" do
before { subject.next }