vitalish-factory_girl 1.2.5 → 1.2.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/README.rdoc +67 -121
  2. data/Rakefile +103 -29
  3. data/VERSION +1 -0
  4. data/lib/factory_girl/aliases.rb +32 -3
  5. data/lib/factory_girl/attribute/association.rb +1 -1
  6. data/lib/factory_girl/attribute/callback.rb +1 -1
  7. data/lib/factory_girl/attribute/dynamic.rb +3 -3
  8. data/lib/factory_girl/attribute/static.rb +1 -1
  9. data/lib/factory_girl/attribute.rb +3 -3
  10. data/lib/factory_girl/factory.rb +354 -164
  11. data/lib/factory_girl/proxy/attributes_for.rb +1 -1
  12. data/lib/factory_girl/proxy/build.rb +5 -7
  13. data/lib/factory_girl/proxy/create.rb +3 -2
  14. data/lib/factory_girl/proxy/stub.rb +5 -19
  15. data/lib/factory_girl/proxy.rb +23 -7
  16. data/lib/factory_girl/sequence.rb +40 -5
  17. data/lib/factory_girl/step_definitions.rb +13 -19
  18. data/lib/factory_girl/syntax/blueprint.rb +5 -5
  19. data/lib/factory_girl/syntax/generate.rb +8 -13
  20. data/lib/factory_girl/syntax/make.rb +7 -9
  21. data/lib/factory_girl/syntax/sham.rb +8 -11
  22. data/lib/factory_girl/syntax.rb +7 -7
  23. data/lib/factory_girl.rb +19 -8
  24. data/spec/factory_girl/aliases_spec.rb +5 -9
  25. data/spec/factory_girl/attribute/association_spec.rb +4 -4
  26. data/spec/factory_girl/attribute/callback_spec.rb +4 -4
  27. data/spec/factory_girl/attribute/dynamic_spec.rb +10 -21
  28. data/spec/factory_girl/attribute/static_spec.rb +6 -6
  29. data/spec/factory_girl/attribute_spec.rb +6 -6
  30. data/spec/factory_girl/factory_spec.rb +465 -305
  31. data/spec/factory_girl/proxy/attributes_for_spec.rb +3 -3
  32. data/spec/factory_girl/proxy/build_spec.rb +13 -18
  33. data/spec/factory_girl/proxy/create_spec.rb +13 -18
  34. data/spec/factory_girl/proxy/stub_spec.rb +6 -7
  35. data/spec/factory_girl/proxy_spec.rb +3 -3
  36. data/spec/factory_girl/sequence_spec.rb +39 -16
  37. data/spec/factory_girl/syntax/blueprint_spec.rb +34 -0
  38. data/spec/factory_girl/syntax/generate_spec.rb +57 -0
  39. data/spec/factory_girl/syntax/make_spec.rb +35 -0
  40. data/spec/factory_girl/syntax/sham_spec.rb +35 -0
  41. data/spec/integration_spec.rb +304 -0
  42. data/spec/models.rb +43 -0
  43. data/spec/spec_helper.rb +10 -85
  44. metadata +15 -3
@@ -1,4 +1,4 @@
1
- module FactoryGirl
1
+ class Factory
2
2
  class Proxy #:nodoc:
3
3
  class AttributesFor < Proxy #:nodoc:
4
4
  def initialize(klass)
@@ -1,4 +1,4 @@
1
- module FactoryGirl
1
+ class Factory
2
2
  class Proxy #:nodoc:
3
3
  class Build < Proxy #:nodoc:
4
4
  def initialize(klass)
@@ -13,14 +13,12 @@ module FactoryGirl
13
13
  @instance.send(:"#{attribute}=", value)
14
14
  end
15
15
 
16
- def associate(name, factory_name, overrides)
17
- factory = FactoryGirl.factory_by_name(factory_name)
18
- set(name, factory.run(Proxy::Create, overrides))
16
+ def associate(name, factory, attributes)
17
+ set(name, Factory.create(factory, attributes))
19
18
  end
20
19
 
21
- def association(factory_name, overrides = {})
22
- factory = FactoryGirl.factory_by_name(factory_name)
23
- factory.run(Proxy::Create, overrides)
20
+ def association(factory, overrides = {})
21
+ Factory.create(factory, overrides)
24
22
  end
