diff-lcs 1.5.1 → 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.
Files changed (132) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +581 -0
  3. data/CODE_OF_CONDUCT.md +166 -0
  4. data/CONTRIBUTING.md +127 -0
  5. data/CONTRIBUTORS.md +59 -0
  6. data/LICENCE.md +68 -0
  7. data/Manifest.txt +99 -35
  8. data/README.md +105 -0
  9. data/Rakefile +107 -96
  10. data/SECURITY.md +36 -0
  11. data/integration/compare/array_diff_spec.rb +10 -0
  12. data/integration/compare/hash_diff_spec.rb +25 -0
  13. data/integration/compare/string_diff_spec.rb +10 -0
  14. data/integration/rspec_differ_spec.rb +26 -0
  15. data/integration/rspec_expectations_spec.rb +32 -0
  16. data/integration/runner +20 -0
  17. data/lib/diff/lcs/block.rb +29 -24
  18. data/lib/diff/lcs/callbacks.rb +240 -242
  19. data/lib/diff/lcs/change.rb +102 -104
  20. data/lib/diff/lcs/hunk.rb +110 -157
  21. data/lib/diff/lcs/internals.rb +92 -96
  22. data/lib/diff/lcs/ldiff.rb +81 -73
  23. data/lib/diff/lcs/version.rb +7 -0
  24. data/lib/diff/lcs.rb +440 -466
  25. data/{docs → licenses}/artistic.txt +1 -1
  26. data/licenses/dco.txt +34 -0
  27. data/spec/hunk_spec.rb +33 -46
  28. data/spec/issues_spec.rb +32 -32
  29. data/spec/lcs_spec.rb +6 -6
  30. data/spec/ldiff_spec.rb +27 -16
  31. data/spec/patch_spec.rb +1 -1
  32. data/spec/spec_helper.rb +98 -108
  33. data/test/fixtures/123_x +2 -0
  34. data/test/fixtures/456_x +2 -0
  35. data/test/fixtures/empty +0 -0
  36. data/test/fixtures/file1.bin +0 -0
  37. data/test/fixtures/file2.bin +0 -0
  38. data/test/fixtures/four_lines +4 -0
  39. data/test/fixtures/four_lines_with_missing_new_line +4 -0
  40. data/test/fixtures/ldiff/diff.missing_new_line1-e +1 -0
  41. data/test/fixtures/ldiff/diff.missing_new_line1-f +1 -0
  42. data/test/fixtures/ldiff/diff.missing_new_line2-e +1 -0
  43. data/test/fixtures/ldiff/diff.missing_new_line2-f +1 -0
  44. data/test/fixtures/ldiff/error.diff.chef-e +2 -0
  45. data/test/fixtures/ldiff/error.diff.chef-f +2 -0
  46. data/test/fixtures/ldiff/error.diff.missing_new_line1-e +1 -0
  47. data/test/fixtures/ldiff/error.diff.missing_new_line1-f +1 -0
  48. data/test/fixtures/ldiff/error.diff.missing_new_line2-e +1 -0
  49. data/test/fixtures/ldiff/error.diff.missing_new_line2-f +1 -0
  50. data/test/fixtures/ldiff/output.diff-c +7 -0
  51. data/test/fixtures/ldiff/output.diff-u +5 -0
  52. data/test/fixtures/ldiff/output.diff.bin1 +0 -0
  53. data/test/fixtures/ldiff/output.diff.bin1-c +0 -0
  54. data/test/fixtures/ldiff/output.diff.bin1-e +0 -0
  55. data/test/fixtures/ldiff/output.diff.bin1-f +0 -0
  56. data/test/fixtures/ldiff/output.diff.bin1-u +0 -0
  57. data/test/fixtures/ldiff/output.diff.bin2 +1 -0
  58. data/test/fixtures/ldiff/output.diff.bin2-c +1 -0
  59. data/test/fixtures/ldiff/output.diff.bin2-e +1 -0
  60. data/test/fixtures/ldiff/output.diff.bin2-f +1 -0
  61. data/test/fixtures/ldiff/output.diff.bin2-u +1 -0
  62. data/{spec → test}/fixtures/ldiff/output.diff.chef-c +2 -2
  63. data/test/fixtures/ldiff/output.diff.chef-u +9 -0
  64. data/{spec → test}/fixtures/ldiff/output.diff.chef2-c +2 -2
  65. data/{spec → test}/fixtures/ldiff/output.diff.chef2-u +2 -2
  66. data/test/fixtures/ldiff/output.diff.empty.vs.four_lines +5 -0
  67. data/test/fixtures/ldiff/output.diff.empty.vs.four_lines-c +9 -0
  68. data/test/fixtures/ldiff/output.diff.empty.vs.four_lines-e +6 -0
  69. data/test/fixtures/ldiff/output.diff.empty.vs.four_lines-f +6 -0
  70. data/test/fixtures/ldiff/output.diff.empty.vs.four_lines-u +7 -0
  71. data/test/fixtures/ldiff/output.diff.four_lines.vs.empty +5 -0
  72. data/test/fixtures/ldiff/output.diff.four_lines.vs.empty-c +9 -0
  73. data/test/fixtures/ldiff/output.diff.four_lines.vs.empty-e +1 -0
  74. data/test/fixtures/ldiff/output.diff.four_lines.vs.empty-f +1 -0
  75. data/test/fixtures/ldiff/output.diff.four_lines.vs.empty-u +7 -0
  76. data/test/fixtures/ldiff/output.diff.issue95_trailing_context +4 -0
  77. data/test/fixtures/ldiff/output.diff.issue95_trailing_context-c +9 -0
  78. data/{spec/fixtures/ldiff/output.diff-e → test/fixtures/ldiff/output.diff.issue95_trailing_context-e} +1 -1
  79. data/{spec/fixtures/ldiff/output.diff-f → test/fixtures/ldiff/output.diff.issue95_trailing_context-f} +1 -1
  80. data/test/fixtures/ldiff/output.diff.issue95_trailing_context-u +6 -0
  81. data/test/fixtures/ldiff/output.diff.missing_new_line1 +5 -0
  82. data/test/fixtures/ldiff/output.diff.missing_new_line1-c +14 -0
  83. data/test/fixtures/ldiff/output.diff.missing_new_line1-e +0 -0
  84. data/test/fixtures/ldiff/output.diff.missing_new_line1-f +0 -0
  85. data/test/fixtures/ldiff/output.diff.missing_new_line1-u +9 -0
  86. data/test/fixtures/ldiff/output.diff.missing_new_line2 +5 -0
  87. data/test/fixtures/ldiff/output.diff.missing_new_line2-c +14 -0
  88. data/test/fixtures/ldiff/output.diff.missing_new_line2-e +0 -0
  89. data/test/fixtures/ldiff/output.diff.missing_new_line2-f +0 -0
  90. data/test/fixtures/ldiff/output.diff.missing_new_line2-u +9 -0
  91. data/test/test_block.rb +34 -0
  92. data/test/test_change.rb +234 -0
  93. data/test/test_diff.rb +53 -0
  94. data/test/test_helper.rb +225 -0
  95. data/test/test_hunk.rb +72 -0
  96. data/test/test_issues.rb +168 -0
  97. data/test/test_lcs.rb +47 -0
  98. data/test/test_ldiff.rb +89 -0
  99. data/test/test_patch.rb +362 -0
  100. data/test/test_sdiff.rb +167 -0
  101. data/test/test_traverse_balanced.rb +322 -0
  102. data/test/test_traverse_sequences.rb +187 -0
  103. metadata +211 -103
  104. data/.rspec +0 -1
  105. data/Code-of-Conduct.md +0 -74
  106. data/Contributing.md +0 -121
  107. data/History.md +0 -431
  108. data/License.md +0 -41
  109. data/README.rdoc +0 -84
  110. data/bin/htmldiff +0 -35
  111. data/lib/diff/lcs/backports.rb +0 -9
  112. data/lib/diff/lcs/htmldiff.rb +0 -158
  113. data/spec/fixtures/ldiff/output.diff-c +0 -7
  114. data/spec/fixtures/ldiff/output.diff-u +0 -5
  115. data/spec/fixtures/ldiff/output.diff.chef-e +0 -3
  116. data/spec/fixtures/ldiff/output.diff.chef-f +0 -3
  117. data/spec/fixtures/ldiff/output.diff.chef-u +0 -9
  118. data/spec/fixtures/ldiff/output.diff.chef2-e +0 -7
  119. data/spec/fixtures/ldiff/output.diff.chef2-f +0 -7
  120. /data/{docs → licenses}/COPYING.txt +0 -0
  121. /data/{spec → test}/fixtures/aX +0 -0
  122. /data/{spec → test}/fixtures/bXaX +0 -0
  123. /data/{spec → test}/fixtures/ds1.csv +0 -0
  124. /data/{spec → test}/fixtures/ds2.csv +0 -0
  125. /data/{spec → test}/fixtures/ldiff/output.diff +0 -0
  126. /data/{spec → test}/fixtures/ldiff/output.diff.chef +0 -0
  127. /data/{spec → test}/fixtures/ldiff/output.diff.chef2 +0 -0
  128. /data/{spec → test}/fixtures/ldiff/output.diff.chef2-d +0 -0
  129. /data/{spec → test}/fixtures/new-chef +0 -0
  130. /data/{spec → test}/fixtures/new-chef2 +0 -0
  131. /data/{spec → test}/fixtures/old-chef +0 -0
  132. /data/{spec → test}/fixtures/old-chef2 +0 -0
