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 159 160 161 162 163 164 165 166 167 168 169 170 171 172
|
require "spec_helper"
require "pp"
RSpec.describe "Diffs printed when arguments don't match" do
before do
allow(RSpec::Mocks.configuration).to receive(:color?).and_return(false)
end
context "with a non matcher object" do
it "does not print a diff when single line arguments are mismatched" do
with_unfulfilled_double do |d|
expect(d).to receive(:foo).with("some string")
expect {
d.foo("this other string")
}.to fail_with(a_string_excluding("Diff:"))
end
end
it "does not print a diff when differ returns a string of only whitespace" do
differ = instance_double(RSpec::Support::Differ, :diff => " \n \t ")
allow(RSpec::Support::Differ).to receive_messages(:new => differ)
with_unfulfilled_double do |d|
expect(d).to receive(:foo).with("some string\nline2")
expect {
d.foo("this other string")
}.to fail_with(a_string_excluding("Diff:"))
end
end
it "prints a diff of the strings for individual mismatched multi-line string arguments" do
with_unfulfilled_double do |d|
expect(d).to receive(:foo).with("some string\nline2")
expect {
d.foo("this other string")
}.to fail_with("#<Double \"double\"> received :foo with unexpected arguments\n" \
" expected: (\"some string\\nline2\")\n got: (\"this other string\")\n" \
"Diff:\n@@ -1,3 +1,2 @@\n-some string\n-line2\n+this other string\n")
end
end
it "prints a diff of the args lists for multiple mismatched string arguments" do
with_unfulfilled_double do |d|
expect(d).to receive(:foo).with("some string\nline2", "some other string")
expect {
d.foo("this other string")
}.to fail_with("#<Double \"double\"> received :foo with unexpected arguments\n" \
" expected: (\"some string\\nline2\", \"some other string\")\n" \
" got: (\"this other string\")\nDiff:\n@@ -1,3 +1,2 @@\n-some string\\nline2\n-some other string\n+this other string\n")
end
end
it "does not print a diff when multiple single-line string arguments are mismatched" do
with_unfulfilled_double do |d|
expect(d).to receive(:foo).with("some string", "some other string")
expect {
d.foo("this other string", "a fourth string")
}.to fail_with(a_string_excluding("Diff:"))
end
end
let(:expected_hash) { {:foo => :bar, :baz => :quz} }
let(:actual_hash) { {:bad => :hash} }
it "prints a diff with hash args" do
with_unfulfilled_double do |d|
expect(d).to receive(:foo).with(expected_hash)
expect {
d.foo(:bad => :hash)
}.to fail_with(/\A#<Double "double"> received :foo with unexpected arguments\n expected: \(#{hash_regex_inspect expected_hash}\)\n got: \(#{hash_regex_inspect actual_hash}\)\nDiff:\n@@ \-1\,2 \+1\,2 @@\n\-\[#{hash_regex_inspect expected_hash}\]\n\+\[#{hash_regex_inspect actual_hash}\]\n\z/)
end
end
it "prints a diff with an expected hash arg and a non-hash actual arg" do
with_unfulfilled_double do |d|
expect(d).to receive(:foo).with(expected_hash)
expect {
d.foo(Object.new)
}.to fail_with(/-\[#{hash_regex_inspect expected_hash}\].*\+\[#<Object.*>\]/m)
end
end
if RUBY_VERSION.to_f < 1.9
# Ruby 1.8 hashes are not ordered, but `#inspect` on a particular unchanged
# hash instance should return consistent output. However, on Travis that does
# not always seem to be true and we have no idea why. Somehow, the travis build
# has occasionally failed due to the output ordering varying between `inspect`
# calls to the same hash. This regex allows us to work around that.
def hash_regex_inspect(hash)
"\\{(#{hash.map { |key, value| "#{key.inspect}=>#{value.inspect}.*" }.join "|"}){#{hash.size}}\\}"
end
else
def hash_regex_inspect(hash)
Regexp.escape(hash.inspect)
end
end
it "prints a diff with array args" do
with_unfulfilled_double do |d|
expect(d).to receive(:foo).with([:a, :b, :c])
expect {
d.foo([])
}.to fail_with("#<Double \"double\"> received :foo with unexpected arguments\n expected: ([:a, :b, :c])\n got: ([])\nDiff:\n@@ -1,2 +1,2 @@\n-[[:a, :b, :c]]\n+[[]]\n")
end
end
context "that defines #description" do
it "does not use the object's description for a non-matcher object that implements #description" do
with_unfulfilled_double do |d|
collab = double(:collab, :description => "This string")
collab_inspect = collab.inspect
expect(d).to receive(:foo).with(collab)
expect {
d.foo([])
}.to fail_with("#<Double \"double\"> received :foo with unexpected arguments\n" \
" expected: (#{collab_inspect})\n" \
" got: ([])\nDiff:\n@@ -1,2 +1,2 @@\n-[#{collab_inspect}]\n+[[]]\n")
end
end
end
end
context "with a matcher object" do
context "that defines #description" do
it "uses the object's description" do
with_unfulfilled_double do |d|
collab = fake_matcher(Object.new)
collab_description = collab.description
expect(d).to receive(:foo).with(collab)
expect {
d.foo([:a, :b])
}.to fail_with("#<Double \"double\"> received :foo with unexpected arguments\n" \
" expected: (#{collab_description})\n" \
" got: ([:a, :b])\nDiff:\n@@ -1,2 +1,2 @@\n-[\"#{collab_description}\"]\n+[[:a, :b]]\n")
end
end
end
context "that does not define #description" do
it "for a matcher object that does not implement #description" do
with_unfulfilled_double do |d|
collab = Class.new do
def self.name
"RSpec::Mocks::ArgumentMatchers::"
end
def inspect
"#<MyCollab>"
end
end.new
expect(RSpec::Support.is_a_matcher?(collab)).to be true
collab_inspect = collab.inspect
collab_pp = PP.pp(collab, "").strip
expect(d).to receive(:foo).with(collab)
expect {
d.foo([:a, :b])
}.to fail_with("#<Double \"double\"> received :foo with unexpected arguments\n" \
" expected: (#{collab_inspect})\n" \
" got: ([:a, :b])\nDiff:\n@@ -1,2 +1,2 @@\n-[#{collab_pp}]\n+[[:a, :b]]\n")
end
end
end
end
end
|