25
23
 
26
24
  def result
@@ -1,10 +1,11 @@
1
- module FactoryGirl
1
+ class Factory
2
2
  class Proxy #:nodoc:
3
3
  class Create < Build #:nodoc:
4
4
  def result
5
5
  run_callbacks(:after_build)
6
+ temp_attributes = @instance.attributes
6
7
  @instance.save!
7
- run_callbacks(:after_create)
8
+ run_callbacks(:after_create,temp_attributes)
8
9
  @instance
9
10
  end
10
11
  end
@@ -1,4 +1,4 @@
1
- module FactoryGirl
1
+ class Factory
2
2
  class Proxy
3
3
  class Stub < Proxy #:nodoc:
4
4
  @@next_id = 1000
@@ -11,14 +11,6 @@ module FactoryGirl
11
11
  id.nil?
12
12
  end
13
13
 
14
- def save(*args)
15
- raise "stubbed models are not allowed to access the database"
16
- end
17
-
18
- def destroy(*args)
19
- raise "stubbed models are not allowed to access the database"
20
- end
21
-
22
14
  def connection
23
15
  raise "stubbed models are not allowed to access the database"
24
16
  end
@@ -26,10 +18,6 @@ module FactoryGirl
26
18
  def reload
27
19
  raise "stubbed models are not allowed to access the database"
28
20
  end
29
-
30
- def update_attribute(*args)
31
- raise "stubbed models are not allowed to access the database"
32
- end
33
21
  end
34
22
  end
35
23
 
@@ -45,14 +33,12 @@ module FactoryGirl
45
33
  @instance.send(:"#{attribute}=", value)
46
34
  end
47
35
 
48
- def associate(name, factory_name, overrides)
49
- factory = FactoryGirl.factory_by_name(factory_name)
50
- set(name, factory.run(Proxy::Stub, overrides))
36
+ def associate(name, factory, attributes)
37
+ set(name, Factory.stub(factory, attributes))
51
38
  end
52
39
 
53
- def association(factory_name, overrides = {})
54
- factory = FactoryGirl.factory_by_name(factory_name)
55
- factory.run(Proxy::Stub, overrides)
40
+ def association(factory, overrides = {})
41
+ Factory.stub(factory, overrides)
56
42
  end
57
43
 
58
44
  def result
@@ -1,4 +1,5 @@
1
- module FactoryGirl
1
+ class Factory
2
+
2
3
  class Proxy #:nodoc:
3
4
 
4
5
  attr_reader :callbacks
@@ -12,6 +13,11 @@ module FactoryGirl
12
13
 
13
14
  def set(attribute, value)
14
15
  end
16
+
17
+ def set_param(attribute, value)
18
+ @params ||= {}
19
+ @params[attribute] = value
20
+ end
15
21
 
16
22
  def associate(name, factory, attributes)
17
23
  end
@@ -25,7 +31,16 @@ module FactoryGirl
25
31
  def run_callbacks(name)
26
32
  if @callbacks && @callbacks[name]
27
33
  @callbacks[name].each do |block|
28
- block.arity.zero? ? block.call : block.call(@instance)
34
+ case block.arity
35
+ when 0
36
+ block.call
37
+ when 1
38
+ block.call(@instance)
39
+ when 2
40
+ block.call(@instance,@params)
41
+ when 3
42
+ block.call(@instance,@params,attrib)
43
+ end
29
44
  end
30
45
  end
31
46
  end
@@ -41,24 +56,24 @@ module FactoryGirl
41
56
  #
42
57
  # Returns:
43
58
  # The generated association for the current build strategy. Note that
44
- # associations are not generated for the attributes_for strategy. Returns
59
+ # assocaitions are not generated for the attributes_for strategy. Returns
45
60
  # nil in this case.
46
61
  #
47
62
  # Example:
48
63
  #
49
- # factory :user do
64
+ # Factory.define :user do |f|
50
65
  # # ...
51
66
  # end
52
67
  #
53
- # factory :post do
68
+ # Factory.define :post do |f|
54
69
  # # ...
55
- # author { |post| post.association(:user, :name => 'Joe') }
70
+ # f.author {|a| a.association :user, :name => 'Joe' }
56
71
  # end
