diffr 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .yardoc/*
6
+ coverage/*
7
+ doc/*
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm 1.9.2@diffr --create
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in diffr.gemspec
4
+ gemspec
@@ -0,0 +1,72 @@
1
+ Diffr
2
+ ======
3
+
4
+ A simple diff utility written in Ruby. It works with single or
5
+ multi-line strings and returns an array of hashes that indicates
6
+ the line number affected and change: added, deleted, or same.
7
+
8
+ Overview
9
+ --------
10
+
11
+ ```ruby
12
+
13
+ old = "This line of document stays the same.
14
+ The dokument should be spelled correctly.
15
+ This line should be deleted."
16
+
17
+ new = "The new document has a line break!
18
+
19
+ This line of document stays the same.
20
+ The document should be spelled correctly.
21
+ Finally, a brand new line."
22
+
23
+ Diff.diffs(old, new).each do |diff|
24
+ puts diff
25
+ end
26
+
27
+ # Produces:
28
+
29
+ # {:line => 1, :change => :add, :string => "The new document has a line break!"}
30
+ # {:line => 2, :change => :add, :string => ""}
31
+ # {:line => 1, :change => :same, :string => "This line of document stays the same."}
32
+ # {:line => 2, :change => :delete, :string => "The dokument should be spelled correctly."}
33
+ # {:line => 3, :change => :delete, :string => "This line should be deleted."}
34
+ # {:line => 4, :change => :add, :string => "The document should be spelled correctly."}
35
+ # {:line => 5, :change => :add, :string => "Finally, a brand new line."}
36
+
37
+ # With a little formatting, we can produce something very similar to Unix's diff (unified format):
38
+
39
+ SYMBOLS = {:add => '+', :delete => '-', :same => ' '}
40
+
41
+ Diff.diffs(old, new).each do |diff|
42
+ puts SYMBOLS[diff[:change]] + diff[:string]
43
+ end
44
+
45
+ # Produces:
46
+
47
+ # +The new document has a line break!
48
+ # +
49
+ # This line of document stays the same.
50
+ # -The dokument should be spelled correctly.
51
+ # -This line should be deleted.
52
+ # +The document should be spelled correctly.
53
+ # +Finally, a brand new line.
54
+
55
+ ```
56
+
57
+ Installing Diffr
58
+ ----------------
59
+
60
+ ### In a Ruby app, as a gem
61
+
62
+ First install the gem.
63
+
64
+ $ gem install diffr
65
+
66
+ Next include it in your application.
67
+
68
+ ```ruby
69
+
70
+ require 'diffr'
71
+
72
+ ```
@@ -0,0 +1,26 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rake/testtask'
5
+ task :default => :test
6
+
7
+ desc 'Run tests (default)'
8
+ Rake::TestTask.new(:test) do |t|
9
+ t.test_files = FileList['test/**/*_test.rb']
10
+ t.ruby_opts = ['-Itest']
11
+ t.libs << "lib" << "test"
12
+ t.ruby_opts << '-rubygems' if defined? Gem
13
+ end
14
+
15
+ if ENV['RAILS_ENV']=='development' # yard gem is only in development
16
+ YARD::Rake::YardocTask.new do |t|
17
+ t.files = ['lib/**/*.rb']
18
+ end
19
+ end
20
+
21
+ namespace :docs do
22
+ desc 'Generate documentation for the appliaction with Yard'
23
+ task :yard do
24
+ system("yardoc 'lib/**/*.rb' - README.md")
25
+ end
26
+ end
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "diffr/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "diffr"
7
+ s.version = Diffr::VERSION
8
+ s.authors = ["Matt Sears"]
9
+ s.email = ["matt@mattsears.com"]
10
+ s.homepage = "http://www.mattsears.com"
11
+ s.summary = %q{A simple diff utility written in Ruby}
12
+ s.description = %q{A simple utility that returns the differences between two objects}
13
+
14
+ s.rubyforge_project = "diffr"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ s.add_development_dependency "simplecov"
23
+ s.add_development_dependency "minitest"
24
+ s.add_development_dependency "yard"
25
+ s.add_development_dependency "rdiscount"
26
+ # s.add_runtime_dependency "rest-client"
27
+ end
@@ -0,0 +1,85 @@
1
+ require "diffr/version"
2
+ #
3
+ # == Diffr Module
4
+ #
5
+ # A simple utility that returns the differences between two strings
6
+ #
7
+ # == Examples:
8
+ #
9
+ # @old = "This line of document stays the same.
10
+ # The dokument should be spelled correctly.
11
+ # This line should be deleted."
12
+ #
13
+ # @new = "The new document has a line break!
14
+ #
15
+ # This line of document stays the same.
16
+ # The document should be spelled correctly.
17
+ # Finally, a brand new line."
18
+ #
19
+ # Diff.diffs(old, new)
20
+ #
21
+ # Produces:
22
+ # [ {:source=>:new, :line=>1, :change=>:add, :string=>"The new document has a line break!"},
23
+ # {:source=>:new, :line=>2, :change=>:add, :string=>""},
24
+ # {:source=>:old, :line=>1, :change=>:same, :string=>"This line of document stays the same."},
25
+ # {:source=>:old, :line=>2, :change=>:delete, :string=>"The dokument should be spelled correctly."},
26
+ # {:source=>:old, :line=>3, :change=>:delete, :string=>"This line should be deleted."},
27
+ # {:source=>:new, :line=>4, :change=>:add, :string=>"The document should be spelled correctly."},
28
+ # {:source=>:new, :line=>5, :change=>:add, :string=>"Finally, a brand new line."} ]
29
+ #
30
+ module Diffr
31
+ attr_accessor :diffs, :sequences
32
+
33
+ # Returns an array of hashes that contain metadata about the differences
34
+ # between the two given strings.
35
+ #
36
+ # @return [Array] of diffs
37
+ #
38
+ def self.diffs(old, new)
39
+ new, old, @diffs = new.lines.to_a, old.lines.to_a, []
40
+ build_sequences(old, new)
41
+ find_diffs(old, new, old.size, new.size)
42
+ end
43
+
44
+ private
45
+
46
+ # Backtrace through the sequences and determine what changed between the old
47
+ # string and new string
48
+ #
49
+ # @return [Array] of diffs
50
+ #
51
+ def self.find_diffs(old, new, row, col)
52
+ if row > 0 && col > 0 && old[row-1] == new[col-1]
53
+ find_diffs(old, new, row-1, col-1)
54
+ @diffs << { :source => :old, :line => row, :change => :same, :string => old[row-1].strip }
55
+ elsif col > 0 && (row == 0 || @sequences[row][col-1] >= @sequences[row-1][col])
56
+ find_diffs(old, new, row, col-1)
57
+ @diffs << { :source => :new, :line => col, :change => :add, :string => new[col-1].strip }
58
+ elsif row > 0 && (col == 0 || @sequences[row][col-1] < @sequences[row-1][col])
59
+ find_diffs(old, new, row-1, col)
60
+ @diffs << { :source => :old, :line => row, :change => :delete, :string => old[row-1].strip }
61
+ end
62
+ end
63
+
64
+ # Build a sequence matrix by finding the sequence of items that is present in
65
+ # both original string in the same order. That is, find a new sequence which
66
+ # can be obtained from the first sequence by deleting some items, and from the
67
+ # second sequence by deleting other items.
68
+ #
69
+ # @return [Array] of sequences
70
+ #
71
+ def self.build_sequences(old, new)
72
+ rows, cols = old.size+1, new.size+1
73
+ @sequences = rows.times.map{|x|[0]*(x+1)}
74
+ rows.times.each do |row|
75
+ cols.times.each do |col|
76
+ @sequences[row][col] = if old[row-1] == new[col-1]
77
+ @sequences[row-1][col-1] + 1
78
+ else
79
+ [@sequences[row][col-1].to_i, @sequences[row-1][col].to_i].max
80
+ end
81
+ end
82
+ end
83
+ end
84
+
85
+ end
@@ -0,0 +1,3 @@
1
+ module Diffr
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,44 @@
1
+ require 'helper'
2
+
3
+ describe Diffr do
4
+
5
+ describe "how do two strings diffr?" do
6
+
7
+ it "should return an array diffs for single line strings" do
8
+ Diffr.diffs("this is an old string", "this is a new string").must_equal [
9
+ {:source=>:old, :line=>1, :change=>:delete, :string=>"this is an old string"},
10
+ {:source=>:new, :line=>1, :change=>:add, :string=>"this is a new string"}
11
+ ]
12
+ end
13
+
14
+ describe "with multiline strings" do
15
+ before do
16
+ @old_text = <<-END.gsub(/^ {6}/, '')
17
+ This line of document stays the same.
18
+ The dokument should be spelled correctly.
19
+ This line should be deleted.
20
+ END
21
+ @new_text = <<-END.gsub(/^ {6}/, '')
22
+ The new document has a line break!
23
+
24
+ This line of document stays the same.
25
+ The document should be spelled correctly.
26
+ Finally, a brand new line.
27
+ END
28
+ end
29
+
30
+ it "should return the diffs for each line" do
31
+ Diffr.diffs(@old_text, @new_text).must_equal [
32
+ {:source=>:new, :line=>1, :change=>:add, :string=>"The new document has a line break!"},
33
+ {:source=>:new, :line=>2, :change=>:add, :string=>""},
34
+ {:source=>:old, :line=>1, :change=>:same, :string=>"This line of document stays the same."},
35
+ {:source=>:old, :line=>2, :change=>:delete, :string=>"The dokument should be spelled correctly."},
36
+ {:source=>:old, :line=>3, :change=>:delete, :string=>"This line should be deleted."},
37
+ {:source=>:new, :line=>4, :change=>:add, :string=>"The document should be spelled correctly."},
38
+ {:source=>:new, :line=>5, :change=>:add, :string=>"Finally, a brand new line."}
39
+ ]
40
+ end
41
+ end
42
+
43
+ end
44
+ end
@@ -0,0 +1,11 @@
1
+ require "bundler"
2
+ Bundler.setup
3
+
4
+ require 'simplecov'
5
+ SimpleCov.start do
6
+ add_group 'Diffr', 'lib/diffr'
7
+ end
8
+
9
+ require 'minitest/autorun'
10
+ require 'diffr'
11
+
metadata ADDED
@@ -0,0 +1,110 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: diffr
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - Matt Sears
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-08-24 00:00:00 -04:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: simplecov
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: "0"
25
+ type: :development
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest
29
+ prerelease: false
30
+ requirement: &id002 !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: "0"
36
+ type: :development
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: yard
40
+ prerelease: false
41
+ requirement: &id003 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: "0"
47
+ type: :development
48
+ version_requirements: *id003
49
+ - !ruby/object:Gem::Dependency
50
+ name: rdiscount
51
+ prerelease: false
52
+ requirement: &id004 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ type: :development
59
+ version_requirements: *id004
60
+ description: A simple utility that returns the differences between two objects
61
+ email:
62
+ - matt@mattsears.com
63
+ executables: []
64
+
65
+ extensions: []
66
+
67
+ extra_rdoc_files: []
68
+
69
+ files:
70
+ - .gitignore
71
+ - .rvmrc
72
+ - Gemfile
73
+ - README.md
74
+ - Rakefile
75
+ - diffr.gemspec
76
+ - lib/diffr.rb
77
+ - lib/diffr/version.rb
78
+ - test/diffr_test.rb
79
+ - test/helper.rb
80
+ has_rdoc: true
81
+ homepage: http://www.mattsears.com
82
+ licenses: []
83
+
84
+ post_install_message:
85
+ rdoc_options: []
86
+
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: "0"
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: "0"
101
+ requirements: []
102
+
103
+ rubyforge_project: diffr
104
+ rubygems_version: 1.6.2
105
+ signing_key:
106
+ specification_version: 3
107
+ summary: A simple diff utility written in Ruby
108
+ test_files:
109
+ - test/diffr_test.rb
110
+ - test/helper.rb