1package patchutil
2
3import (
4 "reflect"
5 "testing"
6)
7
8func TestIsPatchValid(t *testing.T) {
9 tests := []struct {
10 name string
11 patch string
12 expected bool
13 }{
14 {
15 name: `empty patch`,
16 patch: ``,
17 expected: false,
18 },
19 {
20 name: `single line patch`,
21 patch: `single line`,
22 expected: false,
23 },
24 {
25 name: `valid diff patch`,
26 patch: `diff --git a/file.txt b/file.txt
27index abc..def 100644
28--- a/file.txt
29+++ b/file.txt
30@@ -1,3 +1,3 @@
31-old line
32+new line
33 context`,
34 expected: true,
35 },
36 {
37 name: `valid patch starting with ---`,
38 patch: `--- a/file.txt
39+++ b/file.txt
40@@ -1,3 +1,3 @@
41-old line
42+new line
43 context`,
44 expected: true,
45 },
46 {
47 name: `valid patch starting with Index`,
48 patch: `Index: file.txt
49==========
50--- a/file.txt
51+++ b/file.txt
52@@ -1,3 +1,3 @@
53-old line
54+new line
55 context`,
56 expected: true,
57 },
58 {
59 name: `valid patch starting with +++`,
60 patch: `+++ b/file.txt
61--- a/file.txt
62@@ -1,3 +1,3 @@
63-old line
64+new line
65 context`,
66 expected: true,
67 },
68 {
69 name: `valid patch starting with @@`,
70 patch: `@@ -1,3 +1,3 @@
71-old line
72+new line
73 context
74`,
75 expected: true,
76 },
77 {
78 name: `valid format patch`,
79 patch: `From 3c5035488318164b81f60fe3adcd6c9199d76331 Mon Sep 17 00:00:00 2001
80From: Author <author@example.com>
81Date: Wed, 16 Apr 2025 11:01:00 +0300
82Subject: [PATCH] Example patch
83
84diff --git a/file.txt b/file.txt
85index 123456..789012 100644
86--- a/file.txt
87+++ b/file.txt
88@@ -1 +1 @@
89-old content
90+new content
91--
922.48.1`,
93 expected: true,
94 },
95 {
96 name: `invalid format patch`,
97 patch: `From 1234567890123456789012345678901234567890 Mon Sep 17 00:00:00 2001
98From: Author <author@example.com>
99This is not a valid patch format`,
100 expected: false,
101 },
102 {
103 name: `not a patch at all`,
104 patch: `This is
105just some
106random text
107that isn't a patch`,
108 expected: false,
109 },
110 }
111
112 for _, tt := range tests {
113 t.Run(tt.name, func(t *testing.T) {
114 result := IsPatchValid(tt.patch)
115 if result != tt.expected {
116 t.Errorf("IsPatchValid() = %v, want %v", result, tt.expected)
117 }
118 })
119 }
120}
121
122func TestSplitPatches(t *testing.T) {
123 tests := []struct {
124 name string
125 input string
126 expected []string
127 }{
128 {
129 name: "Empty input",
130 input: "",
131 expected: []string{},
132 },
133 {
134 name: "No valid patches",
135 input: "This is not a \nJust some random text",
136 expected: []string{},
137 },
138 {
139 name: "Single patch",
140 input: `From 3c5035488318164b81f60fe3adcd6c9199d76331 Mon Sep 17 00:00:00 2001
141From: Author <author@example.com>
142Date: Wed, 16 Apr 2025 11:01:00 +0300
143Subject: [PATCH] Example patch
144
145diff --git a/file.txt b/file.txt
146index 123456..789012 100644
147--- a/file.txt
148+++ b/file.txt
149@@ -1 +1 @@
150-old content
151+new content
152--
1532.48.1`,
154 expected: []string{
155 `From 3c5035488318164b81f60fe3adcd6c9199d76331 Mon Sep 17 00:00:00 2001
156From: Author <author@example.com>
157Date: Wed, 16 Apr 2025 11:01:00 +0300
158Subject: [PATCH] Example patch
159
160diff --git a/file.txt b/file.txt
161index 123456..789012 100644
162--- a/file.txt
163+++ b/file.txt
164@@ -1 +1 @@
165-old content
166+new content
167--
1682.48.1`,
169 },
170 },
171 {
172 name: "Two patches",
173 input: `From 3c5035488318164b81f60fe3adcd6c9199d76331 Mon Sep 17 00:00:00 2001
174From: Author <author@example.com>
175Date: Wed, 16 Apr 2025 11:01:00 +0300
176Subject: [PATCH 1/2] First patch
177
178diff --git a/file1.txt b/file1.txt
179index 123456..789012 100644
180--- a/file1.txt
181+++ b/file1.txt
182@@ -1 +1 @@
183-old content
184+new content
185--
1862.48.1
187From a9529f3b3a653329a5268f0f4067225480207e3c Mon Sep 17 00:00:00 2001
188From: Author <author@example.com>
189Date: Wed, 16 Apr 2025 11:03:11 +0300
190Subject: [PATCH 2/2] Second patch
191
192diff --git a/file2.txt b/file2.txt
193index abcdef..ghijkl 100644
194--- a/file2.txt
195+++ b/file2.txt
196@@ -1 +1 @@
197-foo bar
198+baz qux
199--
2002.48.1`,
201 expected: []string{
202 `From 3c5035488318164b81f60fe3adcd6c9199d76331 Mon Sep 17 00:00:00 2001
203From: Author <author@example.com>
204Date: Wed, 16 Apr 2025 11:01:00 +0300
205Subject: [PATCH 1/2] First patch
206
207diff --git a/file1.txt b/file1.txt
208index 123456..789012 100644
209--- a/file1.txt
210+++ b/file1.txt
211@@ -1 +1 @@
212-old content
213+new content
214--
2152.48.1`,
216 `From a9529f3b3a653329a5268f0f4067225480207e3c Mon Sep 17 00:00:00 2001
217From: Author <author@example.com>
218Date: Wed, 16 Apr 2025 11:03:11 +0300
219Subject: [PATCH 2/2] Second patch
220
221diff --git a/file2.txt b/file2.txt
222index abcdef..ghijkl 100644
223--- a/file2.txt
224+++ b/file2.txt
225@@ -1 +1 @@
226-foo bar
227+baz qux
228--
2292.48.1`,
230 },
231 },
232 {
233 name: "Patches with additional text between them",
234 input: `Some text before the patches
235
236From 3c5035488318164b81f60fe3adcd6c9199d76331 Mon Sep 17 00:00:00 2001
237From: Author <author@example.com>
238Subject: [PATCH] First patch
239
240diff content here
241--
2422.48.1
243
244Some text between patches
245
246From a9529f3b3a653329a5268f0f4067225480207e3c Mon Sep 17 00:00:00 2001
247From: Author <author@example.com>
248Subject: [PATCH] Second patch
249
250more diff content
251--
2522.48.1
253
254Text after patches`,
255 expected: []string{
256 `From 3c5035488318164b81f60fe3adcd6c9199d76331 Mon Sep 17 00:00:00 2001
257From: Author <author@example.com>
258Subject: [PATCH] First patch
259
260diff content here
261--
2622.48.1
263
264Some text between patches`,
265 `From a9529f3b3a653329a5268f0f4067225480207e3c Mon Sep 17 00:00:00 2001
266From: Author <author@example.com>
267Subject: [PATCH] Second patch
268
269more diff content
270--
2712.48.1
272
273Text after patches`,
274 },
275 },
276 {
277 name: "Patches with whitespace padding",
278 input: `
279
280From 3c5035488318164b81f60fe3adcd6c9199d76331 Mon Sep 17 00:00:00 2001
281From: Author <author@example.com>
282Subject: Patch
283
284content
285--
2862.48.1
287
288
289From a9529f3b3a653329a5268f0f4067225480207e3c Mon Sep 17 00:00:00 2001
290From: Author <author@example.com>
291Subject: Another patch
292
293content
294--
2952.48.1
296 `,
297 expected: []string{
298 `From 3c5035488318164b81f60fe3adcd6c9199d76331 Mon Sep 17 00:00:00 2001
299From: Author <author@example.com>
300Subject: Patch
301
302content
303--
3042.48.1`,
305 `From a9529f3b3a653329a5268f0f4067225480207e3c Mon Sep 17 00:00:00 2001
306From: Author <author@example.com>
307Subject: Another patch
308
309content
310--
3112.48.1`,
312 },
313 },
314 }
315
316 for _, tt := range tests {
317 t.Run(tt.name, func(t *testing.T) {
318 result := splitFormatPatch(tt.input)
319 if !reflect.DeepEqual(result, tt.expected) {
320 t.Errorf("splitPatches() = %v, want %v", result, tt.expected)
321 }
322 })
323 }
324}