Skip to content

Commit

Permalink
Update test suite and test directly against ActiveRecord
Browse files Browse the repository at this point in the history
This commit reconfigures the test suite to test directly against
ActiveRecord. It accomplishes this by setting up an in-memory SQLite
store. There are several models added for each test module.

This commit also updates the RSpec configuration to be reflect the
modern DSL. This includes changes to the .rspec file and
`spec_helper.rb`.

Finally, this commit removes a lot of tests that were directly or
indirectly testing either ActiveRecord functionality (through the use of
doubles/mocks) or other module functionality (which is redundant, since
those modules are tested directly).

- Add SQLite to development dependencies
- Modify `.rspec` file to include `spec_helper.rb` in every spec
- Add a lot of models for the various specs to use and a schema, which
  ActiveRecord loads
- Update specs to use the new AR-backed models instead of mocks
- Update specs to remove redundant and/or unnecessary tests
- Update specs to new RSpec syntax/DSL
  • Loading branch information
lleger committed Feb 12, 2015
1 parent b9d15e1 commit b328353
Show file tree
Hide file tree
Showing 26 changed files with 391 additions and 349 deletions.
1 change: 1 addition & 0 deletions .rspec
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
--color
--require spec_helper
3 changes: 2 additions & 1 deletion consistency_fail.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ EOF
s.license = "MIT"

s.add_development_dependency "activerecord", "~>3.0"
s.add_development_dependency "rspec", "~>3.1"
s.add_development_dependency "sqlite3", "~>1.3"
s.add_development_dependency "rspec", "~>3.2"

s.files = `git ls-files`.split("\n")
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
Expand Down
55 changes: 37 additions & 18 deletions spec/index_spec.rb
Original file line number Diff line number Diff line change
@@ -1,40 +1,59 @@
require 'spec_helper'
require 'consistency_fail/index'

describe ConsistencyFail::Index do


let(:index) do
ConsistencyFail::Index.new(
CorrectAddress,
CorrectAddress.table_name,
["city", "state"]
)
end

describe "value objectiness" do
it "holds onto model, table name, and columns" do
model = double("model")
index = ConsistencyFail::Index.new(model, "addresses", ["city", "state"])
expect(index.model).to eq(model)
expect(index.table_name).to eq("addresses")
expect(index.columns).to eq(["city", "state"])
expect(index.model).to eq(CorrectAddress)
expect(index.table_name).to eq("correct_addresses")
expect(index.columns).to eq(
["city", "state"]
)
end

it "leaves columns in the initial order (since we only care about presence, not performance)" do
index = ConsistencyFail::Index.new(double('model'), "addresses", ["state", "city"])
expect(index.columns).to eq(["state", "city"])
expect(index.columns).to eq(
["city", "state"]
)
end
end

