database_cleaner 1.0.0.RC1 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. data/Gemfile.lock +6 -0
  2. data/History.txt +11 -3
  3. data/README.markdown +39 -3
  4. data/VERSION.yml +2 -2
  5. data/examples/Gemfile +2 -0
  6. data/examples/Gemfile.lock +6 -0
  7. data/examples/config/redis.yml +8 -0
  8. data/examples/features/support/env.rb +8 -1
  9. data/examples/lib/mongoid_models.rb +1 -1
  10. data/examples/lib/ohm_models.rb +43 -0
  11. data/examples/lib/redis_models.rb +65 -0
  12. data/features/cleaning.feature +11 -9
  13. data/features/cleaning_default_strategy.feature +2 -0
  14. data/features/cleaning_multiple_orms.feature +19 -0
  15. data/features/step_definitions/database_cleaner_steps.rb +3 -2
  16. data/features/step_definitions/ohm_steps.rb +31 -0
  17. data/features/step_definitions/redis_steps.rb +31 -0
  18. data/lib/database_cleaner/active_record/base.rb +1 -7
  19. data/lib/database_cleaner/active_record/transaction.rb +4 -0
  20. data/lib/database_cleaner/base.rb +19 -3
  21. data/lib/database_cleaner/configuration.rb +5 -1
  22. data/lib/database_cleaner/mongoid/truncation.rb +2 -2
  23. data/lib/database_cleaner/moped/base.rb +35 -0
  24. data/lib/database_cleaner/moped/truncation.rb +4 -24
  25. data/lib/database_cleaner/moped/truncation_base.rb +34 -0
  26. data/lib/database_cleaner/ohm/truncation.rb +15 -0
  27. data/lib/database_cleaner/redis/base.rb +31 -0
  28. data/lib/database_cleaner/redis/truncation.rb +26 -0
  29. data/spec/database_cleaner/active_record/base_spec.rb +2 -19
  30. data/spec/database_cleaner/active_record/transaction_spec.rb +2 -0
  31. data/spec/database_cleaner/base_spec.rb +73 -7
  32. data/spec/database_cleaner/configuration_spec.rb +15 -1
  33. data/spec/database_cleaner/moped/moped_examples.rb +26 -0
  34. data/spec/database_cleaner/moped/truncation_spec.rb +75 -0
  35. data/spec/database_cleaner/ohm/truncation_spec.rb +70 -0
  36. data/spec/database_cleaner/redis/base_spec.rb +32 -0
  37. data/spec/database_cleaner/redis/truncation_spec.rb +63 -0
  38. metadata +20 -5
data/Gemfile.lock CHANGED
@@ -135,6 +135,10 @@ GEM
135
135
  multi_json (1.5.0)
136
136
  mysql (2.8.1)
137
137
  mysql2 (0.3.11)
138
+ nest (1.1.2)
139
+ redis
140
+ ohm (0.1.5)
141
+ nest (~> 1.0)
138
142
  origin (1.0.11)
139
143
  pg (0.14.1)
140
144
  plucky (0.5.2)
@@ -160,6 +164,7 @@ GEM
160
164
  rake (10.0.3)
161
165
  rdoc (3.12)
162
166
  json (~> 1.4)
167
+ redis (3.0.4)
163
168
  rest-client (1.6.7)
164
169
  mime-types (>= 1.16)
165
170
  rspec (2.12.0)
@@ -213,6 +218,7 @@ DEPENDENCIES
213
218
  mongoid
214
219
  mysql (~> 2.8.1)
215
220
  mysql2
221
+ ohm (~> 0.1.3)
216
222
  pg
217
223
  rake
218
224
  rspec-rails
data/History.txt CHANGED
@@ -1,20 +1,28 @@
1
- == 1.0.0 2012-03-xx
1
+ == 1.0.1 2013-05-13
2
+
3
+ * Patch release to fix broken gemspec file. Sorry folks!
4
+
5
+ == 1.0.0 2013-05-13
2
6
 
