require 'rspec' require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'diffy')) class Diffy::Diff attr_reader :tempfiles end describe Diffy::Diff do describe "diffing two files" do def tempfile(string, fn = 'diffy-spec') t = Tempfile.new(fn) # ensure tempfiles aren't unlinked when GC runs by maintaining a # reference to them. @tempfiles ||=[] @tempfiles.push(t) t.print(string) t.flush t.close t.path end it "should accept file paths as arguments" do string1 = "foo\nbar\nbang\n" string2 = "foo\nbang\n" path1, path2 = tempfile(string1), tempfile(string2) expect(Diffy::Diff.new(path1, path2, :source => 'files').to_s).to eq <<-DIFF foo -bar bang DIFF end it "should accept file paths with spaces as arguments" do string1 = "foo\nbar\nbang\n" string2 = "foo\nbang\n" path1, path2 = tempfile(string1, 'path with spaces'), tempfile(string2, 'path with spaces') expect(Diffy::Diff.new(path1, path2, :source => 'files').to_s).to eq <<-DIFF foo -bar bang DIFF end it "should have and empty tempfiles variable after calling diff" do string1 = "foo\nbar\nbang\n" string2 = "foo\nbang\n" path1, path2 = tempfile(string1, 'path with spaces'), tempfile(string2, 'path with spaces') res = Diffy::Diff.new(path1, path2, :source => 'strings') expect(res.tempfiles).to eq nil res.diff expect(res.tempfiles).to eq [] end it "should accept file paths with spaces as arguments on windows" do begin orig_verbose, $VERBOSE = $VERBOSE, nil #silence redefine constant warnings orig_windows, Diffy::WINDOWS = Diffy::WINDOWS, true string1 = "foo\nbar\nbang\n" string2 = "foo\nbang\n" path1, path2 = tempfile(string1, 'path with spaces'), tempfile(string2, 'path with spaces') expect(Diffy::Diff.new(path1, path2, :source => 'files').to_s).to eq <<-DIFF foo -bar bang DIFF ensure Diffy::WINDOWS, $VERBOSE = orig_windows, orig_verbose end end describe "with no line different" do before do string1 = "foo\nbar\nbang\n" string2 = "foo\nbar\nbang\n" @path1, @path2 = tempfile(string1), tempfile(string2) end it "should show everything" do expect(Diffy::Diff.new(@path1, @path2, :source => 'files', :allow_empty_diff => false). to_s).to eq <<-DIFF foo bar bang DIFF end it "should not show everything if the :allow_empty_diff option is set" do expect(Diffy::Diff.new(@path1, @path2, :source => 'files', :allow_empty_diff => true).to_s).to eq('') end end describe "with lines that start with backslashes" do before do string1 = "foo\n\\\\bag\nbang\n" string2 = "foo\n\\\\bar\nbang\n" @path1, @path2 = tempfile(string1), tempfile(string2) end it "should not leave lines out" do expect(Diffy::Diff.new(@path1, @path2, :source => 'files').to_s).to eq <<-DIFF foo -\\\\bag +\\\\bar bang DIFF end end describe "with non valid UTF bytes" do before do string1 = "Foo ICS95095010000000000083320000BS01030000004100+\xFF00000000000000000\n" string2 = "Bar ICS95095010000000000083320000BS01030000004100+\xFF00000000000000000\n" @path1, @path2 = tempfile(string1), tempfile(string2) end it "should not raise invalid encoding issues" do desired = <<-DIFF -Foo ICS95095010000000000083320000BS01030000004100+\xFF00000000000000000 +Bar ICS95095010000000000083320000BS01030000004100+\xFF00000000000000000 DIFF desired.force_encoding("ASCII-8BIT") if desired.respond_to?(:force_encoding) expect(Diffy::Diff.new(@path1, @path2, :source => 'files').to_s).to eq(desired) end end end describe "handling temp files" do it "should unlink tempfiles after generating the diff" do before_tmpfiles = Dir.entries(Dir.tmpdir) ::Diffy::Diff.new("a", "b").to_s after_tmpfiles = Dir.entries(Dir.tmpdir) expect(before_tmpfiles).to match_array(after_tmpfiles) end it "should still be able to generate multiple diffs" do d = ::Diffy::Diff.new("a", "b") expect(d.to_s).to be_a String expect(d.to_s(:html)).to be_a String end end describe "options[:context]" do it "should limit context lines to 1" do diff = Diffy::Diff.new("foo\nfoo\nBAR\nbang\nbaz", "foo\nfoo\nbar\nbang\nbaz", :context => 1) expect(diff.to_s).to eq <<-DIFF foo -BAR +bar bang DIFF end end describe "options[:include_plus_and_minus_in_html]" do it "defaults to false" do @diffy = Diffy::Diff.new(" foo\nbar\n", "foo\nbar\n") expect(@diffy.options[:include_plus_and_minus_in_html]).to eq(false) end it "can be set to true" do @diffy = Diffy::Diff.new(" foo\nbar\n", "foo\nbar\n", :include_plus_and_minus_in_html=> true ) expect(@diffy.options[:include_plus_and_minus_in_html]).to eq(true) end describe "formats" do it "includes symbols in html_simple" do output = Diffy::Diff.new("foo\nbar\nbang\n", "foo\nbang\n", :include_plus_and_minus_in_html => true ). to_s(:html_simple) expect(output).to eq <<-HTML
HTML end it "includes symbols in html" do output = Diffy::Diff.new("foo\nbar\nbang\n", "foo\naba\nbang\n", :include_plus_and_minus_in_html => true ). to_s(:html) expect(output).to eq <<-HTML
HTML end end end describe "options[:include_diff_info]" do it "defaults to false" do @diffy = Diffy::Diff.new(" foo\nbar\n", "foo\nbar\n") expect(@diffy.options[:include_diff_info]).to eq(false) end it "can be set to true" do @diffy = Diffy::Diff.new(" foo\nbar\n", "foo\nbar\n", :include_diff_info => true ) expect(@diffy.options[:include_diff_info]).to eq(true) end it "includes all diff output" do output = Diffy::Diff.new("foo\nbar\nbang\n", "foo\nbang\n", :include_diff_info => true ).to_s expect(output.to_s).to match( /@@/) expect(output).to match( /---/) expect(output).to match( /\+\+\+/) end describe "formats" do it "works for :color" do output = Diffy::Diff.new("foo\nbar\nbang\n", "foo\nbang\n", :include_diff_info => true ).to_s(:color) expect(output).to match( /\e\[0m\n\e\[36m\@\@/ ) expect(output.to_s).to match( /\e\[90m---/) expect(output.to_s).to match( /\e\[0m\n\e\[90m\+\+\+/) end it "works for :html_simple" do output = Diffy::Diff.new("foo\nbar\nbang\n", "foo\nbang\n", :include_diff_info => true ).to_s(:html_simple) expect(output.split("\n")).to include( "
  • @@ -1,3 +1,2 @@
  • " ) expect(output).to include( "
  • ---") expect(output).to include( "
  • +++") end end end describe "options[:diff]" do it "should accept an option to diff" do @diff = Diffy::Diff.new(" foo\nbar\n", "foo\nbar\n", :diff => "-w", :allow_empty_diff => false) expect(@diff.to_s).to eq <<-DIFF foo bar DIFF end it "should accept multiple arguments to diff" do @diff = Diffy::Diff.new(" foo\nbar\n", "foo\nbaz\n", :diff => ["-w", "-U 3"]) expect(@diff.to_s).to eq <<-DIFF foo -bar +baz DIFF end end describe "#to_s" do describe "with no line different" do before do @string1 = "foo\nbar\nbang\n" @string2 = "foo\nbar\nbang\n" end it "should show everything" do expect(Diffy::Diff.new(@string1, @string2, :allow_empty_diff => false).to_s).to eq <<-DIFF foo bar bang DIFF end end describe "with one line different" do before do @string1 = "foo\nbar\nbang\n" @string2 = "foo\nbang\n" end it "should show one line removed" do expect(Diffy::Diff.new(@string1, @string2).to_s).to eq <<-DIFF foo -bar bang DIFF end it "to_s should accept a format key" do expect(Diffy::Diff.new(@string1, @string2).to_s(:color)). to eq(" foo\n\e[31m-bar\e[0m\n bang\n") end it "should accept a default format option" do old_format = Diffy::Diff.default_format Diffy::Diff.default_format = :color expect(Diffy::Diff.new(@string1, @string2).to_s). to eq(" foo\n\e[31m-bar\e[0m\n bang\n") Diffy::Diff.default_format = old_format end it "should accept a default options" do old_options = Diffy::Diff.default_options Diffy::Diff.default_options = old_options.merge(:include_diff_info => true) expect(Diffy::Diff.new(@string1, @string2).to_s). to include('@@ -1,3 +1,2 @@') Diffy::Diff.default_options = old_options end it "should show one line added" do expect(Diffy::Diff.new(@string2, @string1).to_s). to eq <<-DIFF foo +bar bang DIFF end end describe "with one line changed" do before do @string1 = "foo\nbar\nbang\n" @string2 = "foo\nbong\nbang\n" end it "should show one line added and one removed" do expect(Diffy::Diff.new(@string1, @string2).to_s).to eq <<-DIFF foo -bar +bong bang DIFF end end describe "with totally different strings" do before do @string1 = "foo\nbar\nbang\n" @string2 = "one\ntwo\nthree\n" end it "should show one line added and one removed" do expect(Diffy::Diff.new(@string1, @string2).to_s).to eq <<-DIFF -foo -bar -bang +one +two +three DIFF end end describe "with a somewhat complicated diff" do before do @string1 = "foo\nbar\nbang\nwoot\n" @string2 = "one\ntwo\nthree\nbar\nbang\nbaz\n" @diff = Diffy::Diff.new(@string1, @string2) end it "should show one line added and one removed" do expect(@diff.to_s).to eq <<-DIFF -foo +one +two +three bar bang -woot +baz DIFF end it "should make an awesome simple html diff" do expect(@diff.to_s(:html_simple)).to eq <<-HTML
    • foo
    • one
    • two
    • three
    • bar
    • bang
    • woot
    • baz
    HTML end it "should accept overrides to diff's options" do @diff = Diffy::Diff.new(@string1, @string2, :diff => "--rcs") expect(@diff.to_s).to eq <<-DIFF d1 1 a1 3 one two three d4 1 a4 1 baz DIFF end end describe "html" do it "should not allow html injection on the last line" do @string1 = "hahaha\ntime flies like an arrow\nfoo bar\nbang baz\n", "").to_s(:html) expect(diff).to include('<script>') expect(diff).not_to include('