factory_girl 2.0.5 → 2.1.0

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 (44) hide show
  1. data/.autotest +9 -0
  2. data/.gitignore +8 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +10 -0
  5. data/.yardopts +5 -0
  6. data/Appraisals +3 -0
  7. data/GETTING_STARTED.md +67 -8
  8. data/Gemfile +2 -11
  9. data/Gemfile.lock +51 -34
  10. data/README.md +3 -1
  11. data/cucumber.yml +1 -0
  12. data/features/find_definitions.feature +21 -8
  13. data/features/step_definitions/factory_girl_steps.rb +4 -4
  14. data/gemfiles/2.1.gemfile +8 -0
  15. data/gemfiles/2.1.gemfile.lock +73 -0
  16. data/gemfiles/2.3.gemfile +7 -0
  17. data/gemfiles/2.3.gemfile.lock +71 -0
  18. data/gemfiles/3.0.gemfile +7 -0
  19. data/gemfiles/3.0.gemfile.lock +81 -0
  20. data/gemfiles/3.1.gemfile +7 -0
  21. data/gemfiles/3.1.gemfile.lock +91 -0
  22. data/lib/factory_girl.rb +1 -0
  23. data/lib/factory_girl/attribute.rb +4 -0
  24. data/lib/factory_girl/attribute_list.rb +35 -13
  25. data/lib/factory_girl/factory.rb +36 -9
  26. data/lib/factory_girl/proxy/build.rb +21 -2
  27. data/lib/factory_girl/proxy/create.rb +6 -0
  28. data/lib/factory_girl/proxy/stub.rb +10 -2
  29. data/lib/factory_girl/rails2.rb +1 -0
  30. data/lib/factory_girl/reload.rb +8 -0
  31. data/lib/factory_girl/syntax/default.rb +16 -0
  32. data/lib/factory_girl/version.rb +1 -1
  33. data/spec/acceptance/build_spec.rb +31 -0
  34. data/spec/acceptance/create_spec.rb +27 -1
  35. data/spec/acceptance/modify_factories_spec.rb +184 -0
  36. data/spec/acceptance/stub_spec.rb +64 -0
  37. data/spec/factory_girl/attribute_list_spec.rb +54 -2
  38. data/spec/factory_girl/factory_spec.rb +6 -4
  39. data/spec/factory_girl/proxy/build_spec.rb +24 -0
  40. data/spec/factory_girl/proxy/stub_spec.rb +14 -0
  41. data/spec/spec_helper.rb +1 -0
  42. data/spec/support/shared_examples/proxy.rb +29 -0
  43. metadata +109 -57
  44. data/features/support/test.db +0 -0
@@ -23,19 +23,38 @@ module FactoryGirl
23
23
  end
24
24
 
25
25
  def associate(name, factory_name, overrides)
26
+ method = get_method(overrides[:method])
26
27
  factory = FactoryGirl.factory_by_name(factory_name)
27
- set(name, factory.run(Proxy::Create, overrides))
28
+ set(name, factory.run(method, remove_method(overrides)))
28
29
  end
29
30
 
30
31
  def association(factory_name, overrides = {})
32
+ method = get_method(overrides[:method])
31
33
  factory = FactoryGirl.factory_by_name(factory_name)
32
- factory.run(Proxy::Create, overrides)
34
+ factory.run(method, remove_method(overrides))
35
+ end
36
+
37
+ def remove_method(overrides)
38
+ overrides.dup.delete_if {|key, value| key == :method}
33
39
  end
34
40
 
35
41
  def result(to_create)
36
42
  run_callbacks(:after_build)
37
43
  @instance
38
44
  end
45
+
46
+ def parse_method(method)
47
+ method ||= :create
48
+ if :build == method
49
+ return Proxy::Build
50
+ elsif :create == method
51
+ return Proxy::Create
52
+ else
53
+ raise "unrecognized method #{method}"
54
+ end
55
+ end
56
+
57
+ alias_method :get_method, :parse_method
39
58
  end
40
59
  end
41
60
  end
@@ -11,6 +11,12 @@ module FactoryGirl
11
11
  run_callbacks(:after_create)
