factory_girl 2.0.4 → 2.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. data/CONTRIBUTION_GUIDELINES.md +1 -0
  2. data/GETTING_STARTED.md +28 -4
  3. data/Gemfile +2 -1
  4. data/Gemfile.lock +6 -2
  5. data/features/factory_girl_steps.feature +17 -0
  6. data/features/step_definitions/database_steps.rb +22 -0
  7. data/features/support/factories.rb +13 -0
  8. data/features/support/test.db +0 -0
  9. data/lib/factory_girl/aliases.rb +1 -3
  10. data/lib/factory_girl/attribute.rb +16 -8
  11. data/lib/factory_girl/attribute/association.rb +0 -3
  12. data/lib/factory_girl/attribute/callback.rb +0 -2
  13. data/lib/factory_girl/attribute/dynamic.rb +1 -3
  14. data/lib/factory_girl/attribute/static.rb +1 -1
  15. data/lib/factory_girl/attribute_list.rb +30 -9
  16. data/lib/factory_girl/factory.rb +1 -1
  17. data/lib/factory_girl/proxy.rb +7 -5
  18. data/lib/factory_girl/proxy/attributes_for.rb +8 -3
  19. data/lib/factory_girl/proxy/build.rb +12 -3
  20. data/lib/factory_girl/proxy/stub.rb +12 -3
  21. data/lib/factory_girl/sequence.rb +2 -2
  22. data/lib/factory_girl/step_definitions.rb +3 -2
  23. data/lib/factory_girl/version.rb +1 -1
  24. data/spec/acceptance/attribute_aliases_spec.rb +0 -1
  25. data/spec/acceptance/attributes_for_spec.rb +0 -1
  26. data/spec/acceptance/attributes_ordered_spec.rb +24 -6
  27. data/spec/acceptance/build_list_spec.rb +0 -1
  28. data/spec/acceptance/build_spec.rb +0 -1
  29. data/spec/acceptance/build_stubbed_spec.rb +0 -1
  30. data/spec/acceptance/callbacks_spec.rb +0 -1
  31. data/spec/acceptance/create_list_spec.rb +0 -1
  32. data/spec/acceptance/create_spec.rb +0 -1
  33. data/spec/acceptance/default_strategy_spec.rb +0 -1
  34. data/spec/acceptance/definition_spec.rb +0 -1
  35. data/spec/acceptance/definition_without_block_spec.rb +0 -1
  36. data/spec/acceptance/overrides_spec.rb +0 -1
  37. data/spec/acceptance/parent_spec.rb +18 -1
  38. data/spec/acceptance/sequence_spec.rb +0 -1
  39. data/spec/acceptance/syntax/blueprint_spec.rb +0 -1
  40. data/spec/acceptance/syntax/generate_spec.rb +0 -1
  41. data/spec/acceptance/syntax/make_spec.rb +0 -1
  42. data/spec/acceptance/syntax/sham_spec.rb +0 -1
  43. data/spec/acceptance/syntax/vintage_spec.rb +27 -29
  44. data/spec/acceptance/traits_spec.rb +0 -1
  45. data/spec/acceptance/transient_attributes_spec.rb +68 -0
  46. data/spec/factory_girl/aliases_spec.rb +19 -21
  47. data/spec/factory_girl/attribute/association_spec.rb +16 -24
  48. data/spec/factory_girl/attribute/callback_spec.rb +14 -15
  49. data/spec/factory_girl/attribute/dynamic_spec.rb +41 -45
  50. data/spec/factory_girl/attribute/implicit_spec.rb +18 -30
  51. data/spec/factory_girl/attribute/sequence_spec.rb +11 -13
  52. data/spec/factory_girl/attribute/static_spec.rb +13 -20
  53. data/spec/factory_girl/attribute_list_spec.rb +9 -1
  54. data/spec/factory_girl/attribute_spec.rb +17 -28
  55. data/spec/factory_girl/definition_proxy_spec.rb +131 -82
  56. data/spec/factory_girl/deprecated_spec.rb +15 -36
  57. data/spec/factory_girl/factory_spec.rb +106 -135
  58. data/spec/factory_girl/find_definitions_spec.rb +7 -6
  59. data/spec/factory_girl/proxy/attributes_for_spec.rb +23 -32
  60. data/spec/factory_girl/proxy/build_spec.rb +6 -80
  61. data/spec/factory_girl/proxy/create_spec.rb +24 -89
  62. data/spec/factory_girl/proxy/stub_spec.rb +14 -73
  63. data/spec/factory_girl/proxy_spec.rb +53 -53
  64. data/spec/factory_girl/registry_spec.rb +13 -29
  65. data/spec/factory_girl/sequence_spec.rb +24 -72
  66. data/spec/factory_girl_spec.rb +10 -5
  67. data/spec/spec_helper.rb +5 -79
  68. data/spec/support/macros/define_constant.rb +86 -0
  69. data/spec/support/shared_examples/proxy.rb +99 -0
  70. metadata +34 -20
  71. data/spec/acceptance/acceptance_helper.rb +0 -11
