diff-lcs 1.2.1 → 1.2.2

Sign up to get free protection for your applications and to get access to all the features.
data.tar.gz.sig CHANGED
Binary file
@@ -6,8 +6,9 @@ before_script:
6
6
  - rake travis:before -t
7
7
  language: ruby
8
8
  notifications:
9
- email: false
9
+ email: true
10
10
  rvm:
11
+ - 2.0.0
11
12
  - 1.9.3
12
13
  - 1.9.2
13
14
  - ruby-head
@@ -61,3 +61,4 @@ Thanks to everyone else who has contributed to Diff::LCS:
61
61
  * Kenichi Kamiya
62
62
  * Michael Granger
63
63
  * Vít Ondruch
64
+ * Jon Rowe
@@ -1,3 +1,17 @@
1
+ == 1.2.2 / 2013-03-30
2
+
3
+ * Bugs Fixed:
4
+ * Diff::LCS::Hunk could not properly generate a difference for comparison
5
+ sets that are not US-ASCII-compatible because of the use of literal regular
6
+ expressions and strings. Jon Rowe (JonRowe) found this in
7
+ rspec/rspec-expectations#219 and provided a first pass implementation in
8
+ diff-lcs#15. I've reworked it because of test failures in Rubinius when
9
+ running in Ruby 1.9 mode. This coerces the added values to the encoding of
10
+ the old dataset (as determined by the first piece of the old dataset).
11
+ https://github.com/rspec/rspec-expectations/issues/219
12
+ https://github.com/halostatue/diff-lcs/pull/15
13
+ * Adding Travis CI testing for Ruby 2.0.
14
+
1
15
  == 1.2.1 / 2013-02-09
2
16
 
3
17
  * Bugs Fixed:
@@ -29,6 +29,7 @@ lib/diff/lcs/ldiff.rb
29
29
  lib/diff/lcs/string.rb
30
30
  spec/change_spec.rb
31
31
  spec/diff_spec.rb
32
+ spec/hunk_spec.rb
32
33
  spec/issues_spec.rb
33
34
  spec/lcs_spec.rb
34
35
  spec/patch_spec.rb
@@ -11,9 +11,9 @@ Diff::LCS computes the difference between two Enumerable sequences using the
11
11
  McIlroy-Hunt longest common subsequence (LCS) algorithm. It includes utilities
12
12
  to create a simple HTML diff output format and a standard diff-like tool.
13
13
 
14
- This is release 1.2.1, restoring the public API to what existed in Diff::LCS
15
- 1.1.x. Everyone is strongly encouraged to upgrade to this version as it fixes
16
- all known outstanding issues.
14
+ This is release 1.2.2, fixing a bug that prevented comparison of values that
15
+ are not US-ASCII-compatible. Thanks to Jon Rowe for finding and providing most
16
+ of the work behind this issue. This is a recommended release.
17
17
 
18
18
  == Synopsis
19
19
 
@@ -1,7 +1,7 @@
1
1
  # -*- ruby encoding: utf-8 -*-
2
2
 
3
3
  module Diff; end unless defined? Diff
4
- # = Diff::LCS 1.2.1
4
+ # = Diff::LCS 1.2.2
5
5
  #
6
6
  # Computes "intelligent" differences between two sequenced Enumerables. This
7
7
  # is an implementation of the McIlroy-Hunt "diff" algorithm for Enumerable
@@ -129,7 +129,7 @@ module Diff; end unless defined? Diff
129
129
  # Common Subsequences</em>, CACM, vol.20, no.5, pp.350-353, May
130
130
  # 1977, with a few minor improvements to improve the speed."
131
131
  module Diff::LCS
132
- VERSION = '1.2.1'
132
+ VERSION = '1.2.2'
133
133
  end
134
134
 
135
135
  require 'diff/lcs/callbacks'
@@ -11,6 +11,9 @@ class Diff::LCS::Hunk
11
11
  def initialize(data_old, data_new, piece, flag_context, file_length_difference)
