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.
- data/README.rdoc +67 -121
- data/Rakefile +103 -29
- data/VERSION +1 -0
- data/lib/factory_girl/aliases.rb +32 -3
- 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/attribute.rb +3 -3
- data/lib/factory_girl/factory.rb +354 -164
- data/lib/factory_girl/proxy/attributes_for.rb +1 -1
- data/lib/factory_girl/proxy/build.rb +5 -7
- data/lib/factory_girl/proxy/create.rb +3 -2
- data/lib/factory_girl/proxy/stub.rb +5 -19
- data/lib/factory_girl/proxy.rb +23 -7
- data/lib/factory_girl/sequence.rb +40 -5
- data/lib/factory_girl/step_definitions.rb +13 -19
- data/lib/factory_girl/syntax/blueprint.rb +5 -5
- data/lib/factory_girl/syntax/generate.rb +8 -13
- data/lib/factory_girl/syntax/make.rb +7 -9
- data/lib/factory_girl/syntax/sham.rb +8 -11
- data/lib/factory_girl/syntax.rb +7 -7
- data/lib/factory_girl.rb +19 -8
- data/spec/factory_girl/aliases_spec.rb +5 -9
- data/spec/factory_girl/attribute/association_spec.rb +4 -4
- data/spec/factory_girl/attribute/callback_spec.rb +4 -4
- data/spec/factory_girl/attribute/dynamic_spec.rb +10 -21
- data/spec/factory_girl/attribute/static_spec.rb +6 -6
- data/spec/factory_girl/attribute_spec.rb +6 -6
- data/spec/factory_girl/factory_spec.rb +465 -305
- data/spec/factory_girl/proxy/attributes_for_spec.rb +3 -3
- data/spec/factory_girl/proxy/build_spec.rb +13 -18
- data/spec/factory_girl/proxy/create_spec.rb +13 -18
- data/spec/factory_girl/proxy/stub_spec.rb +6 -7
- data/spec/factory_girl/proxy_spec.rb +3 -3
- data/spec/factory_girl/sequence_spec.rb +39 -16
- data/spec/factory_girl/syntax/blueprint_spec.rb +34 -0
- data/spec/factory_girl/syntax/generate_spec.rb +57 -0
- data/spec/factory_girl/syntax/make_spec.rb +35 -0
- data/spec/factory_girl/syntax/sham_spec.rb +35 -0
- data/spec/integration_spec.rb +304 -0
- data/spec/models.rb +43 -0
- data/spec/spec_helper.rb +10 -85
- metadata +15 -3
@@ -1,4 +1,4 @@
|
|
1
|
-
|
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,
|
17
|
-
|
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(
|
22
|
-
factory
|
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
|
-
|
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
|
-
|
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,
|
49
|
-
|
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(
|
54
|
-
factory
|
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
|
data/lib/factory_girl/proxy.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
|
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
|
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
|
-
#
|
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
|
-
#
|
64
|
+
# Factory.define :user do |f|
|
50
65
|
# # ...
|
51
66
|
# end
|
52
67
|
#
|
53
|
-
#
|
68
|
+
# Factory.define :post do |f|
|
54
69
|
# # ...
|
55
|
-
# author {
|
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
|
-
|
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(
|
10
|
+
def initialize (&proc) #:nodoc:
|
11
11
|
@proc = proc
|
12
|
-
@value =
|
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
|
-
|
6
|
-
factory =
|
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 =>
|
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
|
-
|
32
|
-
|
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.
|
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.
|
34
|
+
Factory(factory.factory_name)
|
41
35
|
end
|
42
36
|
|
43
|
-
Given /^(\d+) #{factory.human_name
|
44
|
-
count.to_i.times { Factory(factory.
|
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.
|
45
|
+
Factory(factory.factory_name, column.name => value)
|
52
46
|
end
|
53
47
|
|
54
|
-
Given /^(\d+) #{factory.human_name
|
55
|
-
count.to_i.times { Factory(factory.
|
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
|
-
|
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
|
-
|
31
|
-
|
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,
|
41
|
+
ActiveRecord::Base.send(:include, Factory::Syntax::Blueprint::ActiveRecord)
|
42
|
+
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
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
|
-
#
|
11
|
-
# factory
|
12
|
-
#
|
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
|
-
|
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
|
-
|
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
|
-
|
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,
|
68
|
+
ActiveRecord::Base.send(:include, Factory::Syntax::Generate::ActiveRecord)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
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
|
-
#
|
12
|
-
# factory
|
13
|
-
#
|
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
|
-
|
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,
|
39
|
+
ActiveRecord::Base.send(:include, Factory::Syntax::Make::ActiveRecord)
|
@@ -1,8 +1,8 @@
|
|
1
|
-
|
1
|
+
class Factory
|
2
2
|
module Syntax
|
3
3
|
|
4
4
|
# Adds a Sham module, which provides an alternate interface to
|
5
|
-
#
|
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
|
-
#
|
14
|
-
# factory
|
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,
|
25
|
+
def self.method_missing(name, &block)
|
28
26
|
if block_given?
|
29
|
-
|
30
|
-
FactoryGirl.sequences[name] = Sequence.new(start_value || 1, &block)
|
27
|
+
Factory.sequence(name, &block)
|
31
28
|
else
|
32
|
-
|
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
|
42
|
+
include Factory::Syntax::Sham
|