factory_girl 2.0.0.beta1 → 2.0.0.beta2

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