diff 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|