modelfactory 0.8.1 → 0.8.9
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/History.txt +4 -4
- data/License.txt +1 -1
- data/Manifest.txt +8 -1
- data/README.txt +52 -92
- data/Rakefile +2 -1
- data/lib/fixture_converter.rb +2 -2
- data/lib/model_factory.rb +7 -107
- data/lib/modelfactory.rb +61 -0
- data/lib/modelfactory/factory.rb +59 -0
- data/lib/modelfactory/legacy.rb +191 -0
- data/lib/{model_factory → modelfactory}/version.rb +1 -1
- data/test/fixtures/schema.rb +8 -0
- data/test/fixtures/strict_widget.rb +6 -0
- data/test/fixtures/widget.rb +4 -0
- data/test/model_factory_legacy_test.rb +142 -0
- data/test/model_factory_test.rb +68 -121
- data/test/test_helper.rb +17 -7
- metadata +51 -3
data/History.txt
CHANGED
@@ -1,15 +1,15 @@
|
|
1
|
-
== 0.8.
|
1
|
+
== 0.8.9 2009-05-19
|
2
|
+
* Renamed the required lib to 'modelfactory'
|
3
|
+
* Completely redesigned API, see the documentation in README.txt
|
2
4
|
|
5
|
+
== 0.8.1 2009-05-08
|
3
6
|
* Ruby 1.9.1 compatibility
|
4
7
|
|
5
8
|
== 0.8.0 2008-12-10
|
6
|
-
|
7
9
|
* added the ability to specify multiple named types of defaults
|
8
10
|
|
9
11
|
== 0.7.0 2008-11-11
|
10
|
-
|
11
12
|
* Documentation and rubygem
|
12
13
|
|
13
14
|
== 0.0.1 2008-01-25
|
14
|
-
|
15
15
|
* Initial release
|
data/License.txt
CHANGED
data/Manifest.txt
CHANGED
@@ -5,11 +5,18 @@ README.txt
|
|
5
5
|
Rakefile
|
6
6
|
lib/fixture_converter.rb
|
7
7
|
lib/model_factory.rb
|
8
|
-
lib/
|
8
|
+
lib/modelfactory.rb
|
9
|
+
lib/modelfactory/factory.rb
|
10
|
+
lib/modelfactory/legacy.rb
|
11
|
+
lib/modelfactory/version.rb
|
9
12
|
script/destroy
|
10
13
|
script/fixtures2factories
|
11
14
|
script/generate
|
12
15
|
script/txt2html
|
13
16
|
setup.rb
|
17
|
+
test/fixtures/schema.rb
|
18
|
+
test/fixtures/strict_widget.rb
|
19
|
+
test/fixtures/widget.rb
|
20
|
+
test/model_factory_legacy_test.rb
|
14
21
|
test/model_factory_test.rb
|
15
22
|
test/test_helper.rb
|
data/README.txt
CHANGED
@@ -6,117 +6,76 @@ Rails applications.
|
|
6
6
|
The best explanation for the motivation behind ModelFactory (and the inspiration
|
7
7
|
for this module) comes from Dan Manges' blog: http://www.dcmanges.com/blog/38
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NOTE that the API has changed recently, but ModelFactory is still fully
|
10
|
+
backward-compatible with previous releases. For a description of the original
|
11
|
+
API see ModelFactory::Legacy.
|
12
12
|
|
13
|
-
|
14
|
-
to spot factory calls in your tests and keep your factory code out of your
|
15
|
-
test code. ModelFactory adds some useful facilities for generating optional
|
16
|
-
defaults for commonly instantiated types. It also fakes up id generation in
|
17
|
-
the ActiveRecord models created with new, to assist in unit testing without
|
18
|
-
the database.
|
13
|
+
== Usage
|
19
14
|
|
20
|
-
|
21
|
-
|
22
|
-
The purpose of default values is to generate valid instances, not to serve as
|
23
|
-
replacements for fixture data. When writing tests that use factory-generated
|
24
|
-
objects, it's important never to depend on default values in your test assertions.
|
25
|
-
If you depend on defaults in your tests they become more fragile and the intention
|
26
|
-
is harder to discern. Alway override values you care about when using factory objects.
|
15
|
+
The essential purpose of ModelFactory is the automatic generation of valid,
|
16
|
+
opaque ActiveRecord objects whose contents are unimportant.
|
27
17
|
|
28
|
-
|
29
|
-
consider whether it would be appropriate to add a custom toplevel method to
|
30
|
-
your factory module that includes this initialization. You can also specify
|
31
|
-
multiple named types of defaults, described below. Be aware that both of these
|
32
|
-
techniques should be used sparingly, as they can have some of the same issues
|
33
|
-
as fixtures.
|
18
|
+
require 'modelfactory'
|
34
19
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
== Using ModelFactory
|
43
|
-
|
44
|
-
Put something like this in your test helper:
|
20
|
+
ModelFactory.configuration do
|
21
|
+
default(User) do |m|
|
22
|
+
m.name = "Factory User"
|
23
|
+
m.email = "user@factory.ws"
|
24
|
+
end
|
25
|
+
end
|
45
26
|
|
46
|
-
|
27
|
+
ModelFactory[User].create.name # => 'Factory User'
|
47
28
|
|
48
|
-
|
49
|
-
|
29
|
+
If you don't care for the factory creation syntax, ModelFactory defines the
|
30
|
+
factory class method on ActiveRecord models. The following is equivalent
|
31
|
+
to ModelFactory[User].create:
|
50
32
|
|
51
|
-
|
52
|
-
default Color, {
|
53
|
-
:name => 'chartreuse'
|
54
|
-
}
|
33
|
+
User.factory.create
|
55
34
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
}
|
35
|
+
Since factory-created instances are meant to be valid, you will probably
|
36
|
+
need a way to generate unique values. ModelFactory keeps a counter for each
|
37
|
+
type that increments when each new instance is created. This counter is passed
|
38
|
+
to configuration blocks to make it easier to generate unique values:
|
61
39
|
|
62
|
-
|
63
|
-
|
64
|
-
|
40
|
+
ModelFactory.configuration do
|
41
|
+
default(User) do |m, i|
|
42
|
+
m.name = "Factory User #{i}"
|
43
|
+
m.email = "user#{i}@factory.ws"
|
65
44
|
end
|
66
|
-
|
67
45
|
end
|
68
46
|
|
69
|
-
|
47
|
+
User.factory.create.name # => 'Factory User 1'
|
48
|
+
User.factory.create.email # => 'user2@factory.ws'
|
70
49
|
|
71
|
-
|
72
|
-
|
73
|
-
user = Factory.create_user
|
74
|
-
user.friends << Factory.create_user(:first_name => 'Frank')
|
75
|
-
assert user.likes_frank?
|
76
|
-
end
|
50
|
+
Defaults can be overriden on instance creation. By not specifying unimportant
|
51
|
+
values, the intention of your tests becomes clearer:
|
77
52
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
assert user.likes_blue?
|
53
|
+
def test_welcome
|
54
|
+
user = ModelFactory[User].create(:name => 'bob')
|
55
|
+
assert_equal 'Welcome, bob!', user.welcome
|
82
56
|
end
|
83
57
|
|
84
|
-
|
85
|
-
# factory methods that build objects with specific traits.
|
86
|
-
def test_yet_something_else
|
87
|
-
user = Factory.new_user_with_colorblindness
|
88
|
-
assert !user.likes_blue?
|
89
|
-
end
|
58
|
+
It's possible to configure named factories:
|
90
59
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
default User, :joined {
|
98
|
-
:first_name => 'Harry',
|
99
|
-
:last_name => 'Manchester',
|
100
|
-
:joined => true,
|
101
|
-
:set_password => true,
|
102
|
-
}
|
103
|
-
|
104
|
-
default User, :unjoined {
|
105
|
-
:first_name => 'Harry',
|
106
|
-
:last_name => 'Manchester',
|
107
|
-
:joined => false,
|
108
|
-
:set_password => false,
|
109
|
-
}
|
60
|
+
ModelFactory.configuration do
|
61
|
+
admin(User) do |m, i|
|
62
|
+
m.name = "Admin User #{i}"
|
63
|
+
m.admin = true
|
64
|
+
end
|
110
65
|
end
|
111
66
|
|
112
|
-
|
67
|
+
User.factory.create_admin.admin # => true
|
113
68
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
69
|
+
Named factories do not inherit anything from the default, so you'll still need to
|
70
|
+
provide enough to data to allow the creation of valid objects.
|
71
|
+
|
72
|
+
=== A Note About Defaults
|
73
|
+
|
74
|
+
The purpose of default values is to generate valid instances, not to serve as
|
75
|
+
replacements for fixture data. When writing tests that use factory-generated
|
76
|
+
objects, it's important never to depend on default values in your test assertions.
|
77
|
+
If you depend on defaults in your tests they become more fragile and the intention
|
78
|
+
is harder to discern. Alway override values you care about when using factory objects.
|
120
79
|
|
121
80
|
== Installing ModelFactory
|
122
81
|
|
@@ -124,6 +83,7 @@ Then in your test:
|
|
124
83
|
|
125
84
|
== License
|
126
85
|
|
127
|
-
Copyright (c) 2008 Justin Balthrop and Zack Hobson
|
86
|
+
Copyright (c) 2008, 2009 Justin Balthrop and Zack Hobson
|
87
|
+
|
128
88
|
Published under The MIT License, see License.txt
|
129
89
|
|
data/Rakefile
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'hoe'
|
3
3
|
$:.unshift(File.dirname(__FILE__) + "/lib")
|
4
|
-
require '
|
4
|
+
require 'modelfactory/version'
|
5
5
|
|
6
6
|
Hoe.new('ModelFactory', ModelFactory::VERSION::STRING) do |p|
|
7
7
|
p.name = "modelfactory"
|
@@ -15,6 +15,7 @@ Hoe.new('ModelFactory', ModelFactory::VERSION::STRING) do |p|
|
|
15
15
|
p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
|
16
16
|
p.test_globs = ["test/**/*_test.rb"]
|
17
17
|
p.clean_globs |= ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store']
|
18
|
+
p.extra_dev_deps = ['active_record', 'mocha', 'thoughtbot-shoulda', 'sqlite3-ruby']
|
18
19
|
end
|
19
20
|
|
20
21
|
|
data/lib/fixture_converter.rb
CHANGED
data/lib/model_factory.rb
CHANGED
@@ -1,113 +1,13 @@
|
|
1
|
+
#
|
2
|
+
# This is the legacy modelfactory API.
|
3
|
+
# The current implementation is in lib/modelfactory.rb.
|
4
|
+
#
|
1
5
|
require 'rubygems'
|
2
6
|
require 'active_record'
|
7
|
+
require 'modelfactory/legacy'
|
3
8
|
|
4
9
|
module ModelFactory
|
5
|
-
def
|
6
|
-
|
7
|
-
return @max_id += 1
|
8
|
-
end
|
9
|
-
|
10
|
-
#
|
11
|
-
# When specifying defaults, you should only provide only enough data that
|
12
|
-
# the created instance is valid. If you want to include another factory
|
13
|
-
# object as a dependency use the special method default_* instead of
|
14
|
-
# create_* or new_*.
|
15
|
-
#
|
16
|
-
def default(class_type, *default_args)
|
17
|
-
defaults = default_args.pop || {}
|
18
|
-
prefix = default_args.first
|
19
|
-
class_name = class_type.name.demodulize.underscore
|
20
|
-
class_name = "#{prefix}_#{class_name}" if prefix
|
21
|
-
|
22
|
-
(class << self; self; end).module_eval do
|
23
|
-
define_method "create_#{class_name}" do |*args|
|
24
|
-
attributes = args.first || {}
|
25
|
-
create_instance(class_type, attributes, defaults)
|
26
|
-
end
|
27
|
-
|
28
|
-
define_method "new_#{class_name}" do |*args|
|
29
|
-
attributes = args.first || {}
|
30
|
-
new_instance(class_type, attributes, defaults)
|
31
|
-
end
|
32
|
-
|
33
|
-
define_method "default_#{class_name}" do |*args|
|
34
|
-
attributes = args.first || {}
|
35
|
-
default_closure(class_type, attributes, defaults)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def create_instance(class_type, attributes, defaults = {}) # :nodoc:
|
41
|
-
attributes = instantiate_defaults(:create, defaults.merge(attributes))
|
42
|
-
instance = class_type.create!(attributes)
|
43
|
-
if update_protected_attributes(instance, attributes)
|
44
|
-
instance.save
|
45
|
-
end
|
46
|
-
instance
|
47
|
-
end
|
48
|
-
|
49
|
-
def new_instance(class_type, attributes, defaults = {}) # :nodoc:
|
50
|
-
attributes = instantiate_defaults(:new, defaults.merge(attributes))
|
51
|
-
instance = class_type.new(attributes)
|
52
|
-
instance.id = next_local_id
|
53
|
-
update_protected_attributes(instance, attributes)
|
54
|
-
instance
|
55
|
-
end
|
56
|
-
|
57
|
-
def default_closure(class_type, attributes, defaults = {}) # :nodoc:
|
58
|
-
lambda do |create_or_new|
|
59
|
-
case create_or_new
|
60
|
-
when :new ; new_instance(class_type, attributes, defaults)
|
61
|
-
when :create ; create_instance(class_type, attributes, defaults)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def instantiate_defaults(create_or_new, attributes) # :nodoc:
|
67
|
-
attributes.each do |key, value|
|
68
|
-
if value.is_a?(Proc)
|
69
|
-
attributes[key] = value.arity == 0 ? value.call : value.call(create_or_new)
|
70
|
-
end
|
71
|
-
end
|
72
|
-
attributes
|
73
|
-
end
|
74
|
-
|
75
|
-
def update_protected_attributes(instance, attributes) # :nodoc:
|
76
|
-
modified = false
|
77
|
-
protected_attrs = instance.class.protected_attributes
|
78
|
-
protected_attrs = protected_attrs.to_set if protected_attrs
|
79
|
-
accessible_attrs = instance.class.accessible_attributes
|
80
|
-
accessible_attrs = accessible_attrs.to_set if accessible_attrs
|
81
|
-
|
82
|
-
if protected_attrs or accessible_attrs
|
83
|
-
attributes.each do |key, value|
|
84
|
-
# Support symbols and strings.
|
85
|
-
next if protected_attrs and (not protected_attrs.include?(key) or protected_attrs.include?(key.to_s))
|
86
|
-
next if accessible_attrs and (accessible_attrs.include?(key) or accessible_attrs.include?(key.to_s))
|
87
|
-
modified = true
|
88
|
-
instance.send("#{key}=", value)
|
89
|
-
end
|
90
|
-
end
|
91
|
-
return modified
|
92
|
-
end
|
93
|
-
|
94
|
-
# Any class methods of the form "new_some_type(attrs)" or "create_some_type(attrs)" will be converted to
|
95
|
-
# "SomeType.new(attrs)" and "SomeType.create!(attrs)" respectively.
|
96
|
-
# These basically function as though you'd used the 'default' directive with empty defaults.
|
97
|
-
def method_missing(missing_method, attributes = {})
|
98
|
-
if missing_method.to_s.match(/^(new|create|default)_([a-z][\w_]+)$/)
|
99
|
-
method, class_name = $1, $2
|
100
|
-
class_type = class_name.camelize.constantize
|
101
|
-
case method
|
102
|
-
when 'create'
|
103
|
-
create_instance(class_type, attributes)
|
104
|
-
when 'new'
|
105
|
-
new_instance(class_type, attributes)
|
106
|
-
when 'default'
|
107
|
-
default_closure(class_type, attributes)
|
108
|
-
end
|
109
|
-
else
|
110
|
-
raise NoMethodError, "no such method '#{missing_method}'"
|
111
|
-
end
|
10
|
+
def self.extended(mod)
|
11
|
+
mod.extend(ModelFactory::Legacy)
|
112
12
|
end
|
113
13
|
end
|
data/lib/modelfactory.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'active_record'
|
3
|
+
require 'modelfactory/factory'
|
4
|
+
require 'modelfactory/legacy'
|
5
|
+
|
6
|
+
ActiveRecord::Base.class_eval do
|
7
|
+
def self.factory ; ModelFactory[self] ; end
|
8
|
+
end
|
9
|
+
|
10
|
+
module ModelFactory
|
11
|
+
# Configure the factory singleton by passing a block.
|
12
|
+
#
|
13
|
+
# You can call this method multiple times. Each time you do so it will
|
14
|
+
# clear the existing configuration and reset the counters.
|
15
|
+
#
|
16
|
+
# You don't need to configure ModelFactory to use it.
|
17
|
+
def self.configure(&block)
|
18
|
+
@singleton = Wrapper.new(&block)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Get the Factory for a given model class.
|
22
|
+
def self.[](klass)
|
23
|
+
@singleton ||= Wrapper.new
|
24
|
+
@singleton.wrap(klass)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Enable legacy API compatibility.
|
28
|
+
def self.extended(mod) # :nodoc:
|
29
|
+
mod.extend(ModelFactory::Legacy)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Singleton Factory wrapper class.
|
33
|
+
class Wrapper # :nodoc:
|
34
|
+
# Create a new FactoryConfiguration with the given block.
|
35
|
+
def initialize(&block)
|
36
|
+
@config = FactoryConfiguration.new(&block)
|
37
|
+
@factory = {}
|
38
|
+
end
|
39
|
+
|
40
|
+
# Wraps a given class in a configured Factory instance.
|
41
|
+
def wrap(klass)
|
42
|
+
@factory[klass] ||= Factory.new(klass, @config.class_opts[klass])
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Factory configuration class.
|
47
|
+
class FactoryConfiguration # :nodoc:
|
48
|
+
attr_reader :class_opts
|
49
|
+
|
50
|
+
def initialize(&block)
|
51
|
+
@class_opts = {}
|
52
|
+
instance_eval(&block) if block_given?
|
53
|
+
end
|
54
|
+
|
55
|
+
# All method calls set up a configuration named after the method.
|
56
|
+
def method_missing(method, klass, &block)
|
57
|
+
@class_opts[klass] ||= {}
|
58
|
+
@class_opts[klass][method] = block
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module ModelFactory # :nodoc:
|
2
|
+
# This API allows you to instantiate models.
|
3
|
+
class Factory # :nodoc:
|
4
|
+
def initialize(klass, opt)
|
5
|
+
@counter = 0
|
6
|
+
@class = klass
|
7
|
+
@options = opt || {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def create(opt = {}, &block)
|
11
|
+
create_named(:default, opt, &block)
|
12
|
+
end
|
13
|
+
|
14
|
+
def new(opt = {}, &block)
|
15
|
+
new_named(:default, opt, &block)
|
16
|
+
end
|
17
|
+
|
18
|
+
def method_missing(method, opt = {}, &block)
|
19
|
+
case method.to_s
|
20
|
+
when /^create_(.+)$/
|
21
|
+
create_named($1.to_sym, opt, &block)
|
22
|
+
when /^new_(.+)$/
|
23
|
+
new_named($1.to_sym, opt, &block)
|
24
|
+
else
|
25
|
+
raise NameError, "no such method `#{method}'"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def next_counter
|
32
|
+
@counter += 1
|
33
|
+
end
|
34
|
+
|
35
|
+
def new_named(name, opt = {}, &block)
|
36
|
+
instance = @class.new
|
37
|
+
if @options[name]
|
38
|
+
case @options[name].arity
|
39
|
+
when 2
|
40
|
+
@options[name].call(instance, next_counter) if @options[name]
|
41
|
+
else
|
42
|
+
@options[name].call(instance) if @options[name]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
opt.each {|k,v| instance.send("#{k}=", v) }
|
46
|
+
yield instance if block_given?
|
47
|
+
instance
|
48
|
+
end
|
49
|
+
|
50
|
+
def create_named(name, opt = {}, &block)
|
51
|
+
instance = new_named(name, opt, &block)
|
52
|
+
instance.save!
|
53
|
+
instance.reload
|
54
|
+
instance
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
@@ -0,0 +1,191 @@
|
|
1
|
+
module ModelFactory
|
2
|
+
# == ModelFactory Legacy API
|
3
|
+
#
|
4
|
+
# Put something like this in your test helper:
|
5
|
+
#
|
6
|
+
# require 'model_factory'
|
7
|
+
#
|
8
|
+
# module Factory
|
9
|
+
# extend ModelFactory
|
10
|
+
#
|
11
|
+
# # a default block accepts a class and a hash of default values
|
12
|
+
# default Color, {
|
13
|
+
# :name => 'chartreuse'
|
14
|
+
# }
|
15
|
+
#
|
16
|
+
# default User, {
|
17
|
+
# :first_name => 'Harry',
|
18
|
+
# :last_name => 'Manchester',
|
19
|
+
# :favorite_color => default_color
|
20
|
+
# }
|
21
|
+
#
|
22
|
+
# # Add class methods to create whatever kind of objects you need for your tests
|
23
|
+
# def self.new_user_with_colorblindness
|
24
|
+
# new_user { :favorite_color => nil }
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# Then in your tests you use Factory methods to instantiate your test objects:
|
30
|
+
#
|
31
|
+
# # For most functional tests you can use create.
|
32
|
+
# def test_something
|
33
|
+
# user = Factory.create_user
|
34
|
+
# user.friends << Factory.create_user(:first_name => 'Frank')
|
35
|
+
# assert user.likes_frank?
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# # For unit tests you use new.
|
39
|
+
# def test_something_else
|
40
|
+
# user = Factory.new_user(:favorite_color => Factory.new_color(:name => 'blue'))
|
41
|
+
# assert user.likes_blue?
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
# # Assertions should not depend on default data, but it can be useful to create
|
45
|
+
# # factory methods that build objects with specific traits.
|
46
|
+
# def test_yet_something_else
|
47
|
+
# user = Factory.new_user_with_colorblindness
|
48
|
+
# assert !user.likes_blue?
|
49
|
+
# end
|
50
|
+
#
|
51
|
+
# You can also specify types of models in your calls to defaults, but be careful. This can
|
52
|
+
# easily start to become a lot like fixtures:
|
53
|
+
#
|
54
|
+
# module Factory
|
55
|
+
# extend ModelFactory
|
56
|
+
#
|
57
|
+
# default User, :joined {
|
58
|
+
# :first_name => 'Harry',
|
59
|
+
# :last_name => 'Manchester',
|
60
|
+
# :joined => true,
|
61
|
+
# :set_password => true,
|
62
|
+
# }
|
63
|
+
#
|
64
|
+
# default User, :unjoined {
|
65
|
+
# :first_name => 'Harry',
|
66
|
+
# :last_name => 'Manchester',
|
67
|
+
# :joined => false,
|
68
|
+
# :set_password => false,
|
69
|
+
# }
|
70
|
+
# end
|
71
|
+
#
|
72
|
+
# Then in your test:
|
73
|
+
#
|
74
|
+
# def test_something
|
75
|
+
# user1 = Factory.create_joined_user(:first_name => 'Bill')
|
76
|
+
# user2 = Factory.create_unjoined_user(:first_name => 'Sandy')
|
77
|
+
# assert user1.joined?
|
78
|
+
# assert !user2.joined?
|
79
|
+
# end
|
80
|
+
#
|
81
|
+
module Legacy
|
82
|
+
def next_local_id # :nodoc:
|
83
|
+
@max_id ||= 0
|
84
|
+
return @max_id += 1
|
85
|
+
end
|
86
|
+
|
87
|
+
#
|
88
|
+
# When specifying defaults, you should only provide only enough data that
|
89
|
+
# the created instance is valid. If you want to include another factory
|
90
|
+
# object as a dependency use the special method default_* instead of
|
91
|
+
# create_* or new_*.
|
92
|
+
#
|
93
|
+
def default(class_type, *default_args)
|
94
|
+
defaults = default_args.pop || {}
|
95
|
+
prefix = default_args.first
|
96
|
+
class_name = class_type.name.demodulize.underscore
|
97
|
+
class_name = "#{prefix}_#{class_name}" if prefix
|
98
|
+
|
99
|
+
(class << self; self; end).module_eval do
|
100
|
+
define_method "create_#{class_name}" do |*args|
|
101
|
+
attributes = args.first || {}
|
102
|
+
create_instance(class_type, attributes, defaults)
|
103
|
+
end
|
104
|
+
|
105
|
+
define_method "new_#{class_name}" do |*args|
|
106
|
+
attributes = args.first || {}
|
107
|
+
new_instance(class_type, attributes, defaults)
|
108
|
+
end
|
109
|
+
|
110
|
+
define_method "default_#{class_name}" do |*args|
|
111
|
+
attributes = args.first || {}
|
112
|
+
default_closure(class_type, attributes, defaults)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def create_instance(class_type, attributes, defaults = {}) # :nodoc:
|
118
|
+
attributes = instantiate_defaults(:create, defaults.merge(attributes))
|
119
|
+
instance = class_type.create!(attributes)
|
120
|
+
if update_protected_attributes(instance, attributes)
|
121
|
+
instance.save
|
122
|
+
end
|
123
|
+
instance
|
124
|
+
end
|
125
|
+
|
126
|
+
def new_instance(class_type, attributes, defaults = {}) # :nodoc:
|
127
|
+
attributes = instantiate_defaults(:new, defaults.merge(attributes))
|
128
|
+
instance = class_type.new(attributes)
|
129
|
+
instance.id = next_local_id
|
130
|
+
update_protected_attributes(instance, attributes)
|
131
|
+
instance
|
132
|
+
end
|
133
|
+
|
134
|
+
def default_closure(class_type, attributes, defaults = {}) # :nodoc:
|
135
|
+
lambda do |create_or_new|
|
136
|
+
case create_or_new
|
137
|
+
when :new ; new_instance(class_type, attributes, defaults)
|
138
|
+
when :create ; create_instance(class_type, attributes, defaults)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def instantiate_defaults(create_or_new, attributes) # :nodoc:
|
144
|
+
attributes.each do |key, value|
|
145
|
+
if value.is_a?(Proc)
|
146
|
+
attributes[key] = value.arity == 0 ? value.call : value.call(create_or_new)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
attributes
|
150
|
+
end
|
151
|
+
|
152
|
+
def update_protected_attributes(instance, attributes) # :nodoc:
|
153
|
+
modified = false
|
154
|
+
protected_attrs = instance.class.protected_attributes
|
155
|
+
protected_attrs = protected_attrs.to_set if protected_attrs
|
156
|
+
accessible_attrs = instance.class.accessible_attributes
|
157
|
+
accessible_attrs = accessible_attrs.to_set if accessible_attrs
|
158
|
+
|
159
|
+
if protected_attrs or accessible_attrs
|
160
|
+
attributes.each do |key, value|
|
161
|
+
# Support symbols and strings.
|
162
|
+
next if protected_attrs and (not protected_attrs.include?(key) or protected_attrs.include?(key.to_s))
|
163
|
+
next if accessible_attrs and (accessible_attrs.include?(key) or accessible_attrs.include?(key.to_s))
|
164
|
+
modified = true
|
165
|
+
instance.send("#{key}=", value)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
return modified
|
169
|
+
end
|
170
|
+
|
171
|
+
# Any class methods of the form "new_some_type(attrs)" or "create_some_type(attrs)" will be converted to
|
172
|
+
# "SomeType.new(attrs)" and "SomeType.create!(attrs)" respectively.
|
173
|
+
# These basically function as though you'd used the 'default' directive with empty defaults.
|
174
|
+
def method_missing(missing_method, attributes = {})
|
175
|
+
if missing_method.to_s.match(/^(new|create|default)_([a-z][\w_]+)$/)
|
176
|
+
method, class_name = $1, $2
|
177
|
+
class_type = class_name.camelize.constantize
|
178
|
+
case method
|
179
|
+
when 'create'
|
180
|
+
create_instance(class_type, attributes)
|
181
|
+
when 'new'
|
182
|
+
new_instance(class_type, attributes)
|
183
|
+
when 'default'
|
184
|
+
default_closure(class_type, attributes)
|
185
|
+
end
|
186
|
+
else
|
187
|
+
raise NoMethodError, "no such method '#{missing_method}'"
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
require File.dirname(__FILE__) + '/../lib/model_factory'
|
3
|
+
|
4
|
+
# The classes below are rough mocks of ActiveRecord::Base that only handle instantiation.
|
5
|
+
|
6
|
+
# This class has defaults defined.
|
7
|
+
class ModelFactoryTestDef
|
8
|
+
def self.protected_attributes; nil; end
|
9
|
+
def self.accessible_attributes; nil; end
|
10
|
+
|
11
|
+
attr_accessor :id, :nest, :bar, :baz
|
12
|
+
def initialize(opts = {})
|
13
|
+
opts.each do |k,v|
|
14
|
+
self.send("#{k}=", v)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# This class has no defaults defined.
|
20
|
+
class ModelFactoryTestNoDef < ModelFactoryTestDef; end
|
21
|
+
|
22
|
+
# This class has nested defaults defined.
|
23
|
+
class ModelFactoryTestNestDef < ModelFactoryTestDef; end
|
24
|
+
|
25
|
+
# This class has protected attributes.
|
26
|
+
class ModelFactoryTestProtected < ModelFactoryTestDef
|
27
|
+
def self.protected_attributes; [:baz]; end
|
28
|
+
|
29
|
+
def initialize(opts = {})
|
30
|
+
opts = opts.clone
|
31
|
+
opts.delete(:baz) # Simulate a protected attribute.
|
32
|
+
super(opts)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# This class has accessible attributes.
|
37
|
+
class ModelFactoryTestAccessible < ModelFactoryTestDef
|
38
|
+
def self.accessible_attributes; [:id, :nest, 'bar']; end
|
39
|
+
|
40
|
+
def initialize(opts = {})
|
41
|
+
opts = opts.clone
|
42
|
+
opts.delete(:baz) # Simulate a protected attribute.
|
43
|
+
super(opts)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# This is the testfactory class def with test defaults.
|
48
|
+
class ModelFactoryTestFactory
|
49
|
+
extend ModelFactory
|
50
|
+
default ModelFactoryTestDef, { :bar => 'baz' }
|
51
|
+
default ModelFactoryTestNestDef, { :nest => default_model_factory_test_def }
|
52
|
+
end
|
53
|
+
|
54
|
+
class ModelFactoryTest < Test::Unit::TestCase
|
55
|
+
context "legacy api compatibility" do
|
56
|
+
should "initialize protected attributes" do
|
57
|
+
m = ModelFactoryTestFactory.new_model_factory_test_protected(:baz => 4)
|
58
|
+
assert_equal 4, m.baz
|
59
|
+
end
|
60
|
+
|
61
|
+
should "initialize dynamic protected attributes" do
|
62
|
+
i = 1
|
63
|
+
m = ModelFactoryTestFactory.new_model_factory_test_protected(:bar => 3, :baz => lambda { i += 1 } )
|
64
|
+
assert_equal 2, m.baz
|
65
|
+
end
|
66
|
+
|
67
|
+
should "initialize accessible attributes" do
|
68
|
+
m = ModelFactoryTestFactory.new_model_factory_test_accessible(:baz => 4)
|
69
|
+
assert_equal 4, m.baz
|
70
|
+
end
|
71
|
+
|
72
|
+
should "initialize dynamic accessible attributes" do
|
73
|
+
i = 1
|
74
|
+
m = ModelFactoryTestFactory.new_model_factory_test_accessible(:bar => 3, :baz => lambda { i += 1 } )
|
75
|
+
assert_equal 2, m.baz
|
76
|
+
end
|
77
|
+
|
78
|
+
should "initialize with no arguments and nested defaults" do
|
79
|
+
m = ModelFactoryTestFactory.new_model_factory_test_nest_def
|
80
|
+
assert m.nest.id > 0
|
81
|
+
assert m.id > 0
|
82
|
+
end
|
83
|
+
|
84
|
+
should "intialize with arguments and nested defaults" do
|
85
|
+
m = ModelFactoryTestFactory.new_model_factory_test_nest_def(:bar => 'foo')
|
86
|
+
assert_equal 'foo', m.bar
|
87
|
+
assert m.nest.id > 0
|
88
|
+
assert m.id > 0
|
89
|
+
end
|
90
|
+
|
91
|
+
should "intialize with no arguments and explicit defaults" do
|
92
|
+
m = ModelFactoryTestFactory.new_model_factory_test_def
|
93
|
+
assert_equal 'baz', m.bar
|
94
|
+
assert m.id > 0
|
95
|
+
end
|
96
|
+
|
97
|
+
should "intialize with arguments and explicit defaults" do
|
98
|
+
m = ModelFactoryTestFactory.new_model_factory_test_def(:bar => 'foo')
|
99
|
+
assert_equal 'foo', m.bar
|
100
|
+
assert m.id > 0
|
101
|
+
end
|
102
|
+
|
103
|
+
should "create with arguments and explicit defaults" do
|
104
|
+
instance = ModelFactoryTestDef.new
|
105
|
+
ModelFactoryTestDef.expects(:create!).with(:bar => 'foo').returns(instance)
|
106
|
+
ModelFactoryTestFactory.create_model_factory_test_def(:bar => 'foo')
|
107
|
+
end
|
108
|
+
|
109
|
+
should "create with no arguments and explicit defaults" do
|
110
|
+
instance = ModelFactoryTestDef.new
|
111
|
+
ModelFactoryTestDef.expects(:create!).with(:bar => 'baz').returns(instance)
|
112
|
+
ModelFactoryTestFactory.create_model_factory_test_def
|
113
|
+
end
|
114
|
+
|
115
|
+
should "initialize with no arguments and no defaults" do
|
116
|
+
instance = ModelFactoryTestNoDef.new
|
117
|
+
ModelFactoryTestNoDef.expects(:new).returns(instance)
|
118
|
+
m = ModelFactoryTestFactory.new_model_factory_test_no_def
|
119
|
+
assert m.id > 0
|
120
|
+
end
|
121
|
+
|
122
|
+
should "initialize with arguments and no defaults" do
|
123
|
+
instance = ModelFactoryTestNoDef.new
|
124
|
+
ModelFactoryTestNoDef.expects(:new).with(:bar => 'foo').returns(instance)
|
125
|
+
m = ModelFactoryTestFactory.new_model_factory_test_no_def(:bar => 'foo')
|
126
|
+
assert m.id > 0
|
127
|
+
end
|
128
|
+
|
129
|
+
should "create with no arguments and no defaults" do
|
130
|
+
instance = ModelFactoryTestNoDef.new
|
131
|
+
ModelFactoryTestNoDef.expects(:create!).returns(instance)
|
132
|
+
ModelFactoryTestFactory.create_model_factory_test_no_def
|
133
|
+
end
|
134
|
+
|
135
|
+
should "create with arguments and no defaults" do
|
136
|
+
instance = ModelFactoryTestNoDef.new
|
137
|
+
ModelFactoryTestNoDef.expects(:create!).with(:bar => 'foo').returns(instance)
|
138
|
+
ModelFactoryTestFactory.create_model_factory_test_no_def(:bar => 'foo')
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
data/test/model_factory_test.rb
CHANGED
@@ -1,139 +1,86 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
require File.dirname(__FILE__) + '/../lib/modelfactory'
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
# This class has defaults defined.
|
6
|
-
class ModelFactoryTestDef
|
7
|
-
def self.protected_attributes; nil; end
|
8
|
-
def self.accessible_attributes; nil; end
|
9
|
-
|
10
|
-
attr_accessor :id, :nest, :bar, :baz
|
11
|
-
def initialize(opts = {})
|
12
|
-
opts.each do |k,v|
|
13
|
-
self.send("#{k}=", v)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
# This class has no defaults defined.
|
19
|
-
class ModelFactoryTestNoDef < ModelFactoryTestDef; end
|
20
|
-
|
21
|
-
# This class has nested defaults defined.
|
22
|
-
class ModelFactoryTestNestDef < ModelFactoryTestDef; end
|
23
|
-
|
24
|
-
# This class has protected attributes.
|
25
|
-
class ModelFactoryTestProtected < ModelFactoryTestDef
|
26
|
-
def self.protected_attributes; [:baz]; end
|
4
|
+
class ModelFactoryTest < Test::Unit::TestCase
|
27
5
|
|
28
|
-
|
29
|
-
|
30
|
-
opts.delete(:baz) # Simulate a protected attribute.
|
31
|
-
super(opts)
|
6
|
+
should "not instantiate when using new" do
|
7
|
+
assert Widget.factory.new.new_record?
|
32
8
|
end
|
33
|
-
end
|
34
|
-
|
35
|
-
# This class has accessible attributes.
|
36
|
-
class ModelFactoryTestAccessible < ModelFactoryTestDef
|
37
|
-
def self.accessible_attributes; [:id, :nest, 'bar']; end
|
38
9
|
|
39
|
-
|
40
|
-
|
41
|
-
opts.delete(:baz) # Simulate a protected attribute.
|
42
|
-
super(opts)
|
10
|
+
should "instantiate when using create" do
|
11
|
+
assert !Widget.factory.create.new_record?
|
43
12
|
end
|
44
|
-
end
|
45
|
-
|
46
|
-
# This is the testfactory class def with test defaults.
|
47
|
-
class ModelFactoryTestFactory
|
48
|
-
extend ModelFactory
|
49
|
-
default ModelFactoryTestDef, { :bar => 'baz' }
|
50
|
-
default ModelFactoryTestNestDef, { :nest => default_model_factory_test_def }
|
51
|
-
end
|
52
13
|
|
53
|
-
|
54
|
-
|
55
|
-
m = ModelFactoryTestFactory.new_model_factory_test_protected(:baz => 4)
|
56
|
-
assert_equal 4, m.baz
|
14
|
+
should "raise on creation of invalid records" do
|
15
|
+
assert_raises(ActiveRecord::RecordInvalid) { StrictWidget.factory.create }
|
57
16
|
end
|
58
17
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
test "accessible attributes" do
|
66
|
-
m = ModelFactoryTestFactory.new_model_factory_test_accessible(:baz => 4)
|
67
|
-
assert_equal 4, m.baz
|
68
|
-
end
|
18
|
+
context "with a specified default that uses automatic numbering" do
|
19
|
+
setup do
|
20
|
+
ModelFactory.configure do
|
21
|
+
default(Widget) {|w, i| w.price = i }
|
22
|
+
end
|
23
|
+
end
|
69
24
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
assert_equal 2, m.baz
|
74
|
-
end
|
75
|
-
|
76
|
-
test "new with no arguments and nested defaults" do
|
77
|
-
m = ModelFactoryTestFactory.new_model_factory_test_nest_def
|
78
|
-
assert m.nest.id > 0
|
79
|
-
assert m.id > 0
|
80
|
-
end
|
81
|
-
|
82
|
-
test "new with arguments and nested defaults" do
|
83
|
-
m = ModelFactoryTestFactory.new_model_factory_test_nest_def(:bar => 'foo')
|
84
|
-
assert_equal 'foo', m.bar
|
85
|
-
assert m.nest.id > 0
|
86
|
-
assert m.id > 0
|
87
|
-
end
|
88
|
-
|
89
|
-
test "new with no arguments and explicit defaults" do
|
90
|
-
m = ModelFactoryTestFactory.new_model_factory_test_def
|
91
|
-
assert_equal 'baz', m.bar
|
92
|
-
assert m.id > 0
|
93
|
-
end
|
94
|
-
|
95
|
-
test "new with arguments and explicit defaults" do
|
96
|
-
m = ModelFactoryTestFactory.new_model_factory_test_def(:bar => 'foo')
|
97
|
-
assert_equal 'foo', m.bar
|
98
|
-
assert m.id > 0
|
99
|
-
end
|
100
|
-
|
101
|
-
test "create with arguments and explicit defaults" do
|
102
|
-
instance = ModelFactoryTestDef.new
|
103
|
-
ModelFactoryTestDef.expects(:create!).with(:bar => 'foo').returns(instance)
|
104
|
-
ModelFactoryTestFactory.create_model_factory_test_def(:bar => 'foo')
|
105
|
-
end
|
106
|
-
|
107
|
-
test "create with no arguments and explicit defaults" do
|
108
|
-
instance = ModelFactoryTestDef.new
|
109
|
-
ModelFactoryTestDef.expects(:create!).with(:bar => 'baz').returns(instance)
|
110
|
-
ModelFactoryTestFactory.create_model_factory_test_def
|
111
|
-
end
|
112
|
-
|
113
|
-
test "new with no arguments and no defaults" do
|
114
|
-
instance = ModelFactoryTestNoDef.new
|
115
|
-
ModelFactoryTestNoDef.expects(:new).returns(instance)
|
116
|
-
m = ModelFactoryTestFactory.new_model_factory_test_no_def
|
117
|
-
assert m.id > 0
|
118
|
-
end
|
25
|
+
should "start counting at 1 after configuration" do
|
26
|
+
assert_equal 1.0, Widget.factory.create.price
|
27
|
+
end
|
119
28
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
29
|
+
should "generate a unique sequence" do
|
30
|
+
w = []
|
31
|
+
3.times { w << Widget.factory.create.price }
|
32
|
+
assert_equal w.uniq, w
|
33
|
+
end
|
125
34
|
end
|
126
35
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
36
|
+
context "with a specified default" do
|
37
|
+
setup do
|
38
|
+
ModelFactory.configure do
|
39
|
+
default(Widget) {|w| w.name = 'foobaz' }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
should "initialize defaults with no arguments" do
|
44
|
+
assert_equal 'foobaz', Widget.factory.create.name
|
45
|
+
end
|
46
|
+
|
47
|
+
should "initialize defaults with an unspecified argument" do
|
48
|
+
assert_equal 'foobaz', Widget.factory.create(:price => 4.0).name
|
49
|
+
end
|
50
|
+
|
51
|
+
should "initialize with an unspecified argument" do
|
52
|
+
assert_equal 4, Widget.factory.create(:price => 4.0).price
|
53
|
+
end
|
131
54
|
end
|
132
55
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
56
|
+
context "with a named factory" do
|
57
|
+
setup do
|
58
|
+
ModelFactory.configure do
|
59
|
+
default(Widget) {|w| w.name = 'wubbo' }
|
60
|
+
favorite(Widget) {|w| w.name = 'foobaz' }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
should "not apply named config to default" do
|
65
|
+
assert_equal 'wubbo', Widget.factory.create.name
|
66
|
+
end
|
67
|
+
|
68
|
+
should "not apply any config to unrecognized name" do
|
69
|
+
assert_equal nil, Widget.factory.create_emptyfoo.name
|
70
|
+
end
|
71
|
+
|
72
|
+
should "initialize defaults with no arguments" do
|
73
|
+
assert_equal 'foobaz', Widget.factory.create_favorite.name
|
74
|
+
end
|
75
|
+
|
76
|
+
should "initialize defaults with an unspecified argument" do
|
77
|
+
assert_equal 'foobaz', Widget.factory.create_favorite(:price => 4.0).name
|
78
|
+
end
|
79
|
+
|
80
|
+
should "initialize with an unspecified argument" do
|
81
|
+
assert_equal 4, Widget.factory.create_favorite(:price => 4.0).price
|
82
|
+
end
|
137
83
|
end
|
138
84
|
end
|
139
85
|
|
86
|
+
|
data/test/test_helper.rb
CHANGED
@@ -1,12 +1,22 @@
|
|
1
1
|
require 'test/unit'
|
2
2
|
require 'rubygems'
|
3
3
|
require 'mocha'
|
4
|
-
require
|
4
|
+
require 'shoulda'
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
6
|
+
require 'active_record'
|
7
|
+
ActiveRecord::Base.establish_connection(
|
8
|
+
:database => ':memory:',
|
9
|
+
:adapter => 'sqlite3',
|
10
|
+
:timeout => 500
|
11
|
+
)
|
12
|
+
|
13
|
+
require 'active_record/fixtures'
|
14
|
+
require 'test/fixtures/schema.rb'
|
15
|
+
class Test::Unit::TestCase
|
16
|
+
FIXTURES_PATH = File.join(File.dirname(__FILE__), '/fixtures')
|
17
|
+
dep = defined?(ActiveSupport::Dependencies) ?
|
18
|
+
ActiveSupport::Dependencies :
|
19
|
+
::Dependencies
|
20
|
+
dep.load_paths.unshift FIXTURES_PATH
|
12
21
|
end
|
22
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: modelfactory
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justin Balthrop
|
@@ -10,9 +10,49 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2009-05-
|
13
|
+
date: 2009-05-19 00:00:00 -07:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: active_record
|
18
|
+
type: :development
|
19
|
+
version_requirement:
|
20
|
+
version_requirements: !ruby/object:Gem::Requirement
|
21
|
+
requirements:
|
22
|
+
- - ">="
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: "0"
|
25
|
+
version:
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: mocha
|
28
|
+
type: :development
|
29
|
+
version_requirement:
|
30
|
+
version_requirements: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: "0"
|
35
|
+
version:
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: thoughtbot-shoulda
|
38
|
+
type: :development
|
39
|
+
version_requirement:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: "0"
|
45
|
+
version:
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: sqlite3-ruby
|
48
|
+
type: :development
|
49
|
+
version_requirement:
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: "0"
|
55
|
+
version:
|
16
56
|
- !ruby/object:Gem::Dependency
|
17
57
|
name: hoe
|
18
58
|
type: :development
|
@@ -42,12 +82,19 @@ files:
|
|
42
82
|
- Rakefile
|
43
83
|
- lib/fixture_converter.rb
|
44
84
|
- lib/model_factory.rb
|
45
|
-
- lib/
|
85
|
+
- lib/modelfactory.rb
|
86
|
+
- lib/modelfactory/factory.rb
|
87
|
+
- lib/modelfactory/legacy.rb
|
88
|
+
- lib/modelfactory/version.rb
|
46
89
|
- script/destroy
|
47
90
|
- script/fixtures2factories
|
48
91
|
- script/generate
|
49
92
|
- script/txt2html
|
50
93
|
- setup.rb
|
94
|
+
- test/fixtures/schema.rb
|
95
|
+
- test/fixtures/strict_widget.rb
|
96
|
+
- test/fixtures/widget.rb
|
97
|
+
- test/model_factory_legacy_test.rb
|
51
98
|
- test/model_factory_test.rb
|
52
99
|
- test/test_helper.rb
|
53
100
|
has_rdoc: true
|
@@ -79,3 +126,4 @@ specification_version: 2
|
|
79
126
|
summary: A replacement for fixtures.
|
80
127
|
test_files:
|
81
128
|
- test/model_factory_test.rb
|
129
|
+
- test/model_factory_legacy_test.rb
|