Files
wehub-resource-sync a06f331eb8
CI / benchmark (push) Has been skipped
install-script / posix-syntax (push) Successful in 6m1s
CI / build-onnx (push) Failing after 6m43s
init-smoke / dry-run (push) Failing after 15m57s
security / govulncheck (push) Has been cancelled
security / trivy-fs (push) Has been cancelled
CI / test (1.26, ubuntu-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
CI / test (1.26, macos-latest) (push) Has been cancelled
CI / build-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
install-script / powershell-syntax (push) Has been cancelled
install-script / install (macos-14) (push) Has been cancelled
install-script / install (ubuntu-latest) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:33:42 +08:00

75 lines
3.4 KiB
Go

package resolver
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/zzet/gortex/internal/graph"
)
func rtkEndpointNode(g *graph.Graph, id, file, endpoint, kind string) {
g.AddNode(&graph.Node{ID: id, Kind: graph.KindFunction, Name: "api." + endpoint, FilePath: file, Meta: map[string]any{"rtk_endpoint": endpoint, "rtk_kind": kind}})
}
func rtkHookNode(g *graph.Graph, id, file, name string) {
g.AddNode(&graph.Node{ID: id, Kind: graph.KindFunction, Name: name, FilePath: file, Meta: map[string]any{"rtk_generated_hook": true}})
}
func synthRTKEdge(g graph.Store, from, to string) *graph.Edge {
for e := range g.EdgesByKind(graph.EdgeCalls) {
if e == nil || e.From != from || e.To != to || e.Meta == nil {
continue
}
if by, _ := e.Meta[MetaSynthesizedBy].(string); by == SynthRTKQuery {
return e
}
}
return nil
}
func TestResolveRTKQueryCalls_HookToEndpointAndComponentToHook(t *testing.T) {
g := graph.New()
rtkEndpointNode(g, "api.ts::api.getUser", "api.ts", "getUser", "query")
rtkHookNode(g, "api.ts::useGetUserQuery", "api.ts", "useGetUserQuery")
// generated-hook → endpoint placeholder.
g.AddEdge(&graph.Edge{From: "api.ts::useGetUserQuery", To: "unresolved::*.getUser", Kind: graph.EdgeCalls, FilePath: "api.ts", Meta: map[string]any{"via": rtkQueryVia, "rtk_endpoint": "getUser"}})
// component → hook, left unresolved by the generic resolver (cross-file).
g.AddNode(&graph.Node{ID: "page.tsx::Profile", Kind: graph.KindFunction, Name: "Profile", FilePath: "page.tsx"})
g.AddEdge(&graph.Edge{From: "page.tsx::Profile", To: "unresolved::useGetUserQuery", Kind: graph.EdgeCalls, FilePath: "page.tsx"})
n := ResolveRTKQueryCalls(g)
require.Equal(t, 2, n)
hookToEp := synthRTKEdge(g, "api.ts::useGetUserQuery", "api.ts::api.getUser")
require.NotNil(t, hookToEp, "hook should reach its endpoint")
assert.Equal(t, ConfidenceTyped, hookToEp.Confidence)
assert.Equal(t, ProvenanceFramework, hookToEp.Meta[MetaProvenance])
compToHook := synthRTKEdge(g, "page.tsx::Profile", "api.ts::useGetUserQuery")
require.NotNil(t, compToHook, "component call binds to the generated hook")
assert.Equal(t, ProvenanceFramework, compToHook.Meta[MetaProvenance])
}
func TestResolveRTKQueryCalls_UnknownEndpointStaysPlaceholder(t *testing.T) {
g := graph.New()
rtkHookNode(g, "api.ts::useFooQuery", "api.ts", "useFooQuery")
rtkEndpointNode(g, "api.ts::api.bar", "api.ts", "bar", "query") // different endpoint
g.AddEdge(&graph.Edge{From: "api.ts::useFooQuery", To: "unresolved::*.foo", Kind: graph.EdgeCalls, FilePath: "api.ts", Meta: map[string]any{"via": rtkQueryVia, "rtk_endpoint": "foo"}})
assert.Equal(t, 0, ResolveRTKQueryCalls(g))
assert.Nil(t, synthRTKEdge(g, "api.ts::useFooQuery", "api.ts::api.bar"))
}
func TestResolveRTKQueryCalls_SameCreateApiFileGate(t *testing.T) {
// An endpoint named getUser in a different file must not bind the hook.
g := graph.New()
rtkHookNode(g, "a.ts::useGetUserQuery", "a.ts", "useGetUserQuery")
rtkEndpointNode(g, "b.ts::api.getUser", "b.ts", "getUser", "query")
g.AddEdge(&graph.Edge{From: "a.ts::useGetUserQuery", To: "unresolved::*.getUser", Kind: graph.EdgeCalls, FilePath: "a.ts", Meta: map[string]any{"via": rtkQueryVia, "rtk_endpoint": "getUser"}})
assert.Equal(t, 0, ResolveRTKQueryCalls(g), "cross-file endpoint must not bind")
assert.Nil(t, synthRTKEdge(g, "a.ts::useGetUserQuery", "b.ts::api.getUser"))
}