saimonmoore-database_cleaner 0.5.0
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 +81 -0
- data/LICENSE +20 -0
- data/README.textile +127 -0
- data/Rakefile +46 -0
- data/TODO +0 -0
- data/VERSION.yml +5 -0
- data/cucumber.yml +1 -0
- data/examples/features/example.feature +11 -0
- data/examples/features/step_definitions/example_steps.rb +8 -0
- data/examples/features/support/env.rb +23 -0
- data/examples/lib/activerecord_models.rb +12 -0
- data/examples/lib/couchpotato_models.rb +21 -0
- data/examples/lib/couchrest_models.rb +23 -0
- data/examples/lib/datamapper_models.rb +16 -0
- data/examples/lib/mongomapper_models.rb +17 -0
- data/features/cleaning.feature +21 -0
- data/features/step_definitions/database_cleaner_steps.rb +25 -0
- data/features/support/env.rb +7 -0
- data/lib/database_cleaner.rb +3 -0
- data/lib/database_cleaner/active_record/transaction.rb +26 -0
- data/lib/database_cleaner/active_record/truncation.rb +79 -0
- data/lib/database_cleaner/configuration.rb +128 -0
- data/lib/database_cleaner/couch_potato/truncation.rb +26 -0
- data/lib/database_cleaner/couchrest/compatibility.rb +12 -0
- data/lib/database_cleaner/couchrest/truncation.rb +28 -0
- data/lib/database_cleaner/cucumber.rb +8 -0
- data/lib/database_cleaner/data_mapper/transaction.rb +23 -0
- data/lib/database_cleaner/data_mapper/truncation.rb +142 -0
- data/lib/database_cleaner/mongo_mapper/truncation.rb +30 -0
- data/lib/database_cleaner/truncation_base.rb +41 -0
- data/spec/database_cleaner/active_record/truncation_spec.rb +66 -0
- data/spec/database_cleaner/configuration_spec.rb +104 -0
- data/spec/database_cleaner/couch_potato/truncation_spec.rb +40 -0
- data/spec/database_cleaner/couchrest/truncation_spec.rb +56 -0
- data/spec/database_cleaner/mongo_mapper/truncation_spec.rb +81 -0
- data/spec/spec.opts +6 -0
- data/spec/spec_helper.rb +12 -0
- metadata +104 -0
data/History.txt
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
0.5.x (In Git)
|
2
|
+
|
3
|
+
=== New features
|
4
|
+
* clean and clean_with methods are now aliased to clean! and clean_with!. (Ben Mabey)
|
5
|
+
|
6
|
+
== 0.5.0 2010-02-22 - The CouchPotato Release
|
7
|
+
|
8
|
+
=== New features
|
9
|
+
* Basic truncation support for CouchPotato / CouchDB. (Martin Rehfeld)
|
10
|
+
* SQLite3 on JRuby will fall back to delete if truncate doesn't work. (Darrin Holst)
|
11
|
+
* JDBC is used for ActiveRecord automaticaly when JRuby is detected. (Darrin Holst)
|
12
|
+
|
13
|
+
=== Bufixes
|
14
|
+
* MongoMapper truncation strategy now works with :only and :except options. (Ben Mabey)
|
15
|
+
|
16
|
+
== 0.4.3 2010-01-17
|
17
|
+
|
18
|
+
=== New features
|
19
|
+
* Truncation for ActiveRecord oracle_enhanced adapter. (Edgars Beigarts)
|
20
|
+
|
21
|
+
== 0.4.2 2010-01-12
|
22
|
+
|
23
|
+
=== Bufixes
|
24
|
+
* Datamapper truncation now uses 'select' instead of deprecated the 'query' method. (Steve Tooke)
|
25
|
+
|
26
|
+
== 0.4.1 2010-01-07
|
27
|
+
|
28
|
+
=== Bufixes
|
29
|
+
* Postgres tables with FKs now truncate (added TRUNCADE CASCADE) using Datamapper. (Ben Mabey)
|
30
|
+
|
31
|
+
== 0.4.0 2009-12-23 (The MongoMapper Edition)
|
32
|
+
|
33
|
+
=== New features
|
34
|
+
* MongoMapper support for the truncation strategy. (Aubrey Holland)
|
35
|
+
|
36
|
+
== 0.3.0 2009-12-20
|
37
|
+
|
38
|
+
=== New features
|
39
|
+
* DataMapper 0.10.0 Compatible. (Martin Gamsjaeger)
|
40
|
+
=== Bufixes
|
41
|
+
* Postgres tables with FKs now truncate (added TRUNCADE CASCADE). (Vika - yozhyk on github)
|
42
|
+
|
43
|
+
== 0.2.3 2009-05-30
|
44
|
+
|
45
|
+
=== New features
|
46
|
+
* Support for SQL Server truncation (Adam Meehan)
|
47
|
+
|
48
|
+
== 0.2.2 2009-05-08
|
49
|
+
=== Bufixes
|
50
|
+
* Added proper gemspec description and summary. (Ben Mabey, thanks to Martin Gamsjaeger)
|
51
|
+
|
52
|
+
=== New features
|
53
|
+
|
54
|
+
== 0.2.1 2009-05-08
|
55
|
+
=== Bufixes
|
56
|
+
* Removed extraneous TruncationBase class definition. (Ben Mabey)
|
57
|
+
|
58
|
+
== 0.2.0 2009-05-08 - The Datamapper Release
|
59
|
+
|
60
|
+
=== New features
|
61
|
+
* DataMapper strategies (Martin Gamsjaeger)
|
62
|
+
* Transaction
|
63
|
+
* Truncation - working SQLite3, MySQL adapters. Experimental Postgres adapter (not tested).
|
64
|
+
|
65
|
+
== 0.1.3 2009-04-30
|
66
|
+
|
67
|
+
=== New features
|
68
|
+
* PostgresSQLAdapter for AR to support the truncation strategy. (Alberto Perdomo)
|
69
|
+
=== Bufixes
|
70
|
+
* Added missing quotes around table names in truncation calls. (Michael MacDonald)
|
71
|
+
|
72
|
+
== 0.1.2 2009-03-05
|
73
|
+
=== New features
|
74
|
+
* JDBC Adapter to enable AR truncation strategy to work. (Kamal Fariz Mahyuddin)
|
75
|
+
|
76
|
+
== 0.1.1 2009-03-04 - Initial Release (Ben Mabey)
|
77
|
+
* Basic infrastructure
|
78
|
+
* Features, RSpec code examples
|
79
|
+
* ActiveRecord strategies
|
80
|
+
* Truncation - with MySQL, and SQLite3 adapters.
|
81
|
+
* Transaction - wrap your modifications and roll them back.
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Ben Mabey
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.textile
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
h1. Database Cleaner
|
2
|
+
|
3
|
+
Database Cleaner is a set of strategies for cleaning your database in Ruby.
|
4
|
+
The original use case was to ensure a clean state during tests. Each strategy
|
5
|
+
is a small amount of code but is code that is usually needed in any ruby app
|
6
|
+
that is testing with a database.
|
7
|
+
|
8
|
+
ActiveRecord, DataMapper, MongoMapper, CouchRest and CouchPotato are supported.
|
9
|
+
|
10
|
+
h2. How to use
|
11
|
+
|
12
|
+
<pre>
|
13
|
+
require 'database_cleaner'
|
14
|
+
DatabaseCleaner.strategy = :truncation
|
15
|
+
|
16
|
+
# then, whenever you need to clean the DB
|
17
|
+
DatabaseCleaner.clean
|
18
|
+
</pre>
|
19
|
+
|
20
|
+
With the :truncation strategy you can also pass in options, for example:
|
21
|
+
<pre>
|
22
|
+
DatabaseCleaner.strategy = :truncation, {:only => %w[widgets dogs some_other_table]}
|
23
|
+
</pre>
|
24
|
+
|
25
|
+
<pre>
|
26
|
+
DatabaseCleaner.strategy = :truncation, {:except => %w[widgets]}
|
27
|
+
</pre>
|
28
|
+
|
29
|
+
(I should point out the truncation strategy will never truncate your schema_migrations table.)
|
30
|
+
|
31
|
+
|
32
|
+
Some strategies require that you call DatabaseCleaner.start before calling clean
|
33
|
+
(for example the :transaction one needs to know to open up a transaction). So
|
34
|
+
you would have:
|
35
|
+
|
36
|
+
<pre>
|
37
|
+
require 'database_cleaner'
|
38
|
+
DatabaseCleaner.strategy = :transaction
|
39
|
+
|
40
|
+
DatabaseCleaner.start # usually this is called in setup of a test
|
41
|
+
dirty_the_db
|
42
|
+
DatabaseCleaner.clean # cleanup of the test
|
43
|
+
</pre>
|
44
|
+
|
45
|
+
At times you may want to do a single clean with one strategy. For example, you may want
|
46
|
+
to start the process by truncating all the tables, but then use the faster transaction
|
47
|
+
strategy the remaining time. To accomplish this you can say:
|
48
|
+
|
49
|
+
<pre>
|
50
|
+
require 'database_cleaner'
|
51
|
+
DatabaseCleaner.clean_with :truncation
|
52
|
+
DatabaseCleaner.strategy = :transaction
|
53
|
+
# then make the DatabaseCleaner.start and DatabaseCleaner.clean calls appropriately
|
54
|
+
</pre>
|
55
|
+
|
56
|
+
Example usage with RSpec:
|
57
|
+
|
58
|
+
<pre>
|
59
|
+
Spec::Runner.configure do |config|
|
60
|
+
|
61
|
+
config.before(:suite) do
|
62
|
+
DatabaseCleaner.strategy = :transaction
|
63
|
+
DatabaseCleaner.clean_with(:truncation)
|
64
|
+
end
|
65
|
+
|
66
|
+
config.before(:each) do
|
67
|
+
DatabaseCleaner.start
|
68
|
+
end
|
69
|
+
|
70
|
+
config.after(:each) do
|
71
|
+
DatabaseCleaner.clean
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
</pre>
|
76
|
+
|
77
|
+
For use in Cucumber please see the section below.
|
78
|
+
|
79
|
+
|
80
|
+
|
81
|
+
h2. Why?
|
82
|
+
|
83
|
+
One of my motivations for writing this library was to have an easy way to
|
84
|
+
turn on what Rails calls "transactional_fixtures" in my non-rails
|
85
|
+
ActiveRecord projects. For example, Cucumber ships with a Rails world that
|
86
|
+
will wrap each scenario in a transaction. This is great, but what if you are
|
87
|
+
using ActiveRecord in a non-rails project? You used to have to copy-and-paste
|
88
|
+
the needed code, but with DatabaseCleaner you can now say:
|
89
|
+
|
90
|
+
<pre>
|
91
|
+
#env.rb
|
92
|
+
require 'database_cleaner'
|
93
|
+
require 'database_cleaner/cucumber'
|
94
|
+
DatabaseCleaner.strategy = :transaction
|
95
|
+
</pre>
|
96
|
+
|
97
|
+
Now lets say you are running your features and it requires that another process be
|
98
|
+
involved (i.e. Selenium running against your app's server.) You can simply change
|
99
|
+
your strategy type:
|
100
|
+
|
101
|
+
<pre>
|
102
|
+
#env.rb
|
103
|
+
require 'database_cleaner'
|
104
|
+
require 'database_cleaner/cucumber'
|
105
|
+
DatabaseCleaner.strategy = :truncation
|
106
|
+
</pre>
|
107
|
+
|
108
|
+
You can have the best of both worlds and use the best one for the job:
|
109
|
+
<pre>
|
110
|
+
#env.rb
|
111
|
+
require 'database_cleaner'
|
112
|
+
require 'database_cleaner/cucumber'
|
113
|
+
DatabaseCleaner.strategy = (ENV['SELENIUM'] == 'true') ? :truncation : :transaction
|
114
|
+
</pre>
|
115
|
+
|
116
|
+
h2. CouchRest
|
117
|
+
Due to the fact that couchrest does not have the concept of a global attribute for
|
118
|
+
storing the default database name when using with database_cleaner you must:
|
119
|
+
<pre>
|
120
|
+
require 'database_cleaner/couchrest/compatibility'
|
121
|
+
::CouchRest.default_database_name = 'dbname_or_url'
|
122
|
+
</pre>
|
123
|
+
before actually calling DatabaseCleaner.clean
|
124
|
+
|
125
|
+
he. COPYRIGHT
|
126
|
+
|
127
|
+
Copyright (c) 2009 Ben Mabey. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'rake'
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'jeweler'
|
5
|
+
Jeweler::Tasks.new do |s|
|
6
|
+
s.name = "database_cleaner"
|
7
|
+
s.summary = %Q{Strategies for cleaning databases. Can be used to ensure a clean state for testing.}
|
8
|
+
s.email = "ben@benmabey.com"
|
9
|
+
s.homepage = "http://github.com/bmabey/database_cleaner"
|
10
|
+
s.description = "Strategies for cleaning databases. Can be used to ensure a clean state for testing."
|
11
|
+
s.files = FileList["[A-Z]*.*", "{examples,lib,features,spec}/**/*", "Rakefile", "cucumber.yml"]
|
12
|
+
s.authors = ["Ben Mabey"]
|
13
|
+
end
|
14
|
+
rescue LoadError
|
15
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
16
|
+
end
|
17
|
+
|
18
|
+
require 'rake/rdoctask'
|
19
|
+
Rake::RDocTask.new do |rdoc|
|
20
|
+
rdoc.rdoc_dir = 'rdoc'
|
21
|
+
rdoc.title = 'database_cleaner'
|
22
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
23
|
+
rdoc.rdoc_files.include('README*')
|
24
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
25
|
+
end
|
26
|
+
|
27
|
+
require 'spec/rake/spectask'
|
28
|
+
Spec::Rake::SpecTask.new(:spec) do |t|
|
29
|
+
t.libs << 'lib' << 'spec'
|
30
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
31
|
+
end
|
32
|
+
|
33
|
+
Spec::Rake::SpecTask.new(:rcov) do |t|
|
34
|
+
t.libs << 'lib' << 'spec'
|
35
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
36
|
+
t.rcov = true
|
37
|
+
end
|
38
|
+
|
39
|
+
begin
|
40
|
+
require 'cucumber/rake/task'
|
41
|
+
Cucumber::Rake::Task.new(:features)
|
42
|
+
rescue LoadError
|
43
|
+
puts "Cucumber is not available. In order to run features, you must: sudo gem install cucumber"
|
44
|
+
end
|
45
|
+
|
46
|
+
task :default => [:spec, :features]
|
data/TODO
ADDED
File without changes
|
data/VERSION.yml
ADDED
data/cucumber.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
default: features
|
@@ -0,0 +1,11 @@
|
|
1
|
+
Feature: example
|
2
|
+
In order to test DataBase Cleaner
|
3
|
+
Here are some scenarios that rely on the DB being clean!
|
4
|
+
|
5
|
+
Scenario: dirty the db
|
6
|
+
When I create a widget
|
7
|
+
Then I should see 1 widget
|
8
|
+
|
9
|
+
Scenario: assume a clean db
|
10
|
+
When I create a widget
|
11
|
+
Then I should see 1 widget
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'spec/expectations'
|
3
|
+
|
4
|
+
orm = ENV['ORM']
|
5
|
+
strategy = ENV['STRATEGY']
|
6
|
+
|
7
|
+
if orm && strategy
|
8
|
+
|
9
|
+
$:.unshift(File.dirname(__FILE__) + '/../../../lib')
|
10
|
+
require 'database_cleaner'
|
11
|
+
require 'database_cleaner/cucumber'
|
12
|
+
|
13
|
+
begin
|
14
|
+
require "#{File.dirname(__FILE__)}/../../lib/#{orm}_models"
|
15
|
+
rescue LoadError => error
|
16
|
+
raise "You don't have the #{orm} ORM installed error: #{error.message} #{error.backtrace.join("\n")}"
|
17
|
+
end
|
18
|
+
|
19
|
+
DatabaseCleaner.strategy = strategy.to_sym
|
20
|
+
|
21
|
+
else
|
22
|
+
raise "Run 'ORM=activerecord|datamapper|mongomapper|couchpotato|couchrest STRATEGY=transaction|truncation cucumber examples/features'"
|
23
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
ActiveRecord::Base.establish_connection(:adapter => "#{"jdbc" if defined?(JRUBY_VERSION)}sqlite3", :database => ":memory:")
|
4
|
+
|
5
|
+
ActiveRecord::Schema.define(:version => 1) do
|
6
|
+
create_table :widgets do |t|
|
7
|
+
t.string :name
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class Widget < ActiveRecord::Base
|
12
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'couch_potato'
|
2
|
+
|
3
|
+
::CouchPotato::Config.database_name = 'couch_potato_test'
|
4
|
+
|
5
|
+
class Widget
|
6
|
+
include CouchPotato::Persistence
|
7
|
+
|
8
|
+
property :name
|
9
|
+
view :by_name, :key => :name
|
10
|
+
|
11
|
+
|
12
|
+
# mimic the AR interface used in example_steps
|
13
|
+
|
14
|
+
def self.create!(attrs = {})
|
15
|
+
CouchPotato.database.save(self.new)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.count
|
19
|
+
CouchPotato.database.view(::Widget.by_name).size
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'couchrest'
|
2
|
+
require 'database_cleaner/couchrest/compatibility' #opens CouchRest module to add default_database_name accessor
|
3
|
+
|
4
|
+
DEFAULT_COUCHREST_DBNAME = 'couch_rest_test'
|
5
|
+
::CouchRest.default_database_name= DEFAULT_COUCHREST_DBNAME
|
6
|
+
|
7
|
+
class Widget < CouchRest::ExtendedDocument
|
8
|
+
use_database ::CouchRest.database!(DEFAULT_COUCHREST_DBNAME)
|
9
|
+
|
10
|
+
property :name
|
11
|
+
view_by :name
|
12
|
+
|
13
|
+
def self.create!(options = {})
|
14
|
+
instance = new(options)
|
15
|
+
instance.create!
|
16
|
+
instance
|
17
|
+
end
|
18
|
+
|
19
|
+
# def self.count
|
20
|
+
# CouchPotato.database.view(::Widget.by_name).size
|
21
|
+
# end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "dm-core"
|
2
|
+
|
3
|
+
# only to please activerecord API used in database_cleaner/examples/features/step_definitions
|
4
|
+
# yes, i know that's lazy ...
|
5
|
+
require "dm-validations"
|
6
|
+
require "dm-aggregates"
|
7
|
+
|
8
|
+
DataMapper.setup(:default, "sqlite3::memory:")
|
9
|
+
|
10
|
+
class Widget
|
11
|
+
include DataMapper::Resource
|
12
|
+
property :id, Serial
|
13
|
+
property :name, String
|
14
|
+
end
|
15
|
+
|
16
|
+
Widget.auto_migrate!
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'mongomapper'
|
2
|
+
|
3
|
+
::MongoMapper.connection = Mongo::Connection.new('127.0.0.1')
|
4
|
+
::MongoMapper.database = 'database_cleaner_test'
|
5
|
+
|
6
|
+
class Widget
|
7
|
+
include MongoMapper::Document
|
8
|
+
key :id, Integer
|
9
|
+
key :name, String
|
10
|
+
|
11
|
+
class << self
|
12
|
+
#mongomapper doesn't seem to provide this...
|
13
|
+
def create!(*args)
|
14
|
+
new(*args).save!
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
Feature: database cleaning
|
2
|
+
In order to ease example and feature writing
|
3
|
+
As a developer
|
4
|
+
I want to have my database in a clean state
|
5
|
+
|
6
|
+
Scenario Outline: ruby app
|
7
|
+
Given I am using <ORM>
|
8
|
+
And the <Strategy> cleaning strategy
|
9
|
+
|
10
|
+
When I run my scenarios that rely on a clean database
|
11
|
+
Then I should see all green
|
12
|
+
|
13
|
+
Examples:
|
14
|
+
| ORM | Strategy |
|
15
|
+
| ActiveRecord | transaction |
|
16
|
+
| ActiveRecord | truncation |
|
17
|
+
| DataMapper | transaction |
|
18
|
+
| DataMapper | truncation |
|
19
|
+
| MongoMapper | truncation |
|
20
|
+
| CouchPotato | truncation |
|
21
|
+
| CouchRest | truncation |
|