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_matcher"
|
||||||
require 'shoulda/matchers/active_record/association_matchers'
|
require "shoulda/matchers/active_record/association_matchers"
|
||||||
require 'shoulda/matchers/active_record/association_matchers/counter_cache_matcher'
|
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/inverse_of_matcher"
|
||||||
require 'shoulda/matchers/active_record/association_matchers/join_table_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/order_matcher"
|
||||||
require 'shoulda/matchers/active_record/association_matchers/through_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/dependent_matcher"
|
||||||
require 'shoulda/matchers/active_record/association_matchers/source_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_reflector"
|
||||||
require 'shoulda/matchers/active_record/association_matchers/model_reflection'
|
require "shoulda/matchers/active_record/association_matchers/model_reflection"
|
||||||
require 'shoulda/matchers/active_record/association_matchers/option_verifier'
|
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_column_matcher"
|
||||||
require 'shoulda/matchers/active_record/have_db_index_matcher'
|
require "shoulda/matchers/active_record/have_db_index_matcher"
|
||||||
require 'shoulda/matchers/active_record/have_readonly_attribute_matcher'
|
require "shoulda/matchers/active_record/have_readonly_attribute_matcher"
|
||||||
require 'shoulda/matchers/active_record/serialize_matcher'
|
require "shoulda/matchers/active_record/serialize_matcher"
|
||||||
require 'shoulda/matchers/active_record/accept_nested_attributes_for_matcher'
|
require "shoulda/matchers/active_record/accept_nested_attributes_for_matcher"
|
||||||
|
require "shoulda/matchers/active_record/define_enum_for_matcher"
|
||||||
|
|
||||||
module Shoulda
|
module Shoulda
|
||||||
module Matchers
|
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?
|
def rails_gte_4_1?
|
||||||
Gem::Requirement.new('>= 4.1').satisfied_by?(rails_version)
|
Gem::Requirement.new('>= 4.1').satisfied_by?(rails_version)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def active_record_supports_enum?
|
||||||
|
defined?(::ActiveRecord::Enum)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
RSpec.configure do |config|
|
RSpec.configure do |config|
|
||||||
|
|
Loading…
Add table
Reference in a new issue