Tweak have_implicit_order_column + tests

* Make the error messaging a little more natural
* Align tests to the current style (specifically using `match_against`)
This commit is contained in:
Elliot Winkler 2020-03-20 12:18:40 -06:00
parent 67af0dfc89
commit 6a2e7551b2
4 changed files with 148 additions and 135 deletions

View File

@ -67,8 +67,8 @@ GEM
bootsnap (1.4.5)
msgpack (~> 1.0)
builder (3.2.4)
byebug (11.1.1)
capybara (3.31.0)
byebug (11.0.1)
capybara (3.30.0)
addressable
mini_mime (>= 0.1.3)
nokogiri (~> 1.8)
@ -79,14 +79,14 @@ GEM
childprocess (3.0.0)
coderay (1.1.2)
concurrent-ruby (1.1.5)
crass (1.0.6)
crass (1.0.5)
diff-lcs (1.3)
erubi (1.9.0)
ffi (1.12.1)
ffi (1.11.3)
fssm (0.2.10)
globalid (0.4.2)
activesupport (>= 4.2.0)
i18n (1.8.2)
i18n (1.7.0)
concurrent-ruby (~> 1.0)
jaro_winkler (1.5.4)
jbuilder (2.9.1)
@ -103,31 +103,31 @@ GEM
marcel (0.3.3)
mimemagic (~> 0.3.2)
method_source (0.9.2)
mimemagic (0.3.4)
mimemagic (0.3.3)
mini_mime (1.0.2)
mini_portile2 (2.4.0)
minitest (5.14.0)
minitest (5.13.0)
msgpack (1.3.1)
multi_json (1.14.1)
nio4r (2.5.2)
nokogiri (1.10.7)
mini_portile2 (~> 2.4.0)
parallel (1.19.1)
parser (2.7.0.2)
parser (2.7.0.0)
ast (~> 2.4.0)
pg (1.2.2)
pg (1.2.0)
pry (0.12.2)
coderay (~> 1.1.0)
method_source (~> 0.9.0)
pry-byebug (3.8.0)
pry-byebug (3.7.0)
byebug (~> 11.0)
pry (~> 0.10)
public_suffix (4.0.3)
public_suffix (4.0.1)
puma (4.3.1)
nio4r (~> 2.0)
pygments.rb (1.2.1)
multi_json (>= 1.0.0)
rack (2.1.2)
rack (2.0.8)
rack-proxy (0.6.5)
rack
rack-test (1.1.0)
@ -173,12 +173,12 @@ GEM
rspec-core (~> 3.9.0)
rspec-expectations (~> 3.9.0)
rspec-mocks (~> 3.9.0)
rspec-core (3.9.1)
rspec-support (~> 3.9.1)
rspec-core (3.9.0)
rspec-support (~> 3.9.0)
rspec-expectations (3.9.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.9.0)
rspec-mocks (3.9.1)
rspec-mocks (3.9.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.9.0)
rspec-rails (3.9.0)
@ -189,20 +189,20 @@ GEM
rspec-expectations (~> 3.9.0)
rspec-mocks (~> 3.9.0)
rspec-support (~> 3.9.0)
rspec-support (3.9.2)
rubocop (0.79.0)
rspec-support (3.9.0)
rubocop (0.78.0)
jaro_winkler (~> 1.5.1)
parallel (~> 1.10)
parser (>= 2.7.0.1)
parser (>= 2.6)
rainbow (>= 2.2.2, < 4.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 1.7)
rubocop-rails (2.4.2)
rubocop-rails (2.4.1)
rack (>= 1.1)
rubocop (>= 0.72.0)
ruby-progressbar (1.10.1)
ruby_dep (1.5.0)
rubyzip (2.1.0)
rubyzip (2.0.0)
sass-rails (6.0.0)
sassc-rails (~> 2.1, >= 2.1.1)
sassc (2.2.1)
@ -213,7 +213,7 @@ GEM
sprockets (> 3.0)
sprockets-rails
tilt
selenium-webdriver (3.142.7)
selenium-webdriver (3.142.6)
childprocess (>= 0.5, < 4.0)
rubyzip (>= 1.2.2)
shoulda-context (1.2.2)
@ -239,8 +239,8 @@ GEM
turbolinks-source (5.2.0)
tzinfo (1.2.6)
thread_safe (~> 0.1)
unicode-display_width (1.6.1)
webdrivers (4.2.0)
unicode-display_width (1.6.0)
webdrivers (4.1.3)
nokogiri (~> 1.6)
rubyzip (>= 1.3.0)
selenium-webdriver (>= 3.0, < 4.0)
@ -253,7 +253,7 @@ GEM
websocket-extensions (0.1.4)
xpath (3.2.0)
nokogiri (~> 1.8)
yard (0.9.24)
yard (0.9.20)
zeitwerk (2.2.2)
zeus (0.15.14)
method_source (>= 0.6.7)
@ -298,4 +298,4 @@ DEPENDENCIES
zeus
BUNDLED WITH
1.17.2
1.17.3