57
72
  #
58
73
  # # Builds (but doesn't save) a Post and a User
59
74
  # Factory.build(:post)
60
75
  #
61
- # # Builds and saves a User, builds a Post, assigns the User to the
76
+ # # Builds and saves a User, builds a Post, assigns the User to the
62
77
  # # author association, and saves the User.
63
78
  # Factory.create(:post)
64
79
  #
@@ -74,4 +89,5 @@ module FactoryGirl
74
89
  raise NotImplementedError, "Strategies must return a result"
75
90
  end
76
91
  end
92
+
77
93
  end
@@ -1,4 +1,4 @@
1
- module FactoryGirl
1
+ class Factory
2
2
 
3
3
  # Raised when calling Factory.sequence from a dynamic attribute block
4
4
  class SequenceAbuseError < StandardError; end
@@ -7,16 +7,15 @@ module FactoryGirl
7
7
  # using next.
8
8
  class Sequence
9
9
 
10
- def initialize(value = 1, &proc) #:nodoc:
10
+ def initialize (&proc) #:nodoc:
11
11
  @proc = proc
12
- @value = value || 1
12
+ @value = 0
13
13
  end
14
14
 
15
15
  # Returns the next value for this sequence
16
16
  def next
17
+ @value += 1
17
18
  @proc.call(@value)
18
- ensure
19
- @value = @value.next
20
19
  end
21
20
 
22
21
  end
@@ -25,4 +24,40 @@ module FactoryGirl
25
24
  attr_accessor :sequences #:nodoc:
26
25
  end
27
26
  self.sequences = {}
27
+
28
+ # Defines a new sequence that can be used to generate unique values in a specific format.
29
+ #
30
+ # Arguments:
31
+ # name: (Symbol)
32
+ # A unique name for this sequence. This name will be referenced when
33
+ # calling next to generate new values from this sequence.
34
+ # block: (Proc)
35
+ # The code to generate each value in the sequence. This block will be
36
+ # called with a unique number each time a value in the sequence is to be
37
+ # generated. The block should return the generated value for the
38
+ # sequence.
39
+ #
40
+ # Example:
41
+ #
42
+ # Factory.sequence(:email) {|n| "somebody_#{n}@example.com" }
43
+ def self.sequence (name, &block)
44
+ self.sequences[name] = Sequence.new(&block)
45
+ end
46
+
47
+ # Generates and returns the next value in a sequence.
48
+ #
49
+ # Arguments:
50
+ # name: (Symbol)
51
+ # The name of the sequence that a value should be generated for.
52
+ #
53
+ # Returns:
54
+ # The next value in the sequence. (Object)
55
+ def self.next (sequence)
56
+ unless self.sequences.key?(sequence)
57
+ raise "No such sequence: #{sequence}"
58
+ end
59
+
60
+ self.sequences[sequence].next
61
+ end
62
+
28
63
  end
@@ -1,17 +1,10 @@
1
1
  module FactoryGirlStepHelpers
2
-
3
2
  def convert_association_string_to_instance(factory_name, assignment)
4
3
  attribute, value = assignment.split(':', 2)
5
- return if value.blank?
6
- factory = FactoryGirl.factory_by_name(factory_name)
7
- attributes = convert_human_hash_to_attribute_hash({attribute => value.strip}, factory.associations)
8
- attributes_find = {}
9
- attributes.each do |k, v|
10
- k = "#{k}_id" if v.is_a? ActiveRecord::Base
11
- attributes_find[k] = v
12
- end
4
+ attributes = convert_human_hash_to_attribute_hash(attribute => value.strip)
5
+ factory = Factory.factory_by_name(factory_name)
13
6
  model_class = factory.build_class
14
- model_class.find(:first, :conditions => attributes_find) or
7
+ model_class.find(:first, :conditions => attributes) or
15
8
  Factory(factory_name, attributes)
16
9
  end
17
10
 
@@ -28,31 +21,32 @@ end
28
21
 
29
22
  World(FactoryGirlStepHelpers)
30
23
 
