database_cleaner 0.9.1 → 1.0.0.RC1
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 +127 -136
- data/History.txt +19 -1
- data/README.markdown +335 -0
- data/VERSION.yml +5 -5
- data/examples/Gemfile +18 -9
- data/examples/Gemfile.lock +127 -136
- data/examples/features/support/env.rb +3 -12
- data/lib/database_cleaner/active_record/base.rb +9 -9
- data/lib/database_cleaner/active_record/deletion.rb +5 -48
- data/lib/database_cleaner/active_record/transaction.rb +31 -9
- data/lib/database_cleaner/active_record/truncation.rb +23 -6
- data/lib/database_cleaner/data_mapper/truncation.rb +6 -2
- data/lib/database_cleaner/sequel/truncation.rb +1 -1
- data/spec/database_cleaner/active_record/base_spec.rb +32 -11
- data/spec/database_cleaner/active_record/transaction_spec.rb +101 -42
- data/spec/database_cleaner/active_record/truncation_spec.rb +1 -1
- metadata +28 -331
- data/README.textile +0 -247
@@ -32,9 +32,9 @@ module DatabaseCleaner
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def load_config
|
35
|
-
if self.db != :default && File.file?(ActiveRecord.config_file_location)
|
36
|
-
connection_details
|
37
|
-
@connection_hash
|
35
|
+
if self.db != :default && self.db.is_a?(Symbol) && File.file?(ActiveRecord.config_file_location)
|
36
|
+
connection_details = YAML::load(ERB.new(IO.read(ActiveRecord.config_file_location)).result)
|
37
|
+
@connection_hash = connection_details[self.db.to_s]
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
@@ -43,12 +43,12 @@ module DatabaseCleaner
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def connection_class
|
46
|
-
@connection_class ||= if @db
|
47
|
-
|
46
|
+
@connection_class ||= if @db && !@db.is_a?(Symbol)
|
47
|
+
@db
|
48
48
|
elsif connection_hash
|
49
49
|
lookup_from_connection_pool || establish_connection
|
50
50
|
else
|
51
|
-
|
51
|
+
::ActiveRecord::Base
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
@@ -57,8 +57,8 @@ module DatabaseCleaner
|
|
57
57
|
def lookup_from_connection_pool
|
58
58
|
if ::ActiveRecord::Base.respond_to?(:descendants)
|
59
59
|
database_name = connection_hash["database"] || connection_hash[:database]
|
60
|
-
models
|
61
|
-
models.detect {|m| m.connection_pool.spec.config[:database] == database_name}
|
60
|
+
models = ::ActiveRecord::Base.descendants
|
61
|
+
models.detect { |m| m.connection_pool.spec.config[:database] == database_name }
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
@@ -67,7 +67,7 @@ module DatabaseCleaner
|
|
67
67
|
strategy_class.send :establish_connection, connection_hash
|
68
68
|
strategy_class
|
69
69
|
end
|
70
|
-
|
70
|
+
|
71
71
|
end
|
72
72
|
end
|
73
73
|
end
|
@@ -3,51 +3,6 @@ require 'active_record/connection_adapters/abstract_adapter'
|
|
3
3
|
require "database_cleaner/generic/truncation"
|
4
4
|
require 'database_cleaner/active_record/base'
|
5
5
|
require 'database_cleaner/active_record/truncation'
|
6
|
-
# This file may seem to have duplication with that of truncation, but by keeping them separate
|
7
|
-
# we avoiding loading this code when it is not being used (which is the common case).
|
8
|
-
|
9
|
-
module ActiveRecord
|
10
|
-
module ConnectionAdapters
|
11
|
-
|
12
|
-
class MysqlAdapter < MYSQL_ADAPTER_PARENT
|
13
|
-
def delete_table(table_name)
|
14
|
-
execute("DELETE FROM #{quote_table_name(table_name)};")
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
class Mysql2Adapter < MYSQL2_ADAPTER_PARENT
|
19
|
-
def delete_table(table_name)
|
20
|
-
execute("DELETE FROM #{quote_table_name(table_name)};")
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
class JdbcAdapter < AbstractAdapter
|
25
|
-
def delete_table(table_name)
|
26
|
-
execute("DELETE FROM #{quote_table_name(table_name)};")
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
class PostgreSQLAdapter < POSTGRE_ADAPTER_PARENT
|
31
|
-
def delete_table(table_name)
|
32
|
-
execute("DELETE FROM #{quote_table_name(table_name)};")
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
class SQLServerAdapter < AbstractAdapter
|
37
|
-
def delete_table(table_name)
|
38
|
-
execute("DELETE FROM #{quote_table_name(table_name)};")
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
class OracleEnhancedAdapter < AbstractAdapter
|
43
|
-
def delete_table(table_name)
|
44
|
-
execute("DELETE FROM #{quote_table_name(table_name)}")
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
6
|
|
52
7
|
module DatabaseCleaner::ActiveRecord
|
53
8
|
class Deletion < Truncation
|
@@ -55,9 +10,11 @@ module DatabaseCleaner::ActiveRecord
|
|
55
10
|
def clean
|
56
11
|
connection = connection_class.connection
|
57
12
|
connection.disable_referential_integrity do
|
58
|
-
tables_to_truncate(connection).
|
59
|
-
connection.
|
60
|
-
end
|
13
|
+
sql = tables_to_truncate(connection).map do |table_name|
|
14
|
+
"DELETE FROM #{connection.quote_table_name(table_name)}"
|
15
|
+
end.join(";")
|
16
|
+
|
17
|
+
connection.execute sql
|
61
18
|
end
|
62
19
|
end
|
63
20
|
|
@@ -7,25 +7,47 @@ module DatabaseCleaner::ActiveRecord
|
|
7
7
|
include ::DatabaseCleaner::Generic::Transaction
|
8
8
|
|
9
9
|
def start
|
10
|
-
if
|
11
|
-
connection_class.connection.increment_open_transactions
|
10
|
+
if connection_maintains_transaction_count?
|
11
|
+
if connection_class.connection.respond_to?(:increment_open_transactions)
|
12
|
+
connection_class.connection.increment_open_transactions
|
13
|
+
else
|
14
|
+
connection_class.__send__(:increment_open_transactions)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
if connection_class.connection.respond_to?(:begin_transaction)
|
18
|
+
connection_class.connection.begin_transaction
|
12
19
|
else
|
13
|
-
connection_class.
|
20
|
+
connection_class.connection.begin_db_transaction
|
14
21
|
end
|
15
|
-
connection_class.connection.begin_db_transaction
|
16
22
|
end
|
17
23
|
|
18
24
|
|
19
25
|
def clean
|
20
26
|
return unless connection_class.connection.open_transactions > 0
|
21
27
|
|
22
|
-
connection_class.connection.
|
23
|
-
|
24
|
-
if connection_class.connection.respond_to?(:decrement_open_transactions)
|
25
|
-
connection_class.connection.decrement_open_transactions
|
28
|
+
if connection_class.connection.respond_to?(:rollback_transaction)
|
29
|
+
connection_class.connection.rollback_transaction
|
26
30
|
else
|
27
|
-
connection_class.
|
31
|
+
connection_class.connection.rollback_db_transaction
|
28
32
|
end
|
33
|
+
|
34
|
+
# The below is for handling after_commit hooks.. see https://github.com/bmabey/database_cleaner/issues/99
|
35
|
+
if connection_class.connection.respond_to?(:rollback_transaction_records)
|
36
|
+
connection_class.connection.send(:rollback_transaction_records, true)
|
37
|
+
end
|
38
|
+
|
39
|
+
if connection_maintains_transaction_count?
|
40
|
+
if connection_class.connection.respond_to?(:decrement_open_transactions)
|
41
|
+
connection_class.connection.decrement_open_transactions
|
42
|
+
else
|
43
|
+
connection_class.__send__(:decrement_open_transactions)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def connection_maintains_transaction_count?
|
49
|
+
ActiveRecord::VERSION::MAJOR < 4
|
29
50
|
end
|
51
|
+
|
30
52
|
end
|
31
53
|
end
|
@@ -55,7 +55,9 @@ module DatabaseCleaner
|
|
55
55
|
|
56
56
|
|
57
57
|
def row_count(table)
|
58
|
-
|
58
|
+
# Patch for MysqlAdapter with ActiveRecord 3.2.7 later
|
59
|
+
# select_value("SELECT 1") #=> "1"
|
60
|
+
select_value("SELECT EXISTS (SELECT 1 FROM #{quote_table_name(table)} LIMIT 1)").to_i
|
59
61
|
end
|
60
62
|
|
61
63
|
# Returns a boolean indicating if the given table has an auto-inc number higher than 0.
|
@@ -66,7 +68,9 @@ module DatabaseCleaner
|
|
66
68
|
if row_count(table) > 0
|
67
69
|
true
|
68
70
|
else
|
69
|
-
|
71
|
+
# Patch for MysqlAdapter with ActiveRecord 3.2.7 later
|
72
|
+
# select_value("SELECT 1") #=> "1"
|
73
|
+
select_value(<<-SQL).to_i > 1 # returns nil if not present
|
70
74
|
SELECT Auto_increment
|
71
75
|
FROM information_schema.tables
|
72
76
|
WHERE table_name='#{table}';
|
@@ -90,9 +94,18 @@ module DatabaseCleaner
|
|
90
94
|
module SQLiteAdapter
|
91
95
|
def delete_table(table_name)
|
92
96
|
execute("DELETE FROM #{quote_table_name(table_name)};")
|
93
|
-
|
97
|
+
if uses_sequence
|
98
|
+
execute("DELETE FROM sqlite_sequence where name = '#{table_name}';")
|
99
|
+
end
|
94
100
|
end
|
95
101
|
alias truncate_table delete_table
|
102
|
+
|
103
|
+
private
|
104
|
+
|
105
|
+
# Returns a boolean indicating if the SQLite database is using the sqlite_sequence table.
|
106
|
+
def uses_sequence
|
107
|
+
select_value("SELECT name FROM sqlite_master WHERE type='table' AND name='sqlite_sequence';")
|
108
|
+
end
|
96
109
|
end
|
97
110
|
|
98
111
|
module TruncateOrDelete
|
@@ -139,8 +152,8 @@ module DatabaseCleaner
|
|
139
152
|
# but then the table is cleaned. In other words, this function tells us if the given table
|
140
153
|
# was ever inserted into.
|
141
154
|
def has_been_used?(table)
|
142
|
-
cur_val = select_value("SELECT currval('#{table}_id_seq');").to_i rescue
|
143
|
-
cur_val
|
155
|
+
cur_val = select_value("SELECT currval('#{table}_id_seq');").to_i rescue 0
|
156
|
+
cur_val > 0
|
144
157
|
end
|
145
158
|
|
146
159
|
def has_rows?(table)
|
@@ -182,7 +195,11 @@ module ActiveRecord
|
|
182
195
|
MYSQL2_ADAPTER_PARENT = AbstractAdapter
|
183
196
|
end
|
184
197
|
|
185
|
-
|
198
|
+
if defined?(SQLite3Adapter) && SQLite3Adapter.superclass == ActiveRecord::ConnectionAdapters::AbstractAdapter
|
199
|
+
SQLITE_ADAPTER_PARENT = USE_ARJDBC_WORKAROUND ? JdbcAdapter : AbstractAdapter
|
200
|
+
else
|
201
|
+
SQLITE_ADAPTER_PARENT = USE_ARJDBC_WORKAROUND ? JdbcAdapter : SQLiteAdapter
|
202
|
+
end
|
186
203
|
POSTGRE_ADAPTER_PARENT = USE_ARJDBC_WORKAROUND ? JdbcAdapter : AbstractAdapter
|
187
204
|
|
188
205
|
class MysqlAdapter < MYSQL_ADAPTER_PARENT
|
@@ -53,7 +53,9 @@ module DataMapper
|
|
53
53
|
|
54
54
|
def truncate_table(table_name)
|
55
55
|
execute("DELETE FROM #{quote_name(table_name)};")
|
56
|
-
|
56
|
+
if uses_sequence
|
57
|
+
execute("DELETE FROM sqlite_sequence where name = '#{table_name}';")
|
58
|
+
end
|
57
59
|
end
|
58
60
|
|
59
61
|
# this is a no-op copied from activerecord
|
@@ -80,7 +82,9 @@ module DataMapper
|
|
80
82
|
|
81
83
|
def truncate_table(table_name)
|
82
84
|
execute("DELETE FROM #{quote_name(table_name)};")
|
83
|
-
|
85
|
+
if uses_sequence
|
86
|
+
execute("DELETE FROM sqlite_sequence where name = '#{table_name}';")
|
87
|
+
end
|
84
88
|
end
|
85
89
|
|
86
90
|
# this is a no-op copied from activerecord
|
@@ -62,7 +62,7 @@ module DatabaseCleaner
|
|
62
62
|
|
63
63
|
before do
|
64
64
|
subject.db = :my_db
|
65
|
-
yaml
|
65
|
+
yaml = <<-Y
|
66
66
|
my_db:
|
67
67
|
database: <%= "ONE".downcase %>
|
68
68
|
Y
|
@@ -71,7 +71,7 @@ my_db:
|
|
71
71
|
end
|
72
72
|
|
73
73
|
it "should parse the config" do
|
74
|
-
YAML.should_receive(:load).and_return(
|
74
|
+
YAML.should_receive(:load).and_return({ :nil => nil })
|
75
75
|
subject.load_config
|
76
76
|
end
|
77
77
|
|
@@ -80,19 +80,26 @@ my_db:
|
|
80
80
|
my_db:
|
81
81
|
database: one
|
82
82
|
Y
|
83
|
-
YAML.should_receive(:load).with(transformed).and_return({ "my_db" => {"database" => "one"} })
|
83
|
+
YAML.should_receive(:load).with(transformed).and_return({ "my_db" => { "database" => "one" } })
|
84
84
|
subject.load_config
|
85
85
|
end
|
86
86
|
|
87
87
|
it "should store the relevant config in connection_hash" do
|
88
88
|
subject.load_config
|
89
|
-
subject.connection_hash.should == {"database" => "one"}
|
89
|
+
subject.connection_hash.should == { "database" => "one" }
|
90
90
|
end
|
91
91
|
|
92
92
|
it "should skip config if config file is not available" do
|
93
93
|
File.should_receive(:file?).with(config_location).and_return(false)
|
94
94
|
subject.load_config
|
95
|
-
subject.connection_hash.
|
95
|
+
subject.connection_hash.should_not be
|
96
|
+
end
|
97
|
+
|
98
|
+
it "skips the file when the model is set" do
|
99
|
+
subject.db = FakeModel
|
100
|
+
YAML.should_not_receive(:load)
|
101
|
+
subject.load_config
|
102
|
+
subject.connection_hash.should_not be
|
96
103
|
end
|
97
104
|
|
98
105
|
it "skips the file when the db is set to :default" do
|
@@ -100,6 +107,7 @@ my_db:
|
|
100
107
|
subject.db = :default
|
101
108
|
YAML.should_not_receive(:load)
|
102
109
|
subject.load_config
|
110
|
+
subject.connection_hash.should_not be
|
103
111
|
end
|
104
112
|
|
105
113
|
end
|
@@ -122,19 +130,32 @@ my_db:
|
|
122
130
|
end
|
123
131
|
|
124
132
|
describe "connection_class" do
|
125
|
-
it { expect{ subject.connection_class }.to_not raise_error }
|
133
|
+
it { expect { subject.connection_class }.to_not raise_error }
|
126
134
|
it "should default to ActiveRecord::Base" do
|
127
135
|
subject.connection_class.should == ::ActiveRecord::Base
|
128
136
|
end
|
129
137
|
|
130
|
-
|
131
|
-
|
132
|
-
|
138
|
+
context "with database models" do
|
139
|
+
context "connection_hash is set" do
|
140
|
+
it "allows for database models to be passed in" do
|
141
|
+
subject.db = FakeModel
|
142
|
+
subject.connection_hash = { }
|
143
|
+
subject.load_config
|
144
|
+
subject.connection_class.should == FakeModel
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
context "connection_hash is not set" do
|
149
|
+
it "allows for database models to be passed in" do
|
150
|
+
subject.db = FakeModel
|
151
|
+
subject.connection_class.should == FakeModel
|
152
|
+
end
|
153
|
+
end
|
133
154
|
end
|
134
155
|
|
135
156
|
context "when connection_hash is set" do
|
136
157
|
let(:hash) { mock("hash") }
|
137
|
-
before { ::ActiveRecord::Base.stub!(:respond_to?).and_return(false)}
|
158
|
+
before { ::ActiveRecord::Base.stub!(:respond_to?).and_return(false) }
|
138
159
|
before { subject.stub(:connection_hash).and_return(hash) }
|
139
160
|
|
140
161
|
it "should create connection_class if it doesnt exist if connection_hash is set" do
|
@@ -142,7 +163,7 @@ my_db:
|
|
142
163
|
subject.connection_class
|
143
164
|
end
|
144
165
|
|
145
|
-
it
|
166
|
+
it "should configure the class from create_connection_class if connection_hash is set" do
|
146
167
|
strategy_class = mock('strategy_class')
|
147
168
|
strategy_class.should_receive(:establish_connection).with(hash)
|
148
169
|
|
@@ -8,70 +8,129 @@ module DatabaseCleaner
|
|
8
8
|
describe Transaction do
|
9
9
|
let (:connection) { mock("connection") }
|
10
10
|
before(:each) do
|
11
|
-
::ActiveRecord::Base.stub
|
11
|
+
::ActiveRecord::Base.stub(:connection).and_return(connection)
|
12
12
|
end
|
13
13
|
|
14
14
|
describe "#start" do
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
15
|
+
[:begin_transaction, :begin_db_transaction].each do |begin_transaction_method|
|
16
|
+
context "using #{begin_transaction_method}" do
|
17
|
+
before do
|
18
|
+
connection.stub(begin_transaction_method)
|
19
|
+
connection.stub(:respond_to?).with(:begin_transaction).and_return(:begin_transaction == begin_transaction_method)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should increment open transactions if possible" do
|
23
|
+
connection.stub(:respond_to?).with(:increment_open_transactions).and_return(true)
|
24
|
+
connection.should_receive(:increment_open_transactions)
|
25
|
+
Transaction.new.start
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should tell ActiveRecord to increment connection if its not possible to increment current connection" do
|
29
|
+
connection.stub(:respond_to?).with(:increment_open_transactions).and_return(false)
|
30
|
+
::ActiveRecord::Base.should_receive(:increment_open_transactions)
|
31
|
+
Transaction.new.start
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should start a transaction" do
|
35
|
+
connection.stub(:respond_to?).with(:increment_open_transactions).and_return(true)
|
36
|
+
connection.stub(:increment_open_transactions)
|
37
|
+
connection.should_receive(begin_transaction_method)
|
38
|
+
Transaction.new.start
|
39
|
+
end
|
40
|
+
end
|
36
41
|
end
|
37
42
|
end
|
38
43
|
|
39
44
|
describe "#clean" do
|
40
|
-
|
45
|
+
context "manual accounting of transaction count" do
|
46
|
+
it "should start a transaction" do
|
41
47
|
connection.should_receive(:open_transactions).and_return(1)
|
42
48
|
|
43
|
-
connection.stub
|
49
|
+
connection.stub(:decrement_open_transactions)
|
44
50
|
|
45
51
|
connection.should_receive(:rollback_db_transaction)
|
46
52
|
Transaction.new.clean
|
47
|
-
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should decrement open transactions if possible" do
|
56
|
+
connection.should_receive(:open_transactions).and_return(1)
|
48
57
|
|
49
|
-
|
50
|
-
|
58
|
+
connection.stub(:respond_to?).with(:decrement_open_transactions).and_return(true)
|
59
|
+
connection.stub(:respond_to?).with(:rollback_transaction_records).and_return(false)
|
60
|
+
connection.stub(:respond_to?).with(:rollback_transaction).and_return(false)
|
61
|
+
connection.stub(:rollback_db_transaction)
|
51
62
|
|
52
|
-
|
53
|
-
|
63
|
+
connection.should_receive(:decrement_open_transactions)
|
64
|
+
Transaction.new.clean
|
65
|
+
end
|
54
66
|
|
55
|
-
|
56
|
-
|
57
|
-
end
|
67
|
+
it "should not try to decrement or rollback if open_transactions is 0 for whatever reason" do
|
68
|
+
connection.should_receive(:open_transactions).and_return(0)
|
58
69
|
|
59
|
-
|
60
|
-
|
70
|
+
Transaction.new.clean
|
71
|
+
end
|
61
72
|
|
62
|
-
|
73
|
+
it "should decrement connection via ActiveRecord::Base if connection won't" do
|
74
|
+
connection.should_receive(:open_transactions).and_return(1)
|
75
|
+
connection.stub(:respond_to?).with(:decrement_open_transactions).and_return(false)
|
76
|
+
connection.stub(:respond_to?).with(:rollback_transaction_records).and_return(false)
|
77
|
+
connection.stub(:respond_to?).with(:rollback_transaction).and_return(false)
|
78
|
+
connection.stub(:rollback_db_transaction)
|
79
|
+
|
80
|
+
::ActiveRecord::Base.should_receive(:decrement_open_transactions)
|
81
|
+
Transaction.new.clean
|
82
|
+
end
|
63
83
|
end
|
64
84
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
85
|
+
context "automatic accounting of transaction count (AR 4)" do
|
86
|
+
before {stub_const("ActiveRecord::VERSION::MAJOR", 4) }
|
87
|
+
|
88
|
+
it "should start a transaction" do
|
89
|
+
connection.stub(:rollback_db_transaction)
|
90
|
+
connection.should_receive(:open_transactions).and_return(1)
|
91
|
+
|
92
|
+
connection.should_not_receive(:decrement_open_transactions)
|
93
|
+
connection.should_receive(:rollback_transaction)
|
94
|
+
Transaction.new.clean
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should decrement open transactions if possible" do
|
98
|
+
connection.stub(:rollback_transaction)
|
99
|
+
connection.should_receive(:open_transactions).and_return(1)
|
100
|
+
|
101
|
+
connection.should_not_receive(:decrement_open_transactions)
|
102
|
+
Transaction.new.clean
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should not try to decrement or rollback if open_transactions is 0 for whatever reason" do
|
106
|
+
connection.should_receive(:open_transactions).and_return(0)
|
107
|
+
|
108
|
+
Transaction.new.clean
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should decrement connection via ActiveRecord::Base if connection won't" do
|
112
|
+
connection.should_receive(:open_transactions).and_return(1)
|
113
|
+
connection.stub(:respond_to?).with(:rollback_transaction_records).and_return(false)
|
114
|
+
connection.stub(:respond_to?).with(:rollback_transaction).and_return(true)
|
115
|
+
connection.stub(:rollback_transaction)
|
69
116
|
|
70
|
-
|
71
|
-
|
117
|
+
::ActiveRecord::Base.should_not_receive(:decrement_open_transactions)
|
118
|
+
Transaction.new.clean
|
119
|
+
end
|
72
120
|
end
|
73
121
|
end
|
74
|
-
end
|
75
122
|
|
123
|
+
describe "#connection_maintains_transaction_count?" do
|
124
|
+
it "should return true if the major active record version is < 4" do
|
125
|
+
stub_const("ActiveRecord::VERSION::MAJOR", 3)
|
126
|
+
Transaction.new.connection_maintains_transaction_count?.should be_true
|
127
|
+
end
|
128
|
+
it "should return false if the major active record version is > 3" do
|
129
|
+
stub_const("ActiveRecord::VERSION::MAJOR", 4)
|
130
|
+
Transaction.new.connection_maintains_transaction_count?.should be_false
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
76
135
|
end
|
77
136
|
end
|