main
semdiff_lang_test.go
Eric Bower
·
2026-02-25
1package patchbin
2
3import (
4 "testing"
5)
6
7const sampleJSDiff = `diff --git a/foo.js b/foo.js
8index 1111111..2222222 100644
9--- a/foo.js
10+++ b/foo.js
11@@ -1,5 +1,9 @@
12 module.exports = {};
13
14-function add(a) {
15- return a
16+function add(a, b) {
17+ return a + b
18+}
19+
20+function sub(a, b) {
21+ return a - b
22 }
23`
24
25func TestSemanticChangesJavaScript(t *testing.T) {
26 files, _, err := ParsePatch(sampleJSDiff)
27 if err != nil {
28 t.Fatalf("ParsePatch: %v", err)
29 }
30 if len(files) != 1 {
31 t.Fatalf("expected 1 file, got %d", len(files))
32 }
33
34 changes := AnalyzeSemanticChanges(files[0])
35 if len(changes) == 0 {
36 t.Fatalf("expected semantic changes, got none")
37 }
38
39 var sawAdd, sawSub bool
40 for _, c := range changes {
41 t.Logf("change: kind=%s entity=%s name=%s oldSig=%q newSig=%q hunk=%d",
42 c.Kind, c.EntityKind, c.Name, c.OldSig, c.NewSig, c.HunkIndex)
43 if c.Name == "add" && c.Kind == SemanticSignatureChanged {
44 sawAdd = true
45 }
46 if c.Name == "sub" && c.Kind == SemanticAdded {
47 sawSub = true
48 }
49 }
50
51 if !sawAdd {
52 t.Errorf("expected add to be reported as signature_changed")
53 }
54 if !sawSub {
55 t.Errorf("expected sub to be reported as added")
56 }
57}
58
59const sampleTSDiff = `diff --git a/foo.ts b/foo.ts
60index 1111111..2222222 100644
61--- a/foo.ts
62+++ b/foo.ts
63@@ -1,5 +1,9 @@
64 export {};
65
66-function add(a: number): number {
67- return a
68+function add(a: number, b: number): number {
69+ return a + b
70+}
71+
72+function sub(a: number, b: number): number {
73+ return a - b
74 }
75`
76
77func TestSemanticChangesTypeScript(t *testing.T) {
78 files, _, err := ParsePatch(sampleTSDiff)
79 if err != nil {
80 t.Fatalf("ParsePatch: %v", err)
81 }
82 if len(files) != 1 {
83 t.Fatalf("expected 1 file, got %d", len(files))
84 }
85
86 changes := AnalyzeSemanticChanges(files[0])
87 if len(changes) == 0 {
88 t.Fatalf("expected semantic changes, got none")
89 }
90
91 var sawAdd, sawSub bool
92 for _, c := range changes {
93 t.Logf("change: kind=%s entity=%s name=%s oldSig=%q newSig=%q hunk=%d",
94 c.Kind, c.EntityKind, c.Name, c.OldSig, c.NewSig, c.HunkIndex)
95 if c.Name == "add" && c.Kind == SemanticSignatureChanged {
96 sawAdd = true
97 }
98 if c.Name == "sub" && c.Kind == SemanticAdded {
99 sawSub = true
100 }
101 }
102
103 if !sawAdd {
104 t.Errorf("expected add to be reported as signature_changed")
105 }
106 if !sawSub {
107 t.Errorf("expected sub to be reported as added")
108 }
109}
110
111const samplePyDiff = `diff --git a/foo.py b/foo.py
112index 1111111..2222222 100644
113--- a/foo.py
114+++ b/foo.py
115@@ -1,4 +1,7 @@
116 import os
117
118-def add(a):
119- return a
120+def add(a, b):
121+ return a + b
122+
123+def sub(a, b):
124+ return a - b
125`
126
127func TestSemanticChangesPython(t *testing.T) {
128 files, _, err := ParsePatch(samplePyDiff)
129 if err != nil {
130 t.Fatalf("ParsePatch: %v", err)
131 }
132 if len(files) != 1 {
133 t.Fatalf("expected 1 file, got %d", len(files))
134 }
135
136 changes := AnalyzeSemanticChanges(files[0])
137 if len(changes) == 0 {
138 t.Fatalf("expected semantic changes, got none")
139 }
140
141 var sawAdd, sawSub bool
142 for _, c := range changes {
143 t.Logf("change: kind=%s entity=%s name=%s oldSig=%q newSig=%q hunk=%d",
144 c.Kind, c.EntityKind, c.Name, c.OldSig, c.NewSig, c.HunkIndex)
145 if c.Name == "add" && c.Kind == SemanticSignatureChanged {
146 sawAdd = true
147 }
148 if c.Name == "sub" && c.Kind == SemanticAdded {
149 sawSub = true
150 }
151 }
152
153 if !sawAdd {
154 t.Errorf("expected add to be reported as signature_changed")
155 }
156 if !sawSub {
157 t.Errorf("expected sub to be reported as added")
158 }
159}
160
161const sampleRustDiff = `diff --git a/foo.rs b/foo.rs
162index 1111111..2222222 100644
163--- a/foo.rs
164+++ b/foo.rs
165@@ -1,5 +1,9 @@
166 mod foo;
167
168-fn add(a: i32) -> i32 {
169- return a
170+fn add(a: i32, b: i32) -> i32 {
171+ return a + b
172+}
173+
174+fn sub(a: i32, b: i32) -> i32 {
175+ return a - b
176 }
177`
178
179func TestSemanticChangesRust(t *testing.T) {
180 files, _, err := ParsePatch(sampleRustDiff)
181 if err != nil {
182 t.Fatalf("ParsePatch: %v", err)
183 }
184 if len(files) != 1 {
185 t.Fatalf("expected 1 file, got %d", len(files))
186 }
187
188 changes := AnalyzeSemanticChanges(files[0])
189 if len(changes) == 0 {
190 t.Fatalf("expected semantic changes, got none")
191 }
192
193 var sawAdd, sawSub bool
194 for _, c := range changes {
195 t.Logf("change: kind=%s entity=%s name=%s oldSig=%q newSig=%q hunk=%d",
196 c.Kind, c.EntityKind, c.Name, c.OldSig, c.NewSig, c.HunkIndex)
197 if c.Name == "add" && c.Kind == SemanticSignatureChanged {
198 sawAdd = true
199 }
200 if c.Name == "sub" && c.Kind == SemanticAdded {
201 sawSub = true
202 }
203 }
204
205 if !sawAdd {
206 t.Errorf("expected add to be reported as signature_changed")
207 }
208 if !sawSub {
209 t.Errorf("expected sub to be reported as added")
210 }
211}