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
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "activerecord", "~> 2.3"
6
+
7
+ gemspec :path=>"../"
@@ -0,0 +1,71 @@
1
+ PATH
2
+ remote: /Users/joshuaclayton/dev/gems/factory_girl
3
+ specs:
4
+ factory_girl (2.1.0)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ activerecord (2.3.12)
10
+ activesupport (= 2.3.12)
11
+ activesupport (2.3.12)
12
+ appraisal (0.3.8)
13
+ bundler
14
+ rake
15
+ aruba (0.3.7)
16
+ childprocess (>= 0.1.9)
17
+ cucumber (>= 0.10.5)
18
+ rspec (>= 2.6.0)
19
+ bluecloth (2.1.0)
20
+ bourne (1.0)
21
+ mocha (= 0.9.8)
22
+ builder (3.0.0)
23
+ childprocess (0.1.9)
24
+ ffi (~> 1.0.6)
25
+ cucumber (1.0.0)
26
+ builder (>= 2.1.2)
27
+ diff-lcs (>= 1.1.2)
28
+ gherkin (~> 2.4.1)
29
+ json (>= 1.4.6)
30
+ term-ansicolor (>= 1.0.5)
31
+ diff-lcs (1.1.2)
32
+ ffi (1.0.9)
33
+ gherkin (2.4.1)
34
+ json (>= 1.4.6)
35
+ json (1.5.3)
36
+ mocha (0.9.8)
37
+ rake
38
+ rake (0.9.2)
39
+ rcov (0.9.9)
40
+ rspec (2.6.0)
41
+ rspec-core (~> 2.6.0)
42
+ rspec-expectations (~> 2.6.0)
43
+ rspec-mocks (~> 2.6.0)
44
+ rspec-core (2.6.4)
45
+ rspec-expectations (2.6.0)
46
+ diff-lcs (~> 1.1.2)
47
+ rspec-mocks (2.6.0)
48
+ sqlite3 (1.3.3)
49
+ sqlite3-ruby (1.3.3)
50
+ sqlite3 (>= 1.3.3)
51
+ term-ansicolor (1.0.5)
52
+ timecop (0.3.5)
53
+ yard (0.7.2)
54
+
55
+ PLATFORMS
56
+ ruby
57
+
58
+ DEPENDENCIES
59
+ activerecord (~> 2.3)
60
+ appraisal (~> 0.3.8)
61
+ aruba
62
+ bluecloth
63
+ bourne
64
+ cucumber (~> 1.0.0)
65
+ factory_girl!
66
+ mocha
67
+ rcov
68
+ rspec (~> 2.0)
69
+ sqlite3-ruby
70
+ timecop
71
+ yard
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "activerecord", "~> 3.0"
6
+
7
+ gemspec :path=>"../"
@@ -0,0 +1,81 @@
1
+ PATH
2
+ remote: /Users/joshuaclayton/dev/gems/factory_girl
3
+ specs:
4
+ factory_girl (2.1.0)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ activemodel (3.0.9)
10
+ activesupport (= 3.0.9)
11
+ builder (~> 2.1.2)
12
+ i18n (~> 0.5.0)
13
+ activerecord (3.0.9)
14
+ activemodel (= 3.0.9)
15
+ activesupport (= 3.0.9)
16
+ arel (~> 2.0.10)
17
+ tzinfo (~> 0.3.23)
18
+ activesupport (3.0.9)
19
+ appraisal (0.3.8)
20
+ bundler
21
+ rake
22
+ arel (2.0.10)
23
+ aruba (0.3.7)
24
+ childprocess (>= 0.1.9)
25
+ cucumber (>= 0.10.5)
26
+ rspec (>= 2.6.0)
27
+ bluecloth (2.1.0)
28
+ bourne (1.0)
29
+ mocha (= 0.9.8)
30
+ builder (2.1.2)
31
+ childprocess (0.1.9)
32
+ ffi (~> 1.0.6)
33
+ cucumber (1.0.0)
34
+ builder (>= 2.1.2)
35
+ diff-lcs (>= 1.1.2)
36
+ gherkin (~> 2.4.1)
37
+ json (>= 1.4.6)
38
+ term-ansicolor (>= 1.0.5)
39
+ diff-lcs (1.1.2)
40
+ ffi (1.0.9)
41
+ gherkin (2.4.1)
42
+ json (>= 1.4.6)
43
+ i18n (0.5.0)
44
+ json (1.5.3)
45
+ mocha (0.9.8)
46
+ rake
47
+ rake (0.9.2)
48
+ rcov (0.9.9)
49
+ rspec (2.6.0)
50
+ rspec-core (~> 2.6.0)
51
+ rspec-expectations (~> 2.6.0)
52
+ rspec-mocks (~> 2.6.0)
53
+ rspec-core (2.6.4)
54
+ rspec-expectations (2.6.0)
55
+ diff-lcs (~> 1.1.2)
56
+ rspec-mocks (2.6.0)
57
+ sqlite3 (1.3.3)
58
+ sqlite3-ruby (1.3.3)
59
+ sqlite3 (>= 1.3.3)
60
+ term-ansicolor (1.0.5)
61
+ timecop (0.3.5)
62
+ tzinfo (0.3.28)
63
+ yard (0.7.2)
64
+
65
+ PLATFORMS
66
+ ruby
67
+
68
+ DEPENDENCIES
69
+ activerecord (~> 3.0)
70
+ appraisal (~> 0.3.8)
71
+ aruba
72
+ bluecloth
73
+ bourne
74
+ cucumber (~> 1.0.0)
75
+ factory_girl!
76
+ mocha
77
+ rcov
78
+ rspec (~> 2.0)
79
+ sqlite3-ruby
80
+ timecop
81
+ yard
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "activerecord", "~> 3.1"
6
+
7
+ gemspec :path=>"../"
@@ -0,0 +1,91 @@
1
+ PATH
2
+ remote: /Users/joshuaclayton/dev/gems/factory_girl
3
+ specs:
4
+ factory_girl (2.1.0)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ activemodel (3.1.0)
10
+ activesupport (= 3.1.0)
11
+ bcrypt-ruby (~> 3.0.0)
12
+ builder (~> 3.0.0)
13
+ i18n (~> 0.6)
14
+ activerecord (3.1.0)
15
+ activemodel (= 3.1.0)
16
+ activesupport (= 3.1.0)
17
+ arel (~> 2.2.1)
18
+ tzinfo (~> 0.3.29)
19
+ activesupport (3.1.0)
20
+ multi_json (~> 1.0)
21
+ appraisal (0.3.8)
22
+ bundler
23
+ rake
24
+ arel (2.2.1)
25
+ aruba (0.4.5)
26
+ bcat (>= 0.6.1)
27
+ childprocess (>= 0.1.9)
28
+ cucumber (>= 0.10.7)
29
+ rdiscount (>= 1.6.8)
30
+ rspec (>= 2.6.0)
31
+ bcat (0.6.1)
32
+ rack (~> 1.0)
33
+ bcrypt-ruby (3.0.0)
34
+ bluecloth (2.1.0)
35
+ bourne (1.0)
36
+ mocha (= 0.9.8)
37
+ builder (3.0.0)
38
+ childprocess (0.2.1)
39
+ ffi (~> 1.0.6)
40
+ cucumber (1.0.2)
41
+ builder (>= 2.1.2)
42
+ diff-lcs (>= 1.1.2)
43
+ gherkin (~> 2.4.5)
44
+ json (>= 1.4.6)
45
+ term-ansicolor (>= 1.0.5)
46
+ diff-lcs (1.1.3)
47
+ ffi (1.0.9)
48
+ gherkin (2.4.16)
49
+ json (>= 1.4.6)
50
+ i18n (0.6.0)
51
+ json (1.5.4)
52
+ mocha (0.9.8)
53
+ rake
54
+ multi_json (1.0.3)
55
+ rack (1.3.2)
56
+ rake (0.9.2)
57
+ rcov (0.9.10)
58
+ rdiscount (1.6.8)
59
+ rspec (2.6.0)
60
+ rspec-core (~> 2.6.0)
61
+ rspec-expectations (~> 2.6.0)
62
+ rspec-mocks (~> 2.6.0)
63
+ rspec-core (2.6.4)
64
+ rspec-expectations (2.6.0)
65
+ diff-lcs (~> 1.1.2)
66
+ rspec-mocks (2.6.0)
67
+ sqlite3 (1.3.4)
68
+ sqlite3-ruby (1.3.3)
69
+ sqlite3 (>= 1.3.3)
70
+ term-ansicolor (1.0.6)
71
+ timecop (0.3.5)
72
+ tzinfo (0.3.29)
73
+ yard (0.7.2)
74
+
75
+ PLATFORMS
76
+ ruby
77
+
78
+ DEPENDENCIES
79
+ activerecord (~> 3.1)
80
+ appraisal (~> 0.3.8)
81
+ aruba
82
+ bluecloth
83
+ bourne
84
+ cucumber (~> 1.0.0)
85
+ factory_girl!
86
+ mocha
87
+ rcov
88
+ rspec (~> 2.0)
89
+ sqlite3-ruby
90
+ timecop
91
+ yard
data/lib/factory_girl.rb CHANGED
@@ -22,6 +22,7 @@ require 'factory_girl/syntax/methods'
22
22
  require 'factory_girl/syntax/default'