31
- FactoryGirl.factories.values.each do |factory|
32
- Given /^the following (?:#{factory.human_name}|#{factory.human_name.pluralize}) exists?:$/ do |table|
24
+ Factory.factories.values.each do |factory|
25
+ # TODO: support irregular pluralizations
26
+ Given /^the following #{factory.human_name}s? exists?:$/ do |table|
33
27
  table.hashes.each do |human_hash|
34
28
  attributes = convert_human_hash_to_attribute_hash(human_hash, factory.associations)
35
- factory.run(FactoryGirl::Proxy::Create, attributes)
29
+ Factory.create(factory.factory_name, attributes)
36
30
  end
37
31
  end
38
32
 
39
33
  Given /^an? #{factory.human_name} exists$/ do
40
- Factory(factory.name)
34
+ Factory(factory.factory_name)
41
35
  end
42
36
 
43
- Given /^(\d+) #{factory.human_name.pluralize} exist$/ do |count|
44
- count.to_i.times { Factory(factory.name) }
37
+ Given /^(\d+) #{factory.human_name}s exist$/ do |count|
38
+ count.to_i.times { Factory(factory.human_name) }
45
39
  end
46
40
 
47
41
  if factory.build_class.respond_to?(:columns)
48
42
  factory.build_class.columns.each do |column|
49
43
  human_column_name = column.name.downcase.gsub('_', ' ')
50
44
  Given /^an? #{factory.human_name} exists with an? #{human_column_name} of "([^"]*)"$/i do |value|
51
- Factory(factory.name, column.name => value)
45
+ Factory(factory.factory_name, column.name => value)
52
46
  end
53
47
 
54
- Given /^(\d+) #{factory.human_name.pluralize} exist with an? #{human_column_name} of "([^"]*)"$/i do |count, value|
55
- count.to_i.times { Factory(factory.name, column.name => value) }
48
+ Given /^(\d+) #{factory.human_name}s exist with an? #{human_column_name} of "([^"]*)"$/i do |count, value|
49
+ count.to_i.times { Factory(factory.factory_name, column.name => value) }
56
50
  end
57
51
  end
58
52
  end
@@ -1,4 +1,4 @@
1
- module FactoryGirl
1
+ class Factory
2
2
  module Syntax
3
3
 
4
4
  # Extends ActiveRecord::Base to provide a make class method, which is an
@@ -27,9 +27,8 @@ module FactoryGirl
27
27
 
28
28
  def blueprint(&block)
29
29
  instance = Factory.new(name.underscore, :class => self)
30
- proxy = FactoryGirl::DefinitionProxy.new(instance)
31
- proxy.instance_eval(&block)
32
- FactoryGirl.register_factory(instance)
30
+ instance.instance_eval(&block)
31
+ Factory.factories[instance.factory_name] = instance
33
32
  end
34
33
 
35
34
  end
@@ -39,4 +38,5 @@ module FactoryGirl
39
38
  end
40
39
  end
41
40
 
42
- ActiveRecord::Base.send(:include, FactoryGirl::Syntax::Blueprint::ActiveRecord)
41
+ ActiveRecord::Base.send(:include, Factory::Syntax::Blueprint::ActiveRecord)
42
+
@@ -1,4 +1,4 @@
1
- module FactoryGirl
1
+ class Factory
2
2
  module Syntax
3
3
 
4
4
  # Extends ActiveRecord::Base to provide generation methods for factories.
@@ -7,11 +7,9 @@ module FactoryGirl
7
7
  #
8
8
  # require 'factory_girl/syntax/generate'
9
9
  #
10
- # FactoryGirl.define do
11
- # factory :user do
12
- # name 'Billy Bob'
13
- # email 'billy@bob.example.com'
14
- # end
10
+ # Factory.define :user do |factory|
11
+ # factory.name 'Billy Bob'
12
+ # factory.email 'billy@bob.example.com'
15
13
  # end
16
14
  #
17
15
  # # Creates a saved instance without raising (same as saving the result
@@ -42,23 +40,20 @@ module FactoryGirl
42
40
  module ClassMethods #:nodoc:
43
41
 
44
42
  def generate(overrides = {}, &block)
45
- factory = FactoryGirl.factory_by_name(name.underscore)
46
- instance = factory.run(Proxy::Build, overrides)
43
+ instance = Factory.build(name.underscore, overrides)
47
44
  instance.save
48
45
  yield(instance) if block_given?
49
46
  instance
50
47
  end
51
48
 
52
49
  def generate!(overrides = {}, &block)
53
- factory = FactoryGirl.factory_by_name(name.underscore)
54
- instance = factory.run(Proxy::Create, overrides)
50
+ instance = Factory.create(name.underscore, overrides)
55
51
  yield(instance) if block_given?
56
52
  instance
57
53
  end
58
54
 
59
55
  def spawn(overrides = {}, &block)
60
- factory = FactoryGirl.factory_by_name(name.underscore)
61
- instance = factory.run(Proxy::Build, overrides)
56
+ instance = Factory.build(name.underscore, overrides)
62
57
  yield(instance) if block_given?
63
58
  instance
64
59
  end
@@ -70,4 +65,4 @@ module FactoryGirl
70
65
  end
71
66
  end
72
67
 
73
- ActiveRecord::Base.send(:include, FactoryGirl::Syntax::Generate::ActiveRecord)
68
+ ActiveRecord::Base.send(:include, Factory::Syntax::Generate::ActiveRecord)
@@ -1,4 +1,4 @@
1
- module FactoryGirl
1
+ class Factory
2
2
  module Syntax
3
3
 
4
4
  # Extends ActiveRecord::Base to provide a make class method, which is a
@@ -7,12 +7,10 @@ module FactoryGirl
7
7
  # Usage:
8
8
  #
9
9
  # require 'factory_girl/syntax/make'
10
- #
11
- # FactoryGirl.define do
12
- # factory :user do
13
- # name 'Billy Bob'
14
- # email 'billy@bob.example.com'
15
- # end
10
+ #
11
+ # Factory.define :user do |factory|
12
+ # factory.name 'Billy Bob'
13
+ # factory.email 'billy@bob.example.com'
16
14
  # end
17
15
  #
18
16
  # User.make(:name => 'Johnny')
@@ -28,7 +26,7 @@ module FactoryGirl
28
26
  module ClassMethods #:nodoc:
29
27
 
30
28
  def make(overrides = {})
31
- FactoryGirl.factory_by_name(name.underscore).run(Proxy::Create, overrides)
29
+ Factory.create(name.underscore, overrides)
32
30
  end
33
31
 
34
32
  end
@@ -38,4 +36,4 @@ module FactoryGirl
38
36
  end
39
37
  end
40
38
 
41
- ActiveRecord::Base.send(:include, FactoryGirl::Syntax::Make::ActiveRecord)
39
+ ActiveRecord::Base.send(:include, Factory::Syntax::Make::ActiveRecord)
@@ -1,8 +1,8 @@
1
- module FactoryGirl
1
+ class Factory
2
2
  module Syntax
3
3
 
4
4
  # Adds a Sham module, which provides an alternate interface to
5
- # FactoryGirl::Sequence.
5
+ # Factory::Sequence.
6
6
  #
7
7
  # Usage:
8
8
  #
@@ -10,10 +10,8 @@ module FactoryGirl
10
10
  #
11
11
  # Sham.email {|n| "somebody#{n}@example.com" }
12
12
  #
13
- # FactoryGirl.define do
14
- # factory :user do
15
- # email
16
- # end
13
+ # Factory.define :user do |factory|
14
+ # factory.email { Sham.email }
17
15
  # end
18
16
  #
19
17
  # Note that you can also use Faker, but it is recommended that you simply
@@ -24,12 +22,11 @@ module FactoryGirl
24
22
  # This syntax was derived from Pete Yandell's machinist.
25
23
  module Sham
26
24
  module Sham #:nodoc:
27
- def self.method_missing(name, *args, &block)
25
+ def self.method_missing(name, &block)
28
26
  if block_given?
29
- start_value = args.first
30
- FactoryGirl.sequences[name] = Sequence.new(start_value || 1, &block)
27
+ Factory.sequence(name, &block)
31
28
  else
32
- FactoryGirl.sequences[name].next
29
+ Factory.next(name)
33
30
  end
34
31
  end
35
32
 
@@ -42,4 +39,4 @@ module FactoryGirl
42
39
  end
43
40
  end
44
41
 
45
- include FactoryGirl::Syntax::Sham
42
+ include Factory::Syntax::Sham