diff 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/Manifest +13 -0
- data/README +69 -0
- data/Rakefile +12 -0
- data/TODO +17 -0
- data/diff.gemspec +33 -0
- data/lib/diff.rb +278 -0
- data/lib/emaildiff.rb +73 -0
- data/lib/unixdiff.rb +74 -0
- data/test/test_cases.rb +137 -0
- data/test/test_diff.rb +24 -0
- data/test/test_emailcases.rb +60 -0
- data/test/test_emaildiff.rb +26 -0
- data/test/test_unixdiff.rb +39 -0
- metadata +111 -0
- metadata.gz.sig +0 -0
data.tar.gz.sig
ADDED
Binary file
|
data/Manifest
ADDED
data/README
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
|
2
|
+
diff.rb README
|
3
|
+
|
4
|
+
Diff Algorithm Implementation, Copyright (C) 2001 Lars
|
5
|
+
Christensen, larsch@cs.auc.dk.
|
6
|
+
|
7
|
+
LEGAL NOTICE
|
8
|
+
|
9
|
+
This program is free software; you can redistribute it and/or
|
10
|
+
modify it under the terms of the GNU General Public License as
|
11
|
+
published by the Free Software Foundation; either version 2 of the
|
12
|
+
License, or (at your option) any later version.
|
13
|
+
|
14
|
+
This program is distributed in the hope that it will be useful,
|
15
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
16
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
17
|
+
General Public License for more details.
|
18
|
+
|
19
|
+
You should have received a copy of the GNU General Public License
|
20
|
+
along with this program; if not, write to the Free Software
|
21
|
+
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
22
|
+
02111-1307, USA.
|
23
|
+
|
24
|
+
ABOUT
|
25
|
+
|
26
|
+
This implementation is basically a Ruby conversion of the Perl
|
27
|
+
Algorithm::Diff module in CPAN.
|
28
|
+
|
29
|
+
Diff is an algorithm which computes the differences between two
|
30
|
+
lists a and b. The resulting set of differences can be applied to
|
31
|
+
a (also called "patching") to get b. This is also what the Unix
|
32
|
+
command line tools "diff" and "patch" are able to do.
|
33
|
+
|
34
|
+
diff.rb generates a "minimal diff". This means that the set of
|
35
|
+
changes that should be applied to a to get b can not be fewer than
|
36
|
+
those generated by diff.rb. diff.rb does not generate contextual
|
37
|
+
diffs. Therefor, the diff can only be succesfully applied to a
|
38
|
+
list exactly equal to to original a.
|
39
|
+
|
40
|
+
Documentation is in RD format in diff.rb. Ruby rd2 on it to
|
41
|
+
extract into other formats.
|
42
|
+
|
43
|
+
INSTALLATION
|
44
|
+
|
45
|
+
You should not installed this library system wide, because it is a
|
46
|
+
work in progress and the API may still change. You should place
|
47
|
+
the file "diff.rb" together with the source that needs to use it
|
48
|
+
and simply put "require 'diff'" at the top of your program file.
|
49
|
+
|
50
|
+
REVISION HISTORY
|
51
|
+
|
52
|
+
Version 0.1
|
53
|
+
|
54
|
+
Initial release. Diff algorithm works.
|
55
|
+
|
56
|
+
Version 0.2
|
57
|
+
|
58
|
+
Speed improvements and code clean up
|
59
|
+
|
60
|
+
Version 0.3
|
61
|
+
|
62
|
+
Added unixdiff.rb, an implementation of Unix Diff (simple
|
63
|
+
format only)
|
64
|
+
|
65
|
+
CREDITS
|
66
|
+
|
67
|
+
Thanks to authors of Perl's Algorithm::Diff (originally written by
|
68
|
+
Mark-Jason Dominus, currently maintained by Ned Konz).
|
69
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'echoe'
|
4
|
+
|
5
|
+
Echoe.new('diff','0.3.1') do |s|
|
6
|
+
s.description = "Diff Algorithm Implementation"
|
7
|
+
s.url = "http://users.cybercity.dk/~dsl8950/ruby/diff.html"
|
8
|
+
s.author = "Wayne Walter"
|
9
|
+
s.email = "diffgem@tickzoom.com"
|
10
|
+
s.ignore_pattern = []
|
11
|
+
s.development_dependencies = []
|
12
|
+
end
|
data/TODO
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
= For 1.0:
|
2
|
+
|
3
|
+
* Settle on a diff format, e.g. what should the first field look like:
|
4
|
+
[ '+', 23, "foo" ]
|
5
|
+
[ :add, 23, "foo" ]
|
6
|
+
[ DiffAdd, 23, "foo" ]
|
7
|
+
or should we have classed
|
8
|
+
class DiffAdd
|
9
|
+
attr_reader :position, :element
|
10
|
+
end
|
11
|
+
|
12
|
+
= Other Ideas:
|
13
|
+
|
14
|
+
* Contextual diffs?
|
15
|
+
* Unix diff/patch compatible wrapper
|
16
|
+
|
17
|
+
|
data/diff.gemspec
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{diff}
|
5
|
+
s.version = "0.3.1"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Wayne Walter"]
|
9
|
+
s.cert_chain = ["/root/.ssh/gem-public_cert.pem"]
|
10
|
+
s.date = %q{2010-06-27}
|
11
|
+
s.description = %q{Diff Algorithm Implementation}
|
12
|
+
s.email = %q{diffgem@tickzoom.com}
|
13
|
+
s.extra_rdoc_files = ["README", "TODO", "lib/diff.rb", "lib/emaildiff.rb", "lib/unixdiff.rb"]
|
14
|
+
s.files = ["Manifest", "README", "Rakefile", "TODO", "diff.gemspec", "lib/diff.rb", "lib/emaildiff.rb", "lib/unixdiff.rb", "test/test_cases.rb", "test/test_diff.rb", "test/test_emailcases.rb", "test/test_emaildiff.rb", "test/test_unixdiff.rb"]
|
15
|
+
s.homepage = %q{http://users.cybercity.dk/~dsl8950/ruby/diff.html}
|
16
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Diff", "--main", "README"]
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
s.rubyforge_project = %q{diff}
|
19
|
+
s.rubygems_version = %q{1.3.7}
|
20
|
+
s.signing_key = %q{/root/.ssh/gem-private_key.pem}
|
21
|
+
s.summary = %q{Diff Algorithm Implementation}
|
22
|
+
s.test_files = ["test/test_emailcases.rb", "test/test_emaildiff.rb", "test/test_unixdiff.rb", "test/test_diff.rb", "test/test_cases.rb"]
|
23
|
+
|
24
|
+
if s.respond_to? :specification_version then
|
25
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
26
|
+
s.specification_version = 3
|
27
|
+
|
28
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
29
|
+
else
|
30
|
+
end
|
31
|
+
else
|
32
|
+
end
|
33
|
+
end
|
data/lib/diff.rb
ADDED
@@ -0,0 +1,278 @@
|
|
1
|
+
class Diff
|
2
|
+
|
3
|
+
def Diff.lcs(a, b)
|
4
|
+
astart = 0
|
5
|
+
bstart = 0
|
6
|
+
afinish = a.length-1
|
7
|
+
bfinish = b.length-1
|
8
|
+
mvector = []
|
9
|
+
|
10
|
+
# First we prune off any common elements at the beginning
|
11
|
+
while (astart <= afinish && bstart <= afinish && a[astart] == b[bstart])
|
12
|
+
mvector[astart] = bstart
|
13
|
+
astart += 1
|
14
|
+
bstart += 1
|
15
|
+
end
|
16
|
+
|
17
|
+
# now the end
|
18
|
+
while (astart <= afinish && bstart <= bfinish && a[afinish] == b[bfinish])
|
19
|
+
mvector[afinish] = bfinish
|
20
|
+
afinish -= 1
|
21
|
+
bfinish -= 1
|
22
|
+
end
|
23
|
+
|
24
|
+
bmatches = b.reverse_hash(bstart..bfinish)
|
25
|
+
thresh = []
|
26
|
+
links = []
|
27
|
+
|
28
|
+
(astart..afinish).each { |aindex|
|
29
|
+
aelem = a[aindex]
|
30
|
+
next unless bmatches.has_key? aelem
|
31
|
+
k = nil
|
32
|
+
bmatches[aelem].reverse.each { |bindex|
|
33
|
+
if k && (thresh[k] > bindex) && (thresh[k-1] < bindex)
|
34
|
+
thresh[k] = bindex
|
35
|
+
else
|
36
|
+
k = thresh.replacenextlarger(bindex, k)
|
37
|
+
end
|
38
|
+
links[k] = [ (k==0) ? nil : links[k-1], aindex, bindex ] if k
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
42
|
+
if !thresh.empty?
|
43
|
+
link = links[thresh.length-1]
|
44
|
+
while link
|
45
|
+
mvector[link[1]] = link[2]
|
46
|
+
link = link[0]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
return mvector
|
51
|
+
end
|
52
|
+
|
53
|
+
def makediff(a, b)
|
54
|
+
mvector = Diff.lcs(a, b)
|
55
|
+
ai = bi = 0
|
56
|
+
while ai < mvector.length
|
57
|
+
bline = mvector[ai]
|
58
|
+
if bline
|
59
|
+
while bi < bline
|
60
|
+
discardb(bi, b[bi])
|
61
|
+
bi += 1
|
62
|
+
end
|
63
|
+
match(ai, bi)
|
64
|
+
bi += 1
|
65
|
+
else
|
66
|
+
discarda(ai, a[ai])
|
67
|
+
end
|
68
|
+
ai += 1
|
69
|
+
end
|
70
|
+
while ai < a.length
|
71
|
+
discarda(ai, a[ai])
|
72
|
+
ai += 1
|
73
|
+
end
|
74
|
+
while bi < b.length
|
75
|
+
discardb(bi, b[bi])
|
76
|
+
bi += 1
|
77
|
+
end
|
78
|
+
match(ai, bi)
|
79
|
+
1
|
80
|
+
end
|
81
|
+
|
82
|
+
def compactdiffs
|
83
|
+
diffs = []
|
84
|
+
@diffs.each { |df|
|
85
|
+
i = 0
|
86
|
+
curdiff = []
|
87
|
+
while i < df.length
|
88
|
+
whot = df[i][0]
|
89
|
+
s = @isstring ? df[i][2].chr : [df[i][2]]
|
90
|
+
p = df[i][1]
|
91
|
+
last = df[i][1]
|
92
|
+
i += 1
|
93
|
+
while df[i] && df[i][0] == whot && df[i][1] == last+1
|
94
|
+
s << df[i][2]
|
95
|
+
last = df[i][1]
|
96
|
+
i += 1
|
97
|
+
end
|
98
|
+
curdiff.push [whot, p, s]
|
99
|
+
end
|
100
|
+
diffs.push curdiff
|
101
|
+
}
|
102
|
+
return diffs
|
103
|
+
end
|
104
|
+
|
105
|
+
attr_reader :diffs, :difftype
|
106
|
+
|
107
|
+
def initialize(diffs_or_a, b = nil, isstring = nil)
|
108
|
+
if b.nil?
|
109
|
+
@diffs = diffs_or_a
|
110
|
+
@isstring = isstring
|
111
|
+
else
|
112
|
+
@diffs = []
|
113
|
+
@curdiffs = []
|
114
|
+
makediff(diffs_or_a, b)
|
115
|
+
@difftype = diffs_or_a.class
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def match(ai, bi)
|
120
|
+
@diffs.push @curdiffs unless @curdiffs.empty?
|
121
|
+
@curdiffs = []
|
122
|
+
end
|
123
|
+
|
124
|
+
def discarda(i, elem)
|
125
|
+
@curdiffs.push ['-', i, elem]
|
126
|
+
end
|
127
|
+
|
128
|
+
def discardb(i, elem)
|
129
|
+
@curdiffs.push ['+', i, elem]
|
130
|
+
end
|
131
|
+
|
132
|
+
def compact
|
133
|
+
return Diff.new(compactdiffs)
|
134
|
+
end
|
135
|
+
|
136
|
+
def compact!
|
137
|
+
@diffs = compactdiffs
|
138
|
+
end
|
139
|
+
|
140
|
+
def inspect
|
141
|
+
@diffs.inspect
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
|
146
|
+
module Diffable
|
147
|
+
def diff(b)
|
148
|
+
Diff.new(self, b)
|
149
|
+
end
|
150
|
+
|
151
|
+
# Create a hash that maps elements of the array to arrays of indices
|
152
|
+
# where the elements are found.
|
153
|
+
|
154
|
+
def reverse_hash(range = (0...self.length))
|
155
|
+
revmap = {}
|
156
|
+
range.each { |i|
|
157
|
+
elem = self[i]
|
158
|
+
if revmap.has_key? elem
|
159
|
+
revmap[elem].push i
|
160
|
+
else
|
161
|
+
revmap[elem] = [i]
|
162
|
+
end
|
163
|
+
}
|
164
|
+
return revmap
|
165
|
+
end
|
166
|
+
|
167
|
+
def replacenextlarger(value, high = nil)
|
168
|
+
high ||= self.length
|
169
|
+
if self.empty? || value > self[-1]
|
170
|
+
push value
|
171
|
+
return high
|
172
|
+
end
|
173
|
+
# binary search for replacement point
|
174
|
+
low = 0
|
175
|
+
while low < high
|
176
|
+
index = (high+low)/2
|
177
|
+
found = self[index]
|
178
|
+
return nil if value == found
|
179
|
+
if value > found
|
180
|
+
low = index + 1
|
181
|
+
else
|
182
|
+
high = index
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
self[low] = value
|
187
|
+
# $stderr << "replace #{value} : 0/#{low}/#{init_high} (#{steps} steps) (#{init_high-low} off )\n"
|
188
|
+
# $stderr.puts self.inspect
|
189
|
+
#gets
|
190
|
+
#p length - low
|
191
|
+
return low
|
192
|
+
end
|
193
|
+
|
194
|
+
def patch(diff)
|
195
|
+
newary = nil
|
196
|
+
if diff.difftype == String
|
197
|
+
newary = diff.difftype.new('')
|
198
|
+
else
|
199
|
+
newary = diff.difftype.new
|
200
|
+
end
|
201
|
+
ai = 0
|
202
|
+
bi = 0
|
203
|
+
diff.diffs.each { |d|
|
204
|
+
d.each { |mod|
|
205
|
+
case mod[0]
|
206
|
+
when '-'
|
207
|
+
while ai < mod[1]
|
208
|
+
newary << self[ai]
|
209
|
+
ai += 1
|
210
|
+
bi += 1
|
211
|
+
end
|
212
|
+
ai += 1
|
213
|
+
when '+'
|
214
|
+
while bi < mod[1]
|
215
|
+
newary << self[ai]
|
216
|
+
ai += 1
|
217
|
+
bi += 1
|
218
|
+
end
|
219
|
+
newary << mod[2]
|
220
|
+
bi += 1
|
221
|
+
else
|
222
|
+
raise "Unknown diff action"
|
223
|
+
end
|
224
|
+
}
|
225
|
+
}
|
226
|
+
while ai < self.length
|
227
|
+
newary << self[ai]
|
228
|
+
ai += 1
|
229
|
+
bi += 1
|
230
|
+
end
|
231
|
+
return newary
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
class Array
|
236
|
+
include Diffable
|
237
|
+
end
|
238
|
+
|
239
|
+
class String
|
240
|
+
include Diffable
|
241
|
+
end
|
242
|
+
|
243
|
+
=begin
|
244
|
+
= Diff
|
245
|
+
(({diff.rb})) - computes the differences between two arrays or
|
246
|
+
strings. Copyright (C) 2001 Lars Christensen
|
247
|
+
|
248
|
+
== Synopsis
|
249
|
+
|
250
|
+
diff = Diff.new(a, b)
|
251
|
+
b = a.patch(diff)
|
252
|
+
|
253
|
+
== Class Diff
|
254
|
+
=== Class Methods
|
255
|
+
--- Diff.new(a, b)
|
256
|
+
--- a.diff(b)
|
257
|
+
Creates a Diff object which represent the differences between
|
258
|
+
((|a|)) and ((|b|)). ((|a|)) and ((|b|)) can be either be arrays
|
259
|
+
of any objects, strings, or object of any class that include
|
260
|
+
module ((|Diffable|))
|
261
|
+
|
262
|
+
== Module Diffable
|
263
|
+
The module ((|Diffable|)) is intended to be included in any class for
|
264
|
+
which differences are to be computed. Diffable is included into String
|
265
|
+
and Array when (({diff.rb})) is (({require}))'d.
|
266
|
+
|
267
|
+
Classes including Diffable should implement (({[]})) to get element at
|
268
|
+
integer indices, (({<<})) to append elements to the object and
|
269
|
+
(({ClassName#new})) should accept 0 arguments to create a new empty
|
270
|
+
object.
|
271
|
+
|
272
|
+
=== Instance Methods
|
273
|
+
--- Diffable#patch(diff)
|
274
|
+
Applies the differences from ((|diff|)) to the object ((|obj|))
|
275
|
+
and return the result. ((|obj|)) is not changed. ((|obj|)) and
|
276
|
+
can be either an array or a string, but must match the object
|
277
|
+
from which the ((|diff|)) was created.
|
278
|
+
=end
|
data/lib/emaildiff.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'diff'
|
2
|
+
|
3
|
+
module HTMLCollapsable
|
4
|
+
def diff(b)
|
5
|
+
Diff.new(self, b)
|
6
|
+
end
|
7
|
+
|
8
|
+
def collapse(diff,starttoken,endtoken)
|
9
|
+
newary = nil
|
10
|
+
if diff.difftype == String
|
11
|
+
newary = diff.difftype.new('')
|
12
|
+
else
|
13
|
+
newary = diff.difftype.new
|
14
|
+
end
|
15
|
+
ai = 0
|
16
|
+
bi = 0
|
17
|
+
diff.diffs.each { |d|
|
18
|
+
d.each { |mod|
|
19
|
+
quoted = 0
|
20
|
+
case mod[0]
|
21
|
+
when '-'
|
22
|
+
if ai < mod[1]
|
23
|
+
quoted = 1
|
24
|
+
end
|
25
|
+
newary << starttoken if quoted == 1
|
26
|
+
while ai < mod[1]
|
27
|
+
newary << self[ai]
|
28
|
+
ai += 1
|
29
|
+
bi += 1
|
30
|
+
end
|
31
|
+
newary << endtoken if quoted == 1
|
32
|
+
ai += 1
|
33
|
+
when '+'
|
34
|
+
if bi < mod[1]
|
35
|
+
quoted = 1
|
36
|
+
end
|
37
|
+
newary << starttoken if quoted == 1
|
38
|
+
while bi < mod[1]
|
39
|
+
newary << self[ai]
|
40
|
+
ai += 1
|
41
|
+
bi += 1
|
42
|
+
end
|
43
|
+
newary << endtoken if quoted == 1
|
44
|
+
newary << mod[2]
|
45
|
+
bi += 1
|
46
|
+
else
|
47
|
+
raise "Unknown diff action"
|
48
|
+
end
|
49
|
+
}
|
50
|
+
}
|
51
|
+
quoted = 0
|
52
|
+
if ai < self.length
|
53
|
+
quoted = 1
|
54
|
+
end
|
55
|
+
newary << starttoken if quoted == 1
|
56
|
+
while ai < self.length
|
57
|
+
newary << self[ai]
|
58
|
+
ai += 1
|
59
|
+
bi += 1
|
60
|
+
end
|
61
|
+
newary << endtoken if quoted == 1
|
62
|
+
return newary
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class Array
|
67
|
+
include HTMLCollapsable
|
68
|
+
end
|
69
|
+
|
70
|
+
class String
|
71
|
+
include HTMLCollapsable
|
72
|
+
end
|
73
|
+
|
data/lib/unixdiff.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'diff'
|
4
|
+
|
5
|
+
def loadfile(filename)
|
6
|
+
lines = nil
|
7
|
+
File.open(filename, "r") { |f|
|
8
|
+
lines = f.readlines
|
9
|
+
}
|
10
|
+
return lines
|
11
|
+
end
|
12
|
+
|
13
|
+
def diffrange(a, b)
|
14
|
+
if (a == b)
|
15
|
+
"#{a}"
|
16
|
+
else
|
17
|
+
"#{a},#{b}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class Diff
|
22
|
+
def to_diff(io = $defout)
|
23
|
+
offset = 0
|
24
|
+
@diffs.each { |b|
|
25
|
+
first = b[0][1]
|
26
|
+
length = b.length
|
27
|
+
action = b[0][0]
|
28
|
+
addcount = 0
|
29
|
+
remcount = 0
|
30
|
+
b.each { |l|
|
31
|
+
if l[0] == "+"
|
32
|
+
addcount += 1
|
33
|
+
elsif l[0] == "-"
|
34
|
+
remcount += 1
|
35
|
+
end
|
36
|
+
}
|
37
|
+
if addcount == 0
|
38
|
+
puts "#{diffrange(first+1, first+remcount)}d#{first+offset}"
|
39
|
+
elsif remcount == 0
|
40
|
+
puts "#{first-offset}a#{diffrange(first+1, first+addcount)}"
|
41
|
+
else
|
42
|
+
puts "#{diffrange(first+1, first+remcount)}c#{diffrange(first+offset+1, first+offset+addcount)}"
|
43
|
+
end
|
44
|
+
lastdel = (b[0][0] == "-")
|
45
|
+
b.each { |l|
|
46
|
+
if l[0] == "-"
|
47
|
+
offset -= 1
|
48
|
+
print "< "
|
49
|
+
elsif l[0] == "+"
|
50
|
+
offset += 1
|
51
|
+
if lastdel
|
52
|
+
lastdel = false
|
53
|
+
puts "---"
|
54
|
+
end
|
55
|
+
print "> "
|
56
|
+
end
|
57
|
+
print l[2]
|
58
|
+
}
|
59
|
+
}
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
if $0 == __FILE__
|
64
|
+
|
65
|
+
file1 = ARGV.shift
|
66
|
+
file2 = ARGV.shift
|
67
|
+
|
68
|
+
ary1 = loadfile file1
|
69
|
+
ary2 = loadfile file2
|
70
|
+
|
71
|
+
diff = Diff.new(ary1, ary2)
|
72
|
+
diff.to_diff
|
73
|
+
|
74
|
+
end
|
data/test/test_cases.rb
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
module DiffArrayTests
|
2
|
+
|
3
|
+
def test_array_append
|
4
|
+
difftest [1,2,3], [1,2,3,4]
|
5
|
+
difftest [1,2,3], [1,2,3,4,5]
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_array_prepend
|
9
|
+
difftest [1,2,3], [0,1,2,3]
|
10
|
+
difftest [1,2,3], [-1,0,1,2,3]
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_array_insert
|
14
|
+
difftest [1,2,3], [1,2,4,3]
|
15
|
+
difftest [1,2,3], [1,2,4,5,3]
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_array_remove
|
19
|
+
difftest [1,2,3], [1,3]
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_array_cutfront
|
23
|
+
difftest [1,2,3], [2,3]
|
24
|
+
difftest [1,2,3], [3]
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_array_cutback
|
28
|
+
difftest [1,2,3], [1,2]
|
29
|
+
difftest [1,2,3], [1]
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_array_empty
|
33
|
+
difftest [1,2,3], []
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_array_fill
|
37
|
+
difftest [], [1,2,3]
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_array_change
|
41
|
+
difftest [1,2,3], [1,4,3]
|
42
|
+
difftest [1,2,3], [1,4,5]
|
43
|
+
difftest [1,2,3,4], [1,5,4]
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_array_noop
|
47
|
+
difftest [1,2,3], [1,2,3]
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_array_grow
|
51
|
+
difftest [1,2,3], [4,1,5,2,6,3,7]
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_array_shrink
|
55
|
+
difftest [1,2,3,4,5,6,7], [2,4,6]
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
module DiffStringTests
|
61
|
+
|
62
|
+
def test_string_append
|
63
|
+
difftest "abc", "abcd"
|
64
|
+
difftest "abc", "abcde"
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_string_preprend
|
68
|
+
difftest "abc", "qabc"
|
69
|
+
difftest "abc", "qrabc"
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_string_insert
|
73
|
+
difftest "abc", "abqc"
|
74
|
+
difftest "abc", "abqrc"
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_string_cutfront
|
78
|
+
difftest "abc", "bc"
|
79
|
+
difftest "abc", "c"
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_string_cutback
|
83
|
+
difftest "abc", "ab"
|
84
|
+
difftest "abc", "a"
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_string_empty
|
88
|
+
difftest "abc", ""
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_string_fill
|
92
|
+
difftest "", "abc"
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_string_change
|
96
|
+
difftest "abc", "aqc"
|
97
|
+
difftest "abc", "aqrc"
|
98
|
+
difftest "abcd", "aqd"
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_string_noop
|
102
|
+
difftest "abc", "abc"
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_string_grow
|
106
|
+
difftest "abc", "qarbsct"
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_string_shrink
|
110
|
+
difftest "abcdefg", "bdf"
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_string_remove
|
114
|
+
difftest "abc", "ac"
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
module DiffStressTest
|
120
|
+
Elems = [1,2,3]
|
121
|
+
def generate_array
|
122
|
+
length = (16 + 16 * rand).to_i
|
123
|
+
ary = []
|
124
|
+
length.times {
|
125
|
+
ary << Elems[(rand * Elems.length).to_i]
|
126
|
+
}
|
127
|
+
return ary
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_stress
|
131
|
+
256.times {
|
132
|
+
a = generate_array
|
133
|
+
b = generate_array
|
134
|
+
difftest(a, b)
|
135
|
+
}
|
136
|
+
end
|
137
|
+
end
|
data/test/test_diff.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'runit/testcase'
|
2
|
+
require 'runit/cui/testrunner'
|
3
|
+
require 'runit/testsuite'
|
4
|
+
require 'diff'
|
5
|
+
require 'test_cases'
|
6
|
+
|
7
|
+
class DiffTest < RUNIT::TestCase
|
8
|
+
|
9
|
+
include DiffStringTests
|
10
|
+
include DiffArrayTests
|
11
|
+
include DiffStressTest
|
12
|
+
|
13
|
+
def difftest(a, b)
|
14
|
+
diff = Diff.new(a, b)
|
15
|
+
c = a.patch(diff)
|
16
|
+
assert_equal(b, c)
|
17
|
+
diff = Diff.new(b, a)
|
18
|
+
c = b.patch(diff)
|
19
|
+
assert_equal(a, c)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
RUNIT::CUI::TestRunner.run(DiffTest.suite)
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module DiffArrayTests
|
2
|
+
|
3
|
+
def test_array_append
|
4
|
+
difftest [1,2,3], [1,2,3,4], [888,1,2,3,999,4]
|
5
|
+
difftest [1,2,3], [1,2,3,4,5], [888,1,2,3,999,4,5]
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_array_prepend
|
9
|
+
difftest [1,2,3], [0,1,2,3], [0,888,1,2,3,999]
|
10
|
+
difftest [1,2,3], [-1,0,1,2,3], [-1,0,888,1,2,3,999]
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_array_insert
|
14
|
+
difftest [1,2,3], [1,2,4,3], [888,1,2,999,4,888,3,999]
|
15
|
+
difftest [1,2,3], [1,2,4,5,3], [888,1,2,999,4,5,888,3,999]
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_array_remove
|
19
|
+
difftest [1,2,3], [1,3], [888,1,999,888,3,999]
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_array_cutfront
|
24
|
+
difftest [1,2,3], [2,3], [888,2,3,999]
|
25
|
+
difftest [1,2,3], [3], [888,3,999]
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_array_cutback
|
29
|
+
difftest [1,2,3], [1,2], [888,1,2,999]
|
30
|
+
difftest [1,2,3], [1], [888,1,999]
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_array_empty
|
34
|
+
difftest [1,2,3], [], []
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_array_fill
|
38
|
+
difftest [], [1,2,3], [1,2,3]
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_array_change
|
42
|
+
difftest [1,2,3], [1,4,3], [888,1,999,4,888,3,999]
|
43
|
+
difftest [1,2,3], [1,4,5], [888,1,999,4,5]
|
44
|
+
difftest [1,2,3,4], [1,5,4], [888,1,999,5,888,4,999]
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_array_noop
|
48
|
+
difftest [1,2,3], [1,2,3], [888,1,2,3,999]
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_array_grow
|
52
|
+
difftest [1,2,3], [4,1,5,2,6,3,7], [4,888,1,999,5,888,2,999,6,888,3,999,7]
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_array_shrink
|
56
|
+
difftest [1,2,3,4,5,6,7], [2,4,6], [888,2,999,888,4,999,888,6,999]
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'runit/testcase'
|
2
|
+
require 'runit/cui/testrunner'
|
3
|
+
require 'runit/testsuite'
|
4
|
+
require 'diff'
|
5
|
+
require 'emaildiff'
|
6
|
+
require 'test_emailcases'
|
7
|
+
|
8
|
+
class EmailDiffTest < RUNIT::TestCase
|
9
|
+
|
10
|
+
include DiffArrayTests
|
11
|
+
|
12
|
+
def difftest(a, b, c)
|
13
|
+
#puts "old string:"
|
14
|
+
#puts a
|
15
|
+
#puts "new string:"
|
16
|
+
#puts b
|
17
|
+
diff = Diff.new(a, b)
|
18
|
+
d = a.collapse(diff,888,999)
|
19
|
+
#puts "result:"
|
20
|
+
#puts c
|
21
|
+
assert_equal(c,d)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
RUNIT::CUI::TestRunner.run(EmailDiffTest.suite)
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'runit/testcase'
|
2
|
+
require 'runit/cui/testrunner'
|
3
|
+
require 'runit/testsuite'
|
4
|
+
require 'diff'
|
5
|
+
require 'test_cases'
|
6
|
+
|
7
|
+
class UnixDiffTest < RUNIT::TestCase
|
8
|
+
|
9
|
+
include DiffArrayTests
|
10
|
+
#include DiffStressTest
|
11
|
+
|
12
|
+
def makefile(filename, ary)
|
13
|
+
File.open(filename, "w") { |f|
|
14
|
+
ary.each { |elem|
|
15
|
+
f.puts elem.to_s
|
16
|
+
}
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
def rundiff(prog)
|
21
|
+
res = []
|
22
|
+
IO.popen("#{prog} file1 file2") { |f|
|
23
|
+
while ln = f.gets
|
24
|
+
res << ln
|
25
|
+
end
|
26
|
+
}
|
27
|
+
res
|
28
|
+
end
|
29
|
+
|
30
|
+
def difftest(a, b)
|
31
|
+
makefile("file1", a)
|
32
|
+
makefile("file2", b)
|
33
|
+
result1 = rundiff("diff")
|
34
|
+
result2 = rundiff("lib/unixdiff.rb");
|
35
|
+
assert_equal(result1, result2)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
RUNIT::CUI::TestRunner.run(UnixDiffTest.suite)
|
metadata
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: diff
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 3
|
8
|
+
- 1
|
9
|
+
version: 0.3.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Wayne Walter
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain:
|
16
|
+
- |
|
17
|
+
-----BEGIN CERTIFICATE-----
|
18
|
+
MIIDNjCCAh6gAwIBAgIBADANBgkqhkiG9w0BAQUFADBBMRAwDgYDVQQDDAdkaWZm
|
19
|
+
Z2VtMRgwFgYKCZImiZPyLGQBGRYIdGlja3pvb20xEzARBgoJkiaJk/IsZAEZFgNj
|
20
|
+
b20wHhcNMTAwNjI3MDUwNjEyWhcNMTEwNjI3MDUwNjEyWjBBMRAwDgYDVQQDDAdk
|
21
|
+
aWZmZ2VtMRgwFgYKCZImiZPyLGQBGRYIdGlja3pvb20xEzARBgoJkiaJk/IsZAEZ
|
22
|
+
FgNjb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDbPiHhbX0yQuqX
|
23
|
+
NONpzyqFHMSIM6aUXrOMWv1VWJejRli2ssdixBEL3laSCbAIpBwPQXlUbkl5Keq6
|
24
|
+
kZK9LmztDK3S8y37YSJ/ojFjdX8AM/MVByC2BJGQGEzIrHikiKwlJ8GxM3pLow4+
|
25
|
+
+av0dyWCUgVn9bGvDIcay780i4wmaSC2Sf9Obkgu1TiR0hc48AtUOToN4RwdScL0
|
26
|
+
oAmKG/lSYGUhkhUROdghMEaGMotCFHm5szM5miOxK5PqCq14cQP5W+ubKo2oE6iF
|
27
|
+
3YH7iG+qspCGOGjKcz8g+AYmMsN8sO2oh1orM7EG6Bm1RI6gKeruC6ez1woF8jn2
|
28
|
+
6WGa9a4rAgMBAAGjOTA3MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQW
|
29
|
+
BBRYb3kBzatxDzFkBANlHfc1S5u7yjANBgkqhkiG9w0BAQUFAAOCAQEAhISiSEuF
|
30
|
+
RbvSpMfZe4g/9O2e+A6pE7BCmmR6EzGanQFf39DMSdwd8GbtW1p7ZQYGuxiFVGQw
|
31
|
+
OZiRnP5QNqqtR5LjArw9obt9BgeJjhAs0WI97G9LJdKu4kz1Yee+6kN5Dt5hjrVX
|
32
|
+
tHxTUv4oyN8PxyKnQt+pevLsp7TkaYHtl2+VLg9iU5syNPhASx7erHwiMu6yNOjZ
|
33
|
+
uwsQ4lOsT6OM45inY82GupysnaP5BrZh/WBQ3m8mdA47pGBmHH3Vm57hooA+RSW7
|
34
|
+
NYrQY6HQkU2llwX9w8Ts8rO45tig6pSbgkim0V0ewjxWUI4D7zzc1t55ZsJJZu9o
|
35
|
+
nbAv9FEyqLVW8Q==
|
36
|
+
-----END CERTIFICATE-----
|
37
|
+
|
38
|
+
date: 2010-06-27 00:00:00 +00:00
|
39
|
+
default_executable:
|
40
|
+
dependencies: []
|
41
|
+
|
42
|
+
description: Diff Algorithm Implementation
|
43
|
+
email: diffgem@tickzoom.com
|
44
|
+
executables: []
|
45
|
+
|
46
|
+
extensions: []
|
47
|
+
|
48
|
+
extra_rdoc_files:
|
49
|
+
- README
|
50
|
+
- TODO
|
51
|
+
- lib/diff.rb
|
52
|
+
- lib/emaildiff.rb
|
53
|
+
- lib/unixdiff.rb
|
54
|
+
files:
|
55
|
+
- Manifest
|
56
|
+
- README
|
57
|
+
- Rakefile
|
58
|
+
- TODO
|
59
|
+
- diff.gemspec
|
60
|
+
- lib/diff.rb
|
61
|
+
- lib/emaildiff.rb
|
62
|
+
- lib/unixdiff.rb
|
63
|
+
- test/test_cases.rb
|
64
|
+
- test/test_diff.rb
|
65
|
+
- test/test_emailcases.rb
|
66
|
+
- test/test_emaildiff.rb
|
67
|
+
- test/test_unixdiff.rb
|
68
|
+
has_rdoc: true
|
69
|
+
homepage: http://users.cybercity.dk/~dsl8950/ruby/diff.html
|
70
|
+
licenses: []
|
71
|
+
|
72
|
+
post_install_message:
|
73
|
+
rdoc_options:
|
74
|
+
- --line-numbers
|
75
|
+
- --inline-source
|
76
|
+
- --title
|
77
|
+
- Diff
|
78
|
+
- --main
|
79
|
+
- README
|
80
|
+
require_paths:
|
81
|
+
- lib
|
82
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
segments:
|
88
|
+
- 0
|
89
|
+
version: "0"
|
90
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
91
|
+
none: false
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
segments:
|
96
|
+
- 1
|
97
|
+
- 2
|
98
|
+
version: "1.2"
|
99
|
+
requirements: []
|
100
|
+
|
101
|
+
rubyforge_project: diff
|
102
|
+
rubygems_version: 1.3.7
|
103
|
+
signing_key:
|
104
|
+
specification_version: 3
|
105
|
+
summary: Diff Algorithm Implementation
|
106
|
+
test_files:
|
107
|
+
- test/test_emailcases.rb
|
108
|
+
- test/test_emaildiff.rb
|
109
|
+
- test/test_unixdiff.rb
|
110
|
+
- test/test_diff.rb
|
111
|
+
- test/test_cases.rb
|
metadata.gz.sig
ADDED
Binary file
|