23
23
  require 'factory_girl/syntax/vintage'
24
24
  require 'factory_girl/find_definitions'
25
+ require 'factory_girl/reload'
25
26
  require 'factory_girl/deprecated'
26
27
  require 'factory_girl/version'
27
28
 
@@ -42,6 +42,10 @@ module FactoryGirl
42
42
  self.priority <=> another.priority
43
43
  end
44
44
 
45
+ def ==(another)
46
+ self.object_id == another.object_id
47
+ end
48
+
45
49
  private
46
50
 
47
51
  def ensure_non_attribute_writer!
@@ -3,11 +3,12 @@ module FactoryGirl
3
3
  include Enumerable
4
4
 
5
5
  def initialize
6
- @attributes = {}
6
+ @attributes = {}
7
+ @overridable = false
7
8
  end
8
9
 
9
10
  def define_attribute(attribute)
10
- if attribute_defined?(attribute.name)
11
+ if !overridable? && attribute_defined?(attribute.name)
11
12
  raise AttributeDefinitionError, "Attribute already defined: #{attribute.name}"
12
13
  end
13
14
 
@@ -27,30 +28,34 @@ module FactoryGirl
27
28
  end
28
29
 
29
30
  def attribute_defined?(attribute_name)
30
- !@attributes.values.flatten.detect do |attribute|
31
- attribute.name == attribute_name &&
32
- !attribute.is_a?(FactoryGirl::Attribute::Callback)
33
- end.nil?
31
+ !!find_attribute(attribute_name)
34
32
  end