12
12
  @instance
13
13
  end
14
+
15
+ def get_method(method_string)
16
+ # Leaving this as Proxy::Build in the :method => :build case
17
+ # is a bit strange, but does it have any user-visible behaviors?
18
+ parse_method(method_string)
19
+ end
14
20
  end
15
21
  end
16
22
  end
@@ -12,6 +12,10 @@ module FactoryGirl
12
12
  !new_record?
13
13
  end
14
14
 
15
+ def created_at
16
+ @created_at ||= Time.now
17
+ end
18
+
15
19
  def new_record?
16
20
  id.nil?
17
21
  end
@@ -60,12 +64,16 @@ module FactoryGirl
60
64
 
61
65
  def associate(name, factory_name, overrides)
62
66
  factory = FactoryGirl.factory_by_name(factory_name)
63
- set(name, factory.run(Proxy::Stub, overrides))
67
+ set(name, factory.run(Proxy::Stub, remove_method(overrides)))
64
68
  end
65
69
 
66
70
  def association(factory_name, overrides = {})
67
71
  factory = FactoryGirl.factory_by_name(factory_name)
68
- factory.run(Proxy::Stub, overrides)
72
+ factory.run(Proxy::Stub, remove_method(overrides))
73
+ end
74
+
75
+ def remove_method(overrides)
76
+ overrides.dup.delete_if {|key, value| key == :method}
69
77
  end
70
78
 
71
79
  def result(to_create)
@@ -1,5 +1,6 @@
1
1
  Rails.configuration.after_initialize do
2
2
  FactoryGirl.definition_file_paths = [
3
+ File.join(Rails.root, 'factories'),
3
4
  File.join(Rails.root, 'test', 'factories'),
4
5
  File.join(Rails.root, 'spec', 'factories')
5
6
  ]
@@ -0,0 +1,8 @@
1
+ module FactoryGirl
2
+ def self.reload
3
+ self.factories.clear
4
+ self.sequences.clear
5
+ self.traits.clear
6
+ self.find_definitions
7
+ end
8
+ end
@@ -7,6 +7,10 @@ module FactoryGirl
7
7
  DSL.run(block)
8
8
  end
9
9
 
10
+ def modify(&block)
11
+ ModifyDSL.run(block)
12
+ end
13
+
10
14
  class DSL
11
15
  def self.run(block)
12
16
  new.instance_eval(&block)
@@ -39,6 +43,18 @@ module FactoryGirl
39
43
  FactoryGirl.register_trait(Trait.new(name, &block))
40
44
  end
41
45
  end
46
+
47
+ class ModifyDSL
48
+ def self.run(block)
49
+ new.instance_eval(&block)
50
+ end
51
+
52
+ def factory(name, options = {}, &block)
53
+ factory = FactoryGirl.factory_by_name(name).allow_overrides
54
+ proxy = FactoryGirl::DefinitionProxy.new(factory)
55
+ proxy.instance_eval(&block)
56
+ end
57
+ end
42
58
  end
43
59
  end
44
60
 
@@ -1,4 +1,4 @@
1
1
  module FactoryGirl
2
- VERSION = "2.0.5"
2
+ VERSION = "2.1.0"
3
3
  end
4
4
 
@@ -31,3 +31,34 @@ describe "a built instance" do
31
31
  end
32
32
  end
33
33
 
34
+ describe "a built instance with :method => :build" do
35
+ include FactoryGirl::Syntax::Methods
36
+
37
+ before do
38
+ define_model('User')
39
+
40
+ define_model('Post', :user_id => :integer) do
41
+ belongs_to :user
42
+ end
43
+
44
+ FactoryGirl.define do
45
+ factory :user
46
+
47
+ factory :post do
48
+ association(:user, :method => :build)
49
+ end
50
+ end
51
+ end
52
+
53
+ subject { build(:post) }
54
+
55
+ it "isn't saved" do
56
+ should be_new_record
57
+ end
58
+
59
+ it "assigns but does not save associations" do
60
+ subject.user.should be_kind_of(User)
61
+ subject.user.should be_new_record
62
+ end
63
+
64
+ end
@@ -31,6 +31,33 @@ describe "a created instance" do
31
31
  end
