Skip to content
This repository
Browse code

Prep for FactoryGirl 4.0

  • Loading branch information...
commit e9d9e3099b65e08ae18988c8f3f9a39b09a60902 1 parent 8d2f517
Joshua Clayton authored

Showing 27 changed files with 50 additions and 1,443 deletions. Show diff stats Hide diff stats

  1. 78  GETTING_STARTED.md
  2. 6  README.md
  3. 241  features/factory_girl_steps.feature
  4. 37  features/step_definitions/database_steps.rb
  5. 7  features/step_definitions/factory_girl_steps.rb
  6. 125  features/support/factories.rb
  7. 2  lib/factory_girl.rb
  8. 16  lib/factory_girl/attribute_assigner.rb
  9. 12  lib/factory_girl/configuration.rb
  10. 9  lib/factory_girl/decorator/invocation_ignorer.rb
  11. 4  lib/factory_girl/definition_proxy.rb
  12. 151  lib/factory_girl/step_definitions.rb
  13. 11  lib/factory_girl/syntax.rb
  14. 40  lib/factory_girl/syntax/blueprint.rb
  15. 70  lib/factory_girl/syntax/generate.rb
  16. 44  lib/factory_girl/syntax/make.rb
  17. 47  lib/factory_girl/syntax/sham.rb
  18. 130  lib/factory_girl/syntax/vintage.rb
  19. 2  spec/acceptance/global_initialize_with_spec.rb
  20. 44  spec/acceptance/initialize_with_spec.rb
  21. 36  spec/acceptance/syntax/blueprint_spec.rb
  22. 61  spec/acceptance/syntax/generate_spec.rb
  23. 54  spec/acceptance/syntax/make_spec.rb
  24. 43  spec/acceptance/syntax/sham_spec.rb
  25. 219  spec/acceptance/syntax/vintage_spec.rb
  26. 2  spec/acceptance/traits_spec.rb
  27. 2  spec/factory_girl/aliases_spec.rb
78  GETTING_STARTED.md
Source Rendered
@@ -7,13 +7,13 @@ Update Your Gemfile
7 7
 If you're using Rails, you'll need to change the required version of `factory_girl_rails`:
8 8
 
9 9
 ```ruby
10  
-gem "factory_girl_rails", "~> 3.0"
  10
+gem "factory_girl_rails", "~> 4.0"
11 11
 ```
12 12
 
13 13
 If you're *not* using Rails, you'll just have to change the required version of `factory_girl`:
14 14
 
15 15
 ```ruby
16  
-gem "factory_girl", "~> 3.0"
  16
+gem "factory_girl", "~> 4.0"
17 17
 ```
18 18
 
19 19
 JRuby users: FactoryGirl works with JRuby starting with 1.6.7.2 (latest stable, as per July 2012).
@@ -875,14 +875,41 @@ FactoryGirl.define do
875 875
 end
876 876
 ```
877 877
 
878  
-When using `initialize_with`, attributes accessed from the `initialize_with`
879  
-block are assigned a second time to the instance. Duplicate assignment can be
880  
-disabled by configuring FactoryGirl as such:
  878
+When using `initialize_with`, attributes accessed from within the `initialize_with`
  879
+block are assigned *only* in the constructor; this equates to roughly the
  880
+following code:
881 881
 
882  
-    FactoryGirl.duplicate_attribute_assignment_from_initialize_with = false
  882
+```ruby
  883
+FactoryGirl.define do
  884
+  factory :user do
  885
+    initialize_with { new(name) }
  886
+
  887
+    name { 'value' }
  888
+  end
  889
+end
  890
+
  891
+FactoryGirl.build(:user)
  892
+# runs
  893
+User.new('value')
  894
+```
  895
+
  896
+This prevents duplicate assignment; in versions of FactoryGirl before 4.0, it
  897
+would run this:
883 898
 
884  
-This would allow for attributes declared as ignored to not be ignored, since
885  
-it won't assign them for a second time.
  899
+```ruby
  900
+FactoryGirl.define do
  901
+  factory :user do
  902
+    initialize_with { new(name) }
  903
+
  904
+    name { 'value' }
  905
+  end
  906
+end
  907
+
  908
+FactoryGirl.build(:user)
  909
+# runs
  910
+user = User.new('value')
  911
+user.name = 'value'
  912
+```
886 913
 
887 914
 Custom Strategies
888 915
 -----------------
@@ -1042,38 +1069,3 @@ config.after(:suite) do
1042 1069
   puts @factory_girl_results
1043 1070
 end
1044 1071
 ```
1045  
-
1046  
-Cucumber Integration
1047  
---------------------
1048  
-
1049  
-factory\_girl ships with step definitions that make calling factories from Cucumber easier. To use them, add the following to features/support/env.rb:
1050  
-
1051  
-```ruby
1052  
-require "factory_girl/step_definitions"
1053  
-```
1054  
-
1055  
-Note: These step definitions are _deprecated_. Read why here:
1056  
-http://robots.thoughtbot.com/post/25650434584/writing-better-cucumber-scenarios-or-why-were
1057  
-
1058  
-Alternate Syntaxes
1059  
-------------------
1060  
-
1061  
-Users' tastes for syntax vary dramatically, but most users are looking for a
1062  
-common feature set. Because of this factory\_girl supports "syntax layers" which
1063  
-provide alternate interfaces. See Factory::Syntax for information about the
1064  
-various layers available. For example, the Machinist-style syntax is popular:
1065  
-
1066  
-```ruby
1067  
-require "factory_girl/syntax/blueprint"
1068  
-require "factory_girl/syntax/make"
1069  
-require "factory_girl/syntax/sham"
1070  
-
1071  
-Sham.email {|n| "#{n}@example.com" }
1072  
-
1073  
-User.blueprint do
1074  
-  name  { "Billy Bob" }
1075  
-  email { Sham.email  }
1076  
-end
1077  
-
1078  
-User.make(name: "Johnny")
1079  
-```
6  README.md
Source Rendered
@@ -62,12 +62,6 @@ factory_girl was written by Joe Ferris with contributions from several authors,
62 62
 * Josh Clayton