35
33
 
36
34
  def apply_attributes(attributes_to_apply)
37
35
  new_attributes = []
38
36
 
39
37
  attributes_to_apply.each do |attribute|
40
- if attribute_defined?(attribute.name)
41
- @attributes.each_value do |attributes|
42
- attributes.delete_if do |attrib|
43
- new_attributes << attrib.clone if attrib.name == attribute.name
44
- end
45
- end
38
+ new_attribute = if !overridable? && defined_attribute = find_attribute(attribute.name)
39
+ defined_attribute
46
40
  else
47
- new_attributes << attribute.clone
41
+ attribute
48
42
  end
43
+
44
+ delete_attribute(attribute.name)
45
+ new_attributes << new_attribute
49
46
  end
50
47
 
51
48
  prepend_attributes new_attributes
52
49
  end
53
50
 
51
+ def overridable
52
+ @overridable = true
53
+ end
54
+
55
+ def overridable?
56
+ @overridable
57
+ end
58
+
54
59
  private
55
60
 
56
61
  def valid_callback_names
@@ -58,6 +63,8 @@ module FactoryGirl
58
63
  end
59
64
 
60
65
  def add_attribute(attribute)
66
+ delete_attribute(attribute.name) if overridable?
67
+
61
68
  @attributes[attribute.priority] ||= []
