1
0
Fork 0
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:
Mauro George 2013-12-31 17:54:21 -02:00 committed by Elliot Winkler
parent 165859247c
commit eaa970e3c6
4 changed files with 215 additions and 17 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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|