63 63
 * Thomas Walpole
64 64
 
65  
-The syntax layers are derived from software written by the following authors:
66  
-
67  
-* Pete Yandell
68  
-* Rick Bradley
69  
-* Yossef Mendelssohn
70  
-
71 65
 ![thoughtbot](http://thoughtbot.com/images/tm/logo.png)
72 66
 
73 67
 factory_girl is maintained and funded by [thoughtbot, inc](http://thoughtbot.com/community)
241  features/factory_girl_steps.feature
... ...
@@ -1,241 +0,0 @@
1  
-Feature: Use step definitions generated by factories
2  
-
3  
-  Scenario: create a post and verify its attributes
4  
-    Given the following post exists:
5  
-      | Title       | Body                |
6  
-      | a fun title | here is the content |
7  
-    Then I should find the following for the last post:
8  
-      | title       | body                |
9  
-      | a fun title | here is the content |
10  
-
11  
-  Scenario: create a post and verify its attributes without the trailing colon
12  
-    Given the following post exists
13  
-      | Title       | Body                |
14  
-      | a fun title | here is the content |
15  
-    Then I should find the following for the last post:
16  
-      | title       | body                |
17  
-      | a fun title | here is the content |
18  
-
19  
-  Scenario: create a post without a table and verify its attributes
20  
-    Given a post exists with a title of "a fun title"
21  
-    Then I should find the following for the last post:
22  
-      | title       |
23  
-      | a fun title |
24  
-
25  
-  Scenario: flexible English when creating posts
26  
-    Given an post exists with an title of "a fun title"
27  
-    Then I should find the following for the last post:
28  
-      | title       |
29  
-      | a fun title |
30  
-
31  
-  Scenario: create a post with an underscore in an attribute name
32  
-    Given a post exists with an author ID of "5"
33  
-    Then I should find the following for the last post:
34  
-      | author_id |
35  
-      | 5         |
36  
-
37  
-  Scenario: create several posts
38  
-    Given the following posts exist:
39  
-      | Title | Body   |
40  
-      | one   | first  |
41  
-      | two   | second |
42  
-      | three | third  |
43  
-    Then I should find the following for the last post:
44  
-      | title | body  |
45  
-      | three | third |
46  
-    And there should be 3 posts
47  
-
48  
-  Scenario: create a post with a new author
49  
-    Given the following post exists:
50  
-      | Title   | Author   |
51  
-      | a title | ID: 123  |
52  
-    Then I should find the following for the last post:
53  
-      | title   | author_id |
54  
-      | a title | 123       |
55  
-    And I should find the following for the last user:
56  
-      | id  |
57  
-      | 123 |
58  
-
59  
-  Scenario: create a post with an existing author
60  
-    Given the following user exists:
61  
-      | ID  | Name |
62  
-      | 123 | Joe  |
63  
-    And the following post exists:
64  
-      | Title   | Author    |
65  
-      | a title | Name: Joe |
66  
-    Then I should find the following for the last post:
67  
-      | title   | author_id |
68  
-      | a title | 123       |
69  
-    And there should be 1 user
70  
-
71  
-  Scenario: create a titled post with a new author (inherited association)
72  
-    Given the following titled post exists:
73  
-      | Title               | Author  |
74  
-      | A Post with a Title | ID: 123 |
75  
-    Then I should find the following for the last post:
76  
-      | title               | author_id |
77  
-      | A Post with a Title | 123       |
78  
-
79  
-  Scenario: create post with and without a category association
80  
-    Given the following users exist:
81  
-      | ID  | Name |
82  
-      | 123 | Joe  |
83  
-    And the following posts exist:
84  
-      | Title                      | Author    | Category          |
85  
-      | a title                    | Name: Joe | Name: programming |
86  
-      | a title without a category | Name: Joe |                   |
87  
-    Then I should find the following for the last post:
88  
-      | title                      | category_id |
89  
-      | a title without a category |             |
90  
-
91  
-  Scenario: create a user without attributes
92  
-    Given a user exists
93  
-    Then there should be 1 user
94  
-
95  
-  Scenario: create several users without attributes
96  
-    Given 3 users exist
97  
-    Then there should be 3 users
98  
-
99  
-  Scenario: create several users with one attribute
100  
-    Given 3 users exist with a name of "John"
101  
-    Then there should be 3 users
102  
-    And I should find the following for the last user:
103  
-      | name |
104  
-      | John |
105  
-
106  
-  Scenario: create instances of a factory with an underscore in its name
107  
-    Given an admin user exists with a name of "John"
108  
-    Then I should find the following for the last user:
109  
-      | name | admin |
110  
-      | John | true  |
111  
-
112  
-  Scenario: create a several instances of a factory with an underscore in its name
113  
-    Given 3 admin users exist
114  
-    Then I should find the following for the last user:
115  
-      | admin |
116  
-      | true  |
117  
-
118  
-  Scenario: use true values when creating instances
119  
-    Given the following user exists:
120  
-      | name | admin |
121  
-      | Bill | true  |
122  
-    Then I should find the following for the last user:
123  
-      | name | admin |
124  
-      | Bill | true  |
125  
-
126  
-  Scenario: use false values when creating instances
127  
-    Given the following user exists:
128  
-      | name | admin |
129  
-      | Mike | false |
130  
-    Then I should find the following for the last user:
131  
-      | name | admin |
132  
-      | Mike | false |
133  
-
134  
-  Scenario: Properly pluralize words
135  
-    Given the following categories exist:
136  
-      | name       |
137  
-      | Bed        |
138  
-      | Test Drive |
139  
-    And 2 categories exist
140  
-    And 2 categories exist with a name of "Future"
141  
-    Then there should be 6 categories
142  
-
143  
-  Scenario: create a post with an existing category group
144  
-    Given the following category exists:
145  
-      | ID  | name    | category group |
146  
-      | 123 | fiction | Name: books    |
147  
-    And the following post exists:
148  
-      | Title                      | Author    | Category                    |
149  
-      | a title                    | Name: Joe | Category Group: Name: books |
150  
-    Then I should find the following for the last post:
151  
-      | title   | category_id |
152  
-      | a title | 123         |
153  
-
154  
-  Scenario: create a post with an existing category group and a new category
155  
-    Given the following category group exists:
156  
-      | ID  | name  |
157  
-      | 456 | books |
158  
-    And the following post exists:
159  
-      | Title     | Author    | Category                    |
160  
-      | a title   | Name: Joe | Category Group: Name: books |
161  
-    Then I should find the following for the last post:
162  
-      | title   |
163  
-      | a title |
164  
-    And I should find the following for the last category:
165  
-      | category_group_id |
166  
-      | 456               |
167  
-
168  
-  Scenario: factory name and attributes should not be case sensitive
169  
-    Given the following category exists:
170  
-      | name    | category group |
171  
-      | fiction | Name: books    |
172  
-    Then there should be 1 category
173  
-    Given the following Category exists:
174  
-      | name    | category group |
175  
-      | science | Name: books    |
176  
-    Then there should be 2 categories
177  
-
178  
-  Scenario: factory name and attributes should not be case sensitive
179  
-    Given a user exists
180  
-    Then there should be 1 user
181  
-    Given a User exists
182  
-    Then there should be 2 Users
183  
-
184  
-  Scenario: factory name and attributes should not be case sensitive
185  
-    Given 3 users exist
186  
-    Then there should be 3 users
187  
-    Given 3 Users exist
188  
-    Then there should be 6 Users
189  
-
190  
-  Scenario: factory name and attributes should not be case sensitive
191  
-    Given a category exists with a name of "fiction"
192  
-    Then there should be 1 category
193  
-    Given a Category exists with a name of "science"
194  
-    Then there should be 2 Categories
195  
-
196  
-  Scenario: factory name and attributes should not be case sensitive
197  
-    Given 3 categories exist with a name of "fiction"
198  
-    Then there should be 3 categories
199  
-    Given 3 Categories exist with a name of "science"
200  
-    Then there should be 6 Categories
201  
-
202  
-  Scenario: step definitions work correctly with aliases
203  
-    Given the following person exists:
204  
-      | ID  | Name |
205  
-      | 123 | Joe  |
206  
-    Then I should find the following for the last user:
207  
-      | id  | name |
208  
-      | 123 | Joe  |
209  
-
210  
-  Scenario: pass a FactoryGirl table as an argument and modify it
211  
-    Given these super users exist:
212  
-      | id  | Name |
213  
-      | 123 | Joe  |
214  
-    Then I should find the following for the last user:
215  
-      | id  | name | admin |
216  
-      | 123 | Joe  | true  |
217  
-
218  
-  Scenario: Transform parses string data into array before assigning to an association
219  
-    Given the following tags exist:
220  
-      | name  |
221  
-      | funky |
222  
-      | cool  |
223  
-      | hip   |
224  
-    And the following post exists:
225  
-      | title       | tags      |
226  
-      | Tagged post | cool, hip |
227  
-    Then the post "Tagged post" should have the following tags:
228  
-      | name |
229  
-      | cool |
230  
-      | hip  |
231  
-    And the post "Tagged post" should not have the following tags:
232  
-      | name  |
233  
-      | funky |
234  
-
235  
-  Scenario: step definitions work correctly with ORMs that have simple `columns`
236  
-    Given a simple column exists
237  
-    Then there should be 1 SimpleColumn
238  
-
239  
-  Scenario: step definitions work correctly with model classes that simply have attribute names
240  
-    Given a named attribute model exists with a title of "a fun title"
241  
-    Then there should be 1 NamedAttributeModel
37  features/step_definitions/database_steps.rb
... ...
@@ -1,42 +1,9 @@
1  
-Then /^I should find the following for the last (.*):$/ do |model, table|
2  
-  model_class = model.camelize.constantize
3  
-  last_instance = model_class.last or raise "No #{model.pluralize} exist"
  1
+Then /^I should find the following for the last category:$/ do |table|
4 2
   table.hashes.first.each do |key, value|
5  
-    last_instance.attributes[key].to_s.should == value
  3
+    Category.last.attributes[key].to_s.should == value
6 4
   end
7 5
 end
8 6
 
9  
-Then /^there should be (\d+) (.*)$/ do |count, model|
10  
-  model_class = model.singularize.camelize.constantize
11  
-  model_class.count.should == count.to_i
12  
-end
13  
-
14  
-Then /^the post "([^"]*)" should (not )?have the following tags?:$/ do |post_title, negate, table|
15  
-  post = Post.find_by_title!(post_title)
16  
-
17  
-  table.hashes.each do |row|
18  
-    tag = Tag.find_by_name(row[:name])
19  
-
20  
-    if negate
21  
-      post.tags.should_not include(tag)
22  
-    else
23  
-      post.tags.should include(tag)
24  
-    end
25  
-  end
26  
-end
27  
-
28  
-Transform /^table:(?:.*,)?tags(?:,.*)?$/ do |table|
29  
-  table.map_column!("tags") do |tags|
30  
-    tags.split(',').map {|tag| Tag.find_by_name! tag.strip }
31  
-  end
32  
-  table
33  
-end
34  
-
35 7
 Before do
