require 'sqlite3' require 'active_record' require 'activerecord-tablefree' require 'logger' require 'spec_helper' def make_tablefree_model(database = nil, nested = nil) eval < :#{database}" : 'has_no_table'} column :id, :integer column :name, :string #{if nested ' has_many :arm_rests accepts_nested_attributes_for :arm_rests ' end} end EOCLASS if nested eval < :#{database}" : 'has_no_table'} belongs_to :chair column :id, :integer column :chair_id, :integer column :name, :string end EOCLASS end end def remove_models Object.send(:remove_const, :Chair) rescue nil Object.send(:remove_const, :ArmRest) rescue nil end ActiveRecord::Base.logger = Logger.new(STDERR) ActiveRecord::Base.logger.level = Logger::Severity::UNKNOWN shared_examples_for "an active record instance" do it { should respond_to :id } it { should respond_to :id= } it { should respond_to :name } it { should respond_to :name= } it { should respond_to :update_attributes } describe "#attributes=" do before(:example){ subject.attributes=({:name => 'Jarl Friis'}) } it "assign attributes" do expect(subject.name).to eq 'Jarl Friis' end end end shared_examples_for "a nested active record" do describe "conllection#build" do specify do expect(subject.arm_rests.build({:name => 'nice arm_rest'})).to be_an_instance_of(ArmRest) end end describe "conllection#<<" do specify do expect(subject.arm_rests << ArmRest.new({:name => 'nice arm_rest'})).to have(1).items end describe 'appending two children' do before(:example) do subject.arm_rests << [ArmRest.new({:name => 'left'}), ArmRest.new({:name => 'right'})] end it "assigns nested attributes" do expect(subject.arm_rests[0].name).to eq 'left' expect(subject.arm_rests[1].name).to eq 'right' end end end describe "#attributes=" do before(:example){ subject.attributes=({ :name => 'Jarl Friis', :arm_rests_attributes => [ {:name => 'left'}, {:name => 'right'} ] }) } it "assigns attributes" do expect(subject.name).to eq 'Jarl Friis' end it "assigns nested attributes" do expect(subject.arm_rests[0].name).to eq 'left' expect(subject.arm_rests[1].name).to eq 'right' end end end shared_examples_for "a tablefree model with fail_fast" do case ActiveRecord::VERSION::MAJOR when 3 describe "#all" do it "raises ActiveRecord::Tablefree::NoDatabase" do expect { subject.all }.to raise_exception(ActiveRecord::Tablefree::NoDatabase) end end when 4 describe "#all" do it "raises ActiveRecord::Tablefree::NoDatabase" do expect { subject.all }.to_not raise_exception end end describe "#all[]" do it "raises ActiveRecord::Tablefree::NoDatabase" do expect { subject.all[0] }.to raise_exception(ActiveRecord::Tablefree::NoDatabase) end end end describe "#create" do it "raises ActiveRecord::Tablefree::NoDatabase" do expect { subject.create(:name => 'Jarl') }.to raise_exception(ActiveRecord::Tablefree::NoDatabase) end end describe "#destroy" do it "raises ActiveRecord::Tablefree::NoDatabase" do expect { subject.destroy(1) }.to raise_exception(ActiveRecord::Tablefree::NoDatabase) end end describe "#destroy_all" do it "raises ActiveRecord::Tablefree::NoDatabase" do expect { subject.destroy_all }.to raise_exception(ActiveRecord::Tablefree::NoDatabase) end end end shared_examples_for "a tablefree model instance with fail_fast" do it_behaves_like "an active record instance" describe "#save" do it "raises ActiveRecord::Tablefree::NoDatabase" do expect { subject.save }.to raise_exception(ActiveRecord::Tablefree::NoDatabase) end end describe "#save!" do it "raises ActiveRecord::Tablefree::NoDatabase" do expect { subject.save! }.to raise_exception(ActiveRecord::Tablefree::NoDatabase) end end describe "#reload" do it "raises ActiveRecord::Tablefree::NoDatabase" do expect { subject.reload }.to raise_exception(ActiveRecord::Tablefree::NoDatabase) end end describe "#update_attributes" do it "raises ActiveRecord::Tablefree::NoDatabase" do expect { subject.update_attributes(:name => 'Jarl') }.to raise_exception(StandardError) end end end describe "Tablefree model with fail_fast" do before(:context) {make_tablefree_model(nil, nil)} after(:context){ remove_models } subject { Chair } it_behaves_like "a tablefree model with fail_fast" describe "instance" do subject { Chair.new(:name => 'Jarl') } it_behaves_like "a tablefree model instance with fail_fast" end end describe "Tablefree nested with fail_fast" do before(:context) {make_tablefree_model(nil, true)} after(:context){ remove_models } subject { Chair } it_behaves_like "a tablefree model with fail_fast" describe "#new" do it "accepts attributes" do expect(subject.new(:name => "Jarl")).to be_an_instance_of(subject) end it "assign attributes" do expect(subject.new(:name => "Jarl").name).to eq "Jarl" end end describe "instance" do subject { Chair.new(:name => 'Jarl') } it_behaves_like "a tablefree model instance with fail_fast" it_behaves_like "a nested active record" describe "#update_attributes" do it "raises ActiveRecord::Tablefree::NoDatabase" do expect do subject.update_attributes(:arm_rests => {:name => 'nice arm_rest'}) end.to raise_exception(StandardError) end end end describe "instance with nested models" do subject do Chair.new(:name => "Jarl", :arm_rests => [ ArmRest.new(:name => 'left'), ArmRest.new(:name => 'right'), ]) end it {should be_an_instance_of(Chair) } it {should have(2).arm_rests } end describe "instance with nested attributes" do subject do Chair.new(:name => "Jarl", :arm_rests_attributes => [ {:name => 'left'}, {:name => 'right'}, ]) end it {should be_an_instance_of(Chair)} it {should have(2).arm_rests } end end ## ## Succeeding database ## shared_examples_for "a model with succeeding database" do describe "#all" do specify { expect(subject.all).to eq []} end describe "#create" do specify { expect(subject.create(:name => 'Jarl')).to be_an_instance_of(subject) } end describe "#destroy" do specify { expect(subject.destroy(1)).to be_an_instance_of(subject) } end describe "#destroy_all" do specify { expect(subject.destroy_all).to eq [] } end end shared_examples_for "an instance with succeeding database" do it_behaves_like "an active record instance" describe "#save" do specify { expect(subject.save).to eq true } end describe "#save!" do specify { expect(subject.save!).to eq true } end describe "#reload" do before { subject.save! } specify { expect(subject.reload).to eq subject } end describe "#update_attributes" do specify { expect(subject.update_attributes(:name => 'Jarl Friis')).to eq true } end end describe "ActiveRecord with real database" do ##This is only here to ensure that the shared examples are actually behaving like a real database. before(:context) do FileUtils.mkdir_p "tmp" ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => 'tmp/test.db') ActiveRecord::Base.connection.execute("drop table if exists chairs") ActiveRecord::Base.connection.execute("create table chairs (id INTEGER PRIMARY KEY, name TEXT )") class Chair < ActiveRecord::Base end end after(:context) do remove_models ActiveRecord::Base.clear_all_connections! end subject { Chair } it_behaves_like "a model with succeeding database" describe "instance" do subject { Chair.new(:name => 'Jarl') } it_behaves_like "an instance with succeeding database" end end describe "Tablefree model with succeeding database" do before(:context) { make_tablefree_model(:pretend_success, nil) } after(:context){ remove_models } subject { Chair } it_behaves_like "a model with succeeding database" describe "instance" do subject { Chair.new(:name => 'Jarl') } it_behaves_like "an instance with succeeding database" end end