Improve failure message for enum matcher

When the enum matcher fails, the message it generates is not as clear as
it could be, particularly around showing the expected enum values versus
the actual ones. This commit expands the failure message to be more
helpful (and ensures that the description of the matcher is kept
compact).
This commit is contained in:
Elliot Winkler 2019-06-09 01:57:09 -06:00
parent 47e21951b6
commit 47f47d0d7a
2 changed files with 390 additions and 165 deletions

View File

@ -144,33 +144,24 @@ module Shoulda
end
def description
description = "define :#{attribute_name} as an enum, backed by "
description = "#{simple_description} backed by "
description << Shoulda::Matchers::Util.a_or_an(expected_column_type)
if options[:expected_prefix]
description << ', using a prefix of '
description << "#{options[:expected_prefix].inspect}"
end
if options[:expected_suffix]
if options[:expected_prefix]
description << ' and'
else
description << ', using'
end
description << ' a suffix of '
description << "#{options[:expected_suffix].inspect}"
end
if presented_expected_enum_values.any?
description << ', with possible values '
if expected_enum_values.any?
description << ' with values '
description << Shoulda::Matchers::Util.inspect_value(
presented_expected_enum_values,
expected_enum_values,
)
end
if options[:prefix]
description << ", prefix: #{options[:prefix].inspect}"
end
if options[:suffix]
description << ", suffix: #{options[:suffix].inspect}"
end
description
end
@ -187,13 +178,13 @@ module Shoulda
with_values(expected_enum_values)
end
def with_prefix(expected_prefix = attribute_name)
options[:expected_prefix] = expected_prefix
def with_prefix(expected_prefix = true)
options[:prefix] = expected_prefix
self
end
def with_suffix(expected_suffix = attribute_name)
options[:expected_suffix] = expected_suffix
def with_suffix(expected_suffix = true)
options[:suffix] = expected_suffix
self
end
@ -212,13 +203,14 @@ module Shoulda
end
def failure_message
message = "Expected #{model} to #{expectation}"
message =
if enum_defined?
"Expected #{model} to #{expectation}. "
else
"Expected #{model} to #{expectation}, but "
end
if failure_reason
message << ". However, #{failure_reason}"
end
message << '.'
message << failure_message_continuation + '.'
Shoulda::Matchers.word_wrap(message)
end
@ -230,18 +222,63 @@ module Shoulda
private
attr_reader :attribute_name, :options, :record, :failure_reason
attr_reader :attribute_name, :options, :record,
:failure_message_continuation
def expectation
description
if enum_defined?
expectation = "#{simple_description} backed by "
expectation << Shoulda::Matchers::Util.a_or_an(expected_column_type)
if expected_enum_values.any?
expectation << ', mapping '
expectation << presented_enum_mapping(
normalized_expected_enum_values,
)
end
if expected_prefix
expectation <<
if expected_suffix
', '
else
' and '
end
expectation << 'prefixing accessor methods with '
expectation << "#{expected_prefix}_".inspect
end
if expected_suffix
expectation <<
if expected_prefix
', and '
else
' and '
end
expectation << 'suffixing accessor methods with '
expectation << "_#{expected_suffix}".inspect
end
expectation
else
simple_description
end
end
def presented_expected_enum_values
if expected_enum_values.is_a?(Hash)
expected_enum_values.symbolize_keys
else
expected_enum_values
end
def simple_description
"define :#{attribute_name} as an enum"
end
def presented_enum_mapping(enum_values)
enum_values.
map { |output_to_input|
output_to_input.
map(&Shoulda::Matchers::Util.method(:inspect_value)).
join(' to ')
}.
to_sentence
end
def normalized_expected_enum_values
@ -256,14 +293,6 @@ module Shoulda
options[:expected_enum_values]
end
def presented_actual_enum_values
if expected_enum_values.is_a?(Array)
to_array(actual_enum_values)
else
to_hash(actual_enum_values).symbolize_keys
end
end
def normalized_actual_enum_values
to_hash(actual_enum_values)
end
@ -276,7 +305,8 @@ module Shoulda
if model.defined_enums.include?(attribute_name.to_s)
true
else
@failure_reason = "no such enum exists in #{model}"
@failure_message_continuation =
"no such enum exists on #{model}"
false
end
end
@ -289,11 +319,9 @@ module Shoulda
if passed
true
else
@failure_reason =
"the actual enum values for #{attribute_name.inspect} are " +
Shoulda::Matchers::Util.inspect_value(
presented_actual_enum_values,
)
@failure_message_continuation =
"However, #{attribute_name.inspect} actually maps " +
presented_enum_mapping(normalized_actual_enum_values)
false
end
end
@ -302,8 +330,8 @@ module Shoulda
if column.type == expected_column_type.to_sym
true
else
@failure_reason =
"#{attribute_name.inspect} is " +
@failure_message_continuation =
"However, #{attribute_name.inspect} is " +
Shoulda::Matchers::Util.a_or_an(column.type) +
' column'
false
@ -330,30 +358,59 @@ module Shoulda
if passed
true
else
@failure_reason =
if options[:expected_prefix]
if options[:expected_suffix]
'it was defined with either a different prefix, a ' +
'different suffix, or neither one at all'
else
'it was defined with either a different prefix or none at all'
end
elsif options[:expected_suffix]
'it was defined with either a different suffix or none at all'
message = "#{attribute_name.inspect} does map to these "
message << 'values, but the enum is '
if expected_prefix
if expected_suffix
message << 'configured with either a different prefix or '
message << 'suffix, or no prefix or suffix at all'
else
message << 'configured with either a different prefix or no '
message << 'prefix at all'
end
elsif expected_suffix
message << 'configured with either a different suffix or no '
message << 'suffix at all'
end
message << " (we can't tell which)"
@failure_message_continuation = message
false
end
end
def expected_singleton_methods
expected_enum_value_names.map do |name|
[options[:expected_prefix], name, options[:expected_suffix]].
[expected_prefix, name, expected_suffix].
select(&:present?).
join('_').
to_sym
end
end
def expected_prefix
if options.include?(:prefix)
if options[:prefix] == true
attribute_name#.to_sym
else
options[:prefix]#.to_sym
end
end
end
def expected_suffix
if options.include?(:suffix)
if options[:suffix] == true
attribute_name#.to_sym
else
options[:suffix]#.to_sym
end
end
end
def to_hash(value)
if value.is_a?(Array)
value.each_with_index.inject({}) do |hash, (item, index)|

