factory_girl 2.0.0.beta1 → 2.0.0.beta2

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 (63) hide show
  1. data/Appraisals +12 -0
  2. data/{CONTRIBUTION_GUIDELINES.rdoc → CONTRIBUTION_GUIDELINES.md} +3 -3
  3. data/GETTING_STARTED.md +246 -0
  4. data/Gemfile +12 -0
  5. data/Gemfile.lock +62 -0
  6. data/README.md +64 -0
  7. data/Rakefile +15 -30
  8. data/features/factory_girl_steps.feature +26 -0
  9. data/features/step_definitions/database_steps.rb +2 -0
  10. data/features/support/env.rb +0 -9
  11. data/features/support/factories.rb +15 -0
  12. data/features/support/test.db +0 -0
  13. data/lib/factory_girl.rb +2 -0
  14. data/lib/factory_girl/definition_proxy.rb +10 -43
  15. data/lib/factory_girl/factory.rb +48 -17
  16. data/lib/factory_girl/proxy.rb +3 -3
  17. data/lib/factory_girl/proxy/attributes_for.rb +1 -1
  18. data/lib/factory_girl/proxy/build.rb +3 -3
  19. data/lib/factory_girl/proxy/create.rb +6 -2
  20. data/lib/factory_girl/proxy/stub.rb +3 -3
  21. data/lib/factory_girl/registry.rb +59 -0
  22. data/lib/factory_girl/sequence.rb +23 -9
  23. data/lib/factory_girl/step_definitions.rb +16 -9
  24. data/lib/factory_girl/syntax/blueprint.rb +2 -2
  25. data/lib/factory_girl/syntax/default.rb +5 -3
  26. data/lib/factory_girl/syntax/generate.rb +6 -6
  27. data/lib/factory_girl/syntax/make.rb +2 -2
  28. data/lib/factory_girl/syntax/methods.rb +75 -0
  29. data/lib/factory_girl/syntax/sham.rb +2 -2
  30. data/lib/factory_girl/syntax/vintage.rb +16 -79
  31. data/lib/factory_girl/version.rb +1 -1
  32. data/spec/acceptance/acceptance_helper.rb +7 -12
  33. data/spec/acceptance/attribute_aliases_spec.rb +26 -0
  34. data/spec/acceptance/attributes_for_spec.rb +48 -0
  35. data/spec/acceptance/build_spec.rb +35 -0
  36. data/spec/acceptance/build_stubbed_spec.rb +79 -0
  37. data/spec/acceptance/callbacks_spec.rb +42 -0
  38. data/spec/acceptance/create_spec.rb +67 -0
  39. data/spec/acceptance/default_strategy_spec.rb +27 -0
  40. data/spec/acceptance/definition_spec.rb +28 -0
  41. data/spec/acceptance/parent_spec.rb +39 -0
  42. data/spec/acceptance/sequence_spec.rb +32 -0
  43. data/spec/acceptance/syntax/blueprint_spec.rb +7 -5
  44. data/spec/acceptance/syntax/generate_spec.rb +10 -4
  45. data/spec/acceptance/syntax/make_spec.rb +7 -4
  46. data/spec/acceptance/syntax/sham_spec.rb +15 -8
  47. data/spec/acceptance/syntax/vintage_spec.rb +57 -17
  48. data/spec/factory_girl/attribute/dynamic_spec.rb +1 -1
  49. data/spec/factory_girl/definition_proxy_spec.rb +13 -11
  50. data/spec/factory_girl/factory_spec.rb +29 -52
  51. data/spec/factory_girl/find_definitions_spec.rb +34 -23
  52. data/spec/factory_girl/proxy/attributes_for_spec.rb +6 -6
  53. data/spec/factory_girl/proxy/build_spec.rb +4 -4
  54. data/spec/factory_girl/proxy/create_spec.rb +11 -3
  55. data/spec/factory_girl/proxy/stub_spec.rb +6 -6
  56. data/spec/factory_girl/proxy_spec.rb +1 -1
  57. data/spec/factory_girl/registry_spec.rb +92 -0
  58. data/spec/factory_girl/sequence_spec.rb +65 -8
  59. data/spec/spec_helper.rb +75 -29
  60. metadata +66 -43
  61. data/README.rdoc +0 -282
  62. data/spec/acceptance/acceptance_spec.rb +0 -288
  63. data/spec/acceptance/models.rb +0 -48
@@ -8,6 +8,22 @@ share_examples_for "finds definitions" do
8
8
  subject { FactoryGirl }
9
9
  end