@@ -1,10 +1,16 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe FactoryGirl::Registry do
4
- let(:factory) { FactoryGirl::Factory.new(:object) }
4
+ let(:aliases) { [:thing, :widget] }
5
+ let(:sequence) { FactoryGirl::Sequence.new(:email) { |n| "somebody#{n}@example.com" } }
6
+ let(:factory) { FactoryGirl::Factory.new(:object) }
7
+ let(:other_factory) { FactoryGirl::Factory.new(:string) }
8
+ let(:factory_with_aliases) { FactoryGirl::Factory.new(:string, :aliases => aliases) }
5
9
 
6
10
  subject { FactoryGirl::Registry.new }
7
11
 
12
+ it { should be_kind_of(Enumerable) }
13
+
8
14
  it "finds a registered a factory" do
9
15
  subject.add(factory)
10
16
  subject.find(factory.name).should == factory
@@ -38,33 +44,18 @@ describe FactoryGirl::Registry do
38
44
  end
39
45
 
40
46
  it "iterates registered factories" do
41
- other_factory = FactoryGirl::Factory.new(:string)
42
47
  subject.add(factory)
43
48
  subject.add(other_factory)
44
- result = []
45
-
46
- subject.each do |value|
47
- result << value
48
- end
49
-
50
- result.should =~ [factory, other_factory]
49
+ subject.to_a.should =~ [factory, other_factory]
51
50
  end
52
51
 
53
52
  it "iterates registered factories uniquely with aliases" do
54
- other_factory = FactoryGirl::Factory.new(:string, :aliases => [:awesome])
55
53
  subject.add(factory)
56
- subject.add(other_factory)
57
- result = []
58
-
59
- subject.each do |value|
60
- result << value
61
- end
62
-
63
- result.should =~ [factory, other_factory]
54
+ subject.add(factory_with_aliases)
55
+ subject.to_a.should =~ [factory, factory_with_aliases]
64
56
  end
65
57
 
66
58
  it "registers an sequence" do
67
- sequence = FactoryGirl::Sequence.new(:email) { |n| "somebody#{n}@example.com" }
68
59
  subject.add(sequence)
69
60
  subject.find(:email).should == sequence
70
61
  end
@@ -75,22 +66,15 @@ describe FactoryGirl::Registry do
75
66
  end
76
67
 
77
68
  it "registers aliases" do
78
- aliases = [:thing, :widget]
79
- factory = FactoryGirl::Factory.new(:object, :aliases => aliases)
80
- subject.add(factory)
69
+ subject.add(factory_with_aliases)
81
70
  aliases.each do |name|
82
- subject.find(name).should == factory
71
+ subject.find(name).should == factory_with_aliases
83
72
  end
84
73
  end
85
74
 
86
- it "is enumerable" do
87
- should be_kind_of(Enumerable)
88
- end
89
-
90
75
  it "clears registered factories" do
91
76
  subject.add(factory)
92
77
  subject.clear
93
- subject.count.should == 0
78
+ subject.count.should be_zero
94
79
  end
95
80
  end
96
-
@@ -2,95 +2,47 @@ require 'spec_helper'
2
2
 
3
3
  describe FactoryGirl::Sequence do
4
4
  describe "a basic sequence" do
5
- before do
6
- @name = :test
7
- @sequence = FactoryGirl::Sequence.new(@name) {|n| "=#{n}" }
8
- end
9
-
10
- it "has a name" do
11
- @sequence.name.should == @name
12
- end
5
+ let(:name) { :test }
6
+ subject { FactoryGirl::Sequence.new(name) {|n| "=#{n}" } }
13
7
 
14
- it "has names" do
15
- @sequence.names.should == [@name]
16
- end
17
-
18
- it "should start with a value of 1" do
19
- @sequence.next.should == "=1"
20
- end
8
+ its(:name) { should == name }
9
+ its(:names) { should == [name] }
10
+ its(:next) { should == "=1" }
11
+ its(:default_strategy) { should == :create }
21
12
 