32
32
  end
33
33
 
34
+ describe "a created instance, specifying :method => build" do
35
+ include FactoryGirl::Syntax::Methods
36
+
37
+ before do
38
+ define_model('User')
39
+
40
+ define_model('Post', :user_id => :integer) do
41
+ belongs_to :user
42
+ end
43
+
44
+ FactoryGirl.define do
45
+ factory :user
46
+
47
+ factory :post do
48
+ association(:user, :method => :build)
49
+ end
50
+ end
51
+ end
52
+
53
+ subject { create('post') }
54
+
55
+ it "still saves associations (:method => :build only affects build, not create)" do
56
+ subject.user.should be_kind_of(User)
57
+ subject.user.should_not be_new_record
58
+ end
59
+ end
60
+
34
61
  describe "a custom create" do
35
62
  include FactoryGirl::Syntax::Methods
36
63
 
@@ -62,4 +89,3 @@ describe "a custom create" do
62
89
  FactoryGirl.create(:user).should be_persisted
63
90
  end
64
91
  end
65
-
@@ -0,0 +1,184 @@
1
+ require "spec_helper"
2
+
3
+ describe "modifying factories" do
4
+ include FactoryGirl::Syntax::Methods
5
+
6
+ before do
7
+ define_model('User', :name => :string, :admin => :boolean, :email => :string, :login => :string)
8
+
9
+ FactoryGirl.define do
10
+ sequence(:email) {|n| "user#{n}@example.com" }
11
+
12
+ factory :user do
13
+ email
14
+
15
+ after_create do |user|
16
+ user.login = user.name.upcase if user.name
17
+ end
18
+
19
+ factory :admin do
20
+ admin true
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ context "simple modification" do
27
+ before do
28
+ FactoryGirl.modify do
29
+ factory :user do
30
+ name "Great User"
31
+ end
32
+ end
33
+ end
34
+
35
+ subject { create(:user) }
36
+ its(:name) { should == "Great User" }
37
+ its(:login) { should == "GREAT USER" }
38
+
39
+ it "doesn't allow the factory to be subsequently defined" do
40
+ expect do
41
+ FactoryGirl.define { factory :user }
42
+ end.to raise_error(FactoryGirl::DuplicateDefinitionError)
43
+ end
44
+
45
+ it "does allow the factory to be subsequently modified" do
46
+ FactoryGirl.modify do
47
+ factory :user do
48
+ name "Overridden again!"
49
+ end
50
+ end
51
+
52
+ create(:user).name.should == "Overridden again!"
53
+ end
54
+ end
55
+
56
+ context "adding callbacks" do
57
+ before do
58
+ FactoryGirl.modify do
59
+ factory :user do
60
+ name "Great User"
61
+ after_create do |user|
62
+ user.name = user.name.downcase
63
+ user.login = nil
64
+ end
65
+ end
66
+ end
67
+ end
68
+
69
+ subject { create(:user) }
70
+
71
+ its(:name) { should == "great user" }
72
+ its(:login) { should be_nil }
73
+ end
74
+
75
+ context "reusing traits" do
76
+ before do
77
+ FactoryGirl.define do
78
+ trait :rockstar do
79
+ name "Johnny Rockstar!!!"
80
+ end
81
+ end
82
+
83
+ FactoryGirl.modify do
84
+ factory :user do
85
+ rockstar
86
+ email { "#{name}@example.com" }
87
+ end
88
+ end
89
+ end
90
+
91
+ subject { create(:user) }
92
+
93
+ its(:name) { should == "Johnny Rockstar!!!" }
94
+ its(:email) { should == "Johnny Rockstar!!!@example.com" }
95
+ its(:login) { should == "JOHNNY ROCKSTAR!!!" }
96
+ end
97
+
98
+ context "redefining attributes" do
99
+ before do
100
+ FactoryGirl.modify do
101
+ factory :user do
102
+ email { "#{name}-modified@example.com" }
103
+ name "Great User"
104
+ end
105
+ end
106
+ end
107
+
108
+ context "creating user" do
109
+ context "without overrides" do
110
+ subject { create(:user) }
111
+
112
+ its(:name) { should == "Great User" }
113
+ its(:email) { should == "Great User-modified@example.com" }
114
+ end
115
+
116
+ context "overriding dynamic attributes" do
117
+ subject { create(:user, :email => "perfect@example.com") }
118
+
119
+ its(:name) { should == "Great User" }
120
+ its(:email) { should == "perfect@example.com" }
121
+ end
122
+
123
+ context "overriding static attributes" do
124
+ subject { create(:user, :name => "wonderful") }
125
+
126
+ its(:name) { should == "wonderful" }
127
+ its(:email) { should == "wonderful-modified@example.com" }
128
+ end
129
+ end
130
+
131
+ context "creating admin" do
132
+ context "without overrides" do
133
+ subject { create(:admin) }
134
+
135
+ its(:name) { should == "Great User" }
136
+ its(:email) { should == "Great User-modified@example.com" }
137
+ its(:admin) { should be_true }
138
+ end
139
+
140
+ context "overriding dynamic attributes" do
141
+ subject { create(:admin, :email => "perfect@example.com") }
142
+
143
+ its(:name) { should == "Great User" }
144
+ its(:email) { should == "perfect@example.com" }
145
+ its(:admin) { should be_true }
146
+ end
147
+
148
+ context "overriding static attributes" do
149
+ subject { create(:admin, :name => "wonderful") }
150
+
151
+ its(:name) { should == "wonderful" }
152
+ its(:email) { should == "wonderful-modified@example.com" }
153
+ its(:admin) { should be_true }
154
+ end
155
+ end
156
+ end
157
+
158
+ it "doesn't overwrite already defined child's attributes" do
159
+ FactoryGirl.modify do
160
+ factory :user do
161
+ admin false
162
+ end
163
+ end
164
+ create(:admin).should be_admin
165
+ end
166
+
167
+ it "allows for overriding child classes" do
168
+ FactoryGirl.modify do
169
+ factory :admin do
170
+ admin false
171
+ end
172
+ end
173
+
174
+ create(:admin).should_not be_admin
175
+ end
176
+
177
+ it "raises an exception if the factory was not defined before" do
178
+ lambda {
179
+ FactoryGirl.modify do
180
+ factory :unknown_factory
181
+ end
182
+ }.should raise_error(ArgumentError)
183
+ end
184
+ end
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+
3
+ describe "a stubbed instance" do
4
+ include FactoryGirl::Syntax::Methods
5
+
6
+ before do
7
+ define_model('User')
8
+
9
+ define_model('Post', :user_id => :integer) do
10
+ belongs_to :user
11
+ end
12
+
13
+ FactoryGirl.define do
14
+ factory :user
15
+
16
+ factory :post do
17
+ user
18
+ end
19
+ end
20
+ end
21
+
22
+ subject { build_stubbed(:post) }
23
+
24
+ it "acts as if it came from the database" do
25
+ should_not be_new_record
26
+ end
27
+
28
+ it "assigns associations and acts as if it is saved" do
29
+ subject.user.should be_kind_of(User)
30
+ subject.user.should_not be_new_record
31
+ end
32
+ end
33
+
34
+ describe "a stubbed instance with :method => :build" do
35
+ include FactoryGirl::Syntax::Methods
36
+
37
+ before do
38
+ define_model('User')
39
+
40
+ define_model('Post', :user_id => :integer) do
41
+ belongs_to :user
42
+ end
43
+
44
+ FactoryGirl.define do
45
+ factory :user
46
+
47
+ factory :post do
48
+ association(:user, :method => :build)
49
+ end
50
+ end
51
+ end
52
+
53
+ subject { build_stubbed(:post) }
54
+
55
+ it "acts as if it is saved in the database" do
56
+ should_not be_new_record
57
+ end
58
+
59
+ it "assigns associations and acts as if it is saved" do
60
+ subject.user.should be_kind_of(User)
61
+ subject.user.should_not be_new_record
62
+ end
63
+
64
+ end