@@ -0,0 +1 @@
1
+ <new_file>: No newline at end of file
@@ -0,0 +1 @@
1
+ <new_file>: No newline at end of file
@@ -0,0 +1 @@
1
+ <old_file>: No newline at end of file
@@ -0,0 +1 @@
1
+ <old_file>: No newline at end of file
@@ -0,0 +1,7 @@
1
+ *** test/fixtures/aX 2020-06-23 11:15:32.000000000 -0400
2
+ --- test/fixtures/bXaX 2020-06-23 11:15:32.000000000 -0400
3
+ ***************
4
+ *** 1 ****
5
+ ! aX
6
+ --- 1 ----
7
+ ! bXaX
@@ -0,0 +1,5 @@
1
+ --- test/fixtures/aX 2020-06-23 11:15:32.000000000 -0400
2
+ +++ test/fixtures/bXaX 2020-06-23 11:15:32.000000000 -0400
3
+ @@ -1 +1 @@
4
+ -aX
5
+ +bXaX
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1 @@
1
+ Binary files test/fixtures/file1.bin and test/fixtures/file2.bin differ
@@ -0,0 +1 @@
1
+ Binary files test/fixtures/file1.bin and test/fixtures/file2.bin differ
@@ -0,0 +1 @@
1
+ Binary files test/fixtures/file1.bin and test/fixtures/file2.bin differ
@@ -0,0 +1 @@
1
+ Binary files test/fixtures/file1.bin and test/fixtures/file2.bin differ
@@ -0,0 +1 @@
1
+ Binary files test/fixtures/file1.bin and test/fixtures/file2.bin differ
@@ -1,5 +1,5 @@
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
1
+ *** test/fixtures/old-chef 2020-06-23 23:18:20.000000000 -0400
2
+ --- test/fixtures/new-chef 2020-06-23 23:18:20.000000000 -0400
3
3
  ***************
4
4
  *** 1,4 ****
5
5
  {
@@ -0,0 +1,9 @@
1
+ --- test/fixtures/old-chef 2020-06-23 23:18:20.000000000 -0400
2
+ +++ test/fixtures/new-chef 2020-06-23 23:18:20.000000000 -0400
3
+ @@ -1,4 +1,4 @@
4
+ {
5
+ "name": "x",
6
+ - "description": "hi"
7
+ + "description": "lo"
8
+ }
9
+
@@ -1,5 +1,5 @@
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
1
+ *** test/fixtures/old-chef2 2020-06-30 09:43:35.000000000 -0400
2
+ --- test/fixtures/new-chef2 2020-06-30 09:44:32.000000000 -0400
3
3
  ***************
4
4
  *** 1,5 ****
5
5
  recipe[a::default]
@@ -1,5 +1,5 @@
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
1
+ --- test/fixtures/old-chef2 2020-06-30 09:43:35.000000000 -0400
2
+ +++ test/fixtures/new-chef2 2020-06-30 09:44:32.000000000 -0400
3
3
  @@ -1,5 +1,4 @@
4
4
  recipe[a::default]
5
5
  -recipe[b::default]
@@ -0,0 +1,5 @@
1
+ 0a1,4
2
+ > one
3
+ > two
4
+ > three
5
+ > four
@@ -0,0 +1,9 @@
1
+ *** test/fixtures/empty 2025-01-31 12:14:52.856031635 +0100
2
+ --- test/fixtures/four_lines 2025-01-31 12:13:45.476036544 +0100
3
+ ***************
4
+ *** 0 ****
5
+ --- 1,4 ----
6
+ + one
7
+ + two
8
+ + three
9
+ + four
@@ -0,0 +1,6 @@
1
+ 0a
2
+ one
3
+ two
4
+ three
5
+ four
6
+ .
@@ -0,0 +1,6 @@
1
+ a0
2
+ one
3
+ two
4
+ three
5
+ four
6
+ .
@@ -0,0 +1,7 @@
1
+ --- test/fixtures/empty 2025-01-31 12:14:52.856031635 +0100
2
+ +++ test/fixtures/four_lines 2025-01-31 12:13:45.476036544 +0100
3
+ @@ -0,0 +1,4 @@
4
+ +one
5
+ +two
6
+ +three
7
+ +four
@@ -0,0 +1,5 @@
1
+ 1,4d0
2
+ < one
3
+ < two
4
+ < three
5
+ < four
@@ -0,0 +1,9 @@
1
+ *** test/fixtures/four_lines 2025-01-31 12:13:45.476036544 +0100
2
+ --- test/fixtures/empty 2025-01-31 12:14:52.856031635 +0100
3
+ ***************
4
+ *** 1,4 ****
5
+ - one
6
+ - two
7
+ - three
8
+ - four
9
+ --- 0 ----
@@ -0,0 +1,7 @@
1
+ --- test/fixtures/four_lines 2025-01-31 12:13:45.476036544 +0100
2
+ +++ test/fixtures/empty 2025-01-31 12:14:52.856031635 +0100
3
+ @@ -1,4 +0,0 @@
4
+ -one
5
+ -two
6
+ -three
7
+ -four
@@ -0,0 +1,4 @@
1
+ 1c1
2
+ < 123
3
+ ---
4
+ > 456
@@ -0,0 +1,9 @@
1
+ *** test/fixtures/123_x 2025-01-31 17:00:17.070615716 +0100
2
+ --- test/fixtures/456_x 2025-01-31 16:58:26.380624827 +0100
3
+ ***************
4
+ *** 1,2 ****
5
+ ! 123
6
+ x
7
+ --- 1,2 ----
8
+ ! 456
9
+ x
@@ -0,0 +1,6 @@
1
+ --- test/fixtures/123_x 2025-01-31 17:00:17.070615716 +0100
2
+ +++ test/fixtures/456_x 2025-01-31 16:58:26.380624827 +0100
3
+ @@ -1,2 +1,2 @@
4
+ -123
5
+ +456
6
+ x
@@ -0,0 +1,5 @@
1
+ 4c4
2
+ < four
3
+ ---
4
+ > four
5
+
@@ -0,0 +1,14 @@
1
+ *** test/fixtures/four_lines 2025-01-31 12:17:43.926013315 +0100
2
+ --- test/fixtures/four_lines_with_missing_new_line 2025-01-31 12:17:43.926013315 +0100
3
+ ***************
4
+ *** 1,4 ****
5
+ one
6
+ two
7
+ three
8
+ ! four
9
+ --- 1,4 ----
10
+ one
11
+ two
12
+ three
13
+ ! four
14
+
@@ -0,0 +1,9 @@
1
+ --- test/fixtures/four_lines 2025-01-31 12:17:43.926013315 +0100
2
+ +++ test/fixtures/four_lines_with_missing_new_line 2025-01-31 12:17:43.926013315 +0100
3
+ @@ -1,4 +1,4 @@
4
+ one
5
+ two
6
+ three
7
+ -four
8
+ +four
9
+
@@ -0,0 +1,5 @@
1
+ 4c4
2
+ < four
3
+
4
+ ---
5
+ > four
@@ -0,0 +1,14 @@
1
+ *** test/fixtures/four_lines_with_missing_new_line 2025-01-31 12:17:43.926013315 +0100
2
+ --- test/fixtures/four_lines 2025-01-31 12:17:43.926013315 +0100
3
+ ***************
4
+ *** 1,4 ****
5
+ one
6
+ two
7
+ three
8
+ ! four
9
+
10
+ --- 1,4 ----
11
+ one
12
+ two
13
+ three
14
+ ! four
@@ -0,0 +1,9 @@
1
+ --- test/fixtures/four_lines_with_missing_new_line 2025-01-31 12:17:43.926013315 +0100
2
+ +++ test/fixtures/four_lines 2025-01-31 12:17:43.926013315 +0100
3
+ @@ -1,4 +1,4 @@
4
+ one
5
+ two
6
+ three
7
+ -four
8
+
9
+ +four
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "test_helper"
4
+ require "diff/lcs/block"
5
+
6
+ class TestBlock < Minitest::Test
7
+ include Diff::LCS::TestHelper
8
+
9
+ def test_op_unchanged
10
+ block = Diff::LCS::Block.from_chunk([])
11
+ assert_equal "^", block.op
12
+ end
13
+
14
+ def test_op_delete
15
+ changes = [Diff::LCS::Change.new("-", 0, "a")]
16
+ block = Diff::LCS::Block.from_chunk(changes)
17
+ assert_equal "-", block.op
18
+ end
19
+
20
+ def test_op_insert
21
+ changes = [Diff::LCS::Change.new("+", 0, "a")]
22
+ block = Diff::LCS::Block.from_chunk(changes)
23
+ assert_equal "+", block.op
24
+ end
25
+
26
+ def test_op_conflict
27
+ changes = [
28
+ Diff::LCS::Change.new("-", 0, "a"),
29
+ Diff::LCS::Change.new("+", 0, "b")
30
+ ]
31
+ block = Diff::LCS::Block.from_chunk(changes)
32
+ assert_equal "!", block.op
33
+ end
34
+ end
@@ -0,0 +1,234 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ class TestChange < Minitest::Test
6
+ def test_invalid_change
7
+ assert_raises RuntimeError, /Invalid CHange Action/ do
8
+ change("~", 0, "element")
9
+ end
10
+
11
+ assert_raises RuntimeError, /Invalid Position Type/ do
12
+ change("+", 3.5, "element")
13
+ end
14
+ end
15
+
16
+ def test_from_a
17
+ assert_kind_of Diff::LCS::Change, change_from_a(["+", 0, "element"])
18
+ assert_kind_of Diff::LCS::Change, change_from_a(["+", 0, "element"], Diff::LCS::ContextChange)
19
+ assert_kind_of Diff::LCS::ContextChange,
20
+ change_from_a(["!", [1, "old_element"], [2, "new_element"]])
21
+ assert_kind_of Diff::LCS::ContextChange,
22
+ change_from_a(["!", [1, "old_element"], [2, "new_element"]], Diff::LCS::ContextChange)
23
+
24
+ assert_raises RuntimeError, "Invalid change array format provided." do
25
+ change_from_a(["+", 0])
26
+ end
27
+
28
+ assert_raises RuntimeError, "Invalid change array format provided." do
29
+ change_from_a(["+", 0], Diff::LCS::ContextChange)
30
+ end
31
+ end
32
+
33
+ def test_spaceship_reflexive
34
+ c1 = change("=", 5, "x")
35
+ c2 = change("=", 5, "x")
36
+ assert_equal 0, c1 <=> c2
37
+ end
38
+
39
+ def test_spaceship_position_precedence
40
+ c1 = change("=", 5, "x")
41
+ c2 = change("=", 10, "x")
42
+
43
+ assert_equal(-1, c1 <=> c2)
44
+ assert_equal 1, c2 <=> c1
45
+ end
46
+
47
+ def test_spaceship_action_precedence
48
+ valid_actions.each_cons(2) do |a1, a2|
49
+ c1 = change(a1, 5, "x")
50
+ c2 = change(a2, 5, "x")
51
+
52
+ assert_equal(-1, c1 <=> c2, "#{a1} should sort before #{a2}")
53
+ assert_equal 1, c2 <=> c1
54
+ end
55
+ end
56
+
57
+ def test_spaceship_element_precedence
58
+ c1 = change("=", 5, "a")
59
+ c2 = change("=", 5, "z")
60
+
61
+ assert_equal(-1, c1 <=> c2)
62
+ assert_equal 1, c2 <=> c1
63
+ assert_equal 0, c1 <=> change("=", 5, "a")
64
+ end
65
+
66
+ def test_add
67
+ change = change("+", 0, "element")
68
+
69
+ assert change.adding?
70
+
71
+ refute change.deleting?
72
+ refute change.unchanged?
73
+ refute change.changed?
74
+ refute change.finished_a?
75
+ refute change.finished_b?
76
+ end
77
+
78
+ def test_delete
79
+ change = change("-", 0, "element")
80
+
81
+ assert change.deleting?
82
+
83
+ refute change.adding?
84
+ refute change.unchanged?
85
+ refute change.changed?
86
+ refute change.finished_a?
87
+ refute change.finished_b?
88
+ end
89
+
90
+ def test_unchanged
91
+ change = change("=", 0, "element")
92
+
93
+ assert change.unchanged?
94
+
95
+ refute change.deleting?
96
+ refute change.adding?
97
+ refute change.changed?
98
+ refute change.finished_a?
99
+ refute change.finished_b?
100
+ end
101
+
102
+ def test_changed
103
+ change = change("!", 0, "element")
104
+
105
+ assert change.changed?
106
+
107
+ refute change.deleting?
108
+ refute change.adding?
109
+ refute change.unchanged?
110
+ refute change.finished_a?
111
+ refute change.finished_b?
112
+ end
113
+
114
+ def test_finished_a
115
+ change = change(">", 0, "element")
116
+
117
+ assert change.finished_a?
118
+
119
+ refute change.deleting?
120
+ refute change.adding?
121
+ refute change.unchanged?
122
+ refute change.changed?
123
+ refute change.finished_b?
124
+ end
125
+
126
+ def test_finished_b
127
+ change = change("<", 0, "element")
128
+
129
+ assert change.finished_b?
130
+
131
+ refute change.deleting?
132
+ refute change.adding?
133
+ refute change.unchanged?
134
+ refute change.changed?
135
+ refute change.finished_a?
136
+ end
137
+
138
+ def test_as_array
139
+ action, position, element = change("!", 0, "element")
140
+ assert_equal "!", action
141
+ assert_equal 0, position
142
+ assert_equal "element", element
143
+ end
144
+ end
145
+
146
+ class TestContextChange < Minitest::Test
147
+ private def change(...) = Diff::LCS::ContextChange.new(...)
148
+ private def simplify(...) = Diff::LCS::ContextChange.simplify(change(...))
149
+
150
+ def test_invalid_change
151
+ assert_raises RuntimeError, /Invalid CHange Action/ do
152
+ change("~", 0, "old", 0, "new")
153
+ end
154
+
155
+ assert_raises RuntimeError, /Invalid Position Type/ do
156
+ change("+", 3.5, "old", 0, "new")
157
+ end
158
+
159
+ assert_raises RuntimeError, /Invalid Position Type/ do
160
+ change("+", 0, "old", 3.5, "new")
161
+ end
162
+ end
163
+
164
+ def test_as_array
165
+ action, old, new = change("!", 1, "old_element", 2, "new_element")
166
+
167
+ assert_equal "!", action
168
+ assert_equal [1, "old_element"], old
169
+ assert_equal [2, "new_element"], new
170
+ end
171
+
172
+ def test_spaceship_reflexive
173
+ c1 = change("=", 5, "x", 10, "y")
174
+ c2 = change("=", 5, "x", 10, "y")
175
+ assert_equal 0, c1 <=> c2
176
+ end
177
+
178
+ def test_spaceship_position_precedence
179
+ c1 = change("=", 5, "x", 10, "y")
180
+ c2 = change("=", 15, "x", 10, "y")
181
+
182
+ assert_equal(-1, c1 <=> c2)
183
+ assert_equal 1, c2 <=> c1
184
+
185
+ c1 = change("=", 5, "x", 10, "y")
186
+ c2 = change("=", 5, "x", 20, "y")
187
+
188
+ assert_equal(-1, c1 <=> c2)
189
+ assert_equal 1, c2 <=> c1
190
+ end
191
+
192
+ def test_spaceship_action_precedence
193
+ valid_actions.each_cons(2) do |a1, a2|
194
+ c1 = change(a1, 5, "x", 10, "y")
195
+ c2 = change(a2, 5, "x", 10, "y")
196
+
197
+ assert_equal(-1, c1 <=> c2, "#{a1} should sort before #{a2}")
198
+ assert_equal 1, c2 <=> c1
199
+ end
200
+ end
201
+
202
+ def test_spaceship_element_precedence
203
+ c1 = change("=", 5, "a", 10, "y")
204
+ c2 = change("=", 5, "z", 10, "y")
205
+
206
+ assert_equal(-1, c1 <=> c2, "old_element precedence")
207
+ assert_equal 1, c2 <=> c1
208
+
209
+ c3 = change("=", 5, "x", 10, "a")
210
+ c4 = change("=", 5, "x", 10, "z")
211
+
212
+ assert_equal(-1, c3 <=> c4, "new_element precedence")
213
+ assert_equal 1, c4 <=> c3
214
+ assert_equal 0, c3 <=> Diff::LCS::ContextChange.new("=", 5, "x", 10, "a")
215
+ end
216
+
217
+ def test_simplify
218
+ simplify("-", 5, "old", 10, "new") => {action:, new_element:}
219
+ assert_equal action, "-"
220
+ assert_nil new_element
221
+
222
+ simplify("<", 5, "old", 10, "new") => {action:, new_element:}
223
+ assert_equal action, "-"
224
+ assert_nil new_element
225
+
226
+ simplify("+", 5, "old", 10, "new") => {action:, old_element:}
227
+ assert_equal action, "+"
228
+ assert_nil old_element
229
+
230
+ simplify(">", 5, "old", 10, "new") => {action:, old_element:}
231
+ assert_equal action, "+"
232
+ assert_nil old_element
233
+ end
234
+ end
data/test/test_diff.rb ADDED
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "test_helper"
4
+
5
+ class TestDiff < Minitest::Test
6
+ def test_correctly_diffs_seq1_to_seq2
7
+ assert_equal change_diff(correct_forward_diff), diff(seq1, seq2)
8
+ end
9
+
10
+ def test_correctly_diffs_seq2_to_seq1
11
+ assert_equal change_diff(correct_backward_diff), diff(seq2, seq1)
12
+ end
13
+
14
+ def test_correctly_diffs_against_empty_sequence_forward
15
+ correct_diff = [
16
+ [
17
+ ["-", 0, "abcd"],
18
+ ["-", 1, "efgh"],
19
+ ["-", 2, "ijkl"],
20
+ ["-", 3, "mnopqrstuvwxyz"]
21
+ ]
22
+ ]
23
+
24
+ assert_equal change_diff(correct_diff), diff(word_sequence, [])
25
+ end
26
+
27
+ def test_correctly_diffs_against_empty_sequence_backward
28
+ correct_diff = [
29
+ [
30
+ ["+", 0, "abcd"],
31
+ ["+", 1, "efgh"],
32
+ ["+", 2, "ijkl"],
33
+ ["+", 3, "mnopqrstuvwxyz"]
34
+ ]
35
+ ]
36
+
37
+ assert_equal change_diff(correct_diff), diff([], word_sequence)
38
+ end
39
+
40
+ def test_correctly_diffs_xx_and_xaxb
41
+ left = "xx"
42
+ right = "xaxb"
43
+ assert_equal right, patch(left, diff(left, right))
44
+ end
45
+
46
+ def test_returns_empty_diff_with_hello_hello
47
+ assert_empty diff(hello, hello)
48
+ end
49
+
50
+ def test_returns_empty_diff_with_hello_ary_hello_ary
51
+ assert_empty diff(hello_ary, hello_ary)
52
+ end
53
+ end