12
12
  # At first, a hunk will have just one Block in it
13
13
  @blocks = [ Diff::LCS::Block.new(piece) ]
14
+ if String.method_defined?(:encoding)
15
+ @preferred_data_encoding = data_old[0].encoding
16
+ end
14
17
  @data_old = data_old
15
18
  @data_new = data_new
16
19
 
@@ -120,19 +123,19 @@ class Diff::LCS::Hunk
120
123
  # Calculate item number range. Old diff range is just like a context
121
124
  # diff range, except the ranges are on one line with the action between
122
125
  # them.
123
- s = "#{context_range(:old)}#{op_act[block.op]}#{context_range(:new)}\n"
126
+ s = encode("#{context_range(:old)}#{op_act[block.op]}#{context_range(:new)}\n")
124
127
  # If removing anything, just print out all the remove lines in the hunk
125
128
  # which is just all the remove lines in the block.
126
- @data_old[@start_old .. @end_old].each { |e| s << "< #{e}\n" } unless block.remove.empty?
127
- s << "---\n" if block.op == "!"
128
- @data_new[@start_new .. @end_new].each { |e| s << "> #{e}\n" } unless block.insert.empty?
129
+ @data_old[@start_old .. @end_old].each { |e| s << encode("< ") + e + encode("\n") } unless block.remove.empty?
130
+ s << encode("---\n") if block.op == "!"
131
+ @data_new[@start_new .. @end_new].each { |e| s << encode("> ") + e + encode("\n") } unless block.insert.empty?
129
132
  s
130
133
  end
131
134
  private :old_diff
132
135
 
133
136
  def unified_diff
134
137
  # Calculate item number range.
135
- s = "@@ -#{unified_range(:old)} +#{unified_range(:new)} @@\n"
138
+ s = encode("@@ -#{unified_range(:old)} +#{unified_range(:new)} @@\n")
136
139
 
137
140
  # Outlist starts containing the hunk of the old file. Removing an item
138
141
  # just means putting a '-' in front of it. Inserting an item requires
@@ -145,30 +148,30 @@ class Diff::LCS::Hunk
145
148
  # file -- don't take removed items into account.
146
149
  lo, hi, num_added, num_removed = @start_old, @end_old, 0, 0
147
150
 
148
- outlist = @data_old[lo .. hi].collect { |e| e.gsub(/^/, ' ') }
151
+ outlist = @data_old[lo .. hi].map { |e| e.insert(0, encode(' ')) }
149
152
 
150
153
  @blocks.each do |block|
151
154
  block.remove.each do |item|
152
- op = item.action.to_s # -
155
+ op = item.action.to_s # -
153
156
  offset = item.position - lo + num_added
154
- outlist[offset].gsub!(/^ /, op.to_s)
157
+ outlist[offset][0, 1] = encode(op)
155
158
  num_removed += 1
156
159
  end
157
160
  block.insert.each do |item|
158
- op = item.action.to_s # +
161
+ op = item.action.to_s # +
159
162
  offset = item.position - @start_new + num_removed
160
- outlist[offset, 0] = "#{op}#{@data_new[item.position]}"
163
+ outlist[offset, 0] = encode(op) + @data_new[item.position]
161
164
  num_added += 1
162
165
  end
163
166
  end
164
167
 
165
- s << outlist.join("\n")
168
+ s << outlist.join(encode("\n"))
166
169
  end
167
170
  private :unified_diff
168
171
 
169
172
  def context_diff
170
- s = "***************\n"
171
- s << "*** #{context_range(:old)} ****\n"
173
+ s = encode("***************\n")
174
+ s << encode("*** #{context_range(:old)} ****\n")
172
175
  r = context_range(:new)
173
176
 
174
177
  # Print out file 1 part for each block in context diff format if there
@@ -176,23 +179,24 @@ class Diff::LCS::Hunk
176
179
  lo, hi = @start_old, @end_old
177
180
  removes = @blocks.select { |e| not e.remove.empty? }
178
181
  if removes
