factory_girl 1.3.3 → 2.0.0.beta1
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.
- data/README.rdoc +68 -60
- data/features/support/test.db +0 -0
- data/lib/factory_girl.rb +6 -12
- data/lib/factory_girl/aliases.rb +2 -31
- data/lib/factory_girl/attribute.rb +1 -1
- data/lib/factory_girl/attribute/association.rb +1 -1
- data/lib/factory_girl/attribute/callback.rb +1 -1
- data/lib/factory_girl/attribute/dynamic.rb +3 -3
- data/lib/factory_girl/attribute/static.rb +1 -1
- data/lib/factory_girl/definition_proxy.rb +180 -0
- data/lib/factory_girl/deprecated.rb +18 -0
- data/lib/factory_girl/factory.rb +120 -355
- data/lib/factory_girl/find_definitions.rb +25 -0
- data/lib/factory_girl/proxy.rb +4 -6
- data/lib/factory_girl/proxy/attributes_for.rb +1 -1
- data/lib/factory_girl/proxy/build.rb +7 -5
- data/lib/factory_girl/proxy/create.rb +1 -1
- data/lib/factory_girl/proxy/stub.rb +11 -5
- data/lib/factory_girl/rails2.rb +1 -1
- data/lib/factory_girl/sequence.rb +5 -40
- data/lib/factory_girl/step_definitions.rb +7 -7
- data/lib/factory_girl/syntax.rb +7 -7
- data/lib/factory_girl/syntax/blueprint.rb +5 -4
- data/lib/factory_girl/syntax/default.rb +31 -0
- data/lib/factory_girl/syntax/generate.rb +13 -8
- data/lib/factory_girl/syntax/make.rb +8 -6
- data/lib/factory_girl/syntax/sham.rb +11 -8
- data/lib/factory_girl/syntax/vintage.rb +196 -0
- data/lib/factory_girl/version.rb +4 -0
- data/spec/acceptance/acceptance_spec.rb +43 -60
- data/spec/acceptance/syntax/blueprint_spec.rb +1 -5
- data/spec/acceptance/syntax/generate_spec.rb +1 -4
- data/spec/acceptance/syntax/make_spec.rb +1 -4
- data/spec/acceptance/syntax/sham_spec.rb +9 -7
- data/spec/acceptance/syntax/vintage_spec.rb +184 -0
- data/spec/factory_girl/aliases_spec.rb +5 -5
- data/spec/factory_girl/attribute/association_spec.rb +3 -3
- data/spec/factory_girl/attribute/callback_spec.rb +3 -3
- data/spec/factory_girl/attribute/dynamic_spec.rb +20 -9
- data/spec/factory_girl/attribute/static_spec.rb +5 -5
- data/spec/factory_girl/attribute_spec.rb +5 -5
- data/spec/factory_girl/definition_proxy_spec.rb +138 -0
- data/spec/factory_girl/deprecated_spec.rb +66 -0
- data/spec/factory_girl/factory_spec.rb +283 -566
- data/spec/factory_girl/find_definitions_spec.rb +89 -0
- data/spec/factory_girl/proxy/attributes_for_spec.rb +2 -2
- data/spec/factory_girl/proxy/build_spec.rb +17 -12
- data/spec/factory_girl/proxy/create_spec.rb +17 -12
- data/spec/factory_girl/proxy/stub_spec.rb +6 -5
- data/spec/factory_girl/proxy_spec.rb +2 -2
- data/spec/factory_girl/sequence_spec.rb +15 -38
- data/spec/spec_helper.rb +4 -0
- metadata +28 -11
@@ -0,0 +1,25 @@
|
|
1
|
+
module FactoryGirl
|
2
|
+
|
3
|
+
class << self
|
4
|
+
attr_accessor :factories #:nodoc:
|
5
|
+
|
6
|
+
# An Array of strings specifying locations that should be searched for
|
7
|
+
# factory definitions. By default, factory_girl will attempt to require
|
8
|
+
# "factories," "test/factories," and "spec/factories." Only the first
|
9
|
+
# existing file will be loaded.
|
10
|
+
attr_accessor :definition_file_paths
|
11
|
+
end
|
12
|
+
self.definition_file_paths = %w(factories test/factories spec/factories)
|
13
|
+
|
14
|
+
def self.find_definitions #:nodoc:
|
15
|
+
definition_file_paths.each do |path|
|
16
|
+
require("#{path}.rb") if File.exists?("#{path}.rb")
|
17
|
+
|
18
|
+
if File.directory? path
|
19
|
+
Dir[File.join(path, '*.rb')].sort.each do |file|
|
20
|
+
require file
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/factory_girl/proxy.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module FactoryGirl
|
3
2
|
class Proxy #:nodoc:
|
4
3
|
|
5
4
|
attr_reader :callbacks
|
@@ -47,13 +46,13 @@ class Factory
|
|
47
46
|
#
|
48
47
|
# Example:
|
49
48
|
#
|
50
|
-
#
|
49
|
+
# factory :user do
|
51
50
|
# # ...
|
52
51
|
# end
|
53
52
|
#
|
54
|
-
#
|
53
|
+
# factory :post do
|
55
54
|
# # ...
|
56
|
-
#
|
55
|
+
# author { |post| post.association(:user, :name => 'Joe') }
|
57
56
|
# end
|
58
57
|
#
|
59
58
|
# # Builds (but doesn't save) a Post and a User
|
@@ -75,5 +74,4 @@ class Factory
|
|
75
74
|
raise NotImplementedError, "Strategies must return a result"
|
76
75
|
end
|
77
76
|
end
|
78
|
-
|
79
77
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
module FactoryGirl
|
2
2
|
class Proxy #:nodoc:
|
3
3
|
class Build < Proxy #:nodoc:
|
4
4
|
def initialize(klass)
|
@@ -13,12 +13,14 @@ class Factory
|
|
13
13
|
@instance.send(:"#{attribute}=", value)
|
14
14
|
end
|
15
15
|
|
16
|
-
def associate(name,
|
17
|
-
|
16
|
+
def associate(name, factory_name, overrides)
|
17
|
+
factory = FactoryGirl.factory_by_name(factory_name)
|
18
|
+
set(name, factory.run(Proxy::Create, overrides))
|
18
19
|
end
|
19
20
|
|
20
|
-
def association(
|
21
|
-
|
21
|
+
def association(factory_name, overrides = {})
|
22
|
+
factory = FactoryGirl.factory_by_name(factory_name)
|
23
|
+
factory.run(Proxy::Create, overrides)
|
22
24
|
end
|
23
25
|
|
24
26
|
def result
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
module FactoryGirl
|
2
2
|
class Proxy
|
3
3
|
class Stub < Proxy #:nodoc:
|
4
4
|
@@next_id = 1000
|
@@ -26,6 +26,10 @@ class Factory
|
|
26
26
|
def reload
|
27
27
|
raise "stubbed models are not allowed to access the database"
|
28
28
|
end
|
29
|
+
|
30
|
+
def update_attribute(*args)
|
31
|
+
raise "stubbed models are not allowed to access the database"
|
32
|
+
end
|
29
33
|
end
|
30
34
|
end
|
31
35
|
|
@@ -41,12 +45,14 @@ class Factory
|
|
41
45
|
@instance.send(:"#{attribute}=", value)
|
42
46
|
end
|
43
47
|
|
44
|
-
def associate(name,
|
45
|
-
|
48
|
+
def associate(name, factory_name, overrides)
|
49
|
+
factory = FactoryGirl.factory_by_name(factory_name)
|
50
|
+
set(name, factory.run(Proxy::Stub, overrides))
|
46
51
|
end
|
47
52
|
|
48
|
-
def association(
|
49
|
-
|
53
|
+
def association(factory_name, overrides = {})
|
54
|
+
factory = FactoryGirl.factory_by_name(factory_name)
|
55
|
+
factory.run(Proxy::Stub, overrides)
|
50
56
|
end
|
51
57
|
|
52
58
|
def result
|
data/lib/factory_girl/rails2.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
Rails.configuration.after_initialize {
|
1
|
+
Rails.configuration.after_initialize { FactoryGirl.find_definitions }
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
module FactoryGirl
|
2
2
|
|
3
3
|
# Raised when calling Factory.sequence from a dynamic attribute block
|
4
4
|
class SequenceAbuseError < StandardError; end
|
@@ -7,15 +7,16 @@ class Factory
|
|
7
7
|
# using next.
|
8
8
|
class Sequence
|
9
9
|
|
10
|
-
def initialize
|
10
|
+
def initialize(value = 1, &proc) #:nodoc:
|
11
11
|
@proc = proc
|
12
|
-
@value =
|
12
|
+
@value = value || 1
|
13
13
|
end
|
14
14
|
|
15
15
|
# Returns the next value for this sequence
|
16
16
|
def next
|
17
|
-
@value += 1
|
18
17
|
@proc.call(@value)
|
18
|
+
ensure
|
19
|
+
@value = @value.next
|
19
20
|
end
|
20
21
|
|
21
22
|
end
|
@@ -24,40 +25,4 @@ class Factory
|
|
24
25
|
attr_accessor :sequences #:nodoc:
|
25
26
|
end
|
26
27
|
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
|
-
|
63
28
|
end
|
@@ -3,7 +3,7 @@ module FactoryGirlStepHelpers
|
|
3
3
|
attribute, value = assignment.split(':', 2)
|
4
4
|
return if value.blank?
|
5
5
|
attributes = convert_human_hash_to_attribute_hash(attribute => value.strip)
|
6
|
-
factory =
|
6
|
+
factory = FactoryGirl.factory_by_name(factory_name)
|
7
7
|
model_class = factory.build_class
|
8
8
|
model_class.find(:first, :conditions => attributes) or
|
9
9
|
Factory(factory_name, attributes)
|
@@ -22,31 +22,31 @@ end
|
|
22
22
|
|
23
23
|
World(FactoryGirlStepHelpers)
|
24
24
|
|
25
|
-
|
25
|
+
FactoryGirl.factories.values.each do |factory|
|
26
26
|
Given /^the following (?:#{factory.human_name}|#{factory.human_name.pluralize}) exists?:$/ do |table|
|
27
27
|
table.hashes.each do |human_hash|
|
28
28
|
attributes = convert_human_hash_to_attribute_hash(human_hash, factory.associations)
|
29
|
-
|
29
|
+
factory.run(FactoryGirl::Proxy::Create, attributes)
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
33
|
Given /^an? #{factory.human_name} exists$/ do
|
34
|
-
Factory(factory.
|
34
|
+
Factory(factory.name)
|
35
35
|
end
|
36
36
|
|
37
37
|
Given /^(\d+) #{factory.human_name.pluralize} exist$/ do |count|
|
38
|
-
count.to_i.times { Factory(factory.
|
38
|
+
count.to_i.times { Factory(factory.name) }
|
39
39
|
end
|
40
40
|
|
41
41
|
if factory.build_class.respond_to?(:columns)
|
42
42
|
factory.build_class.columns.each do |column|
|
43
43
|
human_column_name = column.name.downcase.gsub('_', ' ')
|
44
44
|
Given /^an? #{factory.human_name} exists with an? #{human_column_name} of "([^"]*)"$/i do |value|
|
45
|
-
Factory(factory.
|
45
|
+
Factory(factory.name, column.name => value)
|
46
46
|
end
|
47
47
|
|
48
48
|
Given /^(\d+) #{factory.human_name.pluralize} exist with an? #{human_column_name} of "([^"]*)"$/i do |count, value|
|
49
|
-
count.to_i.times { Factory(factory.
|
49
|
+
count.to_i.times { Factory(factory.name, column.name => value) }
|
50
50
|
end
|
51
51
|
end
|
52
52
|
end
|
data/lib/factory_girl/syntax.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
|
-
|
1
|
+
module FactoryGirl
|
2
2
|
# Provides alternate syntaxes for factory_girl. If you don't like the default
|
3
|
-
# syntax for defining or using factories, look at one of the
|
4
|
-
# modules:
|
3
|
+
# syntax for defining or using factories, look at one of the
|
4
|
+
# FactoryGirl::Syntax modules:
|
5
5
|
#
|
6
|
-
# *
|
7
|
-
# *
|
8
|
-
# *
|
9
|
-
# *
|
6
|
+
# * FactoryGirl::Syntax::Blueprint: definition syntax similar to Machinist
|
7
|
+
# * FactoryGirl::Syntax::Generate: usage syntax similar to Object Daddy
|
8
|
+
# * FactoryGirl::Syntax::Make: usage syntax similar to Machinist
|
9
|
+
# * FactoryGirl::Syntax::Sham: sequence syntax similar to Machinist
|
10
10
|
module Syntax
|
11
11
|
end
|
12
12
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
module FactoryGirl
|
2
2
|
module Syntax
|
3
3
|
|
4
4
|
# Extends ActiveRecord::Base to provide a make class method, which is an
|
@@ -27,8 +27,9 @@ class Factory
|
|
27
27
|
|
28
28
|
def blueprint(&block)
|
29
29
|
instance = Factory.new(name.underscore, :class => self)
|
30
|
-
|
31
|
-
|
30
|
+
proxy = FactoryGirl::DefinitionProxy.new(instance)
|
31
|
+
proxy.instance_eval(&block)
|
32
|
+
FactoryGirl.register_factory(instance)
|
32
33
|
end
|
33
34
|
|
34
35
|
end
|
@@ -38,4 +39,4 @@ class Factory
|
|
38
39
|
end
|
39
40
|
end
|
40
41
|
|
41
|
-
ActiveRecord::Base.send(:include,
|
42
|
+
ActiveRecord::Base.send(:include, FactoryGirl::Syntax::Blueprint::ActiveRecord)
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module FactoryGirl
|
2
|
+
module Syntax
|
3
|
+
module Default
|
4
|
+
def define(&block)
|
5
|
+
DSL.run(block)
|
6
|
+
end
|
7
|
+
|
8
|
+
class DSL
|
9
|
+
def self.run(block)
|
10
|
+
new.instance_eval(&block)
|
11
|
+
end
|
12
|
+
|
13
|
+
def factory(name, options = {}, &block)
|
14
|
+
factory = Factory.new(name, options)
|
15
|
+
proxy = FactoryGirl::DefinitionProxy.new(factory)
|
16
|
+
proxy.instance_eval(&block)
|
17
|
+
if parent = options.delete(:parent)
|
18
|
+
factory.inherit_from(FactoryGirl.factory_by_name(parent))
|
19
|
+
end
|
20
|
+
FactoryGirl.register_factory(factory)
|
21
|
+
end
|
22
|
+
|
23
|
+
def sequence(name, start_value = 1, &block)
|
24
|
+
FactoryGirl.sequences[name] = Sequence.new(start_value, &block)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
extend Syntax::Default
|
31
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
module FactoryGirl
|
2
2
|
module Syntax
|
3
3
|
|
4
4
|
# Extends ActiveRecord::Base to provide generation methods for factories.
|
@@ -7,9 +7,11 @@ class Factory
|
|
7
7
|
#
|
8
8
|
# require 'factory_girl/syntax/generate'
|
9
9
|
#
|
10
|
-
#
|
11
|
-
# factory
|
12
|
-
#
|
10
|
+
# FactoryGirl.define do
|
11
|
+
# factory :user do
|
12
|
+
# name 'Billy Bob'
|
13
|
+
# email 'billy@bob.example.com'
|
14
|
+
# end
|
13
15
|
# end
|
14
16
|
#
|
15
17
|
# # Creates a saved instance without raising (same as saving the result
|
@@ -40,20 +42,23 @@ class Factory
|
|
40
42
|
module ClassMethods #:nodoc:
|
41
43
|
|
42
44
|
def generate(overrides = {}, &block)
|
43
|
-
|
45
|
+
factory = FactoryGirl.factory_by_name(name.underscore)
|
46
|
+
instance = factory.run(Proxy::Build, overrides)
|
44
47
|
instance.save
|
45
48
|
yield(instance) if block_given?
|
46
49
|
instance
|
47
50
|
end
|
48
51
|
|
49
52
|
def generate!(overrides = {}, &block)
|
50
|
-
|
53
|
+
factory = FactoryGirl.factory_by_name(name.underscore)
|
54
|
+
instance = factory.run(Proxy::Create, overrides)
|
51
55
|
yield(instance) if block_given?
|
52
56
|
instance
|
53
57
|
end
|
54
58
|
|
55
59
|
def spawn(overrides = {}, &block)
|
56
|
-
|
60
|
+
factory = FactoryGirl.factory_by_name(name.underscore)
|
61
|
+
instance = factory.run(Proxy::Build, overrides)
|
57
62
|
yield(instance) if block_given?
|
58
63
|
instance
|
59
64
|
end
|
@@ -65,4 +70,4 @@ class Factory
|
|
65
70
|
end
|
66
71
|
end
|
67
72
|
|
68
|
-
ActiveRecord::Base.send(:include,
|
73
|
+
ActiveRecord::Base.send(:include, FactoryGirl::Syntax::Generate::ActiveRecord)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
module FactoryGirl
|
2
2
|
module Syntax
|
3
3
|
|
4
4
|
# Extends ActiveRecord::Base to provide a make class method, which is a
|
@@ -8,9 +8,11 @@ class Factory
|
|
8
8
|
#
|
9
9
|
# require 'factory_girl/syntax/make'
|
10
10
|
#
|
11
|
-
#
|
12
|
-
# factory
|
13
|
-
#
|
11
|
+
# FactoryGirl.define do
|
12
|
+
# factory :user do
|
13
|
+
# name 'Billy Bob'
|
14
|
+
# email 'billy@bob.example.com'
|
15
|
+
# end
|
14
16
|
# end
|
15
17
|
#
|
16
18
|
# User.make(:name => 'Johnny')
|
@@ -26,7 +28,7 @@ class Factory
|
|
26
28
|
module ClassMethods #:nodoc:
|
27
29
|
|
28
30
|
def make(overrides = {})
|
29
|
-
|
31
|
+
FactoryGirl.factory_by_name(name.underscore).run(Proxy::Create, overrides)
|
30
32
|
end
|
31
33
|
|
32
34
|
end
|
@@ -36,4 +38,4 @@ class Factory
|
|
36
38
|
end
|
37
39
|
end
|
38
40
|
|
39
|
-
ActiveRecord::Base.send(:include,
|
41
|
+
ActiveRecord::Base.send(:include, FactoryGirl::Syntax::Make::ActiveRecord)
|
@@ -1,8 +1,8 @@
|
|
1
|
-
|
1
|
+
module FactoryGirl
|
2
2
|
module Syntax
|
3
3
|
|
4
4
|
# Adds a Sham module, which provides an alternate interface to
|
5
|
-
#
|
5
|
+
# FactoryGirl::Sequence.
|
6
6
|
#
|
7
7
|
# Usage:
|
8
8
|
#
|
@@ -10,8 +10,10 @@ class Factory
|
|
10
10
|
#
|
11
11
|
# Sham.email {|n| "somebody#{n}@example.com" }
|
12
12
|
#
|
13
|
-
#
|
14
|
-
# factory
|
13
|
+
# FactoryGirl.define do
|
14
|
+
# factory :user do
|
15
|
+
# email
|
16
|
+
# end
|
15
17
|
# end
|
16
18
|
#
|
17
19
|
# Note that you can also use Faker, but it is recommended that you simply
|
@@ -22,11 +24,12 @@ class Factory
|
|
22
24
|
# This syntax was derived from Pete Yandell's machinist.
|
23
25
|
module Sham
|
24
26
|
module Sham #:nodoc:
|
25
|
-
def self.method_missing(name, &block)
|
27
|
+
def self.method_missing(name, *args, &block)
|
26
28
|
if block_given?
|
27
|
-
|
29
|
+
start_value = args.first
|
30
|
+
FactoryGirl.sequences[name] = Sequence.new(start_value || 1, &block)
|
28
31
|
else
|
29
|
-
|
32
|
+
FactoryGirl.sequences[name].next
|
30
33
|
end
|
31
34
|
end
|
32
35
|
|
@@ -39,4 +42,4 @@ class Factory
|
|
39
42
|
end
|
40
43
|
end
|
41
44
|
|
42
|
-
include
|
45
|
+
include FactoryGirl::Syntax::Sham
|