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

114 lines
2.8 KiB
Go

package languages
import (
"testing"
"github.com/zzet/gortex/internal/graph"
)
func TestGoChannels_SendStatement(t *testing.T) {
src := `package foo
func Run(ch chan int) {
ch <- 1
ch <- 2
}
`
fix := runGoExtract(t, src)
sends := fix.edgesByKind[graph.EdgeSends]
if len(sends) != 2 {
t.Fatalf("expected 2 EdgeSends, got %d", len(sends))
}
for _, e := range sends {
if e.From != "pkg/foo.go::Run" {
t.Errorf("from = %q", e.From)
}
if e.To != "unresolved::ch" {
t.Errorf("to = %q", e.To)
}
}
}
func TestGoChannels_RecvExpression(t *testing.T) {
src := `package foo
func Run(ch chan int) int {
x := <-ch
return x
}
`
fix := runGoExtract(t, src)
recvs := fix.edgesByKind[graph.EdgeRecvs]
if len(recvs) != 1 {
t.Fatalf("expected 1 EdgeRecvs, got %d: %+v", len(recvs), recvs)
}
if recvs[0].To != "unresolved::ch" {
t.Errorf("to = %q", recvs[0].To)
}
}
func TestGoChannels_SelectStatement(t *testing.T) {
src := `package foo
func Run(in chan int, out chan int) {
select {
case v := <-in:
out <- v
case <-in:
}
}
`
fix := runGoExtract(t, src)
if got := len(fix.edgesByKind[graph.EdgeSends]); got != 1 {
t.Errorf("expected 1 send (out <- v), got %d", got)
}
if got := len(fix.edgesByKind[graph.EdgeRecvs]); got != 2 {
t.Errorf("expected 2 recvs (both <-in branches), got %d", got)
}
}
func TestGoChannels_NoFalsePositiveOnNonChannelCode(t *testing.T) {
src := `package foo
func Run(x int) int {
return -x
}
`
fix := runGoExtract(t, src)
if got := len(fix.edgesByKind[graph.EdgeSends]); got != 0 {
t.Errorf("unary minus must not produce sends, got %d", got)
}
if got := len(fix.edgesByKind[graph.EdgeRecvs]); got != 0 {
t.Errorf("unary minus must not produce recvs, got %d", got)
}
}
func TestGoChannels_ClosureBoundariesNotRecursed(t *testing.T) {
// Channel ops inside a closure body should be walked when the
// closure's own emitGoFunctionShape runs (closures are
// extracted as separate function-shape nodes), not by the
// outer function's walker. This test pins the v1 stance —
// channel ops inside `func() {...}` don't fall through to the
// outer Run.
src := `package foo
func Run(ch chan int) {
go func() {
ch <- 1
}()
}
`
fix := runGoExtract(t, src)
sends := fix.edgesByKind[graph.EdgeSends]
// The send happens inside a func_literal — the outer Run's
// walker stops at func_literal boundaries, and the closure
// node itself doesn't (yet) get its body re-walked for
// channel ops since emitGoFunctionShape is only called for
// declared functions/methods. Today's behaviour: zero sends.
// When closures gain function-shape extraction, this becomes
// 1 send attributed to the closure node.
if len(sends) != 0 {
t.Errorf("v1: closure-internal sends should not attribute to outer fn (got %d)", len(sends))
}
}