factory_girl 2.3.2 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +5 -3
- data/Appraisals +4 -0
- data/CONTRIBUTION_GUIDELINES.md +1 -1
- data/Changelog +13 -0
- data/GETTING_STARTED.md +362 -286
- data/Gemfile.lock +1 -1
- data/README.md +8 -8
- data/features/factory_girl_steps.feature +4 -0
- data/features/support/factories.rb +19 -0
- data/gemfiles/2.1.gemfile.lock +1 -1
- data/gemfiles/2.3.gemfile.lock +1 -1
- data/gemfiles/3.0.gemfile.lock +1 -1
- data/gemfiles/3.1.gemfile.lock +1 -1
- data/gemfiles/3.2.gemfile +7 -0
- data/gemfiles/3.2.gemfile.lock +90 -0
- data/lib/factory_girl.rb +4 -0
- data/lib/factory_girl/attribute.rb +1 -9
- data/lib/factory_girl/attribute/association.rb +2 -2
- data/lib/factory_girl/attribute/dynamic.rb +2 -2
- data/lib/factory_girl/attribute/sequence.rb +1 -1
- data/lib/factory_girl/attribute/static.rb +1 -1
- data/lib/factory_girl/attribute_assigner.rb +73 -0
- data/lib/factory_girl/attribute_list.rb +6 -15
- data/lib/factory_girl/callback.rb +2 -2
- data/lib/factory_girl/evaluator.rb +57 -0
- data/lib/factory_girl/evaluator_class_definer.rb +34 -0
- data/lib/factory_girl/factory.rb +31 -80
- data/lib/factory_girl/null_factory.rb +2 -1
- data/lib/factory_girl/null_object.rb +19 -0
- data/lib/factory_girl/proxy.rb +6 -87
- data/lib/factory_girl/proxy/attributes_for.rb +2 -7
- data/lib/factory_girl/proxy/build.rb +4 -3
- data/lib/factory_girl/proxy/create.rb +6 -7
- data/lib/factory_girl/proxy/stub.rb +19 -18
- data/lib/factory_girl/step_definitions.rb +4 -3
- data/lib/factory_girl/version.rb +1 -1
- data/spec/acceptance/aliases_spec.rb +19 -0
- data/spec/acceptance/attributes_for_spec.rb +10 -1
- data/spec/acceptance/attributes_from_instance_spec.rb +53 -0
- data/spec/acceptance/build_spec.rb +8 -0
- data/spec/acceptance/build_stubbed_spec.rb +9 -0
- data/spec/acceptance/create_spec.rb +8 -0
- data/spec/factory_girl/attribute/association_spec.rb +5 -4
- data/spec/factory_girl/attribute/dynamic_spec.rb +9 -10
- data/spec/factory_girl/attribute/sequence_spec.rb +1 -2
- data/spec/factory_girl/attribute/static_spec.rb +1 -2
- data/spec/factory_girl/attribute_list_spec.rb +14 -4
- data/spec/factory_girl/evaluator_class_definer_spec.rb +54 -0
- data/spec/factory_girl/factory_spec.rb +23 -16
- data/spec/factory_girl/null_factory_spec.rb +2 -1
- data/spec/factory_girl/null_object_spec.rb +8 -0
- data/spec/factory_girl/proxy/attributes_for_spec.rb +8 -24
- data/spec/factory_girl/proxy/build_spec.rb +1 -7
- data/spec/factory_girl/proxy/create_spec.rb +2 -27
- data/spec/factory_girl/proxy/stub_spec.rb +14 -13
- data/spec/factory_girl/proxy_spec.rb +1 -33
- data/spec/support/shared_examples/proxy.rb +22 -45
- metadata +133 -177
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,16 +1,16 @@
|
|
1
|
-
# factory_girl [![Build Status](https://secure.travis-ci.org/thoughtbot/factory_girl.png)](http://travis-ci.org/thoughtbot/factory_girl?branch=master)
|
1
|
+
# factory_girl [![Build Status](https://secure.travis-ci.org/thoughtbot/factory_girl.png)](http://travis-ci.org/thoughtbot/factory_girl?branch=master) [![Dependency Status](https://gemnasium.com/thoughtbot/factory_girl.png)](https://gemnasium.com/thoughtbot/factory_girl)
|
2
2
|
|
3
3
|
factory_girl is a fixtures replacement with a straightforward definition syntax, support for multiple build strategies (saved instances, unsaved instances, attribute hashes, and stubbed objects), and support for multiple factories for the same class (user, admin_user, and so on), including factory inheritance.
|
4
4
|
|
5
5
|
If you want to use factory_girl with Rails 3, see
|
6
|
-
[factory_girl_rails](
|
6
|
+
[factory_girl_rails](https://github.com/thoughtbot/factory_girl_rails).
|
7
7
|
|
8
8
|
Documentation
|
9
9
|
-------------
|
10
10
|
|
11
|
-
You should find the documentation for your version of factory_girl on [Rubygems](
|
11
|
+
You should find the documentation for your version of factory_girl on [Rubygems](https://rubygems.org/gems/factory_girl).
|
12
12
|
|
13
|
-
See
|
13
|
+
See [GETTING_STARTED](https://github.com/thoughtbot/factory_girl/blob/master/GETTING_STARTED.md) for information on defining and using factories.
|
14
14
|
|
15
15
|
Install
|
16
16
|
--------
|
@@ -28,15 +28,15 @@ and run `bundle install` from your shell.
|
|
28
28
|
More Information
|
29
29
|
----------------
|
30
30
|
|
31
|
-
* [Rubygems](
|
31
|
+
* [Rubygems](https://rubygems.org/gems/factory_girl)
|
32
32
|
* [Mailing list](http://groups.google.com/group/factory_girl)
|
33
|
-
* [Issues](
|
34
|
-
* [GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS](http://
|
33
|
+
* [Issues](https://github.com/thoughtbot/factory_girl/issues)
|
34
|
+
* [GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS](http://robots.thoughtbot.com/)
|
35
35
|
|
36
36
|
Contributing
|
37
37
|
------------
|
38
38
|
|
39
|
-
Please see the [contribution guidelines](
|
39
|
+
Please see the [contribution guidelines](https://github.com/thoughtbot/factory_girl/blob/master/CONTRIBUTION_GUIDELINES.md).
|
40
40
|
|
41
41
|
Credits
|
42
42
|
-------
|
@@ -215,3 +215,7 @@ Feature: Use step definitions generated by factories
|
|
215
215
|
And the post "Tagged post" should not have the following tags:
|
216
216
|
| name |
|
217
217
|
| funky |
|
218
|
+
|
219
|
+
Scenario: step definitions work correctly with ORMs that have simple `columns`
|
220
|
+
Given a simple column exists
|
221
|
+
Then there should be 1 SimpleColumn
|
@@ -58,6 +58,21 @@ end
|
|
58
58
|
class NonActiveRecord
|
59
59
|
end
|
60
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
|
+
|
61
76
|
FactoryGirl.define do
|
62
77
|
# To make sure the step defs work with an email
|
63
78
|
sequence :email do |n|
|
@@ -90,6 +105,10 @@ FactoryGirl.define do
|
|
90
105
|
# This is here to ensure that factory step definitions don't raise for a non-AR factory
|
91
106
|
factory :non_active_record do
|
92
107
|
end
|
108
|
+
|
109
|
+
# This is here to make FG work with ORMs that have `columns => [:name, :admin, :etc]` on the class (Neo4j)
|
110
|
+
factory :simple_column do
|
111
|
+
end
|
93
112
|
end
|
94
113
|
|
95
114
|
require 'factory_girl/step_definitions'
|
data/gemfiles/2.1.gemfile.lock
CHANGED
data/gemfiles/2.3.gemfile.lock
CHANGED
data/gemfiles/3.0.gemfile.lock
CHANGED
data/gemfiles/3.1.gemfile.lock
CHANGED
@@ -0,0 +1,90 @@
|
|
1
|
+
PATH
|
2
|
+
remote: /Users/joshuaclayton/dev/gems/factory_girl
|
3
|
+
specs:
|
4
|
+
factory_girl (2.4.0)
|
5
|
+
activesupport
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: http://rubygems.org/
|
9
|
+
specs:
|
10
|
+
activemodel (3.2.0.rc2)
|
11
|
+
activesupport (= 3.2.0.rc2)
|
12
|
+
builder (~> 3.0.0)
|
13
|
+
activerecord (3.2.0.rc2)
|
14
|
+
activemodel (= 3.2.0.rc2)
|
15
|
+
activesupport (= 3.2.0.rc2)
|
16
|
+
arel (~> 3.0.0.rc1)
|
17
|
+
tzinfo (~> 0.3.29)
|
18
|
+
activesupport (3.2.0.rc2)
|
19
|
+
i18n (~> 0.6)
|
20
|
+
multi_json (~> 1.0)
|
21
|
+
appraisal (0.3.8)
|
22
|
+
bundler
|
23
|
+
rake
|
24
|
+
arel (3.0.0)
|
25
|
+
aruba (0.4.6)
|
26
|
+
bcat (>= 0.6.1)
|
27
|
+
childprocess (>= 0.2.0)
|
28
|
+
cucumber (>= 1.0.2)
|
29
|
+
rdiscount (>= 1.6.8)
|
30
|
+
rspec (>= 2.6.0)
|
31
|
+
bcat (0.6.2)
|
32
|
+
rack (~> 1.0)
|
33
|
+
bluecloth (2.2.0)
|
34
|
+
bourne (1.0)
|
35
|
+
mocha (= 0.9.8)
|
36
|
+
builder (3.0.0)
|
37
|
+
childprocess (0.2.9)
|
38
|
+
ffi (~> 1.0.6)
|
39
|
+
cucumber (1.0.6)
|
40
|
+
builder (>= 2.1.2)
|
41
|
+
diff-lcs (>= 1.1.2)
|
42
|
+
gherkin (~> 2.4.18)
|
43
|
+
json (>= 1.4.6)
|
44
|
+
term-ansicolor (>= 1.0.6)
|
45
|
+
diff-lcs (1.1.3)
|
46
|
+
ffi (1.0.11)
|
47
|
+
gherkin (2.4.21)
|
48
|
+
json (>= 1.4.6)
|
49
|
+
i18n (0.6.0)
|
50
|
+
json (1.6.4)
|
51
|
+
mocha (0.9.8)
|
52
|
+
rake
|
53
|
+
multi_json (1.0.4)
|
54
|
+
rack (1.4.0)
|
55
|
+
rake (0.9.2.2)
|
56
|
+
rcov (0.9.11)
|
57
|
+
rdiscount (1.6.8)
|
58
|
+
rspec (2.8.0)
|
59
|
+
rspec-core (~> 2.8.0)
|
60
|
+
rspec-expectations (~> 2.8.0)
|
61
|
+
rspec-mocks (~> 2.8.0)
|
62
|
+
rspec-core (2.8.0)
|
63
|
+
rspec-expectations (2.8.0)
|
64
|
+
diff-lcs (~> 1.1.2)
|
65
|
+
rspec-mocks (2.8.0)
|
66
|
+
sqlite3 (1.3.5)
|
67
|
+
sqlite3-ruby (1.3.3)
|
68
|
+
sqlite3 (>= 1.3.3)
|
69
|
+
term-ansicolor (1.0.7)
|
70
|
+
timecop (0.3.5)
|
71
|
+
tzinfo (0.3.31)
|
72
|
+
yard (0.7.4)
|
73
|
+
|
74
|
+
PLATFORMS
|
75
|
+
ruby
|
76
|
+
|
77
|
+
DEPENDENCIES
|
78
|
+
activerecord (~> 3.2.0.rc2)
|
79
|
+
appraisal (~> 0.3.8)
|
80
|
+
aruba
|
81
|
+
bluecloth
|
82
|
+
bourne
|
83
|
+
cucumber (~> 1.0.0)
|
84
|
+
factory_girl!
|
85
|
+
mocha
|
86
|
+
rcov
|
87
|
+
rspec (~> 2.0)
|
88
|
+
sqlite3-ruby
|
89
|
+
timecop
|
90
|
+
yard
|
data/lib/factory_girl.rb
CHANGED
@@ -3,7 +3,11 @@ require "active_support/core_ext/module/delegation"
|
|
3
3
|
require 'factory_girl/proxy'
|
4
4
|
require 'factory_girl/registry'
|
5
5
|
require 'factory_girl/null_factory'
|
6
|
+
require 'factory_girl/null_object'
|
6
7
|
require 'factory_girl/factory'
|
8
|
+
require 'factory_girl/attribute_assigner'
|
9
|
+
require 'factory_girl/evaluator'
|
10
|
+
require 'factory_girl/evaluator_class_definer'
|
7
11
|
require 'factory_girl/attribute'
|
8
12
|
require 'factory_girl/callback'
|
9
13
|
require 'factory_girl/declaration_list'
|
@@ -14,15 +14,7 @@ module FactoryGirl
|
|
14
14
|
ensure_non_attribute_writer!
|
15
15
|
end
|
16
16
|
|
17
|
-
def
|
18
|
-
if @ignored
|
19
|
-
proxy.set_ignored(self, to_proc(proxy))
|
20
|
-
else
|
21
|
-
proxy.set(self, to_proc(proxy))
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def to_proc(proxy)
|
17
|
+
def to_proc
|
26
18
|
lambda { }
|
27
19
|
end
|
28
20
|
|
@@ -9,10 +9,10 @@ module FactoryGirl
|
|
9
9
|
@overrides = overrides
|
10
10
|
end
|
11
11
|
|
12
|
-
def to_proc
|
12
|
+
def to_proc
|
13
13
|
factory = @factory
|
14
14
|
overrides = @overrides
|
15
|
-
lambda {
|
15
|
+
lambda { association(factory, overrides) }
|
16
16
|
end
|
17
17
|
|
18
18
|
def association?
|
@@ -6,11 +6,11 @@ module FactoryGirl
|
|
6
6
|
@block = block
|
7
7
|
end
|
8
8
|
|
9
|
-
def to_proc
|
9
|
+
def to_proc
|
10
10
|
block = @block
|
11
11
|
|
12
12
|
lambda {
|
13
|
-
value = block.arity == 1 ? block.call(
|
13
|
+
value = block.arity == 1 ? block.call(self) : instance_exec(&block)
|
14
14
|
raise SequenceAbuseError if FactoryGirl::Sequence === value
|
15
15
|
value
|
16
16
|
}
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module FactoryGirl
|
2
|
+
class AttributeAssigner
|
3
|
+
def initialize(build_class, evaluator)
|
4
|
+
@build_class = build_class
|
5
|
+
@evaluator = evaluator
|
6
|
+
@attribute_list = evaluator.class.attribute_list
|
7
|
+
@attribute_names_assigned = []
|
8
|
+
end
|
9
|
+
|
10
|
+
def object
|
11
|
+
@evaluator.instance = build_class_instance
|
12
|
+
build_class_instance.tap do |instance|
|
13
|
+
attributes_to_set_on_instance.each do |attribute|
|
14
|
+
instance.send("#{attribute}=", get(attribute))
|
15
|
+
@attribute_names_assigned << attribute
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def hash
|
21
|
+
@evaluator.instance = NullObject.new
|
22
|
+
|
23
|
+
attributes_to_set_on_hash.inject({}) do |result, attribute|
|
24
|
+
result[attribute] = get(attribute)
|
25
|
+
result
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def build_class_instance
|
32
|
+
@build_class_instance ||= @build_class.new
|
33
|
+
end
|
34
|
+
|
35
|
+
def get(attribute_name)
|
36
|
+
@evaluator.send(attribute_name)
|
37
|
+
end
|
38
|
+
|
39
|
+
def attributes_to_set_on_instance
|
40
|
+
attribute_names_to_assign - @attribute_names_assigned
|
41
|
+
end
|
42
|
+
|
43
|
+
def attributes_to_set_on_hash
|
44
|
+
attribute_names_to_assign - association_names
|
45
|
+
end
|
46
|
+
|
47
|
+
def attribute_names_to_assign
|
48
|
+
non_ignored_attribute_names + override_names - ignored_attribute_names - alias_names_to_ignore
|
49
|
+
end
|
50
|
+
|
51
|
+
def non_ignored_attribute_names
|
52
|
+
@attribute_list.reject(&:ignored).map(&:name)
|
53
|
+
end
|
54
|
+
|
55
|
+
def ignored_attribute_names
|
56
|
+
@attribute_list.select(&:ignored).map(&:name)
|
57
|
+
end
|
58
|
+
|
59
|
+
def association_names
|
60
|
+
@attribute_list.associations.map(&:name)
|
61
|
+
end
|
62
|
+
|
63
|
+
def override_names
|
64
|
+
@evaluator.__overrides.keys
|
65
|
+
end
|
66
|
+
|
67
|
+
def alias_names_to_ignore
|
68
|
+
@attribute_list.reject(&:ignored).map do |attribute|
|
69
|
+
override_names.map {|override| attribute.name if attribute.alias_for?(override) && attribute.name != override }
|
70
|
+
end.flatten.compact
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -18,13 +18,12 @@ module FactoryGirl
|
|
18
18
|
@attributes.each(&block)
|
19
19
|
end
|
20
20
|
|
21
|
-
def
|
22
|
-
|
23
|
-
|
24
|
-
delete_attribute(attribute.name)
|
21
|
+
def associations
|
22
|
+
@attributes.select(&:association?)
|
23
|
+
end
|
25
24
|
|
26
|
-
|
27
|
-
|
25
|
+
def apply_attributes(attributes_to_apply)
|
26
|
+
attributes_to_apply.each {|attribute| add_attribute(attribute) }
|
28
27
|
end
|
29
28
|
|
30
29
|
private
|
@@ -47,17 +46,9 @@ module FactoryGirl
|
|
47
46
|
end
|
48
47
|
|
49
48
|
def attribute_defined?(attribute_name)
|
50
|
-
|
51
|
-
end
|
52
|
-
|
53
|
-
def find_attribute(attribute_name)
|
54
|
-
@attributes.detect do |attribute|
|
49
|
+
@attributes.any? do |attribute|
|
55
50
|
attribute.name == attribute_name
|
56
51
|
end
|
57
52
|
end
|
58
|
-
|
59
|
-
def delete_attribute(attribute_name)
|
60
|
-
@attributes.delete_if {|attrib| attrib.name == attribute_name }
|
61
|
-
end
|
62
53
|
end
|
63
54
|
end
|
@@ -10,10 +10,10 @@ module FactoryGirl
|
|
10
10
|
check_name
|
11
11
|
end
|
12
12
|
|
13
|
-
def run(instance,
|
13
|
+
def run(instance, evaluator)
|
14
14
|
case block.arity
|
15
15
|
when 1 then block.call(instance)
|
16
|
-
when 2 then block.call(instance,
|
16
|
+
when 2 then block.call(instance, evaluator)
|
17
17
|
else block.call
|
18
18
|
end
|
19
19
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require "active_support/core_ext/class/attribute"
|
2
|
+
|
3
|
+
module FactoryGirl
|
4
|
+
class Evaluator
|
5
|
+
class_attribute :callbacks, :attribute_lists
|
6
|
+
|
7
|
+
def self.attribute_list
|
8
|
+
AttributeList.new.tap do |list|
|
9
|
+
attribute_lists.each do |attribute_list|
|
10
|
+
list.apply_attributes attribute_list.to_a
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
undef_method(:id) if method_defined?(:id)
|
15
|
+
|
16
|
+
def initialize(build_strategy, overrides = {})
|
17
|
+
@build_strategy = build_strategy
|
18
|
+
@overrides = overrides
|
19
|
+
@cached_attributes = overrides
|
20
|
+
|
21
|
+
@build_strategy.add_observer(CallbackRunner.new(self.class.callbacks, self))
|
22
|
+
end
|
23
|
+
|
24
|
+
delegate :association, :to => :@build_strategy
|
25
|
+
|
26
|
+
def instance=(object_instance)
|
27
|
+
@instance = object_instance
|
28
|
+
end
|
29
|
+
|
30
|
+
def method_missing(method_name, *args, &block)
|
31
|
+
if @cached_attributes.key?(method_name)
|
32
|
+
@cached_attributes[method_name]
|
33
|
+
else
|
34
|
+
@instance.send(method_name, *args, &block)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def __overrides
|
39
|
+
@overrides
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
class CallbackRunner
|
45
|
+
def initialize(callbacks, evaluator)
|
46
|
+
@callbacks = callbacks
|
47
|
+
@evaluator = evaluator
|
48
|
+
end
|
49
|
+
|
50
|
+
def update(name, result_instance)
|
51
|
+
@callbacks.select {|callback| callback.name == name }.each do |callback|
|
52
|
+
callback.run(result_instance, @evaluator)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|