factory_girl 2.0.4 → 2.0.5

Sign up to get free protection for your applications and to get access to all the features.
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