spec/adapter_spec.rb in chrono_model-0.5.3 vs spec/adapter_spec.rb in chrono_model-0.8.0

- old
+ new

@@ -32,18 +32,19 @@ include ChronoTest::Helpers::Adapter context do subject { adapter } it { should be_a_kind_of(ChronoModel::Adapter) } + its(:adapter_name) { should == 'PostgreSQL' } context do - before { adapter.stub(:postgresql_version => 90000) } + before { adapter.stub(:postgresql_version => 90300) } it { should be_chrono_supported } end context do - before { adapter.stub(:postgresql_version => 80400) } + before { adapter.stub(:postgresql_version => 90000) } it { should_not be_chrono_supported } end end table 'test_table' @@ -57,14 +58,16 @@ ['baz', 'text'] ] def native.to_proc proc {|t| - t.string :test, :null => false + t.string :test, :null => false, :default => 'default-value' t.integer :foo t.float :bar t.text :baz + t.integer :ary, :array => true, :null => false, :default => [] + t.boolean :bool, :null => false, :default => false } end native end @@ -115,14 +118,31 @@ it_should_behave_like 'plain table' end with_plain_table do before :all do + adapter.add_index table, :foo + adapter.add_index table, :bar, :unique => true + adapter.change_table table, :temporal => true end it_should_behave_like 'temporal table' + + let(:history_indexes) do + adapter.on_schema(ChronoModel::Adapter::HISTORY_SCHEMA) do + adapter.indexes(table) + end + end + + it "copies plain index to history" do + history_indexes.find {|i| i.columns == ['foo']}.should be_present + end + + it "copies unique index to history without uniqueness constraint" do + history_indexes.find {|i| i.columns == ['bar'] && i.unique == false}.should be_present + end end end describe '.drop_table' do before :all do @@ -393,30 +413,30 @@ end end end + let(:current) { [ChronoModel::Adapter::TEMPORAL_SCHEMA, table].join('.') } + let(:history) { [ChronoModel::Adapter::HISTORY_SCHEMA, table].join('.') } + + def count(table) + adapter.select_value("SELECT COUNT(*) FROM ONLY #{table}").to_i + end + + def ids(table) + adapter.select_values("SELECT id FROM ONLY #{table} ORDER BY id") + end + context 'INSERT multiple values' do before :all do adapter.create_table table, :temporal => true, &columns end after :all do adapter.drop_table table end - let(:current) { [ChronoModel::Adapter::TEMPORAL_SCHEMA, table].join('.') } - let(:history) { [ChronoModel::Adapter::HISTORY_SCHEMA, table].join('.') } - - def count(table) - adapter.select_value("SELECT COUNT(*) FROM ONLY #{table}").to_i - end - - def ids(table) - adapter.select_values("SELECT id FROM ONLY #{table} ORDER BY id") - end - context 'when succeeding' do def insert adapter.execute <<-SQL INSERT INTO #{table} (test, foo) VALUES ('test1', 1), @@ -457,8 +477,128 @@ it { count(current).should == 4 } it { count(history).should == 4 } it { ids(current).should == ids(history) } end + end + + context 'INSERT on NOT NULL columns but with a DEFAULT value' do + before :all do + adapter.create_table table, :temporal => true, &columns + end + + after :all do + adapter.drop_table table + end + + def insert + adapter.execute <<-SQL + INSERT INTO #{table} DEFAULT VALUES + SQL + end + + def select + adapter.select_values <<-SQL + SELECT test FROM #{table} + SQL + end + + it { expect { insert }.to_not raise_error } + it { insert; select.uniq.should == ['default-value'] } + end + + context 'redundant UPDATEs' do + + before :all do + adapter.create_table table, :temporal => true, &columns + + adapter.execute <<-SQL + INSERT INTO #{table} (test, foo) VALUES ('test1', 1); + SQL + + adapter.execute <<-SQL + UPDATE #{table} SET test = 'test2'; + SQL + + adapter.execute <<-SQL + UPDATE #{table} SET test = 'test2'; + SQL + end + + after :all do + adapter.drop_table table + end + + it { count(current).should == 1 } + it { count(history).should == 2 } + + end + + context 'updates on non-journaled fields' do + before :all do + adapter.create_table table, :temporal => true do |t| + t.string 'test' + t.timestamps + end + + adapter.execute <<-SQL + INSERT INTO #{table} (test, created_at, updated_at) VALUES ('test', now(), now()); + SQL + + adapter.execute <<-SQL + UPDATE #{table} SET test = 'test2', updated_at = now(); + SQL + + 2.times do + adapter.execute <<-SQL # Redundant update with only updated_at change + UPDATE #{table} SET test = 'test2', updated_at = now(); + SQL + + adapter.execute <<-SQL + UPDATE #{table} SET updated_at = now(); + SQL + end + end + + after :all do + adapter.drop_table table + end + + it { count(current).should == 1 } + it { count(history).should == 2 } + end + + context 'selective journaled fields' do + before :all do + adapter.create_table table, :temporal => true, :journal => %w( foo ) do |t| + t.string 'foo' + t.string 'bar' + end + + adapter.execute <<-SQL + INSERT INTO #{table} (foo, bar) VALUES ('test foo', 'test bar'); + SQL + + adapter.execute <<-SQL + UPDATE #{table} SET foo = 'test foo', bar = 'no history'; + SQL + + 2.times do + adapter.execute <<-SQL + UPDATE #{table} SET bar = 'really no history'; + SQL + end + end + + after :all do + adapter.drop_table table + end + + it { count(current).should == 1 } + it { count(history).should == 1 } + + it 'preserves options upon column change' + it 'changes option upon table change' + end end