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.
Files changed (58) hide show
  1. data/.travis.yml +5 -3
  2. data/Appraisals +4 -0
  3. data/CONTRIBUTION_GUIDELINES.md +1 -1
  4. data/Changelog +13 -0
  5. data/GETTING_STARTED.md +362 -286
  6. data/Gemfile.lock +1 -1
  7. data/README.md +8 -8
  8. data/features/factory_girl_steps.feature +4 -0
  9. data/features/support/factories.rb +19 -0
  10. data/gemfiles/2.1.gemfile.lock +1 -1
  11. data/gemfiles/2.3.gemfile.lock +1 -1
  12. data/gemfiles/3.0.gemfile.lock +1 -1
  13. data/gemfiles/3.1.gemfile.lock +1 -1
  14. data/gemfiles/3.2.gemfile +7 -0
  15. data/gemfiles/3.2.gemfile.lock +90 -0
  16. data/lib/factory_girl.rb +4 -0
  17. data/lib/factory_girl/attribute.rb +1 -9
  18. data/lib/factory_girl/attribute/association.rb +2 -2
  19. data/lib/factory_girl/attribute/dynamic.rb +2 -2
  20. data/lib/factory_girl/attribute/sequence.rb +1 -1
  21. data/lib/factory_girl/attribute/static.rb +1 -1
  22. data/lib/factory_girl/attribute_assigner.rb +73 -0
  23. data/lib/factory_girl/attribute_list.rb +6 -15
  24. data/lib/factory_girl/callback.rb +2 -2
  25. data/lib/factory_girl/evaluator.rb +57 -0
  26. data/lib/factory_girl/evaluator_class_definer.rb +34 -0
  27. data/lib/factory_girl/factory.rb +31 -80
  28. data/lib/factory_girl/null_factory.rb +2 -1
  29. data/lib/factory_girl/null_object.rb +19 -0
  30. data/lib/factory_girl/proxy.rb +6 -87
  31. data/lib/factory_girl/proxy/attributes_for.rb +2 -7
  32. data/lib/factory_girl/proxy/build.rb +4 -3
  33. data/lib/factory_girl/proxy/create.rb +6 -7
  34. data/lib/factory_girl/proxy/stub.rb +19 -18
  35. data/lib/factory_girl/step_definitions.rb +4 -3
  36. data/lib/factory_girl/version.rb +1 -1
  37. data/spec/acceptance/aliases_spec.rb +19 -0
  38. data/spec/acceptance/attributes_for_spec.rb +10 -1
  39. data/spec/acceptance/attributes_from_instance_spec.rb +53 -0
  40. data/spec/acceptance/build_spec.rb +8 -0
  41. data/spec/acceptance/build_stubbed_spec.rb +9 -0
  42. data/spec/acceptance/create_spec.rb +8 -0
  43. data/spec/factory_girl/attribute/association_spec.rb +5 -4
  44. data/spec/factory_girl/attribute/dynamic_spec.rb +9 -10
  45. data/spec/factory_girl/attribute/sequence_spec.rb +1 -2
  46. data/spec/factory_girl/attribute/static_spec.rb +1 -2
  47. data/spec/factory_girl/attribute_list_spec.rb +14 -4
  48. data/spec/factory_girl/evaluator_class_definer_spec.rb +54 -0
  49. data/spec/factory_girl/factory_spec.rb +23 -16
  50. data/spec/factory_girl/null_factory_spec.rb +2 -1
  51. data/spec/factory_girl/null_object_spec.rb +8 -0
  52. data/spec/factory_girl/proxy/attributes_for_spec.rb +8 -24
  53. data/spec/factory_girl/proxy/build_spec.rb +1 -7
  54. data/spec/factory_girl/proxy/create_spec.rb +2 -27
  55. data/spec/factory_girl/proxy/stub_spec.rb +14 -13
  56. data/spec/factory_girl/proxy_spec.rb +1 -33
  57. data/spec/support/shared_examples/proxy.rb +22 -45
  58. metadata +133 -177
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- factory_girl (2.3.2)
4
+ factory_girl (2.4.0)
5
5
  activesupport
6
6
 
7
7
  GEM
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](http://github.com/thoughtbot/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](http://rubygems.org/gems/factory_girl).
11
+ You should find the documentation for your version of factory_girl on [Rubygems](https://rubygems.org/gems/factory_girl).
12
12
 
13
- See {file:GETTING_STARTED.md} for information on defining and using factories.
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](http://rubygems.org/gems/factory_girl)
31
+ * [Rubygems](https://rubygems.org/gems/factory_girl)
32
32
  * [Mailing list](http://groups.google.com/group/factory_girl)
33
- * [Issues](http://github.com/thoughtbot/factory_girl/issues)
34
- * [GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS](http://giantrobots.thoughtbot.com)
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](http://github.com/thoughtbot/factory_girl/blob/master/CONTRIBUTION_GUIDELINES.md).
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'
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: /Users/joshuaclayton/dev/gems/factory_girl
3
3
  specs:
4
- factory_girl (2.3.2)
4
+ factory_girl (2.4.0)
5
5
  activesupport
6
6
 
7
7
  GEM
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: /Users/joshuaclayton/dev/gems/factory_girl
3
3
  specs:
4
- factory_girl (2.3.2)
4
+ factory_girl (2.4.0)
5
5
  activesupport
6
6
 
7
7
  GEM
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: /Users/joshuaclayton/dev/gems/factory_girl
3
3
  specs:
4
- factory_girl (2.3.2)
4
+ factory_girl (2.4.0)
5
5
  activesupport
6
6
 
7
7
  GEM
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: /Users/joshuaclayton/dev/gems/factory_girl
3
3
  specs:
4
- factory_girl (2.3.2)
4
+ factory_girl (2.4.0)
5
5
  activesupport
6
6
 
7
7
  GEM
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "activerecord", "~> 3.2.0.rc2"
6
+
7
+ gemspec :path=>"../"
@@ -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
@@ -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 add_to(proxy)
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(proxy)
12
+ def to_proc
13
13
  factory = @factory
14
14
  overrides = @overrides
15
- lambda { proxy.association(factory, overrides) }
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(proxy)
9
+ def to_proc
10
10
  block = @block
11
11
 
12
12
  lambda {
13
- value = block.arity == 1 ? block.call(proxy) : proxy.instance_exec(&block)
13
+ value = block.arity == 1 ? block.call(self) : instance_exec(&block)
14
14
  raise SequenceAbuseError if FactoryGirl::Sequence === value
15
15
  value
16
16
  }
@@ -7,7 +7,7 @@ module FactoryGirl
7
7
  @sequence = sequence
8
8
  end
9
9
 
10
- def to_proc(proxy)
10
+ def to_proc
11
11
  sequence = @sequence
12
12
  lambda { FactoryGirl.generate(sequence) }
13
13
  end
@@ -6,7 +6,7 @@ module FactoryGirl
6
6
  @value = value
7
7
  end
8
8
 
9
- def to_proc(proxy)
9
+ def to_proc
10
10
  value = @value
11
11
  lambda { value }
12
12
  end
@@ -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 apply_attributes(attributes_to_apply)
22
- attributes_to_apply.each do |attribute|
23
- new_attribute = find_attribute(attribute.name) || attribute
24
- delete_attribute(attribute.name)
21
+ def associations
22
+ @attributes.select(&:association?)
23
+ end
25
24
 
26
- add_attribute new_attribute
27
- end
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
- !!find_attribute(attribute_name)
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, proxy)
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, proxy)
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