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
114 lines
2.8 KiB
Go
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))
|
|
}
|
|
}
|