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