factory_girl 2.0.4 → 2.0.5

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 (71) hide show
  1. data/CONTRIBUTION_GUIDELINES.md +1 -0
  2. data/GETTING_STARTED.md +28 -4
  3. data/Gemfile +2 -1
  4. data/Gemfile.lock +6 -2
  5. data/features/factory_girl_steps.feature +17 -0
  6. data/features/step_definitions/database_steps.rb +22 -0
  7. data/features/support/factories.rb +13 -0
  8. data/features/support/test.db +0 -0
  9. data/lib/factory_girl/aliases.rb +1 -3
  10. data/lib/factory_girl/attribute.rb +16 -8
  11. data/lib/factory_girl/attribute/association.rb +0 -3
  12. data/lib/factory_girl/attribute/callback.rb +0 -2
  13. data/lib/factory_girl/attribute/dynamic.rb +1 -3
  14. data/lib/factory_girl/attribute/static.rb +1 -1
  15. data/lib/factory_girl/attribute_list.rb +30 -9
  16. data/lib/factory_girl/factory.rb +1 -1
  17. data/lib/factory_girl/proxy.rb +7 -5
  18. data/lib/factory_girl/proxy/attributes_for.rb +8 -3
  19. data/lib/factory_girl/proxy/build.rb +12 -3
  20. data/lib/factory_girl/proxy/stub.rb +12 -3
  21. data/lib/factory_girl/sequence.rb +2 -2
  22. data/lib/factory_girl/step_definitions.rb +3 -2
  23. data/lib/factory_girl/version.rb +1 -1
  24. data/spec/acceptance/attribute_aliases_spec.rb +0 -1
  25. data/spec/acceptance/attributes_for_spec.rb +0 -1
  26. data/spec/acceptance/attributes_ordered_spec.rb +24 -6
  27. data/spec/acceptance/build_list_spec.rb +0 -1
  28. data/spec/acceptance/build_spec.rb +0 -1
  29. data/spec/acceptance/build_stubbed_spec.rb +0 -1
  30. data/spec/acceptance/callbacks_spec.rb +0 -1
  31. data/spec/acceptance/create_list_spec.rb +0 -1
  32. data/spec/acceptance/create_spec.rb +0 -1
  33. data/spec/acceptance/default_strategy_spec.rb +0 -1
  34. data/spec/acceptance/definition_spec.rb +0 -1
  35. data/spec/acceptance/definition_without_block_spec.rb +0 -1
  36. data/spec/acceptance/overrides_spec.rb +0 -1
  37. data/spec/acceptance/parent_spec.rb +18 -1
  38. data/spec/acceptance/sequence_spec.rb +0 -1
  39. data/spec/acceptance/syntax/blueprint_spec.rb +0 -1
  40. data/spec/acceptance/syntax/generate_spec.rb +0 -1
  41. data/spec/acceptance/syntax/make_spec.rb +0 -1
  42. data/spec/acceptance/syntax/sham_spec.rb +0 -1
  43. data/spec/acceptance/syntax/vintage_spec.rb +27 -29
  44. data/spec/acceptance/traits_spec.rb +0 -1
  45. data/spec/acceptance/transient_attributes_spec.rb +68 -0
  46. data/spec/factory_girl/aliases_spec.rb +19 -21
  47. data/spec/factory_girl/attribute/association_spec.rb +16 -24
  48. data/spec/factory_girl/attribute/callback_spec.rb +14 -15
  49. data/spec/factory_girl/attribute/dynamic_spec.rb +41 -45
  50. data/spec/factory_girl/attribute/implicit_spec.rb +18 -30
  51. data/spec/factory_girl/attribute/sequence_spec.rb +11 -13
  52. data/spec/factory_girl/attribute/static_spec.rb +13 -20
  53. data/spec/factory_girl/attribute_list_spec.rb +9 -1
  54. data/spec/factory_girl/attribute_spec.rb +17 -28
  55. data/spec/factory_girl/definition_proxy_spec.rb +131 -82
  56. data/spec/factory_girl/deprecated_spec.rb +15 -36
  57. data/spec/factory_girl/factory_spec.rb +106 -135
  58. data/spec/factory_girl/find_definitions_spec.rb +7 -6
  59. data/spec/factory_girl/proxy/attributes_for_spec.rb +23 -32
  60. data/spec/factory_girl/proxy/build_spec.rb +6 -80
  61. data/spec/factory_girl/proxy/create_spec.rb +24 -89
  62. data/spec/factory_girl/proxy/stub_spec.rb +14 -73
  63. data/spec/factory_girl/proxy_spec.rb +53 -53
  64. data/spec/factory_girl/registry_spec.rb +13 -29
  65. data/spec/factory_girl/sequence_spec.rb +24 -72
  66. data/spec/factory_girl_spec.rb +10 -5
  67. data/spec/spec_helper.rb +5 -79
  68. data/spec/support/macros/define_constant.rb +86 -0
  69. data/spec/support/shared_examples/proxy.rb +99 -0
  70. metadata +34 -20
  71. data/spec/acceptance/acceptance_helper.rb +0 -11
