Skip to content

Commit

Permalink
Allow specifying a non-integer column type for define_enum_for
Browse files Browse the repository at this point in the history
  • Loading branch information
lime authored and mcmire committed Jan 24, 2018
1 parent 2a61824 commit 5650aae
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 13 deletions.
17 changes: 13 additions & 4 deletions lib/shoulda/matchers/active_record/define_enum_for_matcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,14 @@ def with(expected_enum_values)
self
end

def backed_by_column_of_type(expected_column_type)
options[:expected_column_type] = expected_column_type
self
end

def matches?(subject)
@record = subject
enum_defined? && enum_values_match? && column_type_is_integer?
enum_defined? && enum_values_match? && column_type_matches?
end

def failure_message
Expand All @@ -83,7 +88,7 @@ def description
desc << " with #{options[:expected_enum_values]}"
end

desc << " and store the value in a column with an integer type"
desc << " and store the value in a column of type #{expected_column_type}"

desc
end
Expand Down Expand Up @@ -112,8 +117,12 @@ def enum_values_match?
expected_enum_values.empty? || actual_enum_values == expected_enum_values
end

def column_type_is_integer?
column.type == :integer
def expected_column_type
options[:expected_column_type] || :integer
end

def column_type_matches?
column.type == expected_column_type.to_sym
end

def column
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
it 'rejects' do
record = record_with_array_values
plural_enum_attribute = enum_attribute.to_s.pluralize
message = "Expected #{record.class} to define :#{plural_enum_attribute} as an enum and store the value in a column with an integer type"
message = "Expected #{record.class} to define :#{plural_enum_attribute} as an enum and store the value in a column of type integer"

assertion = lambda do
expect(record).to define_enum_for(plural_enum_attribute)
Expand All @@ -22,7 +22,7 @@
def self.statuses; end
end

message = "Expected #{model} to define :statuses as an enum and store the value in a column with an integer type"
message = "Expected #{model} to define :statuses as an enum and store the value in a column of type integer"

assertion = lambda do
expect(model.new).to define_enum_for(:statuses)
Expand All @@ -38,7 +38,7 @@ def self.statuses; end
end

it "rejects a record where the attribute is not defined as an enum" do
message = "Expected #{record_with_array_values.class} to define :#{non_enum_attribute} as an enum and store the value in a column with an integer type"
message = "Expected #{record_with_array_values.class} to define :#{non_enum_attribute} as an enum and store the value in a column of type integer"

assertion = lambda do
expect(record_with_array_values).
Expand All @@ -49,7 +49,7 @@ def self.statuses; end
end

it "rejects a record where the attribute is not defined as an enum with should not" do
message = "Did not expect #{record_with_array_values.class} to define :#{enum_attribute} as an enum and store the value in a column with an integer type"
message = "Did not expect #{record_with_array_values.class} to define :#{enum_attribute} as an enum and store the value in a column of type integer"

assertion = lambda do
expect(record_with_array_values).
Expand All @@ -62,7 +62,7 @@ def self.statuses; end
context 'if the column storing the attribute is not an integer type' do
it 'rejects' do
record = record_with_array_values(column_type: :string)
message = "Expected #{record.class} to define :statuses as an enum and store the value in a column with an integer type"
message = "Expected #{record.class} to define :statuses as an enum and store the value in a column of type integer"

assertion = lambda do
expect(record).to define_enum_for(:statuses)
Expand All @@ -81,7 +81,7 @@ def self.statuses; end
end

it "accepts a record where the attribute is not defined as an enum" do
message = %{Expected #{record_with_array_values.class} to define :#{non_enum_attribute} as an enum with ["open", "close"] and store the value in a column with an integer type}
message = %{Expected #{record_with_array_values.class} to define :#{non_enum_attribute} as an enum with ["open", "close"] and store the value in a column of type integer}

assertion = lambda do
expect(record_with_array_values).
Expand All @@ -92,7 +92,7 @@ def self.statuses; end
end

it "accepts a record where the attribute is defined as an enum but the enum values do not match" do
message = %{Expected #{record_with_array_values.class} to define :#{enum_attribute} as an enum with ["open", "close"] and store the value in a column with an integer type}
message = %{Expected #{record_with_array_values.class} to define :#{enum_attribute} as an enum with ["open", "close"] and store the value in a column of type integer}

assertion = lambda do
expect(record_with_array_values).
Expand All @@ -114,7 +114,7 @@ def self.statuses; end
end

it "accepts a record where the attribute is defined as an enum but the enum values do not match" do
message = %{Expected #{record_with_hash_values.class} to define :#{enum_attribute} as an enum with {:active=>5, :archived=>10} and store the value in a column with an integer type}
message = %{Expected #{record_with_hash_values.class} to define :#{enum_attribute} as an enum with {:active=>5, :archived=>10} and store the value in a column of type integer}

assertion = lambda do
expect(record_with_hash_values).
Expand All @@ -126,7 +126,7 @@ def self.statuses; end
end

it "rejects a record where the attribute is not defined as an enum" do
message = %{Expected #{record_with_hash_values.class} to define :record_with_hash_values as an enum with {:active=>5, :archived=>10} and store the value in a column with an integer type}
message = %{Expected #{record_with_hash_values.class} to define :record_with_hash_values as an enum with {:active=>5, :archived=>10} and store the value in a column of type integer}

assertion = lambda do
expect(record_with_hash_values).
Expand All @@ -139,6 +139,29 @@ def self.statuses; end
end
end

describe 'with the backing column specified to be a string type' do
context 'if the column storing the attribute is a string type' do
it 'accepts' do
record = record_with_array_values(column_type: :string)

expect(record).to define_enum_for(enum_attribute).backed_by_column_of_type(:string)
end
end

context 'if the column storing the attribute is an integer type' do
it 'rejects' do
record = record_with_array_values(column_type: :integer)
message = "Expected #{record.class} to define :#{enum_attribute} as an enum and store the value in a column of type string"

assertion = lambda do
expect(record).to define_enum_for(enum_attribute).backed_by_column_of_type(:string)
end

expect(&assertion).to fail_with_message(message)
end
end
end

def enum_attribute
:status
end
Expand Down

0 comments on commit 5650aae

Please sign in to comment.