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
@@ -1,10 +1,16 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe FactoryGirl::Registry do
4
- let(:factory) { FactoryGirl::Factory.new(:object) }
4
+ let(:aliases) { [:thing, :widget] }
5
+ let(:sequence) { FactoryGirl::Sequence.new(:email) { |n| "somebody#{n}@example.com" } }
6
+ let(:factory) { FactoryGirl::Factory.new(:object) }
7
+ let(:other_factory) { FactoryGirl::Factory.new(:string) }
8
+ let(:factory_with_aliases) { FactoryGirl::Factory.new(:string, :aliases => aliases) }
5
9
 
6
10
  subject { FactoryGirl::Registry.new }
7
11
 
12
+ it { should be_kind_of(Enumerable) }
13
+
8
14
  it "finds a registered a factory" do
9
15
  subject.add(factory)
10
16
  subject.find(factory.name).should == factory
@@ -38,33 +44,18 @@ describe FactoryGirl::Registry do
38
44
  end
39
45
 
40
46
  it "iterates registered factories" do
41
- other_factory = FactoryGirl::Factory.new(:string)
42
47
  subject.add(factory)
43
48
  subject.add(other_factory)
44
- result = []
45
-
46
- subject.each do |value|
47
- result << value
48
- end
49
-
50
- result.should =~ [factory, other_factory]
49
+ subject.to_a.should =~ [factory, other_factory]
51
50
  end
52
51
 
53
52
  it "iterates registered factories uniquely with aliases" do
54
- other_factory = FactoryGirl::Factory.new(:string, :aliases => [:awesome])
55
53
  subject.add(factory)
56
- subject.add(other_factory)
57
- result = []
58
-
59
- subject.each do |value|
60
- result << value
61
- end
62
-
63
- result.should =~ [factory, other_factory]
54
+ subject.add(factory_with_aliases)
55
+ subject.to_a.should =~ [factory, factory_with_aliases]
64
56
  end
65
57
 
66
58
  it "registers an sequence" do
67
- sequence = FactoryGirl::Sequence.new(:email) { |n| "somebody#{n}@example.com" }
68
59
  subject.add(sequence)
69
60
  subject.find(:email).should == sequence
70
61
  end
@@ -75,22 +66,15 @@ describe FactoryGirl::Registry do
75
66
  end
76
67
 
77
68
  it "registers aliases" do
78
- aliases = [:thing, :widget]
79
- factory = FactoryGirl::Factory.new(:object, :aliases => aliases)
80
- subject.add(factory)
69
+ subject.add(factory_with_aliases)
81
70
  aliases.each do |name|
82
- subject.find(name).should == factory
71
+ subject.find(name).should == factory_with_aliases
83
72
  end
84
73
  end
85
74
 
86
- it "is enumerable" do
87
- should be_kind_of(Enumerable)
88
- end
89
-
90
75
  it "clears registered factories" do
91
76
  subject.add(factory)
92
77
  subject.clear
93
- subject.count.should == 0
78
+ subject.count.should be_zero
94
79
  end
95
80
  end
96
-
@@ -2,95 +2,47 @@ require 'spec_helper'
2
2
 
3
3
  describe FactoryGirl::Sequence do
4
4
  describe "a basic sequence" do
5
- before do
6
- @name = :test
7
- @sequence = FactoryGirl::Sequence.new(@name) {|n| "=#{n}" }
8
- end
9
-
10
- it "has a name" do
11
- @sequence.name.should == @name
12
- end
5
+ let(:name) { :test }
6
+ subject { FactoryGirl::Sequence.new(name) {|n| "=#{n}" } }
13
7
 
14
- it "has names" do
15
- @sequence.names.should == [@name]
16
- end
17
-
18
- it "should start with a value of 1" do
19
- @sequence.next.should == "=1"
20
- end
8
+ its(:name) { should == name }
9
+ its(:names) { should == [name] }
10
+ its(:next) { should == "=1" }
11
+ its(:default_strategy) { should == :create }
21
12
 
22
- it "responds to default_strategy" do
23
- @sequence.default_strategy.should == :create
24
- end
25
-
26
- describe "after being called" do
27
- before do
28
- @sequence.next
29
- end
30
-
31
- it "should use the next value" do
32
- @sequence.next.should == "=2"
33
- end
13
+ describe "when incrementing" do
14
+ before { subject.next }
15
+ its(:next) { should == "=2" }
34
16
  end
