diff-lcs 2.0.0.beta.1 → 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.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +30 -5
  3. data/CONTRIBUTING.md +8 -3
  4. data/CONTRIBUTORS.md +19 -9
  5. data/Manifest.txt +88 -70
  6. data/README.md +13 -9
  7. data/Rakefile +90 -22
  8. data/SECURITY.md +1 -10
  9. data/integration/compare/array_diff_spec.rb +10 -0
  10. data/integration/compare/hash_diff_spec.rb +25 -0
  11. data/integration/compare/string_diff_spec.rb +10 -0
  12. data/integration/rspec_differ_spec.rb +26 -0
  13. data/integration/rspec_expectations_spec.rb +32 -0
  14. data/integration/runner +20 -0
  15. data/lib/diff/lcs/change.rb +21 -16
  16. data/lib/diff/lcs/ldiff.rb +9 -4
  17. data/lib/diff/lcs/version.rb +1 -1
  18. data/spec/hunk_spec.rb +32 -34
  19. data/spec/ldiff_spec.rb +7 -7
  20. data/spec/spec_helper.rb +4 -12
  21. data/test/fixtures/ldiff/output.diff-c +7 -0
  22. data/test/fixtures/ldiff/output.diff-u +5 -0
  23. data/test/fixtures/ldiff/output.diff.bin2 +1 -0
  24. data/test/fixtures/ldiff/output.diff.bin2-c +1 -0
  25. data/test/fixtures/ldiff/output.diff.bin2-e +1 -0
  26. data/test/fixtures/ldiff/output.diff.bin2-f +1 -0
  27. data/test/fixtures/ldiff/output.diff.bin2-u +1 -0
  28. data/{spec → test}/fixtures/ldiff/output.diff.chef-c +2 -2
  29. data/test/fixtures/ldiff/output.diff.chef-u +9 -0
  30. data/{spec → test}/fixtures/ldiff/output.diff.chef2-c +2 -2
  31. data/{spec → test}/fixtures/ldiff/output.diff.chef2-u +2 -2
  32. data/test/fixtures/ldiff/output.diff.empty.vs.four_lines-c +9 -0
  33. data/test/fixtures/ldiff/output.diff.empty.vs.four_lines-u +7 -0
  34. data/test/fixtures/ldiff/output.diff.four_lines.vs.empty-c +9 -0
  35. data/test/fixtures/ldiff/output.diff.four_lines.vs.empty-u +7 -0
  36. data/test/fixtures/ldiff/output.diff.issue95_trailing_context-c +9 -0
  37. data/test/fixtures/ldiff/output.diff.issue95_trailing_context-u +6 -0
  38. data/{spec → test}/fixtures/ldiff/output.diff.missing_new_line1-c +2 -2
  39. data/test/fixtures/ldiff/output.diff.missing_new_line1-u +9 -0
  40. data/{spec → test}/fixtures/ldiff/output.diff.missing_new_line2-c +2 -2
  41. data/test/fixtures/ldiff/output.diff.missing_new_line2-u +9 -0
  42. data/test/test_block.rb +34 -0
  43. data/test/test_change.rb +234 -0
  44. data/test/test_diff.rb +53 -0
  45. data/test/test_helper.rb +225 -0
  46. data/test/test_hunk.rb +72 -0
  47. data/test/test_issues.rb +168 -0
  48. data/test/test_lcs.rb +47 -0
  49. data/test/test_ldiff.rb +89 -0
  50. data/test/test_patch.rb +362 -0
  51. data/test/test_sdiff.rb +167 -0
  52. data/test/test_traverse_balanced.rb +322 -0
  53. data/test/test_traverse_sequences.rb +187 -0
  54. metadata +130 -96
  55. data/spec/fixtures/ldiff/output.diff-c +0 -7
  56. data/spec/fixtures/ldiff/output.diff-u +0 -5
  57. data/spec/fixtures/ldiff/output.diff.bin2 +0 -1
  58. data/spec/fixtures/ldiff/output.diff.bin2-c +0 -1
  59. data/spec/fixtures/ldiff/output.diff.bin2-e +0 -1
  60. data/spec/fixtures/ldiff/output.diff.bin2-f +0 -1
  61. data/spec/fixtures/ldiff/output.diff.bin2-u +0 -1
  62. data/spec/fixtures/ldiff/output.diff.chef-u +0 -9
  63. data/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-c +0 -9
  64. data/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-u +0 -7
  65. data/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-c +0 -9
  66. data/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-u +0 -7
  67. data/spec/fixtures/ldiff/output.diff.issue95_trailing_context-c +0 -9
  68. data/spec/fixtures/ldiff/output.diff.issue95_trailing_context-u +0 -6
  69. data/spec/fixtures/ldiff/output.diff.missing_new_line1-u +0 -9
  70. data/spec/fixtures/ldiff/output.diff.missing_new_line2-u +0 -9
  71. /data/{spec → test}/fixtures/123_x +0 -0
  72. /data/{spec → test}/fixtures/456_x +0 -0
  73. /data/{spec → test}/fixtures/aX +0 -0
  74. /data/{spec → test}/fixtures/bXaX +0 -0
  75. /data/{spec → test}/fixtures/ds1.csv +0 -0
  76. /data/{spec → test}/fixtures/ds2.csv +0 -0
  77. /data/{spec → test}/fixtures/empty +0 -0
  78. /data/{spec → test}/fixtures/file1.bin +0 -0
  79. /data/{spec → test}/fixtures/file2.bin +0 -0
  80. /data/{spec → test}/fixtures/four_lines +0 -0
  81. /data/{spec → test}/fixtures/four_lines_with_missing_new_line +0 -0
  82. /data/{spec → test}/fixtures/ldiff/diff.missing_new_line1-e +0 -0
  83. /data/{spec → test}/fixtures/ldiff/diff.missing_new_line1-f +0 -0
  84. /data/{spec → test}/fixtures/ldiff/diff.missing_new_line2-e +0 -0
  85. /data/{spec → test}/fixtures/ldiff/diff.missing_new_line2-f +0 -0
  86. /data/{spec → test}/fixtures/ldiff/error.diff.chef-e +0 -0
  87. /data/{spec → test}/fixtures/ldiff/error.diff.chef-f +0 -0
  88. /data/{spec → test}/fixtures/ldiff/error.diff.missing_new_line1-e +0 -0
  89. /data/{spec → test}/fixtures/ldiff/error.diff.missing_new_line1-f +0 -0
  90. /data/{spec → test}/fixtures/ldiff/error.diff.missing_new_line2-e +0 -0
  91. /data/{spec → test}/fixtures/ldiff/error.diff.missing_new_line2-f +0 -0
  92. /data/{spec → test}/fixtures/ldiff/output.diff +0 -0
  93. /data/{spec → test}/fixtures/ldiff/output.diff.bin1 +0 -0
  94. /data/{spec → test}/fixtures/ldiff/output.diff.bin1-c +0 -0
  95. /data/{spec → test}/fixtures/ldiff/output.diff.bin1-e +0 -0
  96. /data/{spec → test}/fixtures/ldiff/output.diff.bin1-f +0 -0
  97. /data/{spec → test}/fixtures/ldiff/output.diff.bin1-u +0 -0
  98. /data/{spec → test}/fixtures/ldiff/output.diff.chef +0 -0
  99. /data/{spec → test}/fixtures/ldiff/output.diff.chef2 +0 -0
  100. /data/{spec → test}/fixtures/ldiff/output.diff.chef2-d +0 -0
  101. /data/{spec → test}/fixtures/ldiff/output.diff.empty.vs.four_lines +0 -0
  102. /data/{spec → test}/fixtures/ldiff/output.diff.empty.vs.four_lines-e +0 -0
  103. /data/{spec → test}/fixtures/ldiff/output.diff.empty.vs.four_lines-f +0 -0
  104. /data/{spec → test}/fixtures/ldiff/output.diff.four_lines.vs.empty +0 -0
  105. /data/{spec → test}/fixtures/ldiff/output.diff.four_lines.vs.empty-e +0 -0
  106. /data/{spec → test}/fixtures/ldiff/output.diff.four_lines.vs.empty-f +0 -0
  107. /data/{spec → test}/fixtures/ldiff/output.diff.issue95_trailing_context +0 -0
  108. /data/{spec → test}/fixtures/ldiff/output.diff.issue95_trailing_context-e +0 -0
  109. /data/{spec → test}/fixtures/ldiff/output.diff.issue95_trailing_context-f +0 -0
  110. /data/{spec → test}/fixtures/ldiff/output.diff.missing_new_line1 +0 -0
  111. /data/{spec → test}/fixtures/ldiff/output.diff.missing_new_line1-e +0 -0
  112. /data/{spec → test}/fixtures/ldiff/output.diff.missing_new_line1-f +0 -0
  113. /data/{spec → test}/fixtures/ldiff/output.diff.missing_new_line2 +0 -0
  114. /data/{spec → test}/fixtures/ldiff/output.diff.missing_new_line2-e +0 -0
  115. /data/{spec → test}/fixtures/ldiff/output.diff.missing_new_line2-f +0 -0
  116. /data/{spec → test}/fixtures/new-chef +0 -0
  117. /data/{spec → test}/fixtures/new-chef2 +0 -0
  118. /data/{spec → test}/fixtures/old-chef +0 -0
  119. /data/{spec → test}/fixtures/old-chef2 +0 -0