179
- outlist = @data_old[lo .. hi].collect { |e| e.gsub(/^/, ' ') }
182
+ outlist = @data_old[lo .. hi].map { |e| e.insert(0, encode(' ')) }
183
+
180
184
  removes.each do |block|
181
185
  block.remove.each do |item|
182
- outlist[item.position - lo].gsub!(/^ /) { block.op } # - or !
186
+ outlist[item.position - lo][0, 1] = encode(block.op) # - or !
183
187
  end
184
188
  end
185
189
  s << outlist.join("\n")
186
190
  end
187
191
 
188
- s << "\n--- #{r} ----\n"
192
+ s << encode("\n--- #{r} ----\n")
189
193
  lo, hi = @start_new, @end_new
190
194
  inserts = @blocks.select { |e| not e.insert.empty? }
191
195
  if inserts
192
- outlist = @data_new[lo .. hi].collect { |e| e.gsub(/^/, ' ') }
196
+ outlist = @data_new[lo .. hi].collect { |e| e.insert(0, encode(' ')) }
193
197
  inserts.each do |block|
194
198
  block.insert.each do |item|
195
- outlist[item.position - lo].gsub!(/^ /) { block.op } # + or !
199
+ outlist[item.position - lo][0, 1] = encode(block.op) # + or !
196
200
  end
197
201
  end
198
202
  s << outlist.join("\n")
@@ -206,14 +210,14 @@ class Diff::LCS::Hunk
206
210
  warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1
207
211
 
208
212
  if format == :reverse_ed
209
- s = "#{op_act[@blocks[0].op]}#{context_range(:old)}\n"
213
+ s = encode("#{op_act[@blocks[0].op]}#{context_range(:old)}\n")
210
214
  else
211
- s = "#{context_range(:old).gsub(/,/, ' ')}#{op_act[@blocks[0].op]}\n"
215
+ s = encode("#{context_range(:old, ' ')}#{op_act[@blocks[0].op]}\n")
212
216
  end
213
217
 
214
218
  unless @blocks[0].insert.empty?
215
- @data_new[@start_new .. @end_new].each { |e| s << "#{e}\n" }
216
- s << ".\n"
219
+ @data_new[@start_new .. @end_new].each { |e| s << e + encode("\n") }
220
+ s << encode(".\n")
217
221
  end
218
222
  s
219
223
  end
@@ -221,7 +225,7 @@ class Diff::LCS::Hunk
221
225
 
222
226
  # Generate a range of item numbers to print. Only print 1 number if the
223
227
  # range has only one item in it. Otherwise, it's 'start,end'
224
- def context_range(mode)
228
+ def context_range(mode, op = ',')
225
229
  case mode
226
230
  when :old
227
231
  s, e = (@start_old + 1), (@end_old + 1)
@@ -229,7 +233,7 @@ class Diff::LCS::Hunk
229
233
  s, e = (@start_new + 1), (@end_new + 1)
230
234
  end
231
235
 
232
- (s < e) ? "#{s},#{e}" : "#{e}"
236
+ (s < e) ? "#{s}#{op}#{e}" : "#{e}"
233
237
  end
234
238
  private :context_range
235
239
 
@@ -249,4 +253,24 @@ class Diff::LCS::Hunk
249
253
  (length == 1) ? "#{first}" : "#{first},#{length}"
250
254
  end
251
255
  private :unified_range
256
+
257
+ if String.method_defined?(:encoding)
258
+ def encode(literal, target_encoding = @preferred_data_encoding)
259
+ literal.encode target_encoding
260
+ end
261
+
262
+ def encode_as(string, *args)
263
+ args.map { |arg| arg.encode(string.encoding) }
264
+ end
265
+ else
266
+ def encode(literal, target_encoding = nil)
267
+ literal
268
+ end
269
+ def encode_as(string, *args)
270
+ args
271
+ end
272
+ end
273
+
274
+ private :encode
275
+ private :encode_as
252
276
  end