10
10
 
11
+ RSpec::Matchers.define :require_definitions_from do |file|
12
+ match do |given|
13
+ @has_received = have_received.method_missing(:require, file)
14
+ @has_received.matches?(given)
15
+ end
16
+
17
+ description do
18
+ "require definitions from #{file}"
19
+ end
20
+
21
+ failure_message_for_should do
22
+ @has_received.failure_message
23
+ end
24
+ end
25
+
26
+
11
27
  describe "definition loading" do
12
28
  def self.in_directory_with_files(*files)
13
29
  before do
@@ -28,41 +44,35 @@ describe "definition loading" do
28
44
  end
29
45
  end
30
46
 
31
- def require_definitions_from(file)
32
- simple_matcher do |given, matcher|
33
- has_received = have_received.method_missing(:require, file)
34
- result = has_received.matches?(given)
35
- matcher.description = "require definitions from #{file}"
36
- matcher.failure_message = has_received.failure_message
37
- result
38
- end
39
- end
40
-
41
47
  describe "with factories.rb" do
42
48
  in_directory_with_files 'factories.rb'
43
- it_should_behave_like "finds definitions"
44
- it { should require_definitions_from('factories.rb') }
49
+ it_should_behave_like "finds definitions" do
50
+ it { should require_definitions_from('factories.rb') }
51
+ end
45
52
  end
46
53
 
47
54
  %w(spec test).each do |dir|
48
55
  describe "with a factories file under #{dir}" do
49
56
  in_directory_with_files File.join(dir, 'factories.rb')
50
- it_should_behave_like "finds definitions"
51
- it { should require_definitions_from("#{dir}/factories.rb") }
57
+ it_should_behave_like "finds definitions" do
58
+ it { should require_definitions_from("#{dir}/factories.rb") }
59
+ end
52
60
  end
53
61
 
54
62
  describe "with a factories file under #{dir}/factories" do
55
63
  in_directory_with_files File.join(dir, 'factories', 'post_factory.rb')
56
- it_should_behave_like "finds definitions"
57
- it { should require_definitions_from("#{dir}/factories/post_factory.rb") }
64
+ it_should_behave_like "finds definitions" do
65
+ it { should require_definitions_from("#{dir}/factories/post_factory.rb") }
66
+ end
58
67
  end
59
68
 
60
69
  describe "with several factories files under #{dir}/factories" do
61
70
  in_directory_with_files File.join(dir, 'factories', 'post_factory.rb'),
62
71
  File.join(dir, 'factories', 'person_factory.rb')
63
- it_should_behave_like "finds definitions"
64
- it { should require_definitions_from("#{dir}/factories/post_factory.rb") }
65
- it { should require_definitions_from("#{dir}/factories/person_factory.rb") }
72
+ it_should_behave_like "finds definitions" do
73
+ it { should require_definitions_from("#{dir}/factories/post_factory.rb") }
74
+ it { should require_definitions_from("#{dir}/factories/person_factory.rb") }
75
+ end
66
76
  end
67
77
 
68
78
  describe "with several factories files under #{dir}/factories in non-alphabetical order" do
@@ -80,10 +90,11 @@ describe "definition loading" do
80
90
  in_directory_with_files File.join(dir, 'factories.rb'),
81
91
  File.join(dir, 'factories', 'post_factory.rb'),
82
92
  File.join(dir, 'factories', 'person_factory.rb')
83
- it_should_behave_like "finds definitions"
84
- it { should require_definitions_from("#{dir}/factories.rb") }
85
- it { should require_definitions_from("#{dir}/factories/post_factory.rb") }
86
- it { should require_definitions_from("#{dir}/factories/person_factory.rb") }
93
+ it_should_behave_like "finds definitions" do
94
+ it { should require_definitions_from("#{dir}/factories.rb") }
95
+ it { should require_definitions_from("#{dir}/factories/post_factory.rb") }
96
+ it { should require_definitions_from("#{dir}/factories/person_factory.rb") }
97
+ end
87
98
  end
88
99
  end
89
100
  end
@@ -7,12 +7,12 @@ describe FactoryGirl::Proxy::AttributesFor do
7
7
 
8
8
  describe "when asked to associate with another factory" do
9
9
  before do
10
- stub(Factory).create
10
+ stub(FactoryGirl).create
11
11
  @proxy.associate(:owner, :user, {})
12
12
  end
13
13
 
14
14
  it "should not set a value for the association" do
15
- (@proxy.result.key?(:owner)).should_not be
15
+ (@proxy.result(nil).key?(:owner)).should_not be
16
16
  end
