factory_girl 2.0.5 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
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