diffy-3.4.2/0000755000004100000410000000000014256370156012662 5ustar www-datawww-datadiffy-3.4.2/diffy.gemspec0000644000004100000410000000150514256370156015331 0ustar www-datawww-data# coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'diffy/version' Gem::Specification.new do |spec| spec.name = "diffy" spec.version = Diffy::VERSION spec.authors = ["Sam Goldstein"] spec.email = ["sgrock@gmail.org"] spec.description = "Convenient diffing in ruby" spec.summary = "A convenient way to diff string in ruby" spec.homepage = "http://github.com/samg/diffy" spec.license = "MIT" spec.files = `git ls-files`.split($/) spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) spec.require_paths = ["lib"] spec.add_development_dependency "rake" spec.add_development_dependency "rspec" end diffy-3.4.2/.travis.yml0000644000004100000410000000027514256370156014777 0ustar www-datawww-datalanguage: ruby sudo: false cache: bundler rvm: - 1.8.7 - 1.9.3-p551 - 2.0.0-p648 - 2.1.9 - 2.2.6 - 2.3.3 - 2.4.0 - jruby-9.1.12.0 matrix: allow_failures: - rvm: 1.8.7 diffy-3.4.2/.rspec0000644000004100000410000000002214256370156013771 0ustar www-datawww-data--color --profile diffy-3.4.2/README.md0000644000004100000410000002573114256370156014151 0ustar www-datawww-dataDiffy - Easy Diffing With Ruby [![Build Status](https://travis-ci.org/samg/diffy.svg?branch=master)](https://travis-ci.org/samg/diffy) ============================ Need diffs in your ruby app? Diffy has you covered. It provides a convenient way to generate a diff from two strings or files. Instead of reimplementing the LCS diff algorithm Diffy uses battle tested Unix diff to generate diffs, and focuses on providing a convenient interface, and getting out of your way. Supported Formats ----------------- It provides several built in format options which can be passed to `Diffy::Diff#to_s`. * `:text` - Plain text output * `:color` - ANSI colorized text suitable for use in a terminal * `:html` - HTML output. Since version 2.0 this format does inline highlighting of the character changes between lines. * `:html_simple` - HTML output without inline highlighting. This may be useful in situations where high performance is required or simpler output is desired. A default format can be set like so: Diffy::Diff.default_format = :html Installation ------------ ### on Unix gem install diffy ### on Windows: 1. Ensure that you have a working `diff` on your machine and in your search path. There are several options: 1. Install [Diff::LCS](https://github.com/halostatue/diff-lcs), which includes `ldiff`. [RSpec](https://www.relishapp.com/rspec/docs/gettingstarted) depends on Diff::LCS so you may already have it installed. 1. If you're using [RubyInstaller](http://rubyinstaller.org), install the [devkit](http://rubyinstaller.org/add-ons/devkit). 1. Install unxutils note that these tools contain diff 2.7 which has a different handling of whitespace in the diff results. This makes Diffy spec tests yielding one fail on Windows. 1. Install these two individually from the gnuwin32 project note that this delivers diff 2.8 which makes Diffy spec pass even on Windows. 2. Install the gem by gem install diffy Getting Started --------------- Here's an example of using Diffy to diff two strings $ irb >> string1 = <<-TXT >" Hello how are you >" I'm fine >" That's great >" TXT => "Hello how are you\nI'm fine\nThat's great\n" >> string2 = <<-TXT >" Hello how are you? >" I'm fine >" That's swell >" TXT => "Hello how are you?\nI'm fine\nThat's swell\n" >> puts Diffy::Diff.new(string1, string2) -Hello how are you +Hello how are you? I'm fine -That's great +That's swell HTML Output --------------- Outputing the diff as html is easy too. Here's an example using the `:html_simple` formatter. >> puts Diffy::Diff.new(string1, string2).to_s(:html_simple)
  • Hello how are you
  • Hello how are you?
  • I'm fine
  • That's great
  • That's swell
The `:html` formatter will give you inline highlighting a la github. >> puts Diffy::Diff.new("foo\n", "Foo\n").to_s(:html)
  • foo
  • Foo