17
17
  end
18
18
 
@@ -21,9 +21,9 @@ describe FactoryGirl::Proxy::AttributesFor do
21
21
  end
22
22
 
23
23
  it "should not call Factory.create when building an association" do
24
- stub(Factory).create
24
+ stub(FactoryGirl).create
25
25
  @proxy.association(:user).should be_nil
26
- Factory.should have_received.create.never
26
+ FactoryGirl.should have_received.create.never
27
27
  end
28
28
 
29
29
  it "should always return nil when building an association" do
@@ -32,7 +32,7 @@ describe FactoryGirl::Proxy::AttributesFor do
32
32
  end
33
33
 
34
34
  it "should return a hash when asked for the result" do
35
- @proxy.result.should be_kind_of(Hash)
35
+ @proxy.result(nil).should be_kind_of(Hash)
36
36
  end
37
37
 
38
38
  describe "after setting an attribute" do
@@ -41,7 +41,7 @@ describe FactoryGirl::Proxy::AttributesFor do
41
41
  end
42
42
 
43
43
  it "should set that value in the resulting hash" do
44
- @proxy.result[:attribute].should == 'value'
44
+ @proxy.result(nil)[:attribute].should == 'value'
45
45
  end
46
46
 
47
47
  it "should return that value when asked for that attribute" do
@@ -21,7 +21,7 @@ describe FactoryGirl::Proxy::Build do
21
21
  before do
22
22
  @association = "associated-instance"
23
23
  @associated_factory = "associated-factory"
24
- stub(FactoryGirl).factory_by_name { @associated_factory }
24
+ stub(FactoryGirl).find { @associated_factory }
25
25
  stub(@associated_factory).run { @association }
26
26
  @overrides = { 'attr' => 'value' }
27
27
  @proxy.associate(:owner, :user, @overrides)
@@ -39,7 +39,7 @@ describe FactoryGirl::Proxy::Build do
39
39
  it "should run create when building an association" do
40
40
  association = "associated-instance"
41
41
  associated_factory = "associated-factory"
42
- stub(FactoryGirl).factory_by_name { associated_factory }
42
+ stub(FactoryGirl).find { associated_factory }
43
43
  stub(associated_factory).run { association }
44
44
  overrides = { 'attr' => 'value' }
45
45
  @proxy.association(:user, overrides).should == association
@@ -47,14 +47,14 @@ describe FactoryGirl::Proxy::Build do
47
47
  end
48
48
 
49
49
  it "should return the built instance when asked for the result" do
50
- @proxy.result.should == @instance
50
+ @proxy.result(nil).should == @instance
51
51
  end
52
52
 
53
53
  it "should run the :after_build callback when retrieving the result" do
54
54
  spy = Object.new
55
55
  stub(spy).foo
56
56
  @proxy.add_callback(:after_build, proc{ spy.foo })
57
- @proxy.result
57
+ @proxy.result(nil)
58
58
  spy.should have_received.foo
59
59
  end
60
60
 
@@ -22,7 +22,7 @@ describe FactoryGirl::Proxy::Create do
22
22
  before do
23
23
  @association = "associated-instance"
24
24
  @associated_factory = "associated-factory"
25
- stub(FactoryGirl).factory_by_name { @associated_factory }
25
+ stub(FactoryGirl).find { @associated_factory }
26
26
  stub(@associated_factory).run { @association }
27
27
  @overrides = { 'attr' => 'value' }
28
28
  @proxy.associate(:owner, :user, @overrides)
@@ -40,7 +40,7 @@ describe FactoryGirl::Proxy::Create do
40
40
  it "should run create when building an association" do
41
41
  association = "associated-instance"
42
42
  associated_factory = "associated-factory"
43
- stub(FactoryGirl).factory_by_name { associated_factory }
43
+ stub(FactoryGirl).find { associated_factory }
44
44
  stub(associated_factory).run { association }
45
45
  overrides = { 'attr' => 'value' }
46
46
  @proxy.association(:user, overrides).should == association
@@ -55,7 +55,7 @@ describe FactoryGirl::Proxy::Create do
55
55
  stub(@create_spy).foo
56
56
  @proxy.add_callback(:after_build, proc{ @build_spy.foo })
57
57
  @proxy.add_callback(:after_create, proc{ @create_spy.foo })
58
- @result = @proxy.result
58
+ @result = @proxy.result(nil)
59
59
  end
60
60
 
61
61
  it "should save the instance" do