36  
-  Post.delete_all
37  
-  Tag.delete_all
38  
-  User.delete_all
39 8
   Category.delete_all
40  
-  CategoryGroup.delete_all
41 9
 end
42  
-
7  features/step_definitions/factory_girl_steps.rb
@@ -27,13 +27,6 @@ def append_file_to_factory_girl_definitions_path(path_to_file)
27 27
   FactoryGirl.create(factory_name)
28 28
 end
29 29
 
30  
-Given /^these super users exist:$/ do |table|
31  
-  headers = table.headers + ["admin"]
32  
-  rows    = table.rows.map { |row| row + [true] }
33  
-  new_table = Cucumber::Ast::Table.new([headers] + rows)
34  
-  step %{the following person exists:}, new_table
35  
-end
36  
-
37 30
 When /^I find definitions$/ do
38 31
   FactoryGirl.find_definitions
39 32
 end
125  features/support/factories.rb
@@ -5,135 +5,12 @@
5 5
 
6 6
 class CreateSchema < ActiveRecord::Migration
7 7
   def self.up
8  
-    create_table :posts, :force => true do |t|
9  
-      t.integer :author_id
10  
-      t.integer :category_id
11  
-      t.string  :title
12  
-      t.string  :body
13  
-    end
14  
-
15  
-    create_table :category_groups, :force => true do |t|
16  
-      t.string :name
17  
-    end
18  
-
19 8
     create_table :categories, :force => true do |t|
