diff-lcs 1.2.3 → 1.3

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -6,34 +6,52 @@ require 'hoe'
6
6
 
7
7
  Hoe.plugin :bundler
8
8
  Hoe.plugin :doofus
9
- Hoe.plugin :email
10
- Hoe.plugin :gemspec
9
+ Hoe.plugin :email unless ENV['CI'] or ENV['TRAVIS']
10
+ Hoe.plugin :gemspec2
11
11
  Hoe.plugin :git
12
- Hoe.plugin :rubyforge
13
12
  Hoe.plugin :travis
14
13
 
15
- Hoe.spec 'diff-lcs' do
16
- developer('Austin Ziegler', 'austin@rubyforge.org')
14
+ spec = Hoe.spec 'diff-lcs' do
15
+ developer('Austin Ziegler', 'halostatue@gmail.com')
17
16
 
18
- self.remote_rdoc_dir = '.'
19
- self.rsync_args << ' --exclude=statsvn/'
17
+ require_ruby_version '>= 1.8'
20
18
 
21
- self.history_file = 'History.rdoc'
19
+ self.history_file = 'History.md'
22
20
  self.readme_file = 'README.rdoc'
23
- self.extra_rdoc_files = FileList["*.rdoc"].to_a
24
-
25
- self.extra_dev_deps << ['hoe-bundler', '~> 1.2']
26
- self.extra_dev_deps << ['hoe-doofus', '~> 1.0']
27
- self.extra_dev_deps << ['hoe-gemspec', '~> 1.0']
28
- self.extra_dev_deps << ['hoe-git', '~> 1.5']
29
- self.extra_dev_deps << ['hoe-rubygems', '~> 1.0']
30
- self.extra_dev_deps << ['hoe-travis', '~> 1.2']
31
- self.extra_dev_deps << ['rake', '~> 10.0']
32
- self.extra_dev_deps << ['rspec', '~> 2.0']
21
+ self.licenses = [ 'MIT', 'Artistic-2.0', 'GPL-2.0+' ]
22
+
23
+ extra_dev_deps << ['hoe-doofus', '~> 1.0']
24
+ extra_dev_deps << ['hoe-gemspec2', '~> 1.1']
25
+ extra_dev_deps << ['hoe-git', '~> 1.6']
26
+ extra_dev_deps << ['hoe-rubygems', '~> 1.0']
27
+ extra_dev_deps << ['hoe-travis', '~> 1.2']
28
+ extra_dev_deps << ['rspec', '>= 2.0', '< 4']
29
+ extra_dev_deps << ['rake', '>= 10.0', '< 12']
30
+ extra_dev_deps << ['rdoc', '>= 0']
33
31
  end
34
32
 
35
33
  unless Rake::Task.task_defined? :test
36
34
  task :test => :spec
35
+ Rake::Task['travis'].prerequisites.replace(%w(spec))
37
36
  end
38
37
 
39
- # vim: syntax=ruby
38
+ if RUBY_VERSION >= '2.0' && RUBY_ENGINE == 'ruby'
39
+ namespace :spec do
40
+ task :coveralls do
41
+ if ENV['CI'] or ENV['TRAVIS']
42
+ ENV['COVERALLS'] = 'yes'
43
+ Rake::Task['spec'].execute
44
+ else
45
+ Rake::Task['spec:coverage'].execute
46
+ end
47
+ end
48
+
49
+ desc "Runs test coverage. Only works Ruby 2.0+ and assumes 'simplecov' is installed."
50
+ task :coverage do
51
+ ENV['COVERAGE'] = 'yes'
52
+ Rake::Task['spec'].execute
53
+ end
54
+ end
55
+
56
+ # Rake::Task['travis'].prerequisites.replace(%w(spec:coveralls))
57
+ end
@@ -1,59 +1,7 @@
1
1
  # -*- ruby encoding: utf-8 -*-
2
2
 
3
3
  module Diff; end unless defined? Diff