22
- it "responds to default_strategy" do
23
- @sequence.default_strategy.should == :create
24
- end
25
-
26
- describe "after being called" do
27
- before do
28
- @sequence.next
29
- end
30
-
31
- it "should use the next value" do
32
- @sequence.next.should == "=2"
33
- end
13
+ describe "when incrementing" do
14
+ before { subject.next }
15
+ its(:next) { should == "=2" }
34
16
  end
35
17
  end
36
18
 
37
19
  describe "a custom sequence" do
38
- before do
39
- @sequence = FactoryGirl::Sequence.new(:name, "A") {|n| "=#{n}" }
40
- end
20
+ subject { FactoryGirl::Sequence.new(:name, "A") {|n| "=#{n}" } }
21
+ its(:next) { should == "=A" }
41
22
 
42
- it "should start with a value of A" do
43
- @sequence.next.should == "=A"
44
- end
45
-
46
- describe "after being called" do
47
- before do
48
- @sequence.next
49
- end
50
-
51
- it "should use the next value" do
52
- @sequence.next.should == "=B"
53
- end
23
+ describe "when incrementing" do
24
+ before { subject.next }
25
+ its(:next) { should == "=B" }
54
26
  end
55
27
  end
56
28
 
57
29
  describe "a basic sequence without a block" do
58
- before do
59
- @sequence = FactoryGirl::Sequence.new(:name)
60
- end
61
-
62
- it "should start with a value of 1" do
63
- @sequence.next.should == 1
64
- end
30
+ subject { FactoryGirl::Sequence.new(:name) }
31
+ its(:next) { should == 1 }
65
32
 
66
- describe "after being called" do
67
- before do
68
- @sequence.next
69
- end
70
-
71
- it "should use the next value" do
72
- @sequence.next.should == 2
73
- end
33
+ describe "when incrementing" do
34
+ before { subject.next }
35
+ its(:next) { should == 2 }
74
36
  end
75
37
  end
76
38
 
77
39
  describe "a custom sequence without a block" do
78
- before do
79
- @sequence = FactoryGirl::Sequence.new(:name, "A")
80
- end
81
-
82
- it "should start with a value of A" do
83
- @sequence.next.should == "A"
84
- end
85
-
86
- describe "after being called" do
87
- before do
88
- @sequence.next
89
- end
40
+ subject { FactoryGirl::Sequence.new(:name, "A") }
41
+ its(:next) { should == "A" }
90
42
 
91
- it "should use the next value" do
92
- @sequence.next.should == "B"
93
- end
43
+ describe "when incrementing" do
44
+ before { subject.next }
45
+ its(:next) { should == "B" }
94
46
  end
95
47
  end
96
48
  end
@@ -1,17 +1,22 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  describe FactoryGirl do
4
- let(:factory) { FactoryGirl::Factory.new(:object) }
4
+ let(:factory) { FactoryGirl::Factory.new(:object) }
5
5
  let(:sequence) { FactoryGirl::Sequence.new(:email) }
6
+ let(:trait) { FactoryGirl::Trait.new(:admin) }
6
7
 
7
- it "finds a registered a factory" do
8
+ it "finds a registered factory" do
8
9
  FactoryGirl.register_factory(factory)
9
10
  FactoryGirl.factory_by_name(factory.name).should == factory
10
11
  end
11
12
 
12
- it "finds a registered a sequence" do
13
+ it "finds a registered sequence" do
13
14
  FactoryGirl.register_sequence(sequence)
14
15
  FactoryGirl.sequence_by_name(sequence.name).should == sequence
15
16
  end
16
- end
17
17
 
18
+ it "finds a registered trait" do
19
+ FactoryGirl.register_trait(trait)
20
+ FactoryGirl.trait_by_name(trait.name).should == trait
21
+ end
22
+ end
@@ -4,93 +4,19 @@ $LOAD_PATH << File.join(File.dirname(__FILE__))
4
4
  require 'rubygems'
5
5
  require 'rspec'
6
6
  require 'rspec/autorun'
7
- require 'rr'
8
7
 
9
8
  require 'factory_girl'
9
+ require "mocha"
10
+ require "bourne"
10
11
 
11
- module RR
12
- module Adapters
13
- module Rspec
14
- def self.included(mod)
15
- RSpec.configuration.backtrace_clean_patterns.push(RR::Errors::BACKTRACE_IDENTIFIER)
16
- end
17
- end
18
- end
19
- end
12
+ Dir["spec/support/**/*.rb"].each { |f| require File.expand_path(f) }
20
13
 
