mirror of
https://github.com/DatabaseCleaner/database_cleaner
synced 2023-03-27 23:22:03 -04:00
get rspec tests running in ar adapter gem.
This commit is contained in:
parent
ed0e38f441
commit
c39366b11a
35 changed files with 644 additions and 125 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -7,8 +7,9 @@ bundled_gems/
|
||||||
vendor/
|
vendor/
|
||||||
examples/db/*.db
|
examples/db/*.db
|
||||||
examples/config/database.yml
|
examples/config/database.yml
|
||||||
db/config.yml
|
spec/support/config.yml
|
||||||
db/test.sqlite3
|
tmp/*
|
||||||
|
!tmp/.keep
|
||||||
.rbenv-version
|
.rbenv-version
|
||||||
.rvmrc
|
.rvmrc
|
||||||
.ruby-version
|
.ruby-version
|
||||||
|
|
|
@ -11,8 +11,7 @@ upstream:
|
||||||
## 2. Make sure the tests run fine
|
## 2. Make sure the tests run fine
|
||||||
|
|
||||||
- `bundle install`
|
- `bundle install`
|
||||||
- Copy `db/sample.config.yml` to `db/config.yml` and edit it
|
- Copy `spec/support/sample.config.yml` to `spec/support/config.yml` and edit it
|
||||||
- Make sure to create the databases specified in `db/config.yml`
|
|
||||||
- Run the tests with `bundle exec rspec`
|
- Run the tests with `bundle exec rspec`
|
||||||
|
|
||||||
Note that if you don't have all the supported databases installed and running,
|
Note that if you don't have all the supported databases installed and running,
|
||||||
|
|
12
Gemfile.lock
12
Gemfile.lock
|
@ -1,12 +1,14 @@
|
||||||
|
PATH
|
||||||
|
remote: .
|
||||||
|
specs:
|
||||||
|
database_cleaner (1.8.0)
|
||||||
|
|
||||||
PATH
|
PATH
|
||||||
remote: adapters
|
remote: adapters
|
||||||
specs:
|
specs:
|
||||||
database_cleaner-active_record (0.1.0)
|
database_cleaner-active_record (0.1.0)
|
||||||
|
activerecord
|
||||||
PATH
|
database_cleaner (~> 1.8.0)
|
||||||
remote: .
|
|
||||||
specs:
|
|
||||||
database_cleaner (1.7.0)
|
|
||||||
|
|
||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
|
|
|
@ -5,7 +5,9 @@
|
||||||
/doc/
|
/doc/
|
||||||
/pkg/
|
/pkg/
|
||||||
/spec/reports/
|
/spec/reports/
|
||||||
|
/spec/support/config.yml
|
||||||
/tmp/
|
/tmp/
|
||||||
|
!/tmp/.keep
|
||||||
|
|
||||||
# rspec failure tracking
|
# rspec failure tracking
|
||||||
.rspec_status
|
.rspec_status
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
require 'database_cleaner/active_record/version'
|
||||||
require 'database_cleaner'
|
require 'database_cleaner'
|
||||||
require 'database_cleaner/active_record/deletion'
|
require 'database_cleaner/active_record/deletion'
|
||||||
require 'database_cleaner/active_record/transaction'
|
require 'database_cleaner/active_record/transaction'
|
||||||
|
|
|
@ -0,0 +1,166 @@
|
||||||
|
require 'active_record'
|
||||||
|
require 'database_cleaner/active_record/base'
|
||||||
|
require 'database_cleaner/spec'
|
||||||
|
|
||||||
|
class FakeModel
|
||||||
|
def self.connection
|
||||||
|
:fake_connection
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
RSpec.describe DatabaseCleaner::ActiveRecord do
|
||||||
|
it { is_expected.to respond_to(:available_strategies) }
|
||||||
|
|
||||||
|
describe "config_file_location" do
|
||||||
|
after do
|
||||||
|
# prevent global state leakage
|
||||||
|
DatabaseCleaner::ActiveRecord.config_file_location=nil
|
||||||
|
DatabaseCleaner.app_root = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should default to \#{DatabaseCleaner.app_root}/config/database.yml" do
|
||||||
|
DatabaseCleaner::ActiveRecord.config_file_location = nil
|
||||||
|
DatabaseCleaner.app_root = "/path/to"
|
||||||
|
expect(DatabaseCleaner::ActiveRecord.config_file_location).to eq '/path/to/config/database.yml'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module DatabaseCleaner
|
||||||
|
module ActiveRecord
|
||||||
|
class ExampleStrategy
|
||||||
|
include DatabaseCleaner::ActiveRecord::Base
|
||||||
|
end
|
||||||
|
|
||||||
|
RSpec.describe ExampleStrategy do
|
||||||
|
let(:config_location) { '/path/to/config/database.yml' }
|
||||||
|
|
||||||
|
around do |example|
|
||||||
|
DatabaseCleaner::ActiveRecord.config_file_location = config_location
|
||||||
|
example.run
|
||||||
|
DatabaseCleaner::ActiveRecord.config_file_location = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it_should_behave_like "a generic strategy"
|
||||||
|
|
||||||
|
describe "db" do
|
||||||
|
it "should store my desired db" do
|
||||||
|
subject.db = :my_db
|
||||||
|
expect(subject.db).to eq :my_db
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should default to :default" do
|
||||||
|
expect(subject.db).to eq :default
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "db=" do
|
||||||
|
let(:config_location) { "spec/support/example.database.yml" }
|
||||||
|
|
||||||
|
it "should process erb in the config" do
|
||||||
|
subject.db = :my_db
|
||||||
|
expect(subject.connection_hash).to eq({ "database" => "one" })
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when config file differs from established ActiveRecord configuration' do
|
||||||
|
before do
|
||||||
|
allow(::ActiveRecord::Base).to receive(:configurations).and_return({ "my_db" => { "database" => "two"} })
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'uses the ActiveRecord configuration' do
|
||||||
|
subject.db = :my_db
|
||||||
|
expect(subject.connection_hash).to eq({ "database" => "two"})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when config file agrees with ActiveRecord configuration' do
|
||||||
|
before do
|
||||||
|
allow(::ActiveRecord::Base).to receive(:configurations).and_return({ "my_db" => { "database" => "one"} })
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'uses the config file' do
|
||||||
|
subject.db = :my_db
|
||||||
|
expect(subject.connection_hash).to eq({ "database" => "one"})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when ::ActiveRecord::Base.configurations nil' do
|
||||||
|
before do
|
||||||
|
allow(::ActiveRecord::Base).to receive(:configurations).and_return(nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'uses the config file' do
|
||||||
|
subject.db = :my_db
|
||||||
|
expect(subject.connection_hash).to eq({ "database" => "one"})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when ::ActiveRecord::Base.configurations empty' do
|
||||||
|
before do
|
||||||
|
allow(::ActiveRecord::Base).to receive(:configurations).and_return({})
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'uses the config file' do
|
||||||
|
subject.db = :my_db
|
||||||
|
expect(subject.connection_hash).to eq({ "database" => "one"})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when config file is not available' do
|
||||||
|
before do
|
||||||
|
allow(File).to receive(:file?).with(config_location).and_return(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should skip config" do
|
||||||
|
subject.db = :my_db
|
||||||
|
expect(subject.connection_hash).not_to be
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "skips the file when the model is set" do
|
||||||
|
subject.db = FakeModel
|
||||||
|
expect(subject.connection_hash).not_to be
|
||||||
|
end
|
||||||
|
|
||||||
|
it "skips the file when the db is set to :default" do
|
||||||
|
# to avoid https://github.com/bmabey/database_cleaner/issues/72
|
||||||
|
subject.db = :default
|
||||||
|
expect(subject.connection_hash).not_to be
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "connection_class" do
|
||||||
|
it "should default to ActiveRecord::Base" do
|
||||||
|
expect(subject.connection_class).to eq ::ActiveRecord::Base
|
||||||
|
end
|
||||||
|
|
||||||
|
context "with database models" do
|
||||||
|
context "connection_hash is set" do
|
||||||
|
it "reuses the model's connection" do
|
||||||
|
subject.connection_hash = {}
|
||||||
|
subject.db = FakeModel
|
||||||
|
expect(subject.connection_class).to eq FakeModel
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "connection_hash is not set" do
|
||||||
|
it "reuses the model's connection" do
|
||||||
|
subject.db = FakeModel
|
||||||
|
expect(subject.connection_class).to eq FakeModel
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when connection_hash is set" do
|
||||||
|
let(:hash) { {} }
|
||||||
|
before { subject.connection_hash = hash }
|
||||||
|
|
||||||
|
it "establishes a connection with it" do
|
||||||
|
expect(::ActiveRecord::Base).to receive(:establish_connection).with(hash)
|
||||||
|
expect(subject.connection_class).to eq ::ActiveRecord::Base
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,155 @@
|
||||||
|
require 'database_cleaner/active_record/transaction'
|
||||||
|
require 'active_record'
|
||||||
|
|
||||||
|
module DatabaseCleaner
|
||||||
|
module ActiveRecord
|
||||||
|
|
||||||
|
RSpec.describe Transaction do
|
||||||
|
let(:connection) { double("connection") }
|
||||||
|
let(:connection_2) { double("connection_2") }
|
||||||
|
let(:connection_pool) { double("connection_pool") }
|
||||||
|
|
||||||
|
before do
|
||||||
|
allow(::ActiveRecord::Base).to receive(:connection_pool).and_return(connection_pool)
|
||||||
|
allow(connection_pool).to receive(:connections).and_return([connection])
|
||||||
|
allow(::ActiveRecord::Base).to receive(:connection).and_return(connection)
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#start" do
|
||||||
|
[:begin_transaction, :begin_db_transaction].each do |begin_transaction_method|
|
||||||
|
context "using #{begin_transaction_method}" do
|
||||||
|
before do
|
||||||
|
allow(connection).to receive(:transaction)
|
||||||
|
allow(connection).to receive(begin_transaction_method)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should increment open transactions if possible" do
|
||||||
|
expect(connection).to receive(:increment_open_transactions)
|
||||||
|
subject.start
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should tell ActiveRecord to increment connection if its not possible to increment current connection" do
|
||||||
|
expect(::ActiveRecord::Base).to receive(:increment_open_transactions)
|
||||||
|
subject.start
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should start a transaction" do
|
||||||
|
allow(connection).to receive(:increment_open_transactions)
|
||||||
|
expect(connection).to receive(begin_transaction_method)
|
||||||
|
expect(connection).to receive(:transaction)
|
||||||
|
subject.start
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#clean" do
|
||||||
|
context "manual accounting of transaction count" do
|
||||||
|
it "should start a transaction" do
|
||||||
|
expect(connection).to receive(:open_transactions).and_return(1)
|
||||||
|
|
||||||
|
allow(connection).to receive(:decrement_open_transactions)
|
||||||
|
|
||||||
|
expect(connection).to receive(:rollback_db_transaction)
|
||||||
|
subject.clean
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should decrement open transactions if possible" do
|
||||||
|
expect(connection).to receive(:open_transactions).and_return(1)
|
||||||
|
|
||||||
|
allow(connection).to receive(:rollback_db_transaction)
|
||||||
|
|
||||||
|
expect(connection).to receive(:decrement_open_transactions)
|
||||||
|
subject.clean
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should not try to decrement or rollback if open_transactions is 0 for whatever reason" do
|
||||||
|
expect(connection).to receive(:open_transactions).and_return(0)
|
||||||
|
|
||||||
|
subject.clean
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should decrement connection via ActiveRecord::Base if connection won't" do
|
||||||
|
expect(connection).to receive(:open_transactions).and_return(1)
|
||||||
|
allow(connection).to receive(:rollback_db_transaction)
|
||||||
|
|
||||||
|
expect(::ActiveRecord::Base).to receive(:decrement_open_transactions)
|
||||||
|
subject.clean
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should rollback open transactions in all connections" do
|
||||||
|
allow(connection_pool).to receive(:connections).and_return([connection, connection_2])
|
||||||
|
|
||||||
|
expect(connection).to receive(:open_transactions).and_return(1)
|
||||||
|
allow(connection).to receive(:rollback_db_transaction)
|
||||||
|
|
||||||
|
expect(connection_2).to receive(:open_transactions).and_return(1)
|
||||||
|
allow(connection_2).to receive(:rollback_db_transaction)
|
||||||
|
|
||||||
|
expect(::ActiveRecord::Base).to receive(:decrement_open_transactions).twice
|
||||||
|
subject.clean
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should rollback open transactions in all connections with an open transaction" do
|
||||||
|
allow(connection_pool).to receive(:connections).and_return([connection, connection_2])
|
||||||
|
|
||||||
|
expect(connection).to receive(:open_transactions).and_return(1)
|
||||||
|
allow(connection).to receive(:rollback_db_transaction)
|
||||||
|
|
||||||
|
expect(connection_2).to receive(:open_transactions).and_return(0)
|
||||||
|
|
||||||
|
expect(::ActiveRecord::Base).to receive(:decrement_open_transactions).exactly(1).times
|
||||||
|
subject.clean
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "automatic accounting of transaction count (AR 4)" do
|
||||||
|
before { stub_const("ActiveRecord::VERSION::MAJOR", 4) }
|
||||||
|
|
||||||
|
it "should start a transaction" do
|
||||||
|
allow(connection).to receive(:rollback_db_transaction)
|
||||||
|
expect(connection).to receive(:open_transactions).and_return(1)
|
||||||
|
|
||||||
|
expect(connection).not_to receive(:decrement_open_transactions)
|
||||||
|
expect(connection).to receive(:rollback_transaction)
|
||||||
|
subject.clean
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should decrement open transactions if possible" do
|
||||||
|
allow(connection).to receive(:rollback_transaction)
|
||||||
|
expect(connection).to receive(:open_transactions).and_return(1)
|
||||||
|
|
||||||
|
expect(connection).not_to receive(:decrement_open_transactions)
|
||||||
|
subject.clean
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should not try to decrement or rollback if open_transactions is 0 for whatever reason" do
|
||||||
|
expect(connection).to receive(:open_transactions).and_return(0)
|
||||||
|
|
||||||
|
subject.clean
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should decrement connection via ActiveRecord::Base if connection won't" do
|
||||||
|
expect(connection).to receive(:open_transactions).and_return(1)
|
||||||
|
allow(connection).to receive(:rollback_transaction)
|
||||||
|
|
||||||
|
expect(::ActiveRecord::Base).not_to receive(:decrement_open_transactions)
|
||||||
|
subject.clean
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#connection_maintains_transaction_count?" do
|
||||||
|
it "should return true if the major active record version is < 4" do
|
||||||
|
stub_const("ActiveRecord::VERSION::MAJOR", 3)
|
||||||
|
expect(subject.connection_maintains_transaction_count?).to be_truthy
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return false if the major active record version is > 3" do
|
||||||
|
stub_const("ActiveRecord::VERSION::MAJOR", 4)
|
||||||
|
expect(subject.connection_maintains_transaction_count?).to be_falsey
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,120 @@
|
||||||
|
require 'support/active_record_helper'
|
||||||
|
require 'database_cleaner/active_record/truncation'
|
||||||
|
|
||||||
|
RSpec.describe DatabaseCleaner::ActiveRecord::Truncation do
|
||||||
|
ActiveRecordHelper.with_all_dbs do |helper|
|
||||||
|
context "using a #{helper.db} connection" do
|
||||||
|
around do |example|
|
||||||
|
helper.setup
|
||||||
|
example.run
|
||||||
|
helper.teardown
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:connection) { helper.connection }
|
||||||
|
|
||||||
|
before do
|
||||||
|
allow(connection).to receive(:disable_referential_integrity).and_yield
|
||||||
|
allow(connection).to receive(:database_cleaner_view_cache).and_return([])
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#clean' do
|
||||||
|
context "with records" do
|
||||||
|
before do
|
||||||
|
2.times { User.create! }
|
||||||
|
2.times { Agent.create! }
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should truncate all tables" do
|
||||||
|
expect { subject.clean }
|
||||||
|
.to change { [User.count, Agent.count] }
|
||||||
|
.from([2,2])
|
||||||
|
.to([0,0])
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should reset AUTO_INCREMENT index of table" do
|
||||||
|
subject.clean
|
||||||
|
expect(User.create.id).to eq 1
|
||||||
|
end
|
||||||
|
|
||||||
|
xit "should not reset AUTO_INCREMENT index of table if :reset_ids is false" do
|
||||||
|
described_class.new(reset_ids: false).clean
|
||||||
|
expect(User.create.id).to eq 3
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should truncate all tables except for schema_migrations" do
|
||||||
|
subject.clean
|
||||||
|
count = connection.select_value("select count(*) from schema_migrations;").to_i
|
||||||
|
expect(count).to eq 2
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should only truncate the tables specified in the :only option when provided" do
|
||||||
|
expect { described_class.new(only: ['agents']).clean }
|
||||||
|
.to change { [User.count, Agent.count] }
|
||||||
|
.from([2,2])
|
||||||
|
.to([2,0])
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should not truncate the tables specified in the :except option" do
|
||||||
|
expect { described_class.new(except: ['users']).clean }
|
||||||
|
.to change { [User.count, Agent.count] }
|
||||||
|
.from([2,2])
|
||||||
|
.to([2,0])
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should raise an error when :only and :except options are used" do
|
||||||
|
expect {
|
||||||
|
described_class.new(except: ['widgets'], only: ['widgets'])
|
||||||
|
}.to raise_error(ArgumentError)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should raise an error when invalid options are provided" do
|
||||||
|
expect { described_class.new(foo: 'bar') }.to raise_error(ArgumentError)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should not truncate views" do
|
||||||
|
allow(connection).to receive(:database_cleaner_table_cache).and_return(%w[widgets dogs])
|
||||||
|
allow(connection).to receive(:database_cleaner_view_cache).and_return(["widgets"])
|
||||||
|
|
||||||
|
expect(connection).to receive(:truncate_tables).with(['dogs'])
|
||||||
|
|
||||||
|
subject.clean
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "with pre_count optimization option" do
|
||||||
|
subject { described_class.new(pre_count: true) }
|
||||||
|
|
||||||
|
it "only truncates non-empty tables" do
|
||||||
|
pending if helper.db == :sqlite3
|
||||||
|
pending if helper.db == :postgres
|
||||||
|
|
||||||
|
User.create!
|
||||||
|
|
||||||
|
expect(connection).to receive(:truncate_tables).with(['users'])
|
||||||
|
subject.clean
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when :cache_tables is set to true' do
|
||||||
|
it 'caches the list of tables to be truncated' do
|
||||||
|
expect(connection).to receive(:database_cleaner_table_cache).and_return([])
|
||||||
|
expect(connection).not_to receive(:tables)
|
||||||
|
|
||||||
|
allow(connection).to receive(:truncate_tables)
|
||||||
|
described_class.new(cache_tables: true).clean
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when :cache_tables is set to false' do
|
||||||
|
it 'does not cache the list of tables to be truncated' do
|
||||||
|
expect(connection).not_to receive(:database_cleaner_table_cache)
|
||||||
|
expect(connection).to receive(:tables).and_return([])
|
||||||
|
|
||||||
|
allow(connection).to receive(:truncate_tables)
|
||||||
|
described_class.new(cache_tables: false).clean
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,9 +0,0 @@
|
||||||
RSpec.describe DatabaseCleaner::ActiveRecord do
|
|
||||||
it "has a version number" do
|
|
||||||
expect(DatabaseCleaner::ActiveRecord::VERSION).not_to be nil
|
|
||||||
end
|
|
||||||
|
|
||||||
it "does something useful" do
|
|
||||||
expect(false).to eq(true)
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,14 +1,14 @@
|
||||||
require "bundler/setup"
|
require "bundler/setup"
|
||||||
require "database_cleaner/active_record"
|
require 'database_cleaner'
|
||||||
|
|
||||||
RSpec.configure do |config|
|
RSpec.configure do |config|
|
||||||
# Enable flags like --only-failures and --next-failure
|
# These two settings work together to allow you to limit a spec run
|
||||||
config.example_status_persistence_file_path = ".rspec_status"
|
# to individual examples or groups you care about by tagging them with
|
||||||
|
# `:focus` metadata. When nothing is tagged with `:focus`, all examples
|
||||||
|
# get run.
|
||||||
|
config.filter_run :focus
|
||||||
|
config.run_all_when_everything_filtered = true
|
||||||
|
|
||||||
# Disable RSpec exposing methods globally on `Module` and `main`
|
|
||||||
config.disable_monkey_patching!
|
config.disable_monkey_patching!
|
||||||
|
|
||||||
config.expect_with :rspec do |c|
|
|
||||||
c.syntax = :expect
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
require 'active_record'
|
||||||
|
require 'database_cleaner/spec/database_helper'
|
||||||
|
|
||||||
|
class ActiveRecordHelper < DatabaseCleaner::Spec::DatabaseHelper
|
||||||
|
def setup
|
||||||
|
patch_mysql_adapters
|
||||||
|
|
||||||
|
Kernel.const_set "User", Class.new(ActiveRecord::Base)
|
||||||
|
Kernel.const_set "Agent", Class.new(ActiveRecord::Base)
|
||||||
|
|
||||||
|
super
|
||||||
|
|
||||||
|
connection.execute "CREATE TABLE IF NOT EXISTS schema_migrations (version VARCHAR(255));"
|
||||||
|
connection.execute "INSERT INTO schema_migrations VALUES (1), (2);"
|
||||||
|
end
|
||||||
|
|
||||||
|
def teardown
|
||||||
|
connection.execute "DROP TABLE schema_migrations;"
|
||||||
|
|
||||||
|
super
|
||||||
|
|
||||||
|
Kernel.send :remove_const, "User" if defined?(User)
|
||||||
|
Kernel.send :remove_const, "Agent" if defined?(Agent)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def establish_connection(config = default_config)
|
||||||
|
ActiveRecord::Base.establish_connection(config)
|
||||||
|
@connection = ActiveRecord::Base.connection
|
||||||
|
end
|
||||||
|
|
||||||
|
def patch_mysql_adapters
|
||||||
|
# remove DEFAULT NULL from column definition, which is an error on primary keys in MySQL 5.7.3+
|
||||||
|
primary_key_sql = "int(11) auto_increment PRIMARY KEY"
|
||||||
|
ActiveRecord::ConnectionAdapters::MysqlAdapter::NATIVE_DATABASE_TYPES[:primary_key] = primary_key_sql
|
||||||
|
ActiveRecord::ConnectionAdapters::Mysql2Adapter::NATIVE_DATABASE_TYPES[:primary_key] = primary_key_sql
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
my_db:
|
||||||
|
database: <%= "ONE".downcase %>
|
||||||
|
|
|
@ -27,7 +27,7 @@ postgres:
|
||||||
|
|
||||||
sqlite3:
|
sqlite3:
|
||||||
adapter: sqlite3
|
adapter: sqlite3
|
||||||
database: db/test.sqlite3
|
database: tmp/database_cleaner_test.sqlite3
|
||||||
pool: 5
|
pool: 5
|
||||||
timeout: 5000
|
timeout: 5000
|
||||||
encoding: utf8
|
encoding: utf8
|
2
lib/database_cleaner/spec.rb
Normal file
2
lib/database_cleaner/spec.rb
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
require "database_cleaner/spec/database_helper"
|
||||||
|
require "database_cleaner/spec/shared_examples"
|
82
lib/database_cleaner/spec/database_helper.rb
Normal file
82
lib/database_cleaner/spec/database_helper.rb
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
require 'yaml'
|
||||||
|
|
||||||
|
module DatabaseCleaner
|
||||||
|
module Spec
|
||||||
|
class DatabaseHelper < Struct.new(:db)
|
||||||
|
def self.with_all_dbs &block
|
||||||
|
%w[mysql mysql2 sqlite3 postgres].map(&:to_sym).each do |db|
|
||||||
|
yield new(db)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def setup
|
||||||
|
create_db
|
||||||
|
establish_connection
|
||||||
|
load_schema
|
||||||
|
end
|
||||||
|
|
||||||
|
attr_reader :connection
|
||||||
|
|
||||||
|
def teardown
|
||||||
|
drop_db
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def establish_connection(config = default_config)
|
||||||
|
raise NotImplementedError
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_db
|
||||||
|
if db == :sqlite3
|
||||||
|
# NO-OP
|
||||||
|
elsif db == :postgres
|
||||||
|
establish_connection default_config.merge('database' => 'postgres')
|
||||||
|
connection.execute "CREATE DATABASE #{default_config['database']}" rescue nil
|
||||||
|
else
|
||||||
|
establish_connection default_config.merge("database" => nil)
|
||||||
|
connection.execute "CREATE DATABASE IF NOT EXISTS #{default_config['database']}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def load_schema
|
||||||
|
connection.execute <<-SQL
|
||||||
|
CREATE TABLE IF NOT EXISTS users (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
name INTEGER
|
||||||
|
);
|
||||||
|
SQL
|
||||||
|
|
||||||
|
connection.execute <<-SQL
|
||||||
|
CREATE TABLE IF NOT EXISTS agents (
|
||||||
|
name INTEGER
|
||||||
|
);
|
||||||
|
SQL
|
||||||
|
end
|
||||||
|
|
||||||
|
def drop_db
|
||||||
|
if db == :sqlite3
|
||||||
|
begin
|
||||||
|
File.unlink(db_config['sqlite3']['database'])
|
||||||
|
rescue Errno::ENOENT
|
||||||
|
end
|
||||||
|
elsif db == :postgres
|
||||||
|
# FIXME
|
||||||
|
connection.execute "DROP TABLE IF EXISTS users"
|
||||||
|
connection.execute "DROP TABLE IF EXISTS agents"
|
||||||
|
else
|
||||||
|
connection.execute "DROP DATABASE IF EXISTS #{default_config['database']}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def db_config
|
||||||
|
config_path = 'spec/support/config.yml'
|
||||||
|
@db_config ||= YAML.load(IO.read(config_path))
|
||||||
|
end
|
||||||
|
|
||||||
|
def default_config
|
||||||
|
db_config[db.to_s]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,6 +1,6 @@
|
||||||
require 'active_record'
|
require 'active_record'
|
||||||
require 'database_cleaner/active_record/base'
|
require 'database_cleaner/active_record/base'
|
||||||
require 'database_cleaner/shared_strategy'
|
require 'database_cleaner/spec'
|
||||||
|
|
||||||
class FakeModel
|
class FakeModel
|
||||||
def self.connection
|
def self.connection
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
require 'database_cleaner/data_mapper/base'
|
require 'database_cleaner/data_mapper/base'
|
||||||
require 'database_cleaner/shared_strategy'
|
require 'database_cleaner/spec'
|
||||||
|
|
||||||
module DatabaseCleaner
|
module DatabaseCleaner
|
||||||
RSpec.describe DataMapper do
|
RSpec.describe DataMapper do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
require 'database_cleaner/data_mapper/transaction'
|
require 'database_cleaner/data_mapper/transaction'
|
||||||
require 'database_cleaner/shared_strategy'
|
require 'database_cleaner/spec'
|
||||||
#require 'data_mapper'
|
#require 'data_mapper'
|
||||||
|
|
||||||
module DatabaseCleaner
|
module DatabaseCleaner
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
require 'database_cleaner/data_mapper/truncation'
|
require 'database_cleaner/data_mapper/truncation'
|
||||||
require 'database_cleaner/shared_strategy'
|
require 'database_cleaner/spec'
|
||||||
|
|
||||||
module DatabaseCleaner
|
module DatabaseCleaner
|
||||||
module DataMapper
|
module DataMapper
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
require 'database_cleaner/shared_strategy'
|
require 'database_cleaner/spec'
|
||||||
require 'database_cleaner/generic/base'
|
require 'database_cleaner/generic/base'
|
||||||
require 'active_record'
|
require 'active_record'
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
require 'database_cleaner/mongo_mapper/base'
|
require 'database_cleaner/mongo_mapper/base'
|
||||||
require 'database_cleaner/shared_strategy'
|
require 'database_cleaner/spec'
|
||||||
|
|
||||||
module DatabaseCleaner
|
module DatabaseCleaner
|
||||||
RSpec.describe MongoMapper do
|
RSpec.describe MongoMapper do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
require 'database_cleaner/neo4j/base'
|
require 'database_cleaner/neo4j/base'
|
||||||
require 'database_cleaner/shared_strategy'
|
require 'database_cleaner/spec'
|
||||||
|
|
||||||
module DatabaseCleaner
|
module DatabaseCleaner
|
||||||
RSpec.describe Neo4j do
|
RSpec.describe Neo4j do
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
require 'neo4j-core'
|
require 'neo4j-core'
|
||||||
require 'database_cleaner/neo4j/transaction'
|
require 'database_cleaner/neo4j/transaction'
|
||||||
require 'database_cleaner/shared_strategy'
|
require 'database_cleaner/spec'
|
||||||
|
|
||||||
module DatabaseCleaner
|
module DatabaseCleaner
|
||||||
module Neo4j
|
module Neo4j
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
require 'redis'
|
require 'redis'
|
||||||
require 'database_cleaner/redis/base'
|
require 'database_cleaner/redis/base'
|
||||||
require 'database_cleaner/shared_strategy'
|
require 'database_cleaner/spec'
|
||||||
|
|
||||||
module DatabaseCleaner
|
module DatabaseCleaner
|
||||||
RSpec.describe Redis do
|
RSpec.describe Redis do
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
require 'database_cleaner/sequel/base'
|
require 'database_cleaner/sequel/base'
|
||||||
require 'database_cleaner/shared_strategy'
|
require 'database_cleaner/spec'
|
||||||
require 'sequel'
|
require 'sequel'
|
||||||
|
|
||||||
module DatabaseCleaner
|
module DatabaseCleaner
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
require 'database_cleaner/sequel/deletion'
|
require 'database_cleaner/sequel/deletion'
|
||||||
require 'database_cleaner/shared_strategy'
|
require 'database_cleaner/spec'
|
||||||
require 'support/sequel_helper'
|
require 'support/sequel_helper'
|
||||||
|
|
||||||
module DatabaseCleaner
|
module DatabaseCleaner
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
require 'database_cleaner/sequel/transaction'
|
require 'database_cleaner/sequel/transaction'
|
||||||
require 'database_cleaner/shared_strategy'
|
require 'database_cleaner/spec'
|
||||||
require 'support/sequel_helper'
|
require 'support/sequel_helper'
|
||||||
|
|
||||||
module DatabaseCleaner
|
module DatabaseCleaner
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
require 'database_cleaner/sequel/truncation'
|
require 'database_cleaner/sequel/truncation'
|
||||||
require 'database_cleaner/shared_strategy'
|
require 'database_cleaner/spec'
|
||||||
require 'support/sequel_helper'
|
require 'support/sequel_helper'
|
||||||
|
|
||||||
module DatabaseCleaner
|
module DatabaseCleaner
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
require 'active_record'
|
require 'active_record'
|
||||||
require 'support/database_helper'
|
require 'database_cleaner/spec/database_helper'
|
||||||
|
|
||||||
class ActiveRecordHelper < DatabaseHelper
|
class ActiveRecordHelper < DatabaseCleaner::Spec::DatabaseHelper
|
||||||
def setup
|
def setup
|
||||||
patch_mysql_adapters
|
patch_mysql_adapters
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
require 'dm-core'
|
require 'dm-core'
|
||||||
require 'dm-sqlite-adapter'
|
require 'dm-sqlite-adapter'
|
||||||
require 'support/database_helper'
|
require 'database_cleaner/spec/database_helper'
|
||||||
|
|
||||||
class DataMapperHelper < DatabaseHelper
|
class DataMapperHelper < DatabaseCleaner::Spec::DatabaseHelper
|
||||||
def setup
|
def setup
|
||||||
super
|
super
|
||||||
|
|
||||||
|
|
|
@ -1,79 +0,0 @@
|
||||||
require 'yaml'
|
|
||||||
|
|
||||||
class DatabaseHelper < Struct.new(:db)
|
|
||||||
def self.with_all_dbs &block
|
|
||||||
%w[mysql mysql2 sqlite3 postgres].map(&:to_sym).each do |db|
|
|
||||||
yield new(db)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def setup
|
|
||||||
create_db
|
|
||||||
establish_connection
|
|
||||||
load_schema
|
|
||||||
end
|
|
||||||
|
|
||||||
attr_reader :connection
|
|
||||||
|
|
||||||
def teardown
|
|
||||||
drop_db
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def establish_connection(config = default_config)
|
|
||||||
raise NotImplementedError
|
|
||||||
end
|
|
||||||
|
|
||||||
def create_db
|
|
||||||
if db == :sqlite3
|
|
||||||
# NO-OP
|
|
||||||
elsif db == :postgres
|
|
||||||
establish_connection default_config.merge('database' => 'postgres')
|
|
||||||
connection.execute "CREATE DATABASE #{default_config['database']}" rescue nil
|
|
||||||
else
|
|
||||||
establish_connection default_config.merge("database" => nil)
|
|
||||||
connection.execute "CREATE DATABASE IF NOT EXISTS #{default_config['database']}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def load_schema
|
|
||||||
connection.execute <<-SQL
|
|
||||||
CREATE TABLE IF NOT EXISTS users (
|
|
||||||
id SERIAL PRIMARY KEY,
|
|
||||||
name INTEGER
|
|
||||||
);
|
|
||||||
SQL
|
|
||||||
|
|
||||||
connection.execute <<-SQL
|
|
||||||
CREATE TABLE IF NOT EXISTS agents (
|
|
||||||
name INTEGER
|
|
||||||
);
|
|
||||||
SQL
|
|
||||||
end
|
|
||||||
|
|
||||||
def drop_db
|
|
||||||
if db == :sqlite3
|
|
||||||
begin
|
|
||||||
File.unlink(db_config['sqlite3']['database'])
|
|
||||||
rescue Errno::ENOENT
|
|
||||||
end
|
|
||||||
elsif db == :postgres
|
|
||||||
# FIXME
|
|
||||||
connection.execute "DROP TABLE IF EXISTS users"
|
|
||||||
connection.execute "DROP TABLE IF EXISTS agents"
|
|
||||||
else
|
|
||||||
connection.execute "DROP DATABASE IF EXISTS #{default_config['database']}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def db_config
|
|
||||||
config_path = 'db/config.yml'
|
|
||||||
@db_config ||= YAML.load(IO.read(config_path))
|
|
||||||
end
|
|
||||||
|
|
||||||
def default_config
|
|
||||||
db_config[db.to_s]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
34
spec/support/sample.config.yml
Normal file
34
spec/support/sample.config.yml
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
mysql:
|
||||||
|
adapter: mysql
|
||||||
|
database: database_cleaner_test
|
||||||
|
username: root
|
||||||
|
password:
|
||||||
|
host: 127.0.0.1
|
||||||
|
port: 3306
|
||||||
|
encoding: utf8
|
||||||
|
|
||||||
|
mysql2:
|
||||||
|
adapter: mysql2
|
||||||
|
database: database_cleaner_test
|
||||||
|
username: root
|
||||||
|
password:
|
||||||
|
host: 127.0.0.1
|
||||||
|
port: 3306
|
||||||
|
encoding: utf8
|
||||||
|
|
||||||
|
postgres:
|
||||||
|
adapter: postgresql
|
||||||
|
database: database_cleaner_test
|
||||||
|
username: postgres
|
||||||
|
password:
|
||||||
|
host: 127.0.0.1
|
||||||
|
encoding: unicode
|
||||||
|
template: template0
|
||||||
|
|
||||||
|
sqlite3:
|
||||||
|
adapter: sqlite3
|
||||||
|
database: tmp/database_cleaner_test.sqlite3
|
||||||
|
pool: 5
|
||||||
|
timeout: 5000
|
||||||
|
encoding: utf8
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
require 'sequel'
|
require 'sequel'
|
||||||
require 'support/database_helper'
|
require 'database_cleaner/spec/database_helper'
|
||||||
|
|
||||||
class SequelHelper < DatabaseHelper
|
class SequelHelper < DatabaseCleaner::Spec::DatabaseHelper
|
||||||
private
|
private
|
||||||
|
|
||||||
def establish_connection(config = default_config)
|
def establish_connection(config = default_config)
|
||||||
|
|
0
tmp/.keep
Normal file
0
tmp/.keep
Normal file
Loading…
Reference in a new issue