mirror of
https://github.com/thoughtbot/shoulda-matchers.git
synced 2022-11-09 12:01:38 -05:00
Create the define_enum_for matcher
This commit is contained in:
parent
165859247c
commit
eaa970e3c6
4 changed files with 215 additions and 17 deletions
|
@ -1,20 +1,21 @@
|
|||
require 'shoulda/matchers/active_record/association_matcher'
|
||||
require 'shoulda/matchers/active_record/association_matchers'
|
||||
require 'shoulda/matchers/active_record/association_matchers/counter_cache_matcher'
|
||||
require 'shoulda/matchers/active_record/association_matchers/inverse_of_matcher'
|
||||
require 'shoulda/matchers/active_record/association_matchers/join_table_matcher'
|
||||
require 'shoulda/matchers/active_record/association_matchers/order_matcher'
|
||||
require 'shoulda/matchers/active_record/association_matchers/through_matcher'
|
||||
require 'shoulda/matchers/active_record/association_matchers/dependent_matcher'
|
||||
require 'shoulda/matchers/active_record/association_matchers/source_matcher'
|
||||
require 'shoulda/matchers/active_record/association_matchers/model_reflector'
|
||||
require 'shoulda/matchers/active_record/association_matchers/model_reflection'
|
||||
require 'shoulda/matchers/active_record/association_matchers/option_verifier'
|
||||
require 'shoulda/matchers/active_record/have_db_column_matcher'
|
||||
require 'shoulda/matchers/active_record/have_db_index_matcher'
|
||||
require 'shoulda/matchers/active_record/have_readonly_attribute_matcher'
|
||||
require 'shoulda/matchers/active_record/serialize_matcher'
|
||||
require 'shoulda/matchers/active_record/accept_nested_attributes_for_matcher'
|
||||
require "shoulda/matchers/active_record/association_matcher"
|
||||
require "shoulda/matchers/active_record/association_matchers"
|
||||
require "shoulda/matchers/active_record/association_matchers/counter_cache_matcher"
|
||||
require "shoulda/matchers/active_record/association_matchers/inverse_of_matcher"
|
||||
require "shoulda/matchers/active_record/association_matchers/join_table_matcher"
|
||||
require "shoulda/matchers/active_record/association_matchers/order_matcher"
|
||||
require "shoulda/matchers/active_record/association_matchers/through_matcher"
|
||||
require "shoulda/matchers/active_record/association_matchers/dependent_matcher"
|
||||
require "shoulda/matchers/active_record/association_matchers/source_matcher"
|
||||
require "shoulda/matchers/active_record/association_matchers/model_reflector"
|
||||
require "shoulda/matchers/active_record/association_matchers/model_reflection"
|
||||
require "shoulda/matchers/active_record/association_matchers/option_verifier"
|
||||
require "shoulda/matchers/active_record/have_db_column_matcher"
|
||||
require "shoulda/matchers/active_record/have_db_index_matcher"
|
||||
require "shoulda/matchers/active_record/have_readonly_attribute_matcher"
|
||||
require "shoulda/matchers/active_record/serialize_matcher"
|
||||
require "shoulda/matchers/active_record/accept_nested_attributes_for_matcher"
|
||||
require "shoulda/matchers/active_record/define_enum_for_matcher"
|
||||
|
||||
module Shoulda
|
||||
module Matchers
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
module Shoulda
|
||||
module Matchers
|
||||
module ActiveRecord
|
||||
def define_enum_for(name)
|
||||
DefineEnumForMatcher.new(name)
|
||||
end
|
||||
|
||||
class DefineEnumForMatcher
|
||||
def initialize(attribute_name)
|
||||
@attribute_name = attribute_name
|
||||
@options = {}
|
||||
end
|
||||
|
||||
def with(expected_enum_values)
|
||||
options[:expected_enum_values] = expected_enum_values
|
||||
self
|
||||
end
|
||||
|
||||
def matches?(subject)
|
||||
@model = subject
|
||||
enum_defined? && enum_values_match?
|
||||
end
|
||||
|
||||
def failure_message
|
||||
"Expected #{expectation}"
|
||||
end
|
||||
alias :failure_message_for_should :failure_message
|
||||
|
||||
def failure_message_when_negated
|
||||
"Did not expect #{expectation}"
|
||||
end
|
||||
alias :failure_message_for_should_not :failure_message_when_negated
|
||||
|
||||
def description
|
||||
desc = "define :#{attribute_name} as an enum"
|
||||
|
||||
if options[:expected_enum_values]
|
||||
desc << " with #{options[:expected_enum_values]}"
|
||||
end
|
||||
|
||||
desc
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
attr_reader :model, :attribute_name, :options
|
||||
|
||||
def expectation
|
||||
"#{model.class.name} to #{description}"
|
||||
end
|
||||
|
||||
def expected_enum_values
|
||||
hashify(options[:expected_enum_values]).with_indifferent_access
|
||||
end
|
||||
|
||||
def enum_method
|
||||
attribute_name.to_s.pluralize
|
||||
end
|
||||
|
||||
def actual_enum_values
|
||||
model.class.send(enum_method)
|
||||
end
|
||||
|
||||
def enum_defined?
|
||||
model.class.respond_to?(enum_method)
|
||||
end
|
||||
|
||||
def enum_values_match?
|
||||
expected_enum_values.empty? || actual_enum_values == expected_enum_values
|
||||
end
|
||||
|
||||
def hashify(value)
|
||||
if value.nil?
|
||||
return {}
|
||||
end
|
||||
|
||||
if value.is_a?(Array)
|
||||
new_value = {}
|
||||
|
||||
value.each_with_index do |v, i|
|
||||
new_value[v] = i
|
||||
end
|
||||
|
||||
new_value
|
||||
else
|
||||
value
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,101 @@
|
|||
require "spec_helper"
|
||||
|
||||
describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher do
|
||||
if active_record_supports_enum?
|
||||
describe "with only the attribute name specified" do
|
||||
it "accepts a record where the attribute is defined as an enum" do
|
||||
expect(record_with_array_values).to define_enum_for(enum_attribute)
|
||||
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"
|
||||
|
||||
expect do
|
||||
expect(record_with_array_values).to define_enum_for(non_enum_attribute)
|
||||
end.to fail_with_message(message)
|
||||
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"
|
||||
|
||||
expect do
|
||||
expect(record_with_array_values).to_not define_enum_for(enum_attribute)
|
||||
end.to fail_with_message(message)
|
||||
end
|
||||
end
|
||||
|
||||
describe "with both attribute name and enum values specified" do
|
||||
context "when the actual enum values are an array" do
|
||||
it "accepts a record where the attribute is defined as an enum and the enum values match" do
|
||||
expect(record_with_array_values).to define_enum_for(enum_attribute).
|
||||
with(["published", "unpublished", "draft"])
|
||||
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"]}
|
||||
|
||||
expect do
|
||||
expect(record_with_array_values).to define_enum_for(non_enum_attribute).with(["open", "close"])
|
||||
end.to fail_with_message(message)
|
||||
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"]}
|
||||
|
||||
expect do
|
||||
expect(record_with_array_values).to define_enum_for(enum_attribute).with(["open", "close"])
|
||||
end.to fail_with_message(message)
|
||||
end
|
||||
end
|
||||
|
||||
context "when the actual enum values are a hash" do
|
||||
it "accepts a record where the attribute is defined as an enum and the enum values match" do
|
||||
expect(record_with_hash_values).to define_enum_for(enum_attribute).with(active: 0, archived: 1)
|
||||
end
|
||||
|
||||
it "accepts a record where the enum values match when expected enum values are given as an array" do
|
||||
expect(record_with_hash_values).to define_enum_for(enum_attribute).with(["active", "archived"])
|
||||
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}}
|
||||
|
||||
expect do
|
||||
expect(record_with_hash_values).to define_enum_for(enum_attribute).with(active: 5, archived: 10)
|
||||
end.to fail_with_message(message)
|
||||
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}}
|
||||
|
||||
expect do
|
||||
expect(record_with_hash_values)
|
||||
.to define_enum_for(:record_with_hash_values).with(active: 5, archived: 10)
|
||||
end.to fail_with_message(message)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def enum_attribute
|
||||
:status
|
||||
end
|
||||
|
||||
def non_enum_attribute
|
||||
:condition
|
||||
end
|
||||
|
||||
def record_with_array_values
|
||||
_enum_attribute = enum_attribute
|
||||
define_model :record_with_array_values do
|
||||
enum(_enum_attribute => %w(published unpublished draft))
|
||||
end.new
|
||||
end
|
||||
|
||||
def record_with_hash_values
|
||||
_enum_attribute = enum_attribute
|
||||
define_model :record_with_hash_values do
|
||||
enum(_enum_attribute => { active: 0, archived: 1 })
|
||||
end.new
|
||||
end
|
||||
end
|
||||
end
|
|
@ -14,6 +14,10 @@ module RailsVersions
|
|||
def rails_gte_4_1?
|
||||
Gem::Requirement.new('>= 4.1').satisfied_by?(rails_version)
|
||||
end
|
||||
|
||||
def active_record_supports_enum?
|
||||
defined?(::ActiveRecord::Enum)
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.configure do |config|
|
||||
|
|
Loading…
Add table
Reference in a new issue