4
- # = Diff::LCS 1.2.3
5
- #
6
- # Computes "intelligent" differences between two sequenced Enumerables. This
7
- # is an implementation of the McIlroy-Hunt "diff" algorithm for Enumerable
8
- # objects that include Diffable.
9
- #
10
- # Based on Mario I. Wolczko's Smalltalk version (1.2, 1993) and Ned Konz's
11
- # Perl version (Algorithm::Diff 1.15).
12
- #
13
- # == Synopsis
14
- # require 'diff/lcs'
15
- #
16
- # seq1 = %w(a b c e h j l m n p)
17
- # seq2 = %w(b c d e f j k l m r s t)
18
- #
19
- # lcs = Diff::LCS.lcs(seq1, seq2)
20
- # diffs = Diff::LCS.diff(seq1, seq2)
21
- # sdiff = Diff::LCS.sdiff(seq1, seq2)
22
- # seq = Diff::LCS.traverse_sequences(seq1, seq2, callback_obj)
23
- # bal = Diff::LCS.traverse_balanced(seq1, seq2, callback_obj)
24
- # seq2 == Diff::LCS.patch(seq1, diffs)
25
- # seq2 == Diff::LCS.patch!(seq1, diffs)
26
- # seq1 == Diff::LCS.unpatch(seq2, diffs)
27
- # seq1 == Diff::LCS.unpatch!(seq2, diffs)
28
- # seq2 == Diff::LCS.patch(seq1, sdiff)
29
- # seq2 == Diff::LCS.patch!(seq1, sdiff)
30
- # seq1 == Diff::LCS.unpatch(seq2, sdiff)
31
- # seq1 == Diff::LCS.unpatch!(seq2, sdiff)
32
- #
33
- # Alternatively, objects can be extended with Diff::LCS:
34
- #
35
- # seq1.extend(Diff::LCS)
36
- # lcs = seq1.lcs(seq2)
37
- # diffs = seq1.diff(seq2)
38
- # sdiff = seq1.sdiff(seq2)
39
- # seq = seq1.traverse_sequences(seq2, callback_obj)
40
- # bal = seq1.traverse_balanced(seq2, callback_obj)
41
- # seq2 == seq1.patch(diffs)
42
- # seq2 == seq1.patch!(diffs)
43
- # seq1 == seq2.unpatch(diffs)
44
- # seq1 == seq2.unpatch!(diffs)
45
- # seq2 == seq1.patch(sdiff)
46
- # seq2 == seq1.patch!(sdiff)
47
- # seq1 == seq2.unpatch(sdiff)
48
- # seq1 == seq2.unpatch!(sdiff)
49
- #
50
- # Default extensions are provided for Array and String objects through the
51
- # use of 'diff/lcs/array' and 'diff/lcs/string'.
52
- #
53
- # == Introduction (by Mark-Jason Dominus)
54
- #
55
- # <em>The following text is from the Perl documentation. The only changes
56
- # have been to make the text appear better in Rdoc</em>.
4
+ # == How Diff Works (by Mark-Jason Dominus)
57
5
  #
58
6
  # I once read an article written by the authors of +diff+; they said that
59
7
  # they hard worked very hard on the algorithm until they found the right
@@ -100,36 +48,8 @@ module Diff; end unless defined? Diff
100
48
  #
101
49
  # a x b y c z p d q
102
50
  # a b c a x b y c z
103
- #
104
- # == Author
105
- # This version is by Austin Ziegler <austin@rubyforge.org>.
106
- #
107
- # It is based on the Perl Algorithm::Diff (1.15) by Ned Konz , copyright
108
- # &copy; 2000&ndash;2002 and the Smalltalk diff version by Mario I.
109
- # Wolczko, copyright &copy; 1993. Documentation includes work by
110
- # Mark-Jason Dominus.
111
- #
112
- # == Licence
113
- # Copyright &copy; 2004&ndash;2013 Austin Ziegler
114
- # This program is free software; you can redistribute it and/or modify it
115
- # under the same terms as Ruby, or alternatively under the Perl Artistic
116
- # licence.
117
- #
118
- # == Credits
119
- # Much of the documentation is taken directly from the Perl Algorithm::Diff
120
- # implementation and was written originally by Mark-Jason Dominus and later
121
- # by Ned Konz. The basic Ruby implementation was re-ported from the
122
- # Smalltalk implementation, available at
123
- # ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st
124
- #
125
- # #sdiff and #traverse_balanced were written for the Perl version by Mike
126
- # Schilli <m@perlmeister.com>.
127
- #
128
- # "The algorithm is described in <em>A Fast Algorithm for Computing Longest
129
- # Common Subsequences</em>, CACM, vol.20, no.5, pp.350-353, May
130
- # 1977, with a few minor improvements to improve the speed."
131
51
  module Diff::LCS
132
- VERSION = '1.2.3'
52
+ VERSION = '1.3'
133
53
  end
134
54
 
135
55
  require 'diff/lcs/callbacks'
@@ -767,7 +687,7 @@ class << Diff::LCS
767
687
  ai += 1
768
688
  bj += 1
769
689
  end
770
- ai += 1
690
+ ai += 1
771
691
  when '+'
772
692
  while bj < change.position
