Skip to content

Commit

Permalink
Add Redis & Ohm support
Browse files Browse the repository at this point in the history
This contains the work of @hbpoison, updated to work with the current
version of DatabaseCleaner.

https://github.com/bmabey/database_cleaner/pull/87/files
  • Loading branch information
James Conroy-Finn committed May 11, 2013
1 parent ce1d162 commit b70f09a
Show file tree
Hide file tree
Showing 23 changed files with 559 additions and 20 deletions.
2 changes: 2 additions & 0 deletions Gemfile
Expand Up @@ -26,6 +26,8 @@ group :development do
gem 'mysql', '~> 2.8.1'
gem 'mysql2'
gem 'pg'
gem 'sqlite3'
gem 'ohm', '~> 0.1.3'

gem 'guard-rspec'
end
Expand Down
6 changes: 6 additions & 0 deletions Gemfile.lock
Expand Up @@ -135,6 +135,10 @@ GEM
multi_json (1.5.0)
mysql (2.8.1)
mysql2 (0.3.11)
nest (1.1.2)
redis
ohm (0.1.5)
nest (~> 1.0)
origin (1.0.11)
pg (0.14.1)
plucky (0.5.2)
Expand All @@ -160,6 +164,7 @@ GEM
rake (10.0.3)
rdoc (3.12)
json (~> 1.4)
redis (3.0.4)
rest-client (1.6.7)
mime-types (>= 1.16)
rspec (2.12.0)
Expand Down Expand Up @@ -213,6 +218,7 @@ DEPENDENCIES
mongoid
mysql (~> 2.8.1)
mysql2
ohm (~> 0.1.3)
pg
rake
rspec-rails
Expand Down
27 changes: 26 additions & 1 deletion README.markdown
Expand Up @@ -5,7 +5,7 @@ Database Cleaner is a set of strategies for cleaning your database in Ruby.
The original use case was to ensure a clean state during tests.
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.

ActiveRecord, DataMapper, Sequel, MongoMapper, Mongoid, and CouchPotato are supported.
ActiveRecord, DataMapper, Sequel, MongoMapper, Mongoid, CouchPotato, Ohm and Redis are supported.