@@ -72,6 +72,14 @@ describe FactoryGirl::Proxy::Create do
72
72
  end
73
73
  end
74
74
 
75
+ it "runs a custom create block" do
76
+ block = 'custom create block'
77
+ stub(block).call
78
+ stub(@instance).save! { raise }
79
+ instance = @proxy.result(block)
80
+ block.should have_received.call(instance)
81
+ end
82
+
75
83
  describe "when setting an attribute" do
76
84
  before do
77
85
  @proxy.set(:attribute, 'value')
@@ -13,17 +13,17 @@ describe FactoryGirl::Proxy::Stub do
13
13
  end
14
14
 
15
15
  it "should not be a new record" do
16
- @stub.result.should_not be_new_record
16
+ @stub.result(nil).should_not be_new_record
17
17
  end
18
18
 
19
19
  it "should not be able to connect to the database" do
20
- lambda { @stub.result.reload }.should raise_error(RuntimeError)
20
+ lambda { @stub.result(nil).reload }.should raise_error(RuntimeError)
21
21
  end
22
22
 
23
23
  describe "when a user factory exists" do
24
24
  before do
25
25
  @user = "user"
26
- stub(FactoryGirl).factory_by_name { @associated_factory }
26
+ stub(FactoryGirl).find { @associated_factory }
27
27
  @associated_factory = 'associate-factory'
28
28
  end
29
29
 
@@ -37,7 +37,7 @@ describe FactoryGirl::Proxy::Stub do
37
37
  end
38
38
 
39
39
  it "should set a value for the association" do
40
- @stub.result.owner.should == @user
40
+ @stub.result(nil).owner.should == @user
41
41
  end
42
42
  end
43
43
 
@@ -48,14 +48,14 @@ describe FactoryGirl::Proxy::Stub do
48
48
 
49
49
  describe "when asked for the result" do
50
50
  it "should return the actual instance" do
51
- @stub.result.should == @instance
51
+ @stub.result(nil).should == @instance
52
52
  end
53
53
 
54
54
  it "should run the :after_stub callback" do
55
55
  @spy = Object.new
56
56
  stub(@spy).foo
57
57
  @stub.add_callback(:after_stub, proc{ @spy.foo })
58
- @stub.result
58
+ @stub.result(nil)
59
59
  @spy.should have_received.foo
60
60
  end
61
61
  end
@@ -23,7 +23,7 @@ describe FactoryGirl::Proxy do
23
23
  end
24
24
 
25
25
  it "should raise an error when asked for the result" do
26
- lambda { @proxy.result }.should raise_error(NotImplementedError)
26
+ lambda { @proxy.result(nil) }.should raise_error(NotImplementedError)
27
27
  end
28
28
 
29
29
  describe "when adding callbacks" do
@@ -0,0 +1,92 @@
1
+ require 'spec_helper'
2
+
3
+ describe FactoryGirl::Registry do
4
+ let(:factory) { FactoryGirl::Factory.new(:object) }
5
+
6
+ subject { FactoryGirl::Registry.new }
7
+
8
+ it "finds a registered a factory" do
9
+ subject.add(factory)
10
+ subject.find(factory.name).should == factory
11
+ end
12
+
13
+ it "raises when finding an unregistered factory" do
14
+ expect { subject.find(:bogus) }.to raise_error(ArgumentError)
15
+ end
16
+
17
+ it "adds and returns a factory" do
18
+ subject.add(factory).should == factory
19
+ end
20
+
21
+ it "knows that a factory is registered by symbol" do
22
+ subject.add(factory)
23
+ subject.should be_registered(factory.name.to_sym)
24
+ end
25
+
26
+ it "knows that a factory is registered by string" do
27
+ subject.add(factory)
28
+ subject.should be_registered(factory.name.to_s)
29
+ end
30
+
31
+ it "knows that a factory isn't registered" do
32
+ subject.should_not be_registered("bogus")
33
+ end
34
+
35
+ it "can be accessed like a hash" do
36
+ subject.add(factory)
37
+ subject[factory.name].should == factory
38
+ end
39
+
40
+ it "iterates registered factories" do
41
+ other_factory = FactoryGirl::Factory.new(:string)
42
+ subject.add(factory)
43
+ subject.add(other_factory)
44
+ result = {}
45
+
46
+ subject.each do |name, value|
47
+ result[name] = value
48
+ end
49
+
50
+ result.should == { factory.name => factory,
51
+ other_factory.name => other_factory }
52
+ end
53
+
54
+ it "registers an sequence" do
55
+ sequence = FactoryGirl::Sequence.new(:email) { |n| "somebody#{n}@example.com" }
56
+ subject.add(sequence)
57
+ subject.find(:email).should == sequence
58
+ end
59
+
60
+ it "doesn't allow a duplicate name" do
61
+ expect { 2.times { subject.add(factory) } }.
62
+ to raise_error(FactoryGirl::DuplicateDefinitionError)
63
+ end
64
+
65
+ it "registers aliases" do
66
+ aliases = [:thing, :widget]
67
+ factory = FactoryGirl::Factory.new(:object, :aliases => aliases)
68
+ subject.add(factory)
69
+ aliases.each do |name|
70
+ subject.find(name).should == factory
71
+ end
72
+ end
73
+
74
+ context "on the FactoryGirl module" do
75
+ it "finds a registered a factory" do
76
+ FactoryGirl.register(factory)
77
+ FactoryGirl.find(factory.name).should == factory
78
+ end
79
+
80
+ it "knows that a factory is registered by symbol" do
81
+ FactoryGirl.register(factory)
82
+ FactoryGirl.should be_registered(factory.name.to_sym)
83
+ end
84
+
85
+ it "sets the registry" do
86
+ registry = FactoryGirl::Registry.new
87
+ FactoryGirl.registry = registry
88
+ FactoryGirl.registry.should == registry
89
+ end
90
+ end
91
+ end
92
+
@@ -3,40 +3,97 @@ require 'spec_helper'
3
3
  describe FactoryGirl::Sequence do
