database_cleaner 0.5.2 → 0.6.0.rc.1
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/Gemfile.lock +145 -0
- data/History.txt +24 -1
- data/README.textile +48 -0
- data/Rakefile +4 -0
- data/TODO +3 -0
- data/VERSION.yml +3 -2
- data/examples/Gemfile +46 -0
- data/examples/Gemfile.lock +145 -0
- data/examples/config/database.yml +7 -0
- data/examples/config/database.yml.example +8 -0
- data/examples/db/activerecord_one.db +0 -0
- data/examples/db/activerecord_two.db +0 -0
- data/examples/db/datamapper_default.db +0 -0
- data/examples/db/datamapper_one.db +0 -0
- data/examples/db/datamapper_two.db +0 -0
- data/examples/db/sqlite_databases_go_here +0 -0
- data/examples/features/example_multiple_db.feature +23 -0
- data/examples/features/example_multiple_orm.feature +22 -0
- data/examples/features/step_definitions/activerecord_steps.rb +31 -0
- data/examples/features/step_definitions/couchpotato_steps.rb +31 -0
- data/examples/features/step_definitions/datamapper_steps.rb +37 -0
- data/examples/features/step_definitions/mongoid_steps.rb +23 -0
- data/examples/features/step_definitions/mongomapper_steps.rb +31 -0
- data/examples/features/step_definitions/translation_steps.rb +55 -0
- data/examples/features/support/env.rb +49 -10
- data/examples/lib/activerecord_models.rb +34 -5
- data/examples/lib/couchpotato_models.rb +46 -6
- data/examples/lib/datamapper_models.rb +37 -3
- data/examples/lib/mongoid_models.rb +28 -2
- data/examples/lib/mongomapper_models.rb +35 -1
- data/features/cleaning_multiple_dbs.feature +20 -0
- data/features/cleaning_multiple_orms.feature +29 -0
- data/features/step_definitions/database_cleaner_steps.rb +20 -13
- data/features/support/feature_runner.rb +39 -0
- data/lib/database_cleaner/active_record/base.rb +46 -0
- data/lib/database_cleaner/active_record/transaction.rb +10 -10
- data/lib/database_cleaner/active_record/truncation.rb +17 -7
- data/lib/database_cleaner/base.rb +129 -0
- data/lib/database_cleaner/configuration.rb +45 -97
- data/lib/database_cleaner/couch_potato/base.rb +7 -0
- data/lib/database_cleaner/couch_potato/truncation.rb +4 -2
- data/lib/database_cleaner/cucumber.rb +0 -1
- data/lib/database_cleaner/data_mapper/base.rb +21 -0
- data/lib/database_cleaner/data_mapper/transaction.rb +10 -5
- data/lib/database_cleaner/data_mapper/truncation.rb +52 -19
- data/lib/database_cleaner/generic/base.rb +23 -0
- data/lib/database_cleaner/generic/truncation.rb +43 -0
- data/lib/database_cleaner/mongo_mapper/base.rb +20 -0
- data/lib/database_cleaner/mongo_mapper/truncation.rb +9 -3
- data/lib/database_cleaner/mongoid/base.rb +20 -0
- data/lib/database_cleaner/mongoid/truncation.rb +9 -5
- data/spec/database_cleaner/active_record/base_spec.rb +130 -0
- data/spec/database_cleaner/active_record/truncation_spec.rb +19 -18
- data/spec/database_cleaner/base_spec.rb +441 -0
- data/spec/database_cleaner/configuration_spec.rb +255 -68
- data/spec/database_cleaner/couch_potato/truncation_spec.rb +4 -3
- data/spec/database_cleaner/data_mapper/base_spec.rb +30 -0
- data/spec/database_cleaner/data_mapper/transaction_spec.rb +23 -0
- data/spec/database_cleaner/data_mapper/truncation_spec.rb +11 -0
- data/spec/database_cleaner/generic/base_spec.rb +22 -0
- data/spec/database_cleaner/generic/truncation_spec.rb +68 -0
- data/spec/database_cleaner/mongo_mapper/base_spec.rb +33 -0
- data/spec/database_cleaner/mongo_mapper/mongo_examples.rb +8 -0
- data/spec/database_cleaner/mongo_mapper/truncation_spec.rb +11 -18
- data/spec/database_cleaner/shared_strategy_spec.rb +13 -0
- data/spec/rcov.opts +1 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +10 -3
- metadata +76 -8
- data/examples/features/step_definitions/example_steps.rb +0 -8
- data/lib/database_cleaner/truncation_base.rb +0 -41
@@ -1,16 +1,50 @@
|
|
1
1
|
require "dm-core"
|
2
|
+
require "dm-transactions"
|
3
|
+
|
4
|
+
#Datamapper 1.0 requires you to require dm-migrations to automigrate
|
5
|
+
require "dm-migrations"
|
2
6
|
|
3
7
|
# only to please activerecord API used in database_cleaner/examples/features/step_definitions
|
4
8
|
# yes, i know that's lazy ...
|
9
|
+
|
5
10
|
require "dm-validations"
|
6
11
|
require "dm-aggregates"
|
7
12
|
|
8
|
-
DataMapper.setup(:default, "sqlite3
|
13
|
+
DataMapper.setup(:default, "sqlite3:#{DB_DIR}/datamapper_default.db")
|
14
|
+
DataMapper.setup(:one, "sqlite3:#{DB_DIR}/datamapper_one.db")
|
15
|
+
DataMapper.setup(:two, "sqlite3:#{DB_DIR}/datamapper_two.db")
|
16
|
+
|
17
|
+
class DataMapperWidget
|
18
|
+
include DataMapper::Resource
|
19
|
+
|
20
|
+
property :id, Serial
|
21
|
+
property :name, String
|
22
|
+
end
|
9
23
|
|
10
|
-
class
|
24
|
+
class DataMapperWidgetUsingDatabaseOne
|
11
25
|
include DataMapper::Resource
|
26
|
+
|
27
|
+
def self.default_repository_name
|
28
|
+
:one
|
29
|
+
end
|
30
|
+
|
12
31
|
property :id, Serial
|
13
32
|
property :name, String
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
class DataMapperWidgetUsingDatabaseTwo
|
37
|
+
include DataMapper::Resource
|
38
|
+
|
39
|
+
def self.default_repository_name
|
40
|
+
:two
|
41
|
+
end
|
42
|
+
|
43
|
+
property :id, Serial
|
44
|
+
property :name, String
|
45
|
+
|
14
46
|
end
|
15
47
|
|
16
|
-
|
48
|
+
DataMapperWidget.auto_migrate!
|
49
|
+
DataMapperWidgetUsingDatabaseOne.auto_migrate!
|
50
|
+
DataMapperWidgetUsingDatabaseTwo.auto_migrate!
|
@@ -9,15 +9,41 @@ end
|
|
9
9
|
#::MongoMapper.connection = Mongo::Connection.new('127.0.0.1')
|
10
10
|
#::MongoMapper.database = 'database_cleaner_test'
|
11
11
|
|
12
|
-
class
|
12
|
+
class MongoidWidget
|
13
13
|
include Mongoid::Document
|
14
14
|
field :id, :type => Integer
|
15
15
|
field :name
|
16
16
|
|
17
17
|
class << self
|
18
|
-
#
|
18
|
+
#mongoid doesn't seem to provide this...
|
19
19
|
def create!(*args)
|
20
20
|
new(*args).save!
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
24
|
+
|
25
|
+
class MongoidWidgetUsingDatabaseOne
|
26
|
+
include Mongoid::Document
|
27
|
+
field :id, :type => Integer
|
28
|
+
field :name
|
29
|
+
|
30
|
+
class << self
|
31
|
+
#mongoid doesn't seem to provide this...
|
32
|
+
def create!(*args)
|
33
|
+
new(*args).save!
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class MongoidWidgetUsingDatabaseTwo
|
39
|
+
include Mongoid::Document
|
40
|
+
field :id, :type => Integer
|
41
|
+
field :name
|
42
|
+
|
43
|
+
class << self
|
44
|
+
#mongoid doesn't seem to provide this...
|
45
|
+
def create!(*args)
|
46
|
+
new(*args).save!
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -3,7 +3,7 @@ require 'mongo_mapper'
|
|
3
3
|
::MongoMapper.connection = Mongo::Connection.new('127.0.0.1')
|
4
4
|
::MongoMapper.database = 'database_cleaner_test'
|
5
5
|
|
6
|
-
class
|
6
|
+
class MongoMapperWidget
|
7
7
|
include MongoMapper::Document
|
8
8
|
key :id, Integer
|
9
9
|
key :name, String
|
@@ -15,3 +15,37 @@ class Widget
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
18
|
+
|
19
|
+
class MongoMapperWidgetUsingDatabaseOne
|
20
|
+
include MongoMapper::Document
|
21
|
+
|
22
|
+
connection = Mongo::Connection.new('127.0.0.1')
|
23
|
+
set_database_name = 'database_cleaner_test_one'
|
24
|
+
|
25
|
+
key :id, Integer
|
26
|
+
key :name, String
|
27
|
+
|
28
|
+
class << self
|
29
|
+
#mongomapper doesn't seem to provide this...
|
30
|
+
def create!(*args)
|
31
|
+
new(*args).save!
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class MongoMapperWidgetUsingDatabaseTwo
|
37
|
+
include MongoMapper::Document
|
38
|
+
|
39
|
+
connection = Mongo::Connection.new('127.0.0.1')
|
40
|
+
set_database_name = 'database_cleaner_test_two'
|
41
|
+
|
42
|
+
key :id, Integer
|
43
|
+
key :name, String
|
44
|
+
|
45
|
+
class << self
|
46
|
+
#mongomapper doesn't seem to provide this...
|
47
|
+
def create!(*args)
|
48
|
+
new(*args).save!
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Feature: multiple database cleaning
|
2
|
+
In order to ease example and feature writing
|
3
|
+
As a developer
|
4
|
+
I want to have my databases 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 clean databases
|
11
|
+
Then I should see all green
|
12
|
+
|
13
|
+
Examples:
|
14
|
+
| ORM | Strategy |
|
15
|
+
| ActiveRecord | truncation |
|
16
|
+
| DataMapper | truncation |
|
17
|
+
| MongoMapper | truncation |
|
18
|
+
| DataMapper | transaction |
|
19
|
+
# Not working...
|
20
|
+
#| ActiveRecord | transaction |
|
@@ -0,0 +1,29 @@
|
|
1
|
+
Feature: database cleaning using multiple ORMs
|
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 <ORM1> and <ORM2>
|
8
|
+
|
9
|
+
When I run my scenarios that rely on clean databases using multiple orms
|
10
|
+
Then I should see all green
|
11
|
+
|
12
|
+
Examples:
|
13
|
+
| ORM1 | ORM2 |
|
14
|
+
| ActiveRecord | DataMapper |
|
15
|
+
| ActiveRecord | MongoMapper |
|
16
|
+
| ActiveRecord | Mongoid |
|
17
|
+
| ActiveRecord | CouchPotato |
|
18
|
+
| DataMapper | ActiveRecord |
|
19
|
+
| DataMapper | MongoMapper |
|
20
|
+
| DataMapper | Mongoid |
|
21
|
+
| DataMapper | CouchPotato |
|
22
|
+
| MongoMapper | ActiveRecord |
|
23
|
+
| MongoMapper | DataMapper |
|
24
|
+
| MongoMapper | Mongoid |
|
25
|
+
| MongoMapper | CouchPotato |
|
26
|
+
| CouchPotato | ActiveRecord |
|
27
|
+
| CouchPotato | DataMapper |
|
28
|
+
| CouchPotato | MongoMapper |
|
29
|
+
| CouchPotato | Mongoid |
|
@@ -1,25 +1,32 @@
|
|
1
|
+
|
1
2
|
Given /^I am using (ActiveRecord|DataMapper|MongoMapper|Mongoid|CouchPotato)$/ do |orm|
|
2
|
-
@
|
3
|
+
@feature_runner = FeatureRunner.new
|
4
|
+
@feature_runner.orm = orm
|
5
|
+
end
|
6
|
+
|
7
|
+
Given /^I am using (ActiveRecord|DataMapper|MongoMapper|CouchPotato|Mongoid) and (ActiveRecord|DataMapper|MongoMapper|CouchPotato|Mongoid)$/ do |orm1,orm2|
|
8
|
+
@feature_runner = FeatureRunner.new
|
9
|
+
@feature_runner.orm = orm1
|
10
|
+
@feature_runner.another_orm = orm2
|
3
11
|
end
|
4
12
|
|
5
13
|
Given /^the (.+) cleaning strategy$/ do |strategy|
|
6
|
-
@strategy = strategy
|
14
|
+
@feature_runner.strategy = strategy
|
7
15
|
end
|
8
16
|
|
9
17
|
When "I run my scenarios that rely on a clean database" do
|
10
|
-
|
11
|
-
Dir.chdir(full_dir) do
|
12
|
-
ENV['ORM'] = @orm.downcase
|
13
|
-
ENV['STRATEGY'] = @strategy
|
14
|
-
@out = `#{"jruby -S " if defined?(JRUBY_VERSION)}cucumber features`
|
15
|
-
@status = $?.exitstatus
|
16
|
-
end
|
18
|
+
@feature_runner.go 'example'
|
17
19
|
end
|
18
20
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
end
|
21
|
+
When "I run my scenarios that rely on clean databases" do
|
22
|
+
@feature_runner.multiple_databases = true
|
23
|
+
@feature_runner.go 'example_multiple_db'
|
23
24
|
end
|
24
25
|
|
26
|
+
When "I run my scenarios that rely on clean databases using multiple orms" do
|
27
|
+
@feature_runner.go 'example_multiple_orm'
|
28
|
+
end
|
25
29
|
|
30
|
+
Then "I should see all green" do
|
31
|
+
fail "Feature failed with :#{@feature_runner.output}" unless @feature_runner.exit_status == 0
|
32
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
class FeatureRunner
|
2
|
+
attr_accessor :orm
|
3
|
+
attr_accessor :another_orm
|
4
|
+
attr_accessor :multiple_databases
|
5
|
+
attr_accessor :strategy
|
6
|
+
attr_accessor :exit_status
|
7
|
+
attr_accessor :output
|
8
|
+
|
9
|
+
def strategy
|
10
|
+
@strategy || 'truncation'
|
11
|
+
end
|
12
|
+
|
13
|
+
def go(feature)
|
14
|
+
full_dir ||= File.expand_path(File.dirname(__FILE__) + "/../../examples/")
|
15
|
+
Dir.chdir(full_dir) do
|
16
|
+
|
17
|
+
|
18
|
+
ENV['ORM'] = orm
|
19
|
+
ENV['STRATEGY'] = strategy
|
20
|
+
|
21
|
+
if another_orm
|
22
|
+
ENV['ANOTHER_ORM'] = another_orm
|
23
|
+
else
|
24
|
+
ENV['ANOTHER_ORM'] = nil
|
25
|
+
end
|
26
|
+
|
27
|
+
if multiple_databases
|
28
|
+
ENV['MULTIPLE_DBS'] = "true"
|
29
|
+
else
|
30
|
+
ENV['MULTIPLE_DBS'] = nil
|
31
|
+
end
|
32
|
+
|
33
|
+
self.output = `#{"jruby -S " if defined?(JRUBY_VERSION)}cucumber features/#{feature}.feature`
|
34
|
+
|
35
|
+
self.exit_status = $?.exitstatus
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'database_cleaner/generic/base'
|
2
|
+
require 'active_record'
|
3
|
+
|
4
|
+
module DatabaseCleaner
|
5
|
+
module ActiveRecord
|
6
|
+
|
7
|
+
def self.available_strategies
|
8
|
+
%w[truncation transaction]
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.config_file_location
|
12
|
+
"#{DatabaseCleaner.app_root}/config/database.yml"
|
13
|
+
end
|
14
|
+
|
15
|
+
module Base
|
16
|
+
include ::DatabaseCleaner::Generic::Base
|
17
|
+
|
18
|
+
attr_accessor :connection_hash
|
19
|
+
|
20
|
+
def db=(desired_db)
|
21
|
+
@db = desired_db
|
22
|
+
load_config
|
23
|
+
end
|
24
|
+
|
25
|
+
def db
|
26
|
+
@db || super
|
27
|
+
end
|
28
|
+
|
29
|
+
def load_config
|
30
|
+
connection_details = YAML::load(ERB.new(IO.read(ActiveRecord.config_file_location)).result)
|
31
|
+
self.connection_hash = connection_details[self.db.to_s]
|
32
|
+
end
|
33
|
+
|
34
|
+
def create_connection_klass
|
35
|
+
Class.new(::ActiveRecord::Base)
|
36
|
+
end
|
37
|
+
|
38
|
+
def connection_klass
|
39
|
+
return ::ActiveRecord::Base if connection_hash.nil?
|
40
|
+
klass = create_connection_klass
|
41
|
+
klass.send :establish_connection, connection_hash
|
42
|
+
klass
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -1,26 +1,26 @@
|
|
1
|
+
require 'database_cleaner/active_record/base'
|
1
2
|
module DatabaseCleaner::ActiveRecord
|
2
3
|
class Transaction
|
4
|
+
include ::DatabaseCleaner::ActiveRecord::Base
|
3
5
|
|
4
6
|
def start
|
5
|
-
if
|
6
|
-
|
7
|
+
if connection_klass.connection.respond_to?(:increment_open_transactions)
|
8
|
+
connection_klass.connection.increment_open_transactions
|
7
9
|
else
|
8
|
-
|
10
|
+
connection_klass.__send__(:increment_open_transactions)
|
9
11
|
end
|
10
|
-
|
11
|
-
ActiveRecord::Base.connection.begin_db_transaction
|
12
|
+
connection_klass.connection.begin_db_transaction
|
12
13
|
end
|
13
14
|
|
14
15
|
|
15
16
|
def clean
|
16
|
-
|
17
|
+
connection_klass.connection.rollback_db_transaction
|
17
18
|
|
18
|
-
if
|
19
|
-
|
19
|
+
if connection_klass.connection.respond_to?(:decrement_open_transactions)
|
20
|
+
connection_klass.connection.decrement_open_transactions
|
20
21
|
else
|
21
|
-
|
22
|
+
connection_klass.__send__(:decrement_open_transactions)
|
22
23
|
end
|
23
24
|
end
|
24
25
|
end
|
25
|
-
|
26
26
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'active_record/base'
|
2
2
|
require 'active_record/connection_adapters/abstract_adapter'
|
3
|
-
require "database_cleaner/
|
3
|
+
require "database_cleaner/generic/truncation"
|
4
|
+
require 'database_cleaner/active_record/base'
|
4
5
|
|
5
6
|
module ActiveRecord
|
6
7
|
module ConnectionAdapters
|
@@ -17,6 +18,12 @@ module ActiveRecord
|
|
17
18
|
end
|
18
19
|
end
|
19
20
|
|
21
|
+
class Mysql2Adapter < AbstractAdapter
|
22
|
+
def truncate_table(table_name)
|
23
|
+
execute("TRUNCATE TABLE #{quote_table_name(table_name)};")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
20
27
|
class SQLite3Adapter < SQLiteAdapter
|
21
28
|
def truncate_table(table_name)
|
22
29
|
execute("DELETE FROM #{quote_table_name(table_name)};")
|
@@ -36,9 +43,9 @@ module ActiveRecord
|
|
36
43
|
class PostgreSQLAdapter < AbstractAdapter
|
37
44
|
|
38
45
|
def self.db_version
|
39
|
-
@db_version ||=
|
40
|
-
"SELECT CHARACTER_VALUE
|
41
|
-
FROM INFORMATION_SCHEMA.SQL_IMPLEMENTATION_INFO
|
46
|
+
@db_version ||= connection.select_values(
|
47
|
+
"SELECT CHARACTER_VALUE
|
48
|
+
FROM INFORMATION_SCHEMA.SQL_IMPLEMENTATION_INFO
|
42
49
|
WHERE IMPLEMENTATION_INFO_NAME = 'DBMS VERSION' ").to_s
|
43
50
|
end
|
44
51
|
|
@@ -69,7 +76,9 @@ end
|
|
69
76
|
|
70
77
|
|
71
78
|
module DatabaseCleaner::ActiveRecord
|
72
|
-
class Truncation
|
79
|
+
class Truncation
|
80
|
+
include ::DatabaseCleaner::ActiveRecord::Base
|
81
|
+
include ::DatabaseCleaner::Generic::Truncation
|
73
82
|
|
74
83
|
def clean
|
75
84
|
connection.disable_referential_integrity do
|
@@ -82,11 +91,12 @@ module DatabaseCleaner::ActiveRecord
|
|
82
91
|
private
|
83
92
|
|
84
93
|
def tables_to_truncate
|
85
|
-
|
94
|
+
(@only || connection.tables) - @tables_to_exclude
|
86
95
|
end
|
87
96
|
|
88
97
|
def connection
|
89
|
-
|
98
|
+
#::ActiveRecord::Base.connection
|
99
|
+
connection_klass.connection
|
90
100
|
end
|
91
101
|
|
92
102
|
# overwritten
|
@@ -0,0 +1,129 @@
|
|
1
|
+
module DatabaseCleaner
|
2
|
+
class Base
|
3
|
+
|
4
|
+
def initialize(desired_orm = nil,opts = {})
|
5
|
+
if desired_orm == :autodetect || desired_orm.nil?
|
6
|
+
autodetect
|
7
|
+
else
|
8
|
+
self.orm = desired_orm
|
9
|
+
end
|
10
|
+
self.db = opts[:connection] if opts.has_key? :connection
|
11
|
+
end
|
12
|
+
|
13
|
+
def db=(desired_db)
|
14
|
+
self.strategy_db = desired_db
|
15
|
+
@db = desired_db
|
16
|
+
end
|
17
|
+
|
18
|
+
def strategy_db=(desired_db)
|
19
|
+
if strategy.respond_to? :db=
|
20
|
+
strategy.db = desired_db
|
21
|
+
elsif desired_db!= :default
|
22
|
+
raise ArgumentError, "You must provide a strategy object that supports non default databases when you specify a database"
|
23
|
+
end
|
24
|
+
rescue NoStrategySetError
|
25
|
+
#handle NoStrategySetError by doing nothing at all
|
26
|
+
desired_db
|
27
|
+
end
|
28
|
+
|
29
|
+
def db
|
30
|
+
@db || :default
|
31
|
+
end
|
32
|
+
|
33
|
+
def create_strategy(*args)
|
34
|
+
strategy, *strategy_args = args
|
35
|
+
orm_strategy(strategy).new(*strategy_args)
|
36
|
+
end
|
37
|
+
|
38
|
+
def clean_with(*args)
|
39
|
+
strategy = create_strategy(*args)
|
40
|
+
strategy.clean
|
41
|
+
strategy
|
42
|
+
end
|
43
|
+
|
44
|
+
alias clean_with! clean_with
|
45
|
+
|
46
|
+
def strategy=(args)
|
47
|
+
strategy, *strategy_args = args
|
48
|
+
if strategy.is_a?(Symbol)
|
49
|
+
@strategy = create_strategy(*args)
|
50
|
+
elsif strategy_args.empty?
|
51
|
+
@strategy = strategy
|
52
|
+
else
|
53
|
+
raise ArgumentError, "You must provide a strategy object, or a symbol for a known strategy along with initialization params."
|
54
|
+
end
|
55
|
+
|
56
|
+
self.strategy_db = self.db
|
57
|
+
|
58
|
+
@strategy
|
59
|
+
end
|
60
|
+
|
61
|
+
def strategy
|
62
|
+
return @strategy if @strategy
|
63
|
+
raise NoStrategySetError, "Please set a strategy with DatabaseCleaner.strategy=."
|
64
|
+
end
|
65
|
+
|
66
|
+
def orm=(desired_orm)
|
67
|
+
@orm = desired_orm
|
68
|
+
end
|
69
|
+
|
70
|
+
def orm
|
71
|
+
@orm || autodetect
|
72
|
+
end
|
73
|
+
|
74
|
+
def start
|
75
|
+
strategy.start
|
76
|
+
end
|
77
|
+
|
78
|
+
def clean
|
79
|
+
strategy.clean
|
80
|
+
end
|
81
|
+
|
82
|
+
alias clean! clean
|
83
|
+
|
84
|
+
def auto_detected?
|
85
|
+
return true unless @autodetected.nil?
|
86
|
+
end
|
87
|
+
|
88
|
+
#TODO make strategies directly comparable
|
89
|
+
def ==(other)
|
90
|
+
self.orm == other.orm && self.db == other.db && self.strategy.class == other.strategy.class
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
def orm_module
|
96
|
+
::DatabaseCleaner.orm_module(orm)
|
97
|
+
end
|
98
|
+
|
99
|
+
def orm_strategy(strategy)
|
100
|
+
require "database_cleaner/#{orm.to_s}/#{strategy.to_s}"
|
101
|
+
orm_module.const_get(strategy.to_s.capitalize)
|
102
|
+
rescue LoadError => e
|
103
|
+
if orm_module.respond_to? :available_strategies
|
104
|
+
raise UnknownStrategySpecified, "The '#{strategy}' strategy does not exist for the #{orm} ORM! Available strategies: #{orm_module.available_strategies.join(', ')}"
|
105
|
+
else
|
106
|
+
raise UnknownStrategySpecified, "The '#{strategy}' strategy does not exist for the #{orm} ORM!"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def autodetect
|
111
|
+
@orm ||= begin
|
112
|
+
@autodetected = true
|
113
|
+
if defined? ::ActiveRecord
|
114
|
+
:active_record
|
115
|
+
elsif defined? ::DataMapper
|
116
|
+
:data_mapper
|
117
|
+
elsif defined? ::MongoMapper
|
118
|
+
:mongo_mapper
|
119
|
+
elsif defined? ::Mongoid
|
120
|
+
:mongoid
|
121
|
+
elsif defined? ::CouchPotato
|
122
|
+
:couch_potato
|
123
|
+
else
|
124
|
+
raise NoORMDetected, "No known ORM was detected! Is ActiveRecord, DataMapper, MongoMapper, Mongoid, or CouchPotato loaded?"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|