@@ -0,0 +1,63 @@
1
+ # -*- ruby encoding: utf-8 -*-
2
+
3
+ require 'spec_helper'
4
+
5
+ def h(v)
6
+ v.to_s.bytes.to_a.map { |e| "%02x" % e }.join
7
+ end
8
+
9
+ describe "Diff::LCS::Hunk" do
10
+ if String.method_defined?(:encoding)
11
+
12
+ let(:old_data) { ["Tu avec carté {count} itém has".encode('UTF-16LE')] }
13
+ let(:new_data) { ["Tu avec carte {count} item has".encode('UTF-16LE')] }
14
+ let(:pieces) { Diff::LCS.diff old_data, new_data }
15
+ let(:hunk) { Diff::LCS::Hunk.new(old_data, new_data, pieces[0], 3, 0) }
16
+
17
+ it 'should be able to produce a unified diff from the two pieces' do
18
+ expected =
19
+ (<<-EOD.encode('UTF-16LE').chomp)
20
+ @@ -1,2 +1,2 @@
21
+ -Tu avec carté {count} itém has
22
+ +Tu avec carte {count} item has
23
+ EOD
24
+ expect(hunk.diff(:unified).to_s == expected).to eql true
25
+ end
26
+
27
+ it 'should be able to produce a context diff from the two pieces' do
28
+ expected =
29
+ (<<-EOD.encode('UTF-16LE').chomp)
30
+ ***************
31
+ *** 1,2 ****
32
+ !Tu avec carté {count} itém has
33
+ --- 1,2 ----
34
+ !Tu avec carte {count} item has
35
+ EOD
36
+
37
+ expect(hunk.diff(:context).to_s == expected).to eql true
38
+ end
39
+
40
+ it 'should be able to produce an old diff from the two pieces' do
41
+ expected =
42
+ (<<-EOD.encode('UTF-16LE').chomp)
43
+ 1,2c1,2
44
+ < Tu avec carté {count} itém has
45
+ ---
46
+ > Tu avec carte {count} item has
47
+
48
+ EOD
49
+ expect(hunk.diff(:old).to_s == expected).to eql true
50
+ end
51
+
52
+ it 'should be able to produce a reverse ed diff from the two pieces' do
53
+ expected =
54
+ (<<-EOD.encode('UTF-16LE').chomp)
55
+ c1,2
56
+ Tu avec carte {count} item has
57
+ .
58
+
59
+ EOD
60
+ expect(hunk.diff(:reverse_ed).to_s == expected).to eql true
61
+ end
62
+ end
63
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: diff-lcs
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 1.2.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -50,7 +50,7 @@ cert_chain:
50
50
  -----END CERTIFICATE-----
51
51
 
52
52
  '
53
- date: 2013-02-09 00:00:00.000000000 Z
53
+ date: 2013-03-30 00:00:00.000000000 Z
54
54
  dependencies:
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rubyforge
@@ -236,11 +236,11 @@ description: ! 'Diff::LCS computes the difference between two Enumerable sequenc
236
236
  to create a simple HTML diff output format and a standard diff-like tool.
237
237
 
238
238
 
239
- This is release 1.2.1, restoring the public API to what existed in Diff::LCS
239
+ This is release 1.2.2, fixing a bug that prevented comparison of values that
240
240
 
241
- 1.1.x. Everyone is strongly encouraged to upgrade to this version as it fixes
241
+ are not US-ASCII-compatible. Thanks to Jon Rowe for finding and providing most
242
242
 
243
- all known outstanding issues.'
243
+ of the work behind this issue. This is a recommended release.'
244
244
  email:
245
245
  - austin@rubyforge.org
246
246
  executables:
@@ -287,6 +287,7 @@ files:
287
287
  - lib/diff/lcs/string.rb
288
288
  - spec/change_spec.rb
289
289
  - spec/diff_spec.rb
290
+ - spec/hunk_spec.rb
290
291
  - spec/issues_spec.rb
291
292
  - spec/lcs_spec.rb
292
293
  - spec/patch_spec.rb
metadata.gz.sig CHANGED
Binary file