4
4
  describe "a basic sequence" do
5
5
  before do
6
- @sequence = FactoryGirl::Sequence.new {|n| "=#{n}" }
6
+ @name = :test
7
+ @sequence = FactoryGirl::Sequence.new(@name) {|n| "=#{n}" }
8
+ end
9
+
10
+ it "has names" do
11
+ @sequence.names.should == [@name]
7
12
  end
8
13
 
9
14
  it "should start with a value of 1" do
15
+ @sequence.run.should == "=1"
16
+ end
17
+
18
+ it "responds to next" do
10
19
  @sequence.next.should == "=1"
11
20
  end
12
21
 
22
+ it "responds to default_strategy" do
23
+ @sequence.default_strategy.should == :create
24
+ end
25
+
26
+ it "runs compatible with the Factory interface" do
27
+ @sequence.run(nil, nil).should == "=1"
28
+ end
29
+
13
30
  describe "after being called" do
14
31
  before do
15
- @sequence.next
32
+ @sequence.run
16
33
  end
17
34
 
18
35
  it "should use the next value" do
19
- @sequence.next.should == "=2"
36
+ @sequence.run.should == "=2"
20
37
  end
21
38
  end
22
39
  end
23
-
40
+
24
41
  describe "a custom sequence" do
25
42
  before do
26
- @sequence = FactoryGirl::Sequence.new("A") {|n| "=#{n}" }
43
+ @sequence = FactoryGirl::Sequence.new(:name, "A") {|n| "=#{n}" }
44
+ end
45
+
46
+ it "should start with a value of A" do
47
+ @sequence.run.should == "=A"
48
+ end
49
+
50
+ describe "after being called" do
51
+ before do
52
+ @sequence.run
53
+ end
54
+
55
+ it "should use the next value" do
56
+ @sequence.run.should == "=B"
57
+ end
58
+ end
59
+ end
60
+
61
+ describe "a basic sequence without a block" do
62
+ before do
63
+ @sequence = FactoryGirl::Sequence.new(:name)
64
+ end
65
+
66
+ it "should start with a value of 1" do
67
+ @sequence.run.should == 1
68
+ end
69
+
70
+ describe "after being called" do
71
+ before do
72
+ @sequence.run
73
+ end
74
+
75
+ it "should use the next value" do
76
+ @sequence.run.should == 2
77
+ end
78
+ end
79
+ end
80
+
81
+ describe "a custom sequence without a block" do
82
+ before do
83
+ @sequence = FactoryGirl::Sequence.new(:name, "A")
27
84
  end
28
85
 
29
86
  it "should start with a value of A" do
30
- @sequence.next.should == "=A"
87
+ @sequence.run.should == "A"
31
88
  end
32
89
 
33
90
  describe "after being called" do
34
91
  before do
35
- @sequence.next
92
+ @sequence.run
36
93
  end
37
94
 
38
95
  it "should use the next value" do
39
- @sequence.next.should == "=B"
96
+ @sequence.run.should == "B"
40
97
  end
41
98
  end
42
99
  end