35
17
  end
36
18
 
37
19
  describe "a custom sequence" do
38
- before do
39
- @sequence = FactoryGirl::Sequence.new(:name, "A") {|n| "=#{n}" }
40
- end
20
+ subject { FactoryGirl::Sequence.new(:name, "A") {|n| "=#{n}" } }
21
+ its(:next) { should == "=A" }
41
22
 
42
- it "should start with a value of A" do
43
- @sequence.next.should == "=A"
44
- end
45
-
46
- describe "after being called" do
47
- before do
48
- @sequence.next
49
- end
50
-
51
- it "should use the next value" do
52
- @sequence.next.should == "=B"
53
- end
23
+ describe "when incrementing" do
24
+ before { subject.next }
25
+ its(:next) { should == "=B" }
54
26
  end
55
27
  end
56
28
 
57
29
  describe "a basic sequence without a block" do
58
- before do
59
- @sequence = FactoryGirl::Sequence.new(:name)
60
- end
61
-
62
- it "should start with a value of 1" do
63
- @sequence.next.should == 1
64
- end
30
+ subject { FactoryGirl::Sequence.new(:name) }
31
+ its(:next) { should == 1 }
65
32
 
66
- describe "after being called" do
67
- before do
68
- @sequence.next
69
- end
70
-
71
- it "should use the next value" do
72
- @sequence.next.should == 2
73
- end
33
+ describe "when incrementing" do
34
+ before { subject.next }
35
+ its(:next) { should == 2 }
74
36
  end
75
37
  end
76
38
 
77
39
  describe "a custom sequence without a block" do
78
- before do
79
- @sequence = FactoryGirl::Sequence.new(:name, "A")
80
- end
81
-
82
- it "should start with a value of A" do
83
- @sequence.next.should == "A"
84
- end
85
-
86
- describe "after being called" do
87
- before do
88
- @sequence.next
89
- end
40
+ subject { FactoryGirl::Sequence.new(:name, "A") }
41
+ its(:next) { should == "A" }
90
42
 
91
- it "should use the next value" do
92
- @sequence.next.should == "B"
93
- end
43
+ describe "when incrementing" do
44
+ before { subject.next }
45
+ its(:next) { should == "B" }
94
46
  end
95
47
  end
96
48
  end
@@ -1,17 +1,22 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  describe FactoryGirl do
4
- let(:factory) { FactoryGirl::Factory.new(:object) }
4
+ let(:factory) { FactoryGirl::Factory.new(:object) }
5
5
  let(:sequence) { FactoryGirl::Sequence.new(:email) }
6
+ let(:trait) { FactoryGirl::Trait.new(:admin) }
6
7
 
7
- it "finds a registered a factory" do
8
+ it "finds a registered factory" do
8
9
  FactoryGirl.register_factory(factory)
9
10
  FactoryGirl.factory_by_name(factory.name).should == factory
10
11
  end
11
12
 
12
- it "finds a registered a sequence" do
13
+ it "finds a registered sequence" do
13
14
  FactoryGirl.register_sequence(sequence)
14
15
  FactoryGirl.sequence_by_name(sequence.name).should == sequence
15
16
  end
16
- end
17
17
 
18
+ it "finds a registered trait" do
19
+ FactoryGirl.register_trait(trait)
20
+ FactoryGirl.trait_by_name(trait.name).should == trait
21
+ end
22
+ end
@@ -4,93 +4,19 @@ $LOAD_PATH << File.join(File.dirname(__FILE__))
4
4
  require 'rubygems'
5
5
  require 'rspec'
6
6
  require 'rspec/autorun'
7
- require 'rr'
8
7
 
9
8
  require 'factory_girl'
9
+ require "mocha"
10
+ require "bourne"
10
11
 
11
- module RR
12
- module Adapters
13
- module Rspec
14
- def self.included(mod)
15
- RSpec.configuration.backtrace_clean_patterns.push(RR::Errors::BACKTRACE_IDENTIFIER)
16
- end
17
- end
18
- end
19
- end
12
+ Dir["spec/support/**/*.rb"].each { |f| require File.expand_path(f) }
20
13
 
21
14
  RSpec.configure do |config|