View File

@ -1,8 +1,9 @@
module Shoulda
module Matchers
module ActiveRecord
# The `have_implicit_order_column` matcher tests that the model has `implicit_order_column`
# assigned to one of the table columns. (Rails 6+ only)
# The `have_implicit_order_column` matcher tests that the model has
# `implicit_order_column` assigned to one of the table columns.
# (Rails 6+ only.)
#
# class Product < ApplicationRecord
# self.implicit_order_column = :created_at
@ -38,52 +39,70 @@ module Shoulda
end
def failure_message
"Expected #{expectation} (#{@details})"
message =
if details
"Expected #{expectation} (#{details})."
else
"Expected #{expectation}."
end
Shoulda::Matchers.word_wrap(message)
end
def failure_message_when_negated
"Did not expect #{expectation}"
Shoulda::Matchers.word_wrap(
"Did not expect #{expectation}, but it did.",
)
end
def description
"have implicit_order_column assigned to #{@column}"
"have an implicit_order_column of :#{column}"
end
private
def column_exists?
matcher = HaveDbColumnMatcher.new(@column)
attr_reader :column, :subject, :details
if matcher.matches?(@subject)
def column_exists?
matcher = HaveDbColumnMatcher.new(column)
if matcher.matches?(subject)
true
else
@details = "#{model_class} does not have a db column named #{@column}"
@details =
"#{model.table_name} does not have #{a_or_an(":#{column}")} " +
'column'
false
end
end
def implicit_order_column_matches?
model_implicit_order_column = model_class.implicit_order_column
model_implicit_order_column = model.implicit_order_column
if model_implicit_order_column.to_s == @column.to_s
if model_implicit_order_column.to_s == column.to_s
true
else
@details = if model_implicit_order_column.nil?
"#{model_class} implicit_order_column is not set"
else
"#{model_class} implicit_order_column is " +
"set to #{model_implicit_order_column}"
end
@details =
if model_implicit_order_column
'its implicit_order_column is ' +
":#{model_implicit_order_column}"
else
'it does not have an implicit_order_column'
end
false
end
end
def model_class
@subject.class
def expectation
"#{model.name} to have an implicit_order_column of :#{column}"
end
def expectation
"#{model_class.name} to have implicit_order_column set to #{@column}"
def model
subject.class
end
def a_or_an(word)
Shoulda::Matchers::Util.a_or_an(word)
end
end
end

View File

@ -33,7 +33,7 @@ module Shoulda
end
def self.a_or_an(next_word)
if next_word =~ /\A[aeiou]/i && next_word != 'unique'
if next_word =~ /\A:?[aeiou]/i && next_word != 'unique'
"an #{next_word}"
else
"a #{next_word}"

View File