@@ -3,14 +3,19 @@ module FactoryGirl
3
3
  class AttributesFor < Proxy #:nodoc:
4
4
  def initialize(klass)
5
5
  @hash = {}
6
+ @ignored_attributes = {}
6
7
  end
7
8
 
8
9
  def get(attribute)
9
- @hash[attribute]
10
+ @ignored_attributes[attribute] || @hash[attribute]
10
11
  end
11
12
 
12
- def set(attribute, value)
13
- @hash[attribute] = value
13
+ def set(attribute, value, ignored = false)
14
+ if ignored
15
+ @ignored_attributes[attribute] = value
16
+ else
17
+ @hash[attribute] = value
18
+ end
14
19
  end
15
20
 
16
21
  def result(to_create)
@@ -3,14 +3,23 @@ module FactoryGirl
3
3
  class Build < Proxy #:nodoc:
4
4
  def initialize(klass)
5
5
  @instance = klass.new
6
+ @ignored_attributes = {}
6
7
  end
7
8
 
8
9
  def get(attribute)
9
- @instance.send(attribute)
10
+ if @ignored_attributes.has_key?(attribute)
11
+ @ignored_attributes[attribute]
12
+ else
13
+ @instance.send(attribute)
14
+ end
10
15
  end
11
16
 
12
- def set(attribute, value)
13
- @instance.send(:"#{attribute}=", value)
17
+ def set(attribute, value, ignored = false)
18
+ if ignored
19
+ @ignored_attributes[attribute] = value
20
+ else
21
+ @instance.send(:"#{attribute}=", value)
22
+ end
14
23
  end
15
24
 
16
25
  def associate(name, factory_name, overrides)
@@ -5,6 +5,7 @@ module FactoryGirl
5
5
 
6
6
  def initialize(klass)
7
7
  @instance = klass.new
8
+ @ignored_attributes = {}
8
9
  @instance.id = next_id
9
10
  @instance.instance_eval do
10
11
  def persisted?
@@ -42,11 +43,19 @@ module FactoryGirl
42
43
  end
43
44
 
44
45
  def get(attribute)
45
- @instance.send(attribute)
46
+ if @ignored_attributes.has_key?(attribute)
47
+ @ignored_attributes[attribute]
48
+ else
49
+ @instance.send(attribute)
50
+ end
46
51
  end
47
52
 
48
- def set(attribute, value)
49
- @instance.send(:"#{attribute}=", value)
53
+ def set(attribute, value, ignored = false)
54
+ if ignored
55
+ @ignored_attributes[attribute] = value
56
+ else
57
+ @instance.send(:"#{attribute}=", value)
58
+ end
50
59
  end
51
60
 
52
61
  def associate(name, factory_name, overrides)
@@ -9,9 +9,9 @@ module FactoryGirl
9
9
  attr_reader :name
10
10
 
11
11
  def initialize(name, value = 1, &proc) #:nodoc:
12
- @name = name
12
+ @name = name
13
13
  @proc = proc
14
- @value = value || 1
14
+ @value = value
15
15
  end
16
16
 
17
17
  def next
@@ -21,7 +21,8 @@ module FactoryGirlStepHelpers
21
21
  private
22
22
 
23
23
  def process_key_value(key, value)
24
- [key.downcase.gsub(' ', '_').to_sym, value.to_s.strip]
24
+ value = value.strip if value.is_a?(String)
25
+ [key.downcase.gsub(' ', '_').to_sym, value]
25
26
  end
26
27
 