describe "equality test" do
describe "equality test" do
it "passes when everything matches" do
expect(ConsistencyFail::Index.new(double('model'), "addresses", ["city", "state"])).to eq(
ConsistencyFail::Index.new(double('model'),"addresses", ["city", "state"])
expect(index).to eq(
ConsistencyFail::Index.new(
"CorrectAddress".constantize,
"correct_addresses",
["city", "state"]
)
)
end

it "fails when tables are different" do
expect(ConsistencyFail::Index.new(double('model'),"locations", ["city", "state"])).not_to eq(
ConsistencyFail::Index.new(double('model'),"addresses", ["city", "state"])
expect(index).not_to eq(
ConsistencyFail::Index.new(
CorrectAttachment,
CorrectAttachment.table_name,
["attachable_id", "attachable_type"]
)
)
end

it "fails when columns are different" do
expect(ConsistencyFail::Index.new(double('model'),"addresses", ["city", "state"])).not_to eq(
ConsistencyFail::Index.new(double('model'),"addresses", ["state", "zip"])
expect(index).not_to eq(
ConsistencyFail::Index.new(
CorrectAddress,
CorrectAddress.table_name,
["correct_user_id"]
)
)
end
end

end
103 changes: 14 additions & 89 deletions spec/introspectors/has_one_spec.rb
Original file line number Diff line number Diff line change
@@ -1,96 +1,21 @@
require 'spec_helper'
require 'consistency_fail/introspectors/table_data'
require 'consistency_fail/introspectors/has_one'

describe ConsistencyFail::Introspectors::HasOne do
def introspector(model)
ConsistencyFail::Introspectors::HasOne.new(model)
end

describe "instances of has_one" do
it "finds none" do
model = fake_ar_model("User")
allow(model).to receive(:reflect_on_all_associations).and_return([])

expect(subject.instances(model)).to eq([])
end

it "finds one" do
model = fake_ar_model("User")
association = double("association", :macro => :has_one, :options => {})
allow(model).to receive(:reflect_on_all_associations).and_return([association])

expect(subject.instances(model)).to eq([association])
end

it "finds other associations, but not has_one" do
model = fake_ar_model("User")
validation = double("validation", :macro => :has_many)
allow(model).to receive(:reflect_on_all_associations).and_return([validation])

expect(subject.instances(model)).to eq([])
end

it "finds one, but it's a polymorphic association" do
model = fake_ar_model("User")
association = double("association", :macro => :has_one, :options => {:as => "addressable"})
allow(model).to receive(:reflect_on_all_associations).and_return([association])

expect(subject.instances(model)).to eq([])
end

it "finds one, but it's a :through association" do
model = fake_ar_model("User")
association = double("association", :macro => :has_one, :options => {:through => :amodel})
allow(model).to receive(:reflect_on_all_associations).and_return([association])

expect(subject.instances(model)).to eq([])
end
end


describe "finding missing indexes" do
before do
@association = double("association", :macro => :has_one, :options => {})
@model = fake_ar_model("User", :table_exists? => true,
:table_name => "users",
:class_name => "User",
:reflect_on_all_associations => [@association])
@address_class = double("Address Class")
@address_string = "Address"
allow(@address_string).to receive(:constantize).and_return(@address_class)
end

it "finds one" do
allow(@association).to receive_messages(:table_name => :addresses, :class_name => @address_string, :foreign_key => "user_id")
allow(@address_class).to receive_message_chain(:connection, :indexes).with("addresses").and_return([])

indexes = subject.missing_indexes(@model)
expect(indexes).to eq([ConsistencyFail::Index.new(fake_ar_model("Address"), "addresses", ["user_id"])])
end

it "finds one in Rails 3.0.x (where foreign_key is not defined)" do
allow(@association).to receive_messages(:table_name => :addresses, :class_name => @address_string, :primary_key_name => "user_id")
allow(@address_class).to receive_message_chain(:connection, :indexes).with("addresses").and_return([])

indexes = subject.missing_indexes(@model)
expect(indexes).to eq([ConsistencyFail::Index.new(fake_ar_model("Address"), "addresses", ["user_id"])])
end

indexes = subject.missing_indexes(WrongUser)

expect(indexes).to eq([
ConsistencyFail::Index.new(
WrongAddress,
WrongAddress.table_name,
["wrong_user_id"]
)
])
end

it "finds none when they're already in place" do
allow(@association).to receive_messages(:table_name => :addresses, :class_name => @address_string, :foreign_key => "user_id")
index = ConsistencyFail::Index.new(double('model'), "addresses", ["user_id"])

fake_connection = double("connection")
allow(@address_class).to receive_message_chain(:connection).and_return(fake_connection)

allow(ConsistencyFail::Introspectors::TableData).to receive_message_chain(:new, :unique_indexes_by_table).
with(@address_class, fake_connection, "addresses").
and_return([index])

expect(subject.missing_indexes(@model)).to eq([])
expect(subject.missing_indexes(CorrectUser)).to eq([])
end

end

end


80 changes: 12 additions & 68 deletions spec/introspectors/polymorphic_spec.rb
Original file line number Diff line number Diff line change
@@ -1,77 +1,21 @@
require 'spec_helper'
require 'consistency_fail/introspectors/table_data'
require 'consistency_fail/introspectors/polymorphic'

describe ConsistencyFail::Introspectors::Polymorphic do
def introspector(model)
ConsistencyFail::Introspectors::Polymorphic.new(model)
end

describe "instances of polymorphic" do
it "finds none" do
model = fake_ar_model("User")
allow(model).to receive(:reflect_on_all_associations).and_return([])

expect(subject.instances(model)).to eq([])
end

it "finds one" do
model = fake_ar_model("User")
association = double("association", :macro => :has_one, :options => {:as => "addressable"})
allow(model).to receive(:reflect_on_all_associations).and_return([association])

expect(subject.instances(model)).to eq([association])
end

it "finds other has_one associations, but not polymorphic" do
model = fake_ar_model("User")
validation = double("association", :macro => :has_one, :options => {})
allow(model).to receive(:reflect_on_all_associations).and_return([validation])

expect(subject.instances(model)).to eq([])
end

it "finds other non has_one associations" do
model = fake_ar_model("User")
validation = double("association", :macro => :has_many)
allow(model).to receive(:reflect_on_all_associations).and_return([validation])

expect(subject.instances(model)).to eq([])
end
end


describe "finding missing indexes" do
before do
@association = double("association", :macro => :has_one, :options => {:as => "addressable"})
@model = fake_ar_model("User", :table_exists? => true,
:table_name => "users",
:class_name => "User",
:reflect_on_all_associations => [@association])
@address_class = double("Address Class")
@address_string = "Address"
allow(@address_string).to receive(:constantize).and_return(@address_class)
end

it "finds one" do
allow(@association).to receive_messages(:table_name => :addresses, :class_name => @address_string)
allow(@address_class).to receive_message_chain(:connection, :indexes).with("addresses").and_return([])

indexes = subject.missing_indexes(@model)
expect(indexes).to eq([ConsistencyFail::Index.new(fake_ar_model("Address"), "addresses", ["addressable_type", "addressable_id"])])
indexes = subject.missing_indexes(WrongPost)

expect(indexes).to eq([
ConsistencyFail::Index.new(
WrongAttachment,
WrongAttachment.table_name,
["attachable_type", "attachable_id"]
)
])
end

it "finds none when they're already in place" do
allow(@association).to receive_messages(:table_name => :addresses, :class_name => @address_string)
index = ConsistencyFail::Index.new(double('model'), "addresses", ["addressable_type", "addressable_id"])

fake_connection = double("connection")
allow(@address_class).to receive_message_chain(:connection).and_return(fake_connection)

allow(ConsistencyFail::Introspectors::TableData).to receive_message_chain(:new, :unique_indexes_by_table).
with(@address_class, fake_connection, "addresses").
and_return([index])

expect(subject.missing_indexes(@model)).to eq([])
expect(subject.missing_indexes(CorrectPost)).to eq([])
end
end

end
78 changes: 42 additions & 36 deletions spec/introspectors/table_data_spec.rb
Original file line number Diff line number Diff line change
@@ -1,52 +1,58 @@
require 'spec_helper'
require 'consistency_fail/introspectors/table_data'

describe ConsistencyFail::Introspectors::TableData do

describe "finding unique indexes" do
it "finds none when the table does not exist" do
model = fake_ar_model("User", :table_exists? => false)

expect(subject.unique_indexes(model)).to eq([])
expect(subject.unique_indexes(Nonexistent)).to be_empty
end

it "gets one" do
model = fake_ar_model("User", :table_exists? => true,
:table_name => "users")

allow(model).to receive_message_chain(:connection, :indexes).
with("users").
and_return([fake_index_on(["a"], :unique => true)])

indexes = subject.unique_indexes(model)
expect(indexes).to eq([ConsistencyFail::Index.new(double('model'), "users", ["a"])])
index = ConsistencyFail::Index.new(
CorrectAddress,
CorrectAddress.table_name,
["correct_user_id"]
)

expect(
ConsistencyFail::Introspectors::TableData.new.unique_indexes_by_table(
CorrectAddress,
ActiveRecord::Base.connection,
CorrectAddress.table_name
)
).to eq [index]
end

it "doesn't get non-unique indexes" do
model = fake_ar_model("User", :table_exists? => true,
:table_name => "users")

allow(model).to receive_message_chain(:connection, :indexes).
with("users").
and_return([fake_index_on(["a"], :unique => false)])

expect(subject.unique_indexes(model)).to eq([])
expect(
ConsistencyFail::Introspectors::TableData.new.unique_indexes_by_table(
WrongAddress,
ActiveRecord::Base.connection,
WrongAddress.table_name
)
).to be_empty
end

it "gets multiple unique indexes" do
model = fake_ar_model("User", :table_exists? => true,
:table_name => "users")

allow(model).to receive_message_chain(:connection, :indexes).
with("users").
and_return([fake_index_on(["a"], :unique => true),
fake_index_on(["b", "c"], :unique => true)])

indexes = subject.unique_indexes(model)
expect(indexes.size).to eq(2)
expect(indexes).to eq([ConsistencyFail::Index.new(double('model'), "users", ["a"]),
ConsistencyFail::Index.new(double('model'), "users", ["b", "c"])])
indexes = [
ConsistencyFail::Index.new(
CorrectAttachment,
CorrectAttachment.table_name,
["name"]
),
ConsistencyFail::Index.new(
CorrectAttachment,
CorrectAttachment.table_name,
["attachable_id", "attachable_type"]
)
]

expect(
ConsistencyFail::Introspectors::TableData.new.unique_indexes_by_table(
CorrectAttachment,
ActiveRecord::Base.connection,
CorrectAttachment.table_name
)
).to eq indexes
end
end

end

Loading

0 comments on commit b328353

Please sign in to comment.