# encoding: utf-8 require 'spec_helper' require 'ostruct' module RSpec module Expectations describe DiffPresenter do let(:differ) { RSpec::Expectations::DiffPresenter.new } context "without --color" do before { allow(RSpec::Matchers.configuration).to receive_messages(:color? => false) } describe '#diff_as_string' do subject { differ.diff_as_string(@actual, @expected) } it "outputs unified diff of two strings" do @expected = "foo\nzap\nbar\nthis\nis\nsoo\nvery\nvery\nequal\ninsert\na\nanother\nline\n" @actual = "foo\nbar\nzap\nthis\nis\nsoo\nvery\nvery\nequal\ninsert\na\nline\n" expect(subject).to eq(<<-'EOD') @@ -1,6 +1,6 @@ foo -zap bar +zap this is soo @@ -9,6 +9,5 @@ equal insert a -another line EOD end if String.method_defined?(:encoding) it 'copes with encoded strings' do @expected = "Tu avec carte {count} item has".encode('UTF-16LE') @actual = "Tu avec carté {count} itém has".encode('UTF-16LE') expect(subject).to eql(<<-EOD.encode('UTF-16LE')) @@ -1,2 +1,2 @@ -Tu avec carte {count} item has +Tu avec carté {count} itém has EOD end it 'handles differently encoded strings that are compatible' do @expected = "abc".encode('us-ascii') @actual = "강인철".encode('UTF-8') expect(subject).to eql "\n@@ -1,2 +1,2 @@\n-abc\n+강인철\n" end it 'uses the default external encoding when the two strings have incompatible encodings' do @expected = "Tu avec carte {count} item has" @actual = "Tu avec carté {count} itém has".encode('UTF-16LE') expect(subject).to eq("\n@@ -1,2 +1,2 @@\n-Tu avec carte {count} item has\n+Tu avec carté {count} itém has\n") expect(subject.encoding).to eq(Encoding.default_external) end it 'handles any encoding error that occurs with a helpful error message' do expect(Differ).to receive(:new).and_raise(Encoding::CompatibilityError) @expected = "Tu avec carte {count} item has".encode('us-ascii') @actual = "Tu avec carté {count} itém has" expect(subject).to match(/Could not produce a diff/) expect(subject).to match(/actual string \(UTF-8\)/) expect(subject).to match(/expected string \(US-ASCII\)/) end end end describe '#diff_as_object' do it "outputs unified diff message of two objects" do animal_class = Class.new do def initialize(name, species) @name, @species = name, species end def inspect <<-EOA <Animal name=#{@name}, species=#{@species} > EOA end end expected = animal_class.new "bob", "giraffe" actual = animal_class.new "bob", "tortoise" expected_diff = <<'EOD' @@ -1,5 +1,5 @@ <Animal name=bob, - species=tortoise + species=giraffe > EOD diff = differ.diff_as_object(expected,actual) expect(diff).to eq expected_diff end it "outputs unified diff message of two arrays" do expected = [ :foo, 'bar', :baz, 'quux', :metasyntactic, 'variable', :delta, 'charlie', :width, 'quite wide' ] actual = [ :foo, 'bar', :baz, 'quux', :metasyntactic, 'variable', :delta, 'tango' , :width, 'very wide' ] expected_diff = <<'EOD' @@ -5,7 +5,7 @@ :metasyntactic, "variable", :delta, - "tango", + "charlie", :width, - "very wide"] + "quite wide"] EOD diff = differ.diff_as_object(expected,actual) expect(diff).to eq expected_diff end it "outputs unified diff message of two hashes" do expected = { :foo => 'bar', :baz => 'quux', :metasyntactic => 'variable', :delta => 'charlie', :width =>'quite wide' } actual = { :foo => 'bar', :metasyntactic => 'variable', :delta => 'charlotte', :width =>'quite wide' } expected_diff = <<'EOD' @@ -1,4 +1,5 @@ -:delta => "charlotte", +:baz => "quux", +:delta => "charlie", :foo => "bar", :metasyntactic => "variable", :width => "quite wide", EOD diff = differ.diff_as_object(expected,actual) expect(diff).to eq expected_diff end it 'outputs unified diff message of two hashes with differing encoding' do expected_diff = %Q{ @@ -1,2 +1,2 @@ -"a" => "a", #{ (RUBY_VERSION.to_f > 1.8) ? %Q{+"ö" => "ö"} : '+"\303\266" => "\303\266"' }, } diff = differ.diff_as_object({'ö' => 'ö'}, {'a' => 'a'}) expect(diff).to eq expected_diff end it 'outputs unified diff message of two hashes with encoding different to key encoding' do expected_diff = %Q{ @@ -1,2 +1,2 @@ -:a => "a", #{ (RUBY_VERSION.to_f > 1.8) ? %Q{+\"한글\" => \"한글2\"} : '+"\355\225\234\352\270\200" => "\355\225\234\352\270\2002"' }, } diff = differ.diff_as_object({ "한글" => "한글2"}, { :a => "a"}) expect(diff).to eq expected_diff end it "outputs unified diff message of two hashes with object keys" do expected_diff = %Q{ @@ -1,2 +1,2 @@ -["a", "c"] => "b", +["d", "c"] => "b", } diff = differ.diff_as_object({ ['d','c'] => 'b'}, { ['a','c'] => 'b' }) expect(diff).to eq expected_diff end it "outputs unified diff of single line strings" do expected = "this is one string" actual = "this is another string" expected_diff = <<'EOD' @@ -1,2 +1,2 @@ -"this is another string" +"this is one string" EOD diff = differ.diff_as_object(expected,actual) expect(diff).to eq expected_diff end it "outputs unified diff of multi line strings" do expected = "this is:\n one string" actual = "this is:\n another string" expected_diff = <<'EOD' @@ -1,3 +1,3 @@ this is: - another string + one string EOD diff = differ.diff_as_object(expected,actual) expect(diff).to eq expected_diff end it "uses matcher descriptions in place of matchers in diffs" do expected = [a_string_matching(/foo/), a_string_matching(/bar/)] actual = ["poo", "car"] expected_diff = dedent(<<-EOS) | |@@ -1,2 +1,2 @@ |-["poo", "car"] |+[(a string matching /foo/), (a string matching /bar/)] | EOS diff = differ.diff_as_object(expected,actual) expect(diff).to eq expected_diff end end end context "with --color" do before { allow(RSpec::Matchers.configuration).to receive_messages(:color? => true) } it "outputs colored diffs" do expected = "foo bar baz" actual = "foo bang baz" expected_diff = "\e[0m\n\e[0m\e[34m@@ -1,2 +1,2 @@\n\e[0m\e[31m-foo bang baz\n\e[0m\e[32m+foo bar baz\n\e[0m" diff = differ.diff_as_string(expected,actual) expect(diff).to eq expected_diff end end end end end