1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
|
require "spec_helper"
RSpec.describe "Reraising eager raises during the verify step" do
it "does not reraise when a double receives a message that hasn't been allowed/expected" do
with_unfulfilled_double do |dbl|
expect { dbl.foo }.to fail
expect { verify_all }.not_to raise_error
end
end
context "when a negative expectation receives a call" do
it "reraises during verification" do
with_unfulfilled_double do |dbl|
expect(dbl).not_to receive(:foo)
expect { dbl.foo }.to fail
expect { verify_all }.to fail_with(/expected: 0 times with any arguments/)
end
end
it 'notifies both exceptions using the same `:source_id` so `aggregate_failures` can de-dup' do
with_unfulfilled_double do |dbl|
expect(dbl).not_to receive(:foo)
expect { dbl.foo }.to notify_with_same_source_id_as_later_verification
end
end
it 'notifies with a different `source_id` than that for the same double and a different message' do
with_unfulfilled_double do |dbl|
expect(dbl).not_to receive(:foo)
expect {
dbl.foo # should trigger first source_id
reset(dbl)
# Prepare a failing expectation for a different message
expect(dbl).not_to receive(:bar)
RSpec::Support.with_failure_notifier(Proc.new {}) { dbl.bar }
}.not_to notify_with_same_source_id_as_later_verification
end
end
it 'notifies with a different `source_id` than a different double expecting that message' do
with_unfulfilled_double do |dbl_1|
with_unfulfilled_double do |dbl_2|
expect(dbl_1).not_to receive(:foo)
expect(dbl_2).not_to receive(:foo)
expect { dbl_2.foo }.to fail
expect { dbl_1.foo; reset(dbl_1) }.not_to notify_with_same_source_id_as_later_verification
end
end
end
end
context "when an expectation with a count is exceeded" do
def prepare(dbl)
expect(dbl).to receive(:foo).exactly(2).times
dbl.foo
dbl.foo
end
it "reraises during verification" do
with_unfulfilled_double do |dbl|
prepare dbl
expect { dbl.foo }.to fail
expect { verify_all }.to fail_with(/expected: 2 times with any arguments/)
end
end
it 'notifies both exceptions using the same `:source_id` so `aggregate_failures` can de-dup' do
with_unfulfilled_double do |dbl|
prepare dbl
expect { dbl.foo }.to notify_with_same_source_id_as_later_verification
end
end
end
context "when an expectation is called with the wrong arguments" do
it "reraises during verification" do
with_unfulfilled_double do |dbl|
expect(dbl).to receive(:foo).with(1, 2, 3)
expect { dbl.foo(1, 2, 4) }.to fail
expect { verify_all }.to fail_with(/expected: 1 time with arguments: \(1, 2, 3\)/)
end
end
it 'notifies both exceptions using the same `:source_id` so `aggregate_failures` can de-dup' do
with_unfulfilled_double do |dbl|
expect(dbl).to receive(:foo).with(1, 2, 3)
expect { dbl.foo(1, 2, 4) }.to notify_with_same_source_id_as_later_verification
end
end
end
context "when an expectation is called out of order",
:pending => "Says bar was called 0 times when it was, see: http://git.io/pjTq" do
it "reraises during verification" do
with_unfulfilled_double do |dbl|
expect(dbl).to receive(:foo).ordered
expect(dbl).to receive(:bar).ordered
expect { dbl.bar }.to fail
dbl.foo # satisfy the `foo` expectation so that only the bar one fails below
expect { verify_all }.to fail_with(/received :bar out of order/)
end
end
end
RSpec::Matchers.define :notify_with_same_source_id_as_later_verification do
attr_reader :block
match do |block|
@block = block
block_source_id == verify_all_source_id && block_source_id
end
match_when_negated do |block|
@block = block
block_source_id && verify_all_source_id && (
block_source_id != verify_all_source_id
)
end
supports_block_expectations
failure_message do
if block_source_id.nil?
"expected it to notify with a non-nil source id"
else
"expected `verify_all` to notify with source_id: #{block_source_id.inspect} but notified with source_id: #{verify_all_source_id.inspect}"
end
end
failure_message_when_negated do
if block_source_id.nil?
"expected it to notify with a non-nil source id"
else
"expected `verify_all` to notify with a different source_id but got the same one: #{block_source_id.inspect} / #{verify_all_source_id.inspect}"
end
end
def block_source_id
@block_source_id ||= capture_notified_source_id(&block)
end
def verify_all_source_id
@verify_all_source_id ||= capture_notified_source_id { verify_all }
end
def capture_notified_source_id(&block)
source_id = nil
notifier = Proc.new { |_err, opt| source_id = opt.fetch(:source_id) }
RSpec::Support.with_failure_notifier(notifier, &block)
source_id
end
end
end
|