diff-lcs 1.6.2 → 2.0.0.beta.2
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 +65 -4
- data/CONTRIBUTING.md +91 -35
- data/CONTRIBUTORS.md +19 -9
- data/LICENCE.md +39 -11
- data/Manifest.txt +91 -83
- data/README.md +13 -9
- 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 +199 -110
- 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
data/lib/diff/lcs/change.rb
CHANGED
|
@@ -1,53 +1,52 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
# enumerable.
|
|
6
|
-
class Diff::LCS::Change
|
|
7
|
-
IntClass = 1.class # Fixnum is deprecated in Ruby 2.4 # standard:disable Naming/ConstantName
|
|
3
|
+
Diff::LCS::Change = Data.define(:action, :position, :element) # :nodoc:
|
|
4
|
+
Diff::LCS::ContextChange = Data.define(:action, :old_position, :old_element, :new_position, :new_element) # :nodoc:
|
|
8
5
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
#
|
|
13
|
-
|
|
6
|
+
# Represents a simplistic (non-contextual) change. Represents the removal or addition of
|
|
7
|
+
# an element from either the old or the new sequenced enumerable.
|
|
8
|
+
class Diff::LCS::Change
|
|
9
|
+
# The only actions valid for changes are '+' (add), '-' (delete), '=' (no change), '!'
|
|
10
|
+
# (changed), '<' (tail changes from first sequence), or '>' (tail changes from second
|
|
11
|
+
# sequence). The last two ('<>') are only found with Diff::LCS::diff and
|
|
12
|
+
# Diff::LCS::sdiff.
|
|
13
|
+
VALID_ACTIONS = %w[= - + ! > <].freeze
|
|
14
14
|
|
|
15
|
-
def self.valid_action?(action)
|
|
16
|
-
VALID_ACTIONS.include? action
|
|
17
|
-
end
|
|
15
|
+
def self.valid_action?(action) = VALID_ACTIONS.include?(action)
|
|
18
16
|
|
|
17
|
+
##
|
|
19
18
|
# Returns the action this Change represents.
|
|
20
|
-
attr_reader
|
|
19
|
+
# :attr_reader: action
|
|
21
20
|
|
|
21
|
+
##
|
|
22
22
|
# Returns the position of the Change.
|
|
23
|
-
attr_reader
|
|
23
|
+
# :attr_reader: position
|
|
24
|
+
|
|
25
|
+
##
|
|
24
26
|
# Returns the sequence element of the Change.
|
|
25
|
-
attr_reader
|
|
27
|
+
# :attr_reader: element
|
|
26
28
|
|
|
27
|
-
def initialize(
|
|
28
|
-
|
|
29
|
+
def initialize(action:, position:, element:)
|
|
30
|
+
fail "Invalid Change Action '#{action}'" unless Diff::LCS::Change.valid_action?(action)
|
|
31
|
+
fail "Invalid Position Type" unless position.is_a?(Integer)
|
|
29
32
|
|
|
30
|
-
|
|
31
|
-
fail "Invalid Position Type" unless @position.is_a? IntClass
|
|
33
|
+
super
|
|
32
34
|
end
|
|
33
35
|
|
|
34
|
-
def inspect(*_args)
|
|
35
|
-
"#<#{self.class}: #{to_a.inspect}>"
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def to_a
|
|
39
|
-
[@action, @position, @element]
|
|
40
|
-
end
|
|
36
|
+
def inspect(*_args) = "#<#{self.class}: #{to_a.inspect}>"
|
|
41
37
|
|
|
38
|
+
def to_a = [action, position, element]
|
|
42
39
|
alias_method :to_ary, :to_a
|
|
40
|
+
alias_method :deconstruct, :to_a
|
|
41
|
+
|
|
42
|
+
def deconstruct_keys(_) = {action:, position:, element:}
|
|
43
43
|
|
|
44
44
|
def self.from_a(arr)
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
Diff::LCS::Change.new(*arr[0...3])
|
|
45
|
+
case arr
|
|
46
|
+
in [action, [old_position, old_element], [new_position, new_element]]
|
|
47
|
+
Diff::LCS::ContextChange[action, old_position, old_element, new_position, new_element]
|
|
48
|
+
in [action, position, element]
|
|
49
|
+
new(action, position, element)
|
|
51
50
|
else
|
|
52
51
|
fail "Invalid change array format provided."
|
|
53
52
|
end
|
|
@@ -63,112 +62,111 @@ class Diff::LCS::Change
|
|
|
63
62
|
end
|
|
64
63
|
|
|
65
64
|
def <=>(other)
|
|
66
|
-
r =
|
|
67
|
-
r =
|
|
65
|
+
r = position <=> other.position
|
|
66
|
+
r = VALID_ACTIONS.index(action) <=> VALID_ACTIONS.index(other.action) if r.zero?
|
|
68
67
|
r = element <=> other.element if r.zero?
|
|
69
68
|
r
|
|
70
69
|
end
|
|
71
70
|
|
|
72
|
-
def adding?
|
|
73
|
-
@action == "+"
|
|
74
|
-
end
|
|
71
|
+
def adding? = action == "+"
|
|
75
72
|
|
|
76
|
-
def deleting?
|
|
77
|
-
@action == "-"
|
|
78
|
-
end
|
|
73
|
+
def deleting? = action == "-"
|
|
79
74
|
|
|
80
|
-
def unchanged?
|
|
81
|
-
@action == "="
|
|
82
|
-
end
|
|
75
|
+
def unchanged? = action == "="
|
|
83
76
|
|
|
84
|
-
def changed?
|
|
85
|
-
@action == "!"
|
|
86
|
-
end
|
|
77
|
+
def changed? = action == "!"
|
|
87
78
|
|
|
88
|
-
def finished_a?
|
|
89
|
-
@action == ">"
|
|
90
|
-
end
|
|
79
|
+
def finished_a? = action == ">"
|
|
91
80
|
|
|
92
|
-
def finished_b?
|
|
93
|
-
@action == "<"
|
|
94
|
-
end
|
|
81
|
+
def finished_b? = action == "<"
|
|
95
82
|
end
|
|
96
83
|
|
|
97
|
-
# Represents a contextual change. Contains the position and values of the
|
|
98
|
-
#
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
#
|
|
102
|
-
|
|
103
|
-
undef :element
|
|
84
|
+
# Represents a contextual change. Contains the position and values of the elements in the
|
|
85
|
+
# old and the new sequenced enumerable values as well as the action taken.
|
|
86
|
+
class Diff::LCS::ContextChange
|
|
87
|
+
##
|
|
88
|
+
# Returns the action this Change represents.
|
|
89
|
+
# :attr_reader: action
|
|
104
90
|
|
|
91
|
+
##
|
|
105
92
|
# Returns the old position being changed.
|
|
106
|
-
attr_reader
|
|
93
|
+
# :attr_reader: old_position
|
|
94
|
+
|
|
95
|
+
##
|
|
107
96
|
# Returns the new position being changed.
|
|
108
|
-
attr_reader
|
|
97
|
+
# :attr_reader: new_position
|
|
98
|
+
|
|
99
|
+
##
|
|
109
100
|
# Returns the old element being changed.
|
|
110
|
-
attr_reader
|
|
111
|
-
# Returns the new element being changed.
|
|
112
|
-
attr_reader :new_element
|
|
101
|
+
# :attr_reader: old_element
|
|
113
102
|
|
|
114
|
-
|
|
115
|
-
|
|
103
|
+
##
|
|
104
|
+
# Returns the new element being changed.
|
|
105
|
+
# :attr_reader: new_element
|
|
116
106
|
|
|
117
|
-
|
|
118
|
-
fail "Invalid
|
|
119
|
-
fail "Invalid (
|
|
120
|
-
|
|
107
|
+
def initialize(action:, old_position:, old_element:, new_position:, new_element:)
|
|
108
|
+
fail "Invalid Change Action '#{action}'" unless Diff::LCS::Change.valid_action?(action)
|
|
109
|
+
fail "Invalid (Old) Position Type" unless old_position.nil? || old_position.is_a?(Integer)
|
|
110
|
+
fail "Invalid (New) Position Type" unless new_position.nil? || new_position.is_a?(Integer)
|
|
121
111
|
|
|
122
|
-
|
|
123
|
-
[
|
|
124
|
-
@action,
|
|
125
|
-
[@old_position, @old_element],
|
|
126
|
-
[@new_position, @new_element]
|
|
127
|
-
]
|
|
112
|
+
super
|
|
128
113
|
end
|
|
129
114
|
|
|
115
|
+
def to_a = [action, [old_position, old_element], [new_position, new_element]]
|
|
130
116
|
alias_method :to_ary, :to_a
|
|
117
|
+
alias_method :deconstruct, :to_a
|
|
131
118
|
|
|
132
|
-
def
|
|
133
|
-
Diff::LCS::Change.from_a(arr)
|
|
134
|
-
end
|
|
119
|
+
def deconstruct_keys(_) = {action:, old_position:, old_element:, new_position:, new_element:}
|
|
135
120
|
|
|
136
|
-
|
|
137
|
-
# are converted to '-' and '>' actions are converted to '+'.
|
|
138
|
-
def self.simplify(event)
|
|
139
|
-
ea = event.to_a
|
|
121
|
+
def self.from_a(arr) = Diff::LCS::Change.from_a(arr)
|
|
140
122
|
|
|
141
|
-
|
|
123
|
+
# Simplifies a context change for use in some diff callbacks. '<' actions are converted
|
|
124
|
+
# to '-' and '>' actions are converted to '+'.
|
|
125
|
+
def self.simplify(event)
|
|
126
|
+
case event.action
|
|
142
127
|
when "-"
|
|
143
|
-
|
|
128
|
+
event.with(new_element: nil)
|
|
144
129
|
when "<"
|
|
145
|
-
|
|
146
|
-
ea[2][1] = nil
|
|
130
|
+
event.with(action: "-", new_element: nil)
|
|
147
131
|
when "+"
|
|
148
|
-
|
|
132
|
+
event.with(old_element: nil)
|
|
149
133
|
when ">"
|
|
150
|
-
|
|
151
|
-
|
|
134
|
+
event.with(action: "+", old_element: nil)
|
|
135
|
+
else
|
|
136
|
+
event
|
|
152
137
|
end
|
|
153
|
-
|
|
154
|
-
Diff::LCS::ContextChange.from_a(ea)
|
|
155
138
|
end
|
|
156
139
|
|
|
157
140
|
def ==(other)
|
|
158
|
-
(self.class == other.class)
|
|
159
|
-
(
|
|
160
|
-
(
|
|
161
|
-
(
|
|
162
|
-
(
|
|
163
|
-
(
|
|
141
|
+
(self.class == other.class) &&
|
|
142
|
+
(action == other.action) &&
|
|
143
|
+
(old_position == other.old_position) &&
|
|
144
|
+
(new_position == other.new_position) &&
|
|
145
|
+
(old_element == other.old_element) &&
|
|
146
|
+
(new_element == other.new_element)
|
|
164
147
|
end
|
|
165
148
|
|
|
166
149
|
def <=>(other)
|
|
167
|
-
r =
|
|
168
|
-
r =
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
150
|
+
r = old_position <=> other.old_position
|
|
151
|
+
r = new_position <=> other.new_position if r.zero?
|
|
152
|
+
if r.zero?
|
|
153
|
+
r = Diff::LCS::Change::VALID_ACTIONS.index(action) <=>
|
|
154
|
+
Diff::LCS::Change::VALID_ACTIONS.index(other.action)
|
|
155
|
+
end
|
|
156
|
+
r = old_element <=> other.old_element if r.zero?
|
|
157
|
+
r = new_element <=> other.new_element if r.zero?
|
|
172
158
|
r
|
|
173
159
|
end
|
|
160
|
+
|
|
161
|
+
def adding? = action == "+"
|
|
162
|
+
|
|
163
|
+
def deleting? = action == "-"
|
|
164
|
+
|
|
165
|
+
def unchanged? = action == "="
|
|
166
|
+
|
|
167
|
+
def changed? = action == "!"
|
|
168
|
+
|
|
169
|
+
def finished_a? = action == ">"
|
|
170
|
+
|
|
171
|
+
def finished_b? = action == "<"
|
|
174
172
|
end
|