View File

@ -9,8 +9,8 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
column_type: :integer,
)
message = format_message(<<-MESSAGE)
Expected Example to define :attrs as an enum, backed by an integer.
However, no such enum exists in Example.
Expected Example to define :attrs as an enum, but no such enum exists on
Example.
MESSAGE
assertion = lambda do
@ -28,8 +28,8 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
end
message = format_message(<<-MESSAGE)
Expected Example to define :attr as an enum, backed by an integer.
However, no such enum exists in Example.
Expected Example to define :attr as an enum, but no such enum exists on
Example.
MESSAGE
assertion = lambda do
@ -48,8 +48,8 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
attribute_name: :attr,
)
message = format_message(<<-MESSAGE)
Expected Example to define :attr as an enum, backed by an integer.
However, no such enum exists in Example.
Expected Example to define :attr as an enum, but no such enum exists
on Example.
MESSAGE
assertion = lambda do
@ -68,7 +68,7 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
column_type: :string,
)
message = format_message(<<-MESSAGE)
Expected Example to define :attr as an enum, backed by an integer.
Expected Example to define :attr as an enum backed by an integer.
However, :attr is a string column.
MESSAGE
@ -81,30 +81,23 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
end
context 'if the attribute is defined as an enum' do
it 'accepts' do
it 'matches' do
record = build_record_with_array_values(attribute_name: :attr)
expect(record).to define_enum_for(:attr)
expect { define_enum_for(:attr) }.
to match_against(record).
or_fail_with(<<-MESSAGE, wrap: true)
Expected Example not to define :attr as an enum backed by an
integer, but it did.
MESSAGE
end
context 'and the matcher is negated' do
it 'rejects with an appropriate failure message' do
record = build_record_with_array_values(
model_name: 'Example',
attribute_name: :attr,
column_type: :integer,
)
message = format_message(<<-MESSAGE)
Expected Example not to define :attr as an enum, backed by an integer,
but it did.
MESSAGE
it 'has the right description' do
matcher = define_enum_for(:attr)
assertion = lambda do
expect(record).not_to define_enum_for(:attr)
end
expect(&assertion).to fail_with_message(message)
end
expect(matcher.description).to eq(<<~MESSAGE.strip)
define :attr as an enum backed by an integer
MESSAGE
end
end
end
@ -118,9 +111,8 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
attribute_name: :attr,
)
message = format_message(<<-MESSAGE)
Expected Example to define :attr as an enum, backed by an integer,
with possible values ["open", "close"]. However, no such enum
exists in Example.
Expected Example to define :attr as an enum, but no such enum
exists on Example.
MESSAGE
assertion = lambda do
@ -142,9 +134,10 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
values: ['published', 'unpublished', 'draft'],
)
message = format_message(<<-MESSAGE)
Expected Example to define :attr as an enum, backed by an integer,
with possible values ["open", "close"]. However, the actual
enum values for :attr are ["published", "unpublished", "draft"].
Expected Example to define :attr as an enum backed by an integer,
mapping "open" to 0 and "close" to 1. However, :attr
actually maps "published" to 0, "unpublished" to 1, and
"draft" to 2.
MESSAGE
assertion = lambda do
@ -158,14 +151,33 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
end
context 'and the enum values match' do
it 'accepts' do
it 'matches' do
record = build_record_with_array_values(
attribute_name: :attr,
values: ['published', 'unpublished', 'draft'],
)
expect(record).to define_enum_for(:attr).
matcher = lambda do
define_enum_for(:attr).
with_values(['published', 'unpublished', 'draft'])
end
expect(&matcher).
to match_against(record).
or_fail_with(<<-MESSAGE, wrap: true)
Expected Example not to define :attr as an enum backed by an
integer, mapping "published" to 0, "unpublished" to 1,
and "draft" to 2, but it did.
MESSAGE
end
it 'has the right description' do
matcher = define_enum_for(:attr).
with_values(['published', 'unpublished', 'draft'])
expect(matcher.description).to eq(<<~MESSAGE.strip)
define :attr as an enum backed by an integer with values ["published", "unpublished", "draft"]
MESSAGE
end
end
end
@ -179,9 +191,8 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
attribute_name: :attr,
)
message = format_message(<<-MESSAGE)
Expected Example to define :attr as an enum, backed by an integer,
with possible values {active: 5, archived: 10}. However, no such
enum exists in Example.
Expected Example to define :attr as an enum, but no such enum exists
on Example.
MESSAGE
assertion = lambda do
@ -203,9 +214,9 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
values: { active: 0, archived: 1 },
)
message = format_message(<<-MESSAGE)
Expected Example to define :attr as an enum, backed by an integer,
with possible values {active: 5, archived: 10}. However, the
actual enum values for :attr are {active: 0, archived: 1}.
Expected Example to define :attr as an enum backed by an integer,
mapping "active" to 5 and "archived" to 10. However, :attr
actually maps "active" to 0 and "archived" to 1.
MESSAGE
assertion = lambda do
@ -220,28 +231,64 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
context 'and the enum values match' do
context 'when expected enum values are a hash' do
it 'accepts' do
it 'matches' do
record = build_record_with_hash_values(
attribute_name: :attr,
values: { active: 0, archived: 1 },
)
expect(record).
to define_enum_for(:attr).
matcher = lambda do
define_enum_for(:attr).
with_values(active: 0, archived: 1)
end
expect(&matcher).
to match_against(record).
or_fail_with(<<-MESSAGE, wrap: true)
Expected Example not to define :attr as an enum backed by an
integer, mapping "active" to 0 and "archived" to 1,
but it did.
MESSAGE
end
it 'has the right description' do
matcher = define_enum_for(:attr).
with_values(active: 0, archived: 1)
expect(matcher.description).to eq(<<~MESSAGE.strip)
define :attr as an enum backed by an integer with values {active: 0, archived: 1}
MESSAGE
end
end
context 'when expected enum values are an array' do
it 'accepts' do
it 'matches' do
record = build_record_with_hash_values(
attribute_name: :attr,
values: { active: 0, archived: 1 },
)
expect(record).
to define_enum_for(:attr).
matcher = lambda do
define_enum_for(:attr).
with_values(['active', 'archived'])
end
expect(&matcher).
to match_against(record).
or_fail_with(<<-MESSAGE, wrap: true)
Expected Example not to define :attr as an enum backed by an
integer, mapping "active" to 0 and "archived" to 1,
but it did.
MESSAGE
end
it 'has the right description' do
matcher = define_enum_for(:attr).
with_values(['active', 'archived'])
expect(matcher.description).to eq(<<~MESSAGE.strip)
define :attr as an enum backed by an integer with values ["active", "archived"]
MESSAGE
end
end
end
@ -276,7 +323,7 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
column_type: :integer,
)
message = format_message(<<-MESSAGE)
Expected Example to define :attr as an enum, backed by a string.
Expected Example to define :attr as an enum backed by a string.
However, :attr is an integer column.
MESSAGE
@ -291,15 +338,30 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
end
context 'if the column storing the attribute is of the same type' do
it 'accepts' do
it 'matches' do
record = build_record_with_array_values(
attribute_name: :attr,
column_type: :string,
)
expect(record).
to define_enum_for(:attr).
backed_by_column_of_type(:string)
matcher = lambda do
define_enum_for(:attr).backed_by_column_of_type(:string)
end
expect(&matcher).
to match_against(record).
or_fail_with(<<-MESSAGE, wrap: true)
Expected Example not to define :attr as an enum backed by a string,
but it did.
MESSAGE
end
it 'has the right description' do
matcher = define_enum_for(:attr).backed_by_column_of_type(:string)
expect(matcher.description).to eq(<<~MESSAGE.strip)
define :attr as an enum backed by a string
MESSAGE
end
end
end
@ -324,10 +386,11 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
end
message = format_message(<<-MESSAGE)
Expected Example to define :attr as an enum, backed by an integer,
using a prefix of :foo, with possible values [:active,
:archived]. However, it was defined with either a different
prefix or none at all.
Expected Example to define :attr as an enum backed by an integer,
mapping "active" to 0 and "archived" to 1 and prefixing
accessor methods with "foo_". :attr does map to these values, but
the enum is configured with either a different prefix or no prefix
at all (we can't tell which).
MESSAGE
expect(&assertion).to fail_with_message(message)
@ -352,10 +415,11 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
end
message = format_message(<<-MESSAGE)
Expected Example to define :attr as an enum, backed by an integer,
using a prefix of :bar, with possible values [:active,
:archived]. However, it was defined with either a different
prefix or none at all.
Expected Example to define :attr as an enum backed by an integer,
mapping "active" to 0 and "archived" to 1 and prefixing
accessor methods with "bar_". :attr does map to these values, but
the enum is configured with either a different prefix or no prefix
at all (we can't tell which).
MESSAGE
expect(&assertion).to fail_with_message(message)
@ -363,7 +427,7 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
end
context 'if the attribute was defined with the same prefix' do
it 'accepts' do
it 'matches' do
record = build_record_with_array_values(
model_name: 'Example',
attribute_name: :attr,
@ -371,10 +435,29 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
prefix: :foo,
)
expect(record).
to define_enum_for(:attr).
matcher = lambda do
define_enum_for(:attr).
with_values([:active, :archived]).
with_prefix(:foo)
end
expect(&matcher).
to match_against(record).
or_fail_with(<<-MESSAGE, wrap: true)
Expected Example not to define :attr as an enum backed by an
integer, mapping "active" to 0 and "archived" to 1 and
prefixing accessor methods with "foo_", but it did.
MESSAGE
end
it 'has the right description' do
matcher = define_enum_for(:attr).
with_values([:active, :archived]).
with_prefix(:foo)
expect(matcher.description).to eq(<<~MESSAGE.strip)
define :attr as an enum backed by an integer with values [:active, :archived], prefix: :foo
MESSAGE
end
end
end
@ -397,10 +480,11 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
end
message = format_message(<<-MESSAGE)
Expected Example to define :attr as an enum, backed by an integer,
using a prefix of :attr, with possible values [:active,
:archived]. However, it was defined with either a different
prefix or none at all.
Expected Example to define :attr as an enum backed by an integer,
mapping "active" to 0 and "archived" to 1 and prefixing
accessor methods with "attr_". :attr does map to these values, but
the enum is configured with either a different prefix or no prefix
at all (we can't tell which).
MESSAGE
expect(&assertion).to fail_with_message(message)
@ -408,7 +492,7 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
end
context 'if the attribute was defined with a prefix' do
it 'accepts' do
it 'matches' do
record = build_record_with_array_values(
model_name: 'Example',
attribute_name: :attr,
@ -416,10 +500,29 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
prefix: true,
)
expect(record).
to define_enum_for(:attr).
matcher = lambda do
define_enum_for(:attr).
with_values([:active, :archived]).
with_prefix
end
expect(&matcher).
to match_against(record).
or_fail_with(<<-MESSAGE, wrap: true)
Expected Example not to define :attr as an enum backed by an
integer, mapping "active" to 0 and "archived" to 1 and
prefixing accessor methods with "attr_", but it did.
MESSAGE
end
it 'has the right description' do
matcher = define_enum_for(:attr).
with_values([:active, :archived]).
with_prefix
expect(matcher.description).to eq(<<~MESSAGE.strip)
define :attr as an enum backed by an integer with values [:active, :archived], prefix: true
MESSAGE
end
end
end
@ -444,10 +547,11 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
end
message = format_message(<<-MESSAGE)
Expected Example to define :attr as an enum, backed by an integer,
using a suffix of :foo, with possible values [:active,
:archived]. However, it was defined with either a different
suffix or none at all.
Expected Example to define :attr as an enum backed by an integer,
mapping "active" to 0 and "archived" to 1 and suffixing
accessor methods with "_foo". :attr does map to these values, but
the enum is configured with either a different suffix or no suffix
at all (we can't tell which).
MESSAGE
expect(&assertion).to fail_with_message(message)
@ -472,10 +576,11 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
end
message = format_message(<<-MESSAGE)
Expected Example to define :attr as an enum, backed by an integer,
using a suffix of :bar, with possible values [:active,
:archived]. However, it was defined with either a different
suffix or none at all.
Expected Example to define :attr as an enum backed by an integer,
mapping "active" to 0 and "archived" to 1 and suffixing
accessor methods with "_bar". :attr does map to these values, but
the enum is configured with either a different suffix or no suffix
at all (we can't tell which).
MESSAGE
expect(&assertion).to fail_with_message(message)
@ -483,7 +588,7 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
end
context 'if the attribute was defined with the same suffix' do
it 'accepts' do
it 'matches' do
record = build_record_with_array_values(
model_name: 'Example',
attribute_name: :attr,
@ -491,10 +596,29 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
suffix: :foo,
)
expect(record).
to define_enum_for(:attr).
matcher = lambda do
define_enum_for(:attr).
with_values([:active, :archived]).
with_suffix(:foo)
end
expect(&matcher).
to match_against(record).
or_fail_with(<<-MESSAGE, wrap: true)
Expected Example not to define :attr as an enum backed by an
integer, mapping "active" to 0 and "archived" to 1 and
suffixing accessor methods with "_foo", but it did.
MESSAGE
end
it 'has the right description' do
matcher = define_enum_for(:attr).
with_values([:active, :archived]).
with_suffix(:foo)
expect(matcher.description).to eq(<<~MESSAGE.strip)
define :attr as an enum backed by an integer with values [:active, :archived], suffix: :foo
MESSAGE
end
end
end
@ -517,10 +641,11 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
end
message = format_message(<<-MESSAGE)
Expected Example to define :attr as an enum, backed by an integer,
using a suffix of :attr, with possible values [:active,
:archived]. However, it was defined with either a different
suffix or none at all.
Expected Example to define :attr as an enum backed by an integer,
mapping "active" to 0 and "archived" to 1 and suffixing
accessor methods with "_attr". :attr does map to these values, but
the enum is configured with either a different suffix or no suffix
at all (we can't tell which).
MESSAGE
expect(&assertion).to fail_with_message(message)
@ -528,7 +653,7 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
end
context 'if the attribute was defined with a suffix' do
it 'accepts' do
it 'matches' do
record = build_record_with_array_values(
model_name: 'Example',
attribute_name: :attr,
@ -536,10 +661,29 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
suffix: true,
)
expect(record).
to define_enum_for(:attr).
matcher = lambda do
define_enum_for(:attr).
with_values([:active, :archived]).
with_suffix
end
expect(&matcher).
to match_against(record).
or_fail_with(<<-MESSAGE, wrap: true)
Expected Example not to define :attr as an enum backed by an
integer, mapping "active" to 0 and "archived" to 1 and
suffixing accessor methods with "_attr", but it did.
MESSAGE
end
it 'has the right description' do
matcher = define_enum_for(:attr).
with_values([:active, :archived]).
with_suffix
expect(matcher.description).to eq(<<~MESSAGE.strip)
define :attr as an enum backed by an integer with values [:active, :archived], suffix: true
MESSAGE
end
end
end
@ -566,10 +710,12 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
end
message = format_message(<<-MESSAGE)
Expected Example to define :attr as an enum, backed by an integer,
using a prefix of :whatever and a suffix of :bar, with possible
values [:active, :archived]. However, it was defined with either
a different prefix, a different suffix, or neither one at all.
Expected Example to define :attr as an enum backed by an integer,
mapping "active" to 0 and "archived" to 1, prefixing
accessor methods with "whatever_", and suffixing accessor methods
with "_bar". :attr does map to these values, but the enum is
configured with either a different prefix or suffix, or no prefix or
suffix at all (we can't tell which).
MESSAGE
expect(&assertion).to fail_with_message(message)
@ -595,11 +741,12 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
end
message = format_message(<<-MESSAGE)
Expected Example to define :attr as an enum, backed by an integer,
using a prefix of :foo and a suffix of :whatever, with possible
values [:active, :archived]. However, it was defined with
either a different prefix, a different suffix, or neither one at
all.
Expected Example to define :attr as an enum backed by an integer,
mapping "active" to 0 and "archived" to 1, prefixing
accessor methods with "foo_", and suffixing accessor methods with
"_whatever". :attr does map to these values, but the enum is
configured with either a different prefix or suffix, or no prefix
or suffix at all (we can't tell which).
MESSAGE
expect(&assertion).to fail_with_message(message)
@ -607,7 +754,7 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
end
context 'if the attribute was defined with the same prefix and suffix' do
it 'accepts' do
it 'matches' do
record = build_record_with_array_values(
model_name: 'Example',
attribute_name: :attr,
@ -616,11 +763,32 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
suffix: :bar,
)
expect(record).
to define_enum_for(:attr).
matcher = lambda do
define_enum_for(:attr).
with_values([:active, :archived]).
with_prefix(:foo).
with_suffix(:bar)
end
expect(&matcher).
to match_against(record).
or_fail_with(<<-MESSAGE, wrap: true)
Expected Example not to define :attr as an enum backed by an
integer, mapping "active" to 0 and "archived" to 1,
prefixing accessor methods with "foo_", and suffixing accessor
methods with "_bar", but it did.
MESSAGE
end
it 'has the right description' do
matcher = define_enum_for(:attr).
with_values([:active, :archived]).
with_prefix(:foo).
with_suffix(:bar)
expect(matcher.description).to eq(<<~MESSAGE.strip)
define :attr as an enum backed by an integer with values [:active, :archived], prefix: :foo, suffix: :bar
MESSAGE
end
end
end