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:
parent
47e21951b6
commit
47f47d0d7a
|
@ -144,33 +144,24 @@ module Shoulda
|
||||||
end
|
end
|
||||||
|
|
||||||
def description
|
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)
|
description << Shoulda::Matchers::Util.a_or_an(expected_column_type)
|
||||||
|
|
||||||
if options[:expected_prefix]
|
if expected_enum_values.any?
|
||||||
description << ', using a prefix of '
|
description << ' with values '
|
||||||
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 '
|
|
||||||
description << Shoulda::Matchers::Util.inspect_value(
|
description << Shoulda::Matchers::Util.inspect_value(
|
||||||
presented_expected_enum_values,
|
expected_enum_values,
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if options[:prefix]
|
||||||
|
description << ", prefix: #{options[:prefix].inspect}"
|
||||||
|
end
|
||||||
|
|
||||||
|
if options[:suffix]
|
||||||
|
description << ", suffix: #{options[:suffix].inspect}"
|
||||||
|
end
|
||||||
|
|
||||||
description
|
description
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -187,13 +178,13 @@ module Shoulda
|
||||||
with_values(expected_enum_values)
|
with_values(expected_enum_values)
|
||||||
end
|
end
|
||||||
|
|
||||||
def with_prefix(expected_prefix = attribute_name)
|
def with_prefix(expected_prefix = true)
|
||||||
options[:expected_prefix] = expected_prefix
|
options[:prefix] = expected_prefix
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
def with_suffix(expected_suffix = attribute_name)
|
def with_suffix(expected_suffix = true)
|
||||||
options[:expected_suffix] = expected_suffix
|
options[:suffix] = expected_suffix
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -212,13 +203,14 @@ module Shoulda
|
||||||
end
|
end
|
||||||
|
|
||||||
def failure_message
|
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 << failure_message_continuation + '.'
|
||||||
message << ". However, #{failure_reason}"
|
|
||||||
end
|
|
||||||
|
|
||||||
message << '.'
|
|
||||||
|
|
||||||
Shoulda::Matchers.word_wrap(message)
|
Shoulda::Matchers.word_wrap(message)
|
||||||
end
|
end
|
||||||
|
@ -230,18 +222,63 @@ module Shoulda
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
attr_reader :attribute_name, :options, :record, :failure_reason
|
attr_reader :attribute_name, :options, :record,
|
||||||
|
:failure_message_continuation
|
||||||
|
|
||||||
def expectation
|
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
|
end
|
||||||
|
|
||||||
def presented_expected_enum_values
|
def simple_description
|
||||||
if expected_enum_values.is_a?(Hash)
|
"define :#{attribute_name} as an enum"
|
||||||
expected_enum_values.symbolize_keys
|
end
|
||||||
else
|
|
||||||
expected_enum_values
|
def presented_enum_mapping(enum_values)
|
||||||
end
|
enum_values.
|
||||||
|
map { |output_to_input|
|
||||||
|
output_to_input.
|
||||||
|
map(&Shoulda::Matchers::Util.method(:inspect_value)).
|
||||||
|
join(' to ')
|
||||||
|
}.
|
||||||
|
to_sentence
|
||||||
end
|
end
|
||||||
|
|
||||||
def normalized_expected_enum_values
|
def normalized_expected_enum_values
|
||||||
|
@ -256,14 +293,6 @@ module Shoulda
|
||||||
options[:expected_enum_values]
|
options[:expected_enum_values]
|
||||||
end
|
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
|
def normalized_actual_enum_values
|
||||||
to_hash(actual_enum_values)
|
to_hash(actual_enum_values)
|
||||||
end
|
end
|
||||||
|
@ -276,7 +305,8 @@ module Shoulda
|
||||||
if model.defined_enums.include?(attribute_name.to_s)
|
if model.defined_enums.include?(attribute_name.to_s)
|
||||||
true
|
true
|
||||||
else
|
else
|
||||||
@failure_reason = "no such enum exists in #{model}"
|
@failure_message_continuation =
|
||||||
|
"no such enum exists on #{model}"
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -289,11 +319,9 @@ module Shoulda
|
||||||
if passed
|
if passed
|
||||||
true
|
true
|
||||||
else
|
else
|
||||||
@failure_reason =
|
@failure_message_continuation =
|
||||||
"the actual enum values for #{attribute_name.inspect} are " +
|
"However, #{attribute_name.inspect} actually maps " +
|
||||||
Shoulda::Matchers::Util.inspect_value(
|
presented_enum_mapping(normalized_actual_enum_values)
|
||||||
presented_actual_enum_values,
|
|
||||||
)
|
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -302,8 +330,8 @@ module Shoulda
|
||||||
if column.type == expected_column_type.to_sym
|
if column.type == expected_column_type.to_sym
|
||||||
true
|
true
|
||||||
else
|
else
|
||||||
@failure_reason =
|
@failure_message_continuation =
|
||||||
"#{attribute_name.inspect} is " +
|
"However, #{attribute_name.inspect} is " +
|
||||||
Shoulda::Matchers::Util.a_or_an(column.type) +
|
Shoulda::Matchers::Util.a_or_an(column.type) +
|
||||||
' column'
|
' column'
|
||||||
false
|
false
|
||||||
|
@ -330,30 +358,59 @@ module Shoulda
|
||||||
if passed
|
if passed
|
||||||
true
|
true
|
||||||
else
|
else
|
||||||
@failure_reason =
|
message = "#{attribute_name.inspect} does map to these "
|
||||||
if options[:expected_prefix]
|
message << 'values, but the enum is '
|
||||||
if options[:expected_suffix]
|
|
||||||
'it was defined with either a different prefix, a ' +
|
if expected_prefix
|
||||||
'different suffix, or neither one at all'
|
if expected_suffix
|
||||||
else
|
message << 'configured with either a different prefix or '
|
||||||
'it was defined with either a different prefix or none at all'
|
message << 'suffix, or no prefix or suffix at all'
|
||||||
end
|
else
|
||||||
elsif options[:expected_suffix]
|
message << 'configured with either a different prefix or no '
|
||||||
'it was defined with either a different suffix or none at all'
|
message << 'prefix at all'
|
||||||
end
|
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
|
false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def expected_singleton_methods
|
def expected_singleton_methods
|
||||||
expected_enum_value_names.map do |name|
|
expected_enum_value_names.map do |name|
|
||||||
[options[:expected_prefix], name, options[:expected_suffix]].
|
[expected_prefix, name, expected_suffix].
|
||||||
select(&:present?).
|
select(&:present?).
|
||||||
join('_').
|
join('_').
|
||||||
to_sym
|
to_sym
|
||||||
end
|
end
|
||||||
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)
|
def to_hash(value)
|
||||||
if value.is_a?(Array)
|
if value.is_a?(Array)
|
||||||
value.each_with_index.inject({}) do |hash, (item, index)|
|
value.each_with_index.inject({}) do |hash, (item, index)|
|
||||||
|
|
|
@ -9,8 +9,8 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
|
||||||
column_type: :integer,
|
column_type: :integer,
|
||||||
)
|
)
|
||||||
message = format_message(<<-MESSAGE)
|
message = format_message(<<-MESSAGE)
|
||||||
Expected Example to define :attrs as an enum, backed by an integer.
|
Expected Example to define :attrs as an enum, but no such enum exists on
|
||||||
However, no such enum exists in Example.
|
Example.
|
||||||
MESSAGE
|
MESSAGE
|
||||||
|
|
||||||
assertion = lambda do
|
assertion = lambda do
|
||||||
|
@ -28,8 +28,8 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
|
||||||
end
|
end
|
||||||
|
|
||||||
message = format_message(<<-MESSAGE)
|
message = format_message(<<-MESSAGE)
|
||||||
Expected Example to define :attr as an enum, backed by an integer.
|
Expected Example to define :attr as an enum, but no such enum exists on
|
||||||
However, no such enum exists in Example.
|
Example.
|
||||||
MESSAGE
|
MESSAGE
|
||||||
|
|
||||||
assertion = lambda do
|
assertion = lambda do
|
||||||
|
@ -48,8 +48,8 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
|
||||||
attribute_name: :attr,
|
attribute_name: :attr,
|
||||||
)
|
)
|
||||||
message = format_message(<<-MESSAGE)
|
message = format_message(<<-MESSAGE)
|
||||||
Expected Example to define :attr as an enum, backed by an integer.
|
Expected Example to define :attr as an enum, but no such enum exists
|
||||||
However, no such enum exists in Example.
|
on Example.
|
||||||
MESSAGE
|
MESSAGE
|
||||||
|
|
||||||
assertion = lambda do
|
assertion = lambda do
|
||||||
|
@ -68,7 +68,7 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
|
||||||
column_type: :string,
|
column_type: :string,
|
||||||
)
|
)
|
||||||
message = format_message(<<-MESSAGE)
|
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.
|
However, :attr is a string column.
|
||||||
MESSAGE
|
MESSAGE
|
||||||
|
|
||||||
|
@ -81,30 +81,23 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'if the attribute is defined as an enum' do
|
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)
|
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
|
end
|
||||||
|
|
||||||
context 'and the matcher is negated' do
|
it 'has the right description' do
|
||||||
it 'rejects with an appropriate failure message' do
|
matcher = define_enum_for(:attr)
|
||||||
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
|
|
||||||
|
|
||||||
assertion = lambda do
|
expect(matcher.description).to eq(<<~MESSAGE.strip)
|
||||||
expect(record).not_to define_enum_for(:attr)
|
define :attr as an enum backed by an integer
|
||||||
end
|
MESSAGE
|
||||||
|
|
||||||
expect(&assertion).to fail_with_message(message)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -118,9 +111,8 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
|
||||||
attribute_name: :attr,
|
attribute_name: :attr,
|
||||||
)
|
)
|
||||||
message = format_message(<<-MESSAGE)
|
message = format_message(<<-MESSAGE)
|
||||||
Expected Example to define :attr as an enum, backed by an integer,
|
Expected Example to define :attr as an enum, but no such enum
|
||||||
with possible values ‹["open", "close"]›. However, no such enum
|
exists on Example.
|
||||||
exists in Example.
|
|
||||||
MESSAGE
|
MESSAGE
|
||||||
|
|
||||||
assertion = lambda do
|
assertion = lambda do
|
||||||
|
@ -142,9 +134,10 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
|
||||||
values: ['published', 'unpublished', 'draft'],
|
values: ['published', 'unpublished', 'draft'],
|
||||||
)
|
)
|
||||||
message = format_message(<<-MESSAGE)
|
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,
|
||||||
with possible values ‹["open", "close"]›. However, the actual
|
mapping ‹"open"› to ‹0› and ‹"close"› to ‹1›. However, :attr
|
||||||
enum values for :attr are ‹["published", "unpublished", "draft"]›.
|
actually maps ‹"published"› to ‹0›, ‹"unpublished"› to ‹1›, and
|
||||||
|
‹"draft"› to ‹2›.
|
||||||
MESSAGE
|
MESSAGE
|
||||||
|
|
||||||
assertion = lambda do
|
assertion = lambda do
|
||||||
|
@ -158,14 +151,33 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'and the enum values match' do
|
context 'and the enum values match' do
|
||||||
it 'accepts' do
|
it 'matches' do
|
||||||
record = build_record_with_array_values(
|
record = build_record_with_array_values(
|
||||||
attribute_name: :attr,
|
attribute_name: :attr,
|
||||||
values: ['published', 'unpublished', 'draft'],
|
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'])
|
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
|
end
|
||||||
end
|
end
|
||||||
|
@ -179,9 +191,8 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
|
||||||
attribute_name: :attr,
|
attribute_name: :attr,
|
||||||
)
|
)
|
||||||
message = format_message(<<-MESSAGE)
|
message = format_message(<<-MESSAGE)
|
||||||
Expected Example to define :attr as an enum, backed by an integer,
|
Expected Example to define :attr as an enum, but no such enum exists
|
||||||
with possible values ‹{active: 5, archived: 10}›. However, no such
|
on Example.
|
||||||
enum exists in Example.
|
|
||||||
MESSAGE
|
MESSAGE
|
||||||
|
|
||||||
assertion = lambda do
|
assertion = lambda do
|
||||||
|
@ -203,9 +214,9 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
|
||||||
values: { active: 0, archived: 1 },
|
values: { active: 0, archived: 1 },
|
||||||
)
|
)
|
||||||
message = format_message(<<-MESSAGE)
|
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,
|
||||||
with possible values ‹{active: 5, archived: 10}›. However, the
|
mapping ‹"active"› to ‹5› and ‹"archived"› to ‹10›. However, :attr
|
||||||
actual enum values for :attr are ‹{active: 0, archived: 1}›.
|
actually maps ‹"active"› to ‹0› and ‹"archived"› to ‹1›.
|
||||||
MESSAGE
|
MESSAGE
|
||||||
|
|
||||||
assertion = lambda do
|
assertion = lambda do
|
||||||
|
@ -220,28 +231,64 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
|
||||||
|
|
||||||
context 'and the enum values match' do
|
context 'and the enum values match' do
|
||||||
context 'when expected enum values are a hash' do
|
context 'when expected enum values are a hash' do
|
||||||
it 'accepts' do
|
it 'matches' do
|
||||||
record = build_record_with_hash_values(
|
record = build_record_with_hash_values(
|
||||||
attribute_name: :attr,
|
attribute_name: :attr,
|
||||||
values: { active: 0, archived: 1 },
|
values: { active: 0, archived: 1 },
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(record).
|
matcher = lambda do
|
||||||
to define_enum_for(:attr).
|
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)
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when expected enum values are an array' do
|
context 'when expected enum values are an array' do
|
||||||
it 'accepts' do
|
it 'matches' do
|
||||||
record = build_record_with_hash_values(
|
record = build_record_with_hash_values(
|
||||||
attribute_name: :attr,
|
attribute_name: :attr,
|
||||||
values: { active: 0, archived: 1 },
|
values: { active: 0, archived: 1 },
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(record).
|
matcher = lambda do
|
||||||
to define_enum_for(:attr).
|
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'])
|
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
|
end
|
||||||
end
|
end
|
||||||
|
@ -276,7 +323,7 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
|
||||||
column_type: :integer,
|
column_type: :integer,
|
||||||
)
|
)
|
||||||
message = format_message(<<-MESSAGE)
|
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.
|
However, :attr is an integer column.
|
||||||
MESSAGE
|
MESSAGE
|
||||||
|
|
||||||
|
@ -291,15 +338,30 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'if the column storing the attribute is of the same type' do
|
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(
|
record = build_record_with_array_values(
|
||||||
attribute_name: :attr,
|
attribute_name: :attr,
|
||||||
column_type: :string,
|
column_type: :string,
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(record).
|
matcher = lambda do
|
||||||
to define_enum_for(:attr).
|
define_enum_for(:attr).backed_by_column_of_type(:string)
|
||||||
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
|
end
|
||||||
end
|
end
|
||||||
|
@ -324,10 +386,11 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
|
||||||
end
|
end
|
||||||
|
|
||||||
message = format_message(<<-MESSAGE)
|
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,
|
||||||
using a prefix of :foo, with possible values ‹[:active,
|
mapping ‹"active"› to ‹0› and ‹"archived"› to ‹1› and prefixing
|
||||||
:archived]›. However, it was defined with either a different
|
accessor methods with "foo_". :attr does map to these values, but
|
||||||
prefix or none at all.
|
the enum is configured with either a different prefix or no prefix
|
||||||
|
at all (we can't tell which).
|
||||||
MESSAGE
|
MESSAGE
|
||||||
|
|
||||||
expect(&assertion).to fail_with_message(message)
|
expect(&assertion).to fail_with_message(message)
|
||||||
|
@ -352,10 +415,11 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
|
||||||
end
|
end
|
||||||
|
|
||||||
message = format_message(<<-MESSAGE)
|
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,
|
||||||
using a prefix of :bar, with possible values ‹[:active,
|
mapping ‹"active"› to ‹0› and ‹"archived"› to ‹1› and prefixing
|
||||||
:archived]›. However, it was defined with either a different
|
accessor methods with "bar_". :attr does map to these values, but
|
||||||
prefix or none at all.
|
the enum is configured with either a different prefix or no prefix
|
||||||
|
at all (we can't tell which).
|
||||||
MESSAGE
|
MESSAGE
|
||||||
|
|
||||||
expect(&assertion).to fail_with_message(message)
|
expect(&assertion).to fail_with_message(message)
|
||||||
|
@ -363,7 +427,7 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'if the attribute was defined with the same prefix' do
|
context 'if the attribute was defined with the same prefix' do
|
||||||
it 'accepts' do
|
it 'matches' do
|
||||||
record = build_record_with_array_values(
|
record = build_record_with_array_values(
|
||||||
model_name: 'Example',
|
model_name: 'Example',
|
||||||
attribute_name: :attr,
|
attribute_name: :attr,
|
||||||
|
@ -371,10 +435,29 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
|
||||||
prefix: :foo,
|
prefix: :foo,
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(record).
|
matcher = lambda do
|
||||||
to define_enum_for(:attr).
|
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_values([:active, :archived]).
|
||||||
with_prefix(:foo)
|
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
|
end
|
||||||
end
|
end
|
||||||
|
@ -397,10 +480,11 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
|
||||||
end
|
end
|
||||||
|
|
||||||
message = format_message(<<-MESSAGE)
|
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,
|
||||||
using a prefix of :attr, with possible values ‹[:active,
|
mapping ‹"active"› to ‹0› and ‹"archived"› to ‹1› and prefixing
|
||||||
:archived]›. However, it was defined with either a different
|
accessor methods with "attr_". :attr does map to these values, but
|
||||||
prefix or none at all.
|
the enum is configured with either a different prefix or no prefix
|
||||||
|
at all (we can't tell which).
|
||||||
MESSAGE
|
MESSAGE
|
||||||
|
|
||||||
expect(&assertion).to fail_with_message(message)
|
expect(&assertion).to fail_with_message(message)
|
||||||
|
@ -408,7 +492,7 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'if the attribute was defined with a prefix' do
|
context 'if the attribute was defined with a prefix' do
|
||||||
it 'accepts' do
|
it 'matches' do
|
||||||
record = build_record_with_array_values(
|
record = build_record_with_array_values(
|
||||||
model_name: 'Example',
|
model_name: 'Example',
|
||||||
attribute_name: :attr,
|
attribute_name: :attr,
|
||||||
|
@ -416,10 +500,29 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
|
||||||
prefix: true,
|
prefix: true,
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(record).
|
matcher = lambda do
|
||||||
to define_enum_for(:attr).
|
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_values([:active, :archived]).
|
||||||
with_prefix
|
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
|
end
|
||||||
end
|
end
|
||||||
|
@ -444,10 +547,11 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
|
||||||
end
|
end
|
||||||
|
|
||||||
message = format_message(<<-MESSAGE)
|
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,
|
||||||
using a suffix of :foo, with possible values ‹[:active,
|
mapping ‹"active"› to ‹0› and ‹"archived"› to ‹1› and suffixing
|
||||||
:archived]›. However, it was defined with either a different
|
accessor methods with "_foo". :attr does map to these values, but
|
||||||
suffix or none at all.
|
the enum is configured with either a different suffix or no suffix
|
||||||
|
at all (we can't tell which).
|
||||||
MESSAGE
|
MESSAGE
|
||||||
|
|
||||||
expect(&assertion).to fail_with_message(message)
|
expect(&assertion).to fail_with_message(message)
|
||||||
|
@ -472,10 +576,11 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
|
||||||
end
|
end
|
||||||
|
|
||||||
message = format_message(<<-MESSAGE)
|
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,
|
||||||
using a suffix of :bar, with possible values ‹[:active,
|
mapping ‹"active"› to ‹0› and ‹"archived"› to ‹1› and suffixing
|
||||||
:archived]›. However, it was defined with either a different
|
accessor methods with "_bar". :attr does map to these values, but
|
||||||
suffix or none at all.
|
the enum is configured with either a different suffix or no suffix
|
||||||
|
at all (we can't tell which).
|
||||||
MESSAGE
|
MESSAGE
|
||||||
|
|
||||||
expect(&assertion).to fail_with_message(message)
|
expect(&assertion).to fail_with_message(message)
|
||||||
|
@ -483,7 +588,7 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'if the attribute was defined with the same suffix' do
|
context 'if the attribute was defined with the same suffix' do
|
||||||
it 'accepts' do
|
it 'matches' do
|
||||||
record = build_record_with_array_values(
|
record = build_record_with_array_values(
|
||||||
model_name: 'Example',
|
model_name: 'Example',
|
||||||
attribute_name: :attr,
|
attribute_name: :attr,
|
||||||
|
@ -491,10 +596,29 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
|
||||||
suffix: :foo,
|
suffix: :foo,
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(record).
|
matcher = lambda do
|
||||||
to define_enum_for(:attr).
|
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_values([:active, :archived]).
|
||||||
with_suffix(:foo)
|
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
|
end
|
||||||
end
|
end
|
||||||
|
@ -517,10 +641,11 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
|
||||||
end
|
end
|
||||||
|
|
||||||
message = format_message(<<-MESSAGE)
|
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,
|
||||||
using a suffix of :attr, with possible values ‹[:active,
|
mapping ‹"active"› to ‹0› and ‹"archived"› to ‹1› and suffixing
|
||||||
:archived]›. However, it was defined with either a different
|
accessor methods with "_attr". :attr does map to these values, but
|
||||||
suffix or none at all.
|
the enum is configured with either a different suffix or no suffix
|
||||||
|
at all (we can't tell which).
|
||||||
MESSAGE
|
MESSAGE
|
||||||
|
|
||||||
expect(&assertion).to fail_with_message(message)
|
expect(&assertion).to fail_with_message(message)
|
||||||
|
@ -528,7 +653,7 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'if the attribute was defined with a suffix' do
|
context 'if the attribute was defined with a suffix' do
|
||||||
it 'accepts' do
|
it 'matches' do
|
||||||
record = build_record_with_array_values(
|
record = build_record_with_array_values(
|
||||||
model_name: 'Example',
|
model_name: 'Example',
|
||||||
attribute_name: :attr,
|
attribute_name: :attr,
|
||||||
|
@ -536,10 +661,29 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
|
||||||
suffix: true,
|
suffix: true,
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(record).
|
matcher = lambda do
|
||||||
to define_enum_for(:attr).
|
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_values([:active, :archived]).
|
||||||
with_suffix
|
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
|
end
|
||||||
end
|
end
|
||||||
|
@ -566,10 +710,12 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
|
||||||
end
|
end
|
||||||
|
|
||||||
message = format_message(<<-MESSAGE)
|
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,
|
||||||
using a prefix of :whatever and a suffix of :bar, with possible
|
mapping ‹"active"› to ‹0› and ‹"archived"› to ‹1›, prefixing
|
||||||
values ‹[:active, :archived]›. However, it was defined with either
|
accessor methods with "whatever_", and suffixing accessor methods
|
||||||
a different prefix, a different suffix, or neither one at all.
|
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
|
MESSAGE
|
||||||
|
|
||||||
expect(&assertion).to fail_with_message(message)
|
expect(&assertion).to fail_with_message(message)
|
||||||
|
@ -595,11 +741,12 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
|
||||||
end
|
end
|
||||||
|
|
||||||
message = format_message(<<-MESSAGE)
|
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,
|
||||||
using a prefix of :foo and a suffix of :whatever, with possible
|
mapping ‹"active"› to ‹0› and ‹"archived"› to ‹1›, prefixing
|
||||||
values ‹[:active, :archived]›. However, it was defined with
|
accessor methods with "foo_", and suffixing accessor methods with
|
||||||
either a different prefix, a different suffix, or neither one at
|
"_whatever". :attr does map to these values, but the enum is
|
||||||
all.
|
configured with either a different prefix or suffix, or no prefix
|
||||||
|
or suffix at all (we can't tell which).
|
||||||
MESSAGE
|
MESSAGE
|
||||||
|
|
||||||
expect(&assertion).to fail_with_message(message)
|
expect(&assertion).to fail_with_message(message)
|
||||||
|
@ -607,7 +754,7 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'if the attribute was defined with the same prefix and suffix' do
|
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(
|
record = build_record_with_array_values(
|
||||||
model_name: 'Example',
|
model_name: 'Example',
|
||||||
attribute_name: :attr,
|
attribute_name: :attr,
|
||||||
|
@ -616,11 +763,32 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
|
||||||
suffix: :bar,
|
suffix: :bar,
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(record).
|
matcher = lambda do
|
||||||
to define_enum_for(:attr).
|
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_values([:active, :archived]).
|
||||||
with_prefix(:foo).
|
with_prefix(:foo).
|
||||||
with_suffix(:bar)
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue