diff --git a/lib/super_diff/rspec/monkey_patches.rb b/lib/super_diff/rspec/monkey_patches.rb index 851914c5..3e46f5ea 100644 --- a/lib/super_diff/rspec/monkey_patches.rb +++ b/lib/super_diff/rspec/monkey_patches.rb @@ -734,11 +734,9 @@ def actual_for_diff def expected_for_matcher_text if @expected_message - "#<#{@expected_error.name} #{description_of(@expected_message)}>" - elsif @expected_error.is_a? Regexp - "#" + "#<#{describe_expected_error} #{description_of(@expected_message)}>" else - "#<#{@expected_error.name}>" + "#<#{describe_expected_error}>" end end @@ -757,6 +755,20 @@ def expected_action_for_failure_message def matcher_text_builder_class SuperDiff::RSpec::MatcherTextBuilders::RaiseError end + + private + + def describe_expected_error + if @expected_error.is_a? Class + @expected_error.name + elsif @expected_error.is_a? Regexp + "Exception #{description_of(@expected_error)}" + elsif @expected_error.respond_to? :description + @expected_error.description + else + SuperDiff.inspect_object(@expected_error, as_lines: false) + end + end end def self.matcher_name diff --git a/spec/integration/rspec/raise_error_matcher_spec.rb b/spec/integration/rspec/raise_error_matcher_spec.rb index 0233de9d..1572cea0 100644 --- a/spec/integration/rspec/raise_error_matcher_spec.rb +++ b/spec/integration/rspec/raise_error_matcher_spec.rb @@ -741,4 +741,430 @@ end end end + + context "with a simple RSpec matcher" do + context "when used in the positive" do + context "when the block raises a different error than what is given" do + context "when the message is short" do + it "produces the correct failure message" do + as_both_colored_and_uncolored do |color_enabled| + snippet = <<~TEST.strip + expect { raise StandardError.new('boo') }.to raise_error(a_kind_of(Array)) + TEST + program = + make_plain_test_program(snippet, color_enabled: color_enabled) + + expected_output = + build_expected_output( + color_enabled: color_enabled, + snippet: + "expect { raise StandardError.new('boo') }.to raise_error(a_kind_of(Array))", + expectation: + proc do + line do + plain "Expected raised exception " + actual %|#| + plain " to match " + expected "#" + plain "." + end + end + ) + + expect(program).to produce_output_when_run( + expected_output + ).in_color(color_enabled) + end + end + end + + context "when the message is long" do + it "produces the correct failure message" do + as_both_colored_and_uncolored do |color_enabled| + snippet = <<~TEST.strip + expect { raise StandardError.new('this is a super super super long message') }.to raise_error(a_kind_of(RuntimeError)) + TEST + program = + make_plain_test_program(snippet, color_enabled: color_enabled) + + expected_output = + build_expected_output( + color_enabled: color_enabled, + snippet: + "expect { raise StandardError.new('this is a super super super long message') }.to raise_error(a_kind_of(RuntimeError))", + newline_before_expectation: true, + expectation: + proc do + line do + plain "Expected raised exception " + actual %|#| + end + + line do + plain " to match " + expected "#" + end + end + ) + + expect(program).to produce_output_when_run( + expected_output + ).in_color(color_enabled) + end + end + end + end + + context "when the block raises no error" do + it "produces the correct failure message" do + as_both_colored_and_uncolored do |color_enabled| + snippet = <<~TEST.strip + expect { }.to raise_error(a_kind_of(RuntimeError)) + TEST + program = + make_plain_test_program(snippet, color_enabled: color_enabled) + + expected_output = + build_expected_output( + color_enabled: color_enabled, + snippet: "expect { }.to raise_error(a_kind_of(RuntimeError))", + expectation: + proc do + line do + plain "Expected block to raise error " + expected "#" + plain "." + end + end + ) + + expect(program).to produce_output_when_run( + expected_output + ).in_color(color_enabled) + end + end + end + end + + context "when used in the negative" do + context "when the message is short" do + it "produces the correct failure message" do + as_both_colored_and_uncolored do |color_enabled| + snippet = <<~TEST.strip + expect { raise StandardError.new('boo') }.not_to raise_error(a_kind_of(StandardError)) + TEST + program = + make_plain_test_program(snippet, color_enabled: color_enabled) + + expected_output = + build_expected_output( + color_enabled: color_enabled, + snippet: + "expect { raise StandardError.new('boo') }.not_to raise_error(a_kind_of(StandardError))", + expectation: + proc do + line do + plain "Expected raised exception " + actual %|#| + plain " not to match " + expected "#" + plain "." + end + end + ) + + expect(program).to produce_output_when_run( + expected_output + ).in_color(color_enabled) + end + end + end + + context "when the message is long" do + it "produces the correct failure message" do + as_both_colored_and_uncolored do |color_enabled| + snippet = <<~TEST.strip + expect { raise StandardError.new('this is a super super long message') }.not_to raise_error(a_kind_of(StandardError)) + TEST + program = + make_plain_test_program(snippet, color_enabled: color_enabled) + + expected_output = + build_expected_output( + color_enabled: color_enabled, + snippet: + "expect { raise StandardError.new('this is a super super long message') }.not_to raise_error(a_kind_of(StandardError))", + newline_before_expectation: true, + expectation: + proc do + line do + plain "Expected raised exception " + actual %|#| + end + + line do + plain " not to match " + expected "#" + end + end + ) + + expect(program).to produce_output_when_run( + expected_output + ).in_color(color_enabled) + end + end + end + end + end + + context "with a compound RSpec matcher" do + context "when used in the positive" do + context "when the block raises a different error than what is given" do + context "when the message is short" do + it "produces the correct failure message" do + as_both_colored_and_uncolored do |color_enabled| + snippet = <<~TEST.strip + expect { raise StandardError.new('boo') }.to raise_error(a_kind_of(Array).or eq(true)) + TEST + program = + make_plain_test_program(snippet, color_enabled: color_enabled) + + expected_output = + build_expected_output( + color_enabled: color_enabled, + snippet: + "expect { raise StandardError.new('boo') }.to raise_error(a_kind_of(Array).or eq(true))", + expectation: + proc do + line do + plain "Expected raised exception " + actual %|#| + plain " to match " + expected "#" + plain "." + end + end + ) + + expect(program).to produce_output_when_run( + expected_output + ).in_color(color_enabled) + end + end + end + + context "when the message is long" do + it "produces the correct failure message" do + as_both_colored_and_uncolored do |color_enabled| + snippet = <<~TEST.strip + expect { raise StandardError.new('this is a super super super long message') }.to raise_error(a_kind_of(RuntimeError).and having_attributes(beep: :boop)) + TEST + program = + make_plain_test_program(snippet, color_enabled: color_enabled) + + expected_output = + build_expected_output( + color_enabled: color_enabled, + snippet: + "expect { raise StandardError.new('this is a super super super long message') }.to raise_error(a_kind_of(RuntimeError).and having_attributes(beep: :boop))", + newline_before_expectation: true, + expectation: + proc do + line do + plain "Expected raised exception " + actual %|#| + end + + line do + plain " to match " + expected "#" + end + end + ) + + expect(program).to produce_output_when_run( + expected_output + ).in_color(color_enabled) + end + end + end + end + + context "when the block raises no error" do + it "produces the correct failure message" do + as_both_colored_and_uncolored do |color_enabled| + snippet = <<~TEST.strip + expect { }.to raise_error(a_kind_of(RuntimeError).and having_attributes(beep: :boop)) + TEST + program = + make_plain_test_program(snippet, color_enabled: color_enabled) + + expected_output = + build_expected_output( + color_enabled: color_enabled, + snippet: + "expect { }.to raise_error(a_kind_of(RuntimeError).and having_attributes(beep: :boop))", + expectation: + proc do + line do + plain "Expected block to raise error " + expected "#" + plain "." + end + end + ) + + expect(program).to produce_output_when_run( + expected_output + ).in_color(color_enabled) + end + end + end + end + + context "when used in the negative" do + context "when the message is short" do + it "produces the correct failure message" do + as_both_colored_and_uncolored do |color_enabled| + snippet = <<~TEST.strip + expect { raise StandardError.new('boo') }.not_to raise_error(a_kind_of(StandardError).or eq(true)) + TEST + program = + make_plain_test_program(snippet, color_enabled: color_enabled) + + expected_output = + build_expected_output( + color_enabled: color_enabled, + snippet: + "expect { raise StandardError.new('boo') }.not_to raise_error(a_kind_of(StandardError).or eq(true))", + expectation: + proc do + line do + plain "Expected raised exception " + actual %|#| + plain " not to match " + expected "#" + plain "." + end + end + ) + + expect(program).to produce_output_when_run( + expected_output + ).in_color(color_enabled) + end + end + end + + context "when the message is long" do + it "produces the correct failure message" do + as_both_colored_and_uncolored do |color_enabled| + snippet = <<~TEST.strip + expect { raise StandardError.new('this is a super super long message') }.not_to raise_error(a_kind_of(StandardError).and having_attributes(message: kind_of(String))) + TEST + program = + make_plain_test_program(snippet, color_enabled: color_enabled) + + expected_output = + build_expected_output( + color_enabled: color_enabled, + snippet: + "expect { raise StandardError.new('this is a super super long message') }.not_to raise_error(a_kind_of(StandardError).and having_attributes(message: kind_of(String)))", + newline_before_expectation: true, + expectation: + proc do + line do + plain "Expected raised exception " + actual %|#| + end + + line do + plain " not to match " + expected "#)>" + end + end + ) + + expect(program).to produce_output_when_run( + expected_output + ).in_color(color_enabled) + end + end + end + end + end + + context "with an RSpec matcher and expected message" do + context "when the block raises a different error than what is given" do + context "when the message is short" do + it "produces the correct failure message" do + as_both_colored_and_uncolored do |color_enabled| + snippet = <<~TEST.strip + expect { raise StandardError.new('boo') }.to raise_error(a_kind_of(RuntimeError), "boo") + TEST + program = + make_plain_test_program(snippet, color_enabled: color_enabled) + + expected_output = + build_expected_output( + color_enabled: color_enabled, + snippet: + "expect { raise StandardError.new('boo') }.to raise_error(a_kind_of(RuntimeError), \"boo\")", + expectation: + proc do + line do + plain "Expected raised exception " + actual %|#| + plain " to match " + expected "#" + plain "." + end + end + ) + + expect(program).to produce_output_when_run( + expected_output + ).in_color(color_enabled) + end + end + end + + context "when the message is long" do + it "produces the correct failure message" do + as_both_colored_and_uncolored do |color_enabled| + snippet = <<~TEST.strip + expect { raise StandardError.new('this is a super super super long message') }.to raise_error(a_kind_of(RuntimeError), "beep") + TEST + program = + make_plain_test_program(snippet, color_enabled: color_enabled) + + expected_output = + build_expected_output( + color_enabled: color_enabled, + snippet: + "expect { raise StandardError.new('this is a super super super long message') }.to raise_error(a_kind_of(RuntimeError), \"beep\")", + newline_before_expectation: true, + expectation: + proc do + line do + plain "Expected raised exception " + actual %|#| + end + + line do + plain " to match " + expected "#" + end + end + ) + + expect(program).to produce_output_when_run( + expected_output + ).in_color(color_enabled) + end + end + end + end + end end diff --git a/spec/unit/rspec/matchers/raise_error_spec.rb b/spec/unit/rspec/matchers/raise_error_spec.rb index da57887c..3b198dea 100644 --- a/spec/unit/rspec/matchers/raise_error_spec.rb +++ b/spec/unit/rspec/matchers/raise_error_spec.rb @@ -41,5 +41,13 @@ ) end end + + context "with a matcher" do + it "returns the correct output" do + expect(raise_error(a_kind_of(RuntimeError)).description).to eq( + "raise error #" + ) + end + end end end