62
69
  @attributes[attribute.priority] << attribute
63
70
  attribute
@@ -76,5 +83,20 @@ module FactoryGirl
76
83
  result
77
84
  end.flatten
78
85
  end
86
+
87
+ def find_attribute(attribute_name)
88
+ @attributes.values.flatten.detect do |attribute|
89
+ attribute.name == attribute_name &&
90
+ !attribute.is_a?(FactoryGirl::Attribute::Callback)
91
+ end
92
+ end
93
+
94
+ def delete_attribute(attribute_name)
95
+ if attribute_defined?(attribute_name)
96
+ @attributes.each_value do |attributes|
97
+ attributes.delete_if {|attrib| attrib.name == attribute_name }
98
+ end
99
+ end
100
+ end
79
101
  end
80
102
  end
@@ -34,18 +34,37 @@ module FactoryGirl
34
34
 
35
35
  def initialize(name, options = {}) #:nodoc:
36
36
  assert_valid_options(options)
37
- @name = factory_name_for(name)
38
- @parent = options[:parent]
39
- @options = options
40
- @attribute_list = AttributeList.new
41
- @traits = []
37
+ @name = factory_name_for(name)
38
+ @parent = options[:parent]
39
+ @options = options
40
+ @traits = []
41
+ @children = []
42
+ @attribute_list = AttributeList.new
43
+ @inherited_attribute_list = AttributeList.new
44
+ end
45
+
46
+ def allow_overrides
47
+ @attribute_list.overridable
48
+ @inherited_attribute_list.overridable
49
+ self
50
+ end
51
+
52
+ def allow_overrides?
53
+ @attribute_list.overridable?
42
54
  end
43
55
 
44
56
  def inherit_from(parent) #:nodoc:
45
57
  @options[:class] ||= parent.class_name
46
58
  @options[:default_strategy] ||= parent.default_strategy
47
59
 
48
- apply_attributes(parent.attributes)
60
+ allow_overrides if parent.allow_overrides?
61
+ parent.add_child(self)
62
+
63
+ @inherited_attribute_list.apply_attributes(parent.attributes)
64
+ end
65
+
66
+ def add_child(factory)
67
+ @children << factory unless @children.include?(factory)
49
68
  end
50
69
 
51
70
  def apply_traits(traits) #:nodoc:
@@ -63,7 +82,7 @@ module FactoryGirl
63
82
  raise AssociationDefinitionError, "Self-referencing association '#{attribute.name}' in factory '#{self.name}'"
64
83
  end
65
84
 
66
- @attribute_list.define_attribute(attribute)
85
+ @attribute_list.define_attribute(attribute).tap { update_children }
67
86
  end
68
87
 
69
88
  def define_trait(trait)
@@ -75,13 +94,17 @@ module FactoryGirl
75
94
  end
76
95
 
77
96
  def attributes
78
- @attribute_list.to_a
97
+ AttributeList.new.tap do |list|
98
+ list.apply_attributes(@attribute_list)
99
+ list.apply_attributes(@inherited_attribute_list)
100
+ end.to_a
79
101
  end
80
102
 
81
103
  def run(proxy_class, overrides) #:nodoc:
82
104
  proxy = proxy_class.new(build_class)
83
105
  overrides = symbolize_keys(overrides)
84
- @attribute_list.each do |attribute|
106
+
107
+ attributes.each do |attribute|
85
108
  factory_overrides = overrides.select { |attr, val| attribute.aliases_for?(attr) }
86
109
  if factory_overrides.empty?
87
110
  attribute.add_to(proxy)
@@ -146,6 +169,10 @@ module FactoryGirl
146
169
 
147
170
  private
148
171
 
172
+ def update_children
173
+ @children.each { |child| child.inherit_from(self) }
174
+ end
175
+
149
176
  def class_for (class_or_to_s)
150
177
  if class_or_to_s.respond_to?(:to_sym)
151
178
  class_name = variable_name_to_class_name(class_or_to_s)