database_cleaner 1.6.2 → 1.8.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CONTRIBUTE.markdown +1 -2
- data/Gemfile.lock +132 -93
- data/History.rdoc +67 -0
- data/README.markdown +88 -217
- data/Rakefile +12 -8
- data/{lib → adapters/database_cleaner-active_record/lib}/database_cleaner/active_record/base.rb +14 -5
- data/{lib → adapters/database_cleaner-active_record/lib}/database_cleaner/active_record/deletion.rb +19 -17
- data/{lib → adapters/database_cleaner-active_record/lib}/database_cleaner/active_record/truncation.rb +25 -20
- data/adapters/database_cleaner-active_record/lib/database_cleaner/active_record/version.rb +5 -0
- data/adapters/database_cleaner-active_record/lib/database_cleaner/active_record.rb +6 -0
- data/adapters/database_cleaner-active_record/lib/database_cleaner-active_record.rb +1 -0
- data/adapters/database_cleaner-couch_potato/lib/database_cleaner/couch_potato/version.rb +5 -0
- data/adapters/database_cleaner-couch_potato/lib/database_cleaner/couch_potato.rb +11 -0
- data/adapters/database_cleaner-couch_potato/lib/database_cleaner-couch_potato.rb +1 -0
- data/{lib → adapters/database_cleaner-data_mapper/lib}/database_cleaner/data_mapper/base.rb +4 -0
- data/{lib → adapters/database_cleaner-data_mapper/lib}/database_cleaner/data_mapper/truncation.rb +4 -3
- data/adapters/database_cleaner-data_mapper/lib/database_cleaner/data_mapper/version.rb +5 -0
- data/adapters/database_cleaner-data_mapper/lib/database_cleaner/data_mapper.rb +4 -0
- data/adapters/database_cleaner-data_mapper/lib/database_cleaner-data_mapper.rb +1 -0
- data/{lib → adapters/database_cleaner-mongo/lib}/database_cleaner/mongo/truncation.rb +2 -0
- data/adapters/database_cleaner-mongo/lib/database_cleaner/mongo/version.rb +5 -0
- data/adapters/database_cleaner-mongo/lib/database_cleaner/mongo.rb +10 -0
- data/adapters/database_cleaner-mongo/lib/database_cleaner-mongo.rb +1 -0
- data/{lib → adapters/database_cleaner-mongo_mapper/lib}/database_cleaner/mongo_mapper/base.rb +4 -0
- data/adapters/database_cleaner-mongo_mapper/lib/database_cleaner/mongo_mapper/truncation.rb +35 -0
- data/adapters/database_cleaner-mongo_mapper/lib/database_cleaner/mongo_mapper/version.rb +5 -0
- data/adapters/database_cleaner-mongo_mapper/lib/database_cleaner/mongo_mapper.rb +4 -0
- data/adapters/database_cleaner-mongo_mapper/lib/database_cleaner-mongo_mapper.rb +1 -0
- data/adapters/database_cleaner-mongoid/lib/database_cleaner/mongoid/mongo1_truncation_mixin.rb +26 -0
- data/{lib/database_cleaner/mongo2/truncation_mixin.rb → adapters/database_cleaner-mongoid/lib/database_cleaner/mongoid/mongo2_truncation_mixin.rb} +3 -4
- data/adapters/database_cleaner-mongoid/lib/database_cleaner/mongoid/mongoid_truncation_mixin.rb +65 -0
- data/{lib → adapters/database_cleaner-mongoid/lib}/database_cleaner/mongoid/truncation.rb +6 -6
- data/adapters/database_cleaner-mongoid/lib/database_cleaner/mongoid/version.rb +5 -0
- data/adapters/database_cleaner-mongoid/lib/database_cleaner/mongoid.rb +10 -0
- data/adapters/database_cleaner-mongoid/lib/database_cleaner-mongoid.rb +1 -0
- data/{lib → adapters/database_cleaner-moped/lib}/database_cleaner/moped/base.rb +1 -1
- data/{lib → adapters/database_cleaner-moped/lib}/database_cleaner/moped/truncation_base.rb +4 -0
- data/adapters/database_cleaner-moped/lib/database_cleaner/moped/version.rb +5 -0
- data/adapters/database_cleaner-moped/lib/database_cleaner/moped.rb +10 -0
- data/adapters/database_cleaner-moped/lib/database_cleaner-moped.rb +1 -0
- data/{lib → adapters/database_cleaner-neo4j/lib}/database_cleaner/neo4j/base.rb +4 -0
- data/adapters/database_cleaner-neo4j/lib/database_cleaner/neo4j/version.rb +5 -0
- data/adapters/database_cleaner-neo4j/lib/database_cleaner/neo4j.rb +6 -0
- data/adapters/database_cleaner-neo4j/lib/database_cleaner-neo4j.rb +1 -0
- data/adapters/database_cleaner-ohm/lib/database_cleaner/ohm/truncation.rb +24 -0
- data/adapters/database_cleaner-ohm/lib/database_cleaner/ohm/version.rb +5 -0
- data/adapters/database_cleaner-ohm/lib/database_cleaner/ohm.rb +12 -0
- data/adapters/database_cleaner-ohm/lib/database_cleaner-ohm.rb +1 -0
- data/{lib → adapters/database_cleaner-redis/lib}/database_cleaner/redis/base.rb +4 -0
- data/adapters/database_cleaner-redis/lib/database_cleaner/redis/version.rb +5 -0
- data/adapters/database_cleaner-redis/lib/database_cleaner/redis.rb +4 -0
- data/adapters/database_cleaner-redis/lib/database_cleaner-redis.rb +1 -0
- data/{lib → adapters/database_cleaner-sequel/lib}/database_cleaner/sequel/base.rb +4 -0
- data/{lib → adapters/database_cleaner-sequel/lib}/database_cleaner/sequel/truncation.rb +16 -15
- data/adapters/database_cleaner-sequel/lib/database_cleaner/sequel/version.rb +5 -0
- data/adapters/database_cleaner-sequel/lib/database_cleaner/sequel.rb +6 -0
- data/adapters/database_cleaner-sequel/lib/database_cleaner-sequel.rb +1 -0
- data/lib/database_cleaner/base.rb +94 -105
- data/lib/database_cleaner/configuration.rb +87 -83
- data/lib/database_cleaner/deprecation.rb +26 -0
- data/lib/database_cleaner/null_strategy.rb +6 -6
- data/lib/database_cleaner/orm_autodetector.rb +41 -0
- data/lib/database_cleaner/safeguard.rb +107 -0
- data/lib/database_cleaner/spec/database_helper.rb +82 -0
- data/lib/database_cleaner/spec/shared_examples.rb +15 -0
- data/lib/database_cleaner/spec.rb +2 -0
- data/lib/database_cleaner/version.rb +3 -0
- data/lib/database_cleaner.rb +41 -2
- metadata +113 -126
- data/VERSION.yml +0 -4
- data/examples/Gemfile +0 -1
- data/examples/Gemfile.lock +0 -1
- data/examples/config/database.yml.example +0 -8
- data/examples/config/redis.yml +0 -8
- data/examples/db/sqlite_databases_go_here +0 -0
- data/examples/features/example.feature +0 -11
- data/examples/features/example_multiple_db.feature +0 -23
- data/examples/features/example_multiple_orm.feature +0 -22
- data/examples/features/step_definitions/activerecord_steps.rb +0 -31
- data/examples/features/step_definitions/couchpotato_steps.rb +0 -31
- data/examples/features/step_definitions/datamapper_steps.rb +0 -37
- data/examples/features/step_definitions/mongoid_steps.rb +0 -23
- data/examples/features/step_definitions/mongomapper_steps.rb +0 -31
- data/examples/features/step_definitions/neo4j_steps.rb +0 -23
- data/examples/features/step_definitions/ohm_steps.rb +0 -31
- data/examples/features/step_definitions/redis_steps.rb +0 -31
- data/examples/features/step_definitions/translation_steps.rb +0 -55
- data/examples/features/support/env.rb +0 -61
- data/examples/lib/activerecord_models.rb +0 -41
- data/examples/lib/couchpotato_models.rb +0 -61
- data/examples/lib/datamapper_models.rb +0 -50
- data/examples/lib/mongoid_models.rb +0 -44
- data/examples/lib/mongomapper_models.rb +0 -51
- data/examples/lib/neo4j_models.rb +0 -17
- data/examples/lib/ohm_models.rb +0 -43
- data/examples/lib/redis_models.rb +0 -65
- data/examples/lib/sequel_models.rb +0 -9
- data/features/cleaning.feature +0 -30
- data/features/cleaning_default_strategy.feature +0 -23
- data/features/cleaning_multiple_dbs.feature +0 -22
- data/features/cleaning_multiple_orms.feature +0 -67
- data/features/step_definitions/database_cleaner_steps.rb +0 -33
- data/features/support/env.rb +0 -4
- data/features/support/feature_runner.rb +0 -39
- data/lib/database_cleaner/mongo2/base.rb +0 -16
- data/lib/database_cleaner/mongo_mapper/truncation.rb +0 -19
- data/lib/database_cleaner/ohm/truncation.rb +0 -15
- data/spec/database_cleaner/active_record/base_spec.rb +0 -188
- data/spec/database_cleaner/active_record/transaction_spec.rb +0 -176
- data/spec/database_cleaner/active_record/truncation/mysql2_spec.rb +0 -38
- data/spec/database_cleaner/active_record/truncation/mysql_spec.rb +0 -38
- data/spec/database_cleaner/active_record/truncation/postgresql_spec.rb +0 -75
- data/spec/database_cleaner/active_record/truncation/shared_fast_truncation.rb +0 -40
- data/spec/database_cleaner/active_record/truncation/sqlite3_spec.rb +0 -40
- data/spec/database_cleaner/active_record/truncation_spec.rb +0 -180
- data/spec/database_cleaner/base_spec.rb +0 -617
- data/spec/database_cleaner/configuration_spec.rb +0 -345
- data/spec/database_cleaner/couch_potato/truncation_spec.rb +0 -41
- data/spec/database_cleaner/data_mapper/base_spec.rb +0 -30
- data/spec/database_cleaner/data_mapper/transaction_spec.rb +0 -23
- data/spec/database_cleaner/data_mapper/truncation/sqlite3_spec.rb +0 -41
- data/spec/database_cleaner/data_mapper/truncation_spec.rb +0 -11
- data/spec/database_cleaner/generic/base_spec.rb +0 -61
- data/spec/database_cleaner/generic/truncation_spec.rb +0 -118
- data/spec/database_cleaner/mongo/mongo_examples.rb +0 -26
- data/spec/database_cleaner/mongo/truncation_spec.rb +0 -72
- data/spec/database_cleaner/mongo_mapper/base_spec.rb +0 -33
- data/spec/database_cleaner/mongo_mapper/mongo_examples.rb +0 -8
- data/spec/database_cleaner/mongo_mapper/truncation_spec.rb +0 -74
- data/spec/database_cleaner/moped/moped_examples.rb +0 -32
- data/spec/database_cleaner/moped/truncation_spec.rb +0 -80
- data/spec/database_cleaner/neo4j/base_spec.rb +0 -43
- data/spec/database_cleaner/neo4j/transaction_spec.rb +0 -25
- data/spec/database_cleaner/null_strategy_spec.rb +0 -28
- data/spec/database_cleaner/ohm/truncation_spec.rb +0 -70
- data/spec/database_cleaner/redis/base_spec.rb +0 -43
- data/spec/database_cleaner/redis/truncation_spec.rb +0 -63
- data/spec/database_cleaner/sequel/base_spec.rb +0 -32
- data/spec/database_cleaner/sequel/deletion_spec.rb +0 -58
- data/spec/database_cleaner/sequel/transaction_spec.rb +0 -21
- data/spec/database_cleaner/sequel/truncation/sqlite3_spec.rb +0 -0
- data/spec/database_cleaner/sequel/truncation_spec.rb +0 -182
- data/spec/database_cleaner/shared_strategy.rb +0 -15
- data/spec/rcov.opts +0 -1
- data/spec/spec_helper.rb +0 -21
- data/spec/support/active_record/database_setup.rb +0 -6
- data/spec/support/active_record/migrations/20150101010000_create_users.rb +0 -14
- data/spec/support/active_record/migrations/20150101020000_create_agents.rb +0 -14
- data/spec/support/active_record/mysql2_setup.rb +0 -39
- data/spec/support/active_record/mysql_setup.rb +0 -38
- data/spec/support/active_record/postgresql_setup.rb +0 -48
- data/spec/support/active_record/schema_setup.rb +0 -17
- data/spec/support/active_record/sqlite3_setup.rb +0 -40
- data/spec/support/data_mapper/schema_setup.rb +0 -15
- data/spec/support/data_mapper/sqlite3_setup.rb +0 -39
- /data/{lib → adapters/database_cleaner-active_record/lib}/database_cleaner/active_record/transaction.rb +0 -0
- /data/{lib → adapters/database_cleaner-couch_potato/lib}/database_cleaner/couch_potato/base.rb +0 -0
- /data/{lib → adapters/database_cleaner-couch_potato/lib}/database_cleaner/couch_potato/truncation.rb +0 -0
- /data/{lib → adapters/database_cleaner-data_mapper/lib}/database_cleaner/data_mapper/transaction.rb +0 -0
- /data/{lib → adapters/database_cleaner-mongo/lib}/database_cleaner/mongo/base.rb +0 -0
- /data/{lib → adapters/database_cleaner-mongo/lib}/database_cleaner/mongo/truncation_mixin.rb +0 -0
- /data/{lib → adapters/database_cleaner-mongoid/lib}/database_cleaner/mongoid/base.rb +0 -0
- /data/{lib → adapters/database_cleaner-moped/lib}/database_cleaner/moped/truncation.rb +0 -0
- /data/{lib → adapters/database_cleaner-neo4j/lib}/database_cleaner/neo4j/deletion.rb +0 -0
- /data/{lib → adapters/database_cleaner-neo4j/lib}/database_cleaner/neo4j/transaction.rb +0 -0
- /data/{lib → adapters/database_cleaner-neo4j/lib}/database_cleaner/neo4j/truncation.rb +0 -0
- /data/{lib → adapters/database_cleaner-redis/lib}/database_cleaner/redis/truncation.rb +0 -0
- /data/{lib → adapters/database_cleaner-sequel/lib}/database_cleaner/sequel/deletion.rb +0 -0
- /data/{lib → adapters/database_cleaner-sequel/lib}/database_cleaner/sequel/transaction.rb +0 -0
data/README.markdown
CHANGED
@@ -1,149 +1,76 @@
|
|
1
|
+
<!--
|
2
|
+
**If you're viewing this at https://github.com/DatabaseCleaner/database_cleaner,
|
3
|
+
you're reading the documentation for the `master` branch.
|
4
|
+
[View documentation for the latest release
|
5
|
+
(1.7.0).](https://github.com/DatabaseCleaner/database_cleaner/blob/v1.7.0/README.markdown)**
|
6
|
+
-->
|
1
7
|
# Database Cleaner
|
2
8
|
|
3
9
|
[![Build Status](https://travis-ci.org/DatabaseCleaner/database_cleaner.svg?branch=master)](https://travis-ci.org/DatabaseCleaner/database_cleaner)
|
4
10
|
[![Code Climate](https://codeclimate.com/github/DatabaseCleaner/database_cleaner/badges/gpa.svg)](https://codeclimate.com/github/DatabaseCleaner/database_cleaner)
|
11
|
+
![Gem Version](https://badge.fury.io/rb/database_cleaner.svg)
|
12
|
+
[![SemVer](https://api.dependabot.com/badges/compatibility_score?dependency-name=database_cleaner&package-manager=bundler&version-scheme=semver)](https://dependabot.com/compatibility-score.html?dependency-name=database_cleaner&package-manager=bundler&version-scheme=semver)
|
5
13
|
|
6
|
-
Database Cleaner is a set of strategies for cleaning your database in Ruby.
|
14
|
+
Database Cleaner is a set of gems containing strategies for cleaning your database in Ruby.
|
7
15
|
|
8
16
|
The original use case was to ensure a clean state during tests.
|
9
17
|
Each strategy is a small amount of code but is code that is usually needed in any ruby app that is testing with a database.
|
10
18
|
|
11
19
|
## Gem Setup
|
12
20
|
|
21
|
+
Instead of using the `database_cleaner` gem directly, each ORM has its own gem. Most projects will only need the `database_cleaner-active_record` gem:
|
22
|
+
|
13
23
|
```ruby
|
14
24
|
# Gemfile
|
15
25
|
group :test do
|
16
|
-
gem 'database_cleaner'
|
26
|
+
gem 'database_cleaner-active_record'
|
17
27
|
end
|
18
28
|
```
|
19
29
|
|
20
|
-
|
21
|
-
|
22
|
-
ActiveRecord, DataMapper, Sequel, MongoMapper, Mongoid, CouchPotato, Ohm and Redis are supported.
|
23
|
-
|
24
|
-
Here is an overview of the strategies supported for each library:
|
25
|
-
|
26
|
-
<table>
|
27
|
-
<tbody>
|
28
|
-
<tr>
|
29
|
-
<th>ORM</th>
|
30
|
-
<th>Truncation</th>
|
31
|
-
<th>Transaction</th>
|
32
|
-
<th>Deletion</th>
|
33
|
-
</tr>
|
34
|
-
<tr>
|
35
|
-
<td> ActiveRecord </td>
|
36
|
-
<td> Yes</td>
|
37
|
-
<td> <b>Yes</b></td>
|
38
|
-
<td> Yes</td>
|
39
|
-
</tr>
|
40
|
-
<tr>
|
41
|
-
<td> DataMapper</td>
|
42
|
-
<td> Yes</td>
|
43
|
-
<td> <b>Yes</b></td>
|
44
|
-
<td> No</td>
|
45
|
-
</tr>
|
46
|
-
<tr>
|
47
|
-
<td> CouchPotato</td>
|
48
|
-
<td> <b>Yes</b></td>
|
49
|
-
<td> No</td>
|
50
|
-
<td> No</td>
|
51
|
-
</tr>
|
52
|
-
<tr>
|
53
|
-
<td> MongoMapper</td>
|
54
|
-
<td> <b>Yes</b></td>
|
55
|
-
<td> No</td>
|
56
|
-
<td> No</td>
|
57
|
-
</tr>
|
58
|
-
<tr>
|
59
|
-
<td> Mongoid</td>
|
60
|
-
<td> <b>Yes</b></td>
|
61
|
-
<td> No</td>
|
62
|
-
<td> No</td>
|
63
|
-
</tr>
|
64
|
-
<tr>
|
65
|
-
<td> Sequel</td>
|
66
|
-
<td> <b>Yes</b></td>
|
67
|
-
<td> Yes</td>
|
68
|
-
<td> Yes</td>
|
69
|
-
</tr>
|
70
|
-
<tr>
|
71
|
-
<td>Redis</td>
|
72
|
-
<td><b>Yes</b></td>
|
73
|
-
<td>No</td>
|
74
|
-
<td>No</td>
|
75
|
-
</tr>
|
76
|
-
<tr>
|
77
|
-
<td>Ohm</td>
|
78
|
-
<td><b>Yes</b></td>
|
79
|
-
<td>No</td>
|
80
|
-
<td>No</td>
|
81
|
-
</tr>
|
82
|
-
<tr>
|
83
|
-
<td>Neo4j</td>
|
84
|
-
<td>Yes</td>
|
85
|
-
<td>Yes*</td>
|
86
|
-
<td>Yes*</td>
|
87
|
-
</tr>
|
88
|
-
</tbody>
|
89
|
-
</table>
|
90
|
-
|
91
|
-
\* Truncation and Deletion strategies for Neo4j will just delete all nodes and relationships from the database.
|
92
|
-
|
93
|
-
<table>
|
94
|
-
<tbody>
|
95
|
-
<tr>
|
96
|
-
<th>Driver</th>
|
97
|
-
<th>Truncation</th>
|
98
|
-
<th>Transaction</th>
|
99
|
-
<th>Deletion</th>
|
100
|
-
</tr>
|
101
|
-
<tr>
|
102
|
-
<td> Mongo</td>
|
103
|
-
<td> Yes</td>
|
104
|
-
<td> No</td>
|
105
|
-
<td> No</td>
|
106
|
-
</tr>
|
107
|
-
<tr>
|
108
|
-
<td> Moped</td>
|
109
|
-
<td> Yes</td>
|
110
|
-
<td> No</td>
|
111
|
-
<td> No</td>
|
112
|
-
</tr>
|
113
|
-
</tbody>
|
114
|
-
</table>
|
115
|
-
|
116
|
-
(Default strategy for each library is denoted in bold)
|
30
|
+
If you are using multiple ORMs, just load multiple gems:
|
117
31
|
|
118
|
-
Database Cleaner also includes a `null` strategy (that does no cleaning at all) which can be used with any ORM library.
|
119
|
-
You can also explicitly use it by setting your strategy to `nil`.
|
120
32
|
|
121
|
-
|
33
|
+
```ruby
|
34
|
+
# Gemfile
|
35
|
+
group :test do
|
36
|
+
gem 'database_cleaner-active_record'
|
37
|
+
gem 'database_cleaner-redis'
|
38
|
+
end
|
39
|
+
```
|
122
40
|
|
123
|
-
##
|
41
|
+
## List of adapters
|
124
42
|
|
125
|
-
|
43
|
+
Here is an overview of the databases and ORMs supported by each adapter:
|
126
44
|
|
127
|
-
|
45
|
+
MySQL, PostgreSQL, SQLite, etc
|
46
|
+
* [database_cleaner-active_record](adapters/database_cleaner-active_record)
|
47
|
+
* [database_cleaner-sequel](adapters/database_cleaner-sequel)
|
48
|
+
* [database_cleaner-data_mapper](adapters/database_cleaner-data_mapper)
|
128
49
|
|
129
|
-
|
50
|
+
CouchDB
|
51
|
+
* [database_cleaner-couch_potato](adapters/database_cleaner-couch_potato)
|
130
52
|
|
131
|
-
|
53
|
+
MongoDB
|
54
|
+
* [database_cleaner-mongoid](adapters/database_cleaner-mongoid)
|
55
|
+
* [database_cleaner-mongo_mapper](adapters/database_cleaner-mongo_mapper)
|
56
|
+
* [database_cleaner-moped](adapters/database_cleaner-moped)
|
57
|
+
* [database_cleaner-mongo](adapters/database_cleaner-mongo)
|
132
58
|
|
133
|
-
|
59
|
+
Redis
|
60
|
+
* [database_cleaner-redis](adapters/database_cleaner-redis)
|
61
|
+
* [database_cleaner-ohm](adapters/database_cleaner-ohm)
|
134
62
|
|
135
|
-
|
136
|
-
|
137
|
-
If you are using ActiveRecord then take a look at the [additional options](#additional-activerecord-options-for-truncation) available for `:truncation`.
|
63
|
+
Neo4j
|
64
|
+
* [database_cleaner-neo4j](adapters/database_cleaner-neo4j)
|
138
65
|
|
139
|
-
|
66
|
+
More details on available configuration options can be found in the README for the specific adapter gem that you're using.
|
140
67
|
|
141
|
-
|
68
|
+
For support or to discuss development please use the [Google Group](https://groups.google.com/group/database_cleaner).
|
142
69
|
|
143
70
|
## How to use
|
144
71
|
|
145
72
|
```ruby
|
146
|
-
require 'database_cleaner'
|
73
|
+
require 'database_cleaner/active_record'
|
147
74
|
|
148
75
|
DatabaseCleaner.strategy = :truncation
|
149
76
|
|
@@ -161,15 +88,12 @@ DatabaseCleaner.strategy = :truncation, {:only => %w[widgets dogs some_other_tab
|
|
161
88
|
DatabaseCleaner.strategy = :truncation, {:except => %w[widgets]}
|
162
89
|
```
|
163
90
|
|
164
|
-
With Ohm and Redis, `:only` and `:except` take a list of strings to be
|
165
|
-
passed to [`keys`](http://redis.io/commands/keys)).
|
166
|
-
|
167
91
|
(I should point out the truncation strategy will never truncate your schema_migrations table.)
|
168
92
|
|
169
93
|
Some strategies need to be started before tests are run (for example the `:transaction` strategy needs to know to open up a transaction). This can be accomplished by calling `DatabaseCleaner.start` at the beginning of the run, or by running the tests inside a block to `DatabaseCleaner.cleaning`. So you would have:
|
170
94
|
|
171
95
|
```ruby
|
172
|
-
require 'database_cleaner'
|
96
|
+
require 'database_cleaner/active_record'
|
173
97
|
|
174
98
|
DatabaseCleaner.strategy = :transaction
|
175
99
|
|
@@ -191,7 +115,7 @@ At times you may want to do a single clean with one strategy.
|
|
191
115
|
For example, you may want to start the process by truncating all the tables, but then use the faster transaction strategy the remaining time. To accomplish this you can say:
|
192
116
|
|
193
117
|
```ruby
|
194
|
-
require 'database_cleaner'
|
118
|
+
require 'database_cleaner/active_record'
|
195
119
|
|
196
120
|
DatabaseCleaner.clean_with :truncation
|
197
121
|
|
@@ -200,17 +124,26 @@ DatabaseCleaner.strategy = :transaction
|
|
200
124
|
# then make the DatabaseCleaner.start and DatabaseCleaner.clean calls appropriately
|
201
125
|
```
|
202
126
|
|
203
|
-
|
127
|
+
## What strategy is fastest?
|
204
128
|
|
205
|
-
|
129
|
+
For the SQL libraries the fastest option will be to use `:transaction` as transactions are simply rolled back. If you can use this strategy you should. However, if you wind up needing to use multiple database connections in your tests (i.e. your tests run in a different process than your application) then using this strategy becomes a bit more difficult. You can get around the problem a number of ways.
|
206
130
|
|
207
|
-
|
208
|
-
* `:reset_ids` - This only matters when `:pre_count` is used, and it will make sure that a tables auto-incrementing id is reset even if there are no rows in the table (e.g. records were created in the test but also removed before DatabaseCleaner gets to it). Defaults to `true`.
|
131
|
+
One common approach is to force all processes to use the same database connection ([common ActiveRecord hack](http://blog.plataformatec.com.br/2011/12/three-tips-to-improve-the-performance-of-your-test-suite/)) however this approach has been reported to result in non-deterministic failures.
|
209
132
|
|
210
|
-
|
133
|
+
Another approach is to have the transactions rolled back in the application's process and relax the isolation level of the database (so the tests can read the uncommitted transactions).
|
211
134
|
|
212
|
-
|
135
|
+
An easier, but slower, solution is to use the `:truncation` or `:deletion` strategy.
|
136
|
+
|
137
|
+
So what is fastest out of `:deletion` and `:truncation`? Well, it depends on your table structure and what percentage of tables you populate in an average test. The reasoning is out of the scope of this README but here is a [good SO answer on this topic for Postgres](https://stackoverflow.com/questions/11419536/postgresql-truncation-speed/11423886#11423886).
|
138
|
+
|
139
|
+
Some people report much faster speeds with `:deletion` while others say `:truncation` is faster for them. The best approach therefore is it try all options on your test suite and see what is faster.
|
140
|
+
|
141
|
+
If you are using ActiveRecord then take a look at the [additional options](#additional-activerecord-options-for-truncation) available for `:truncation`.
|
213
142
|
|
143
|
+
Database Cleaner also includes a `null` strategy (that does no cleaning at all) which can be used with any ORM library.
|
144
|
+
You can also explicitly use it by setting your strategy to `nil`.
|
145
|
+
|
146
|
+
## Test Framework Examples
|
214
147
|
|
215
148
|
### RSpec Example
|
216
149
|
|
@@ -295,7 +228,7 @@ RSpec.configure do |config|
|
|
295
228
|
# with the specs, so continue to use transaction strategy for speed.
|
296
229
|
driver_shares_db_connection_with_specs = Capybara.current_driver == :rack_test
|
297
230
|
|
298
|
-
|
231
|
+
unless driver_shares_db_connection_with_specs
|
299
232
|
# Driver is probably for an external browser with an app
|
300
233
|
# under test that does *not* share a database connection with the
|
301
234
|
# specs, so use truncation strategy.
|
@@ -345,14 +278,9 @@ If you're using Cucumber with Rails, just use the generator that ships with cucu
|
|
345
278
|
Otherwise, to add DatabaseCleaner to your project by hand, create a file `features/support/database_cleaner.rb` that looks like this:
|
346
279
|
|
347
280
|
```ruby
|
348
|
-
|
349
|
-
require 'database_cleaner'
|
350
|
-
require 'database_cleaner/cucumber'
|
281
|
+
require 'database_cleaner/active_record'
|
351
282
|
|
352
|
-
|
353
|
-
rescue NameError
|
354
|
-
raise "You need to add database_cleaner to your Gemfile (in the :test group) if you wish to use it."
|
355
|
-
end
|
283
|
+
DatabaseCleaner.strategy = :truncation
|
356
284
|
|
357
285
|
Around do |scenario, block|
|
358
286
|
DatabaseCleaner.cleaning(&block)
|
@@ -370,11 +298,14 @@ Sometimes you need to use multiple ORMs in your application.
|
|
370
298
|
You can use DatabaseCleaner to clean multiple ORMs, and multiple connections for those ORMs.
|
371
299
|
|
372
300
|
```ruby
|
373
|
-
|
301
|
+
require 'database_cleaner/active_record'
|
302
|
+
require 'database_cleaner/mongo_mapper'
|
303
|
+
|
304
|
+
# How to specify particular orms
|
374
305
|
DatabaseCleaner[:active_record].strategy = :transaction
|
375
306
|
DatabaseCleaner[:mongo_mapper].strategy = :truncation
|
376
307
|
|
377
|
-
#How to specify particular connections
|
308
|
+
# How to specify particular connections
|
378
309
|
DatabaseCleaner[:active_record, { :connection => :two }]
|
379
310
|
|
380
311
|
# You may also pass in the model directly:
|
@@ -383,68 +314,6 @@ DatabaseCleaner[:active_record, { :model => ModelWithDifferentConnection }]
|
|
383
314
|
|
384
315
|
Usage beyond that remains the same with `DatabaseCleaner.start` calling any setup on the different configured connections, and `DatabaseCleaner.clean` executing afterwards.
|
385
316
|
|
386
|
-
### Configuration options
|
387
|
-
|
388
|
-
<table>
|
389
|
-
<tbody>
|
390
|
-
<tr>
|
391
|
-
<th>ORM</th>
|
392
|
-
<th>How to access</th>
|
393
|
-
<th>Notes</th>
|
394
|
-
</tr>
|
395
|
-
<tr>
|
396
|
-
<td> Active Record </td>
|
397
|
-
<td> <code>DatabaseCleaner[:active_record]</code></td>
|
398
|
-
<td> Connection specified as <code>:symbol</code> keys, loaded from <code>config/database.yml</code>. You may also pass in the ActiveRecord model under the <code>:model</code> key.</td>
|
399
|
-
</tr>
|
400
|
-
<tr>
|
401
|
-
<td> Data Mapper</td>
|
402
|
-
<td> <code>DatabaseCleaner[:data_mapper]</code></td>
|
403
|
-
<td> Connection specified as <code>:symbol</code> keys, loaded via Datamapper repositories </td>
|
404
|
-
</tr>
|
405
|
-
<tr>
|
406
|
-
<td> Mongo Mapper</td>
|
407
|
-
<td> <code>DatabaseCleaner[:mongo_mapper]</code></td>
|
408
|
-
<td> Multiple connections not yet supported</td>
|
409
|
-
</tr>
|
410
|
-
<tr>
|
411
|
-
<td> Mongoid</td>
|
412
|
-
<td> <code>DatabaseCleaner[:mongoid]</code></td>
|
413
|
-
<td> Multiple databases supported for Mongoid 3. Specify <code>DatabaseCleaner[:mongoid, {:connection => :db_name}]</code> </td>
|
414
|
-
</tr>
|
415
|
-
<tr>
|
416
|
-
<td> Moped</td>
|
417
|
-
<td> <code>DatabaseCleaner[:moped]</code></td>
|
418
|
-
<td> It is necessary to configure database name with <code>DatabaseCleaner[:moped].db = db_name</code> otherwise name `default` will be used.</td>
|
419
|
-
</tr>
|
420
|
-
<tr>
|
421
|
-
<td> Couch Potato</td>
|
422
|
-
<td> <code>DatabaseCleaner[:couch_potato]</code></td>
|
423
|
-
<td> Multiple connections not yet supported</td>
|
424
|
-
</tr>
|
425
|
-
<tr>
|
426
|
-
<td> Sequel</td>
|
427
|
-
<td> <code>DatabaseCleaner[:sequel]</code></td>
|
428
|
-
<td> Multiple databases supported; specify <code>DatabaseCleaner[:sequel, {:connection => Sequel.connect(uri)}]</code></td>
|
429
|
-
</tr>
|
430
|
-
<tr>
|
431
|
-
<td>Redis</td>
|
432
|
-
<td><code>DatabaseCleaner[:redis]</code></td>
|
433
|
-
<td>Connection specified as Redis URI</td>
|
434
|
-
</tr>
|
435
|
-
<tr>
|
436
|
-
<td>Ohm</td>
|
437
|
-
<td><code>DatabaseCleaner[:ohm]</code></td>
|
438
|
-
<td>Connection specified as Redis URI</td>
|
439
|
-
</tr>
|
440
|
-
<tr>
|
441
|
-
<td>Neo4j</td>
|
442
|
-
<td><code>DatabaseCleaner[:neo4j]</code></td>
|
443
|
-
<td>Database type and path(URI) <code>DatabaseCleaner[:neo4j, connection: {type: :server_db, path: 'http://localhost:7475'}].</code></td>
|
444
|
-
</tr>
|
445
|
-
</tbody>
|
446
|
-
</table>
|
447
|
-
|
448
317
|
## Why?
|
449
318
|
|
450
319
|
One of my motivations for writing this library was to have an easy way to turn on what Rails calls "transactional_fixtures" in my non-rails ActiveRecord projects.
|
@@ -455,15 +324,15 @@ After copying and pasting code to do this several times I decided to package it
|
|
455
324
|
|
456
325
|
#### DatabaseCleaner is trying to use the wrong ORM
|
457
326
|
|
458
|
-
DatabaseCleaner has
|
327
|
+
DatabaseCleaner has a deprecated autodetect mechanism where if you do not explicitly define your ORM it will use the first ORM it can detect that is loaded.
|
459
328
|
|
460
329
|
Since ActiveRecord is the most common ORM used that is the first one checked for.
|
461
330
|
|
462
|
-
Sometimes other libraries (e.g. ActiveAdmin) will load other ORMs (e.g. ActiveRecord) even though you are using a different ORM. This will result in DatabaseCleaner trying to use the wrong ORM (e.g. ActiveRecord) unless you explicitly
|
331
|
+
Sometimes other libraries (e.g. ActiveAdmin) will load other ORMs (e.g. ActiveRecord) even though you are using a different ORM. This will result in DatabaseCleaner trying to use the wrong ORM (e.g. ActiveRecord) unless you explicitly require the correct adapter gem:
|
463
332
|
|
464
333
|
```ruby
|
465
|
-
#
|
466
|
-
|
334
|
+
# Gemfile
|
335
|
+
gem "database_cleaner-mongoid"
|
467
336
|
```
|
468
337
|
|
469
338
|
### STDERR is being flooded when using Postgres
|
@@ -485,34 +354,36 @@ test:
|
|
485
354
|
min_messages: WARNING
|
486
355
|
</pre>
|
487
356
|
|
488
|
-
|
357
|
+
## Safeguards
|
489
358
|
|
490
|
-
|
359
|
+
DatabaseCleaner comes with safeguards against:
|
491
360
|
|
492
|
-
|
361
|
+
* Running in production (checking for `ENV`, `RACK_ENV`, and `RAILS_ENV`)
|
362
|
+
* Running against a remote database (checking for a `DATABASE_URL` that does not include `localhost`, `.local` or `127.0.0.1`)
|
493
363
|
|
494
|
-
|
364
|
+
Both safeguards can be disabled separately as follows.
|
495
365
|
|
496
|
-
|
366
|
+
Using environment variables:
|
497
367
|
|
498
|
-
```
|
499
|
-
|
500
|
-
|
501
|
-
load model
|
502
|
-
end
|
368
|
+
```
|
369
|
+
export DATABASE_CLEANER_ALLOW_PRODUCTION=true
|
370
|
+
export DATABASE_CLEANER_ALLOW_REMOTE_DATABASE_URL=true
|
503
371
|
```
|
504
372
|
|
505
|
-
|
373
|
+
In Ruby:
|
506
374
|
|
507
|
-
|
375
|
+
```ruby
|
376
|
+
DatabaseCleaner.allow_production = true
|
377
|
+
DatabaseCleaner.allow_remote_database_url = true
|
378
|
+
```
|
508
379
|
|
509
|
-
|
380
|
+
In Ruby, a URL whitelist can be specified. When specified, DatabaseCleaner will only allow `DATABASE_URL` to be equal
|
381
|
+
to one of the values specified in the url whitelist like so:
|
510
382
|
|
511
383
|
```ruby
|
512
|
-
DatabaseCleaner.
|
384
|
+
DatabaseCleaner.url_whitelist = ['postgres://postgres@localhost', 'postgres://foo@bar']
|
513
385
|
```
|
514
386
|
|
515
|
-
|
516
387
|
## COPYRIGHT
|
517
388
|
|
518
|
-
|
389
|
+
See [LICENSE](LICENSE) for details.
|
data/Rakefile
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
require "rubygems"
|
2
2
|
require "bundler"
|
3
|
+
require "bundler/gem_tasks"
|
3
4
|
Bundler.setup
|
4
5
|
|
5
6
|
require 'rake'
|
6
7
|
require 'rspec/core'
|
7
8
|
require 'rspec/core/rake_task'
|
8
9
|
RSpec::Core::RakeTask.new(:spec) do |spec|
|
9
|
-
|
10
10
|
spec.pattern = FileList['spec/**/*_spec.rb']
|
11
11
|
end
|
12
12
|
|
@@ -15,15 +15,19 @@ RSpec::Core::RakeTask.new(:rcov) do |spec|
|
|
15
15
|
spec.rcov = true
|
16
16
|
end
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
Cucumber::Rake::Task.new(:features)
|
21
|
-
rescue LoadError
|
22
|
-
puts "Cucumber is not available. In order to run features, you must: sudo gem install cucumber"
|
23
|
-
end
|
18
|
+
require 'cucumber/rake/task'
|
19
|
+
Cucumber::Rake::Task.new(:features)
|
24
20
|
|
25
|
-
|
21
|
+
desc "Run adapter test suites"
|
22
|
+
task :adapters do
|
23
|
+
Dir["adapters/*"].each do |adapter_dir|
|
24
|
+
Dir.chdir adapter_dir do
|
25
|
+
sh "bundle exec rake"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
26
29
|
|
30
|
+
task :default => [:spec, :features, :adapters]
|
27
31
|
|
28
32
|
desc "Cleans the project of any tmp file that should not be included in the gemspec."
|
29
33
|
task :clean do
|
data/{lib → adapters/database_cleaner-active_record/lib}/database_cleaner/active_record/base.rb
RENAMED
@@ -1,20 +1,29 @@
|
|
1
|
-
require 'database_cleaner/generic/base'
|
2
1
|
require 'active_record'
|
2
|
+
require 'database_cleaner/generic/base'
|
3
3
|
require 'erb'
|
4
|
+
require 'yaml'
|
4
5
|
|
5
6
|
module DatabaseCleaner
|
6
7
|
module ActiveRecord
|
7
|
-
|
8
8
|
def self.available_strategies
|
9
9
|
%w[truncation transaction deletion]
|
10
10
|
end
|
11
11
|
|
12
|
+
def self.default_strategy
|
13
|
+
:transaction
|
14
|
+
end
|
15
|
+
|
12
16
|
def self.config_file_location=(path)
|
13
17
|
@config_file_location = path
|
14
18
|
end
|
15
19
|
|
16
20
|
def self.config_file_location
|
17
|
-
@config_file_location ||=
|
21
|
+
@config_file_location ||= begin
|
22
|
+
# Has DC.app_root been set? Check in this intrusive way to avoid triggering deprecation warnings if it hasn't.
|
23
|
+
app_root = DatabaseCleaner.send(:configuration).instance_variable_get(:@app_root)
|
24
|
+
root = app_root || Dir.pwd
|
25
|
+
"#{root}/config/database.yml"
|
26
|
+
end
|
18
27
|
end
|
19
28
|
|
20
29
|
module Base
|
@@ -79,14 +88,14 @@ module DatabaseCleaner
|
|
79
88
|
if ::ActiveRecord::Base.respond_to?(:descendants)
|
80
89
|
database_name = connection_hash["database"] || connection_hash[:database]
|
81
90
|
models = ::ActiveRecord::Base.descendants
|
82
|
-
models.detect { |m| m.connection_pool.spec.config[:database] == database_name }
|
91
|
+
models.select(&:connection_pool).detect { |m| m.connection_pool.spec.config[:database] == database_name }
|
83
92
|
end
|
84
93
|
end
|
85
94
|
|
86
95
|
def establish_connection
|
87
96
|
::ActiveRecord::Base.establish_connection(connection_hash)
|
97
|
+
::ActiveRecord::Base
|
88
98
|
end
|
89
|
-
|
90
99
|
end
|
91
100
|
end
|
92
101
|
end
|
data/{lib → adapters/database_cleaner-active_record/lib}/database_cleaner/active_record/deletion.rb
RENAMED
@@ -1,7 +1,6 @@
|
|
1
|
-
require 'active_record
|
1
|
+
require 'active_record'
|
2
2
|
require 'active_record/connection_adapters/abstract_adapter'
|
3
3
|
require "database_cleaner/generic/truncation"
|
4
|
-
require 'database_cleaner/active_record/base'
|
5
4
|
require 'database_cleaner/active_record/truncation'
|
6
5
|
|
7
6
|
module DatabaseCleaner
|
@@ -53,28 +52,31 @@ module DatabaseCleaner::ActiveRecord
|
|
53
52
|
end
|
54
53
|
|
55
54
|
def tables_with_new_rows(connection)
|
56
|
-
|
57
|
-
stats = table_stats_query(connection, @db_name)
|
55
|
+
stats = table_stats_query(connection)
|
58
56
|
if stats != ''
|
59
|
-
connection.
|
57
|
+
connection.select_values(stats)
|
60
58
|
else
|
61
59
|
[]
|
62
60
|
end
|
63
61
|
end
|
64
62
|
|
65
|
-
def table_stats_query(connection
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
63
|
+
def table_stats_query(connection)
|
64
|
+
@table_stats_query ||= build_table_stats_query(connection)
|
65
|
+
ensure
|
66
|
+
@table_stats_query = nil unless @cache_tables
|
67
|
+
end
|
68
|
+
|
69
|
+
def build_table_stats_query(connection)
|
70
|
+
tables = connection.select_values(<<-SQL)
|
71
|
+
SELECT table_name
|
72
|
+
FROM information_schema.tables
|
73
|
+
WHERE table_schema = database()
|
74
|
+
AND #{::DatabaseCleaner::ActiveRecord::Base.exclusion_condition('table_name')};
|
75
|
+
SQL
|
76
|
+
queries = tables.map do |table|
|
77
|
+
"(SELECT #{connection.quote(table)} FROM #{connection.quote_table_name(table)} LIMIT 1)"
|
77
78
|
end
|
79
|
+
queries.join(' UNION ALL ')
|
78
80
|
end
|
79
81
|
|
80
82
|
def information_schema_exists? connection
|
@@ -1,10 +1,10 @@
|
|
1
1
|
require 'active_record/base'
|
2
|
-
|
2
|
+
require 'database_cleaner/active_record/base'
|
3
3
|
require 'active_record/connection_adapters/abstract_adapter'
|
4
4
|
|
5
5
|
#Load available connection adapters
|
6
6
|
%w(
|
7
|
-
abstract_mysql_adapter postgresql_adapter sqlite3_adapter mysql_adapter mysql2_adapter
|
7
|
+
abstract_mysql_adapter postgresql_adapter sqlite3_adapter mysql_adapter mysql2_adapter oracle_enhanced_adapter
|
8
8
|
).each do |known_adapter|
|
9
9
|
begin
|
10
10
|
require "active_record/connection_adapters/#{known_adapter}"
|
@@ -27,7 +27,11 @@ module DatabaseCleaner
|
|
27
27
|
|
28
28
|
def database_cleaner_table_cache
|
29
29
|
# the adapters don't do caching (#130) but we make the assumption that the list stays the same in tests
|
30
|
-
@database_cleaner_tables ||=
|
30
|
+
@database_cleaner_tables ||= database_tables
|
31
|
+
end
|
32
|
+
|
33
|
+
def database_tables
|
34
|
+
::ActiveRecord::VERSION::MAJOR >= 5 ? data_sources : tables
|
31
35
|
end
|
32
36
|
|
33
37
|
def truncate_table(table_name)
|
@@ -63,22 +67,21 @@ module DatabaseCleaner
|
|
63
67
|
select_value("SELECT EXISTS (SELECT 1 FROM #{quote_table_name(table)} LIMIT 1)").to_i
|
64
68
|
end
|
65
69
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
# was ever inserted into.
|
70
|
-
def has_been_used?(table)
|
71
|
-
if has_rows?(table)
|
72
|
-
true
|
73
|
-
else
|
74
|
-
# Patch for MysqlAdapter with ActiveRecord 3.2.7 later
|
75
|
-
# select_value("SELECT 1") #=> "1"
|
76
|
-
select_value(<<-SQL).to_i > 1 # returns nil if not present
|
77
|
-
SELECT Auto_increment
|
70
|
+
def auto_increment_value(table)
|
71
|
+
select_value(<<-SQL).to_i
|
72
|
+
SELECT auto_increment
|
78
73
|
FROM information_schema.tables
|
79
|
-
WHERE table_name='#{table}'
|
80
|
-
|
81
|
-
|
74
|
+
WHERE table_name = '#{table}'
|
75
|
+
AND table_schema = database()
|
76
|
+
SQL
|
77
|
+
end
|
78
|
+
|
79
|
+
# This method tells us if the given table has been inserted into since its
|
80
|
+
# last truncation. Note that the table might have been populated, which
|
81
|
+
# increased the auto-increment counter, but then cleaned again such that
|
82
|
+
# it appears empty now.
|
83
|
+
def has_been_used?(table)
|
84
|
+
has_rows?(table) || auto_increment_value(table) > 1
|
82
85
|
end
|
83
86
|
|
84
87
|
def has_rows?(table)
|
@@ -244,7 +247,7 @@ module DatabaseCleaner::ActiveRecord
|
|
244
247
|
private
|
245
248
|
|
246
249
|
def tables_to_truncate(connection)
|
247
|
-
tables_in_db = cache_tables? ? connection.database_cleaner_table_cache : connection.
|
250
|
+
tables_in_db = cache_tables? ? connection.database_cleaner_table_cache : connection.database_tables
|
248
251
|
to_reject = (@tables_to_exclude + connection.database_cleaner_view_cache)
|
249
252
|
(@only || tables_in_db).reject do |table|
|
250
253
|
if ( m = table.match(/([^.]+)$/) )
|
@@ -257,7 +260,9 @@ module DatabaseCleaner::ActiveRecord
|
|
257
260
|
|
258
261
|
# overwritten
|
259
262
|
def migration_storage_names
|
260
|
-
[::DatabaseCleaner::ActiveRecord::Base.migration_table_name]
|
263
|
+
result = [::DatabaseCleaner::ActiveRecord::Base.migration_table_name]
|
264
|
+
result << ::ActiveRecord::Base.internal_metadata_table_name if ::ActiveRecord::VERSION::MAJOR >= 5
|
265
|
+
result
|
261
266
|
end
|
262
267
|
|
263
268
|
def cache_tables?
|