@@ -0,0 +1,167 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "test_helper"
4
+
5
+ class TestSDiff < Minitest::Test
6
+ def compare_sequences_correctly(s1, s2, result)
7
+ assert_equal context_diff(result), sdiff(s1, s2)
8
+ assert_equal context_diff(reverse_sdiff(result)), sdiff(s2, s1)
9
+ end
10
+
11
+ def test_seq1_seq2
12
+ compare_sequences_correctly(seq1, seq2, correct_forward_sdiff)
13
+ end
14
+
15
+ def test_abc_def_yyy_xxx_ghi_jkl
16
+ s1 = %w[abc def yyy xxx ghi jkl]
17
+ s2 = %w[abc dxf xxx ghi jkl]
18
+ result = [
19
+ ["=", [0, "abc"], [0, "abc"]],
20
+ ["!", [1, "def"], [1, "dxf"]],
21
+ ["-", [2, "yyy"], [2, nil]],
22
+ ["=", [3, "xxx"], [2, "xxx"]],
23
+ ["=", [4, "ghi"], [3, "ghi"]],
24
+ ["=", [5, "jkl"], [4, "jkl"]]
25
+ ]
26
+ compare_sequences_correctly(s1, s2, result)
27
+ end
28
+
29
+ def test_a_b_c_d_e_vs_a_e
30
+ s1 = %w[a b c d e]
31
+ s2 = %w[a e]
32
+ result = [
33
+ ["=", [0, "a"], [0, "a"]],
34
+ ["-", [1, "b"], [1, nil]],
35
+ ["-", [2, "c"], [1, nil]],
36
+ ["-", [3, "d"], [1, nil]],
37
+ ["=", [4, "e"], [1, "e"]]
38
+ ]
39
+ compare_sequences_correctly(s1, s2, result)
40
+ end
41
+
42
+ def test_a_e_vs_a_b_c_d_e
43
+ s1 = %w[a e]
44
+ s2 = %w[a b c d e]
45
+ result = [
46
+ ["=", [0, "a"], [0, "a"]],
47
+ ["+", [1, nil], [1, "b"]],
48
+ ["+", [1, nil], [2, "c"]],
49
+ ["+", [1, nil], [3, "d"]],
50
+ ["=", [1, "e"], [4, "e"]]
51
+ ]
52
+ compare_sequences_correctly(s1, s2, result)
53
+ end
54
+
55
+ def test_v_x_a_e_vs_w_y_a_b_c_d_e
56
+ s1 = %w[v x a e]
57
+ s2 = %w[w y a b c d e]
58
+ result = [
59
+ ["!", [0, "v"], [0, "w"]],
60
+ ["!", [1, "x"], [1, "y"]],
61
+ ["=", [2, "a"], [2, "a"]],
62
+ ["+", [3, nil], [3, "b"]],
63
+ ["+", [3, nil], [4, "c"]],
64
+ ["+", [3, nil], [5, "d"]],
65
+ ["=", [3, "e"], [6, "e"]]
66
+ ]
67
+ compare_sequences_correctly(s1, s2, result)
68
+ end
69
+
70
+ def test_x_a_e_vs_a_b_c_d_e
71
+ s1 = %w[x a e]
72
+ s2 = %w[a b c d e]
73
+ result = [
74
+ ["-", [0, "x"], [0, nil]],
75
+ ["=", [1, "a"], [0, "a"]],
76
+ ["+", [2, nil], [1, "b"]],
77
+ ["+", [2, nil], [2, "c"]],
78
+ ["+", [2, nil], [3, "d"]],
79
+ ["=", [2, "e"], [4, "e"]]
80
+ ]
81
+ compare_sequences_correctly(s1, s2, result)
82
+ end
83
+
84
+ def test_a_e_vs_x_a_b_c_d_e
85
+ s1 = %w[a e]
86
+ s2 = %w[x a b c d e]
87
+ result = [
88
+ ["+", [0, nil], [0, "x"]],
89
+ ["=", [0, "a"], [1, "a"]],
90
+ ["+", [1, nil], [2, "b"]],
91
+ ["+", [1, nil], [3, "c"]],
92
+ ["+", [1, nil], [4, "d"]],
93
+ ["=", [1, "e"], [5, "e"]]
94
+ ]
95
+ compare_sequences_correctly(s1, s2, result)
96
+ end
97
+
98
+ def test_a_e_v_vs_x_a_b_c_d_e_w_x
99
+ s1 = %w[a e v]
100
+ s2 = %w[x a b c d e w x]
101
+ result = [
102
+ ["+", [0, nil], [0, "x"]],
103
+ ["=", [0, "a"], [1, "a"]],
104
+ ["+", [1, nil], [2, "b"]],
105
+ ["+", [1, nil], [3, "c"]],
106
+ ["+", [1, nil], [4, "d"]],
107
+ ["=", [1, "e"], [5, "e"]],
108
+ ["!", [2, "v"], [6, "w"]],
109
+ ["+", [3, nil], [7, "x"]]
110
+ ]
111
+ compare_sequences_correctly(s1, s2, result)
112
+ end
113
+
114
+ def test_empty_vs_a_b_c
115
+ s1 = %w[]
116
+ s2 = %w[a b c]
117
+ result = [
118
+ ["+", [0, nil], [0, "a"]],
119
+ ["+", [0, nil], [1, "b"]],
120
+ ["+", [0, nil], [2, "c"]]
121
+ ]
122
+ compare_sequences_correctly(s1, s2, result)
123
+ end
124
+
125
+ def test_a_b_c_vs_1
126
+ s1 = %w[a b c]
127
+ s2 = %w[1]
128
+ result = [
129
+ ["!", [0, "a"], [0, "1"]],
130
+ ["-", [1, "b"], [1, nil]],
131
+ ["-", [2, "c"], [1, nil]]
132
+ ]
133
+ compare_sequences_correctly(s1, s2, result)
134
+ end
135
+
136
+ def test_a_b_c_vs_c
137
+ s1 = %w[a b c]
138
+ s2 = %w[c]
139
+ result = [
140
+ ["-", [0, "a"], [0, nil]],
141
+ ["-", [1, "b"], [0, nil]],
142
+ ["=", [2, "c"], [0, "c"]]
143
+ ]
144
+ compare_sequences_correctly(s1, s2, result)
145
+ end
146
+
147
+ def test_abcd_efgh_ijkl_mnop_vs_empty
148
+ s1 = %w[abcd efgh ijkl mnop]
149
+ s2 = []
150
+ result = [
151
+ ["-", [0, "abcd"], [0, nil]],
152
+ ["-", [1, "efgh"], [0, nil]],
153
+ ["-", [2, "ijkl"], [0, nil]],
154
+ ["-", [3, "mnop"], [0, nil]]
155
+ ]
156
+ compare_sequences_correctly(s1, s2, result)
157
+ end
158
+
159
+ def test_nested_array_vs_empty
160
+ s1 = [[1, 2]]
161
+ s2 = []
162
+ result = [
163
+ ["-", [0, [1, 2]], [0, nil]]
164
+ ]
165
+ compare_sequences_correctly(s1, s2, result)
166
+ end
167
+ end
@@ -0,0 +1,322 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ class TestTraverseBalanced < Minitest::Test
6
+ def balanced_traversal(s1, s2, callback_type)
7
+ callback = send(callback_type)
8
+ traverse_balanced(s1, s2, callback)
9
+ callback
10
+ end
11
+
12
+ def balanced_reverse(change_result)
13
+ new_result = []
14
+ change_result.each do |line|
15
+ line = [line[0], line[2], line[1]]
16
+ case line[0]
17
+ when "<"
18
+ line[0] = ">"
19
+ when ">"
20
+ line[0] = "<"
21
+ end
22
+ new_result << line
23
+ end
24
+ new_result.sort_by { |line| [line[1], line[2]] }
25
+ end
26
+
27
+ def map_to_no_change(change_result)
28
+ new_result = []
29
+ change_result.each do |line|
30
+ case line[0]
31
+ when "!"
32
+ new_result << ["<", line[1], line[2]]
33
+ new_result << [">", line[1] + 1, line[2]]
34
+ else
35
+ new_result << line
36
+ end
37
+ end
38
+ new_result
39
+ end
40
+
41
+ class BalancedCallback
42
+ def initialize
43
+ reset
44
+ end
45
+
46
+ attr_reader :result
47
+
48
+ def reset
49
+ @result = []
50
+ end
51
+
52
+ def match(event)
53
+ @result << ["=", event.old_position, event.new_position]
54
+ end
55
+
56
+ def discard_a(event)
57
+ @result << ["<", event.old_position, event.new_position]
58
+ end
59
+
60
+ def discard_b(event)
61
+ @result << [">", event.old_position, event.new_position]
62
+ end
63
+
64
+ def change(event)
65
+ @result << ["!", event.old_position, event.new_position]
66
+ end
67
+ end
68
+
69
+ def balanced_callback
70
+ BalancedCallback.new
71
+ end
72
+
73
+ class BalancedCallbackNoChange < BalancedCallback
74
+ undef :change
75
+ end
76
+
77
+ def balanced_callback_no_change
78
+ BalancedCallbackNoChange.new
79
+ end
80
+
81
+ def assert_traversal_with_change(s1, s2, result)
82
+ traversal = balanced_traversal(s1, s2, :balanced_callback)
83
+ assert_equal result, traversal.result
84
+
85
+ traversal = balanced_traversal(s2, s1, :balanced_callback)
86
+ assert_equal balanced_reverse(result), traversal.result
87
+ end
88
+
89
+ def assert_traversal_without_change(s1, s2, result)
90
+ traversal = balanced_traversal(s1, s2, :balanced_callback_no_change)
91
+ assert_equal map_to_no_change(result), traversal.result
92
+
93
+ traversal = balanced_traversal(s2, s1, :balanced_callback_no_change)
94
+ assert_equal map_to_no_change(balanced_reverse(result)), traversal.result
95
+ end
96
+
97
+ def test_identical_string_sequences_abc
98
+ s1 = s2 = "abc"
99
+ result = [
100
+ ["=", 0, 0],
101
+ ["=", 1, 1],
102
+ ["=", 2, 2]
103
+ ]
104
+ assert_traversal_with_change(s1, s2, result)
105
+ assert_traversal_without_change(s1, s2, result)
106
+ end
107
+
108
+ def test_identical_array_sequences_a_b_c
109
+ s1 = s2 = %w[a b c]
110
+ result = [
111
+ ["=", 0, 0],
112
+ ["=", 1, 1],
113
+ ["=", 2, 2]
114
+ ]
115
+ assert_traversal_with_change(s1, s2, result)
116
+ assert_traversal_without_change(s1, s2, result)
117
+ end
118
+
119
+ def test_sequences_a_b_c_and_a_x_c
120
+ s1 = %w[a b c]
121
+ s2 = %w[a x c]
122
+ result = [
123
+ ["=", 0, 0],
124
+ ["!", 1, 1],
125
+ ["=", 2, 2]
126
+ ]
127
+ assert_traversal_with_change(s1, s2, result)
128
+ assert_traversal_without_change(s1, s2, result)
129
+ end
130
+
131
+ def test_sequences_a_x_y_c_and_a_v_w_c
132
+ s1 = %w[a x y c]
133
+ s2 = %w[a v w c]
134
+ result = [
135
+ ["=", 0, 0],
136
+ ["!", 1, 1],
137
+ ["!", 2, 2],
138
+ ["=", 3, 3]
139
+ ]
140
+ assert_traversal_with_change(s1, s2, result)
141
+ assert_traversal_without_change(s1, s2, result)
142
+ end
143
+
144
+ def test_sequences_x_y_c_and_v_w_c
145
+ s1 = %w[x y c]
146
+ s2 = %w[v w c]
147
+ result = [
148
+ ["!", 0, 0],
149
+ ["!", 1, 1],
150
+ ["=", 2, 2]
151
+ ]
152
+ assert_traversal_with_change(s1, s2, result)
153
+ assert_traversal_without_change(s1, s2, result)
154
+ end
155
+
156
+ def test_sequences_a_x_y_z_and_b_v_w
157
+ s1 = %w[a x y z]
158
+ s2 = %w[b v w]
159
+ result = [
160
+ ["!", 0, 0],
161
+ ["!", 1, 1],
162
+ ["!", 2, 2],
163
+ ["<", 3, 3]
164
+ ]
165
+ assert_traversal_with_change(s1, s2, result)
166
+ assert_traversal_without_change(s1, s2, result)
167
+ end
168
+
169
+ def test_sequences_a_z_and_a
170
+ s1 = %w[a z]
171
+ s2 = %w[a]
172
+ result = [
173
+ ["=", 0, 0],
174
+ ["<", 1, 1]
175
+ ]
176
+ assert_traversal_with_change(s1, s2, result)
177
+ assert_traversal_without_change(s1, s2, result)
178
+ end
179
+
180
+ def test_sequences_z_a_and_a
181
+ s1 = %w[z a]
182
+ s2 = %w[a]
183
+ result = [
184
+ ["<", 0, 0],
185
+ ["=", 1, 0]
186
+ ]
187
+ assert_traversal_with_change(s1, s2, result)
188
+ assert_traversal_without_change(s1, s2, result)
189
+ end
190
+
191
+ def test_sequences_a_b_c_and_x_y_z
192
+ s1 = %w[a b c]
193
+ s2 = %w[x y z]
194
+ result = [
195
+ ["!", 0, 0],
196
+ ["!", 1, 1],
197
+ ["!", 2, 2]
198
+ ]
199
+ assert_traversal_with_change(s1, s2, result)
200
+ assert_traversal_without_change(s1, s2, result)
201
+ end
202
+
203
+ def test_strings_a_b_c_and_a_x_c
204
+ s1 = "a b c"
205
+ s2 = "a x c"
206
+ result = [
207
+ ["=", 0, 0],
208
+ ["=", 1, 1],
209
+ ["!", 2, 2],
210
+ ["=", 3, 3],
211
+ ["=", 4, 4]
212
+ ]
213
+ assert_traversal_with_change(s1, s2, result)
214
+ assert_traversal_without_change(s1, s2, result)
215
+ end
216
+
217
+ def test_strings_a_x_y_c_and_a_v_w_c
218
+ s1 = "a x y c"
219
+ s2 = "a v w c"
220
+ result = [
221
+ ["=", 0, 0],
222
+ ["=", 1, 1],
223
+ ["!", 2, 2],
224
+ ["=", 3, 3],
225
+ ["!", 4, 4],
226
+ ["=", 5, 5],
227
+ ["=", 6, 6]
228
+ ]
229
+ assert_traversal_with_change(s1, s2, result)
230
+ assert_traversal_without_change(s1, s2, result)
231
+ end
232
+
233
+ def test_strings_x_y_c_and_v_w_c
234
+ s1 = "x y c"
235
+ s2 = "v w c"
236
+ result = [
237
+ ["!", 0, 0],
238
+ ["=", 1, 1],
239
+ ["!", 2, 2],
240
+ ["=", 3, 3],
241
+ ["=", 4, 4]
242
+ ]
243
+ assert_traversal_with_change(s1, s2, result)
244
+ assert_traversal_without_change(s1, s2, result)
245
+ end
246
+
247
+ def test_strings_a_z_and_a
248
+ s1 = "a z"
249
+ s2 = "a"
250
+ result = [
251
+ ["=", 0, 0],
252
+ ["<", 1, 1],
253
+ ["<", 2, 1]
254
+ ]
255
+ assert_traversal_with_change(s1, s2, result)
256
+ assert_traversal_without_change(s1, s2, result)
257
+ end
258
+
259
+ def test_strings_z_a_and_a
260
+ s1 = "z a"
261
+ s2 = "a"
262
+ result = [
263
+ ["<", 0, 0],
264
+ ["<", 1, 0],
265
+ ["=", 2, 0]
266
+ ]
267
+ assert_traversal_with_change(s1, s2, result)
268
+ assert_traversal_without_change(s1, s2, result)
269
+ end
270
+
271
+ def test_strings_a_b_c_and_x_y_z
272
+ s1 = "a b c"
273
+ s2 = "x y z"
274
+ result = [
275
+ ["!", 0, 0],
276
+ ["=", 1, 1],
277
+ ["!", 2, 2],
278
+ ["=", 3, 3],
279
+ ["!", 4, 4]
280
+ ]
281
+ assert_traversal_with_change(s1, s2, result)
282
+ assert_traversal_without_change(s1, s2, result)
283
+ end
284
+
285
+ def test_strings_abcd_efgh_ijkl_mnopqrstuvwxyz_and_empty
286
+ s1 = "abcd efgh ijkl mnopqrstuvwxyz"
287
+ s2 = ""
288
+ result = [
289
+ ["<", 0, 0],
290
+ ["<", 1, 0],
291
+ ["<", 2, 0],
292
+ ["<", 3, 0],
293
+ ["<", 4, 0],
294
+ ["<", 5, 0],
295
+ ["<", 6, 0],
296
+ ["<", 7, 0],
297
+ ["<", 8, 0],
298
+ ["<", 9, 0],
299
+ ["<", 10, 0],
300
+ ["<", 11, 0],
301
+ ["<", 12, 0],
302
+ ["<", 13, 0],
303
+ ["<", 14, 0],
304
+ ["<", 15, 0],
305
+ ["<", 16, 0],
306
+ ["<", 17, 0],
307
+ ["<", 18, 0],
308
+ ["<", 19, 0],
309
+ ["<", 20, 0],
310
+ ["<", 21, 0],
311
+ ["<", 22, 0],
312
+ ["<", 23, 0],
313
+ ["<", 24, 0],
314
+ ["<", 25, 0],
315
+ ["<", 26, 0],
316
+ ["<", 27, 0],
317
+ ["<", 28, 0]
318
+ ]
319
+ assert_traversal_with_change(s1, s2, result)
320
+ assert_traversal_without_change(s1, s2, result)
321
+ end
322
+ end
@@ -0,0 +1,187 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "test_helper"
4
+
5
+ class TestTraverseSequences < Minitest::Test
6
+ def test_callback_with_no_finishers_over_seq1_seq2_has_correct_lcs_result_on_left_matches
7
+ callback_s1_s2 = simple_callback_no_finishers
8
+ traverse_sequences(seq1, seq2, callback_s1_s2)
9
+
10
+ callback_s2_s1 = simple_callback_no_finishers
11
+ traverse_sequences(seq2, seq1, callback_s2_s1)
12
+
13
+ assert_equal correct_lcs, callback_s1_s2.matched_a
14
+ assert_equal correct_lcs, callback_s2_s1.matched_a
15
+ end
16
+
17
+ def test_callback_with_no_finishers_over_seq1_seq2_has_correct_lcs_result_on_right_matches
18
+ callback_s1_s2 = simple_callback_no_finishers
19
+ traverse_sequences(seq1, seq2, callback_s1_s2)
20
+
21
+ callback_s2_s1 = simple_callback_no_finishers
22
+ traverse_sequences(seq2, seq1, callback_s2_s1)
23
+
24
+ assert_equal correct_lcs, callback_s1_s2.matched_b
25
+ assert_equal correct_lcs, callback_s2_s1.matched_b
26
+ end
27
+
28
+ def test_callback_with_no_finishers_over_seq1_seq2_has_correct_skipped_sequences_with_left_sequence
29
+ callback_s1_s2 = simple_callback_no_finishers
30
+ traverse_sequences(seq1, seq2, callback_s1_s2)
31
+
32
+ callback_s2_s1 = simple_callback_no_finishers
33
+ traverse_sequences(seq2, seq1, callback_s2_s1)
34
+
35
+ assert_equal skipped_seq1, callback_s1_s2.discards_a
36
+ assert_equal skipped_seq2, callback_s2_s1.discards_a
37
+ end
38
+
39
+ def test_callback_with_no_finishers_over_seq1_seq2_has_correct_skipped_sequences_with_right_sequence
40
+ callback_s1_s2 = simple_callback_no_finishers
41
+ traverse_sequences(seq1, seq2, callback_s1_s2)
42
+
43
+ callback_s2_s1 = simple_callback_no_finishers
44
+ traverse_sequences(seq2, seq1, callback_s2_s1)
45
+
46
+ assert_equal skipped_seq2, callback_s1_s2.discards_b
47
+ assert_equal skipped_seq1, callback_s2_s1.discards_b
48
+ end
49
+
50
+ def test_callback_with_no_finishers_over_seq1_seq2_does_not_have_done_markers
51
+ callback_s1_s2 = simple_callback_no_finishers
52
+ traverse_sequences(seq1, seq2, callback_s1_s2)
53
+
54
+ callback_s2_s1 = simple_callback_no_finishers
55
+ traverse_sequences(seq2, seq1, callback_s2_s1)
56
+
57
+ assert_empty callback_s1_s2.done_a
58
+ assert_empty callback_s1_s2.done_b
59
+ assert_empty callback_s2_s1.done_a
60
+ assert_empty callback_s2_s1.done_b
61
+ end
62
+
63
+ def test_callback_with_no_finishers_over_hello_hello_has_correct_lcs_result_on_left_matches
64
+ callback = simple_callback_no_finishers
65
+ traverse_sequences(hello, hello, callback)
66
+
67
+ assert_equal hello.chars, callback.matched_a
68
+ end
69
+
70
+ def test_callback_with_no_finishers_over_hello_hello_has_correct_lcs_result_on_right_matches
71
+ callback = simple_callback_no_finishers
72
+ traverse_sequences(hello, hello, callback)
73
+
74
+ assert_equal hello.chars, callback.matched_b
75
+ end
76
+
77
+ def test_callback_with_no_finishers_over_hello_hello_has_correct_skipped_sequences_with_left_sequence
78
+ callback = simple_callback_no_finishers
79
+ traverse_sequences(hello, hello, callback)
80
+
81
+ assert_empty callback.discards_a
82
+ end
83
+
84
+ def test_callback_with_no_finishers_over_hello_hello_has_correct_skipped_sequences_with_right_sequence
85
+ callback = simple_callback_no_finishers
86
+ traverse_sequences(hello, hello, callback)
87
+
88
+ assert_empty callback.discards_b
89
+ end
90
+
91
+ def test_callback_with_no_finishers_over_hello_hello_does_not_have_done_markers
92
+ callback = simple_callback_no_finishers
93
+ traverse_sequences(hello, hello, callback)
94
+
95
+ assert_empty callback.done_a
96
+ assert_empty callback.done_b
97
+ end
98
+
99
+ def test_callback_with_no_finishers_over_hello_ary_hello_ary_has_correct_lcs_result_on_left_matches
100
+ callback = simple_callback_no_finishers
101
+ traverse_sequences(hello_ary, hello_ary, callback)
102
+
103
+ assert_equal hello_ary, callback.matched_a
104
+ end
105
+
106
+ def test_callback_with_no_finishers_over_hello_ary_hello_ary_has_correct_lcs_result_on_right_matches
107
+ callback = simple_callback_no_finishers
108
+ traverse_sequences(hello_ary, hello_ary, callback)
109
+
110
+ assert_equal hello_ary, callback.matched_b
111
+ end
112
+
113
+ def test_callback_with_no_finishers_over_hello_ary_hello_ary_has_correct_skipped_sequences_with_left_sequence
114
+ callback = simple_callback_no_finishers
115
+ traverse_sequences(hello_ary, hello_ary, callback)
116
+
117
+ assert_empty callback.discards_a
118
+ end
119
+
120
+ def test_callback_with_no_finishers_over_hello_ary_hello_ary_has_correct_skipped_sequences_with_right_sequence
121
+ callback = simple_callback_no_finishers
122
+ traverse_sequences(hello_ary, hello_ary, callback)
123
+
124
+ assert_empty callback.discards_b
125
+ end
126
+
127
+ def test_callback_with_no_finishers_over_hello_ary_hello_ary_does_not_have_done_markers
128
+ callback = simple_callback_no_finishers
129
+ traverse_sequences(hello_ary, hello_ary, callback)
130
+
131
+ assert_empty callback.done_a
132
+ assert_empty callback.done_b
133
+ end
134
+
135
+ def test_callback_with_finisher_has_correct_lcs_result_on_left_matches
136
+ callback_s1_s2 = simple_callback
137
+ traverse_sequences(seq1, seq2, callback_s1_s2)
138
+ callback_s2_s1 = simple_callback
139
+ traverse_sequences(seq2, seq1, callback_s2_s1)
140
+
141
+ assert_equal correct_lcs, callback_s1_s2.matched_a
142
+ assert_equal correct_lcs, callback_s2_s1.matched_a
143
+ end
144
+
145
+ def test_callback_with_finisher_has_correct_lcs_result_on_right_matches
146
+ callback_s1_s2 = simple_callback
147
+ traverse_sequences(seq1, seq2, callback_s1_s2)
148
+ callback_s2_s1 = simple_callback
149
+ traverse_sequences(seq2, seq1, callback_s2_s1)
150
+
151
+ assert_equal correct_lcs, callback_s1_s2.matched_b
152
+ assert_equal correct_lcs, callback_s2_s1.matched_b
153
+ end
154
+
155
+ def test_callback_with_finisher_has_correct_skipped_sequences_for_left_sequence
156
+ callback_s1_s2 = simple_callback
157
+ traverse_sequences(seq1, seq2, callback_s1_s2)
158
+ callback_s2_s1 = simple_callback
159
+ traverse_sequences(seq2, seq1, callback_s2_s1)
160
+
161
+ assert_equal skipped_seq1, callback_s1_s2.discards_a
162
+ assert_equal skipped_seq2, callback_s2_s1.discards_a
163
+ end
164
+
165
+ def test_callback_with_finisher_has_correct_skipped_sequences_for_right_sequence
166
+ callback_s1_s2 = simple_callback
167
+ traverse_sequences(seq1, seq2, callback_s1_s2)
168
+ callback_s2_s1 = simple_callback
169
+ traverse_sequences(seq2, seq1, callback_s2_s1)
170
+
171
+ assert_equal skipped_seq2, callback_s1_s2.discards_b
172
+ assert_equal skipped_seq1, callback_s2_s1.discards_b
173
+ end
174
+
175
+ def test_callback_with_finisher_has_done_markers_differently_sized_sequences
176
+ callback_s1_s2 = simple_callback
177
+ traverse_sequences(seq1, seq2, callback_s1_s2)
178
+ callback_s2_s1 = simple_callback
179
+ traverse_sequences(seq2, seq1, callback_s2_s1)
180
+
181
+ assert_equal [["p", 9, "t", 11]], callback_s1_s2.done_a
182
+ assert_empty callback_s1_s2.done_b
183
+
184
+ assert_empty callback_s2_s1.done_a
185
+ assert_equal [["t", 11, "p", 9]], callback_s2_s1.done_b
186
+ end
187
+ end