diff --git a/lib/shoulda/matchers/active_record/define_enum_for_matcher.rb b/lib/shoulda/matchers/active_record/define_enum_for_matcher.rb index 09e1da20..a194f5da 100644 --- a/lib/shoulda/matchers/active_record/define_enum_for_matcher.rb +++ b/lib/shoulda/matchers/active_record/define_enum_for_matcher.rb @@ -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)| diff --git a/spec/unit/shoulda/matchers/active_record/define_enum_for_matcher_spec.rb b/spec/unit/shoulda/matchers/active_record/define_enum_for_matcher_spec.rb index ef9ce151..8b3517f6 100644 --- a/spec/unit/shoulda/matchers/active_record/define_enum_for_matcher_spec.rb +++ b/spec/unit/shoulda/matchers/active_record/define_enum_for_matcher_spec.rb @@ -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