-
Notifications
You must be signed in to change notification settings - Fork 52
Expand file tree
/
Copy pathcsharp_function_shape_test.go
More file actions
158 lines (143 loc) · 3.77 KB
/
Copy pathcsharp_function_shape_test.go
File metadata and controls
158 lines (143 loc) · 3.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
package languages
import (
"testing"
"github.com/zzet/gortex/internal/graph"
)
func runCSharpExtract(t *testing.T, path, src string) ([]*graph.Node, []*graph.Edge) {
t.Helper()
ext := NewCSharpExtractor()
result, err := ext.Extract(path, []byte(src))
if err != nil {
t.Fatalf("extract: %v", err)
}
return result.Nodes, result.Edges
}
func TestCSharpAsyncSpawns_AwaitInvocation(t *testing.T) {
src := `using System.Threading.Tasks;
public class Svc {
public async Task<User> Load(int id) {
var u = await FetchUser(id);
var r = await client.Query();
return u;
}
}
`
_, edges := runCSharpExtract(t, "x/Svc.cs", src)
spawns := edgesByKind(edges, graph.EdgeSpawns)
want := map[string]bool{"unresolved::FetchUser": false, "unresolved::Query": false}
for _, e := range spawns {
if mode, _ := e.Meta["mode"].(string); mode != "async" {
continue
}
if _, ok := want[e.To]; ok {
want[e.To] = true
}
}
for tgt, found := range want {
if !found {
t.Errorf("expected EdgeSpawns mode=async → %s; got %v", tgt, edgeTargets(spawns))
}
}
}
func TestCSharpFunctionShape_MethodParamsAndReturn(t *testing.T) {
src := `using System.Threading.Tasks;
public class Svc {
public Task<User> Lookup(int id, AuthCtx ctx) { return null; }
}
`
nodes, edges := runCSharpExtract(t, "x/Svc.cs", src)
params := nodesOfKind(nodes, graph.KindParam)
if len(params) != 2 {
t.Fatalf("expected 2 params, got %d: %v", len(params), nodeNames(params))
}
typed := edgesByKind(edges, graph.EdgeTypedAs)
hasAuthCtx := false
for _, e := range typed {
if e.To == "unresolved::AuthCtx" {
hasAuthCtx = true
}
}
if !hasAuthCtx {
t.Errorf("expected EdgeTypedAs → AuthCtx; got %v", edgeTargets(typed))
}
returns := edgesByKind(edges, graph.EdgeReturns)
hasUser := false
for _, e := range returns {
if e.To == "unresolved::User" {
hasUser = true
}
}
if !hasUser {
t.Errorf("expected EdgeReturns → User (Task unwrapped); got %v", edgeTargets(returns))
}
}
func TestCSharpFunctionShape_ClassLevelGeneric(t *testing.T) {
src := `public class Repo<T> {}
`
nodes, _ := runCSharpExtract(t, "x/Repo.cs", src)
gp := nodesOfKind(nodes, graph.KindGenericParam)
hasT := false
for _, n := range gp {
if n.Name == "T" {
hasT = true
}
}
if !hasT {
t.Fatalf("expected KindGenericParam T at class level; got %v", nodeNames(gp))
}
}
func TestCSharpFunctionShape_ConstructorParams(t *testing.T) {
src := `public class Svc {
public Svc(IRepo repo, IAuth auth) {}
}
`
_, edges := runCSharpExtract(t, "x/Svc.cs", src)
params := edgesByKind(edges, graph.EdgeParamOf)
hasCtor := false
for _, e := range params {
if e.To == "x/Svc.cs::Svc.<init>" {
hasCtor = true
}
}
if !hasCtor {
t.Errorf("expected EdgeParamOf for ctor; got %v", edgeTargets(params))
}
typed := edgesByKind(edges, graph.EdgeTypedAs)
hasIRepo := false
for _, e := range typed {
if e.To == "unresolved::IRepo" {
hasIRepo = true
}
}
if !hasIRepo {
t.Errorf("expected EdgeTypedAs → IRepo; got %v", edgeTargets(typed))
}
}
func TestCSharpAsyncSpawns_TaskRun(t *testing.T) {
src := `using System.Threading.Tasks;
public class Bg {
public void Kick() {
Task.Run(() => Worker());
ThreadPool.QueueUserWorkItem(_ => Worker());
}
}
`
_, edges := runCSharpExtract(t, "x/Bg.cs", src)
spawns := edgesByKind(edges, graph.EdgeSpawns)
hasTaskRun := false
hasThreadPool := false
for _, e := range spawns {
if e.To == "unresolved::Task.Run" {
hasTaskRun = true
}
if e.To == "unresolved::ThreadPool.QueueUserWorkItem" {
hasThreadPool = true
}
}
if !hasTaskRun {
t.Errorf("expected EdgeSpawns → Task.Run; got %v", edgeTargets(spawns))
}
if !hasThreadPool {
t.Errorf("expected EdgeSpawns → ThreadPool.QueueUserWorkItem; got %v", edgeTargets(spawns))
}
}