27
28
  class AssociationManager
@@ -39,7 +40,7 @@ module FactoryGirlStepHelpers
39
40
  return unless association
40
41
 
41
42
  if attributes_hash = nested_attribute_hash
42
- factory.build_class.find(:first, :conditions => attributes_hash.attributes(FindAttributes)) or
43
+ factory.build_class.first(:conditions => attributes_hash.attributes(FindAttributes)) or
43
44
  FactoryGirl.create(association.factory, attributes_hash.attributes)
44
45
  end
45
46
  end
@@ -1,4 +1,4 @@
1
1
  module FactoryGirl
2
- VERSION = "2.0.4"
2
+ VERSION = "2.0.5"
3
3
  end
4
4
 
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'acceptance/acceptance_helper'
3
2
 
4
3
  describe "attribute aliases" do
5
4
  before do
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'acceptance/acceptance_helper'
3
2
 
4
3
  describe "a generated attributes hash" do
5
4
  include FactoryGirl::Syntax::Methods
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'acceptance/acceptance_helper'
3
2
 
4
3
  describe "a generated attributes hash where order matters" do
5
4
  include FactoryGirl::Syntax::Methods
@@ -20,14 +19,33 @@ describe "a generated attributes hash where order matters" do
20
19
  static 1
21
20
  end
22
21
  end
22
+
23
+ factory :without_parent, :class => ParentModel do
24
+ evaluates_first { static }
25
+ evaluates_second { evaluates_first }
26
+ evaluates_third { evaluates_second }
27
+ static 1
28
+ end
23
29
  end
24
30
  end
25
31
 
26
- subject { FactoryGirl.build(:child_model) }
32
+ context "factory with a parent" do
33
+ subject { FactoryGirl.build(:child_model) }
27
34
 
28
- it "assigns attributes in the order they're defined with preference to static attributes" do
29
- subject[:evaluates_first].should == 1
30
- subject[:evaluates_second].should == 1
31
- subject[:evaluates_third].should == 1
35
+ it "assigns attributes in the order they're defined with preference to static attributes" do
36
+ subject[:evaluates_first].should == 1
37
+ subject[:evaluates_second].should == 1
38
+ subject[:evaluates_third].should == 1
39
+ end
40
+ end
41
+
42
+ context "factory without a parent" do
43
+ subject { FactoryGirl.build(:without_parent) }
44
+
45
+ it "assigns attributes in the order they're defined with preference to static attributes without a parent class" do
46
+ subject[:evaluates_first].should == 1
47
+ subject[:evaluates_second].should == 1
48
+ subject[:evaluates_third].should == 1
49
+ end
32
50
  end
33
51
  end
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'acceptance/acceptance_helper'
3
2
 
4
3
  describe "build multiple instances" do
5
4
  before do
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'acceptance/acceptance_helper'
3
2
 
4
3
  describe "a built instance" do
5
4
  include FactoryGirl::Syntax::Methods
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'acceptance/acceptance_helper'
3
2
 
4
3
  describe "a generated stub instance" do
5
4
  include FactoryGirl::Syntax::Methods
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'acceptance/acceptance_helper'
3
2
 
4
3
  describe "callbacks" do
5
4
  before do
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'acceptance/acceptance_helper'
3
2
 
4
3
  describe "create multiple instances" do
5
4
  before do
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'acceptance/acceptance_helper'
3
2
 
4
3
  describe "a created instance" do
5
4
  include FactoryGirl::Syntax::Methods
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'acceptance/acceptance_helper'
3
2
 
4
3
  describe "default strategy" do
5
4
  it "uses create when not specified" do
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'acceptance/acceptance_helper'
3
2
 
4
3
  describe "an instance generated by a factory with a custom class name" do
5
4
  before do
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'acceptance/acceptance_helper'
3
2
 
4
3
  describe "an instance generated by a factory" do
5
4
  before do
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'acceptance/acceptance_helper'
3
2
  require 'active_support/ordered_hash'
4
3
 
5
4
  describe "attribute overrides" do
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'acceptance/acceptance_helper'
3
2
 
4
3
  describe "an instance generated by a factory that inherits from another factory" do
5
4
  before do
@@ -20,6 +19,14 @@ describe "an instance generated by a factory that inherits from another factory"
20
19
  factory :guest do
21
20
  email { "#{name}-guest@example.com" }
