mirror of
https://github.com/thoughtbot/shoulda-matchers.git
synced 2022-11-09 12:01:38 -05:00
Consolidate set_session and set_flash APIs
* Refactor so they both use SetSessionOrFlashMatcher internally * Remove `set_session['key']` in favor of `set_session('key')` * `set_flash['key'].to(nil)` no longer works if set_flash has never been set
This commit is contained in:
parent
801f2c7c1e
commit
535fe05be8
10 changed files with 582 additions and 653 deletions
8
NEWS.md
8
NEWS.md
|
@ -13,7 +13,13 @@
|
|||
* `ensure_inclusion_of`, `ensure_exclusion_of`, and `ensure_length_of` have been
|
||||
removed in favor of their `validate_*` counterparts.
|
||||
|
||||
* `set_the_flash` has been removed in favor of `set_flash`.
|
||||
* `set_the_flash` and `set_session` have been changed to more closely align with
|
||||
each other:
|
||||
* `set_the_flash` has been removed in favor of `set_flash`.
|
||||
* `set_session('foo')` is no longer valid syntax, please use
|
||||
`set_session['foo']` instead.
|
||||
* `set_session['key'].to(nil)` will no longer pass when the key in question
|
||||
has not been set yet.
|
||||
|
||||
# 2.8.0
|
||||
|
||||
|
|
|
@ -11,6 +11,8 @@ require 'shoulda/matchers/action_controller/rescue_from_matcher'
|
|||
require 'shoulda/matchers/action_controller/callback_matcher'
|
||||
require 'shoulda/matchers/action_controller/strong_parameters_matcher'
|
||||
require 'shoulda/matchers/action_controller/set_session_or_flash_matcher'
|
||||
require 'shoulda/matchers/action_controller/flash_store'
|
||||
require 'shoulda/matchers/action_controller/session_store'
|
||||
|
||||
module Shoulda
|
||||
module Matchers
|
||||
|
|
95
lib/shoulda/matchers/action_controller/flash_store.rb
Normal file
95
lib/shoulda/matchers/action_controller/flash_store.rb
Normal file
|
@ -0,0 +1,95 @@
|
|||
module Shoulda
|
||||
module Matchers
|
||||
module ActionController
|
||||
# @private
|
||||
class FlashStore
|
||||
def self.future
|
||||
new
|
||||
end
|
||||
|
||||
def self.now
|
||||
new.use_now!
|
||||
end
|
||||
|
||||
attr_accessor :controller
|
||||
|
||||
def initialize
|
||||
@use_now = false
|
||||
end
|
||||
|
||||
def name
|
||||
if @use_now
|
||||
'flash.now'
|
||||
else
|
||||
'flash'
|
||||
end
|
||||
end
|
||||
|
||||
def has_key?(key)
|
||||
values_to_check.include?(key)
|
||||
end
|
||||
|
||||
def has_value?(expected_value)
|
||||
values_to_check.values.any? do |actual_value|
|
||||
expected_value === actual_value
|
||||
end
|
||||
end
|
||||
|
||||
def empty?
|
||||
flash.empty?
|
||||
end
|
||||
|
||||
def use_now!
|
||||
@use_now = true
|
||||
self
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def flash
|
||||
@_flash ||= copy_of_flash_from_controller
|
||||
end
|
||||
|
||||
def copy_of_flash_from_controller
|
||||
controller.flash.dup.tap do |flash|
|
||||
copy_flashes(controller.flash, flash)
|
||||
copy_discard_if_necessary(controller.flash, flash)
|
||||
# sweep_flash_if_necessary(flash)
|
||||
end
|
||||
end
|
||||
|
||||
def copy_flashes(original_flash, new_flash)
|
||||
flashes = original_flash.instance_variable_get('@flashes').dup
|
||||
new_flash.instance_variable_set('@flashes', flashes)
|
||||
end
|
||||
|
||||
def copy_discard_if_necessary(original_flash, new_flash)
|
||||
discard = original_flash.instance_variable_get('@discard').dup
|
||||
new_flash.instance_variable_set('@discard', discard)
|
||||
end
|
||||
|
||||
def sweep_flash_if_necessary(flash)
|
||||
unless @use_now
|
||||
flash.sweep
|
||||
end
|
||||
end
|
||||
|
||||
def set_values
|
||||
flash.instance_variable_get('@flashes')
|
||||
end
|
||||
|
||||
def keys_to_discard
|
||||
flash.instance_variable_get('@discard')
|
||||
end
|
||||
|
||||
def values_to_check
|
||||
if @use_now
|
||||
set_values.slice(*keys_to_discard.to_a)
|
||||
else
|
||||
set_values.except(*keys_to_discard.to_a)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
34
lib/shoulda/matchers/action_controller/session_store.rb
Normal file
34
lib/shoulda/matchers/action_controller/session_store.rb
Normal file
|
@ -0,0 +1,34 @@
|
|||
module Shoulda
|
||||
module Matchers
|
||||
module ActionController
|
||||
# @private
|
||||
class SessionStore
|
||||
attr_accessor :controller
|
||||
|
||||
def name
|
||||
'session'
|
||||
end
|
||||
|
||||
def has_key?(key)
|
||||
session.key?(key)
|
||||
end
|
||||
|
||||
def has_value?(expected_value)
|
||||
session.values.any? do |actual_value|
|
||||
expected_value === actual_value
|
||||
end
|
||||
end
|
||||
|
||||
def empty?
|
||||
session.empty?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def session
|
||||
controller.session
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,3 +1,5 @@
|
|||
require 'forwardable'
|
||||
|
||||
module Shoulda
|
||||
module Matchers
|
||||
module ActionController
|
||||
|
@ -146,151 +148,54 @@ module Shoulda
|
|||
# @return [SetFlashMatcher]
|
||||
#
|
||||
def set_flash
|
||||
SetFlashMatcher.new
|
||||
SetFlashMatcher.new.in_context(self)
|
||||
end
|
||||
|
||||
# @private
|
||||
class SetFlashMatcher
|
||||
def initialize
|
||||
@options = {}
|
||||
@value = nil
|
||||
end
|
||||
extend Forwardable
|
||||
|
||||
def to(value)
|
||||
if !value.is_a?(String) && !value.is_a?(Regexp)
|
||||
raise "cannot match against #{value.inspect}"
|
||||
end
|
||||
@value = value
|
||||
self
|
||||
def_delegators :underlying_matcher,
|
||||
:description,
|
||||
:matches?,
|
||||
:failure_message,
|
||||
:failure_message_when_negated
|
||||
alias_method \
|
||||
:failure_message_for_should,
|
||||
:failure_message
|
||||
alias_method \
|
||||
:failure_message_for_should_not,
|
||||
:failure_message_when_negated
|
||||
|
||||
def initialize
|
||||
store = FlashStore.future
|
||||
@underlying_matcher = SetSessionOrFlashMatcher.new(store)
|
||||
end
|
||||
|
||||
def now
|
||||
@options[:now] = true
|
||||
store = FlashStore.now
|
||||
@underlying_matcher = SetSessionOrFlashMatcher.new(store)
|
||||
self
|
||||
end
|
||||
|
||||
def in_context(context)
|
||||
underlying_matcher.in_context(context)
|
||||
self
|
||||
end
|
||||
|
||||
def [](key)
|
||||
@options[:key] = key
|
||||
underlying_matcher[key]
|
||||
self
|
||||
end
|
||||
|
||||
def matches?(controller)
|
||||
@controller = controller
|
||||
sets_the_flash? && string_value_matches? && regexp_value_matches?
|
||||
def to(expected_value = nil, &block)
|
||||
underlying_matcher.to(expected_value, &block)
|
||||
self
|
||||
end
|
||||
|
||||
def description
|
||||
description = "set the #{expected_flash_invocation}"
|
||||
description << " to #{@value.inspect}" unless @value.nil?
|
||||
description
|
||||
end
|
||||
protected
|
||||
|
||||
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
|
||||
|
||||
private
|
||||
|
||||
def sets_the_flash?
|
||||
flash_values.any?
|
||||
end
|
||||
|
||||
def string_value_matches?
|
||||
if @value.is_a?(String)
|
||||
flash_values.any? {|value| value == @value }
|
||||
else
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
def regexp_value_matches?
|
||||
if @value.is_a?(Regexp)
|
||||
flash_values.any? {|value| value =~ @value }
|
||||
else
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
def flash_values
|
||||
if @options.key?(:key)
|
||||
flash_hash = HashWithIndifferentAccess.new(flash.to_hash)
|
||||
[flash_hash[@options[:key]]]
|
||||
else
|
||||
flash.to_hash.values
|
||||
end
|
||||
end
|
||||
|
||||
def flash
|
||||
@flash ||= copy_of_flash_from_controller
|
||||
end
|
||||
|
||||
def copy_of_flash_from_controller
|
||||
@controller.flash.dup.tap do |flash|
|
||||
copy_flashes(@controller.flash, flash)
|
||||
copy_discard_if_necessary(@controller.flash, flash)
|
||||
sweep_flash_if_necessary(flash)
|
||||
end
|
||||
end
|
||||
|
||||
def copy_flashes(original_flash, new_flash)
|
||||
flashes = original_flash.instance_variable_get('@flashes').dup
|
||||
new_flash.instance_variable_set('@flashes', flashes)
|
||||
end
|
||||
|
||||
def copy_discard_if_necessary(original_flash, new_flash)
|
||||
discard_ivar = :@discard
|
||||
if original_flash.instance_variable_defined?(discard_ivar)
|
||||
discard = original_flash.instance_variable_get(discard_ivar).dup
|
||||
new_flash.instance_variable_set(discard_ivar, discard)
|
||||
end
|
||||
end
|
||||
|
||||
def sweep_flash_if_necessary(flash)
|
||||
unless @options[:now]
|
||||
flash.sweep
|
||||
end
|
||||
end
|
||||
|
||||
def expectation
|
||||
expectation = "the #{expected_flash_invocation} to be set"
|
||||
expectation << " to #{@value.inspect}" unless @value.nil?
|
||||
expectation << ", but #{flash_description}"
|
||||
expectation
|
||||
end
|
||||
|
||||
def flash_description
|
||||
if flash.blank?
|
||||
'no flash was set'
|
||||
else
|
||||
"was #{flash.inspect}"
|
||||
end
|
||||
end
|
||||
|
||||
def expected_flash_invocation
|
||||
"flash#{pretty_now}#{pretty_key}"
|
||||
end
|
||||
|
||||
def pretty_now
|
||||
if @options[:now]
|
||||
'.now'
|
||||
else
|
||||
''
|
||||
end
|
||||
end
|
||||
|
||||
def pretty_key
|
||||
if @options[:key]
|
||||
"[:#{@options[:key]}]"
|
||||
else
|
||||
''
|
||||
end
|
||||
end
|
||||
attr_reader :underlying_matcher
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
require 'forwardable'
|
||||
|
||||
module Shoulda
|
||||
module Matchers
|
||||
module ActionController
|
||||
|
@ -112,132 +114,49 @@ module Shoulda
|
|||
#
|
||||
# @return [SetSessionMatcher]
|
||||
#
|
||||
def set_session(key = nil)
|
||||
SetSessionMatcher.new(key)
|
||||
def set_session
|
||||
SetSessionMatcher.new.in_context(self)
|
||||
end
|
||||
|
||||
# @private
|
||||
class SetSessionMatcher
|
||||
def initialize(key)
|
||||
if key
|
||||
Shoulda::Matchers.warn <<EOT
|
||||
Passing a key to set_session is deprecated.
|
||||
Please use the hash syntax instead (e.g., `set_session[:foo]`, not `set_session(:foo)`).
|
||||
EOT
|
||||
self[key]
|
||||
end
|
||||
extend Forwardable
|
||||
|
||||
@value_block = nil
|
||||
end
|
||||
def_delegators :underlying_matcher,
|
||||
:description,
|
||||
:matches?,
|
||||
:failure_message,
|
||||
:failure_message_when_negated
|
||||
alias_method \
|
||||
:failure_message_for_should,
|
||||
:failure_message
|
||||
alias_method \
|
||||
:failure_message_for_should_not,
|
||||
:failure_message_when_negated
|
||||
|
||||
def [](key)
|
||||
@key = key.to_s
|
||||
self
|
||||
end
|
||||
|
||||
def to(value = nil, &block)
|
||||
@value = value
|
||||
@value_block = block
|
||||
self
|
||||
end
|
||||
|
||||
def matches?(controller)
|
||||
@controller = controller
|
||||
|
||||
if @value_block
|
||||
@value = @context.instance_eval(&@value_block)
|
||||
end
|
||||
|
||||
if nil_value_expected_but_actual_value_unset?
|
||||
Shoulda::Matchers.warn <<EOT
|
||||
Using `should set_session[...].to(nil)` to assert that a variable is unset is deprecated.
|
||||
Please use `should_not set_session[...]` instead.
|
||||
EOT
|
||||
end
|
||||
|
||||
if key_specified? && value_specified?
|
||||
@value === session[@key]
|
||||
elsif key_specified?
|
||||
session.key?(@key)
|
||||
elsif value_specified?
|
||||
session.values.any? { |value| @value === value }
|
||||
else
|
||||
session_present?
|
||||
end
|
||||
end
|
||||
|
||||
def failure_message
|
||||
"Expected #{expectation}, but #{result}"
|
||||
end
|
||||
alias failure_message_for_should failure_message
|
||||
|
||||
def failure_message_when_negated
|
||||
"Didn't expect #{expectation}, but it was"
|
||||
end
|
||||
alias failure_message_for_should_not failure_message_when_negated
|
||||
|
||||
def description
|
||||
"should #{expectation}"
|
||||
def initialize
|
||||
store = SessionStore.new
|
||||
@underlying_matcher = SetSessionOrFlashMatcher.new(store)
|
||||
end
|
||||
|
||||
def in_context(context)
|
||||
@context = context
|
||||
underlying_matcher.in_context(context)
|
||||
self
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def key_specified?
|
||||
defined?(@key)
|
||||
def [](key)
|
||||
underlying_matcher[key]
|
||||
self
|
||||
end
|
||||
|
||||
def value_specified?
|
||||
defined?(@value)
|
||||
def to(expected_value = nil, &block)
|
||||
underlying_matcher.to(expected_value, &block)
|
||||
self
|
||||
end
|
||||
|
||||
def value_or_default_value
|
||||
defined?(@value) && @value
|
||||
end
|
||||
protected
|
||||
|
||||
def nil_value_expected_but_actual_value_unset?
|
||||
value_specified? && @value.nil? && !session.key?(@key)
|
||||
end
|
||||
|
||||
def session_present?
|
||||
!session.empty?
|
||||
end
|
||||
|
||||
def expectation
|
||||
expectation = ""
|
||||
|
||||
if key_specified?
|
||||
expectation << "session variable #{@key.inspect}"
|
||||
else
|
||||
expectation << "any session variable"
|
||||
end
|
||||
|
||||
expectation << " to be"
|
||||
|
||||
if value_specified? && !@value.nil?
|
||||
expectation << " #{@value.inspect}"
|
||||
else
|
||||
expectation << " set"
|
||||
end
|
||||
|
||||
expectation
|
||||
end
|
||||
|
||||
def result
|
||||
if session_present?
|
||||
"the session was #{session.inspect}"
|
||||
else
|
||||
'no session variables were set'
|
||||
end
|
||||
end
|
||||
|
||||
def session
|
||||
@controller.session
|
||||
end
|
||||
attr_reader :underlying_matcher
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -84,7 +84,7 @@ module Shoulda
|
|||
if key_set?
|
||||
string << " #{store.name}[#{key.inspect}]"
|
||||
else
|
||||
string << " any #{store.name} key"
|
||||
string << " any key in #{store.name}"
|
||||
end
|
||||
|
||||
if expected_value_set?
|
||||
|
|
355
spec/support/unit/shared_examples/set_session_or_flash.rb
Normal file
355
spec/support/unit/shared_examples/set_session_or_flash.rb
Normal file
|
@ -0,0 +1,355 @@
|
|||
shared_examples_for 'set session or flash matcher' do
|
||||
context 'without any qualifiers' do
|
||||
it 'produces the right description' do
|
||||
expected_description = "should set any key in #{store_name}"
|
||||
matcher = set_store
|
||||
|
||||
expect(matcher.description).to eq expected_description
|
||||
end
|
||||
|
||||
context 'in the positive' do
|
||||
context 'if the store is not empty' do
|
||||
it 'accepts' do
|
||||
controller = controller_with_store('any key' => 'any value')
|
||||
expect(controller).to set_store
|
||||
end
|
||||
end
|
||||
|
||||
context 'if the store is empty' do
|
||||
it 'rejects' do
|
||||
controller = controller_with_empty_store
|
||||
expect(controller).not_to set_store
|
||||
end
|
||||
|
||||
it 'produces the correct failure message' do
|
||||
controller = controller_with_empty_store
|
||||
expected_message = %<Expected #{controller.class} to set any key in #{store_name}, but it did not>
|
||||
|
||||
expect { expect(controller).to set_store }.
|
||||
to fail_with_message(expected_message)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'in the negative' do
|
||||
context 'if the given key is present in the store' do
|
||||
it 'produces the correct failure message' do
|
||||
controller = controller_with_store('any key' => 'any value')
|
||||
expected_message = %<Expected #{controller.class} not to set any key in #{store_name}, but it did>
|
||||
assertion = proc do
|
||||
expect(controller).not_to set_store
|
||||
end
|
||||
|
||||
expect(&assertion).to fail_with_message(expected_message)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with #[]' do
|
||||
it 'produces the right description' do
|
||||
matcher = set_store['the key']
|
||||
expected_description = %<should set #{store_name}["the key"]>
|
||||
|
||||
expect(matcher.description).to eq expected_description
|
||||
end
|
||||
|
||||
context 'in the positive' do
|
||||
context 'if the given key is present in the store' do
|
||||
it 'accepts' do
|
||||
controller = controller_with_store('the key' => 'any value')
|
||||
expect(controller).to set_store['the key']
|
||||
end
|
||||
end
|
||||
|
||||
context 'if the given key is not present in the store' do
|
||||
it 'rejects' do
|
||||
controller = controller_with_empty_store
|
||||
expect(controller).not_to set_store['the key']
|
||||
end
|
||||
|
||||
it 'produces the correct failure message' do
|
||||
controller = controller_with_empty_store
|
||||
expected_message = %<Expected #{controller.class} to set #{store_name}["the key"], but it did not>
|
||||
assertion = proc do
|
||||
expect(controller).to set_store['the key']
|
||||
end
|
||||
|
||||
expect(&assertion).to fail_with_message(expected_message)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'in the negative' do
|
||||
context 'if the given key is present in the store' do
|
||||
it 'produces the correct failure message' do
|
||||
controller = controller_with_store('the key' => 'any value')
|
||||
expected_message = %<Expected #{controller.class} not to set #{store_name}["the key"], but it did>
|
||||
assertion = proc do
|
||||
expect(controller).not_to set_store['the key']
|
||||
end
|
||||
|
||||
expect(&assertion).to fail_with_message(expected_message)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with #to' do
|
||||
context 'given a static value' do
|
||||
it 'produces the right description' do
|
||||
matcher = set_store.to('the value')
|
||||
expected_description = %<should set any key in #{store_name} to "the value">
|
||||
|
||||
expect(matcher.description).to eq expected_description
|
||||
end
|
||||
|
||||
context 'in the positive' do
|
||||
context 'if the given value is present in the store' do
|
||||
it 'accepts' do
|
||||
controller = controller_with_store('any key' => 'the value')
|
||||
expect(controller).to set_store.to('the value')
|
||||
end
|
||||
|
||||
it 'accepts given a value of nil' do
|
||||
controller = controller_with_store('any key' => nil)
|
||||
expect(controller).to set_store.to(nil)
|
||||
end
|
||||
|
||||
it 'accepts given a value of false' do
|
||||
controller = controller_with_store('any key' => false)
|
||||
expect(controller).to set_store.to(false)
|
||||
end
|
||||
end
|
||||
|
||||
context 'if the given value is not present in the store' do
|
||||
it 'rejects' do
|
||||
controller = controller_with_empty_store
|
||||
expect(controller).not_to set_store.to('the value')
|
||||
end
|
||||
|
||||
it 'rejects checking for nil' do
|
||||
controller = controller_with_empty_store
|
||||
expect(controller).not_to set_store.to(nil)
|
||||
end
|
||||
|
||||
it 'produces the correct failure message' do
|
||||
controller = controller_with_empty_store
|
||||
expected_message = %<Expected #{controller.class} to set any key in #{store_name} to "the value", but it did not>
|
||||
assertion = proc do
|
||||
expect(controller).to set_store.to('the value')
|
||||
end
|
||||
|
||||
expect(&assertion).to fail_with_message(expected_message)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'in the negative' do
|
||||
context 'if the given value is present in the store' do
|
||||
it 'produces the correct failure message' do
|
||||
controller = controller_with_store('any key' => 'the value')
|
||||
expected_message = %<Expected #{controller.class} not to set any key in #{store_name} to "the value", but it did>
|
||||
assertion = proc do
|
||||
expect(controller).not_to set_store.to('the value')
|
||||
end
|
||||
|
||||
expect(&assertion).to fail_with_message(expected_message)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'given a regexp' do
|
||||
it 'produces the right description' do
|
||||
matcher = set_store.to(/value/)
|
||||
expected_description = %<should set any key in #{store_name} to a value matching /value/>
|
||||
|
||||
expect(matcher.description).to eq expected_description
|
||||
end
|
||||
|
||||
context 'in the positive' do
|
||||
context 'if the given value is present in the store' do
|
||||
it 'accepts' do
|
||||
controller = controller_with_store('any key' => 'the value')
|
||||
expect(controller).to set_store.to(/value/)
|
||||
end
|
||||
|
||||
it 'accepts given a value of nil' do
|
||||
controller = controller_with_store('any key' => nil)
|
||||
expect(controller).to set_store.to(nil)
|
||||
end
|
||||
|
||||
it 'accepts given a value of false' do
|
||||
controller = controller_with_store('any key' => false)
|
||||
expect(controller).to set_store.to(false)
|
||||
end
|
||||
end
|
||||
|
||||
context 'if the given value is not present in the store' do
|
||||
it 'rejects' do
|
||||
controller = controller_with_empty_store
|
||||
expect(controller).not_to set_store.to(/value/)
|
||||
end
|
||||
|
||||
it 'produces the correct failure message' do
|
||||
controller = controller_with_empty_store
|
||||
expected_message = %<Expected #{controller.class} to set any key in #{store_name} to a value matching /value/, but it did not>
|
||||
assertion = proc do
|
||||
expect(controller).to set_store.to(/value/)
|
||||
end
|
||||
|
||||
expect(&assertion).to fail_with_message(expected_message)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'in the negative' do
|
||||
context 'if the given value is present in the store' do
|
||||
it 'produces the correct failure message' do
|
||||
controller = controller_with_store('any key' => 'the value')
|
||||
expected_message = %<Expected #{controller.class} not to set any key in #{store_name} to a value matching /value/, but it did>
|
||||
assertion = proc do
|
||||
expect(controller).not_to set_store.to(/value/)
|
||||
end
|
||||
|
||||
expect(&assertion).to fail_with_message(expected_message)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with #[] + #to' do
|
||||
context 'given a static value' do
|
||||
it 'produces the right description' do
|
||||
expected_description = %<should set #{store_name}["the key"] to "the value">
|
||||
matcher = set_store['the key'].to('the value')
|
||||
|
||||
expect(matcher.description).to eq expected_description
|
||||
end
|
||||
|
||||
context 'in the positive' do
|
||||
context 'if the given value is present in the store' do
|
||||
it 'accepts' do
|
||||
controller = controller_with_store('the key' => 'the value')
|
||||
expect(controller).to set_store['the key'].to('the value')
|
||||
end
|
||||
end
|
||||
|
||||
context 'if the given value is not present in the store' do
|
||||
it 'rejects' do
|
||||
controller = controller_with_empty_store
|
||||
expect(controller).not_to set_store['the key'].to('the value')
|
||||
end
|
||||
|
||||
it 'produces the correct failure message' do
|
||||
controller = controller_with_empty_store
|
||||
expected_message = %<Expected #{controller.class} to set #{store_name}["the key"] to "the value", but it did not>
|
||||
assertion = proc do
|
||||
expect(controller).to set_store['the key'].to('the value')
|
||||
end
|
||||
|
||||
expect(&assertion).to fail_with_message(expected_message)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'in the negative' do
|
||||
context 'if the given value is present in the store' do
|
||||
it 'produces the correct failure message' do
|
||||
controller = controller_with_store('the key' => 'the value')
|
||||
expected_message = %<Expected #{controller.class} not to set #{store_name}["the key"] to "the value", but it did>
|
||||
assertion = proc do
|
||||
expect(controller).not_to set_store['the key'].to('the value')
|
||||
end
|
||||
|
||||
expect(&assertion).to fail_with_message(expected_message)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'given a dynamic value' do
|
||||
it 'produces the right description' do
|
||||
context = double('context', method_in_context: 'the value')
|
||||
matcher = set_store['the key'].
|
||||
in_context(context).
|
||||
to { method_in_context }
|
||||
expected_description = %<should set #{store_name}["the key"] to "the value">
|
||||
|
||||
expect(matcher.description).to eq expected_description
|
||||
end
|
||||
|
||||
context 'in the positive' do
|
||||
context 'if the value evaluated in the context is present in the store' do
|
||||
it 'accepts' do
|
||||
controller = controller_with_store('the key' => 'the value')
|
||||
context = double('context', method_in_context: 'the value')
|
||||
|
||||
expect(controller).to set_store['the key'].
|
||||
in_context(context).
|
||||
to { method_in_context }
|
||||
end
|
||||
end
|
||||
|
||||
context 'if the value evaluated in the context is not present in the store' do
|
||||
it 'rejects' do
|
||||
controller = controller_with_empty_store
|
||||
context = double('context', method_in_context: 'the value')
|
||||
|
||||
expect(controller).not_to set_store['the key'].
|
||||
in_context(context).
|
||||
to { method_in_context }
|
||||
end
|
||||
|
||||
it 'produces the correct failure message' do
|
||||
controller = controller_with_empty_store
|
||||
context = double('context', method_in_context: 'the value')
|
||||
expected_message = %<Expected #{controller.class} to set #{store_name}["the key"] to "the value", but it did not>
|
||||
assertion = proc do
|
||||
expect(controller).to set_store['the key'].
|
||||
in_context(context).
|
||||
to { method_in_context }
|
||||
end
|
||||
|
||||
expect(&assertion).to fail_with_message(expected_message)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'in the negative' do
|
||||
context 'if the value evaluated in the context is present in the store' do
|
||||
it 'produces the correct failure message' do
|
||||
context = double('context', method_in_context: 'the value')
|
||||
controller = controller_with_store('the key' => 'the value')
|
||||
expected_message = %<Expected #{controller.class} not to set #{store_name}["the key"] to "the value", but it did>
|
||||
assertion = proc do
|
||||
expect(controller).not_to set_store['the key'].
|
||||
in_context(context).
|
||||
to { method_in_context }
|
||||
end
|
||||
|
||||
expect(&assertion).to fail_with_message(expected_message)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def controller_with_empty_store
|
||||
build_fake_response
|
||||
end
|
||||
|
||||
def controller_with_store(store_contents)
|
||||
context = self
|
||||
|
||||
build_fake_response do
|
||||
store = context.store_within(self)
|
||||
|
||||
store_contents.each do |key, value|
|
||||
store[key] = value
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,153 +1,43 @@
|
|||
require 'unit_spec_helper'
|
||||
|
||||
describe Shoulda::Matchers::ActionController::SetFlashMatcher, type: :controller do
|
||||
it 'fails with unmatchable #to' do
|
||||
expect { set_flash.to(1) }.to raise_error('cannot match against 1')
|
||||
end
|
||||
|
||||
context 'a controller that sets a flash message' do
|
||||
it 'accepts setting any flash message' do
|
||||
expect(controller_with_flash(notice: 'hi')).to set_flash
|
||||
it_behaves_like 'set session or flash matcher' do
|
||||
def store_name
|
||||
'flash'
|
||||
end
|
||||
|
||||
it 'accepts setting the exact flash message' do
|
||||
expect(controller_with_flash(notice: 'hi')).to set_flash.to('hi')
|
||||
def set_store
|
||||
set_flash
|
||||
end
|
||||
|
||||
it 'accepts setting a matched flash message' do
|
||||
expect(controller_with_flash(notice: 'hello')).to set_flash.to(/he/)
|
||||
end
|
||||
|
||||
it 'rejects setting a different flash message' do
|
||||
expect(controller_with_flash(notice: 'hi')).
|
||||
not_to set_flash.to('other')
|
||||
end
|
||||
|
||||
it 'rejects setting a different pattern' do
|
||||
expect(controller_with_flash(notice: 'hi')).
|
||||
not_to set_flash.to(/other/)
|
||||
def store_within(controller)
|
||||
controller.flash
|
||||
end
|
||||
end
|
||||
|
||||
context 'a controller that sets a flash.now message' do
|
||||
it 'rejects setting any flash message' do
|
||||
expect(controller_with_flash_now).not_to set_flash
|
||||
it_behaves_like 'set session or flash matcher' do
|
||||
def store_name
|
||||
'flash.now'
|
||||
end
|
||||
|
||||
it 'accepts setting any flash.now message' do
|
||||
expect(controller_with_flash_now).to set_flash.now
|
||||
def set_store
|
||||
set_flash.now
|
||||
end
|
||||
|
||||
it 'accepts setting the exact flash.now message' do
|
||||
expect(controller_with_flash_now(notice: 'hi')).
|
||||
to set_flash.now.to('hi')
|
||||
end
|
||||
|
||||
it 'accepts setting a matched flash.now message' do
|
||||
expect(controller_with_flash_now(notice: 'flasher')).
|
||||
to set_flash.now.to(/lash/)
|
||||
end
|
||||
|
||||
it 'rejects setting a different flash.now message' do
|
||||
expect(controller_with_flash_now(notice: 'hi')).
|
||||
not_to set_flash.now.to('other')
|
||||
end
|
||||
|
||||
it 'rejects setting a different flash.now pattern' do
|
||||
expect(controller_with_flash_now(notice: 'hi')).
|
||||
not_to set_flash.now.to(/other/)
|
||||
def store_within(controller)
|
||||
controller.flash.now
|
||||
end
|
||||
end
|
||||
|
||||
context 'a controller that sets flash messages for multiple keys' do
|
||||
it 'accepts flash message for either key' do
|
||||
controller = controller_with_flash(notice: 'one', alert: 'two')
|
||||
|
||||
expect(controller).to set_flash[:notice]
|
||||
expect(controller).to set_flash[:alert]
|
||||
end
|
||||
|
||||
it 'rejects a flash message that is not one of the set keys' do
|
||||
expect(controller_with_flash(notice: 'one', alert: 'two')).
|
||||
not_to set_flash[:warning]
|
||||
end
|
||||
|
||||
it 'accepts exact flash message of notice' do
|
||||
expect(controller_with_flash(notice: 'one', alert: 'two')).
|
||||
to set_flash[:notice].to('one')
|
||||
end
|
||||
|
||||
it 'accepts setting a matched flash message of notice' do
|
||||
expect(controller_with_flash(notice: 'one', alert: 'two')).
|
||||
to set_flash[:notice].to(/on/)
|
||||
end
|
||||
|
||||
it 'rejects setting a different flash message of notice' do
|
||||
expect(controller_with_flash(notice: 'one', alert: 'two')).
|
||||
not_to set_flash[:notice].to('other')
|
||||
end
|
||||
|
||||
it 'rejects setting a different pattern' do
|
||||
expect(controller_with_flash(notice: 'one', alert: 'two')).
|
||||
not_to set_flash[:notice].to(/other/)
|
||||
end
|
||||
end
|
||||
|
||||
context 'a controller that sets flash and flash.now' do
|
||||
it 'accepts setting any flash.now message' do
|
||||
context 'when the controller sets both flash and flash.now' do
|
||||
it 'does not mix flash and flash.now' do
|
||||
controller = build_fake_response do
|
||||
flash.now[:notice] = 'value'
|
||||
flash[:success] = 'great job'
|
||||
flash['key for flash'] = 'value for flash'
|
||||
flash.now['key for flash.now'] = 'value for flash.now'
|
||||
end
|
||||
|
||||
expect(controller).to set_flash.now
|
||||
expect(controller).to set_flash
|
||||
end
|
||||
|
||||
it 'accepts setting a matched flash.now message' do
|
||||
controller = build_fake_response do
|
||||
flash.now[:notice] = 'value'
|
||||
flash[:success] = 'great job'
|
||||
end
|
||||
|
||||
expect(controller).to set_flash.now.to(/value/)
|
||||
expect(controller).to set_flash.to(/great/)
|
||||
end
|
||||
|
||||
it 'rejects setting a different flash.now message' do
|
||||
controller = build_fake_response do
|
||||
flash.now[:notice] = 'value'
|
||||
flash[:success] = 'great job'
|
||||
end
|
||||
|
||||
expect(controller).not_to set_flash.now.to('other')
|
||||
expect(controller).not_to set_flash.to('other')
|
||||
end
|
||||
end
|
||||
|
||||
context 'a controller that does not set a flash message' do
|
||||
it 'rejects setting any flash message' do
|
||||
expect(controller_with_no_flashes).not_to set_flash
|
||||
end
|
||||
end
|
||||
|
||||
def controller_with_no_flashes
|
||||
build_fake_response
|
||||
end
|
||||
|
||||
def controller_with_flash(flash_hash)
|
||||
build_fake_response do
|
||||
flash_hash.each do |key, value|
|
||||
flash[key] = value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def controller_with_flash_now(flash_hash = { notice: 'hi' })
|
||||
build_fake_response do
|
||||
flash_hash.each do |key, value|
|
||||
flash.now[key] = value
|
||||
end
|
||||
expect(controller).not_to set_flash['key for flash.now']
|
||||
expect(controller).not_to set_flash.now['key for flash']
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,294 +1,17 @@
|
|||
require 'unit_spec_helper'
|
||||
|
||||
describe Shoulda::Matchers::ActionController, '#set_session', type: :controller do
|
||||
context 'passing an argument to the initializer' do
|
||||
it 'is deprecated in favor of using #[]' do
|
||||
expectation = proc { set_session(:foo) }
|
||||
|
||||
expect(&expectation).to print_warning_including(
|
||||
'Passing a key to set_session is deprecated'
|
||||
)
|
||||
describe Shoulda::Matchers::ActionController::SetSessionMatcher, type: :controller do
|
||||
it_behaves_like 'set session or flash matcher' do
|
||||
def store_name
|
||||
'session'
|
||||
end
|
||||
|
||||
it 'still works regardless' do
|
||||
silence_warnings do
|
||||
expect(controller_with_session(var: 'hi')).to set_session(:var)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'a controller that sets a session variable' do
|
||||
context 'without any qualifiers' do
|
||||
it 'accepts' do
|
||||
expect(controller_with_session(var: 'hi')).to set_session
|
||||
end
|
||||
def set_store
|
||||
set_session
|
||||
end
|
||||
|
||||
context 'with #to' do
|
||||
context 'given a static value' do
|
||||
context 'when any key in session has the given value' do
|
||||
it 'accepts' do
|
||||
expect(controller_with_session(var: 'hi')).
|
||||
to set_session.to('hi')
|
||||
end
|
||||
|
||||
it 'accepts given nil' do
|
||||
silence_warnings do
|
||||
expect(controller_with_session(var: nil)).
|
||||
to set_session.to(nil)
|
||||
end
|
||||
end
|
||||
|
||||
it 'accepts given false' do
|
||||
expect(controller_with_session(var: false)).
|
||||
to set_session.to(false)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when no key in session has the given value' do
|
||||
it 'rejects' do
|
||||
expect(controller_with_session(var: 'hi')).
|
||||
not_to set_session.to('different')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'given a dynamic value' do
|
||||
context 'when any key in session has the given value' do
|
||||
it 'accepts' do
|
||||
context = double(expected: 'hi')
|
||||
expect(controller_with_session(var: 'hi')).
|
||||
to set_session.in_context(context).to { expected }
|
||||
end
|
||||
|
||||
it 'accepts given nil' do
|
||||
silence_warnings do
|
||||
context = double(expected: nil)
|
||||
expect(controller_with_session(var: nil)).
|
||||
to set_session.in_context(context).to { expected }
|
||||
end
|
||||
end
|
||||
|
||||
it 'accepts given false' do
|
||||
context = double(expected: false)
|
||||
expect(controller_with_session(var: false)).
|
||||
to set_session.in_context(context).to { expected }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when no key in session has the given value' do
|
||||
it 'rejects' do
|
||||
context = double(expected: 'different')
|
||||
expect(controller_with_session(var: 'hi')).
|
||||
not_to set_session.in_context(context).to { expected }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'given a regexp' do
|
||||
context 'when any value in session matches the regexp' do
|
||||
it 'accepts' do
|
||||
expect(controller_with_session(var: 'hello')).
|
||||
to set_session.to(/ello/)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when no value in session matches the regexp' do
|
||||
it 'rejects' do
|
||||
expect(controller_with_session(var: 'hello')).
|
||||
not_to set_session.to(/different/)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with #[]' do
|
||||
context 'when the given key is present in session' do
|
||||
it 'accepts' do
|
||||
expect(controller_with_session(var: 'hi')).to set_session[:var]
|
||||
end
|
||||
|
||||
it 'accepts when expected key is a string' do
|
||||
expect(controller_with_session(var: 'hi')).to set_session['var']
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the given key is not present in session' do
|
||||
it 'rejects' do
|
||||
expect(controller_with_session(var: 'hi')).not_to set_session[:other]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with #[] + #to' do
|
||||
context 'given a static value' do
|
||||
context 'when the given key and value are present in session' do
|
||||
it 'accepts' do
|
||||
expect(controller_with_session(var: 'hi')).
|
||||
to set_session[:var].to('hi')
|
||||
end
|
||||
|
||||
it 'accepts given nil' do
|
||||
silence_warnings do
|
||||
expect(controller_with_session(var: nil)).
|
||||
to set_session[:var].to(nil)
|
||||
end
|
||||
end
|
||||
|
||||
it 'accepts given false' do
|
||||
expect(controller_with_session(var: false)).
|
||||
to set_session[:var].to(false)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the given key is present in session but not the given value' do
|
||||
it 'rejects' do
|
||||
expect(controller_with_session(var: 'hi')).
|
||||
not_to set_session[:var].to('other')
|
||||
end
|
||||
|
||||
it 'rejects given nil' do
|
||||
expect(controller_with_session(var: 'hi')).
|
||||
not_to set_session[:var].to(nil)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the given key is not present in session' do
|
||||
it 'accepts given nil' do
|
||||
silence_warnings do
|
||||
expect(controller_with_session(var: 'hi')).
|
||||
to set_session[:other].to(nil)
|
||||
end
|
||||
end
|
||||
|
||||
it 'rejects given false' do
|
||||
expect(controller_with_session(var: false)).
|
||||
not_to set_session[:other].to(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'given a dynamic value' do
|
||||
context 'when the given key and value are present in session' do
|
||||
it 'accepts' do
|
||||
context = double(expected: 'value')
|
||||
|
||||
expect(controller_with_session(var: 'value')).
|
||||
to set_session[:var].in_context(context).to { expected }
|
||||
end
|
||||
|
||||
it 'accepts given nil' do
|
||||
silence_warnings do
|
||||
context = double(expected: nil)
|
||||
|
||||
expect(controller_with_session(var: nil)).
|
||||
to set_session[:var].in_context(context).to { expected }
|
||||
end
|
||||
end
|
||||
|
||||
it 'accepts given false' do
|
||||
context = double(expected: false)
|
||||
|
||||
expect(controller_with_session(var: false)).
|
||||
to set_session[:var].in_context(context).to { expected }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the given key is present in session but not the given value' do
|
||||
it 'rejects given nil' do
|
||||
context = double(expected: nil)
|
||||
|
||||
expect(controller_with_session(var: 'hi')).
|
||||
not_to set_session[:var].in_context(context).to { expected }
|
||||
end
|
||||
|
||||
it 'rejects given false' do
|
||||
context = double(expected: false)
|
||||
|
||||
expect(controller_with_session(var: 'hi')).
|
||||
not_to set_session[:var].in_context(context).to { expected }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the given key is not present in session' do
|
||||
it 'rejects' do
|
||||
context = double(expected: 'other')
|
||||
|
||||
expect(controller_with_session(var: 'unexpected')).
|
||||
not_to set_session[:var].in_context(context).to { expected }
|
||||
end
|
||||
|
||||
it 'accepts given nil' do
|
||||
silence_warnings do
|
||||
context = double(expected: nil)
|
||||
|
||||
expect(controller_with_session(var: 'hi')).
|
||||
to set_session[:other].in_context(context).to { expected }
|
||||
end
|
||||
end
|
||||
|
||||
it 'rejects given false' do
|
||||
context = double(expected: false)
|
||||
|
||||
expect(controller_with_session(var: false)).
|
||||
not_to set_session[:other].in_context(context).to { expected }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'a controller that does not set any session variables' do
|
||||
context 'without any qualifiers' do
|
||||
it 'rejects' do
|
||||
expect(controller_without_session).not_to set_session
|
||||
end
|
||||
end
|
||||
|
||||
context 'with #[]' do
|
||||
it 'rejects' do
|
||||
expect(controller_without_session).
|
||||
not_to set_session['any key']
|
||||
end
|
||||
end
|
||||
|
||||
context 'with #to' do
|
||||
it 'rejects' do
|
||||
expect(controller_without_session).
|
||||
not_to set_session.to('any value')
|
||||
end
|
||||
end
|
||||
|
||||
context 'with #[] + #to' do
|
||||
it 'rejects' do
|
||||
expect(controller_without_session).
|
||||
not_to set_session['any key'].to('any value')
|
||||
end
|
||||
|
||||
it 'prints a warning when using .to(nil) to assert that a variable is unset' do
|
||||
expectation = proc do
|
||||
expect(controller_without_session).to set_session['any key'].to(nil)
|
||||
end
|
||||
|
||||
expected_warning = <<EOT
|
||||
Using `should set_session[...].to(nil)` to assert that a variable is unset is deprecated.
|
||||
Please use `should_not set_session[...]` instead.
|
||||
EOT
|
||||
|
||||
expect(&expectation).to print_warning_including(expected_warning)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def controller_without_session
|
||||
build_fake_response
|
||||
end
|
||||
|
||||
def controller_with_session(session_hash)
|
||||
build_fake_response do
|
||||
session_hash.each do |key, value|
|
||||
session[key] = value
|
||||
end
|
||||
def store_within(controller)
|
||||
controller.session
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue