factory_grabber 1.0.3
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/CHANGELOG +14 -0
- data/Manifest +14 -0
- data/README.md +159 -0
- data/Rakefile +14 -0
- data/factory_grabber.gemspec +30 -0
- data/init.rb +1 -0
- data/lib/dbfile +0 -0
- data/lib/factory_grabber.rb +176 -0
- data/lib/spec/database_setup.rb +9 -0
- data/lib/spec/dbfile +0 -0
- data/lib/spec/factories.rb +9 -0
- data/lib/spec/grab_spec.rb +170 -0
- data/lib/spec/performance_test.rb +22 -0
- data/lib/spec/spec_helper.rb +7 -0
- data/lib/spec/user.rb +4 -0
- metadata +84 -0
data/CHANGELOG
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
|
2
|
+
Version 1.0.3
|
3
|
+
- Added support for virtual attributes
|
4
|
+
|
5
|
+
Version 1.0.1
|
6
|
+
- Re-wrote README as Markdown
|
7
|
+
|
8
|
+
Version 1.0.1 released Tuesday 15th September [Gavin Morrice]
|
9
|
+
- Removed the NumberMethods. Instead of dynamically creating a method for each number, ghost methods are 'created' using method_missing.
|
10
|
+
- Updated README
|
11
|
+
- Updated Rdoc
|
12
|
+
- Added support for 'a' and 'an': Grab.an_author
|
13
|
+
|
14
|
+
Version 1.0.0 released Sunday 13th September [Gavin Morrice]
|
data/Manifest
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
CHANGELOG
|
2
|
+
Manifest
|
3
|
+
README.md
|
4
|
+
Rakefile
|
5
|
+
init.rb
|
6
|
+
lib/dbfile
|
7
|
+
lib/factory_grabber.rb
|
8
|
+
lib/spec/database_setup.rb
|
9
|
+
lib/spec/dbfile
|
10
|
+
lib/spec/factories.rb
|
11
|
+
lib/spec/grab_spec.rb
|
12
|
+
lib/spec/performance_test.rb
|
13
|
+
lib/spec/spec_helper.rb
|
14
|
+
lib/spec/user.rb
|
data/README.md
ADDED
@@ -0,0 +1,159 @@
|
|
1
|
+
Factory Grabber
|
2
|
+
==============
|
3
|
+
|
4
|
+
Factory grabber speeds up your tests by grabbing the nearest appropriate database records to suit your needs.
|
5
|
+
|
6
|
+
The idea is simple: most of the time, when using factories, you don't really care about the specific attributes, you just need a database record to play with. factory_grabber will _'grab'_ a matching record from the database if available or create any extra records if required. Less inserts to the database means faster tests.
|
7
|
+
|
8
|
+
At the moment, only "factory_girl":http://github.com/thoughtbot/factory_girl by thoughtbot is supported. If you'd like to see more factories supported please let me know (gavin@handyrailstips.com)
|
9
|
+
|
10
|
+
To install:
|
11
|
+
===========
|
12
|
+
|
13
|
+
|
14
|
+
As a gem:
|
15
|
+
---------
|
16
|
+
|
17
|
+
sudo gem install git://github.com/GavinM/factory_grabber.git
|
18
|
+
|
19
|
+
# environment.rb
|
20
|
+
config.gem "thoughtbot-factory_girl", :lib => "factory_girl"
|
21
|
+
config.gem "factory_grbber", :version => ">=1.0.2", :lib => false
|
22
|
+
|
23
|
+
As a plugin:
|
24
|
+
------------
|
25
|
+
script/plugin install git://github.com/GavinM/factory_grabber.git
|
26
|
+
|
27
|
+
|
28
|
+
Important:
|
29
|
+
----------
|
30
|
+
|
31
|
+
To benefit from this gem, set use_transactional_fixtures=() to false in *spec_helper.rb*
|
32
|
+
|
33
|
+
Spec::Runner.configure do |config|
|
34
|
+
config.use_transactional_fixtures = false
|
35
|
+
config.use_instantiated_fixtures = false
|
36
|
+
config.fixture_path = RAILS_ROOT + '/spec/fixtures/'
|
37
|
+
end
|
38
|
+
|
39
|
+
Example Usage
|
40
|
+
=============
|
41
|
+
|
42
|
+
First, add the following line to *spec_helper.rb* or *test_helper.rb*:
|
43
|
+
|
44
|
+
require "factory_grabber"
|
45
|
+
|
46
|
+
Then, in your tests/specs:
|
47
|
+
|
48
|
+
# to grab 1 comment:
|
49
|
+
@comment = Grab.a_comment
|
50
|
+
|
51
|
+
# to grab 1 article:
|
52
|
+
@article = Grab.an_article
|
53
|
+
|
54
|
+
#to grab 4 users named "John Smith":
|
55
|
+
@users = Grab.four_users(:first_name => "John", :last_name => "Smith")
|
56
|
+
|
57
|
+
#to grab 73 users with standard factory attributes:
|
58
|
+
@users = Grab.seventy_three_users
|
59
|
+
|
60
|
+
Practical examples:
|
61
|
+
===================
|
62
|
+
|
63
|
+
In a controller spec...
|
64
|
+
describe "GET /posts/1" do
|
65
|
+
|
66
|
+
integrate_views
|
67
|
+
|
68
|
+
before do
|
69
|
+
# will create a record with these attributes if required, if not it will find the existing record
|
70
|
+
@post = Grab.one_post :title => "This is my first post", :body => "This is the post body"
|
71
|
+
end
|
72
|
+
|
73
|
+
def do_get
|
74
|
+
get :show, :id => @post
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should show the post title" do
|
78
|
+
do_get
|
79
|
+
response.should include_text(/This is my first post/)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should show the post body" do
|
83
|
+
do_get
|
84
|
+
response.should include_text(/This is the post body/)
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
describe "GET /posts?page=1" do
|
91
|
+
|
92
|
+
# testing pagination
|
93
|
+
|
94
|
+
integrate_views
|
95
|
+
|
96
|
+
before do
|
97
|
+
# ensures there are at least eleven Post records
|
98
|
+
# if there are less than eleven, new posts are created
|
99
|
+
# if there are eleven or more no posts are created
|
100
|
+
Grab.eleven_posts
|
101
|
+
end
|
102
|
+
|
103
|
+
def do_get
|
104
|
+
get :index, :page => 1
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should find the latest 10 posts" do
|
108
|
+
do_get
|
109
|
+
assigns[:posts].should == Post.find(:all, :order => "created_at DESC", :limit => 10)
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
|
114
|
+
At the moment, all numbers between one and ninety_nine are supported. The general syntax for Grab methods is:
|
115
|
+
|
116
|
+
Grab.[number_in_words]_[factory_name]
|
117
|
+
|
118
|
+
Performance gains
|
119
|
+
==================
|
120
|
+
|
121
|
+
Here's a quick example of the possible performance gains:
|
122
|
+
<pre>
|
123
|
+
Rehearsal --------------------------------------------------------------
|
124
|
+
Create 50 new factories 0.130000 0.200000 0.330000 ( 6.785332)
|
125
|
+
Grab 50 separate factories 0.320000 0.020000 0.340000 ( 0.332814)
|
126
|
+
Grab 50 factories at once 0.010000 0.000000 0.010000 ( 0.012414)
|
127
|
+
----------------------------------------------------- total: 0.680000sec
|
128
|
+
|
129
|
+
user system total real
|
130
|
+
Create 50 new factories 0.100000 0.200000 0.300000 ( 6.354282)
|
131
|
+
Grab 50 separate factories 0.300000 0.000000 0.300000 ( 0.310373)
|
132
|
+
Grab 50 factories at once 0.020000 0.000000 0.020000 ( 0.011400)
|
133
|
+
</pre>
|
134
|
+
|
135
|
+
(These results can be produced for your own environment by running the file "performance_test.rb" in factory_grabber/lib/spec/performance_test.rb)
|
136
|
+
|
137
|
+
Known Issues
|
138
|
+
============
|
139
|
+
|
140
|
+
At the moment, existing factories are found calling the model name. If your factory names do not match the name of the models then new factories will be created each time.
|
141
|
+
eg.
|
142
|
+
|
143
|
+
Factory(:admin_user, :class => :user) do |f|
|
144
|
+
f.username("admin_user")
|
145
|
+
f.admin(true)
|
146
|
+
# ... etc ...
|
147
|
+
end
|
148
|
+
|
149
|
+
Grab.an_admin_user # => will not find records from the database.
|
150
|
+
|
151
|
+
Feedback
|
152
|
+
========
|
153
|
+
|
154
|
+
This project is still an infant - if the Ruby community find it useful I plan on adding a lot more. Please send any ideas/feedback to gavin@handyrailstips.com
|
155
|
+
|
156
|
+
|
157
|
+
Free to upload, edit, share, fork etc.<br />
|
158
|
+
[Gavin Morrice](http://gavinmorrice.com)<br />
|
159
|
+
[www.handyrailstips.com](:http://handyrailstips.com/tips/20)
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "rake"
|
3
|
+
require "echoe"
|
4
|
+
|
5
|
+
Echoe.new("factory_grabber", "1.0.3") do |p|
|
6
|
+
p.description = "Grab or create factories for faster Functional/Integration testing"
|
7
|
+
p.url = "http://github.com/gavinM/factory_grabber"
|
8
|
+
p.author = "Gavin Morrice"
|
9
|
+
p.email = "gavin@handyrailstips.com"
|
10
|
+
p.ignore_pattern = ["tmp/*", "script/*", "dbfile"]
|
11
|
+
p.development_dependencies = []
|
12
|
+
end
|
13
|
+
|
14
|
+
Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{factory_grabber}
|
5
|
+
s.version = "1.0.3"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Gavin Morrice"]
|
9
|
+
s.date = %q{2009-09-17}
|
10
|
+
s.description = %q{Grab or create factories for faster Functional/Integration testing}
|
11
|
+
s.email = %q{gavin@handyrailstips.com}
|
12
|
+
s.extra_rdoc_files = ["CHANGELOG", "README.md", "lib/dbfile", "lib/factory_grabber.rb", "lib/spec/database_setup.rb", "lib/spec/dbfile", "lib/spec/factories.rb", "lib/spec/grab_spec.rb", "lib/spec/performance_test.rb", "lib/spec/spec_helper.rb", "lib/spec/user.rb"]
|
13
|
+
s.files = ["CHANGELOG", "Manifest", "README.md", "Rakefile", "init.rb", "lib/dbfile", "lib/factory_grabber.rb", "lib/spec/database_setup.rb", "lib/spec/dbfile", "lib/spec/factories.rb", "lib/spec/grab_spec.rb", "lib/spec/performance_test.rb", "lib/spec/spec_helper.rb", "lib/spec/user.rb", "factory_grabber.gemspec"]
|
14
|
+
s.homepage = %q{http://github.com/gavinM/factory_grabber}
|
15
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Factory_grabber", "--main", "README.md"]
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
s.rubyforge_project = %q{factory_grabber}
|
18
|
+
s.rubygems_version = %q{1.3.5}
|
19
|
+
s.summary = %q{Grab or create factories for faster Functional/Integration testing}
|
20
|
+
|
21
|
+
if s.respond_to? :specification_version then
|
22
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
23
|
+
s.specification_version = 3
|
24
|
+
|
25
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
26
|
+
else
|
27
|
+
end
|
28
|
+
else
|
29
|
+
end
|
30
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "factory_grabber"
|
data/lib/dbfile
ADDED
Binary file
|
@@ -0,0 +1,176 @@
|
|
1
|
+
# load active support if not in Rails
|
2
|
+
require "activesupport" unless defined?(ActiveSupport::Inflector)
|
3
|
+
require "factory_girl"
|
4
|
+
module FactoryGrabber
|
5
|
+
|
6
|
+
class NotANumberError < NoMethodError;end
|
7
|
+
|
8
|
+
module Grab
|
9
|
+
|
10
|
+
# numbers 1 to 9
|
11
|
+
UNITS = {
|
12
|
+
"one" => 1,
|
13
|
+
"two" => 2,
|
14
|
+
"three" => 3,
|
15
|
+
"four" => 4,
|
16
|
+
"five" => 5,
|
17
|
+
"six" => 6,
|
18
|
+
"seven" => 7,
|
19
|
+
"eight" => 8,
|
20
|
+
"nine" => 9}
|
21
|
+
|
22
|
+
# numbers 10 to 19
|
23
|
+
TEENS = {
|
24
|
+
"ten" => 10,
|
25
|
+
"eleven" => 11,
|
26
|
+
"twelve" => 12,
|
27
|
+
"thirteen" => 13,
|
28
|
+
"fourteen" => 14,
|
29
|
+
"fifteen" => 15,
|
30
|
+
"sixteen" => 16,
|
31
|
+
"seventeen" => 17,
|
32
|
+
"eighteen" => 18,
|
33
|
+
"nineteen" => 19}
|
34
|
+
|
35
|
+
# tens from 20 to 90
|
36
|
+
TENS = {
|
37
|
+
"twenty" => 20,
|
38
|
+
"thirty" => 30,
|
39
|
+
"forty" => 40,
|
40
|
+
"fifty" => 50,
|
41
|
+
"sixty" => 60,
|
42
|
+
"seventy" => 70,
|
43
|
+
"eighty" => 80,
|
44
|
+
"ninety" => 90}
|
45
|
+
|
46
|
+
# define an empty hash
|
47
|
+
ALL_NUMBERS = {}
|
48
|
+
|
49
|
+
# add each number between 1 and 19 to ALL_NUMBERS
|
50
|
+
UNITS.merge(TEENS).each { |name, value| ALL_NUMBERS[name] = value }
|
51
|
+
|
52
|
+
TENS.each do |name, value|
|
53
|
+
# add each ten from 20 to 90 to ALL_NUMBERS
|
54
|
+
ALL_NUMBERS[name] = value
|
55
|
+
# add each remaining number to ALL_NUMBERS
|
56
|
+
UNITS.each { |unit_name, unit_value| ALL_NUMBERS["#{name}_#{unit_name}"] = value + unit_value }
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
# remove unnecessary methods from Grab class
|
61
|
+
instance_methods.each do |m|
|
62
|
+
undef_method m unless m.to_s =~ /method_missing|respond_to?|^__/
|
63
|
+
end
|
64
|
+
|
65
|
+
# add singleton class methods
|
66
|
+
class << self
|
67
|
+
|
68
|
+
# methods called to Grab are not really methods, they're ghost methods.
|
69
|
+
# If method_missing cannot identify the number and the factory to be created it will pass
|
70
|
+
# this up the chain to Object. @name is the method name called (symbol) and options is the hash of
|
71
|
+
# options passed to the method.
|
72
|
+
def method_missing(name, options = {})
|
73
|
+
@options = options
|
74
|
+
@parts_in_name = name.to_s.split("_")
|
75
|
+
|
76
|
+
# replace 'a' or 'an' with 'one'
|
77
|
+
if @parts_in_name.first == "a" || @parts_in_name.first == "an"
|
78
|
+
@parts_in_name.delete_at(0)
|
79
|
+
@parts_in_name.unshift("one")
|
80
|
+
end
|
81
|
+
# rejoins the name with 'a' and 'an' replaced with 'one'
|
82
|
+
@name = @parts_in_name.join("_")
|
83
|
+
|
84
|
+
# check the options if there are any
|
85
|
+
unless @options.empty?
|
86
|
+
check_options_against_database
|
87
|
+
end
|
88
|
+
|
89
|
+
# results to be returned
|
90
|
+
@results = []
|
91
|
+
|
92
|
+
if @should_create_new
|
93
|
+
number.times { @results << create_factory }
|
94
|
+
else
|
95
|
+
# create new records if there is not a sufficient amount in the database
|
96
|
+
required_records ? required_records.times { create_factory } : nil
|
97
|
+
|
98
|
+
# find and return the desired records
|
99
|
+
@results = klass_name_constant.all(:conditions => @options, :limit => number)
|
100
|
+
end
|
101
|
+
# return a single record if only one exists
|
102
|
+
@results.size == 1 ? @results.first : @results
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
# checks the database columns to ensure options are all database columns
|
108
|
+
# if they are not (in the case of virtual attributes) a new factory should be created
|
109
|
+
def check_options_against_database
|
110
|
+
# extract the keys from the options hash as strings
|
111
|
+
option_keys = @options.stringify_keys.keys
|
112
|
+
# fetch the names of the Class's database table columns
|
113
|
+
klass_columns = klass_name_constant.columns.collect { |c| c.name }
|
114
|
+
# @should create new will be true if there are any option keys that are not in db table
|
115
|
+
@should_create_new = !!option_keys.detect { |opt| !klass_columns.include?(opt) }
|
116
|
+
end
|
117
|
+
|
118
|
+
# returns the number part of the method name eg. nineteen
|
119
|
+
def number_name
|
120
|
+
@number_name = if UNITS.include?(@parts_in_name.first) || TEENS.include?(@parts_in_name.first)
|
121
|
+
@parts_in_name.first
|
122
|
+
elsif TENS.include?(@parts_in_name.first)
|
123
|
+
UNITS.include?(@parts_in_name[1]) ? @parts_in_name[0..1].join("_") : @parts_in_name.first
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# returns the number as an integer
|
128
|
+
def number
|
129
|
+
@number = ALL_NUMBERS[number_name]
|
130
|
+
raise NotANumberError, "#{@name} contains an invalid number" unless @number
|
131
|
+
@number
|
132
|
+
end
|
133
|
+
|
134
|
+
# returns the klass name of the
|
135
|
+
def klass_name
|
136
|
+
@name.to_s.scan(/#{number_name}_(.+)/)
|
137
|
+
ActiveSupport::Inflector.singularize($1)
|
138
|
+
end
|
139
|
+
|
140
|
+
# returns the name of the factory as a symbol.
|
141
|
+
# Eg. Grab.four_hippos (would return :hippo)
|
142
|
+
def klass_name_symbol
|
143
|
+
klass_name.to_sym
|
144
|
+
end
|
145
|
+
|
146
|
+
# returns the name of the factory as a Constant.
|
147
|
+
# Eg. Grab.four_hippos (would return :hippo)
|
148
|
+
def klass_name_constant
|
149
|
+
klass_name.classify.constantize
|
150
|
+
end
|
151
|
+
|
152
|
+
# TODO rewrite this to accept various factory gems
|
153
|
+
def create_factory
|
154
|
+
Factory(klass_name_symbol, @options)
|
155
|
+
end
|
156
|
+
|
157
|
+
# returns the number of records required minus the number of records available. If there are enough
|
158
|
+
# records already it will return nil (so we can call <tt>required_records ? do_this : do_that</tt> )
|
159
|
+
def required_records
|
160
|
+
result = (number - number_of_existing_records)
|
161
|
+
result > 0 ? result : nil
|
162
|
+
end
|
163
|
+
|
164
|
+
# finds the number appropriate records already in the database.
|
165
|
+
# if klass_name_constant is not a recognised class then this returns 0
|
166
|
+
def number_of_existing_records
|
167
|
+
return 0 unless defined?(klass_name_constant)
|
168
|
+
klass_name_constant.all(:conditions => @options).count
|
169
|
+
end
|
170
|
+
|
171
|
+
end
|
172
|
+
|
173
|
+
end
|
174
|
+
|
175
|
+
end
|
176
|
+
include FactoryGrabber
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
ActiveRecord::Base.establish_connection :adapter => "sqlite3", :database => "dbfile"
|
3
|
+
|
4
|
+
ActiveRecord::Base.connection.create_table :users, :force => true do |t|
|
5
|
+
t.string :first_name
|
6
|
+
t.string :last_name
|
7
|
+
t.string :email
|
8
|
+
t.boolean :admin
|
9
|
+
end
|
data/lib/spec/dbfile
ADDED
Binary file
|
@@ -0,0 +1,170 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/spec_helper"
|
2
|
+
|
3
|
+
describe Grab do
|
4
|
+
|
5
|
+
describe "Grabbing 'a' or 'an' record" do
|
6
|
+
|
7
|
+
it "should return one record if number is 'a'" do
|
8
|
+
@user = Grab.a_user
|
9
|
+
@user.is_a?(User).should be_true
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should return one record if number is 'an'" do
|
13
|
+
@user = Grab.an_user
|
14
|
+
@user.is_a?(User).should be_true
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "Grabbing various number combinations" do
|
20
|
+
|
21
|
+
it "should return the record if number is one" do
|
22
|
+
@user = Grab.one_user
|
23
|
+
@user.is_a?(User).should be_true
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should grab the correct number of records each time" do
|
27
|
+
# random number between 1 and 99
|
28
|
+
# running these specs hundreds of times (which I have) means that each number will be tested
|
29
|
+
random_number = (rand * 99).ceil
|
30
|
+
# return the number name eg. sixty_one
|
31
|
+
random_name = Grab::ALL_NUMBERS.invert[random_number]
|
32
|
+
@users = Grab.send("#{random_name}_users")
|
33
|
+
@users.size.should == random_number
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "Grabbing existing records" do
|
39
|
+
|
40
|
+
before do
|
41
|
+
Factory :user unless User.all.any?
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should not create a new record if there is one present" do
|
45
|
+
lambda { Grab.one_user }.should_not change { User.count }
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "Grabbing non-existing records" do
|
51
|
+
|
52
|
+
before do
|
53
|
+
User.destroy_all
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should create a new record" do
|
57
|
+
lambda { Grab.one_user }.should change { User.count }.by(1)
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "Grabbing a mixture of existing and non-existing records" do
|
63
|
+
|
64
|
+
before do
|
65
|
+
User.destroy_all
|
66
|
+
2.times { Factory :user }
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should only create one extra record" do
|
70
|
+
lambda { Grab.three_users }.should change { User.count }.by(1)
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "Grabbing factories with virtual attributes" do
|
76
|
+
# Attributes such as password can be set when creating factories but may not have a corresponding
|
77
|
+
# column on the database (ie. they are virtual attributes)
|
78
|
+
# In such cases, to ensure the record has the desired attributes, a new factory should be created
|
79
|
+
it "should create a new factory if attributes are not all in the database" do
|
80
|
+
Factory(:user, :password => "password")
|
81
|
+
lambda { @user = Grab.one_user(:password => "password") }.should change { User.count }.by(1)
|
82
|
+
@user.is_a?(User).should be_true
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
describe :number_name do
|
88
|
+
|
89
|
+
it "should return the correct number if it's a unit" do
|
90
|
+
Grab.one_user
|
91
|
+
Grab.send(:number_name).should == 'one'
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should return the correct number if it's a teen'" do
|
95
|
+
Grab.eleven_users
|
96
|
+
Grab.send(:number_name).should == 'eleven'
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should return the correct number if it's a double-digit" do
|
100
|
+
Grab.twenty_one_users
|
101
|
+
Grab.send(:number_name).should == 'twenty_one'
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should return the correct number if it's a ten" do
|
105
|
+
Grab.twenty_users
|
106
|
+
Grab.send(:number_name).should == 'twenty'
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
describe :number do
|
112
|
+
|
113
|
+
it "should return the correct number if it's a unit" do
|
114
|
+
Grab.four_users
|
115
|
+
Grab.send(:number).should == 4
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should return the correct number if it's a teen'" do
|
119
|
+
Grab.twelve_users
|
120
|
+
Grab.send(:number).should == 12
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should return the correct number if it's a double-digit" do
|
124
|
+
Grab.twenty_one_users
|
125
|
+
Grab.send(:number).should == 21
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should return the correct number if it's a ten" do
|
129
|
+
Grab.twenty_users
|
130
|
+
Grab.send(:number).should == 20
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
describe :klass_name do
|
136
|
+
|
137
|
+
it "should return the name of the factory class as a constant if available" do
|
138
|
+
Grab.one_user
|
139
|
+
Grab.send(:klass_name).should == "user"
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
143
|
+
|
144
|
+
describe :klass_name_constant do
|
145
|
+
|
146
|
+
it "should return the class name as a constant" do
|
147
|
+
Grab.one_user
|
148
|
+
Grab.send(:klass_name_constant).should == User
|
149
|
+
end
|
150
|
+
|
151
|
+
end
|
152
|
+
|
153
|
+
describe :required_records do
|
154
|
+
|
155
|
+
before do
|
156
|
+
end
|
157
|
+
|
158
|
+
it "should return nil if no records are required" do
|
159
|
+
count = User.count
|
160
|
+
if count < 4
|
161
|
+
(4 - count).times { Factory(:user) }
|
162
|
+
end
|
163
|
+
Grab.three_users
|
164
|
+
Grab.send(:required_records).should be_nil
|
165
|
+
end
|
166
|
+
|
167
|
+
|
168
|
+
end
|
169
|
+
|
170
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/spec_helper"
|
2
|
+
require "benchmark"
|
3
|
+
|
4
|
+
# runs a quick benchmark to compare the two
|
5
|
+
Benchmark.bmbm do |test|
|
6
|
+
test.report("Create 50 new factories") do
|
7
|
+
50.times { Factory :user, :first_name => "John", :admin => false }
|
8
|
+
end
|
9
|
+
|
10
|
+
until User.count >= 50
|
11
|
+
Factory :user, :last_name => "Smith", :admin => true
|
12
|
+
end
|
13
|
+
|
14
|
+
test.report("Grab 50 separate factories") do
|
15
|
+
50.times { Grab.one_user :last_name => "Smith", :admin => true }
|
16
|
+
end
|
17
|
+
|
18
|
+
test.report("Grab 50 factories at once") do
|
19
|
+
Grab.fifty_users :last_name => "Smith", :admin => true
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
data/lib/spec/user.rb
ADDED
metadata
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: factory_grabber
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Gavin Morrice
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-09-17 00:00:00 +01:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Grab or create factories for faster Functional/Integration testing
|
17
|
+
email: gavin@handyrailstips.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- CHANGELOG
|
24
|
+
- README.md
|
25
|
+
- lib/dbfile
|
26
|
+
- lib/factory_grabber.rb
|
27
|
+
- lib/spec/database_setup.rb
|
28
|
+
- lib/spec/dbfile
|
29
|
+
- lib/spec/factories.rb
|
30
|
+
- lib/spec/grab_spec.rb
|
31
|
+
- lib/spec/performance_test.rb
|
32
|
+
- lib/spec/spec_helper.rb
|
33
|
+
- lib/spec/user.rb
|
34
|
+
files:
|
35
|
+
- CHANGELOG
|
36
|
+
- Manifest
|
37
|
+
- README.md
|
38
|
+
- Rakefile
|
39
|
+
- init.rb
|
40
|
+
- lib/dbfile
|
41
|
+
- lib/factory_grabber.rb
|
42
|
+
- lib/spec/database_setup.rb
|
43
|
+
- lib/spec/dbfile
|
44
|
+
- lib/spec/factories.rb
|
45
|
+
- lib/spec/grab_spec.rb
|
46
|
+
- lib/spec/performance_test.rb
|
47
|
+
- lib/spec/spec_helper.rb
|
48
|
+
- lib/spec/user.rb
|
49
|
+
- factory_grabber.gemspec
|
50
|
+
has_rdoc: true
|
51
|
+
homepage: http://github.com/gavinM/factory_grabber
|
52
|
+
licenses: []
|
53
|
+
|
54
|
+
post_install_message:
|
55
|
+
rdoc_options:
|
56
|
+
- --line-numbers
|
57
|
+
- --inline-source
|
58
|
+
- --title
|
59
|
+
- Factory_grabber
|
60
|
+
- --main
|
61
|
+
- README.md
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: "0"
|
69
|
+
version:
|
70
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: "1.2"
|
75
|
+
version:
|
76
|
+
requirements: []
|
77
|
+
|
78
|
+
rubyforge_project: factory_grabber
|
79
|
+
rubygems_version: 1.3.5
|
80
|
+
signing_key:
|
81
|
+
specification_version: 3
|
82
|
+
summary: Grab or create factories for faster Functional/Integration testing
|
83
|
+
test_files: []
|
84
|
+
|