22
21
  end
22
+
23
+ factory :no_email do
24
+ email ""
25
+ end
26
+
27
+ factory :bill do
28
+ name { "Bill" } #block to make attribute dynamic
29
+ end
23
30
  end
24
31
  end
25
32
  end
@@ -46,5 +53,15 @@ describe "an instance generated by a factory that inherits from another factory"
46
53
  its(:email) { should eql "John-guest@example.com" }
47
54
  its(:login) { should == "John-guest@example.com" }
48
55
  end
56
+
57
+ describe "the child class redefining parent's dynamic attribute with static attribute" do
58
+ subject { FactoryGirl.create(:no_email) }
59
+ its(:email) { should == "" }
60
+ end
61
+
62
+ describe "the child class redefining parent's static attribute with dynamic attribute" do
63
+ subject { FactoryGirl.create(:bill) }
64
+ its(:name) { should == "Bill" }
65
+ end
49
66
  end
50
67
 
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'acceptance/acceptance_helper'
3
2
 
4
3
  describe "sequences" do
5
4
  include FactoryGirl::Syntax::Methods
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'acceptance/acceptance_helper'
3
2
 
4
3
  require 'factory_girl/syntax/blueprint'
5
4
 
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'acceptance/acceptance_helper'
3
2
 
4
3
  require 'factory_girl/syntax/generate'
5
4
 
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'acceptance/acceptance_helper'
3
2
 
4
3
  require 'factory_girl/syntax/make'
5
4
 
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'acceptance/acceptance_helper'
3
2
 
4
3
  require 'factory_girl/syntax/sham'
5
4
 
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'acceptance/acceptance_helper'
3
2
 
4
3
  describe "vintage syntax" do
5
4
  before do
@@ -64,17 +63,17 @@ end
64
63
  describe "defining a factory" do
65
64
  before do
66
65
  @name = :user
67
- @factory = "factory"
66
+ @factory = stub("factory", :names => [@name])
68
67
  @proxy = "proxy"
69
- stub(@factory).names { [@name] }
70
68
  @options = { :class => 'magic' }
71
- stub(FactoryGirl::Factory).new { @factory }
72
- stub(FactoryGirl::DefinitionProxy).new { @proxy }
69
+ FactoryGirl::Factory.stubs(:new => @factory)
70
+ FactoryGirl::DefinitionProxy.stubs(:new => @proxy)
73
71
  end
74
72
 
75
73
  it "should create a new factory using the specified name and options" do
76
- mock(FactoryGirl::Factory).new(@name, @options) { @factory }
74
+ FactoryGirl::Factory.stubs(:new => @factory)
77
75
  Factory.define(@name, @options) {|f| }
76
+ FactoryGirl::Factory.should have_received(:new).with(@name, @options)
78
77
  end
79
78
 
80
79
  it "should pass the factory do the block" do
@@ -100,44 +99,48 @@ describe "after defining a factory" do
100
99
  end
101
100
 
102
101
  it "should use Proxy::AttributesFor for Factory.attributes_for" do
103
- mock(@factory).run(FactoryGirl::Proxy::AttributesFor, :attr => 'value') { 'result' }
102
+ @factory.stubs(:run => "result")
104
103
  Factory.attributes_for(@name, :attr => 'value').should == 'result'
104
+ @factory.should have_received(:run).with(FactoryGirl::Proxy::AttributesFor, :attr => 'value')
105
105
  end
106
106
 
107
107
  it "should use Proxy::Build for Factory.build" do
108
- mock(@factory).run(FactoryGirl::Proxy::Build, :attr => 'value') { 'result' }
108
+ @factory.stubs(:run => "result")
109
109
  Factory.build(@name, :attr => 'value').should == 'result'
110
+ @factory.should have_received(:run).with(FactoryGirl::Proxy::Build, :attr => 'value')
110
111
  end
111
112
 
112
113
  it "should use Proxy::Create for Factory.create" do
113
- mock(@factory).run(FactoryGirl::Proxy::Create, :attr => 'value') { 'result' }
114
+ @factory.stubs(:run => "result")
114
115
  Factory.create(@name, :attr => 'value').should == 'result'
116
+ @factory.should have_received(:run).with(FactoryGirl::Proxy::Create, :attr => 'value')
115
117
  end
