Name | Total Lines | Lines of Code | Total Coverage | Code Coverage |
---|---|---|---|---|
rcov/ruby/1.8/gems/diff-lcs-1.1.2/lib/diff/lcs/callbacks.rb | 322 | 83 | 84.47%
|
40.96%
|
Code reported as executed by Ruby looks like this...and this: this line is also marked as covered.Lines considered as run by rcov, but not reported by Ruby, look like this,and this: these lines were inferred by rcov (using simple heuristics).Finally, here's a line marked as not executed.
1 #! /usr/env/bin ruby |
2 #-- |
3 # Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca> |
4 # adapted from: |
5 # Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com> |
6 # Smalltalk by Mario I. Wolczko <mario@wolczko.com> |
7 # implements McIlroy-Hunt diff algorithm |
8 # |
9 # This program is free software. It may be redistributed and/or modified under |
10 # the terms of the GPL version 2 (or later), the Perl Artistic licence, or the |
11 # Ruby licence. |
12 # |
13 # $Id: callbacks.rb,v 1.4 2004/09/14 18:51:26 austin Exp $ |
14 #++ |
15 # Contains definitions for all default callback objects. |
16 |
17 require 'diff/lcs/change' |
18 |
19 module Diff::LCS |
20 # This callback object implements the default set of callback events, which |
21 # only returns the event itself. Note that #finished_a and #finished_b are |
22 # not implemented -- I haven't yet figured out where they would be useful. |
23 # |
24 # Note that this is intended to be called as is, e.g., |
25 # |
26 # Diff::LCS.LCS(seq1, seq2, Diff::LCS::DefaultCallbacks) |
27 class DefaultCallbacks |
28 class << self |
29 # Called when two items match. |
30 def match(event) |
31 event |
32 end |
33 # Called when the old value is discarded in favour of the new value. |
34 def discard_a(event) |
35 event |
36 end |
37 # Called when the new value is discarded in favour of the old value. |
38 def discard_b(event) |
39 event |
40 end |
41 # Called when both the old and new values have changed. |
42 def change(event) |
43 event |
44 end |
45 |
46 private :new |
47 end |
48 end |
49 |
50 # An alias for DefaultCallbacks that is used in Diff::LCS#traverse_sequences. |
51 # |
52 # Diff::LCS.LCS(seq1, seq2, Diff::LCS::SequenceCallbacks) |
53 SequenceCallbacks = DefaultCallbacks |
54 # An alias for DefaultCallbacks that is used in Diff::LCS#traverse_balanced. |
55 # |
56 # Diff::LCS.LCS(seq1, seq2, Diff::LCS::BalancedCallbacks) |
57 BalancedCallbacks = DefaultCallbacks |
58 end |
59 |
60 # This will produce a compound array of simple diff change objects. Each |
61 # element in the #diffs array is a +hunk+ or +hunk+ array, where each |
62 # element in each +hunk+ array is a single Change object representing the |
63 # addition or removal of a single element from one of the two tested |
64 # sequences. The +hunk+ provides the full context for the changes. |
65 # |
66 # diffs = Diff::LCS.diff(seq1, seq2) |
67 # # This example shows a simplified array format. |
68 # # [ [ [ '-', 0, 'a' ] ], # 1 |
69 # # [ [ '+', 2, 'd' ] ], # 2 |
70 # # [ [ '-', 4, 'h' ], # 3 |
71 # # [ '+', 4, 'f' ] ], |
72 # # [ [ '+', 6, 'k' ] ], # 4 |
73 # # [ [ '-', 8, 'n' ], # 5 |
74 # # [ '-', 9, 'p' ], |
75 # # [ '+', 9, 'r' ], |
76 # # [ '+', 10, 's' ], |
77 # # [ '+', 11, 't' ] ] ] |
78 # |
79 # There are five hunks here. The first hunk says that the +a+ at position 0 |
80 # of the first sequence should be deleted (<tt>'-'</tt>). The second hunk |
81 # says that the +d+ at position 2 of the second sequence should be inserted |
82 # (<tt>'+'</tt>). The third hunk says that the +h+ at position 4 of the |
83 # first sequence should be removed and replaced with the +f+ from position 4 |
84 # of the second sequence. The other two hunks are described similarly. |
85 # |
86 # === Use |
87 # This callback object must be initialised and is used by the Diff::LCS#diff |
88 # method. |
89 # |
90 # cbo = Diff::LCS::DiffCallbacks.new |
91 # Diff::LCS.LCS(seq1, seq2, cbo) |
92 # cbo.finish |
93 # |
94 # Note that the call to #finish is absolutely necessary, or the last set of |
95 # changes will not be visible. Alternatively, can be used as: |
96 # |
97 # cbo = Diff::LCS::DiffCallbacks.new { |tcbo| Diff::LCS.LCS(seq1, seq2, tcbo) } |
98 # |
99 # The necessary #finish call will be made. |
100 # |
101 # === Simplified Array Format |
102 # The simplified array format used in the example above can be obtained |
103 # with: |
104 # |
105 # require 'pp' |
106 # pp diffs.map { |e| e.map { |f| f.to_a } } |
107 class Diff::LCS::DiffCallbacks |
108 # Returns the difference set collected during the diff process. |
109 attr_reader :diffs |
110 |
111 def initialize # :yields self: |
112 @hunk = [] |
113 @diffs = [] |
114 |
115 if block_given? |
116 begin |
117 yield self |
118 ensure |
119 self.finish |
120 end |
121 end |
122 end |
123 |
124 # Finalizes the diff process. If an unprocessed hunk still exists, then it |
125 # is appended to the diff list. |
126 def finish |
127 add_nonempty_hunk |
128 end |
129 |
130 def match(event) |
131 add_nonempty_hunk |
132 end |
133 |
134 def discard_a(event) |
135 @hunk << Diff::LCS::Change.new('-', event.old_position, event.old_element) |
136 end |
137 |
138 def discard_b(event) |
139 @hunk << Diff::LCS::Change.new('+', event.new_position, event.new_element) |
140 end |
141 |
142 private |
143 def add_nonempty_hunk |
144 @diffs << @hunk unless @hunk.empty? |
145 @hunk = [] |
146 end |
147 end |
148 |
149 # This will produce a compound array of contextual diff change objects. Each |
150 # element in the #diffs array is a "hunk" array, where each element in each |
151 # "hunk" array is a single change. Each change is a Diff::LCS::ContextChange |
152 # that contains both the old index and new index values for the change. The |
153 # "hunk" provides the full context for the changes. Both old and new objects |
154 # will be presented for changed objects. +nil+ will be substituted for a |
155 # discarded object. |
156 # |
157 # seq1 = %w(a b c e h j l m n p) |
158 # seq2 = %w(b c d e f j k l m r s t) |
159 # |
160 # diffs = Diff::LCS.diff(seq1, seq2, Diff::LCS::ContextDiffCallbacks) |
161 # # This example shows a simplified array format. |
162 # # [ [ [ '-', [ 0, 'a' ], [ 0, nil ] ] ], # 1 |
163 # # [ [ '+', [ 3, nil ], [ 2, 'd' ] ] ], # 2 |
164 # # [ [ '-', [ 4, 'h' ], [ 4, nil ] ], # 3 |
165 # # [ '+', [ 5, nil ], [ 4, 'f' ] ] ], |
166 # # [ [ '+', [ 6, nil ], [ 6, 'k' ] ] ], # 4 |
167 # # [ [ '-', [ 8, 'n' ], [ 9, nil ] ], # 5 |
168 # # [ '+', [ 9, nil ], [ 9, 'r' ] ], |
169 # # [ '-', [ 9, 'p' ], [ 10, nil ] ], |
170 # # [ '+', [ 10, nil ], [ 10, 's' ] ], |
171 # # [ '+', [ 10, nil ], [ 11, 't' ] ] ] ] |
172 # |
173 # The five hunks shown are comprised of individual changes; if there is a |
174 # related set of changes, they are still shown individually. |
175 # |
176 # This callback can also be used with Diff::LCS#sdiff, which will produce |
177 # results like: |
178 # |
179 # diffs = Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextCallbacks) |
180 # # This example shows a simplified array format. |
181 # # [ [ [ "-", [ 0, "a" ], [ 0, nil ] ] ], # 1 |
182 # # [ [ "+", [ 3, nil ], [ 2, "d" ] ] ], # 2 |
183 # # [ [ "!", [ 4, "h" ], [ 4, "f" ] ] ], # 3 |
184 # # [ [ "+", [ 6, nil ], [ 6, "k" ] ] ], # 4 |
185 # # [ [ "!", [ 8, "n" ], [ 9, "r" ] ], # 5 |
186 # # [ "!", [ 9, "p" ], [ 10, "s" ] ], |
187 # # [ "+", [ 10, nil ], [ 11, "t" ] ] ] ] |
188 # |
189 # The five hunks are still present, but are significantly shorter in total |
190 # presentation, because changed items are shown as changes ("!") instead of |
191 # potentially "mismatched" pairs of additions and deletions. |
192 # |
193 # The result of this operation is similar to that of |
194 # Diff::LCS::SDiffCallbacks. They may be compared as: |
195 # |
196 # s = Diff::LCS.sdiff(seq1, seq2).reject { |e| e.action == "=" } |
197 # c = Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextDiffCallbacks).flatten |
198 # |
199 # s == c # -> true |
200 # |
201 # === Use |
202 # This callback object must be initialised and can be used by the |
203 # Diff::LCS#diff or Diff::LCS#sdiff methods. |
204 # |
205 # cbo = Diff::LCS::ContextDiffCallbacks.new |
206 # Diff::LCS.LCS(seq1, seq2, cbo) |
207 # cbo.finish |
208 # |
209 # Note that the call to #finish is absolutely necessary, or the last set of |
210 # changes will not be visible. Alternatively, can be used as: |
211 # |
212 # cbo = Diff::LCS::ContextDiffCallbacks.new { |tcbo| Diff::LCS.LCS(seq1, seq2, tcbo) } |
213 # |
214 # The necessary #finish call will be made. |
215 # |
216 # === Simplified Array Format |
217 # The simplified array format used in the example above can be obtained |
218 # with: |
219 # |
220 # require 'pp' |
221 # pp diffs.map { |e| e.map { |f| f.to_a } } |
222 class Diff::LCS::ContextDiffCallbacks < Diff::LCS::DiffCallbacks |
223 def discard_a(event) |
224 @hunk << Diff::LCS::ContextChange.simplify(event) |
225 end |
226 |
227 def discard_b(event) |
228 @hunk << Diff::LCS::ContextChange.simplify(event) |
229 end |
230 |
231 def change(event) |
232 @hunk << Diff::LCS::ContextChange.simplify(event) |
233 end |
234 end |
235 |
236 # This will produce a simple array of diff change objects. Each element in |
237 # the #diffs array is a single ContextChange. In the set of #diffs provided |
238 # by SDiffCallbacks, both old and new objects will be presented for both |
239 # changed <strong>and unchanged</strong> objects. +nil+ will be substituted |
240 # for a discarded object. |
241 # |
242 # The diffset produced by this callback, when provided to Diff::LCS#sdiff, |
243 # will compute and display the necessary components to show two sequences |
244 # and their minimized differences side by side, just like the Unix utility |
245 # +sdiff+. |
246 # |
247 # same same |
248 # before | after |
249 # old < - |
250 # - > new |
251 # |
252 # seq1 = %w(a b c e h j l m n p) |
253 # seq2 = %w(b c d e f j k l m r s t) |
254 # |
255 # diffs = Diff::LCS.sdiff(seq1, seq2) |
256 # # This example shows a simplified array format. |
257 # # [ [ "-", [ 0, "a"], [ 0, nil ] ], |
258 # # [ "=", [ 1, "b"], [ 0, "b" ] ], |
259 # # [ "=", [ 2, "c"], [ 1, "c" ] ], |
260 # # [ "+", [ 3, nil], [ 2, "d" ] ], |
261 # # [ "=", [ 3, "e"], [ 3, "e" ] ], |
262 # # [ "!", [ 4, "h"], [ 4, "f" ] ], |
263 # # [ "=", [ 5, "j"], [ 5, "j" ] ], |
264 # # [ "+", [ 6, nil], [ 6, "k" ] ], |
265 # # [ "=", [ 6, "l"], [ 7, "l" ] ], |
266 # # [ "=", [ 7, "m"], [ 8, "m" ] ], |
267 # # [ "!", [ 8, "n"], [ 9, "r" ] ], |
268 # # [ "!", [ 9, "p"], [ 10, "s" ] ], |
269 # # [ "+", [ 10, nil], [ 11, "t" ] ] ] |
270 # |
271 # The result of this operation is similar to that of |
272 # Diff::LCS::ContextDiffCallbacks. They may be compared as: |
273 # |
274 # s = Diff::LCS.sdiff(seq1, seq2).reject { |e| e.action == "=" } |
275 # c = Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextDiffCallbacks).flatten |
276 # |
277 # s == c # -> true |
278 # |
279 # === Use |
280 # This callback object must be initialised and is used by the Diff::LCS#sdiff |
281 # method. |
282 # |
283 # cbo = Diff::LCS::SDiffCallbacks.new |
284 # Diff::LCS.LCS(seq1, seq2, cbo) |
285 # |
286 # As with the other initialisable callback objects, Diff::LCS::SDiffCallbacks |
287 # can be initialised with a block. As there is no "fininishing" to be done, |
288 # this has no effect on the state of the object. |
289 # |
290 # cbo = Diff::LCS::SDiffCallbacks.new { |tcbo| Diff::LCS.LCS(seq1, seq2, tcbo) } |
291 # |
292 # === Simplified Array Format |
293 # The simplified array format used in the example above can be obtained |
294 # with: |
295 # |
296 # require 'pp' |
297 # pp diffs.map { |e| e.to_a } |
298 class Diff::LCS::SDiffCallbacks |
299 # Returns the difference set collected during the diff process. |
300 attr_reader :diffs |
301 |
302 def initialize #:yields self: |
303 @diffs = [] |
304 yield self if block_given? |
305 end |
306 |
307 def match(event) |
308 @diffs << Diff::LCS::ContextChange.simplify(event) |
309 end |
310 |
311 def discard_a(event) |
312 @diffs << Diff::LCS::ContextChange.simplify(event) |
313 end |
314 |
315 def discard_b(event) |
316 @diffs << Diff::LCS::ContextChange.simplify(event) |
317 end |
318 |
319 def change(event) |
320 @diffs << Diff::LCS::ContextChange.simplify(event) |
321 end |
322 end |
Generated on Fri Apr 22 17:22:42 -0700 2011 with rcov 0.9.8