diff --git a/GETTING_STARTED.md b/GETTING_STARTED.md index d33d7bb..0109462 100644 --- a/GETTING_STARTED.md +++ b/GETTING_STARTED.md @@ -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 ------ diff --git a/lib/factory_girl/definition_proxy.rb b/lib/factory_girl/definition_proxy.rb index 36eb7c6..bd0f2c0 100644 --- a/lib/factory_girl/definition_proxy.rb +++ b/lib/factory_girl/definition_proxy.rb @@ -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 diff --git a/lib/factory_girl/sequence.rb b/lib/factory_girl/sequence.rb index 65b1d69..ecfeddb 100644 --- a/lib/factory_girl/sequence.rb +++ b/lib/factory_girl/sequence.rb @@ -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 diff --git a/lib/factory_girl/syntax/default.rb b/lib/factory_girl/syntax/default.rb index 863ef04..0f3ec25 100644 --- a/lib/factory_girl/syntax/default.rb +++ b/lib/factory_girl/syntax/default.rb @@ -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) diff --git a/spec/acceptance/sequence_spec.rb b/spec/acceptance/sequence_spec.rb index 4dfc4fa..e3dcaa1 100644 --- a/spec/acceptance/sequence_spec.rb +++ b/spec/acceptance/sequence_spec.rb @@ -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 diff --git a/spec/factory_girl/definition_proxy_spec.rb b/spec/factory_girl/definition_proxy_spec.rb index 3581161..6cf0161 100644 --- a/spec/factory_girl/definition_proxy_spec.rb +++ b/spec/factory_girl/definition_proxy_spec.rb @@ -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 diff --git a/spec/factory_girl/registry_spec.rb b/spec/factory_girl/registry_spec.rb index 3e05048..b32efa1 100644 --- a/spec/factory_girl/registry_spec.rb +++ b/spec/factory_girl/registry_spec.rb @@ -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 diff --git a/spec/factory_girl/sequence_spec.rb b/spec/factory_girl/sequence_spec.rb index 8b9251a..dab5cb3 100644 --- a/spec/factory_girl/sequence_spec.rb +++ b/spec/factory_girl/sequence_spec.rb @@ -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 }