21
14
  RSpec.configure do |config|
22
- config.mock_framework = :rr
23
- RSpec::Core::ExampleGroup.send(:include, RR::Adapters::Rspec)
15
+ config.mock_framework = :mocha
16
+
24
17
  config.after do
25
18
  FactoryGirl.factories.clear
26
19
  FactoryGirl.sequences.clear
27
20
  FactoryGirl.traits.clear
28
21
  end
29
22
  end
30
-
31
- module DefinesConstants
32
- def self.included(example_group)
33
- example_group.class_eval do
34
- before do
35
- @defined_constants ||= []
36
- @created_tables ||= []
37
- end
38
-
39
- after do
40
- @defined_constants.reverse.each do |path|
41
- namespace, class_name = *constant_path(path)
42
- namespace.send(:remove_const, class_name)
43
- end
44
- @defined_constants.clear
45
-
46
- @created_tables.each do |table_name|
47
- ActiveRecord::Base.
48
- connection.
49
- execute("DROP TABLE IF EXISTS #{table_name}")
50
- end
51
- @created_tables.clear
52
- end
53
-
54
- def define_class(path, base = Object, &block)
55
- namespace, class_name = *constant_path(path)
56
- klass = Class.new(base)
57
- namespace.const_set(class_name, klass)
58
- klass.class_eval(&block) if block_given?
59
- @defined_constants << path
60
- klass
61
- end
62
-
63
- def define_model(name, columns = {}, &block)
64
- model = define_class(name, ActiveRecord::Base, &block)
65
- create_table(model.table_name) do |table|
66
- columns.each do |name, type|
67
- table.column name, type
68
- end
69
- end
70
- model
71
- end
72
-
73
- def create_table(table_name, &block)
74
- connection = ActiveRecord::Base.connection
75
-
76
- begin
77
- connection.execute("DROP TABLE IF EXISTS #{table_name}")
78
- connection.create_table(table_name, &block)
79
- @created_tables << table_name
80
- connection
81
- rescue Exception => exception
82
- connection.execute("DROP TABLE IF EXISTS #{table_name}")
83
- raise exception
84
- end
85
- end
86
-
87
- def constant_path(constant_name)
88
- names = constant_name.split('::')
89
- class_name = names.pop
90
- namespace = names.inject(Object) { |result, name| result.const_get(name) }
91
- [namespace, class_name]
92
- end
93
- end
94
- end
95
- end
96
-
@@ -0,0 +1,86 @@
1
+ require 'active_record'
2
+
3
+ module DefineConstantMacros
4
+ def define_class(path, base = Object, &block)
5
+ namespace, class_name = *constant_path(path)
6
+ klass = Class.new(base)
7
+ namespace.const_set(class_name, klass)
8
+ klass.class_eval(&block) if block_given?
9
+ @defined_constants << path
10
+ klass
11
+ end
12
+
13
+ def define_model(name, columns = {}, &block)
14
+ model = define_class(name, ActiveRecord::Base, &block)
15
+ create_table(model.table_name) do |table|
16
+ columns.each do |name, type|
17
+ table.column name, type
18
+ end
19
+ end
20
+ model
21
+ end
22
+
23
+ def create_table(table_name, &block)
24
+ connection = ActiveRecord::Base.connection
25
+
26
+ begin
27
+ connection.execute("DROP TABLE IF EXISTS #{table_name}")
28
+ connection.create_table(table_name, &block)
29
+ @created_tables << table_name
30
+ connection
31
+ rescue Exception => exception
32
+ connection.execute("DROP TABLE IF EXISTS #{table_name}")
33
+ raise exception
34
+ end
35
+ end
36
+
37
+ def constant_path(constant_name)
38
+ names = constant_name.split('::')
39
+ class_name = names.pop
40
+ namespace = names.inject(Object) { |result, name| result.const_get(name) }
41
+ [namespace, class_name]
42
+ end
43
+
44
+ def default_constants
45
+ @defined_constants ||= []
46
+ @created_tables ||= []
47
+ end
48
+
49
+ def clear_generated_constants
50
+ @defined_constants.reverse.each do |path|
51
+ namespace, class_name = *constant_path(path)
52
+ namespace.send(:remove_const, class_name)
53
+ end
54
+
55
+ @defined_constants.clear
56
+ end
57
+
58
+ def clear_generated_tables
59
+ @created_tables.each do |table_name|
60
+ ActiveRecord::Base.
61
+ connection.
62
+ execute("DROP TABLE IF EXISTS #{table_name}")
63
+ end
64
+ @created_tables.clear
65
+ end
66
+ end
67
+
68
+ RSpec.configure do |config|
69
+ config.include DefineConstantMacros
70
+
71
+ config.before(:all) do
72
+ ActiveRecord::Base.establish_connection(
73
+ :adapter => 'sqlite3',
74
+ :database => File.join(File.dirname(__FILE__), 'test.db')
75
+ )
76
+ end
77
+
78
+ config.before do
79
+ default_constants
80
+ end
81
+
82
+ config.after do
83
+ clear_generated_constants
84
+ clear_generated_tables
85
+ end
86
+ end
@@ -0,0 +1,99 @@
1
+ shared_examples_for "proxy without association support" do
2
+ it "doesn't raise when asked to associate with another factory" do
3
+ expect { subject.associate(:owner, :user, {}) }.to_not raise_error
4
+ end
5
+
6
+ it "does not call FactoryGirl.create when building an association" do
7
+ FactoryGirl.stubs(:create)
8
+ subject.association(:user)
9
+ FactoryGirl.should have_received(:create).never
10
+ end
11
+
12
+ it "returns nil when building an association" do
13
+ subject.set(:association, 'x')
14
+ subject.association(:user).should be_nil
15
+ end
16
+ end
17
+
18
+ shared_examples_for "proxy with association support" do |factory_girl_proxy_class|
19
+ let(:factory_name) { :user }
20
+ let(:association_name) { :owner }
21
+ let(:factory) { stub("associate_factory") }
22
+ let(:overrides) { { :one => 1, :two => 2 } }
23
+
24
+ before do
25
+ FactoryGirl.stubs(:factory_by_name => factory)
26
+ instance.stubs(association_name => factory_name)
27
+ factory.stubs(:run => factory_name)
28
+ subject.stubs(:set)
29
+ end
30
+
31
+ it "sets a value for the association" do
32
+ subject.associate(association_name, factory_name, {})
33
+ subject.result(nil).send(association_name).should == factory_name
34
+ end
35
+
36
+ it "sets the association attribute as the factory" do
37
+ subject.associate(association_name, factory_name, {})
38
+ subject.should have_received(:set).with(association_name, factory_name)
39
+ end
40
+
41
+ it "runs the factory with the correct proxy class" do
42
+ subject.associate(association_name, factory_name, {})
43
+ factory.should have_received(:run).with(factory_girl_proxy_class, {})
44
+ end
45
+
46
+ it "runs the factory with the correct proxy class and overrides" do
47
+ subject.associate(association_name, factory_name, overrides)
48
+ factory.should have_received(:run).with(factory_girl_proxy_class, overrides)
49
+ end
50
+ end
51
+
52
+ shared_examples_for "proxy with standard getters and setters" do |attribute, value|
53
+ before do
54
+ instance.stubs(:"#{attribute}=" => value, :"#{attribute}" => value)
55
+ end
56
+
57
+ describe "when setting an attribute" do
58
+ before do
59
+ subject.set(attribute, value)
60
+ end
61
+
62
+ its(attribute) { should == value }
63
+ it { instance.should have_received(:"#{attribute}=").with(value) }
64
+ end
65
+
66
+ describe "when setting an ignored attribute" do
67
+ before do
68
+ subject.set(attribute, value, true)
69
+ end
70
+
71
+ it { instance.should have_received(:"#{attribute}=").with(value).never }
72
+ end
73
+
74
+ describe "when getting an attribute" do
75
+ it { subject.get(attribute).should == value }
76
+
77
+ it "retrieves the value from the instance" do
78
+ subject.get(attribute)
79
+ instance.should have_received(:"#{attribute}")
80
+ end
81
+ end
82
+ end
83
+
84
+ shared_examples_for "proxy with callbacks" do |callback_name|
85
+ let(:callback) { stub("#{callback_name} callback", :foo => nil) }
86
+
87
+ before do
88
+ subject.add_callback(callback_name, proc { callback.foo })
89
+ end
90
+
91
+ it "runs the #{callback_name} callback" do
92
+ subject.result(nil)
93
+ callback.should have_received(:foo).once
94
+ end
95
+
96
+ it "returns the proxy instance" do
97
+ subject.result(nil).should == instance
98
+ end
99
+ end