[![Build Status](https://secure.travis-ci.org/bmabey/database_cleaner.png)](http://travis-ci.org/bmabey/database_cleaner)

Expand Down Expand Up @@ -55,6 +55,18 @@ Here is an overview of the strategies supported for each library:
<td> Yes</td>
<td> No</td>
</tr>
<tr>
<td>Redis</td>
<td><b>Yes</b></td>
<td>No</td>
<td>No</td>
</tr>
<tr>
<td>Ohm</td>
<td><b>Yes</b></td>
<td>No</td>
<td>No</td>
</tr>
</tbody>
</table>

Expand Down Expand Up @@ -129,6 +141,9 @@ DatabaseCleaner.strategy = :truncation, {:only => %w[widgets dogs some_other_tab
DatabaseCleaner.strategy = :truncation, {:except => %w[widgets]}
```

With Ohm and Redis, `:only` and `:except` take a list of strings to be
passed to [`keys`](http://redis.io/commands/keys)).

(I should point out the truncation strategy will never truncate your schema_migrations table.)

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:
Expand Down Expand Up @@ -297,6 +312,16 @@ Usage beyond that remains the same with `DatabaseCleaner.start` calling any setu
<td> <code>DatabaseCleaner[:sequel]</code></td>
<td> Multiple databases supported; specify <code>Databasecleaner[:sequel, {:connection =&gt; Sequel.connect(uri)}]</code></td>
</tr>
<tr>
<td>Redis</td>
<td><code>DatabaseCleaner[:redis]</code></td>
<td>Connection specified as Redis URI</td>
</tr>
<tr>
<td>Ohm</td>
<td><code>DatabaseCleaner[:ohm]</code></td>
<td>Connection specified as Redis URI</td>
</tr>
</tbody>
</table>

Expand Down
8 changes: 8 additions & 0 deletions examples/config/redis.yml
@@ -0,0 +1,8 @@
test:
url: 'redis://localhost:6379/0'

one:
url: 'redis://localhost:6379/1'

two:
url: 'redis://localhost:6379/2'
9 changes: 8 additions & 1 deletion examples/features/support/env.rb
Expand Up @@ -15,6 +15,10 @@
strategy = ENV['STRATEGY']
multiple_db = ENV['MULTIPLE_DBS']

config = YAML::load(File.open("#{File.dirname(__FILE__)}/../../config/redis.yml"))
ENV['REDIS_URL'] = config['test']['url']
ENV['REDIS_URL_ONE'] = config['one']['url']
ENV['REDIS_URL_TWO'] = config['two']['url']

if orm && strategy
$:.unshift(File.dirname(__FILE__) + '/../../../lib')
Expand All @@ -37,6 +41,9 @@
when :mongo_mapper
DatabaseCleaner[ orm_sym, {:connection => 'database_cleaner_test_one'} ].strategy = strategy.to_sym
DatabaseCleaner[ orm_sym, {:connection => 'database_cleaner_test_two'} ].strategy = strategy.to_sym
when :redis, :ohm
DatabaseCleaner[ orm_sym, {:connection => ENV['REDIS_URL_ONE']} ].strategy = strategy.to_sym
DatabaseCleaner[ orm_sym, {:connection => ENV['REDIS_URL_TWO']} ].strategy = strategy.to_sym
when :active_record
DatabaseCleaner[:active_record, {:model => ActiveRecordWidgetUsingDatabaseOne} ].strategy = strategy.to_sym
DatabaseCleaner[:active_record, {:model => ActiveRecordWidgetUsingDatabaseTwo} ].strategy = strategy.to_sym
Expand All @@ -53,5 +60,5 @@
end

else
raise "Run 'ORM=ActiveRecord|DataMapper|MongoMapper|CouchPotato [ANOTHER_ORM=...] [MULTIPLE_DBS=true] STRATEGY=transaction|truncation|default cucumber examples/features'"
raise "Run 'ORM=ActiveRecord|DataMapper|MongoMapper|CouchPotato|Ohm|Redis [ANOTHER_ORM=...] [MULTIPLE_DBS=true] STRATEGY=transaction|truncation|default cucumber examples/features'"
end
43 changes: 43 additions & 0 deletions examples/lib/ohm_models.rb
@@ -0,0 +1,43 @@
require 'ohm'

Ohm.connect :url => ENV['REDIS_URL']

class OhmWidget < Ohm::Model
attribute :name

def self.create!(attrs = {})
new({:name => 'some widget'}.merge(attrs)).save
end

def self.count
all.count
end

end

class OhmWidgetUsingDatabaseOne < Ohm::Model
connect :url => ENV['REDIS_URL_ONE']
attribute :name

def self.create!(attrs = {})
new({:name => 'a widget using database one'}.merge(attrs)).save
end

def self.count
all.count
end

end

class OhmWidgetUsingDatabaseTwo < Ohm::Model
connect :url => ENV['REDIS_URL_TWO']
attribute :name

def self.create!(attrs = {})
new({:name => 'a widget using database two'}.merge(attrs)).save
end

def self.count
all.count
end
end
65 changes: 65 additions & 0 deletions examples/lib/redis_models.rb
@@ -0,0 +1,65 @@
require 'redis'

class RedisWidget

def self.redis
threaded ||= Redis.connect
end

def self.redis=(connection)
threaded = connection
end

def self.threaded
Thread.current[self.class.to_s] ||= {}
end

def initialize(options = {})
options = options.dup
@name = options[:name]
end

def connection
self.class.redis
end

def save
unless connection.get(self.class.to_s + ':id')
@id = 0
connection.set(self.class.to_s + ':id', @id)
end
@id = connection.incr(self.class.to_s + ':id')
connection.set(self.class.to_s + ':%d:name' % @id, @name)
end

def self.count
self.redis.keys(self.to_s + '*name').size
end

def self.create!
new(:name => 'some widget').save

end
end

class RedisWidgetUsingDatabaseOne < RedisWidget

def self.redis
threaded[self.class.to_s] ||= Redis.connect :url => ENV['REDIS_URL_ONE']
end

def self.create!
new(:name => 'a widget using database one').save
end
end

class RedisWidgetUsingDatabaseTwo < RedisWidget

def self.redis
threaded[self.class.to_s] ||= Redis.connect :url => ENV['REDIS_URL_TWO']
end

def self.create!
new(:name => 'a widget using database two').save
end
end
20 changes: 11 additions & 9 deletions features/cleaning.feature
Expand Up @@ -11,12 +11,14 @@ Feature: database cleaning
Then I should see all green

Examples:
| ORM | Strategy |
| ActiveRecord | transaction |
| ActiveRecord | truncation |
| ActiveRecord | deletion |
| DataMapper | transaction |
| DataMapper | truncation |
| MongoMapper | truncation |
| Mongoid | truncation |
| CouchPotato | truncation |
| ORM | Strategy |
| ActiveRecord | transaction |
| ActiveRecord | truncation |
| ActiveRecord | deletion |
| DataMapper | transaction |
| DataMapper | truncation |
| MongoMapper | truncation |
| Mongoid | truncation |
| CouchPotato | truncation |
| Redis | truncation |
| Ohm | truncation |
2 changes: 2 additions & 0 deletions features/cleaning_default_strategy.feature
Expand Up @@ -17,3 +17,5 @@ Feature: database cleaning
| MongoMapper |
| Mongoid |
| CouchPotato |
| Redis |
| Ohm |
19 changes: 19 additions & 0 deletions features/cleaning_multiple_orms.feature
Expand Up @@ -15,15 +15,34 @@ Feature: database cleaning using multiple ORMs
| ActiveRecord | MongoMapper |
| ActiveRecord | Mongoid |
| ActiveRecord | CouchPotato |
| ActiveRecord | Ohm |
| ActiveRecord | Redis |
| DataMapper | ActiveRecord |
| DataMapper | MongoMapper |
| DataMapper | Mongoid |
| DataMapper | CouchPotato |
| DataMapper | Ohm |
| DataMapper | Redis |
| MongoMapper | ActiveRecord |
| MongoMapper | DataMapper |
| MongoMapper | Mongoid |
| MongoMapper | CouchPotato |
| MongoMapper | Ohm |
| MongoMapper | Redis |
| CouchPotato | ActiveRecord |
| CouchPotato | DataMapper |
| CouchPotato | MongoMapper |
| CouchPotato | Mongoid |
| CouchPotato | Ohm |
| CouchPotato | Redis |
| Ohm | ActiveRecord |
| Ohm | DataMapper |
| Ohm | MongoMapper |
| Ohm | Mongoid |
| Ohm | CouchPotato |
| Redis | ActiveRecord |
| Redis | DataMapper |
| Redis | MongoMapper |
| Redis | Mongoid |
| Redis | CouchPotato |
| Redis | Ohm |
5 changes: 3 additions & 2 deletions features/step_definitions/database_cleaner_steps.rb
@@ -1,10 +1,11 @@
orms_pattern = /(ActiveRecord|DataMapper|MongoMapper|Mongoid|CouchPotato|Redis|Ohm)/

Given /^I am using (ActiveRecord|DataMapper|MongoMapper|Mongoid|CouchPotato)$/ do |orm|
Given /^I am using #{orms_pattern}$/ do |orm|
@feature_runner = FeatureRunner.new
@feature_runner.orm = orm
end

Given /^I am using (ActiveRecord|DataMapper|MongoMapper|CouchPotato|Mongoid) and (ActiveRecord|DataMapper|MongoMapper|CouchPotato|Mongoid)$/ do |orm1,orm2|
Given /^I am using #{orms_pattern} and #{orms_pattern}$/ do |orm1,orm2|
@feature_runner = FeatureRunner.new
@feature_runner.orm = orm1
@feature_runner.another_orm = orm2
Expand Down
31 changes: 31 additions & 0 deletions features/step_definitions/ohm_steps.rb
@@ -0,0 +1,31 @@
Given /^I have setup database cleaner to clean multiple databases using ohm$/ do
#DatabaseCleaner
# require "#{File.dirname(__FILE__)}/../../../lib/ohm_models"
#
# DatabaseCleaner[:ohm, {:connection => ENV['REDIS_URL_ONE']} ].strategy = :truncation
# DatabaseCleaner[:ohm, {:connection => ENV['REDIS_URL_TWO']} ].strategy = :truncation
end

When /^I create a widget using ohm$/ do
OhmWidget.create!
end

Then /^I should see ([\d]+) widget using ohm$/ do |widget_count|
OhmWidget.count.should == widget_count.to_i
end

When /^I create a widget in one db using ohm$/ do
OhmWidgetUsingDatabaseOne.create!
end

When /^I create a widget in another db using ohm$/ do
OhmWidgetUsingDatabaseTwo.create!
end

Then /^I should see ([\d]+) widget in one db using ohm$/ do |widget_count|
OhmWidgetUsingDatabaseOne.count.should == widget_count.to_i
end

Then /^I should see ([\d]+) widget in another db using ohm$/ do |widget_count|
OhmWidgetUsingDatabaseTwo.count.should == widget_count.to_i
end
31 changes: 31 additions & 0 deletions features/step_definitions/redis_steps.rb
@@ -0,0 +1,31 @@
Given /^I have setup database cleaner to clean multiple databases using redis$/ do
#DatabaseCleaner
# require "#{File.dirname(__FILE__)}/../../../lib/redis_models"
#
# DatabaseCleaner[:redis, {:connection => ENV['REDIS_URL_ONE']} ].strategy = :truncation
# DatabaseCleaner[:redis, {:connection => ENV['REDIS_URL_TWO']} ].strategy = :truncation
end

When /^I create a widget using redis$/ do
RedisWidget.create!
end

Then /^I should see ([\d]+) widget using redis$/ do |widget_count|
RedisWidget.count.should == widget_count.to_i
end

When /^I create a widget in one db using redis$/ do
RedisWidgetUsingDatabaseOne.create!
end

When /^I create a widget in another db using redis$/ do
RedisWidgetUsingDatabaseTwo.create!
end

Then /^I should see ([\d]+) widget in one db using redis$/ do |widget_count|
RedisWidgetUsingDatabaseOne.count.should == widget_count.to_i
end

Then /^I should see ([\d]+) widget in another db using redis$/ do |widget_count|
RedisWidgetUsingDatabaseTwo.count.should == widget_count.to_i
end

0 comments on commit b70f09a

Please sign in to comment.