diff-lcs 1.4.1 → 1.5.0
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.
- checksums.yaml +4 -4
- data/Contributing.md +84 -49
- data/History.md +246 -93
- data/Manifest.txt +15 -1
- data/README.rdoc +9 -8
- data/Rakefile +84 -3
- data/lib/diff/lcs/backports.rb +1 -1
- data/lib/diff/lcs/block.rb +1 -1
- data/lib/diff/lcs/hunk.rb +118 -48
- data/lib/diff/lcs/internals.rb +7 -3
- data/lib/diff/lcs/ldiff.rb +16 -20
- data/lib/diff/lcs.rb +32 -25
- data/spec/fixtures/ldiff/output.diff-c +2 -2
- data/spec/fixtures/ldiff/output.diff-u +2 -2
- data/spec/fixtures/ldiff/output.diff.chef +4 -0
- data/spec/fixtures/ldiff/output.diff.chef-c +15 -0
- data/spec/fixtures/ldiff/output.diff.chef-e +3 -0
- data/spec/fixtures/ldiff/output.diff.chef-f +3 -0
- data/spec/fixtures/ldiff/output.diff.chef-u +9 -0
- data/spec/fixtures/ldiff/output.diff.chef2 +7 -0
- data/spec/fixtures/ldiff/output.diff.chef2-c +20 -0
- data/spec/fixtures/ldiff/output.diff.chef2-d +7 -0
- data/spec/fixtures/ldiff/output.diff.chef2-e +7 -0
- data/spec/fixtures/ldiff/output.diff.chef2-f +7 -0
- data/spec/fixtures/ldiff/output.diff.chef2-u +16 -0
- data/spec/fixtures/new-chef +4 -0
- data/spec/fixtures/new-chef2 +17 -0
- data/spec/fixtures/old-chef +4 -0
- data/spec/fixtures/old-chef2 +14 -0
- data/spec/hunk_spec.rb +21 -10
- data/spec/issues_spec.rb +90 -3
- data/spec/ldiff_spec.rb +44 -31
- data/spec/spec_helper.rb +26 -25
- data/spec/traverse_sequences_spec.rb +2 -4
- metadata +36 -15
- data/autotest/discover.rb +0 -3
data/lib/diff/lcs.rb
CHANGED
@@ -49,7 +49,7 @@ module Diff; end unless defined? Diff # rubocop:disable Style/Documentation
|
|
49
49
|
# a x b y c z p d q
|
50
50
|
# a b c a x b y c z
|
51
51
|
module Diff::LCS
|
52
|
-
VERSION = '1.
|
52
|
+
VERSION = '1.5.0'
|
53
53
|
end
|
54
54
|
|
55
55
|
require 'diff/lcs/callbacks'
|
@@ -60,6 +60,13 @@ module Diff::LCS # rubocop:disable Style/Documentation
|
|
60
60
|
# +self+ and +other+. See Diff::LCS#lcs.
|
61
61
|
#
|
62
62
|
# lcs = seq1.lcs(seq2)
|
63
|
+
#
|
64
|
+
# A note when using objects: Diff::LCS only works properly when each object
|
65
|
+
# can be used as a key in a Hash, which typically means that the objects must
|
66
|
+
# implement Object#eql? in a way that two identical values compare
|
67
|
+
# identically for key purposes. That is:
|
68
|
+
#
|
69
|
+
# O.new('a').eql?(O.new('a')) == true
|
63
70
|
def lcs(other, &block) #:yields self[i] if there are matched subsequences:
|
64
71
|
Diff::LCS.lcs(self, other, &block)
|
65
72
|
end
|
@@ -78,14 +85,14 @@ module Diff::LCS # rubocop:disable Style/Documentation
|
|
78
85
|
# Traverses the discovered longest common subsequences between +self+ and
|
79
86
|
# +other+. See Diff::LCS#traverse_sequences.
|
80
87
|
def traverse_sequences(other, callbacks = nil, &block)
|
81
|
-
traverse_sequences(self, other, callbacks || Diff::LCS::SequenceCallbacks, &block)
|
88
|
+
Diff::LCS.traverse_sequences(self, other, callbacks || Diff::LCS::SequenceCallbacks, &block)
|
82
89
|
end
|
83
90
|
|
84
91
|
# Traverses the discovered longest common subsequences between +self+ and
|
85
92
|
# +other+ using the alternate, balanced algorithm. See
|
86
93
|
# Diff::LCS#traverse_balanced.
|
87
94
|
def traverse_balanced(other, callbacks = nil, &block)
|
88
|
-
traverse_balanced(self, other, callbacks || Diff::LCS::BalancedCallbacks, &block)
|
95
|
+
Diff::LCS.traverse_balanced(self, other, callbacks || Diff::LCS::BalancedCallbacks, &block)
|
89
96
|
end
|
90
97
|
|
91
98
|
# Attempts to patch +self+ with the provided +patchset+. A new sequence based
|
@@ -243,8 +250,9 @@ class << Diff::LCS
|
|
243
250
|
# advance that arrow and will call <tt>callbacks#discard_a</tt> or
|
244
251
|
# <tt>callbacks#discard_b</tt>, depending on which arrow it advanced. If both
|
245
252
|
# arrows point to elements that are not part of the longest common
|
246
|
-
# subsequence, then #traverse_sequences will advance
|
247
|
-
# appropriate callback,
|
253
|
+
# subsequence, then #traverse_sequences will advance arrow +a+ and call the
|
254
|
+
# appropriate callback, then it will advance arrow +b+ and call the appropriate
|
255
|
+
# callback.
|
248
256
|
#
|
249
257
|
# The methods for <tt>callbacks#match</tt>, <tt>callbacks#discard_a</tt>, and
|
250
258
|
# <tt>callbacks#discard_b</tt> are invoked with an event comprising the
|
@@ -285,37 +293,36 @@ class << Diff::LCS
|
|
285
293
|
b_size = seq2.size
|
286
294
|
ai = bj = 0
|
287
295
|
|
288
|
-
|
289
|
-
b_line = matches[i]
|
290
|
-
|
291
|
-
ax = string ? seq1[i, 1] : seq1[i]
|
292
|
-
bx = string ? seq2[bj, 1] : seq2[bj]
|
293
|
-
|
296
|
+
matches.each do |b_line|
|
294
297
|
if b_line.nil?
|
295
|
-
unless
|
296
|
-
|
298
|
+
unless seq1[ai].nil?
|
299
|
+
ax = string ? seq1[ai, 1] : seq1[ai]
|
300
|
+
bx = string ? seq2[bj, 1] : seq2[bj]
|
301
|
+
|
302
|
+
event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
|
297
303
|
event = yield event if block_given?
|
298
304
|
callbacks.discard_a(event)
|
299
305
|
end
|
300
306
|
else
|
307
|
+
ax = string ? seq1[ai, 1] : seq1[ai]
|
308
|
+
|
301
309
|
loop do
|
302
310
|
break unless bj < b_line
|
303
311
|
|
304
312
|
bx = string ? seq2[bj, 1] : seq2[bj]
|
305
|
-
event = Diff::LCS::ContextChange.new('+',
|
313
|
+
event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
|
306
314
|
event = yield event if block_given?
|
307
315
|
callbacks.discard_b(event)
|
308
316
|
bj += 1
|
309
317
|
end
|
310
318
|
bx = string ? seq2[bj, 1] : seq2[bj]
|
311
|
-
event = Diff::LCS::ContextChange.new('=',
|
319
|
+
event = Diff::LCS::ContextChange.new('=', ai, ax, bj, bx)
|
312
320
|
event = yield event if block_given?
|
313
321
|
callbacks.match(event)
|
314
322
|
bj += 1
|
315
323
|
end
|
316
|
-
ai
|
324
|
+
ai += 1
|
317
325
|
end
|
318
|
-
ai += 1
|
319
326
|
|
320
327
|
# The last entry (if any) processed was a match. +ai+ and +bj+ point just
|
321
328
|
# past the last matching lines in their sequences.
|
@@ -373,14 +380,14 @@ class << Diff::LCS
|
|
373
380
|
ai += 1
|
374
381
|
end
|
375
382
|
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
383
|
+
if bj < b_size
|
384
|
+
ax = string ? seq1[ai, 1] : seq1[ai]
|
385
|
+
bx = string ? seq2[bj, 1] : seq2[bj]
|
386
|
+
event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
|
387
|
+
event = yield event if block_given?
|
388
|
+
callbacks.discard_b(event)
|
389
|
+
bj += 1
|
390
|
+
end
|
384
391
|
end
|
385
392
|
end
|
386
393
|
|
@@ -1,5 +1,5 @@
|
|
1
|
-
*** spec/fixtures/aX
|
2
|
-
--- spec/fixtures/bXaX
|
1
|
+
*** spec/fixtures/aX 2020-06-23 11:15:32.000000000 -0400
|
2
|
+
--- spec/fixtures/bXaX 2020-06-23 11:15:32.000000000 -0400
|
3
3
|
***************
|
4
4
|
*** 1 ****
|
5
5
|
! aX
|
@@ -0,0 +1,15 @@
|
|
1
|
+
*** spec/fixtures/old-chef 2020-06-23 23:18:20.000000000 -0400
|
2
|
+
--- spec/fixtures/new-chef 2020-06-23 23:18:20.000000000 -0400
|
3
|
+
***************
|
4
|
+
*** 1,4 ****
|
5
|
+
{
|
6
|
+
"name": "x",
|
7
|
+
! "description": "hi"
|
8
|
+
}
|
9
|
+
|
10
|
+
--- 1,4 ----
|
11
|
+
{
|
12
|
+
"name": "x",
|
13
|
+
! "description": "lo"
|
14
|
+
}
|
15
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
*** spec/fixtures/old-chef2 2020-06-30 09:43:35.000000000 -0400
|
2
|
+
--- spec/fixtures/new-chef2 2020-06-30 09:44:32.000000000 -0400
|
3
|
+
***************
|
4
|
+
*** 1,5 ****
|
5
|
+
recipe[a::default]
|
6
|
+
- recipe[b::default]
|
7
|
+
recipe[c::default]
|
8
|
+
recipe[d::default]
|
9
|
+
recipe[e::default]
|
10
|
+
--- 1,4 ----
|
11
|
+
***************
|
12
|
+
*** 12,14 ****
|
13
|
+
--- 11,17 ----
|
14
|
+
recipe[l::default]
|
15
|
+
recipe[m::default]
|
16
|
+
recipe[n::default]
|
17
|
+
+ recipe[o::new]
|
18
|
+
+ recipe[p::new]
|
19
|
+
+ recipe[q::new]
|
20
|
+
+ recipe[r::new]
|
@@ -0,0 +1,16 @@
|
|
1
|
+
--- spec/fixtures/old-chef2 2020-06-30 09:43:35.000000000 -0400
|
2
|
+
+++ spec/fixtures/new-chef2 2020-06-30 09:44:32.000000000 -0400
|
3
|
+
@@ -1,5 +1,4 @@
|
4
|
+
recipe[a::default]
|
5
|
+
-recipe[b::default]
|
6
|
+
recipe[c::default]
|
7
|
+
recipe[d::default]
|
8
|
+
recipe[e::default]
|
9
|
+
@@ -12,3 +11,7 @@
|
10
|
+
recipe[l::default]
|
11
|
+
recipe[m::default]
|
12
|
+
recipe[n::default]
|
13
|
+
+recipe[o::new]
|
14
|
+
+recipe[p::new]
|
15
|
+
+recipe[q::new]
|
16
|
+
+recipe[r::new]
|
@@ -0,0 +1,17 @@
|
|
1
|
+
recipe[a::default]
|
2
|
+
recipe[c::default]
|
3
|
+
recipe[d::default]
|
4
|
+
recipe[e::default]
|
5
|
+
recipe[f::default]
|
6
|
+
recipe[g::default]
|
7
|
+
recipe[h::default]
|
8
|
+
recipe[i::default]
|
9
|
+
recipe[j::default]
|
10
|
+
recipe[k::default]
|
11
|
+
recipe[l::default]
|
12
|
+
recipe[m::default]
|
13
|
+
recipe[n::default]
|
14
|
+
recipe[o::new]
|
15
|
+
recipe[p::new]
|
16
|
+
recipe[q::new]
|
17
|
+
recipe[r::new]
|
@@ -0,0 +1,14 @@
|
|
1
|
+
recipe[a::default]
|
2
|
+
recipe[b::default]
|
3
|
+
recipe[c::default]
|
4
|
+
recipe[d::default]
|
5
|
+
recipe[e::default]
|
6
|
+
recipe[f::default]
|
7
|
+
recipe[g::default]
|
8
|
+
recipe[h::default]
|
9
|
+
recipe[i::default]
|
10
|
+
recipe[j::default]
|
11
|
+
recipe[k::default]
|
12
|
+
recipe[l::default]
|
13
|
+
recipe[m::default]
|
14
|
+
recipe[n::default]
|
data/spec/hunk_spec.rb
CHANGED
@@ -6,28 +6,39 @@ if String.method_defined?(:encoding)
|
|
6
6
|
require 'diff/lcs/hunk'
|
7
7
|
|
8
8
|
describe Diff::LCS::Hunk do
|
9
|
-
let(:old_data) { ['Tu
|
10
|
-
let(:new_data) { ['Tu
|
9
|
+
let(:old_data) { ['Tu a un carté avec {count} itéms'.encode('UTF-16LE')] }
|
10
|
+
let(:new_data) { ['Tu a un carte avec {count} items'.encode('UTF-16LE')] }
|
11
11
|
let(:pieces) { Diff::LCS.diff old_data, new_data }
|
12
12
|
let(:hunk) { Diff::LCS::Hunk.new(old_data, new_data, pieces[0], 3, 0) }
|
13
13
|
|
14
14
|
it 'produces a unified diff from the two pieces' do
|
15
15
|
expected = <<-EXPECTED.gsub(/^\s+/, '').encode('UTF-16LE').chomp
|
16
16
|
@@ -1 +1 @@
|
17
|
-
-Tu
|
18
|
-
+Tu
|
17
|
+
-Tu a un carté avec {count} itéms
|
18
|
+
+Tu a un carte avec {count} items
|
19
19
|
EXPECTED
|
20
20
|
|
21
21
|
expect(hunk.diff(:unified)).to eq(expected)
|
22
22
|
end
|
23
23
|
|
24
|
+
it 'produces a unified diff from the two pieces (last entry)' do
|
25
|
+
expected = <<-EXPECTED.gsub(/^\s+/, '').encode('UTF-16LE').chomp
|
26
|
+
@@ -1 +1 @@
|
27
|
+
-Tu a un carté avec {count} itéms
|
28
|
+
+Tu a un carte avec {count} items
|
29
|
+
\
|
30
|
+
EXPECTED
|
31
|
+
|
32
|
+
expect(hunk.diff(:unified, true)).to eq(expected)
|
33
|
+
end
|
34
|
+
|
24
35
|
it 'produces a context diff from the two pieces' do
|
25
36
|
expected = <<-EXPECTED.gsub(/^\s+/, '').encode('UTF-16LE').chomp
|
26
37
|
***************
|
27
38
|
*** 1 ****
|
28
|
-
! Tu
|
39
|
+
! Tu a un carté avec {count} itéms
|
29
40
|
--- 1 ----
|
30
|
-
! Tu
|
41
|
+
! Tu a un carte avec {count} items
|
31
42
|
EXPECTED
|
32
43
|
|
33
44
|
expect(hunk.diff(:context)).to eq(expected)
|
@@ -36,9 +47,9 @@ if String.method_defined?(:encoding)
|
|
36
47
|
it 'produces an old diff from the two pieces' do
|
37
48
|
expected = <<-EXPECTED.gsub(/^ +/, '').encode('UTF-16LE').chomp
|
38
49
|
1c1
|
39
|
-
< Tu
|
50
|
+
< Tu a un carté avec {count} itéms
|
40
51
|
---
|
41
|
-
> Tu
|
52
|
+
> Tu a un carte avec {count} items
|
42
53
|
|
43
54
|
EXPECTED
|
44
55
|
|
@@ -48,7 +59,7 @@ if String.method_defined?(:encoding)
|
|
48
59
|
it 'produces a reverse ed diff from the two pieces' do
|
49
60
|
expected = <<-EXPECTED.gsub(/^ +/, '').encode('UTF-16LE').chomp
|
50
61
|
c1
|
51
|
-
Tu
|
62
|
+
Tu a un carte avec {count} items
|
52
63
|
.
|
53
64
|
|
54
65
|
EXPECTED
|
@@ -62,7 +73,7 @@ if String.method_defined?(:encoding)
|
|
62
73
|
it 'produces a unified diff' do
|
63
74
|
expected = <<-EXPECTED.gsub(/^\s+/, '').encode('UTF-16LE').chomp
|
64
75
|
@@ -1 +1,2 @@
|
65
|
-
+Tu
|
76
|
+
+Tu a un carte avec {count} items
|
66
77
|
EXPECTED
|
67
78
|
|
68
79
|
expect(hunk.diff(:unified)).to eq(expected)
|
data/spec/issues_spec.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
|
+
require 'diff/lcs/hunk'
|
4
5
|
|
5
6
|
describe 'Diff::LCS Issues' do
|
6
7
|
include Diff::LCS::SpecHelper::Matchers
|
@@ -55,13 +56,99 @@ describe 'Diff::LCS Issues' do
|
|
55
56
|
end
|
56
57
|
end
|
57
58
|
|
58
|
-
describe
|
59
|
+
describe 'issue #57' do
|
59
60
|
it 'should fail with a correct error' do
|
60
61
|
expect {
|
61
|
-
actual = {:category=>
|
62
|
-
expected = {:category=>
|
62
|
+
actual = { :category => 'app.rack.request' }
|
63
|
+
expected = { :category => 'rack.middleware', :title => 'Anonymous Middleware' }
|
63
64
|
expect(actual).to eq(expected)
|
64
65
|
}.to raise_error(RSpec::Expectations::ExpectationNotMetError)
|
65
66
|
end
|
66
67
|
end
|
68
|
+
|
69
|
+
describe 'issue #60' do
|
70
|
+
it 'should produce unified output with correct context' do
|
71
|
+
old_data = <<-DATA_OLD.strip.split("\n").map(&:chomp)
|
72
|
+
{
|
73
|
+
"name": "x",
|
74
|
+
"description": "hi"
|
75
|
+
}
|
76
|
+
DATA_OLD
|
77
|
+
|
78
|
+
new_data = <<-DATA_NEW.strip.split("\n").map(&:chomp)
|
79
|
+
{
|
80
|
+
"name": "x",
|
81
|
+
"description": "lo"
|
82
|
+
}
|
83
|
+
DATA_NEW
|
84
|
+
|
85
|
+
diff = ::Diff::LCS.diff(old_data, new_data)
|
86
|
+
hunk = ::Diff::LCS::Hunk.new(old_data, new_data, diff.first, 3, 0)
|
87
|
+
|
88
|
+
expect(hunk.diff(:unified)).to eq(<<-EXPECTED.chomp)
|
89
|
+
@@ -1,5 +1,5 @@
|
90
|
+
{
|
91
|
+
"name": "x",
|
92
|
+
- "description": "hi"
|
93
|
+
+ "description": "lo"
|
94
|
+
}
|
95
|
+
EXPECTED
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe 'issue #65' do
|
100
|
+
def diff_lines(old_lines, new_lines)
|
101
|
+
file_length_difference = 0
|
102
|
+
previous_hunk = nil
|
103
|
+
output = []
|
104
|
+
|
105
|
+
Diff::LCS.diff(old_lines, new_lines).each do |piece|
|
106
|
+
hunk = Diff::LCS::Hunk.new(old_lines, new_lines, piece, 3, file_length_difference)
|
107
|
+
file_length_difference = hunk.file_length_difference
|
108
|
+
maybe_contiguous_hunks = (previous_hunk.nil? || hunk.merge(previous_hunk))
|
109
|
+
|
110
|
+
output << "#{previous_hunk.diff(:unified)}\n" unless maybe_contiguous_hunks
|
111
|
+
|
112
|
+
previous_hunk = hunk
|
113
|
+
end
|
114
|
+
output << "#{previous_hunk.diff(:unified, true)}\n" unless previous_hunk.nil?
|
115
|
+
output.join
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'should not misplace the new chunk' do
|
119
|
+
old_data = [
|
120
|
+
'recipe[a::default]', 'recipe[b::default]', 'recipe[c::default]',
|
121
|
+
'recipe[d::default]', 'recipe[e::default]', 'recipe[f::default]',
|
122
|
+
'recipe[g::default]', 'recipe[h::default]', 'recipe[i::default]',
|
123
|
+
'recipe[j::default]', 'recipe[k::default]', 'recipe[l::default]',
|
124
|
+
'recipe[m::default]', 'recipe[n::default]'
|
125
|
+
]
|
126
|
+
|
127
|
+
new_data = [
|
128
|
+
'recipe[a::default]', 'recipe[c::default]', 'recipe[d::default]',
|
129
|
+
'recipe[e::default]', 'recipe[f::default]', 'recipe[g::default]',
|
130
|
+
'recipe[h::default]', 'recipe[i::default]', 'recipe[j::default]',
|
131
|
+
'recipe[k::default]', 'recipe[l::default]', 'recipe[m::default]',
|
132
|
+
'recipe[n::default]', 'recipe[o::new]', 'recipe[p::new]',
|
133
|
+
'recipe[q::new]', 'recipe[r::new]'
|
134
|
+
]
|
135
|
+
|
136
|
+
expect(diff_lines(old_data, new_data)).to eq(<<-EODIFF)
|
137
|
+
@@ -1,5 +1,4 @@
|
138
|
+
recipe[a::default]
|
139
|
+
-recipe[b::default]
|
140
|
+
recipe[c::default]
|
141
|
+
recipe[d::default]
|
142
|
+
recipe[e::default]
|
143
|
+
@@ -12,3 +11,7 @@
|
144
|
+
recipe[l::default]
|
145
|
+
recipe[m::default]
|
146
|
+
recipe[n::default]
|
147
|
+
+recipe[o::new]
|
148
|
+
+recipe[p::new]
|
149
|
+
+recipe[q::new]
|
150
|
+
+recipe[r::new]
|
151
|
+
EODIFF
|
152
|
+
end
|
153
|
+
end
|
67
154
|
end
|
data/spec/ldiff_spec.rb
CHANGED
@@ -5,34 +5,41 @@ require 'spec_helper'
|
|
5
5
|
RSpec.describe 'bin/ldiff' do
|
6
6
|
include CaptureSubprocessIO
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
fixtures = [
|
9
|
+
{ :name => 'output.diff', :left => 'aX', :right => 'bXaX' },
|
10
|
+
{ :name => 'output.diff.chef', :left => 'old-chef', :right => 'new-chef' },
|
11
|
+
{ :name => 'output.diff.chef2', :left => 'old-chef2', :right => 'new-chef2' }
|
12
|
+
].product([nil, '-e', '-f', '-c', '-u']).map { |(fixture, flag)|
|
13
|
+
fixture = fixture.dup
|
14
|
+
fixture[:flag] = flag
|
15
|
+
fixture
|
16
|
+
}
|
13
17
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
expect(run_ldiff('-e')).to eq(output_diff_e)
|
24
|
-
end
|
18
|
+
def self.test_ldiff(fixture)
|
19
|
+
desc = [
|
20
|
+
fixture[:flag],
|
21
|
+
"spec/fixtures/#{fixture[:left]}",
|
22
|
+
"spec/fixtures/#{fixture[:right]}",
|
23
|
+
'#',
|
24
|
+
'=>',
|
25
|
+
"spec/fixtures/ldiff/#{fixture[:name]}#{fixture[:flag]}"
|
26
|
+
].join(' ')
|
25
27
|
|
26
|
-
|
27
|
-
|
28
|
+
it desc do
|
29
|
+
expect(run_ldiff(fixture)).to eq(read_fixture(fixture))
|
30
|
+
end
|
28
31
|
end
|
29
32
|
|
30
|
-
|
31
|
-
|
33
|
+
fixtures.each do |fixture|
|
34
|
+
test_ldiff(fixture)
|
32
35
|
end
|
33
36
|
|
34
|
-
def read_fixture(
|
35
|
-
|
37
|
+
def read_fixture(options)
|
38
|
+
fixture = options.fetch(:name)
|
39
|
+
flag = options.fetch(:flag)
|
40
|
+
name = "spec/fixtures/ldiff/#{fixture}#{flag}"
|
41
|
+
data = IO.__send__(IO.respond_to?(:binread) ? :binread : :read, name)
|
42
|
+
clean_data(data, flag)
|
36
43
|
end
|
37
44
|
|
38
45
|
def clean_data(data, flag)
|
@@ -49,25 +56,31 @@ RSpec.describe 'bin/ldiff' do
|
|
49
56
|
def clean_output_timestamp(data)
|
50
57
|
data.gsub(
|
51
58
|
%r{
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
\
|
59
|
+
^
|
60
|
+
[-+*]{3}
|
61
|
+
\s*
|
62
|
+
spec/fixtures/(\S+)
|
63
|
+
\s*
|
56
64
|
\d{4}-\d\d-\d\d
|
57
|
-
\s
|
65
|
+
\s*
|
58
66
|
\d\d:\d\d:\d\d(?:\.\d+)
|
59
|
-
\s
|
67
|
+
\s*
|
60
68
|
(?:[-+]\d{4}|Z)
|
61
69
|
}x,
|
62
|
-
'*** spec/fixtures/\1 0000-00-00
|
70
|
+
'*** spec/fixtures/\1 0000-00-00 :00 =>:00 =>00.000000000 -0000'
|
63
71
|
)
|
64
72
|
end
|
65
73
|
|
66
|
-
def run_ldiff(
|
74
|
+
def run_ldiff(options)
|
75
|
+
flag = options.fetch(:flag)
|
76
|
+
left = options.fetch(:left)
|
77
|
+
right = options.fetch(:right)
|
78
|
+
|
67
79
|
stdout, stderr = capture_subprocess_io do
|
68
80
|
system("ruby -Ilib bin/ldiff #{flag} spec/fixtures/#{left} spec/fixtures/#{right}")
|
69
81
|
end
|
70
|
-
|
82
|
+
|
83
|
+
expect(stderr).to be_empty if RUBY_VERSION >= '1.9'
|
71
84
|
expect(stdout).not_to be_empty
|
72
85
|
clean_data(stdout, flag)
|
73
86
|
end
|