transactional-factories 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +41 -0
- data/Rakefile +30 -0
- data/VERSION +1 -0
- data/lib/transactional_factories.rb +2 -0
- data/lib/transactional_factories/test_case.rb +21 -0
- data/lib/transactional_factories/test_suite.rb +36 -0
- data/test/db/schema.rb +5 -0
- data/test/lib/blog_post.rb +2 -0
- data/test/test_helper.rb +15 -0
- data/test/unit/blog_post_test.rb +35 -0
- metadata +76 -0
data/README.rdoc
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
= Transactional-factories
|
2
|
+
|
3
|
+
transactional-factories uses nested-transactions to allow efficient, programmatic initialization of test data.
|
4
|
+
|
5
|
+
Typical setup/teardown TestCase callbacks are called prior to every test method. Ruby's Test::Unit::TestCase wraps each test method in a transaction. If your test data must be created programmatically, the data creation code must be run prior to every test method. When the data creation code is slow, this will greatly increase the time it takes to run tests.
|
6
|
+
|
7
|
+
transactional-factories provides self.setup and self.teardown callbacks that are run only once for the entire testsuite. A file-level transaction is used to unwind any changes made in self.setup. Then any test methods are called in nested transactions (per normal TestCase behavior). This relies on database transactions so that we only have to run our data creation code once.
|
8
|
+
|
9
|
+
require 'transactional_factories'
|
10
|
+
|
11
|
+
class MyTest < Test::Unit::TestCase
|
12
|
+
def self.setup
|
13
|
+
100.times { MyModel.create }
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_my_model_1
|
17
|
+
assert_equal 100, MyModel.create
|
18
|
+
MyModel.create
|
19
|
+
assert_equal 101, MyModel.create
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_my_model_2
|
23
|
+
assert_equal 100, MyModel.create
|
24
|
+
MyModel.create
|
25
|
+
assert_equal 101, MyModel.create
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
=== Dependencies
|
30
|
+
|
31
|
+
<b>nested transactional db</b> - You must be using a database that supports nested transactions or savepoints. I've only tested on MySQL. Would be nice to have someone confirm this on PostgreSQL.
|
32
|
+
|
33
|
+
<b>>= ActiveRecord 2.3.x</b> - I don't think ActiveRecord supported nested transactions until 2.3.x.
|
34
|
+
|
35
|
+
<b>use_transactional_fixtures = false</b> - Your test cases can not use transactional fixtures. They're doing about the same thing that the transactional-factories gem is doing and they stomp on each other.
|
36
|
+
|
37
|
+
If you get this: TransactionalFactories::TransactionalFixturesEnabled, it's time to disable transactional fixtures doing something like this:
|
38
|
+
|
39
|
+
class ActiveSupport::TestCase
|
40
|
+
self.use_transactional_fixtures = false
|
41
|
+
end
|
data/Rakefile
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "transactional-factories"
|
8
|
+
gem.summary = "Using nested-transactions to initialize test data programmatically."
|
9
|
+
gem.description = "Transactional-factories uses nested-transactions (like transactional fixtures) to allow efficient initialization of test data programmatically (unlike transactional fixtures)."
|
10
|
+
gem.email = "tim.harrison@yahoo.com"
|
11
|
+
gem.homepage = "http://github.com/heedspin/transactional-factories"
|
12
|
+
gem.authors = ["Tim Harrison"]
|
13
|
+
gem.add_dependency('activerecord', '>= 2.3.2')
|
14
|
+
gem.files.exclude '.gitignore'
|
15
|
+
end
|
16
|
+
Jeweler::RubyforgeTasks.new
|
17
|
+
rescue LoadError
|
18
|
+
puts "Jeweler gem is missing"
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'rake/testtask'
|
22
|
+
Rake::TestTask.new(:test) do |test|
|
23
|
+
test.libs << 'test'
|
24
|
+
test.pattern = 'test/**/*_test.rb'
|
25
|
+
test.verbose = true
|
26
|
+
end
|
27
|
+
|
28
|
+
task :test => :check_dependencies
|
29
|
+
|
30
|
+
task :default => :test
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.1
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class Test::Unit::TestCase
|
2
|
+
class << self
|
3
|
+
def suite
|
4
|
+
method_names = public_instance_methods(true)
|
5
|
+
tests = method_names.delete_if {|method_name| method_name !~ /^test./}
|
6
|
+
suite = TransactionalFactories::TestSuite.new(name)
|
7
|
+
tests.sort.each do
|
8
|
+
|test|
|
9
|
+
catch(:invalid_test) do
|
10
|
+
suite << new(test)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
if (suite.empty?)
|
14
|
+
catch(:invalid_test) do
|
15
|
+
suite << new("default_test")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
return suite
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
|
3
|
+
module TransactionalFactories
|
4
|
+
class TransactionalFixturesEnabled < Exception
|
5
|
+
end
|
6
|
+
class TestSuite < Test::Unit::TestSuite
|
7
|
+
def run(result, &progress_block)
|
8
|
+
if testcase = @tests.find { |tc| tc.class.respond_to?(:setup) }
|
9
|
+
if testcase.class.respond_to?(:use_transactional_fixtures) and testcase.class.use_transactional_fixtures
|
10
|
+
raise TransactionalFixturesEnabled, 'transactional-factories does not work with transactional fixtures. Please set use_transactional_fixtures = false.'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
if @tests.any? { |testcase| testcase.method_name != 'default_test' }
|
14
|
+
ActiveRecord::Base.transaction(:requires_new => true) do
|
15
|
+
testcase.class.setup if testcase
|
16
|
+
begin
|
17
|
+
yield(STARTED, name)
|
18
|
+
@tests.each do |test|
|
19
|
+
ActiveRecord::Base.transaction(:requires_new => true) do
|
20
|
+
test.run(result, &progress_block)
|
21
|
+
raise ActiveRecord::Rollback
|
22
|
+
end
|
23
|
+
end
|
24
|
+
yield(FINISHED, name)
|
25
|
+
rescue
|
26
|
+
raise $!
|
27
|
+
ensure
|
28
|
+
testcase.class.teardown if testcase.class.respond_to?(:teardown)
|
29
|
+
end
|
30
|
+
Timecop.return if defined?(Timecop)
|
31
|
+
raise ActiveRecord::Rollback
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/test/db/schema.rb
ADDED
data/test/test_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'active_record'
|
4
|
+
|
5
|
+
ActiveRecord::Base.logger = Logger.new(STDOUT)
|
6
|
+
ActiveRecord::Base.colorize_logging = false
|
7
|
+
|
8
|
+
ActiveRecord::Base.establish_connection( { :adapter => 'mysql', :database => 'test' } )
|
9
|
+
ActiveRecord::Base.connection.recreate_database('transactional_factories_test')
|
10
|
+
ActiveRecord::Base.clear_active_connections!
|
11
|
+
ActiveRecord::Base.establish_connection( { :adapter => 'mysql', :database => 'transactional_factories_test' } )
|
12
|
+
|
13
|
+
load File.dirname(__FILE__) + '/db/schema.rb'
|
14
|
+
$:.push File.dirname(__FILE__) + '/lib'
|
15
|
+
$:.push File.dirname(__FILE__) + '/../lib'
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
require 'blog_post'
|
4
|
+
require 'transactional_factories'
|
5
|
+
|
6
|
+
class TestBlogPost < Test::Unit::TestCase
|
7
|
+
@@initial_blog_post = nil
|
8
|
+
def self.setup
|
9
|
+
@@initial_blog_post = BlogPost.create(:title => 'initial blog post')
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.teardown
|
13
|
+
raise 'Teardown unhappy' if @@initial_blog_post.nil?
|
14
|
+
# Hard to assert on teardown since it's the last step. How would you know it *didn't* happen?
|
15
|
+
end
|
16
|
+
|
17
|
+
def setup
|
18
|
+
assert @@initial_blog_post
|
19
|
+
assert_equal @@initial_blog_post, BlogPost.first
|
20
|
+
BlogPost.create(:title => 'setup blog post')
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_blog_post1
|
24
|
+
assert_equal 2, BlogPost.count
|
25
|
+
BlogPost.create(:title => 'blog post 1')
|
26
|
+
assert_equal 3, BlogPost.count
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_blog_post2
|
30
|
+
assert_equal 2, BlogPost.count
|
31
|
+
BlogPost.create(:title => 'blog post 2')
|
32
|
+
assert_equal 3, BlogPost.count
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
metadata
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: transactional-factories
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tim Harrison
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-12-31 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: activerecord
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 2.3.2
|
24
|
+
version:
|
25
|
+
description: Transactional-factories uses nested-transactions (like transactional fixtures) to allow efficient initialization of test data programmatically (unlike transactional fixtures).
|
26
|
+
email: tim.harrison@yahoo.com
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- README.rdoc
|
33
|
+
files:
|
34
|
+
- README.rdoc
|
35
|
+
- Rakefile
|
36
|
+
- VERSION
|
37
|
+
- lib/transactional_factories.rb
|
38
|
+
- lib/transactional_factories/test_case.rb
|
39
|
+
- lib/transactional_factories/test_suite.rb
|
40
|
+
- test/db/schema.rb
|
41
|
+
- test/lib/blog_post.rb
|
42
|
+
- test/test_helper.rb
|
43
|
+
- test/unit/blog_post_test.rb
|
44
|
+
has_rdoc: true
|
45
|
+
homepage: http://github.com/heedspin/transactional-factories
|
46
|
+
licenses: []
|
47
|
+
|
48
|
+
post_install_message:
|
49
|
+
rdoc_options:
|
50
|
+
- --charset=UTF-8
|
51
|
+
require_paths:
|
52
|
+
- lib
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: "0"
|
58
|
+
version:
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: "0"
|
64
|
+
version:
|
65
|
+
requirements: []
|
66
|
+
|
67
|
+
rubyforge_project:
|
68
|
+
rubygems_version: 1.3.5
|
69
|
+
signing_key:
|
70
|
+
specification_version: 3
|
71
|
+
summary: Using nested-transactions to initialize test data programmatically.
|
72
|
+
test_files:
|
73
|
+
- test/db/schema.rb
|
74
|
+
- test/lib/blog_post.rb
|
75
|
+
- test/test_helper.rb
|
76
|
+
- test/unit/blog_post_test.rb
|