summaryrefslogtreecommitdiff
path: root/llm-tools-hl-test.el
diff options
context:
space:
mode:
Diffstat (limited to 'llm-tools-hl-test.el')
-rw-r--r--llm-tools-hl-test.el180
1 files changed, 179 insertions, 1 deletions
diff --git a/llm-tools-hl-test.el b/llm-tools-hl-test.el
index 4bc0fa0..85777c8 100644
--- a/llm-tools-hl-test.el
+++ b/llm-tools-hl-test.el
@@ -2,7 +2,7 @@
2(require 'llm-tools-hl) 2(require 'llm-tools-hl)
3 3
4(ert-deftest llm-tools--hl-file-read-test () 4(ert-deftest llm-tools--hl-file-read-test ()
5 "Test that 'llm-tools--hl-file-read' produces correct hashline format." 5 "Test that 'llm-tools--hl-file-read' produces correct hashline format."
6 (let* ((content "\ 6 (let* ((content "\
7const TITLE = \"Mr\"; 7const TITLE = \"Mr\";
8export function greet(name) { 8export function greet(name) {
@@ -23,3 +23,181 @@ export function greet(name) {
23 (unwind-protect 23 (unwind-protect
24 (should (equal actual expected)) 24 (should (equal actual expected))
25 (delete-file file)))) 25 (delete-file file))))
26
27(ert-deftest llm-tools--hl-anchor-to-line-num-test ()
28 (should (= (llm-tools--hl-anchor-to-line-num "5ff") 5))
29 (should (= (llm-tools--hl-anchor-to-line-num "123ab") 123))
30 (should (= (llm-tools--hl-anchor-to-line-num "1vx") 1)))
31
32(ert-deftest llm-tools--hl-parse-section-single-replace ()
33 (let ((section "= 1vx..1vx\n~const TITLE = \"Mrs\";"))
34 (should (= (length (llm-tools--hl-parse-section section)) 1))
35 (let ((op (car (llm-tools--hl-parse-section section))))
36 (should (eq (hl-op-type op) 'replace))
37 (should (equal (hl-op-range op) '("1vx" "1vx")))
38 (should (equal (hl-op-payload op) '("const TITLE = \"Mrs\";"))))))
39
40(ert-deftest llm-tools--hl-parse-section-multi-line-payload ()
41 (let ((section "= 3gv..6be\n~\treturn [\n~\t\t\"Mrs\",\n~\t\tname?.trim() || \"guest\",\n~\t].join(\" \");"))
42 (let ((op (car (llm-tools--hl-parse-section section))))
43 (should (= (length (hl-op-payload op)) 4)))))
44
45(ert-deftest llm-tools--hl-parse-section-blank-replace ()
46 "Replace with no payload should produce nil payload, not empty list."
47 (let ((section "= 5ff..5ff"))
48 (let ((op (car (llm-tools--hl-parse-section section))))
49 (should (eq (hl-op-type op) 'replace))
50 (should (null (hl-op-payload op))))))
51
52(ert-deftest llm-tools--hl-parse-section-insert-after ()
53 (let ((section "+ 4ei\n~\t\t\"Dr\","))
54 (let ((op (car (llm-tools--hl-parse-section section))))
55 (should (eq (hl-op-type op) 'insert-after))
56 (should (string= (hl-op-anchor op) "4ei"))
57 (should (equal (hl-op-payload op) '("\t\t\"Dr\","))))))
58
59(ert-deftest llm-tools--hl-parse-section-insert-before ()
60 (let ((section "< 5ff\n~\t\t\"Dr\","))
61 (let ((op (car (llm-tools--hl-parse-section section))))
62 (should (eq (hl-op-type op) 'insert-before))
63 (should (string= (hl-op-anchor op) "5ff")))))
64
65(ert-deftest llm-tools--hl-parse-section-delete ()
66 (let ((section "- 5ff..5ff"))
67 (let ((op (car (llm-tools--hl-parse-section section))))
68 (should (eq (hl-op-type op) 'delete))
69 (should (equal (hl-op-range op) '("5ff" "5ff"))))))
70
71(ert-deftest llm-tools--hl-parse-section-skip-comments-and-blanks ()
72 (let ((section "# comment\n\n+ 4ei\n~line"))
73 (should (= (length (llm-tools--hl-parse-section section)) 1))))
74
75(ert-deftest llm-tools--hl-parse-section-multiple-ops ()
76 "Two separate insert ops in one section."
77 (let ((section "+ 4ei\n~first\n< 5ff\n~second"))
78 (let ((ops (llm-tools--hl-parse-section section)))
79 (should (= (length ops) 2))
80 (should (eq (hl-op-type (car ops)) 'insert-after))
81 (should (eq (hl-op-type (cadr ops)) 'insert-before)))))
82
83(ert-deftest llm-tools--hl-apply-replace-single-line ()
84 (let* ((content "line1\nline2\nline3\n")
85 (file (make-temp-file nil nil nil content))
86 (patch (format "@@ test\n= 2%s..2%s\n~REPLACED" (elt 1 (llm-tools--hl-hash (string-lines content))))))
87 (unwind-protect
88 (progn
89 (llm-tools--hl-apply patch)
90 (should (string= (llm-tools--hl-file-read file)
91 (string-join
92 (list (format "1%s|line1" (llm-tools--hl-hash "line1"))
93 (format "2%s|REPLACED" (llm-tools--hl-hash "REPLACED"))
94 (format "3%s|line3" (llm-tools--hl-hash "line3")))
95 "\n"))))
96 (delete-file file))))
97
98(ert-deftest llm-tools--hl-apply-insert-after ()
99 (let* ((content "A\nB\nC\n")
100 (file (make-temp-file nil nil nil content))
101 (anchor (format "+ %s" (llm-tools--hl-file-line-hash file 1)))
102 (patch (concat "@@ test\n" anchor "\n~NEW")))
103 (unwind-protect
104 (progn
105 (llm-tools--hl-apply patch)
106 (let ((lines (llm-tools--hl-file-lines file)))
107 (should (equal lines '("A" "NEW" "B" "C")))))
108 (delete-file file))))
109
110(ert-deftest llm-tools--hl-apply-insert-before ()
111 (let* ((content "A\nB\nC\n")
112 (file (make-temp-file nil nil nil content))
113 (anchor (format "< %s" (llm-tools--hl-file-line-hash file 3)))
114 (patch (concat "@@ test\n" anchor "\n~NEW")))
115 (unwind-protect
116 (progn
117 (llm-tools--hl-apply patch)
118 (let ((lines (llm-tools--hl-file-lines file)))
119 (should (equal lines '("A" "B" "NEW" "C")))))
120 (delete-file file))))
121
122(ert-deftest llm-tools--hl-apply-append-to-eof ()
123 (let* ((content "A\nB\n")
124 (file (make-temp-file nil nil nil content))
125 (patch "@@ test\n+ EOF\n~APPENDED"))
126 (unwind-protect
127 (progn
128 (llm-tools--hl-apply patch)
129 (let ((lines (llm-tools--hl-file-lines file)))
130 (should (equal lines '("A" "B" "APPENDED")))))
131 (delete-file file))))
132
133(ert-deftest llm-tools--hl-apply-delete ()
134 (let* ((content "A\nB\nC\n")
135 (file (make-temp-file nil nil nil content))
136 (anchor (llm-tools--hl-file-line-hash file 2))
137 (patch (format "@@ test\n- 2%s..2%s" anchor anchor)))
138 (unwind-protect
139 (progn
140 (llm-tools--hl-apply patch)
141 (let ((lines (llm-tools--hl-file-lines file)))
142 (should (equal lines '("A" "C")))))
143 (delete-file file))))
144
145(ert-deftest llm-tools--hl-apply-blank-line ()
146 "Replace with no payload produces a blank line."
147 (let* ((content "A\nB\nC\n")
148 (file (make-temp-file nil nil nil content))
149 (anchor (llm-tools--hl-file-line-hash file 2))
150 (patch (format "@@ test\n= 2%s..2%s" anchor anchor)))
151 (unwind-protect
152 (progn
153 (llm-tools--hl-apply patch)
154 (let ((lines (llm-tools--hl-file-lines file)))
155 (should (equal lines '("A" "" "C")))))
156 (delete-file file))))
157
158(ert-deftest llm-tools--hl-apply-offset-tracking ()
159 "Multiple ops in one file: verify offset adjusts subsequent line numbers."
160 (let* ((content "A\nB\nC\nD\nE\n")
161 (file (make-temp-file nil nil nil content))
162 (a1 (llm-tools--hl-file-line-hash file 1))
163 (a3 (llm-tools--hl-file-line-hash file 3))
164 ;; Insert 2 lines after line 1, then delete original line 3
165 (patch (format "@@ test\n+ 1%s\n~X\n~Y\n- 3%s..3%s" a1 a3 a3)))
166 (unwind-protect
167 (progn
168 (llm-tools--hl-apply patch)
169 ;; After insert: A X Y B C D E (offset = +2)
170 ;; Original line 3 (C) is now at index 5 (1-based). Delete it.
171 ;; Result: A X Y B D E
172 (let ((lines (llm-tools--hl-file-lines file)))
173 (should (equal lines '("A" "X" "Y" "B" "D" "E")))))
174 (delete-file file))))
175
176(ert-deftest llm-tools--hl-apply-multi-file ()
177 "Two files in one patch both get modified."
178 (let* ((file1 (make-temp-file nil nil nil "A\nB\n"))
179 (file2 (make-temp-file nil nil nil "X\nY\n"))
180 (a1 (llm-tools--hl-file-line-hash file1 1))
181 (a2 (llm-tools--hl-file-line-hash file2 2))
182 (patch (format "@@ %s\n+ 1%s\n~NEW1\n@@ %s\n= 2%s..2%s\n~NEW2"
183 file1 a1 file2 a2 a2)))
184 (unwind-protect
185 (progn
186 (llm-tools--hl-apply patch)
187 (should (equal (llm-tools--hl-file-lines file1) '("A" "NEW1" "B")))
188 (should (equal (llm-tools--hl-file-lines file2) '("X" "NEW2"))))
189 (delete-file file1)
190 (delete-file file2))))
191
192(ert-deftest llm-tools--hl-apply-multi-line-payload ()
193 "Replace with many payload lines."
194 (let* ((content "A\nB\n")
195 (file (make-temp-file nil nil nil content))
196 (a1 (llm-tools--hl-file-line-hash file 1))
197 (patch (format "@@ test\n= 1%s..1%s\n~ONE\n~TWO\n~THREE" a1 a1)))
198 (unwind-protect
199 (progn
200 (llm-tools--hl-apply patch)
201 (let ((lines (llm-tools--hl-file-lines file)))
202 (should (equal lines '("ONE" "TWO" "THREE" "B")))))
203 (delete-file file))))