From c969f1d52f1eb5368a69e175187aae6cc3e93d90 Mon Sep 17 00:00:00 2001 From: Bruno Castro Date: Thu, 4 Mar 2021 19:46:23 -0300 Subject: [PATCH] feat: support alias in matcher define_enum (#1419) --- .../active_record/define_enum_for_matcher.rb | 11 +++++++- .../define_enum_for_matcher_spec.rb | 28 ++++++++++++++++--- 2 files changed, 34 insertions(+), 5 deletions(-) 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 28f877e9a..361295c87 100644 --- a/lib/shoulda/matchers/active_record/define_enum_for_matcher.rb +++ b/lib/shoulda/matchers/active_record/define_enum_for_matcher.rb @@ -6,16 +6,22 @@ module ActiveRecord # # class Process < ActiveRecord::Base # enum status: [:running, :stopped, :suspended] + # + # alias_attribute :kind, :SomeLegacyField + # + # enum kind: [:foo, :bar] # end # # # RSpec # RSpec.describe Process, type: :model do # it { should define_enum_for(:status) } + # it { should define_enum_for(:kind) } # end # # # Minitest (Shoulda) # class ProcessTest < ActiveSupport::TestCase # should define_enum_for(:status) + # should define_enum_for(:kind) # end # # #### Qualifiers @@ -370,7 +376,10 @@ def expected_column_type end def column - model.columns_hash[attribute_name.to_s] + key = attribute_name.to_s + column_name = model.attribute_alias(key) || key + + model.columns_hash[column_name] end def model 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 b7e631472..a1a5dd4bc 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 @@ -796,13 +796,27 @@ def self.statuses end end + context 'if the attribute is defined as an enum but is an alias' do + it 'matches' do + record = build_record_with_array_values(attribute_name: :attr, attribute_alias: :attr_alias) + + expect { define_enum_for(:attr_alias) }. + to match_against(record). + or_fail_with(<<-MESSAGE, wrap: true) + Expected Example not to define :attr_alias as an enum backed by an + integer, but it did. + MESSAGE + end + end + def build_record_with_array_values( model_name: 'Example', attribute_name: :attr, column_type: :integer, values: ['published', 'unpublished', 'draft'], prefix: false, - suffix: false + suffix: false, + attribute_alias: nil ) build_record_with_enum_attribute( model_name: model_name, @@ -811,6 +825,7 @@ def build_record_with_array_values( values: values, prefix: prefix, suffix: suffix, + attribute_alias: attribute_alias, ) end @@ -828,6 +843,7 @@ def build_record_with_hash_values( values: values, prefix: prefix, suffix: suffix, + attribute_alias: nil, ) end @@ -836,18 +852,22 @@ def build_record_with_enum_attribute( attribute_name:, column_type:, values:, + attribute_alias:, prefix: false, suffix: false ) + enum_name = attribute_alias || attribute_name model = define_model( model_name, attribute_name => { type: column_type }, - ) + ) do + alias_attribute attribute_alias, attribute_name + end if active_record_enum_supports_prefix_and_suffix? - model.enum(attribute_name => values, _prefix: prefix, _suffix: suffix) + model.enum(enum_name => values, _prefix: prefix, _suffix: suffix) else - model.enum(attribute_name => values) + model.enum(enum_name => values) end model.new