3
7
  === New Features/Changes
4
8
 
5
9
  * Dropping support for Ruby 1.8.x; Only 1.9.x and beyond will be supported going forward.
6
- * Now supporting (and testing against 2.0.x).
10
+ * Now supporting (and testing against ruby 2.0.x).
7
11
  * Adds support for AR 4.0 by using `begin_transaction` (David Chelimsky and Steve Madsen)
8
12
  * Adds Rails 4 support for SQLite3Adapter
13
+ * Suppport for Moped when used without Mongoid (Cyprian Kowalczyk)
14
+ * Redis & Ohm support (Hengbin Qiu, James Conroy-Finn)
9
15
 
10
16
  * CI Improvements (Jan Vlnas, Murahashi Sanemat Kenichi, Samer Masry, Jordan Hollinger)
11
- * README/Documentation improvements (Marcelo Cajueiro, Donald Ball, TJ Chambers, Nick Huanca
17
+ * README/Documentation improvements (Marcelo Cajueiro, Donald Ball, TJ Chambers, Nick Huanca, Justin Edwards, Ryota Arai)
12
18
 
13
19
  === Bug Fixes
14
20
  * Fixes transaction errors when using `after_commit` hooks in AR.
15
21
  * Fixes truncation error with SQLite (Daniel White)
16
22
  * Fixes `pre_count` logic in AR Postgres. (Jordan Hollinger)
17
23
  * Sequel fix to normalize all table names to strings. (Lauri Peltola)
24
+ * #clean_with now works with multiple connections. (John Ferlito)
25
+ * Always start a AR transaction to prevent nil errors in AR when rolling back (John Hampton, M.Shibuya)
18
26
 
19
27
  == 0.9.1 2012-10-11 (0.9.0 was released first but was yanked due to bad gemspec)
20
28
 
data/README.markdown CHANGED
@@ -5,7 +5,7 @@ Database Cleaner is a set of strategies for cleaning your database in Ruby.
5
5
  The original use case was to ensure a clean state during tests.
6
6
  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.
7
7
 
8
- ActiveRecord, DataMapper, Sequel, MongoMapper, Mongoid, and CouchPotato are supported.
8
+ ActiveRecord, DataMapper, Sequel, MongoMapper, Mongoid, CouchPotato, Ohm and Redis are supported.
9
9
 
10
10
  [![Build Status](https://secure.travis-ci.org/bmabey/database_cleaner.png)](http://travis-ci.org/bmabey/database_cleaner)
11
11
 
@@ -55,6 +55,18 @@ Here is an overview of the strategies supported for each library:
55
55
  <td> Yes</td>
56
56
  <td> No</td>
57
57
  </tr>
58
+ <tr>
59
+ <td>Redis</td>
60
+ <td><b>Yes</b></td>
61
+ <td>No</td>
62
+ <td>No</td>
63
+ </tr>
64
+ <tr>
65
+ <td>Ohm</td>
66
+ <td><b>Yes</b></td>
67
+ <td>No</td>
68
+ <td>No</td>
69
+ </tr>
58
70
  </tbody>
59
71
  </table>
60
72
 
@@ -72,6 +84,12 @@ Here is an overview of the strategies supported for each library:
72
84
  <td> No</td>
73
85
  <td> No</td>
74
86
  </tr>
87
+ <tr>
88
+ <td> Moped</td>
89
+ <td> Yes</td>
90
+ <td> No</td>
91
+ <td> No</td>
92
+ </tr>
75
93
  </tbody>
76
94
  </table>
77
95
 
@@ -88,11 +106,11 @@ For the SQL libraries the fastest option will be to use `:transaction` as transa
88
106
 
89
107
  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.
90
108
 
91
- 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 uncommited transactions).
109
+ 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).
92
110
 
93
111
  An easier, but slower, solution is to use the `:truncation` or `:deletion` strategy.
94
112
 
95
- 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 the the scope of this README but here is a [good SO answer on this topic for Postgres](http://stackoverflow.com/questions/11419536/postgresql-truncation-speed/11423886#11423886).
113
+ 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](http://stackoverflow.com/questions/11419536/postgresql-truncation-speed/11423886#11423886).
96
114
 
97
115
  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.
98
116
 
@@ -123,6 +141,9 @@ DatabaseCleaner.strategy = :truncation, {:only => %w[widgets dogs some_other_tab
123
141
  DatabaseCleaner.strategy = :truncation, {:except => %w[widgets]}
124
142
  ```
125
143
 
144
+ With Ohm and Redis, `:only` and `:except` take a list of strings to be
145
+ passed to [`keys`](http://redis.io/commands/keys)).
146
+
126
147
  (I should point out the truncation strategy will never truncate your schema_migrations table.)
127
148
 
128
149
  Some strategies require that you call `DatabaseCleaner.start` before calling `clean` (for example the `:transaction` one needs to know to open up a transaction). So you would have:
@@ -276,6 +297,11 @@ Usage beyond that remains the same with `DatabaseCleaner.start` calling any setu
276
297
  <td> <code>DatabaseCleaner[:mongoid]</code></td>
277
298
  <td> Multiple databases supported for Mongoid 3. Specify <code>DatabaseCleaner[:mongoid, {:connection =&gt; :db_name}]</code> </td>
278
299
  </tr>
300
+ <tr>
301
+ <td> Moped</td>
302
+ <td> <code>DatabaseCleaner[:moped]</code></td>
303
+ <td> It is necessary to configure database name with <code>DatabaseCleaner[:moped].db = db_name</code> otherwise name `default` will be used.</td>
304
+ </tr>
279
305
  <tr>
280
306
  <td> Couch Potato</td>
281
307
  <td> <code>DatabaseCleaner[:couch_potato]</code></td>
@@ -286,6 +312,16 @@ Usage beyond that remains the same with `DatabaseCleaner.start` calling any setu
286
312
  <td> <code>DatabaseCleaner[:sequel]</code></td>
287
313
  <td> Multiple databases supported; specify <code>Databasecleaner[:sequel, {:connection =&gt; Sequel.connect(uri)}]</code></td>
288
314
  </tr>
315
+ <tr>
316
+ <td>Redis</td>
317
+ <td><code>DatabaseCleaner[:redis]</code></td>
318
+ <td>Connection specified as Redis URI</td>
319
+ </tr>
320
+ <tr>
321
+ <td>Ohm</td>
322
+ <td><code>DatabaseCleaner[:ohm]</code></td>
323
+ <td>Connection specified as Redis URI</td>
324
+ </tr>
289
325
  </tbody>
290
326
  </table>
291
327
 
data/VERSION.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
2
  :minor: 0
3
- :build: RC1
4
- :patch: 0
3
+ :build:
4
+ :patch: 1
5
5
  :major: 1
data/examples/Gemfile CHANGED
@@ -26,6 +26,8 @@ group :development do
26
26
  gem 'mysql', '~> 2.8.1'
27
27
  gem 'mysql2'
28
28
  gem 'pg'
29
+ gem 'sqlite3'
30
+ gem 'ohm', '~> 0.1.3'
29
31
 
30
32
  gem 'guard-rspec'
31
33
  end
@@ -135,6 +135,10 @@ GEM
135
135
  multi_json (1.5.0)
136
136
  mysql (2.8.1)
137
137
  mysql2 (0.3.11)
138
+ nest (1.1.2)
139
+ redis
140
+ ohm (0.1.5)
141
+ nest (~> 1.0)
138
142
  origin (1.0.11)
139
143
  pg (0.14.1)
140
144
  plucky (0.5.2)
@@ -160,6 +164,7 @@ GEM
160
164
  rake (10.0.3)
161
165
  rdoc (3.12)
162
166
  json (~> 1.4)
167
+ redis (3.0.4)
163
168
  rest-client (1.6.7)
164
169
  mime-types (>= 1.16)
165
170
  rspec (2.12.0)
@@ -213,6 +218,7 @@ DEPENDENCIES
213
218
  mongoid
214
219
  mysql (~> 2.8.1)
215
220
  mysql2
221
+ ohm (~> 0.1.3)
216
222
  pg
217
223
  rake
218
224
  rspec-rails
@@ -0,0 +1,8 @@
1
+ test:
2
+ url: 'redis://localhost:6379/0'
3
+
4
+ one:
5
+ url: 'redis://localhost:6379/1'
6
+
7
+ two:
8
+ url: 'redis://localhost:6379/2'
@@ -15,6 +15,10 @@ another_orm = ENV['ANOTHER_ORM']
15
15
  strategy = ENV['STRATEGY']
16
16
  multiple_db = ENV['MULTIPLE_DBS']
17
17
 
18
+ config = YAML::load(File.open("#{File.dirname(__FILE__)}/../../config/redis.yml"))
19
+ ENV['REDIS_URL'] = config['test']['url']
20
+ ENV['REDIS_URL_ONE'] = config['one']['url']
21
+ ENV['REDIS_URL_TWO'] = config['two']['url']
18
22
 
19
23
  if orm && strategy
20
24
  $:.unshift(File.dirname(__FILE__) + '/../../../lib')
@@ -37,6 +41,9 @@ if orm && strategy
37
41
  when :mongo_mapper
38
42
  DatabaseCleaner[ orm_sym, {:connection => 'database_cleaner_test_one'} ].strategy = strategy.to_sym
39
43
  DatabaseCleaner[ orm_sym, {:connection => 'database_cleaner_test_two'} ].strategy = strategy.to_sym
44
+ when :redis, :ohm
45
+ DatabaseCleaner[ orm_sym, {:connection => ENV['REDIS_URL_ONE']} ].strategy = strategy.to_sym
46
+ DatabaseCleaner[ orm_sym, {:connection => ENV['REDIS_URL_TWO']} ].strategy = strategy.to_sym
40
47
  when :active_record
41
48
  DatabaseCleaner[:active_record, {:model => ActiveRecordWidgetUsingDatabaseOne} ].strategy = strategy.to_sym
42
49
  DatabaseCleaner[:active_record, {:model => ActiveRecordWidgetUsingDatabaseTwo} ].strategy = strategy.to_sym
@@ -53,5 +60,5 @@ if orm && strategy
53
60
  end
54
61
 
55
62
  else
56
- raise "Run 'ORM=ActiveRecord|DataMapper|MongoMapper|CouchPotato [ANOTHER_ORM=...] [MULTIPLE_DBS=true] STRATEGY=transaction|truncation|default cucumber examples/features'"
63
+ raise "Run 'ORM=ActiveRecord|DataMapper|MongoMapper|CouchPotato|Ohm|Redis [ANOTHER_ORM=...] [MULTIPLE_DBS=true] STRATEGY=transaction|truncation|default cucumber examples/features'"
57
64
  end
@@ -2,7 +2,7 @@ require 'mongoid'
2
2
 
3
3
  Mongoid.configure do |config|
4
4
  name = 'database_cleaner_test'
5
- config.master = Mongo::Connection.new.db(name)
5
+ config.connect_to(name)
6
6
  end
7
7
 
8
8
 
@@ -0,0 +1,43 @@
1
+ require 'ohm'
2
+
3
+ Ohm.connect :url => ENV['REDIS_URL']
4
+
5
+ class OhmWidget < Ohm::Model
6
+ attribute :name
7
+
8
+ def self.create!(attrs = {})
9
+ new({:name => 'some widget'}.merge(attrs)).save
10
+ end
11
+
12
+ def self.count
13
+ all.count
14
+ end
15
+
16
+ end
17
+
18
+ class OhmWidgetUsingDatabaseOne < Ohm::Model
19
+ connect :url => ENV['REDIS_URL_ONE']
20
+ attribute :name
21
+
22
+ def self.create!(attrs = {})
23
+ new({:name => 'a widget using database one'}.merge(attrs)).save
24
+ end
25
+
26
+ def self.count
27
+ all.count
28
+ end
29
+
30
+ end
31
+
32
+ class OhmWidgetUsingDatabaseTwo < Ohm::Model
33
+ connect :url => ENV['REDIS_URL_TWO']
34
+ attribute :name
35
+
36
+ def self.create!(attrs = {})
37
+ new({:name => 'a widget using database two'}.merge(attrs)).save
38
+ end
39
+
40
+ def self.count
41
+ all.count
42
+ end
43
+ end
@@ -0,0 +1,65 @@
1
+ require 'redis'
2
+
3
+ class RedisWidget
4
+
5
+ def self.redis
6
+ threaded ||= Redis.connect
7
+ end
8
+
9
+ def self.redis=(connection)
10
+ threaded = connection
11
+ end
12
+
13
+ def self.threaded
14
+ Thread.current[self.class.to_s] ||= {}
15
+ end
16
+
17
+ def initialize(options = {})
18
+ options = options.dup
19
+ @name = options[:name]
20
+ end
21
+
22
+ def connection
23
+ self.class.redis
24
+ end
25
+
26
+ def save
27
+ unless connection.get(self.class.to_s + ':id')
28
+ @id = 0
29
+ connection.set(self.class.to_s + ':id', @id)
30
+ end
31
+ @id = connection.incr(self.class.to_s + ':id')
32
+ connection.set(self.class.to_s + ':%d:name' % @id, @name)
33
+ end
34
+
35
+ def self.count
36
+ self.redis.keys(self.to_s + '*name').size
37
+ end
38
+
39
+ def self.create!
40
+ new(:name => 'some widget').save
41
+
42
+ end
43
+ end
44
+
45
+ class RedisWidgetUsingDatabaseOne < RedisWidget
46
+
47
+ def self.redis
48
+ threaded[self.class.to_s] ||= Redis.connect :url => ENV['REDIS_URL_ONE']
49
+ end
50
+
51
+ def self.create!
52
+ new(:name => 'a widget using database one').save
53
+ end
54
+ end
55
+
56
+ class RedisWidgetUsingDatabaseTwo < RedisWidget
57
+
58
+ def self.redis
59
+ threaded[self.class.to_s] ||= Redis.connect :url => ENV['REDIS_URL_TWO']
60
+ end
61
+
62
+ def self.create!
63
+ new(:name => 'a widget using database two').save
64
+ end
65
+ end
@@ -11,12 +11,14 @@ Feature: database cleaning
11
11
  Then I should see all green
12
12
 
13
13
  Examples:
14
- | ORM | Strategy |
15
- | ActiveRecord | transaction |
16
- | ActiveRecord | truncation |
17
- | ActiveRecord | deletion |
18
- | DataMapper | transaction |
19
- | DataMapper | truncation |
20
- | MongoMapper | truncation |
21
- | Mongoid | truncation |
22
- | CouchPotato | truncation |
14
+ | ORM | Strategy |
15
+ | ActiveRecord | transaction |
16
+ | ActiveRecord | truncation |
17
+ | ActiveRecord | deletion |
18
+ | DataMapper | transaction |
19
+ | DataMapper | truncation |
20
+ | MongoMapper | truncation |
21
+ | Mongoid | truncation |
22
+ | CouchPotato | truncation |
23
+ | Redis | truncation |
24
+ | Ohm | truncation |
@@ -17,3 +17,5 @@ Feature: database cleaning
17
17
  | MongoMapper |
18
18
  | Mongoid |
19
19
  | CouchPotato |
20
+ | Redis |
21
+ | Ohm |
@@ -15,15 +15,34 @@ Feature: database cleaning using multiple ORMs
15
15
  | ActiveRecord | MongoMapper |
16
16
  | ActiveRecord | Mongoid |
17
17
  | ActiveRecord | CouchPotato |
18
+ | ActiveRecord | Ohm |
19
+ | ActiveRecord | Redis |
18
20
  | DataMapper | ActiveRecord |
19
21
  | DataMapper | MongoMapper |
20
22
  | DataMapper | Mongoid |
21
23
  | DataMapper | CouchPotato |
24
+ | DataMapper | Ohm |
25
+ | DataMapper | Redis |
22
26
  | MongoMapper | ActiveRecord |
23
27
  | MongoMapper | DataMapper |
24
28
  | MongoMapper | Mongoid |
25
29
  | MongoMapper | CouchPotato |
30
+ | MongoMapper | Ohm |
31
+ | MongoMapper | Redis |
26
32
  | CouchPotato | ActiveRecord |
27
33
  | CouchPotato | DataMapper |
28
34
  | CouchPotato | MongoMapper |
29
35
  | CouchPotato | Mongoid |
36
+ | CouchPotato | Ohm |
37
+ | CouchPotato | Redis |
38
+ | Ohm | ActiveRecord |
39
+ | Ohm | DataMapper |
40
+ | Ohm | MongoMapper |
41
+ | Ohm | Mongoid |
42
+ | Ohm | CouchPotato |
43
+ | Redis | ActiveRecord |
44
+ | Redis | DataMapper |
45
+ | Redis | MongoMapper |
46
+ | Redis | Mongoid |
47
+ | Redis | CouchPotato |
48
+ | Redis | Ohm |
@@ -1,10 +1,11 @@
1
+ orms_pattern = /(ActiveRecord|DataMapper|MongoMapper|Mongoid|CouchPotato|Redis|Ohm)/
1
2
 
2
- Given /^I am using (ActiveRecord|DataMapper|MongoMapper|Mongoid|CouchPotato)$/ do |orm|
3
+ Given /^I am using #{orms_pattern}$/ do |orm|
3
4
  @feature_runner = FeatureRunner.new
4
5
  @feature_runner.orm = orm
5
6
  end
6
7
 
7
- Given /^I am using (ActiveRecord|DataMapper|MongoMapper|CouchPotato|Mongoid) and (ActiveRecord|DataMapper|MongoMapper|CouchPotato|Mongoid)$/ do |orm1,orm2|
8
+ Given /^I am using #{orms_pattern} and #{orms_pattern}$/ do |orm1,orm2|
8
9
  @feature_runner = FeatureRunner.new
9
10
  @feature_runner.orm = orm1
10
11
  @feature_runner.another_orm = orm2
@@ -0,0 +1,31 @@
1
+ Given /^I have setup database cleaner to clean multiple databases using ohm$/ do
2
+ #DatabaseCleaner
3
+ # require "#{File.dirname(__FILE__)}/../../../lib/ohm_models"
4
+ #
5
+ # DatabaseCleaner[:ohm, {:connection => ENV['REDIS_URL_ONE']} ].strategy = :truncation
6
+ # DatabaseCleaner[:ohm, {:connection => ENV['REDIS_URL_TWO']} ].strategy = :truncation
7
+ end
8
+
9
+ When /^I create a widget using ohm$/ do
10
+ OhmWidget.create!
11
+ end
12
+
13
+ Then /^I should see ([\d]+) widget using ohm$/ do |widget_count|
14
+ OhmWidget.count.should == widget_count.to_i
15
+ end
16
+
17
+ When /^I create a widget in one db using ohm$/ do
18
+ OhmWidgetUsingDatabaseOne.create!
19
+ end
20
+
21
+ When /^I create a widget in another db using ohm$/ do
22
+ OhmWidgetUsingDatabaseTwo.create!
23
+ end
24
+
25
+ Then /^I should see ([\d]+) widget in one db using ohm$/ do |widget_count|
26
+ OhmWidgetUsingDatabaseOne.count.should == widget_count.to_i
27
+ end
28
+
29
+ Then /^I should see ([\d]+) widget in another db using ohm$/ do |widget_count|
30
+ OhmWidgetUsingDatabaseTwo.count.should == widget_count.to_i
31
+ end