diff-lcs 1.5.0 → 1.6.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/CHANGELOG.md +491 -0
- data/CODE_OF_CONDUCT.md +128 -0
- data/CONTRIBUTING.md +74 -0
- data/CONTRIBUTORS.md +48 -0
- data/Contributing.md +45 -90
- data/{License.md → LICENCE.md} +6 -4
- data/Manifest.txt +7 -4
- data/README.md +92 -0
- data/Rakefile +43 -66
- data/SECURITY.md +41 -0
- data/bin/htmldiff +4 -4
- data/docs/artistic.txt +1 -1
- data/lib/diff/lcs/array.rb +1 -1
- data/lib/diff/lcs/backports.rb +2 -2
- data/lib/diff/lcs/block.rb +4 -4
- data/lib/diff/lcs/callbacks.rb +9 -7
- data/lib/diff/lcs/change.rb +20 -20
- data/lib/diff/lcs/htmldiff.rb +26 -16
- data/lib/diff/lcs/hunk.rb +66 -45
- data/lib/diff/lcs/internals.rb +17 -17
- data/lib/diff/lcs/ldiff.rb +86 -74
- data/lib/diff/lcs.rb +66 -63
- data/lib/diff-lcs.rb +1 -1
- data/spec/change_spec.rb +50 -50
- data/spec/diff_spec.rb +14 -14
- data/spec/hunk_spec.rb +20 -20
- data/spec/issues_spec.rb +76 -70
- data/spec/lcs_spec.rb +11 -11
- data/spec/ldiff_spec.rb +30 -17
- data/spec/patch_spec.rb +84 -84
- data/spec/sdiff_spec.rb +111 -109
- data/spec/spec_helper.rb +76 -74
- data/spec/traverse_balanced_spec.rb +191 -189
- data/spec/traverse_sequences_spec.rb +31 -31
- metadata +55 -30
- data/Code-of-Conduct.md +0 -74
- data/History.md +0 -400
- data/README.rdoc +0 -84
data/spec/hunk_spec.rb
CHANGED
@@ -1,18 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "spec_helper"
|
4
4
|
|
5
5
|
if String.method_defined?(:encoding)
|
6
|
-
require
|
6
|
+
require "diff/lcs/hunk"
|
7
7
|
|
8
8
|
describe Diff::LCS::Hunk do
|
9
|
-
let(:old_data) { [
|
10
|
-
let(:new_data) { [
|
11
|
-
let(:pieces)
|
12
|
-
let(:hunk)
|
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
|
+
let(:pieces) { Diff::LCS.diff old_data, new_data }
|
12
|
+
let(:hunk) { Diff::LCS::Hunk.new(old_data, new_data, pieces[0], 3, 0) }
|
13
13
|
|
14
|
-
it
|
15
|
-
expected = <<-EXPECTED.gsub(/^\s+/,
|
14
|
+
it "produces a unified diff from the two pieces" do
|
15
|
+
expected = <<-EXPECTED.gsub(/^\s+/, "").encode("UTF-16LE").chomp
|
16
16
|
@@ -1 +1 @@
|
17
17
|
-Tu a un carté avec {count} itéms
|
18
18
|
+Tu a un carte avec {count} items
|
@@ -21,8 +21,8 @@ if String.method_defined?(:encoding)
|
|
21
21
|
expect(hunk.diff(:unified)).to eq(expected)
|
22
22
|
end
|
23
23
|
|
24
|
-
it
|
25
|
-
expected = <<-EXPECTED.gsub(/^\s+/,
|
24
|
+
it "produces a unified diff from the two pieces (last entry)" do
|
25
|
+
expected = <<-EXPECTED.gsub(/^\s+/, "").encode("UTF-16LE").chomp
|
26
26
|
@@ -1 +1 @@
|
27
27
|
-Tu a un carté avec {count} itéms
|
28
28
|
+Tu a un carte avec {count} items
|
@@ -32,8 +32,8 @@ if String.method_defined?(:encoding)
|
|
32
32
|
expect(hunk.diff(:unified, true)).to eq(expected)
|
33
33
|
end
|
34
34
|
|
35
|
-
it
|
36
|
-
expected = <<-EXPECTED.gsub(/^\s+/,
|
35
|
+
it "produces a context diff from the two pieces" do
|
36
|
+
expected = <<-EXPECTED.gsub(/^\s+/, "").encode("UTF-16LE").chomp
|
37
37
|
***************
|
38
38
|
*** 1 ****
|
39
39
|
! Tu a un carté avec {count} itéms
|
@@ -44,8 +44,8 @@ if String.method_defined?(:encoding)
|
|
44
44
|
expect(hunk.diff(:context)).to eq(expected)
|
45
45
|
end
|
46
46
|
|
47
|
-
it
|
48
|
-
expected = <<-EXPECTED.gsub(/^ +/,
|
47
|
+
it "produces an old diff from the two pieces" do
|
48
|
+
expected = <<-EXPECTED.gsub(/^ +/, "").encode("UTF-16LE").chomp
|
49
49
|
1c1
|
50
50
|
< Tu a un carté avec {count} itéms
|
51
51
|
---
|
@@ -56,8 +56,8 @@ if String.method_defined?(:encoding)
|
|
56
56
|
expect(hunk.diff(:old)).to eq(expected)
|
57
57
|
end
|
58
58
|
|
59
|
-
it
|
60
|
-
expected = <<-EXPECTED.gsub(/^ +/,
|
59
|
+
it "produces a reverse ed diff from the two pieces" do
|
60
|
+
expected = <<-EXPECTED.gsub(/^ +/, "").encode("UTF-16LE").chomp
|
61
61
|
c1
|
62
62
|
Tu a un carte avec {count} items
|
63
63
|
.
|
@@ -67,12 +67,12 @@ if String.method_defined?(:encoding)
|
|
67
67
|
expect(hunk.diff(:reverse_ed)).to eq(expected)
|
68
68
|
end
|
69
69
|
|
70
|
-
context
|
70
|
+
context "with empty first data set" do
|
71
71
|
let(:old_data) { [] }
|
72
72
|
|
73
|
-
it
|
74
|
-
expected = <<-EXPECTED.gsub(/^\s+/,
|
75
|
-
@@ -
|
73
|
+
it "produces a unified diff" do
|
74
|
+
expected = <<-EXPECTED.gsub(/^\s+/, "").encode("UTF-16LE").chomp
|
75
|
+
@@ -0,0 +1 @@
|
76
76
|
+Tu a un carte avec {count} items
|
77
77
|
EXPECTED
|
78
78
|
|
data/spec/issues_spec.rb
CHANGED
@@ -1,102 +1,74 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "spec_helper"
|
4
|
+
require "diff/lcs/hunk"
|
5
5
|
|
6
|
-
describe
|
6
|
+
describe "Diff::LCS Issues" do
|
7
7
|
include Diff::LCS::SpecHelper::Matchers
|
8
8
|
|
9
|
-
describe
|
10
|
-
shared_examples
|
9
|
+
describe "issue #1" do
|
10
|
+
shared_examples "handles simple diffs" do |s1, s2, forward_diff|
|
11
11
|
before do
|
12
12
|
@diff_s1_s2 = Diff::LCS.diff(s1, s2)
|
13
13
|
end
|
14
14
|
|
15
|
-
it
|
15
|
+
it "creates the correct diff" do
|
16
16
|
expect(change_diff(forward_diff)).to eq(@diff_s1_s2)
|
17
17
|
end
|
18
18
|
|
19
|
-
it
|
19
|
+
it "creates the correct patch s1->s2" do
|
20
20
|
expect(Diff::LCS.patch(s1, @diff_s1_s2)).to eq(s2)
|
21
21
|
end
|
22
22
|
|
23
|
-
it
|
23
|
+
it "creates the correct patch s2->s1" do
|
24
24
|
expect(Diff::LCS.patch(s2, @diff_s1_s2)).to eq(s1)
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
-
describe
|
29
|
-
it_has_behavior
|
28
|
+
describe "string" do
|
29
|
+
it_has_behavior "handles simple diffs", "aX", "bXaX", [
|
30
30
|
[
|
31
|
-
[
|
32
|
-
[
|
31
|
+
["+", 0, "b"],
|
32
|
+
["+", 1, "X"]
|
33
33
|
]
|
34
34
|
]
|
35
|
-
it_has_behavior
|
35
|
+
it_has_behavior "handles simple diffs", "bXaX", "aX", [
|
36
36
|
[
|
37
|
-
[
|
38
|
-
[
|
37
|
+
["-", 0, "b"],
|
38
|
+
["-", 1, "X"]
|
39
39
|
]
|
40
40
|
]
|
41
41
|
end
|
42
42
|
|
43
|
-
describe
|
44
|
-
it_has_behavior
|
43
|
+
describe "array" do
|
44
|
+
it_has_behavior "handles simple diffs", %w[a X], %w[b X a X], [
|
45
45
|
[
|
46
|
-
[
|
47
|
-
[
|
46
|
+
["+", 0, "b"],
|
47
|
+
["+", 1, "X"]
|
48
48
|
]
|
49
49
|
]
|
50
|
-
it_has_behavior
|
50
|
+
it_has_behavior "handles simple diffs", %w[b X a X], %w[a X], [
|
51
51
|
[
|
52
|
-
[
|
53
|
-
[
|
52
|
+
["-", 0, "b"],
|
53
|
+
["-", 1, "X"]
|
54
54
|
]
|
55
55
|
]
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
|
-
describe
|
60
|
-
it
|
59
|
+
describe "issue #57" do
|
60
|
+
it "should fail with a correct error" do
|
61
|
+
# standard:disable Style/HashSyntax
|
61
62
|
expect {
|
62
|
-
actual = {
|
63
|
-
expected = {
|
63
|
+
actual = {:category => "app.rack.request"}
|
64
|
+
expected = {:category => "rack.middleware", :title => "Anonymous Middleware"}
|
64
65
|
expect(actual).to eq(expected)
|
65
66
|
}.to raise_error(RSpec::Expectations::ExpectationNotMetError)
|
67
|
+
# standard:enable Style/HashSyntax
|
66
68
|
end
|
67
69
|
end
|
68
70
|
|
69
|
-
describe
|
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
|
71
|
+
describe "issue #65" do
|
100
72
|
def diff_lines(old_lines, new_lines)
|
101
73
|
file_length_difference = 0
|
102
74
|
previous_hunk = nil
|
@@ -105,7 +77,7 @@ describe 'Diff::LCS Issues' do
|
|
105
77
|
Diff::LCS.diff(old_lines, new_lines).each do |piece|
|
106
78
|
hunk = Diff::LCS::Hunk.new(old_lines, new_lines, piece, 3, file_length_difference)
|
107
79
|
file_length_difference = hunk.file_length_difference
|
108
|
-
maybe_contiguous_hunks =
|
80
|
+
maybe_contiguous_hunks = previous_hunk.nil? || hunk.merge(previous_hunk)
|
109
81
|
|
110
82
|
output << "#{previous_hunk.diff(:unified)}\n" unless maybe_contiguous_hunks
|
111
83
|
|
@@ -115,24 +87,25 @@ describe 'Diff::LCS Issues' do
|
|
115
87
|
output.join
|
116
88
|
end
|
117
89
|
|
118
|
-
it
|
90
|
+
it "should not misplace the new chunk" do
|
119
91
|
old_data = [
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
92
|
+
"recipe[a::default]", "recipe[b::default]", "recipe[c::default]",
|
93
|
+
"recipe[d::default]", "recipe[e::default]", "recipe[f::default]",
|
94
|
+
"recipe[g::default]", "recipe[h::default]", "recipe[i::default]",
|
95
|
+
"recipe[j::default]", "recipe[k::default]", "recipe[l::default]",
|
96
|
+
"recipe[m::default]", "recipe[n::default]"
|
125
97
|
]
|
126
98
|
|
127
99
|
new_data = [
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
100
|
+
"recipe[a::default]", "recipe[c::default]", "recipe[d::default]",
|
101
|
+
"recipe[e::default]", "recipe[f::default]", "recipe[g::default]",
|
102
|
+
"recipe[h::default]", "recipe[i::default]", "recipe[j::default]",
|
103
|
+
"recipe[k::default]", "recipe[l::default]", "recipe[m::default]",
|
104
|
+
"recipe[n::default]", "recipe[o::new]", "recipe[p::new]",
|
105
|
+
"recipe[q::new]", "recipe[r::new]"
|
134
106
|
]
|
135
107
|
|
108
|
+
# standard:disable Layout/HeredocIndentation
|
136
109
|
expect(diff_lines(old_data, new_data)).to eq(<<-EODIFF)
|
137
110
|
@@ -1,5 +1,4 @@
|
138
111
|
recipe[a::default]
|
@@ -149,6 +122,39 @@ describe 'Diff::LCS Issues' do
|
|
149
122
|
+recipe[q::new]
|
150
123
|
+recipe[r::new]
|
151
124
|
EODIFF
|
125
|
+
# standard:enable Layout/HeredocIndentation
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
describe "issue #107 (replaces issue #60)" do
|
130
|
+
it "should produce unified output with correct context" do
|
131
|
+
# standard:disable Layout/HeredocIndentation
|
132
|
+
old_data = <<-DATA_OLD.strip.split("\n").map(&:chomp)
|
133
|
+
{
|
134
|
+
"name": "x",
|
135
|
+
"description": "hi"
|
136
|
+
}
|
137
|
+
DATA_OLD
|
138
|
+
|
139
|
+
new_data = <<-DATA_NEW.strip.split("\n").map(&:chomp)
|
140
|
+
{
|
141
|
+
"name": "x",
|
142
|
+
"description": "lo"
|
143
|
+
}
|
144
|
+
DATA_NEW
|
145
|
+
|
146
|
+
diff = ::Diff::LCS.diff(old_data, new_data)
|
147
|
+
hunk = ::Diff::LCS::Hunk.new(old_data, new_data, diff.first, 3, 0)
|
148
|
+
|
149
|
+
expect(hunk.diff(:unified)).to eq(<<-EXPECTED.chomp)
|
150
|
+
@@ -1,4 +1,4 @@
|
151
|
+
{
|
152
|
+
"name": "x",
|
153
|
+
- "description": "hi"
|
154
|
+
+ "description": "lo"
|
155
|
+
}
|
156
|
+
EXPECTED
|
157
|
+
# standard:enable Layout/HeredocIndentation
|
152
158
|
end
|
153
159
|
end
|
154
160
|
end
|
data/spec/lcs_spec.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "spec_helper"
|
4
4
|
|
5
|
-
describe Diff::LCS::Internals,
|
5
|
+
describe Diff::LCS::Internals, ".lcs" do
|
6
6
|
include Diff::LCS::SpecHelper::Matchers
|
7
7
|
|
8
|
-
it
|
8
|
+
it "returns a meaningful LCS array with (seq1, seq2)" do
|
9
9
|
res = Diff::LCS::Internals.lcs(seq1, seq2)
|
10
10
|
# The result of the LCS (less the +nil+ values) must be as long as the
|
11
11
|
# correct result.
|
@@ -20,37 +20,37 @@ describe Diff::LCS::Internals, '.lcs' do
|
|
20
20
|
expect(x_seq2).to eq(correct_lcs)
|
21
21
|
end
|
22
22
|
|
23
|
-
it
|
23
|
+
it "returns all indexes with (hello, hello)" do
|
24
24
|
expect(Diff::LCS::Internals.lcs(hello, hello)).to \
|
25
25
|
eq((0...hello.size).to_a)
|
26
26
|
end
|
27
27
|
|
28
|
-
it
|
28
|
+
it "returns all indexes with (hello_ary, hello_ary)" do
|
29
29
|
expect(Diff::LCS::Internals.lcs(hello_ary, hello_ary)).to \
|
30
30
|
eq((0...hello_ary.size).to_a)
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
-
describe Diff::LCS,
|
34
|
+
describe Diff::LCS, ".LCS" do
|
35
35
|
include Diff::LCS::SpecHelper::Matchers
|
36
36
|
|
37
|
-
it
|
37
|
+
it "returns the correct compacted values from Diff::LCS.LCS" do
|
38
38
|
res = Diff::LCS.LCS(seq1, seq2)
|
39
39
|
expect(res).to eq(correct_lcs)
|
40
40
|
expect(res.compact).to eq(res)
|
41
41
|
end
|
42
42
|
|
43
|
-
it
|
43
|
+
it "is transitive" do
|
44
44
|
res = Diff::LCS.LCS(seq2, seq1)
|
45
45
|
expect(res).to eq(correct_lcs)
|
46
46
|
expect(res.compact).to eq(res)
|
47
47
|
end
|
48
48
|
|
49
|
-
it
|
50
|
-
expect(Diff::LCS.LCS(hello, hello)).to eq(hello.
|
49
|
+
it "returns %W(h e l l o) with (hello, hello)" do
|
50
|
+
expect(Diff::LCS.LCS(hello, hello)).to eq(hello.chars)
|
51
51
|
end
|
52
52
|
|
53
|
-
it
|
53
|
+
it "returns hello_ary with (hello_ary, hello_ary)" do
|
54
54
|
expect(Diff::LCS.LCS(hello_ary, hello_ary)).to eq(hello_ary)
|
55
55
|
end
|
56
56
|
end
|
data/spec/ldiff_spec.rb
CHANGED
@@ -1,32 +1,44 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "spec_helper"
|
4
4
|
|
5
|
-
RSpec.describe
|
5
|
+
RSpec.describe "bin/ldiff" do
|
6
6
|
include CaptureSubprocessIO
|
7
7
|
|
8
|
+
# standard:disable Style/HashSyntax
|
8
9
|
fixtures = [
|
9
|
-
{
|
10
|
-
{
|
11
|
-
{
|
12
|
-
|
10
|
+
{:name => "diff", :left => "aX", :right => "bXaX", :diff => 1},
|
11
|
+
{:name => "diff.missing_new_line1", :left => "four_lines", :right => "four_lines_with_missing_new_line", :diff => 1},
|
12
|
+
{:name => "diff.missing_new_line2", :left => "four_lines_with_missing_new_line", :right => "four_lines", :diff => 1},
|
13
|
+
{:name => "diff.issue95_trailing_context", :left => "123_x", :right => "456_x", :diff => 1},
|
14
|
+
{:name => "diff.four_lines.vs.empty", :left => "four_lines", :right => "empty", :diff => 1},
|
15
|
+
{:name => "diff.empty.vs.four_lines", :left => "empty", :right => "four_lines", :diff => 1},
|
16
|
+
{:name => "diff.bin1", :left => "file1.bin", :right => "file1.bin", :diff => 0},
|
17
|
+
{:name => "diff.bin2", :left => "file1.bin", :right => "file2.bin", :diff => 1},
|
18
|
+
{:name => "diff.chef", :left => "old-chef", :right => "new-chef", :diff => 1},
|
19
|
+
{:name => "diff.chef2", :left => "old-chef2", :right => "new-chef2", :diff => 1}
|
20
|
+
].product([nil, "-e", "-f", "-c", "-u"]).map { |(fixture, flag)|
|
13
21
|
fixture = fixture.dup
|
14
22
|
fixture[:flag] = flag
|
15
23
|
fixture
|
16
24
|
}
|
25
|
+
# standard:enable Style/HashSyntax
|
17
26
|
|
18
27
|
def self.test_ldiff(fixture)
|
19
28
|
desc = [
|
20
29
|
fixture[:flag],
|
21
30
|
"spec/fixtures/#{fixture[:left]}",
|
22
31
|
"spec/fixtures/#{fixture[:right]}",
|
23
|
-
|
24
|
-
|
25
|
-
"spec/fixtures/ldiff
|
26
|
-
].join(
|
32
|
+
"#",
|
33
|
+
"=>",
|
34
|
+
"spec/fixtures/ldiff/output.#{fixture[:name]}#{fixture[:flag]}"
|
35
|
+
].join(" ")
|
27
36
|
|
28
37
|
it desc do
|
29
|
-
|
38
|
+
stdout, stderr, status = run_ldiff(fixture)
|
39
|
+
expect(status).to eq(fixture[:diff])
|
40
|
+
expect(stderr).to eq(read_fixture(fixture, mode: "error", allow_missing: true))
|
41
|
+
expect(stdout).to eq(read_fixture(fixture, mode: "output", allow_missing: false))
|
30
42
|
end
|
31
43
|
end
|
32
44
|
|
@@ -34,10 +46,13 @@ RSpec.describe 'bin/ldiff' do
|
|
34
46
|
test_ldiff(fixture)
|
35
47
|
end
|
36
48
|
|
37
|
-
def read_fixture(options)
|
49
|
+
def read_fixture(options, mode: "output", allow_missing: false)
|
38
50
|
fixture = options.fetch(:name)
|
39
51
|
flag = options.fetch(:flag)
|
40
|
-
name = "spec/fixtures/ldiff/#{fixture}#{flag}"
|
52
|
+
name = "spec/fixtures/ldiff/#{mode}.#{fixture}#{flag}"
|
53
|
+
|
54
|
+
return "" if !::File.exist?(name) && allow_missing
|
55
|
+
|
41
56
|
data = IO.__send__(IO.respond_to?(:binread) ? :binread : :read, name)
|
42
57
|
clean_data(data, flag)
|
43
58
|
end
|
@@ -45,7 +60,7 @@ RSpec.describe 'bin/ldiff' do
|
|
45
60
|
def clean_data(data, flag)
|
46
61
|
data =
|
47
62
|
case flag
|
48
|
-
when
|
63
|
+
when "-c", "-u"
|
49
64
|
clean_output_timestamp(data)
|
50
65
|
else
|
51
66
|
data
|
@@ -80,8 +95,6 @@ RSpec.describe 'bin/ldiff' do
|
|
80
95
|
system("ruby -Ilib bin/ldiff #{flag} spec/fixtures/#{left} spec/fixtures/#{right}")
|
81
96
|
end
|
82
97
|
|
83
|
-
|
84
|
-
expect(stdout).not_to be_empty
|
85
|
-
clean_data(stdout, flag)
|
98
|
+
[clean_data(stdout, flag), stderr, $?.exitstatus]
|
86
99
|
end
|
87
100
|
end
|