773
693
  res << (string ? src[ai, 1] : src[ai])
@@ -775,9 +695,9 @@ class << Diff::LCS
775
695
  bj += 1
776
696
  end
777
697
 
778
- bj += 1
698
+ bj += 1
779
699
 
780
- res << change.element
700
+ res << change.element
781
701
  end
782
702
  end
783
703
  end
@@ -4,6 +4,8 @@
4
4
  # addition of an element from either the old or the new sequenced
5
5
  # enumerable.
6
6
  class Diff::LCS::Change
7
+ IntClass = 1.class # Fixnum is deprecated in Ruby 2.4
8
+
7
9
  # The only actions valid for changes are '+' (add), '-' (delete), '='
8
10
  # (no change), '!' (changed), '<' (tail changes from first sequence), or
9
11
  # '>' (tail changes from second sequence). The last two ('<>') are only
@@ -28,7 +30,7 @@ class Diff::LCS::Change
28
30
  unless Diff::LCS::Change.valid_action?(@action)
29
31
  raise "Invalid Change Action '#{@action}'"
30
32
  end
31
- raise "Invalid Position Type" unless @position.kind_of? Fixnum
33
+ raise "Invalid Position Type" unless @position.kind_of? IntClass
32
34
  end
33
35
 
34
36
  def inspect
@@ -40,7 +42,7 @@ class Diff::LCS::Change
40
42
  end
41
43
 
42
44
  def self.from_a(arr)
43
- arr = arr.flatten
45
+ arr = arr.flatten(1)
44
46
  case arr.size
45
47
  when 5
46
48
  Diff::LCS::ContextChange.new(*(arr[0...5]))
@@ -54,6 +56,7 @@ class Diff::LCS::Change
54
56
  include Comparable
55
57
 
56
58
  def ==(other)
59
+ (self.class == other.class) and
57
60
  (self.action == other.action) and
58
61
  (self.position == other.position) and
59
62
  (self.element == other.element)
@@ -114,10 +117,10 @@ class Diff::LCS::ContextChange < Diff::LCS::Change
114
117
  unless Diff::LCS::Change.valid_action?(@action)
115
118
  raise "Invalid Change Action '#{@action}'"
116
119
  end
117
- unless @old_position.nil? or @old_position.kind_of? Fixnum
120
+ unless @old_position.nil? or @old_position.kind_of? IntClass
118
121
  raise "Invalid (Old) Position Type"
119
122
  end
120
- unless @new_position.nil? or @new_position.kind_of? Fixnum
123
+ unless @new_position.nil? or @new_position.kind_of? IntClass
121
124
  raise "Invalid (New) Position Type"
122
125
  end
123
126
  end
@@ -159,6 +162,7 @@ class Diff::LCS::ContextChange < Diff::LCS::Change
159
162
  end
160
163
 
161
164
  def ==(other)
165
+ (self.class == other.class) and
162
166
  (@action == other.action) and
163
167
  (@old_position == other.old_position) and
164
168
  (@new_position == other.new_position) and
@@ -115,8 +115,8 @@ h1 { margin-left: 2em; }
115
115
  formatter = Text::Format.new
116
116
  formatter.tabstop = @options[:expand_tabs]
117
117
 
118
- @left = left.map { |line| formatter.expand(line.chomp) }
119
- @right = right.map { |line| formatter.expand(line.chomp) }
118
+ @left.map! { |line| formatter.expand(line.chomp) }
119
+ @right.map! { |line| formatter.expand(line.chomp) }
120
120
  end
121
121
 
122
122
  @left.map! { |line| CGI.escapeHTML(line.chomp) }
@@ -49,6 +49,7 @@ class << Diff::LCS::Internals
49
49
  (a[a_start] == b[b_start]))
50
50
  vector[a_start] = b_start
51
51
  a_start += 1
52
+ b_start += 1
52
53
  end
53
54
  b_start = a_start
54
55
 
@@ -141,8 +142,6 @@ class << Diff::LCS::Internals
141
142
  # some time. This also works better with Diff::LCS::ContextChange or
142
143
  # Diff::LCS::Change as its source, as an array will cause the creation
143
144
  # of one of the above.
144
- #
145
- # Note: This will be deprecated as a public function in a future release.
146
145
  def intuit_diff_direction(src, patchset, limit = nil)
147
146
  string = src.kind_of?(String)
148
147
  count = left_match = left_miss = right_match = right_miss = 0
@@ -216,19 +215,27 @@ class << Diff::LCS::Internals
216
215
  no_left = (left_match == 0) && (left_miss > 0)
