diff-lcs 1.6.2 → 2.0.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 +67 -4
- data/CODE_OF_CONDUCT.md +152 -114
- data/CONTRIBUTING.md +91 -35
- data/CONTRIBUTORS.md +19 -9
- data/LICENCE.md +39 -11
- data/Manifest.txt +91 -83
- data/README.md +30 -17
- data/Rakefile +99 -73
- data/SECURITY.md +22 -27
- data/integration/compare/array_diff_spec.rb +10 -0
- data/integration/compare/hash_diff_spec.rb +25 -0
- data/integration/compare/string_diff_spec.rb +10 -0
- data/integration/rspec_differ_spec.rb +26 -0
- data/integration/rspec_expectations_spec.rb +32 -0
- data/integration/runner +20 -0
- data/lib/diff/lcs/block.rb +29 -24
- data/lib/diff/lcs/callbacks.rb +240 -242
- data/lib/diff/lcs/change.rb +102 -104
- data/lib/diff/lcs/hunk.rb +92 -155
- data/lib/diff/lcs/internals.rb +92 -96
- data/lib/diff/lcs/ldiff.rb +30 -38
- data/lib/diff/lcs/version.rb +1 -1
- data/lib/diff/lcs.rb +439 -466
- data/licenses/dco.txt +34 -0
- data/spec/hunk_spec.rb +32 -45
- data/spec/lcs_spec.rb +6 -6
- data/spec/ldiff_spec.rb +8 -8
- data/spec/spec_helper.rb +17 -27
- data/test/fixtures/ldiff/output.diff-c +7 -0
- data/test/fixtures/ldiff/output.diff-u +5 -0
- data/test/fixtures/ldiff/output.diff.bin2 +1 -0
- data/test/fixtures/ldiff/output.diff.bin2-c +1 -0
- data/test/fixtures/ldiff/output.diff.bin2-e +1 -0
- data/test/fixtures/ldiff/output.diff.bin2-f +1 -0
- data/test/fixtures/ldiff/output.diff.bin2-u +1 -0
- data/{spec → test}/fixtures/ldiff/output.diff.chef-c +2 -2
- data/test/fixtures/ldiff/output.diff.chef-u +9 -0
- data/{spec → test}/fixtures/ldiff/output.diff.chef2-c +2 -2
- data/{spec → test}/fixtures/ldiff/output.diff.chef2-u +2 -2
- data/test/fixtures/ldiff/output.diff.empty.vs.four_lines-c +9 -0
- data/test/fixtures/ldiff/output.diff.empty.vs.four_lines-u +7 -0
- data/test/fixtures/ldiff/output.diff.four_lines.vs.empty-c +9 -0
- data/test/fixtures/ldiff/output.diff.four_lines.vs.empty-u +7 -0
- data/test/fixtures/ldiff/output.diff.issue95_trailing_context-c +9 -0
- data/test/fixtures/ldiff/output.diff.issue95_trailing_context-u +6 -0
- data/{spec → test}/fixtures/ldiff/output.diff.missing_new_line1-c +2 -2
- data/test/fixtures/ldiff/output.diff.missing_new_line1-u +9 -0
- data/{spec → test}/fixtures/ldiff/output.diff.missing_new_line2-c +2 -2
- data/test/fixtures/ldiff/output.diff.missing_new_line2-u +9 -0
- data/test/test_block.rb +34 -0
- data/test/test_change.rb +234 -0
- data/test/test_diff.rb +53 -0
- data/test/test_helper.rb +225 -0
- data/test/test_hunk.rb +72 -0
- data/test/test_issues.rb +168 -0
- data/test/test_lcs.rb +47 -0
- data/test/test_ldiff.rb +89 -0
- data/test/test_patch.rb +362 -0
- data/test/test_sdiff.rb +167 -0
- data/test/test_traverse_balanced.rb +322 -0
- data/test/test_traverse_sequences.rb +187 -0
- metadata +205 -119
- data/.rspec +0 -1
- data/bin/htmldiff +0 -35
- data/lib/diff/lcs/backports.rb +0 -13
- data/lib/diff/lcs/htmldiff.rb +0 -160
- data/mise.toml +0 -5
- data/spec/fixtures/ldiff/output.diff-c +0 -7
- data/spec/fixtures/ldiff/output.diff-e +0 -3
- data/spec/fixtures/ldiff/output.diff-f +0 -3
- data/spec/fixtures/ldiff/output.diff-u +0 -5
- data/spec/fixtures/ldiff/output.diff.bin2 +0 -1
- data/spec/fixtures/ldiff/output.diff.bin2-c +0 -1
- data/spec/fixtures/ldiff/output.diff.bin2-e +0 -1
- data/spec/fixtures/ldiff/output.diff.bin2-f +0 -1
- data/spec/fixtures/ldiff/output.diff.bin2-u +0 -1
- data/spec/fixtures/ldiff/output.diff.chef-e +0 -3
- data/spec/fixtures/ldiff/output.diff.chef-f +0 -3
- data/spec/fixtures/ldiff/output.diff.chef-u +0 -9
- data/spec/fixtures/ldiff/output.diff.chef2-e +0 -7
- data/spec/fixtures/ldiff/output.diff.chef2-f +0 -7
- data/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-c +0 -9
- data/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-u +0 -7
- data/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-c +0 -9
- data/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-u +0 -7
- data/spec/fixtures/ldiff/output.diff.issue95_trailing_context-c +0 -9
- data/spec/fixtures/ldiff/output.diff.issue95_trailing_context-u +0 -6
- data/spec/fixtures/ldiff/output.diff.missing_new_line1-u +0 -9
- data/spec/fixtures/ldiff/output.diff.missing_new_line2-u +0 -9
- /data/{docs → licenses}/COPYING.txt +0 -0
- /data/{docs → licenses}/artistic.txt +0 -0
- /data/{spec → test}/fixtures/123_x +0 -0
- /data/{spec → test}/fixtures/456_x +0 -0
- /data/{spec → test}/fixtures/aX +0 -0
- /data/{spec → test}/fixtures/bXaX +0 -0
- /data/{spec → test}/fixtures/ds1.csv +0 -0
- /data/{spec → test}/fixtures/ds2.csv +0 -0
- /data/{spec → test}/fixtures/empty +0 -0
- /data/{spec → test}/fixtures/file1.bin +0 -0
- /data/{spec → test}/fixtures/file2.bin +0 -0
- /data/{spec → test}/fixtures/four_lines +0 -0
- /data/{spec → test}/fixtures/four_lines_with_missing_new_line +0 -0
- /data/{spec → test}/fixtures/ldiff/diff.missing_new_line1-e +0 -0
- /data/{spec → test}/fixtures/ldiff/diff.missing_new_line1-f +0 -0
- /data/{spec → test}/fixtures/ldiff/diff.missing_new_line2-e +0 -0
- /data/{spec → test}/fixtures/ldiff/diff.missing_new_line2-f +0 -0
- /data/{spec → test}/fixtures/ldiff/error.diff.chef-e +0 -0
- /data/{spec → test}/fixtures/ldiff/error.diff.chef-f +0 -0
- /data/{spec → test}/fixtures/ldiff/error.diff.missing_new_line1-e +0 -0
- /data/{spec → test}/fixtures/ldiff/error.diff.missing_new_line1-f +0 -0
- /data/{spec → test}/fixtures/ldiff/error.diff.missing_new_line2-e +0 -0
- /data/{spec → test}/fixtures/ldiff/error.diff.missing_new_line2-f +0 -0
- /data/{spec → test}/fixtures/ldiff/output.diff +0 -0
- /data/{spec → test}/fixtures/ldiff/output.diff.bin1 +0 -0
- /data/{spec → test}/fixtures/ldiff/output.diff.bin1-c +0 -0
- /data/{spec → test}/fixtures/ldiff/output.diff.bin1-e +0 -0
- /data/{spec → test}/fixtures/ldiff/output.diff.bin1-f +0 -0
- /data/{spec → test}/fixtures/ldiff/output.diff.bin1-u +0 -0
- /data/{spec → test}/fixtures/ldiff/output.diff.chef +0 -0
- /data/{spec → test}/fixtures/ldiff/output.diff.chef2 +0 -0
- /data/{spec → test}/fixtures/ldiff/output.diff.chef2-d +0 -0
- /data/{spec → test}/fixtures/ldiff/output.diff.empty.vs.four_lines +0 -0
- /data/{spec → test}/fixtures/ldiff/output.diff.empty.vs.four_lines-e +0 -0
- /data/{spec → test}/fixtures/ldiff/output.diff.empty.vs.four_lines-f +0 -0
- /data/{spec → test}/fixtures/ldiff/output.diff.four_lines.vs.empty +0 -0
- /data/{spec → test}/fixtures/ldiff/output.diff.four_lines.vs.empty-e +0 -0
- /data/{spec → test}/fixtures/ldiff/output.diff.four_lines.vs.empty-f +0 -0
- /data/{spec → test}/fixtures/ldiff/output.diff.issue95_trailing_context +0 -0
- /data/{spec → test}/fixtures/ldiff/output.diff.issue95_trailing_context-e +0 -0
- /data/{spec → test}/fixtures/ldiff/output.diff.issue95_trailing_context-f +0 -0
- /data/{spec → test}/fixtures/ldiff/output.diff.missing_new_line1 +0 -0
- /data/{spec → test}/fixtures/ldiff/output.diff.missing_new_line1-e +0 -0
- /data/{spec → test}/fixtures/ldiff/output.diff.missing_new_line1-f +0 -0
- /data/{spec → test}/fixtures/ldiff/output.diff.missing_new_line2 +0 -0
- /data/{spec → test}/fixtures/ldiff/output.diff.missing_new_line2-e +0 -0
- /data/{spec → test}/fixtures/ldiff/output.diff.missing_new_line2-f +0 -0
- /data/{spec → test}/fixtures/new-chef +0 -0
- /data/{spec → test}/fixtures/new-chef2 +0 -0
- /data/{spec → test}/fixtures/old-chef +0 -0
- /data/{spec → test}/fixtures/old-chef2 +0 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Integration test to verify diff-lcs 2.0 works with RSpec's differ
|
|
4
|
+
# This runs RSpec with diff-lcs 1.x installed but loads the repo version
|
|
5
|
+
|
|
6
|
+
RSpec.describe "Diff::LCS 2.0 with RSpec::Support::Differ" do
|
|
7
|
+
let(:differ) { RSpec::Support::Differ.new }
|
|
8
|
+
|
|
9
|
+
it "produces diff output for multiline strings" do
|
|
10
|
+
expected = "foo\nzap\nbar\n"
|
|
11
|
+
actual = "foo\nbar\nzap\n"
|
|
12
|
+
|
|
13
|
+
diff = differ.diff(actual, expected)
|
|
14
|
+
|
|
15
|
+
expect(diff).to be_a(String)
|
|
16
|
+
expect(diff).not_to be_empty
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "handles identical strings" do
|
|
20
|
+
str = "same\n"
|
|
21
|
+
diff = differ.diff(str, str)
|
|
22
|
+
|
|
23
|
+
# May return empty or just newline depending on implementation
|
|
24
|
+
expect(diff.strip).to be_empty
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Integration test for RSpec expectation failures that use diff-lcs
|
|
4
|
+
# Verifies that diff output is generated correctly with diff-lcs 2.0
|
|
5
|
+
|
|
6
|
+
RSpec.describe "Diff::LCS 2.0 with RSpec expectations" do
|
|
7
|
+
it "produces diff for failed multiline string equality" do
|
|
8
|
+
expect {
|
|
9
|
+
expect("foo\nbar\nbaz").to eq("foo\nqux\nbaz")
|
|
10
|
+
}.to raise_error(RSpec::Expectations::ExpectationNotMetError) do |error|
|
|
11
|
+
expect(error.message).to include("Diff:")
|
|
12
|
+
expect(error.message).to match(/[-+](qux|bar)/)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "produces diff for failed hash equality" do
|
|
17
|
+
expect {
|
|
18
|
+
expect({a: 1, b: 2}).to eq({a: 1, b: 3})
|
|
19
|
+
}.to raise_error(RSpec::Expectations::ExpectationNotMetError) do |error|
|
|
20
|
+
expect(error.message).to include("Diff:")
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "does not crash when comparing complex objects" do
|
|
25
|
+
obj1 = {a: [1, 2, 3], b: "test"}
|
|
26
|
+
obj2 = {a: [1, 4, 3], b: "test"}
|
|
27
|
+
|
|
28
|
+
expect {
|
|
29
|
+
expect(obj1).to eq(obj2)
|
|
30
|
+
}.to raise_error(RSpec::Expectations::ExpectationNotMetError)
|
|
31
|
+
end
|
|
32
|
+
end
|
data/integration/runner
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require "rbconfig"
|
|
4
|
+
require "rubygems"
|
|
5
|
+
|
|
6
|
+
if ENV["CI"]
|
|
7
|
+
vendor_dir = Dir.glob(File.join(Dir.pwd, "vendor", "bundle", "{ruby,jruby,truffleruby}", "*")).max
|
|
8
|
+
unless vendor_dir && Dir.exist?(vendor_dir)
|
|
9
|
+
fail "vendor bundle not found; expected vendor/bundle/ruby/*"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Prefer vendored gems, fall back to system gem dir
|
|
13
|
+
ENV["GEM_HOME"] = vendor_dir
|
|
14
|
+
ENV["GEM_PATH"] = "#{vendor_dir}:#{Gem.default_dir}"
|
|
15
|
+
|
|
16
|
+
# Ensure Gem.path is updated for the running process (affects Gem.lookup)
|
|
17
|
+
Gem.use_paths(ENV["GEM_HOME"], ENV["GEM_PATH"].split(":"))
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
exec RbConfig.ruby, "-S", *ARGV
|
data/lib/diff/lcs/block.rb
CHANGED
|
@@ -1,37 +1,42 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
# Basically, this is just a list of changes, where each change adds or
|
|
5
|
-
# deletes a single item. Used by bin/ldiff.
|
|
6
|
-
class Diff::LCS::Block
|
|
7
|
-
attr_reader :changes, :insert, :remove
|
|
3
|
+
Diff::LCS::Block = Data.define(:changes, :insert, :remove) # :nodoc:
|
|
8
4
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
# A block is an operation removing, adding, or changing a group of items, a list of
|
|
6
|
+
# changes, where each change adds or deletes a single item.
|
|
7
|
+
#
|
|
8
|
+
# Used by bin/ldiff.
|
|
9
|
+
class Diff::LCS::Block
|
|
10
|
+
def self.from_chunk(chunk)
|
|
11
|
+
changes, insert, remove = [], [], []
|
|
13
12
|
|
|
14
|
-
chunk.each do
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
chunk.each do
|
|
14
|
+
changes << _1
|
|
15
|
+
remove << _1 if _1.deleting?
|
|
16
|
+
insert << _1 if _1.adding?
|
|
18
17
|
end
|
|
18
|
+
|
|
19
|
+
new(changes: changes.freeze, remove: remove.freeze, insert: insert.freeze)
|
|
19
20
|
end
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
class << self
|
|
23
|
+
private :new, :[]
|
|
23
24
|
end
|
|
24
25
|
|
|
26
|
+
private :with
|
|
27
|
+
|
|
28
|
+
def diff_size = insert.size - remove.size
|
|
29
|
+
|
|
25
30
|
def op
|
|
26
|
-
case [
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
case [remove, insert]
|
|
32
|
+
# Unchanged
|
|
33
|
+
in [[], []] then "^"
|
|
34
|
+
# Delete
|
|
35
|
+
in [_, []] then "-"
|
|
36
|
+
# Insert
|
|
37
|
+
in [[], _] then "+"
|
|
38
|
+
# Conflict
|
|
39
|
+
in [_, _] then "!"
|
|
35
40
|
end
|
|
36
41
|
end
|
|
37
42
|
end
|