module DatabaseCleaner RSpec.describe Cleaner do describe "comparison" do it "should be equal if orm and db are the same" do one = Cleaner.new(:active_record, db: :default) two = Cleaner.new(:active_record, db: :default) expect(one).to eq two expect(two).to eq one end it "should not be equal if orm are not the same" do one = Cleaner.new(:mongo_id, db: :default) two = Cleaner.new(:active_record, db: :default) expect(one).not_to eq two expect(two).not_to eq one end it "should not be equal if db are not the same" do one = Cleaner.new(:active_record, db: :default) two = Cleaner.new(:active_record, db: :other) expect(one).not_to eq two expect(two).not_to eq one end end describe "initialization" do context "db specified" do subject(:cleaner) { Cleaner.new(:active_record, db: :my_db) } it "should store db from :db in params hash" do expect(cleaner.db).to eq :my_db end end describe "orm" do it "should store orm" do cleaner = Cleaner.new(:a_orm) expect(cleaner.orm).to eq :a_orm end it "raises ArgumentError when no orm is specified" do expect { Cleaner.new }.to raise_error(ArgumentError) end end end describe "db" do subject(:cleaner) { Cleaner.new(:orm) } it "should default to :default" do expect(cleaner.db).to eq :default end it "should return any stored db value" do cleaner.db = :test_db expect(cleaner.db).to eq :test_db end end describe "db=" do subject(:cleaner) { Cleaner.new(:orm) } context "when strategy supports db specification" do it "should pass db down to its current strategy" do expect(cleaner.strategy).to receive(:db=).with(:a_new_db) cleaner.db = :a_new_db end end context "when strategy doesn't support db specification" do let(:strategy) { double(respond_to?: false) } before { cleaner.strategy = strategy } it "doesn't pass the default db down to it" do expect(strategy).to_not receive(:db=) cleaner.db = :default end it "should raise an argument error when db isn't default" do expect { cleaner.db = :test }.to raise_error ArgumentError end end end describe "clean_with" do subject(:cleaner) { Cleaner.new(:active_record) } let(:strategy_class) { Class.new(DatabaseCleaner::Strategy) } let(:strategy) { strategy_class.new } before { allow(strategy_class).to receive(:new).and_return(strategy) } before do stub_const "DatabaseCleaner::ActiveRecord::Truncation", strategy_class end it "should pass all arguments to strategy initializer" do expect(strategy_class).to receive(:new).with(:dollar, :amet, { ipsum: "random" }).and_return(strategy) expect(strategy).to receive(:clean) cleaner.clean_with :truncation, :dollar, :amet, ipsum: "random" end it "should invoke clean on the created strategy" do expect(strategy).to receive(:clean) cleaner.clean_with :truncation end it "should return the created strategy" do expect(strategy).to receive(:clean) expect(cleaner.clean_with(:truncation)).to eq strategy end end describe "strategy=" do subject(:cleaner) { Cleaner.new(:active_record) } let(:strategy_class) { Class.new(DatabaseCleaner::Strategy) } let(:orm_module) { Module.new } let(:available_strategies) { DatabaseCleaner::Cleaner.available_strategies(orm_module) } before do stub_const "DatabaseCleaner::ActiveRecord", orm_module stub_const "DatabaseCleaner::ActiveRecord::Truncation", strategy_class stub_const "DatabaseCleaner::ActiveRecord::MyStrategy", strategy_class # stub consts that shouldn't show up in strategy list stub_const "DatabaseCleaner::ActiveRecord::VERSION", "2.0.0" stub_const "DatabaseCleaner::ActiveRecord::Helpers", Module.new stub_const "DatabaseCleaner::ActiveRecord::Base", Class.new(strategy_class) stub_const "DatabaseCleaner::ActiveRecord::ExtendedBase", Class.new(strategy_class) orm_module.private_constant :ExtendedBase end it "should look up and create a the named strategy for the current ORM" do cleaner.strategy = :truncation expect(cleaner.strategy).to be_a(strategy_class) end it "should look up and create a custom strategy for the current ORM" do cleaner.strategy = :my_strategy expect(cleaner.strategy).to be_a(strategy_class) end it "should proxy params with symbolised strategies in an array" do expect(strategy_class).to receive(:new).with({ param: "one" }) cleaner.strategy = [:truncation, param: "one"] end it "should proxy params with symbolised strategies in a separate hash" do expect(strategy_class).to receive(:new).with({ param: "one" }) cleaner.strategy = :truncation, { param: "one" } end it "should accept strategy objects" do strategy = double cleaner.strategy = strategy expect(cleaner.strategy).to eq strategy end it "should raise argument error when params given with strategy object" do expect do cleaner.strategy = double, { param: "one" } end.to raise_error ArgumentError end it "should attempt to set strategy db" do strategy = double expect(strategy).to receive(:db=).with(:default) cleaner.strategy = strategy end it "raises UnknownStrategySpecified on a bad strategy, and lists available strategies" do expect { cleaner.strategy = :horrible_plan }.to \ raise_error(UnknownStrategySpecified, "The 'horrible_plan' strategy does not exist for the active_record ORM! Available strategies: #{available_strategies.join(', ')}") end end describe "strategy" do subject(:cleaner) { Cleaner.new(:a_orm) } it "returns a null strategy when strategy is not set and undetectable" do expect(cleaner.strategy).to be_a(DatabaseCleaner::NullStrategy) end end describe "proxy methods" do subject(:cleaner) { Cleaner.new(:orm) } let(:strategy) { double(:strategy) } before { cleaner.strategy = strategy } describe "start" do it "should proxy start to the strategy" do expect(strategy).to receive(:start) cleaner.start end end describe "clean" do it "should proxy clean to the strategy" do expect(strategy).to receive(:clean) cleaner.clean end end describe "cleaning" do it "should proxy cleaning to the strategy" do expect(strategy).to receive(:cleaning) cleaner.cleaning { } end end end end end