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
|
module RSpec
module Matchers
RSpec.describe Composable do
RSpec::Matchers.define :matcher_using_surface_descriptions_in do |expected|
match { false }
failure_message { surface_descriptions_in(expected).to_s }
end
it "does not blow up when surfacing descriptions from an unreadable IO object" do
expect {
expect(3).to matcher_using_surface_descriptions_in(STDOUT)
}.to fail_with(STDOUT.inspect)
end
it "does not blow up when surfacing descriptions from an unreadable Range object" do
infinity = (1.0/0.0)
infinite_range = -infinity..infinity
expect {
expect(1).to matcher_using_surface_descriptions_in(infinite_range)
}.to fail_with(infinite_range.inspect)
end
it "does not blow up when surfacing descriptions from an Enumerable object whose #each includes the object itself" do
array = ['something']
array << array
expect {
expect(1).to matcher_using_surface_descriptions_in(array)
}.to fail_with(array.to_s)
end
it "does not enumerate normal ranges" do
range = 1..3
expect {
expect(1).to matcher_using_surface_descriptions_in(range)
}.to fail_with(range.inspect)
end
it "doesn't mangle struct descriptions" do
model = Struct.new(:a).new(1)
expect {
expect(1).to matcher_using_surface_descriptions_in(model)
}.to fail_with(model.inspect)
end
RSpec::Matchers.define :all_but_one do |matcher|
match do |actual|
match_count = actual.count { |v| values_match?(matcher, v) }
actual.size == match_count + 1
end
end
context "when using a matcher instance that memoizes state multiple times in a composed expression" do
it "works properly in spite of the memoization" do
expect(["foo", "bar", "a"]).to all_but_one(have_string_length(3))
end
context "when passing a compound expression" do
it "works properly in spite of the memoization" do
expect(["A", "AB", "ABC"]).to all_but_one(
have_string_length(1).or have_string_length(2)
)
end
end
end
describe "cloning data structures containing matchers" do
include Composable
it "clones only the contained matchers" do
matcher_1 = eq(1)
matcher_2 = eq(2)
object = Object.new
uncloneable = nil
data_structure = {
"foo" => matcher_1,
"bar" => [matcher_2, uncloneable],
"bazz" => object
}
cloned = with_matchers_cloned(data_structure)
expect(cloned).not_to equal(data_structure)
expect(cloned["foo"]).to be_a_clone_of(matcher_1)
expect(cloned["bar"].first).to be_a_clone_of(matcher_2)
expect(cloned["bazz"]).to equal(object)
end
it "copies custom matchers properly so they can work even though they have singleton behavior" do
expect("foo").to with_matchers_cloned(have_string_length 3)
end
it 'does not blow up when passed an array containing an IO object' do
stdout = STDOUT
expect(with_matchers_cloned([stdout]).first).to equal(stdout)
end
end
end
end
end
|