217
216
  no_right = (right_match == 0) && (right_miss > 0)
218
217
 
219
- case [no_left, no_right]
220
- when [false, true]
218
+ case [ no_left, no_right ]
219
+ when [ false, true ]
221
220
  :patch
222
- when [true, false]
221
+ when [ true, false ]
223
222
  :unpatch
224
223
  else
225
224
  case left_match <=> right_match
226
225
  when 1
227
- :patch
226
+ if left_miss.zero?
227
+ :patch
228
+ else
229
+ :unpatch
230
+ end
228
231
  when -1
229
- :unpatch
232
+ if right_miss.zero?
233
+ :unpatch
234
+ else
235
+ :patch
236
+ end
230
237
  else
231
- raise "The provided patchset does not appear to apply to the provided value as either source or destination value."
238
+ raise "The provided patchset does not appear to apply to the provided enumerable as either source or destination value."
232
239
  end
233
240
  end
234
241
  end
@@ -4,46 +4,18 @@ require 'optparse'
4
4
  require 'ostruct'
5
5
  require 'diff/lcs/hunk'
6
6
 
7
- # == ldiff Usage
8
- # ldiff [options] oldfile newfile
9
- #
10
- # -c:: Displays a context diff with 3 lines of context.
11
- # -C [LINES], --context [LINES]:: Displays a context diff with LINES lines of context. Default 3 lines.
12
- # -u:: Displays a unified diff with 3 lines of context.
13
- # -U [LINES], --unified [LINES]:: Displays a unified diff with LINES lines of context. Default 3 lines.
14
- # -e:: Creates an 'ed' script to change oldfile to newfile.
15
- # -f:: Creates an 'ed' script to change oldfile to newfile in reverse order.
16
- # -a, --text:: Treats the files as text and compares them line-by-line, even if they do not seem to be text.
17
- # --binary:: Treats the files as binary.
18
- # -q, --brief:: Reports only whether or not the files differ, not the details.
19
- # --help:: Shows the command-line help.
20
- # --version:: Shows the version of Diff::LCS.
21
- #
22
- # By default, runs produces an "old-style" diff, with output like UNIX diff.
23
- #
24
- # == Copyright
25
- # Copyright &copy; 2004 Austin Ziegler
26
- #
27
- # Part of Diff::LCS <http://rubyforge.org/projects/ruwiki/>
28
- # Austin Ziegler <diff-lcs@halostatue.ca>
29
- #
30
- # This program is free software. It may be redistributed and/or modified under
31
- # the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
32
- # Ruby licence.
33
- module Diff::LCS::Ldiff
7
+ module Diff::LCS::Ldiff #:nodoc:
34
8
  BANNER = <<-COPYRIGHT
35
9
  ldiff #{Diff::LCS::VERSION}
36
- Copyright 2004-2013 Austin Ziegler
10
+ Copyright 2004-2014 Austin Ziegler
37
11
 
38
12
  Part of Diff::LCS.
39
- http://rubyforge.org/projects/ruwiki/
40
-
41
- Austin Ziegler <diff-lcs@halostatue.ca>
13
+ https://github.com/halostatue/diff-lcs
42
14
 
43
15
  This program is free software. It may be redistributed and/or modified under
44
16
  the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
45
17
  MIT licence.
46
- COPYRIGHT
18
+ COPYRIGHT
47
19
  end
48
20
 
49
21
  class << Diff::LCS::Ldiff
@@ -85,7 +57,7 @@ class << Diff::LCS::Ldiff
85
57
  return 0
86
58
  end
87
59
  o.on_tail('--version', 'Shows the version of Diff::LCS.') do
88
- error << BANNER
60
+ error << Diff::LCS::Ldiff::BANNER
89
61
  return 0
90
62
  end
91
63
  o.on_tail ""
@@ -118,13 +90,13 @@ class << Diff::LCS::Ldiff
118
90
  file_length_difference = 0
119
91
 
120
92
  if @binary.nil? or @binary
121
- data_old = IO::read(file_old)
122
- data_new = IO::read(file_new)
93
+ data_old = IO.read(file_old)
94
+ data_new = IO.read(file_new)
123
95
 
124
96
  # Test binary status
125
97
  if @binary.nil?
126
- old_txt = data_old[0...4096].scan(/\0/).empty?
127
- new_txt = data_new[0...4096].scan(/\0/).empty?
98
+ old_txt = data_old[0, 4096].scan(/\0/).empty?
99
+ new_txt = data_new[0, 4096].scan(/\0/).empty?
128
100
  @binary = (not old_txt) or (not new_txt)