22
- config.mock_framework = :rr
23
- RSpec::Core::ExampleGroup.send(:include, RR::Adapters::Rspec)
15
+ config.mock_framework = :mocha
16
+
24
17
  config.after do
25
18
  FactoryGirl.factories.clear
26
19
  FactoryGirl.sequences.clear
27
20
  FactoryGirl.traits.clear
28
21
  end
29
22
  end
30
-
31
- module DefinesConstants
32
- def self.included(example_group)
33
- example_group.class_eval do
34
- before do
35
- @defined_constants ||= []
36
- @created_tables ||= []
37
- end
38
-
39
- after do
40
- @defined_constants.reverse.each do |path|
41
- namespace, class_name = *constant_path(path)
42
- namespace.send(:remove_const, class_name)
43
- end
44
- @defined_constants.clear
45
-
46
- @created_tables.each do |table_name|
47
- ActiveRecord::Base.
48
- connection.
49
- execute("DROP TABLE IF EXISTS #{table_name}")
50
- end
51
- @created_tables.clear
52
- end
53
-
54
- def define_class(path, base = Object, &block)
55
- namespace, class_name = *constant_path(path)
56
- klass = Class.new(base)
57
- namespace.const_set(class_name, klass)
58
- klass.class_eval(&block) if block_given?
59
- @defined_constants << path
60
- klass
61
- end
62
-
63
- def define_model(name, columns = {}, &block)
64
- model = define_class(name, ActiveRecord::Base, &block)
65
- create_table(model.table_name) do |table|
66
- columns.each do |name, type|
67
- table.column name, type
68
- end
69
- end
70
- model
71
- end
72
-
73
- def create_table(table_name, &block)
74
- connection = ActiveRecord::Base.connection
75
-
76
- begin
77
- connection.execute("DROP TABLE IF EXISTS #{table_name}")
78
- connection.create_table(table_name, &block)
79
- @created_tables << table_name
80
- connection
81
- rescue Exception => exception
82
- connection.execute("DROP TABLE IF EXISTS #{table_name}")
83
- raise exception
84
- end
85
- end
86
-
87
- def constant_path(constant_name)
88
- names = constant_name.split('::')
89
- class_name = names.pop
90
- namespace = names.inject(Object) { |result, name| result.const_get(name) }
91
- [namespace, class_name]
92
- end
93
- end
94
- end
95
- end
96
-
@@ -0,0 +1,86 @@
1
+ require 'active_record'
2
+
3
+ module DefineConstantMacros
4
+ def define_class(path, base = Object, &block)
5
+ namespace, class_name = *constant_path(path)
6
+ klass = Class.new(base)
7
+ namespace.const_set(class_name, klass)
8
+ klass.class_eval(&block) if block_given?
9
+ @defined_constants << path
10
+ klass
11
+ end
12
+
13
+ def define_model(name, columns = {}, &block)
14
+ model = define_class(name, ActiveRecord::Base, &block)
15
+ create_table(model.table_name) do |table|
16
+ columns.each do |name, type|
17
+ table.column name, type
18
+ end
19
+ end
20
+ model
21
+ end
22
+
23
+ def create_table(table_name, &block)
24
+ connection = ActiveRecord::Base.connection
25
+
26
+ begin
27
+ connection.execute("DROP TABLE IF EXISTS #{table_name}")
28
+ connection.create_table(table_name, &block)
29
+ @created_tables << table_name
30
+ connection
31
+ rescue Exception => exception
32
+ connection.execute("DROP TABLE IF EXISTS #{table_name}")
33
+ raise exception
34
+ end
35
+ end
36
+
37
+ def constant_path(constant_name)
38
+ names = constant_name.split('::')
39
+ class_name = names.pop
40
+ namespace = names.inject(Object) { |result, name| result.const_get(name) }
41
+ [namespace, class_name]
42
+ end
43
+
44
+ def default_constants
45
+ @defined_constants ||= []
46
+ @created_tables ||= []
47
+ end
48
+
49
+ def clear_generated_constants
50
+ @defined_constants.reverse.each do |path|
51
+ namespace, class_name = *constant_path(path)
52
+ namespace.send(:remove_const, class_name)
53
+ end
54
+
55
+ @defined_constants.clear
56
+ end
57
+
58
+ def clear_generated_tables
59
+ @created_tables.each do |table_name|
60
+ ActiveRecord::Base.
61
+ connection.
62
+ execute("DROP TABLE IF EXISTS #{table_name}")
63
+ end
64
+ @created_tables.clear
65
+ end
66
+ end
67
+
68
+ RSpec.configure do |config|
69
+ config.include DefineConstantMacros
70
+
71
+ config.before(:all) do
72
+ ActiveRecord::Base.establish_connection(
73
+ :adapter => 'sqlite3',
74
+ :database => File.join(File.dirname(__FILE__), 'test.db')
75
+ )
76
+ end
77
+
78
+ config.before do
79
+ default_constants
80
+ end
81
+
82
+ config.after do
83
+ clear_generated_constants
84
+ clear_generated_tables
85
+ end
86
+ end
@@ -0,0 +1,99 @@
1
+ shared_examples_for "proxy without association support" do
2
+ it "doesn't raise when asked to associate with another factory" do
3
+ expect { subject.associate(:owner, :user, {}) }.to_not raise_error
4
+ end
5
+
6
+ it "does not call FactoryGirl.create when building an association" do
7
+ FactoryGirl.stubs(:create)
8
+ subject.association(:user)
9
+ FactoryGirl.should have_received(:create).never
10
+ end
11
+
12
+ it "returns nil when building an association" do
13
+ subject.set(:association, 'x')
14
+ subject.association(:user).should be_nil
15
+ end
16
+ end
17
+
18
+ shared_examples_for "proxy with association support" do |factory_girl_proxy_class|
19
+ let(:factory_name) { :user }
20
+ let(:association_name) { :owner }
21
+ let(:factory) { stub("associate_factory") }
22
+ let(:overrides) { { :one => 1, :two => 2 } }
23
+
24
+ before do
25
+ FactoryGirl.stubs(:factory_by_name => factory)
26
+ instance.stubs(association_name => factory_name)
27
+ factory.stubs(:run => factory_name)
28
+ subject.stubs(:set)
29
+ end
30
+
31
+ it "sets a value for the association" do
32
+ subject.associate(association_name, factory_name, {})
33
+ subject.result(nil).send(association_name).should == factory_name
34
+ end
35
+
36
+ it "sets the association attribute as the factory" do
37
+ subject.associate(association_name, factory_name, {})
38
+ subject.should have_received(:set).with(association_name, factory_name)
39
+ end
40
+
41
+ it "runs the factory with the correct proxy class" do
42
+ subject.associate(association_name, factory_name, {})
43
+ factory.should have_received(:run).with(factory_girl_proxy_class, {})
44
+ end
45
+
46
+ it "runs the factory with the correct proxy class and overrides" do
47
+ subject.associate(association_name, factory_name, overrides)
48
+ factory.should have_received(:run).with(factory_girl_proxy_class, overrides)
49
+ end
50
+ end
51
+
52
+ shared_examples_for "proxy with standard getters and setters" do |attribute, value|
53
+ before do
54
+ instance.stubs(:"#{attribute}=" => value, :"#{attribute}" => value)
55
+ end
56
+
57
+ describe "when setting an attribute" do
58
+ before do
59
+ subject.set(attribute, value)
60
+ end
61
+
62
+ its(attribute) { should == value }
63
+ it { instance.should have_received(:"#{attribute}=").with(value) }
64
+ end
65
+
66
+ describe "when setting an ignored attribute" do
67
+ before do
68
+ subject.set(attribute, value, true)
69
+ end
70
+
71
+ it { instance.should have_received(:"#{attribute}=").with(value).never }
72
+ end
73
+
74
+ describe "when getting an attribute" do
75
+ it { subject.get(attribute).should == value }
76
+
77
+ it "retrieves the value from the instance" do
78
+ subject.get(attribute)
79
+ instance.should have_received(:"#{attribute}")
80
+ end
81
+ end
82
+ end
83
+
84
+ shared_examples_for "proxy with callbacks" do |callback_name|
85
+ let(:callback) { stub("#{callback_name} callback", :foo => nil) }
86
+
87
+ before do
88
+ subject.add_callback(callback_name, proc { callback.foo })
89
+ end
90
+
91
+ it "runs the #{callback_name} callback" do
92
+ subject.result(nil)
93
+ callback.should have_received(:foo).once
94
+ end
95
+
96
+ it "returns the proxy instance" do
97
+ subject.result(nil).should == instance
98
+ end
99
+ end