116
118
 
117
119
  it "should use Proxy::Stub for Factory.stub" do
118
- mock(@factory).run(FactoryGirl::Proxy::Stub, :attr => 'value') { 'result' }
120
+ @factory.stubs(:run => "result")
119
121
  Factory.stub(@name, :attr => 'value').should == 'result'
122
+ @factory.should have_received(:run).with(FactoryGirl::Proxy::Stub, :attr => 'value')
120
123
  end
121
124
 
122
125
  it "should use default strategy option as Factory.default_strategy" do
123
- stub(@factory).default_strategy { :create }
124
- mock(@factory).run(FactoryGirl::Proxy::Create, :attr => 'value') { 'result' }
126
+ @factory.stubs(:default_strategy => :create, :run => "result")
125
127
  Factory.default_strategy(@name, :attr => 'value').should == 'result'
128
+ @factory.should have_received(:run).with(FactoryGirl::Proxy::Create, :attr => 'value')
126
129
  end
127
130
 
128
131
  it "should use the default strategy for the global Factory method" do
129
- stub(@factory).default_strategy { :create }
130
- mock(@factory).run(FactoryGirl::Proxy::Create, :attr => 'value') { 'result' }
132
+ @factory.stubs(:default_strategy => :create, :run => "result")
131
133
  Factory(@name, :attr => 'value').should == 'result'
134
+ @factory.should have_received(:run).with(FactoryGirl::Proxy::Create, :attr => 'value')
132
135
  end
133
136
 
134
137
  [:build, :create, :attributes_for, :stub].each do |method|
135
- it "should raise an ArgumentError on #{method} with a nonexistant factory" do
138
+ it "should raise an ArgumentError on #{method} with a nonexistent factory" do
136
139
  lambda { Factory.send(method, :bogus) }.should raise_error(ArgumentError)
137
140
  end
138
141
 
139
142
  it "should recognize either 'name' or :name for Factory.#{method}" do
140
- stub(@factory).run
143
+ @factory.stubs(:run)
141
144
  lambda { Factory.send(method, @name.to_s) }.should_not raise_error
142
145
  lambda { Factory.send(method, @name.to_sym) }.should_not raise_error
143
146
  end
@@ -146,26 +149,22 @@ end
146
149
 
147
150
  describe "defining a sequence" do
148
151
  before do
149
- @name = :count
150
- @sequence = FactoryGirl::Sequence.new(@name) {}
151
- stub(FactoryGirl::Sequence).new { @sequence }
152
+ @name = :count
152
153
  end
153
154
 
154
155
  it "should create a new sequence" do
155
- mock(FactoryGirl::Sequence).new(@name, 1) { @sequence }
156
156
  Factory.sequence(@name)
157
+ Factory.next(@name).should == 1
157
158
  end
158
159
 
159
160
  it "should use the supplied block as the sequence generator" do
160
- stub(FactoryGirl::Sequence).new { @sequence }.yields(1)
161
- yielded = false
162
- Factory.sequence(@name) {|n| yielded = true }
163
- (yielded).should be
161
+ Factory.sequence(@name) {|n| "user-#{n}" }
162
+ Factory.next(@name).should == "user-1"
164
163
  end
165
164
 
166
165
  it "should use the supplied start_value as the sequence start_value" do
167
- mock(FactoryGirl::Sequence).new(@name, "A") { @sequence }
168
166
  Factory.sequence(@name, "A")
167
+ Factory.next(@name).should == "A"
169
168
  end
170
169
  end
171
170
 
@@ -175,16 +174,15 @@ describe "after defining a sequence" do
175
174
  @sequence = FactoryGirl::Sequence.new(@name) {}
176
175
  @value = '1 2 5'
177
176
 
178
- stub(@sequence).next { @value }
179
- stub(FactoryGirl::Sequence).new { @sequence }
177
+ @sequence.stubs(:next => @value)
178
+ FactoryGirl::Sequence.stubs(:new => @sequence)
180
179
 
181
180
  Factory.sequence(@name) {}
182
181
  end
183
182
 
184
183
  it "should call next on the sequence when sent next" do
185
- mock(@sequence).next
186
-
187
184
  Factory.next(@name)
185
+ @sequence.should have_received(:next)
188
186
  end
189
187
 
190
188
  it "should return the value from the sequence" do