20  
-      t.integer :category_group_id
21  
-      t.string :name
22  
-    end
23  
-
24  
-    create_table :tags, :force => true do |t|
25  
-      t.integer :post_id
26 9
       t.string :name
27 10
     end
28  
-
29  
-    create_table :users, :force => true do |t|
30  
-      t.string  :name
31  
-      t.boolean :admin, :default => false, :null => false
32  
-    end
33 11
   end
34 12
 end
35 13
 
36 14
 CreateSchema.suppress_messages { CreateSchema.migrate(:up) }
37 15
 
38  
-class User < ActiveRecord::Base
39  
-end
40  
-
41  
-class CategoryGroup < ActiveRecord::Base
42  
-end
43  
-
44  
-class Category < ActiveRecord::Base
45  
-  belongs_to :category_group
46  
-end
47  
-
48  
-class Post < ActiveRecord::Base
49  
-  belongs_to :author, :class_name => 'User'
50  
-  belongs_to :category
51  
-  has_many :tags
52  
-end
53  
-
54  
-class Tag < ActiveRecord::Base
55  
-  belongs_to :post
56  
-end
57  
-
58  
-class NonActiveRecord
59  
-end
60  
-
61  
-class SimpleColumn
62  
-  def self.columns
63  
-    [:name]
64  
-  end
65  
-
66  
-  def save!
67  
-    @@count ||= 0
68  
-    @@count += 1
69  
-  end
70  
-
71  
-  def self.count
72  
-    @@count
73  
-  end
74  
-end
75  
-
76  
-class NamedAttributeModel
77  
-  def self.attribute_names
78  
-    %w(title)
79  
-  end
80  
-
81  
-  attr_accessor :title
82  
-
83  
-  def save!
84  
-    @@count ||= 0
85  
-    @@count += 1
86  
-  end
87  
-
88  
-  def self.count
89  
-    @@count
90  
-  end
91  
-end
92  
-
93  
-FactoryGirl.define do
94  
-  # To make sure the step defs work with an email
95  
-  sequence :email do |n|
96  
-    "email#{n}@example.com"
97  
-  end
98  
-
99  
-  factory :user, :aliases => [:person] do
100  
-    factory :admin_user do
101  
-      admin true
102  
-    end
103  
-  end
104  
-
105  
-  factory :category do
106  
-    name "programming"
107  
-    category_group
108  
-  end
109  
-
110  
-  factory :category_group do
111  
-    name "tecnhology"
112  
-  end
113  
-
114  
-  factory :post do
115  
-    association :author, :factory => :user
116  
-    category
117  
-  end
118  
-
119  
-  factory :titled_post, :parent => :post do
120  
-    title 'A Post with a Title'
121  
-  end
122  
-
123  
-  factory :tag do
124  
-    post
125  
-  end
126  
-  # This is here to ensure that factory step definitions don't raise for a non-AR factory
127  
-  factory :non_active_record do
128  
-  end
129  
-
130  
-  # This is here to make FG work with ORMs that have `columns => [:name, :admin, :etc]` on the class (Neo4j)
131  
-  factory :simple_column do
132  
-  end
133  
-
134  
-  factory :named_attribute_model do
135  
-  end
136  
-end
137  
-
138  
-require 'factory_girl/step_definitions'
139  
-
  16
+class Category < ActiveRecord::Base; end
2  lib/factory_girl.rb
... ...
@@ -1,5 +1,6 @@
1 1
 require 'set'
2 2
 require 'active_support/core_ext/module/delegation'
  3
+require 'active_support/deprecation'
3 4
 require 'active_support/notifications'
4 5
 
5 6
 require 'factory_girl/definition_hierarchy'
@@ -41,7 +42,6 @@
41 42
 require 'factory_girl/decorator/class_key_hash'
42 43
 require 'factory_girl/decorator/disallows_duplicates_registry'
43 44
 require 'factory_girl/decorator/invocation_tracker'
44  
-require 'factory_girl/decorator/invocation_ignorer'
45 45
 require 'factory_girl/decorator/new_constructor'
46 46
 require 'factory_girl/version'
47 47
 
16  lib/factory_girl/attribute_assigner.rb
@@ -35,29 +35,17 @@ def method_tracking_evaluator
35 35
     end
36 36
 
37 37
     def decorated_evaluator