@ -2,169 +2,163 @@ require 'unit_spec_helper'
describe Shoulda::Matchers::ActiveRecord::HaveImplicitOrderColumnMatcher, type: :model do
if active_record_supports_implicit_order_column?
context 'when implicit_order_column is defined for the column' do
context 'when column name is a symbol' do
context 'when the model sets implicit_order_column to the given column' do
context 'when the given column name is a symbol' do
it 'accepts' do
record = record_with_implicit_order_column_on(
'created_at',
:created_at,
model_name: 'Employee',
columns: { created_at: :timestamp },
)
expect(record).to have_implicit_order_column(:created_at)
expect { have_implicit_order_column(:created_at) }.
to match_against(record).
or_fail_with(<<~MESSAGE, wrap: true)
Did not expect Employee to have an implicit_order_column of
:created_at, but it did.
MESSAGE
end
end
context 'when column name is a string' do
context 'when the given column name is a string' do
it 'accepts' do
record = record_with_implicit_order_column_on(
'created_at',
:created_at,
columns: { created_at: :timestamp },
)
expect(record).to have_implicit_order_column('created_at')
expect { have_implicit_order_column('created_at') }.
to match_against(record).
or_fail_with(<<~MESSAGE, wrap: true)
Did not expect Employee to have an implicit_order_column of
:created_at, but it did.
MESSAGE
end
end
end
context 'when implicit_order_column is defined for another column' do
context 'when column name is a symbol' do
context 'when the model sets implicit_order_column to another column' do
context 'when the given column name is a symbol' do
it 'rejects with an appropriate failure message' do
record = record_with_implicit_order_column_on(
'created_at',
:created_at,
columns: { created_at: :timestamp, email: :string },
)
assertion = lambda {
expect(record).to have_implicit_order_column(:email)
}
message = format_message(<<-MESSAGE, one_line: true)
Expected Employee to have implicit_order_column set to email
(Employee implicit_order_column is set to created_at)
MESSAGE
expect(&assertion).to fail_with_message(message)
expect { have_implicit_order_column(:email) }.
not_to match_against(record).
and_fail_with(<<~MESSAGE, wrap: true)
Expected Employee to have an implicit_order_column of :email
(its implicit_order_column is :created_at).
MESSAGE
end
end
context 'when column name is a string' do
context 'when the given column name is a string' do
it 'rejects with an appropriate failure message' do
record = record_with_implicit_order_column_on(
'created_at',
:created_at,
columns: { created_at: :timestamp, email: :string },
)
assertion = lambda {
expect(record).to have_implicit_order_column('email')
}
message = format_message(<<-MESSAGE, one_line: true)
Expected Employee to have implicit_order_column set to email
(Employee implicit_order_column is set to created_at)
MESSAGE
expect(&assertion).to fail_with_message(message)
expect { have_implicit_order_column('email') }.
not_to match_against(record).
and_fail_with(<<~MESSAGE, wrap: true)
Expected Employee to have an implicit_order_column of :email
(its implicit_order_column is :created_at).
MESSAGE
end
end
end
context 'when implicit_order_column is NOT defined on model' do
context 'when column name is a symbol' do
context 'when the model does NOT set implicit_order_column' do
context 'when the given column name is a symbol' do
it 'rejects with an appropriate failure message' do
record = record_without_implicit_order_column(
columns: { created_at: :timestamp },
)
assertion = lambda {
expect(record).to have_implicit_order_column(:created_at)
}
message = format_message(<<-MESSAGE, one_line: true)
Expected Employee to have implicit_order_column set to created_at
(Employee implicit_order_column is not set)
MESSAGE
expect(&assertion).to fail_with_message(message)
expect { have_implicit_order_column(:created_at) }.
not_to match_against(record).
and_fail_with(<<~MESSAGE, wrap: true)
Expected Employee to have an implicit_order_column of :created_at
(it does not have an implicit_order_column).
MESSAGE
end
end
context 'when column name is a string' do
context 'when the given column name is a string' do
it 'rejects with an appropriate failure message' do
record = record_without_implicit_order_column(
columns: { created_at: :timestamp },
)
assertion = lambda {
expect(record).to have_implicit_order_column('created_at')
}
message = format_message(<<-MESSAGE, one_line: true)
Expected Employee to have implicit_order_column set to created_at
(Employee implicit_order_column is not set)
MESSAGE
expect(&assertion).to fail_with_message(message)
expect { have_implicit_order_column('created_at') }.
not_to match_against(record).
and_fail_with(<<~MESSAGE, wrap: true)
Expected Employee to have an implicit_order_column of :created_at
(it does not have an implicit_order_column).
MESSAGE
end
end
end
context 'when given column does NOT exist' do
context 'when column name is a symbol' do
context 'when the given column does not exist on the table' do
context 'when the given column name is a symbol' do
it 'rejects with an appropriate failure message' do
record = record_without_implicit_order_column(
columns: { created_at: :timestamp },
)
assertion = lambda {
expect(record).to have_implicit_order_column(:whatever)
}
message = format_message(<<-MESSAGE, one_line: true)
Expected Employee to have implicit_order_column set to whatever
(Employee does not have a db column named whatever)
MESSAGE
expect(&assertion).to fail_with_message(message)
expect { have_implicit_order_column(:individual) }.
not_to match_against(record).
and_fail_with(<<~MESSAGE, wrap: true)
Expected Employee to have an implicit_order_column of :individual
(employees does not have an :individual column).
MESSAGE
end
end
context 'when column name is a string' do
context 'when the given column name is a string' do
it 'rejects with an appropriate failure message' do
record = record_without_implicit_order_column(
columns: { created_at: :timestamp },
)
assertion = lambda {
expect(record).to have_implicit_order_column('whatever')
}
message = format_message(<<-MESSAGE, one_line: true)
Expected Employee to have implicit_order_column set to whatever
(Employee does not have a db column named whatever)
MESSAGE
expect(&assertion).to fail_with_message(message)
expect { have_implicit_order_column('individual') }.
not_to match_against(record).
and_fail_with(<<~MESSAGE, wrap: true)
Expected Employee to have an implicit_order_column of :individual
(employees does not have an :individual column).
MESSAGE
end
end
end
describe 'description' do
it 'returns correct description' do
describe '#description' do
it 'returns the correct description' do
matcher = have_implicit_order_column(:created_at)
expect(matcher.description).to \
eq('have implicit_order_column assigned to created_at')
expect(matcher.description).to eq(
'have an implicit_order_column of :created_at',
)
end
end
def record_with_implicit_order_column_on(column_name, columns:)
define_model(:employee, columns) do |model|
model.implicit_order_column = column_name
end.new
def record_with_implicit_order_column_on(
column_name,
columns:,
model_name: 'Employee'
)
model = define_model(model_name, columns) do |m|
m.implicit_order_column = column_name
end
model.new
end
def record_without_implicit_order_column(columns:)
define_model(:employee, columns).new
def record_without_implicit_order_column(columns:, model_name: 'Employee')
define_model(model_name, columns).new
end
end
end