129
101
  old_txt = new_txt = nil
130
102
  end
@@ -134,8 +106,8 @@ class << Diff::LCS::Ldiff
134
106
  data_new = data_new.split($/).map { |e| e.chomp }
135
107
  end
136
108
  else
137
- data_old = IO::readlines(file_old).map { |e| e.chomp }
138
- data_new = IO::readlines(file_new).map { |e| e.chomp }
109
+ data_old = IO.readlines(file_old).map { |e| e.chomp }
110
+ data_new = IO.readlines(file_new).map { |e| e.chomp }
139
111
  end
140
112
 
141
113
  # diff yields lots of pieces, each of which is basically a Block object
@@ -148,16 +120,16 @@ class << Diff::LCS::Ldiff
148
120
 
149
121
  return 0 unless diffs
150
122
 
151
- if (@format == :report) and diffs
123
+ if @format == :report
152
124
  output << "Files #{file_old} and #{file_new} differ\n"
153
125
  return 1
154
126
  end
155
127
 
156
128
  if (@format == :unified) or (@format == :context)
157
129
  ft = File.stat(file_old).mtime.localtime.strftime('%Y-%m-%d %H:%M:%S.%N %z')
158
- puts "#{char_old} #{file_old}\t#{ft}"
130
+ output << "#{char_old} #{file_old}\t#{ft}\n"
159
131
  ft = File.stat(file_new).mtime.localtime.strftime('%Y-%m-%d %H:%M:%S.%N %z')
160
- puts "#{char_new} #{file_new}\t#{ft}"
132
+ output << "#{char_new} #{file_new}\t#{ft}\n"
161
133
  end
162
134
 
163
135
  # Loop over hunks. If a hunk overlaps with the last hunk, join them.
@@ -2,20 +2,20 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe "Diff::LCS.diff" do
5
+ describe Diff::LCS, ".diff" do
6
6
  include Diff::LCS::SpecHelper::Matchers
7
7
 
8
- it "should correctly diff seq1 to seq2" do
8
+ it "correctly diffs seq1 to seq2" do
9
9
  diff_s1_s2 = Diff::LCS.diff(seq1, seq2)
10
- change_diff(correct_forward_diff).should == diff_s1_s2
10
+ expect(change_diff(correct_forward_diff)).to eq(diff_s1_s2)
11
11
  end
12
12
 
13
- it "should correctly diff seq2 to seq1" do
13
+ it "correctly diffs seq2 to seq1" do
14
14
  diff_s2_s1 = Diff::LCS.diff(seq2, seq1)
15
- change_diff(correct_backward_diff).should == diff_s2_s1
15
+ expect(change_diff(correct_backward_diff)).to eq(diff_s2_s1)
16
16
  end
17
17
 
18
- it "should correctly diff against an empty sequence" do
18
+ it "correctly diffs against an empty sequence" do
19
19
  diff = Diff::LCS.diff(word_sequence, [])
20
20
  correct_diff = [
21
21
  [ [ '-', 0, 'abcd' ],
@@ -24,18 +24,24 @@ describe "Diff::LCS.diff" do
24
24
  [ '-', 3, 'mnopqrstuvwxyz' ] ]
25
25
  ]
26
26
 
27
- change_diff(correct_diff).should == diff
27
+ expect(change_diff(correct_diff)).to eq(diff)
28
28
 
29
29
  diff = Diff::LCS.diff([], word_sequence)
30
30
  correct_diff.each { |hunk| hunk.each { |change| change[0] = '+' } }
31
- change_diff(correct_diff).should == diff
31
+ expect(change_diff(correct_diff)).to eq(diff)
32
32
  end
33
33
 
34
- it "should return an empty diff with (hello, hello)" do
35
- Diff::LCS.diff(hello, hello).should == []
34
+ it "correctly diffs 'xx' and 'xaxb'" do
35
+ left = 'xx'
36
+ right = 'xaxb'
37
+ expect(Diff::LCS.patch(left, Diff::LCS.diff(left, right))).to eq(right)
36
38
  end
37
39
 
38
- it "should return an empty diff with (hello_ary, hello_ary)" do
39
- Diff::LCS.diff(hello_ary, hello_ary).should == []
40
+ it "returns an empty diff with (hello, hello)" do
41
+ expect(Diff::LCS.diff(hello, hello)).to be_empty
42
+ end
43
+
44
+ it "returns an empty diff with (hello_ary, hello_ary)" do
45
+ expect(Diff::LCS.diff(hello_ary, hello_ary)).to be_empty
40
46
  end
41
47
  end