1
0
Fork 0
mirror of https://github.com/thoughtbot/shoulda-matchers.git synced 2022-11-09 12:01:38 -05:00

Add have_rich_text_matcher

The `have_rich_text` matcher tests usage of the `has_rich_text` macro that was added in Rails 6.
This commit is contained in:
Pedro Paiva 2020-01-13 19:51:43 -03:00 committed by Elliot Winkler
parent 0b49b5762f
commit 0b23942feb
8 changed files with 183 additions and 0 deletions

View file

@ -126,6 +126,9 @@ if Gem::Requirement.new('>= 2.5.0').satisfied_by?(Gem::Version.new(RUBY_VERSION)
gem 'selenium-webdriver'
gem 'webdrivers'
# Other dependencies
gem 'actiontext', '~> 6.0.2.1'
# Database adapters
gem 'pg', '>= 0.18', '< 2.0'
gem 'sqlite3', '~> 1.4'

View file

@ -334,6 +334,8 @@ about any of them, make sure to [consult the documentation][rubydocs]!
tests your `has_one` associations.
* **[have_readonly_attribute](lib/shoulda/matchers/active_record/have_readonly_attribute_matcher.rb)**
tests usage of the `attr_readonly` macro.
* **[have_rich_text](lib/shoulda/matchers/active_record/have_rich_text_matcher.rb)**
tests your `has_rich_text` associations.
* **[serialize](lib/shoulda/matchers/active_record/serialize_matcher.rb)** tests
usage of the `serialize` macro.
* **[validate_uniqueness_of](lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb)**

View file

@ -33,5 +33,6 @@ gem "listen", ">= 3.0.5", "< 3.2"
gem "spring-watcher-listen", "~> 2.0.0"
gem "selenium-webdriver"
gem "webdrivers"
gem "actiontext", "~> 6.0.2.1"
gem "pg", ">= 0.18", "< 2.0"
gem "sqlite3", "~> 1.4"

View file

@ -262,6 +262,7 @@ PLATFORMS
ruby
DEPENDENCIES
actiontext (~> 6.0.2.1)
appraisal (= 2.2.0)
bcrypt (~> 3.1.7)
bootsnap (>= 1.4.2)

View file

@ -15,6 +15,7 @@ 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/have_rich_text_matcher"
require "shoulda/matchers/active_record/have_secure_token_matcher"
require "shoulda/matchers/active_record/serialize_matcher"
require "shoulda/matchers/active_record/accept_nested_attributes_for_matcher"

View file

@ -0,0 +1,79 @@
module Shoulda
module Matchers
module ActiveRecord
# The `have_rich_text` matcher tests usage of the
# `has_rich_text` macro.
#
# #### Example
#
# class Post < ActiveRecord
# has_rich_text :content
# end
#
# # RSpec
# RSpec.describe Post, type: :model do
# it { is_expected.to have_rich_text(:content) }
# end
#
# # Minitest (Shoulda)
# class PostTest < ActiveSupport::TestCase
# should have_rich_text(:content)
# end
#
# @return [HaveRichText]
#
def have_rich_text(rich_text_attribute)
HaveRichText.new(rich_text_attribute)
end
# @private
class HaveRichText
def initialize(rich_text_attribute)
@rich_text_attribute = rich_text_attribute
end
def description
"have configured :#{rich_text_attribute} as a ActionText::RichText association"
end
def failure_message
"Expected #{subject.class} to #{error_description}"
end
def failure_message_when_negated
"Did not expect #{subject.class} to have ActionText::RichText :#{rich_text_attribute}"
end
def matches?(subject)
@subject = subject
@error = run_checks
@error.nil?
end
private
attr_reader :error, :rich_text_attribute, :subject
def run_checks
if !has_attribute?
":#{rich_text_attribute} does not exist"
elsif !has_expected_action_text?
:default
end
end
def has_attribute?
@subject.respond_to?(rich_text_attribute.to_s)
end
def has_expected_action_text?
@subject.send(rich_text_attribute).class.name == 'ActionText::RichText'
end
def error_description
error == :default ? description : "#{description} but #{error}"
end
end
end
end
end

View file

@ -25,6 +25,11 @@ module UnitTests
def load
load_environment
if rails_version > 5 && bundle.includes?('actiontext')
add_action_text_migration
end
run_migrations
end
@ -165,6 +170,12 @@ end
TEXT
end
def add_action_text_migration
fs.within_project do
run_command! 'bundle exec rake action_text:install:migrations'
end
end
def add_initializer_for_time_zone_aware_types
path = 'config/initializers/configure_time_zone_aware_types.rb'
fs.write(path, <<-TEXT)

View file

@ -0,0 +1,85 @@
require 'unit_spec_helper'
describe Shoulda::Matchers::ActiveRecord::HaveRichText, type: :model do
def self.rich_text_is_defined?
defined?(ActionText::RichText)
end
context '#description' do
it 'returns the message including the name of the provided association' do
matcher = have_rich_text(:content)
expect(matcher.description).
to eq('have configured :content as a ActionText::RichText association')
end
end
if rich_text_is_defined?
context 'when the model has a RichText association' do
it 'matches when the subject configures has_rich_text' do
valid_record = new_post(is_rich_text_association: true)
expected_message = 'Did not expect Post to have ActionText::RichText :content'
expect { have_rich_text(:content) }.
to match_against(valid_record).
or_fail_with(expected_message)
end
end
context 'when the model does not have a RichText association' do
it 'does not match when provided with a model attribute that exist' do
invalid_record = new_post(has_invalid_content: true)
expected_message = 'Expected Post to have configured :invalid_content as a ' \
'ActionText::RichText association'
expect { have_rich_text(:invalid_content) }.
not_to match_against(invalid_record).
and_fail_with(expected_message)
end
it 'does not match when provided with a model attribute that does not exist' do
invalid_record = new_post
expected_message = 'Expected Post to have configured :invalid_attribute as a ' \
'ActionText::RichText association but :invalid_attribute does not exist'
expect { have_rich_text(:invalid_attribute) }.
not_to match_against(invalid_record).
and_fail_with(expected_message)
end
end
else
it 'does not match when provided with a model attribute that exist' do
invalid_record = new_post(has_invalid_content: true)
expected_message = 'Expected Post to have configured :invalid_content as a ' \
'ActionText::RichText association'
expect { have_rich_text(:invalid_content) }.
not_to match_against(invalid_record).
and_fail_with(expected_message)
end
it 'does not match when provided with a model attribute that does not exist' do
invalid_record = new_post
expected_message = 'Expected Post to have configured :invalid_attribute as a ' \
'ActionText::RichText association but :invalid_attribute does not exist'
expect { have_rich_text(:invalid_attribute) }.
not_to match_against(invalid_record).
and_fail_with(expected_message)
end
end
def new_post(has_invalid_content: false, is_rich_text_association: false)
columns = {}
if has_invalid_content
columns[:invalid_content] = :string
end
define_model 'Post', columns do
if is_rich_text_association
has_rich_text :content
end
end.new
end
end