38  
-      invocation_decorator.new(
  38
+      Decorator::InvocationTracker.new(
39 39
         Decorator::NewConstructor.new(@evaluator, @build_class)
40 40
       )
41 41
     end
42 42
 
43  
-    def invocation_decorator
44  
-      if FactoryGirl.duplicate_attribute_assignment_from_initialize_with
45  
-        Decorator::InvocationIgnorer
46  
-      else
47  
-        Decorator::InvocationTracker
48  
-      end
49  
-    end
50  
-
51 43
     def methods_invoked_on_evaluator
52 44
       method_tracking_evaluator.__invoked_methods__
53 45
     end
54 46
 
55 47
     def build_class_instance
56  
-      @build_class_instance ||= method_tracking_evaluator.instance_exec(&@instance_builder).tap do
57  
-        if @instance_builder != FactoryGirl.constructor && FactoryGirl.duplicate_attribute_assignment_from_initialize_with
58  
-          ActiveSupport::Deprecation.warn 'Accessing attributes from initialize_with when duplicate assignment is enabled is deprecated; use FactoryGirl.duplicate_attribute_assignment_from_initialize_with = false.', caller
59  
-        end
60  
-      end
  48
+      @build_class_instance ||= method_tracking_evaluator.instance_exec(&@instance_builder)
61 49
     end
62 50
 
63 51
     def build_hash
12  lib/factory_girl/configuration.rb
@@ -3,8 +3,6 @@ module FactoryGirl
3 3
   class Configuration
4 4
     attr_reader :factories, :sequences, :traits, :strategies, :callback_names
5 5
 
6  
-    attr_accessor :duplicate_attribute_assignment_from_initialize_with
7  
-
8 6
     def initialize
9 7
       @factories      = Decorator::DisallowsDuplicatesRegistry.new(Registry.new('Factory'))
10 8
       @sequences      = Decorator::DisallowsDuplicatesRegistry.new(Registry.new('Sequence'))
@@ -13,8 +11,6 @@ def initialize
13 11
       @callback_names = Set.new
14 12
       @definition     = Definition.new
15 13
 
16  
-      @duplicate_attribute_assignment_from_initialize_with = true
17  
-
18 14
       to_create {|instance| instance.save! }
19 15
       initialize_with { new }
20 16
     end
@@ -24,5 +20,13 @@ def initialize
24 20
     def initialize_with(&block)
25 21
       @definition.define_constructor(&block)
26 22
     end
  23
+
  24
+    def duplicate_attribute_assignment_from_initialize_with
  25
+      false
  26
+    end
  27
+
  28
+    def duplicate_attribute_assignment_from_initialize_with=(value)
  29
+      ActiveSupport::Deprecation.warn 'Assignment of duplicate_attribute_assignment_from_initialize_with is unnecessary as this is now default behavior in FactoryGirl 4.0; this line can be removed', caller
  30
+    end
27 31
   end
28 32
 end
9  lib/factory_girl/decorator/invocation_ignorer.rb
... ...
@@ -1,9 +0,0 @@
1  
-module FactoryGirl
2  
-  class Decorator
3  
-    class InvocationIgnorer < Decorator
4  
-      def __invoked_methods__
5  
-        []
6  
-      end
7  
-    end
8  
-  end
9  
-end
4  lib/factory_girl/definition_proxy.rb
@@ -85,10 +85,6 @@ def method_missing(name, *args, &block)
85 85
         @definition.declare_attribute(Declaration::Implicit.new(name, @definition, @ignore))
86 86
       elsif args.first.respond_to?(:has_key?) && args.first.has_key?(:factory)
87 87
         association(name, *args)
88  
-      elsif FactoryGirl.callback_names.include?(name)
89  
-        callback_when, callback_name = name.to_s.split('_', 2)
90  
-        ActiveSupport::Deprecation.warn "Calling #{name} is deprecated; use the syntax #{callback_when}(:#{callback_name}) {}", caller
91  
-        @definition.add_callback(Callback.new(name, block))
92 88
       else
93 89
         add_attribute(name, *args, &block)
94 90
       end
151  lib/factory_girl/step_definitions.rb
... ...
@@ -1,151 +0,0 @@
1  
-require 'active_support/deprecation'
2  
-
3  
-# @api private
4  
-module FactoryGirlStepHelpers
5  
-  def convert_human_hash_to_attribute_hash(human_hash, associations = [])
6  
-    HumanHashToAttributeHash.new(human_hash, associations).attributes
7  
-  end
8  
-
9  
-  class HumanHashToAttributeHash
10  
-    attr_reader :associations
11  
-
12  
-    def initialize(human_hash, associations)
13  
-      @human_hash   = human_hash
14  
-      @associations = associations
15  
-    end
16  
-
17  
-    def attributes(strategy = CreateAttributes)
18  
-      @human_hash.inject({}) do |attribute_hash, (human_key, value)|
19  
-        attributes = strategy.new(self, *process_key_value(human_key, value))
20  
-        attribute_hash.merge({ attributes.key => attributes.value })
21  
-      end
22  
-    end
23  
-
24  
-    private
25  
-
26  
-    def process_key_value(key, value)
27  
-      value = value.strip if value.is_a?(String)
28  
-      [key.downcase.gsub(' ', '_').to_sym, value]
29  
-    end
30  
-
31  
-    class AssociationManager
32  
-      def initialize(human_hash_to_attributes_hash, key, value)
33  
-        @human_hash_to_attributes_hash = human_hash_to_attributes_hash
34  
-        @key   = key
35  
-        @value = value
36  
-      end
37  
-
38  
-      def association
39  
-        @human_hash_to_attributes_hash.associations.detect {|association| association.name == @key }
40  
-      end
41  
-
42  
-      def association_instance
43  
-        return unless association
44  
-
45  
-        if attributes_hash = nested_attribute_hash
46  
-          factory.build_class.first(conditions: attributes_hash.attributes(FindAttributes)) or
47  
-          FactoryGirl.create(association.factory, attributes_hash.attributes)
48  
-        end
49  
-      end
50  
-
51  
-      private
52  
-
53  
-      def factory
54  
-        FactoryGirl.factory_by_name(association.factory)
55  
-      end
56  
-
57  
-      def nested_attribute_hash
58  
-        attribute, value = @value.split(':', 2)
59  
-        return if value.blank?
60  
-
61  
-        HumanHashToAttributeHash.new({ attribute => value }, factory.associations)
62  
-      end
63  
-    end
64  
-
65  
-    class AttributeStrategy
66  
-      attr_reader :key, :value, :association_manager
67  
-
68  
-      def initialize(human_hash_to_attributes_hash, key, value)
69  
-        @association_manager = AssociationManager.new(human_hash_to_attributes_hash, key, value)
70  
-        @key   = key
71  
-        @value = value
72  
-      end
73  
-    end
74  
-
75  
-    class FindAttributes < AttributeStrategy
76  
-      def initialize(human_hash_to_attributes_hash, key, value)
77  
-        super
78  
-
79  
-        if association_manager.association
80  
-          @key = "#{@key}_id"
81  
-          @value = association_manager.association_instance.try(:id)
82  
-        end
83  
-      end
84  
-    end
85  
-
86  
-    class CreateAttributes < AttributeStrategy
87  
-      def initialize(human_hash_to_attributes_hash, key, value)
88  
-        super
89  
-
90  
-        if association_manager.association
91  
-          @value = association_manager.association_instance
92  
-        end
93  
-      end
94  
-    end
95  
-  end
96  
-end
97  
-
98  
-World(FactoryGirlStepHelpers)
99  
-
100  
-FactoryGirl.factories.each do |factory|
101  
-  factory.compile
102  
-  factory.human_names.each do |human_name|
103  
-    attribute_names_for_model = if factory.build_class.respond_to?(:attribute_names)
104  
-      factory.build_class.attribute_names
105  
-    elsif factory.build_class.respond_to?(:columns)
106  
-      factory.build_class.columns.map do |column|
107  
-        column.respond_to?(:name) ? column.name : column.to_s
108  
-      end
109  
-    else
110  
-      []
111  
-    end
112  
-
113  
-    Given /^the following (?:#{human_name}|#{human_name.pluralize}) exists?:?$/i do |table|
114  
-      ActiveSupport::Deprecation.warn %{The step 'Given the following #{human_name} exists:' is deprecated and will be removed in 4.0}
115  
-
116  
-      table.hashes.each do |human_hash|
117  
-        attributes = convert_human_hash_to_attribute_hash(human_hash, factory.associations)
118  
-        FactoryGirl.create(factory.name, attributes)
119  
-      end
120  
-    end
121  
-
122  
-    Given /^an? #{human_name} exists$/i do
123  
-      ActiveSupport::Deprecation.warn %{The step 'Given a #{human_name} exists' is deprecated and will be removed in 4.0}
124  
-
125  
-      FactoryGirl.create(factory.name)
126  
-    end
127  
-
128  
-    Given /^(\d+) #{human_name.pluralize} exist$/i do |count|
129  
-      ActiveSupport::Deprecation.warn %{The step 'Given #{count} #{human_name.pluralize} exist' is deprecated and will be removed in 4.0}
130  
-
131  
-      FactoryGirl.create_list(factory.name, count.to_i)
132  
-    end
133  
-
134  
-    attribute_names_for_model.each do |attribute_name|
135  
-      human_column_name = attribute_name.downcase.gsub('_', ' ')
136  
-
137  
-      Given /^an? #{human_name} exists with an? #{human_column_name} of "([^"]*)"$/i do |value|
138  
-        ActiveSupport::Deprecation.warn %{The step 'Given a #{human_name} exists with a #{human_column_name} of "#{value}"' is deprecated and will be removed in 4.0}
139  
-
140  
-        FactoryGirl.create(factory.name, attribute_name => value)
141  
-      end
142  
-
143  
-      Given /^(\d+) #{human_name.pluralize} exist with an? #{human_column_name} of "([^"]*)"$/i do |count, value|
144  
-        ActiveSupport::Deprecation.warn %{The step 'Given #{count} #{human_name.pluralize} exists with a #{human_column_name} of "#{value}"' is deprecated and will be removed in 4.0}
145  
-
146  
-        FactoryGirl.create_list(factory.name, count.to_i, attribute_name => value)
147  
-      end
148  
-    end
149  
-  end
150  
-end
151  
-
11  lib/factory_girl/syntax.rb
... ...
@@ -1,18 +1,7 @@
1  
-require 'active_support/deprecation'
2  
-
3 1
 require 'factory_girl/syntax/methods'
4 2
 require 'factory_girl/syntax/default'
5  
-require 'factory_girl/syntax/vintage'
6 3
 
7 4
 module FactoryGirl
8  
-  # Provides alternate syntaxes for factory_girl. If you don't like the default
9  
-  # syntax for defining or using factories, look at one of the
10  
-  # FactoryGirl::Syntax modules:
11  
-  #
12  
-  # * FactoryGirl::Syntax::Blueprint: definition syntax similar to Machinist
13  
-  # * FactoryGirl::Syntax::Generate: usage syntax similar to Object Daddy
14  
-  # * FactoryGirl::Syntax::Make: usage syntax similar to Machinist
15  
-  # * FactoryGirl::Syntax::Sham: sequence syntax similar to Machinist
16 5
   module Syntax
17 6
   end
18 7
 end
40  lib/factory_girl/syntax/blueprint.rb
... ...
@@ -1,40 +0,0 @@
1  
-module FactoryGirl
2  
-  module Syntax
3  
-
4  
-    # Extends ActiveRecord::Base to provide a make class method, which is an
5  
-    # alternate syntax for defining factories.
6  
-    #
7  
-    # Usage:
8  
-    #
9  
-    #   require 'factory_girl/syntax/blueprint'
10  
-    #
11  
-    #   User.blueprint do
12  
-    #     name  { 'Billy Bob'             }
13  
-    #     email { 'billy@bob.example.com' }
14  
-    #   end
15  
-    #
16  
-    #   FactoryGirl.create(:user, name: 'Johnny')
17  
-    #
18  
-    # This syntax was derived from Pete Yandell's machinist.
19  
-    # @api private
20  
-    module Blueprint
21  
-      module ActiveRecord
22  
-        def self.included(base)
23  
-          base.extend ClassMethods
24  
-        end
25  
-
26  
-        module ClassMethods
27  
-          def blueprint(&block)
28  
-            ActiveSupport::Deprecation.warn 'Model.blueprint is deprecated; use the FactoryGirl.define syntax instead', caller
29  
-            instance = Factory.new(name.underscore, class: self)
30  
-            proxy = FactoryGirl::DefinitionProxy.new(instance)
31  
-            proxy.instance_eval(&block)
32  
-            FactoryGirl.register_factory(instance)
33  
-          end
34  
-        end
35  
-      end
36  
-    end
37  
-  end
38  
-end
39  
-
40  
-ActiveRecord::Base.send(:include, FactoryGirl::Syntax::Blueprint::ActiveRecord)
70  lib/factory_girl/syntax/generate.rb
... ...
@@ -1,70 +0,0 @@
1  
-module FactoryGirl
2  
-  module Syntax
3  
-
4  
-    # Extends ActiveRecord::Base to provide generation methods for factories.
5  
-    #
6  
-    # Usage:
7  
-    #
8  
-    #   require 'factory_girl/syntax/generate'
9  
-    #
10  
-    #   FactoryGirl.define do
11  
-    #     factory :user do
12  
-    #       name 'Billy Bob'
13  
-    #       email 'billy@bob.example.com'
14  
-    #     end
15  
-    #   end
16  
-    #
17  
-    #   # Creates a saved instance without raising (same as saving the result
18  
-    #   # of FactoryGirl.build)
19  
-    #   User.generate(name: 'Johnny')
20  
-    #
21  
-    #   # Creates a saved instance and raises when invalid (same as
22  
-    #   # FactoryGirl.create)
23  
-    #   User.generate!
24  
-    #
25  
-    #   # Creates an unsaved instance (same as FactoryGirl.build)
26  
-    #   User.spawn
27  
-    #
28  
-    #   # Creates an instance and yields it to the passed block
29  
-    #   User.generate do |user|
30  
-    #     # ...do something with user...
31  
-    #   end
32  
-    #
33  
-    # This syntax was derived from Rick Bradley and Yossef Mendelssohn's
34  
-    # object_daddy.
35  
-    # @api private
36  
-    module Generate
37  
-      module ActiveRecord
38  
-        def self.included(base)
39  
-          base.extend ClassMethods
40  
-        end
41  
-
42  
-        module ClassMethods
43  
-          def generate(overrides = {}, &block)
44  
-            ActiveSupport::Deprecation.warn 'Model.generate is deprecated; use FactoryGirl.build(:name) instead.', caller
45  
-            instance = FactoryRunner.new(name.underscore, :build, [overrides]).run
46  
-            instance.save
47  
-            yield(instance) if block_given?
48  
-            instance
49  
-          end
50  
-
51  
-          def generate!(overrides = {}, &block)
52  
-            ActiveSupport::Deprecation.warn 'Model.generate! is deprecated; use FactoryGirl.create(:name) instead.', caller
53  
-            instance = FactoryRunner.new(name.underscore, :create, [overrides]).run
54  
-            yield(instance) if block_given?
55  
-            instance
56  
-          end
57  
-
58  
-          def spawn(overrides = {}, &block)
59  
-            ActiveSupport::Deprecation.warn 'Model.spawn is deprecated; use FactoryGirl.build(:name) instead.', caller
60  
-            instance = FactoryRunner.new(name.underscore, :build, [overrides]).run
61  
-            yield(instance) if block_given?
62  
-            instance
63  
-          end
64  
-        end
65  
-      end
66  
-    end
67  
-  end
68  
-end
69  
-
70  
-ActiveRecord::Base.send(:include, FactoryGirl::Syntax::Generate::ActiveRecord)
44  lib/factory_girl/syntax/make.rb
... ...
@@ -1,44 +0,0 @@
1  
-module FactoryGirl
2  
-  module Syntax
3  
-
4  
-    # Extends ActiveRecord::Base to provide a make class method, which is a
5  
-    # shortcut for FactoryGirl.create.
6  
-    #
7  
-    # Usage:
8  
-    #
9  
-    #   require 'factory_girl/syntax/make'
10  
-    #
11  
-    #   FactoryGirl.define do
12  
-    #     factory :user do
13  
-    #       name 'Billy Bob'
14  
-    #       email 'billy@bob.example.com'
15  
-    #     end
16  
-    #   end
17  
-    #
18  
-    #   User.make(name: 'Johnny')
19  
-    #
20  
-    # This syntax was derived from Pete Yandell's machinist.
21  
-    # @api private
22  
-    module Make
23  
-      module ActiveRecord
24  
-        def self.included(base)
25  
-          base.extend ClassMethods
26  
-        end
27  
-
28  
-        module ClassMethods
29  
-          def make(overrides = {})
30  
-            ActiveSupport::Deprecation.warn 'Model.make is deprecated; use FactoryGirl.build(:model) instead.', caller
31  
-            FactoryRunner.new(name.underscore, :build, [overrides]).run
32  
-          end
33  
-
34  
-          def make!(overrides = {})
35  
-            ActiveSupport::Deprecation.warn 'Model.make! is deprecated; use FactoryGirl.create(:model) instead.', caller
36  
-            FactoryRunner.new(name.underscore, :create, [overrides]).run
37  
-          end
38  
-        end
39  
-      end
40  
-    end
41  
-  end
42  
-end
43  
-
44  
-ActiveRecord::Base.send(:include, FactoryGirl::Syntax::Make::ActiveRecord)
47  lib/factory_girl/syntax/sham.rb
... ...
@@ -1,47 +0,0 @@
1  
-module FactoryGirl
2  
-  module Syntax
3  
-
4  
-    # Adds a Sham module, which provides an alternate interface to
5  
-    # FactoryGirl::Sequence.
6  
-    #
7  
-    # Usage:
8  
-    #
9  
-    #   require 'factory_girl/syntax/sham'
10  
-    #
11  
-    #   Sham.email {|n| "somebody#{n}@example.com" }
12  
-    #
13  
-    #   FactoryGirl.define do
14  
-    #     factory :user do
15  
-    #       email
16  
-    #     end
17  
-    #   end
18  
-    #
19  
-    # Note that you can also use Faker, but it is recommended that you simply
20  
-    # use a sequence as in the above example, as factory_girl does not provide
21  
-    # protection against duplication in randomized sequences, and a randomized
22  
-    # value does not provide any tangible benefits over an ascending sequence.
23  
-    #
24  
-    # This syntax was derived from Pete Yandell's machinist.
25  
-    # @api private
26  
-    module Sham
27  
-      module Sham
28  
-        def self.method_missing(name, *args, &block)
29  
-          if block_given?
30  
-            ActiveSupport::Deprecation.warn 'Sham.sequence is deprecated; use the FactoryGirl.define syntax instead', caller
31  
-            start_value = args.first
32  
-            FactoryGirl.register_sequence(Sequence.new(name, start_value || 1, &block))
33  
-          else
34  
-            FactoryGirl.sequence_by_name(name).next
35  
-          end
36  
-        end
37  
-
38  
-        # overrides name on Module
39  
-        def self.name(&block)
40  
-          method_missing('name', &block)
41  
-        end
42  
-      end
43  
-    end
44  
-  end
45  
-end
46  
-
47  
-include FactoryGirl::Syntax::Sham
130  lib/factory_girl/syntax/vintage.rb
... ...
@@ -1,130 +0,0 @@
1  
-module FactoryGirl
2  
-  module Syntax
3  
-    module Vintage
4  
-      module ::Factory
5  
-        # Defines a new factory that can be used by the build strategies (create and
6  
-        # build) to build new objects.
7  
-        #
8  
-        # Arguments:
9  
-        # * name: +Symbol+ or +String+
10  
-        #   A unique name used to identify this factory.
11  
-        # * options: +Hash+
12  
-        #
13  
-        # Options:
14  
-        # * class: +Symbol+, +Class+, or +String+
15  
-        #   The class that will be used when generating instances for this factory. If not specified, the class will be guessed from the factory name.
16  
-        # * parent: +Symbol+
17  
-        #   The parent factory. If specified, the attributes from the parent
18  
-        #   factory will be copied to the current one with an ability to override
19  
-        #   them.
20  
-        #
21  
-        # Yields: +Factory+
22  
-        # The newly created factory.
23  
-        def self.define(name, options = {})
24  
-          ActiveSupport::Deprecation.warn 'Factory.define is deprecated; use the FactoryGirl.define block syntax to declare your factory.', caller
25  
-          factory = FactoryGirl::Factory.new(name, options)
26  
-          proxy = FactoryGirl::DefinitionProxy.new(factory)
27  
-          yield(proxy)
28  
-          FactoryGirl.register_factory(factory)
29  
-        end
30  
-
31  
-        # Defines a new sequence that can be used to generate unique values in a specific format.
32  
-        #
33  
-        # Arguments:
34  
-        #   name: (Symbol)
35  
-        #     A unique name for this sequence. This name will be referenced when
36  
-        #     calling next to generate new values from this sequence.
37  
-        #   block: (Proc)
38  
-        #     The code to generate each value in the sequence. This block will be
39  
-        #     called with a unique number each time a value in the sequence is to be
40  
-        #     generated. The block should return the generated value for the
41  
-        #     sequence.
42  
-        #
43  
-        # Example:
44  
-        #
45  
-        #   Factory.sequence(:email) {|n| "somebody_#{n}@example.com" }
46  
-        def self.sequence(name, start_value = 1, &block)
47  
-          ActiveSupport::Deprecation.warn 'Factory.sequence is deprecated; use the FactoryGirl.define block syntax to declare your sequence.', caller
48  
-          FactoryGirl.register_sequence(Sequence.new(name, start_value, &block))
49  
-        end
50  
-
51  
-        # Generates and returns the next value in a sequence.
52  
-        #
53  
-        # Arguments:
54  
-        #   name: (Symbol)
55  
-        #     The name of the sequence that a value should be generated for.
56  
-        #
57  
-        # Returns:
58  
-        #   The next value in the sequence. (Object)
59  
-        def self.next(name)
60  
-          ActiveSupport::Deprecation.warn 'Factory.next is deprecated; use FactoryGirl.generate instead.', caller
61  
-          FactoryGirl.generate(name)
62  
-        end
63  
-
64  
-        # Defines a new alias for attributes.
65  
-        #
66  
-        # Arguments:
67  
-        # * pattern: +Regexp+
68  
-        #   A pattern that will be matched against attributes when looking for
69  
-        #   aliases. Contents captured in the pattern can be used in the alias.
70  
-        # * replace: +String+