There's some pretty nice css provided in `Diffy::CSS`. >> puts Diffy::CSS .diff{overflow:auto;} .diff ul{background:#fff;overflow:auto;font-size:13px;list-style:none;margin:0;padding:0;display:table;width:100%;} .diff del, .diff ins{display:block;text-decoration:none;} .diff li{padding:0; display:table-row;margin: 0;height:1em;} .diff li.ins{background:#dfd; color:#080} .diff li.del{background:#fee; color:#b00} .diff li:hover{background:#ffc} /* try 'whitespace:pre;' if you don't want lines to wrap */ .diff del, .diff ins, .diff span{white-space:pre-wrap;font-family:courier;} .diff del strong{font-weight:normal;background:#fcc;} .diff ins strong{font-weight:normal;background:#9f9;} .diff li.diff-comment { display: none; } .diff li.diff-block-info { background: none repeat scroll 0 0 gray; } There's also a colorblind-safe version of the pallete provided in `Diffy::CSS_COLORBLIND_1`. Side-by-side comparisons ------------------------ Side-by-side comparisons, or split views as called by some, are supported by using the `Diffy::SplitDiff` class. This class takes a diff returned from `Diffy::Diff` and splits it in two parts (or two sides): left and right. The left side represents deletions while the right side represents insertions. The class is used as follows: ``` Diffy::SplitDiff.new(string1, string2, options = {}) ``` The optional options hash is passed along to the main `Diff::Diff` class, so all default options such as full diff output are supported. The output format may be changed by passing the format with the options hash (see below), and all default formats are supported. Unlike `Diffy::Diff`, `Diffy::SplitDiff` does not use `#to_s` to output the resulting diff. Instead, two self-explanatory methods are used to output the diff: `#left` and `#right`. Using the earlier example, this is what they look like in action: ``` >> puts Diffy::SplitDiff.new(string1, string2).left -Hello how are you I'm fine -That's great ``` ``` >> puts Diffy::SplitDiff.new(string1, string2).right +Hello how are you? I'm fine +That's swell ``` ### Changing the split view output format The output format may be changed by passing the format with the options hash: ``` Diffy::SplitDiff.new(string1, string2, :format => :html) ``` This will result in the following: ``` >> puts Diffy::SplitDiff.new(string1, string2, :format => :html).left
  • Hello how are you
  • I'm fine
  • That's great
``` ``` >> puts Diffy::SplitDiff.new(string1, string2, :format => :html).right
  • Hello how are you?
  • I'm fine
  • That's swell
``` Other Diff Options ------------------ ### Diffing files instead of strings You can diff files instead of strings by using the `:source` option. >> puts Diffy::Diff.new('/tmp/foo', '/tmp/bar', :source => 'files') ### Full Diff Output By default Diffy removes the superfluous diff output. This is because its default is to show the complete diff'ed file (`diff -U10000` is the default). Diffy does support full output, just use the `:include_diff_info => true` option when initializing: >> Diffy::Diff.new("foo\nbar\n", "foo\nbar\nbaz\n", :include_diff_info => true).to_s(:text) =>--- /Users/chaffeqa/Projects/stiwiki/tmp/diffy20111116-82153-ie27ex 2011-11-16 20:16:41.000000000 -0500 +++ /Users/chaffeqa/Projects/stiwiki/tmp/diffy20111116-82153-wzrhw5 2011-11-16 20:16:41.000000000 -0500 @@ -1,2 +1,3 @@ foo bar +baz And even deals a bit with the formatting! ### Empty Diff Behavior By default Diffy will return empty string if there are no differences in inputs. In previous versions the full text of its first input was returned in this case. To restore this behaviour simply use the `:allow_empty_diff => false` option when initializing. ### Plus and Minus symbols in HTML output By default Diffy doesn't include the `+`, `-`, and ` ` at the beginning of line for HTML output. You can use the `:include_plus_and_minus_in_html` option to include those symbols in the output. >> puts Diffy::Diff.new(string1, string2, :include_plus_and_minus_in_html => true).to_s(:html_simple)
  • -Hello how are you
  • +Hello how are you?
  • I'm fine
  • -That's great
  • +That's swell
### Number of lines of context around changes You can use the `:context` option to override the number of lines of context that are shown around each change (this defaults to 10000 to show the full file). >> puts Diffy::Diff.new("foo\nfoo\nBAR\nbang\nbaz", "foo\nfoo\nbar\nbang\nbaz", :context => 1) foo -BAR +bar bang ### Overriding the command line options passed to diff. You can use the `:diff` option to override the command line options that are passed to unix diff. They default to `-U10000`. This option will noop if combined with the `:context` option. >> puts Diffy::Diff.new(" foo\nbar\n", "foo\nbar\n", :diff => "-w") foo bar ### `:ignore_crlf` when doing HTML compares You can make the HTML output ignore the CRLF by passing the `:ignore_crlf` option a truthy value. >> puts Diffy::Diff.new(" foo\nbar\n", "foo\r\nbar\r\n", ignore_crlf: true).to_s(:html) "
" Default Diff Options -------------------- You can set the default options for new `Diffy::Diff`s using the `Diffy::Diff.default_options` and `Diffy::Diff.default_options=` methods. Options passed to `Diffy::Diff.new` will be merged into the default options. >> Diffy::Diff.default_options => {:diff=>"-U10000", :source=>"strings", :include_diff_info=>false, :include_plus_and_minus_in_html=>false} >> Diffy::Diff.default_options.merge!(:source => 'files') => {:diff=>"-U10000", :source=>"files", :include_diff_info=>false, :include_plus_and_minus_in_html=>false} Custom Formats -------------- Diffy tries to make generating your own custom formatted output easy. `Diffy::Diff` provides an enumerable interface which lets you iterate over lines in the diff. >> Diffy::Diff.new("foo\nbar\n", "foo\nbar\nbaz\n").each do |line| >* case line >> when /^\+/ then puts "line #{line.chomp} added" >> when /^-/ then puts "line #{line.chomp} removed" >> end >> end line +baz added => [" foo\n", " bar\n", "+baz\n"] You can also use `Diffy::Diff#each_chunk` to iterate each grouping of additions, deletions, and unchanged in a diff. >> Diffy::Diff.new("foo\nbar\nbang\nbaz\n", "foo\nbar\nbing\nbong\n").each_chunk.to_a => [" foo\n bar\n", "-bang\n-baz\n", "+bing\n+bong\n"] Use `#map`, `#inject`, or any of Enumerable's methods. Go crazy. Testing ------------ Diffy includes a full set of rspec tests. When contributing please include tests for your changes. [![Build Status](https://secure.travis-ci.org/samg/diffy.png)](http://travis-ci.org/samg/diffy) --------------------------------------------------------------------- Report bugs or request features at http://github.com/samg/diffy/issues diffy-3.4.2/spec/0000755000004100000410000000000014256370156013614 5ustar www-datawww-datadiffy-3.4.2/spec/demo_app.rb0000644000004100000410000000313614256370156015730 0ustar www-datawww-datarequire 'rubygems' require 'sinatra' require 'json' require File.dirname(__FILE__) + '/../lib/diffy' blk = proc do Diffy::Diff.default_options.merge! JSON.parse(params[:options]) rescue {} haml "- d = Diffy::Diff.new(params[:one].to_s, params[:two].to_s)\n%div= d.to_s(:html)\n%pre= d.to_s" end post '/', &blk get '/', &blk __END__ @@ layout %html %head :css .diff{overflow:auto;} .diff ul{background:#fff;overflow:auto;font-size:13px;list-style:none;margin:0;padding:0;display:table;width:100%;} .diff del, .diff ins{display:block;text-decoration:none;} .diff li{padding:0; display:table-row;margin: 0;height:1em;} .diff li.ins{background:#dfd; color:#080} .diff li.del{background:#fee; color:#b00} .diff li:hover{background:#ffc} .diff del, .diff ins, .diff span{white-space:pre-wrap;font-family:courier;} .diff del strong{font-weight:normal;background:#fcc;} .diff ins strong{font-weight:normal;background:#9f9;} .diff li.diff-comment { display: none; } .diff li.diff-block-info { background: none repeat scroll 0 0 gray; } %body = yield %form{:action => '', :method => 'post'} %label JSON diff options %textarea{:name => 'options', :style => 'width:100%;height:250px;'}= params[:options] %label One %textarea{:name => 'one', :style => 'width:100%;height:250px;'}= params[:one] %br/ %label Two %textarea{:name => 'two', :style => 'width:100%;height:250px;'}= params[:two] %br/ %input{:type => 'submit'} %br/ @@ index %div.title Hello world!!!!! diffy-3.4.2/spec/diffy_spec.rb0000644000004100000410000005203214256370156016256 0ustar www-datawww-datarequire 'rspec' require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'diffy')) 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 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
  • foo
  • -bar
  • bang
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
  • foo
  • -bar
  • +aba
  • bang
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('