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

115 lines
3.8 KiB
Go

package languages
import (
"testing"
"github.com/zzet/gortex/internal/graph"
)
func TestJSEmitter_NamedHandlerAttributedToHandler(t *testing.T) {
// A bare emitter (no `events` import) with a named handler: the listen
// edge attributes to the handler node, not the .on call's enclosing
// function, so the resolver's synthesized call lands on onReady.
src := `function onReady() {}
function boot(emitter) {
emitter.on('ready', onReady);
emitter.emit('ready');
}
`
fix := runJSExtractFixture(t, "app.js", src)
events := fix.nodesByKind[graph.KindEvent]
if len(events) != 1 || events[0].ID != "event::emitter::emitter::ready" {
t.Fatalf("want 1 emitter topic event::emitter::emitter::ready, got %+v", events)
}
if tr, _ := events[0].Meta["transport"].(string); tr != "emitter" {
t.Errorf("topic transport = %q (want emitter)", tr)
}
listens := fix.edgesByKind[graph.EdgeListensOn]
if len(listens) != 1 {
t.Fatalf("want 1 EdgeListensOn, got %d", len(listens))
}
if listens[0].From != "app.js::onReady" {
t.Errorf("listen From = %q (want app.js::onReady — the handler, not the enclosing fn)", listens[0].From)
}
emits := fix.edgesByKind[graph.EdgeEmits]
if len(emits) != 1 {
t.Fatalf("want 1 EdgeEmits, got %d", len(emits))
}
if emits[0].From != "app.js::boot" {
t.Errorf("emit From = %q (want app.js::boot — the enclosing fn)", emits[0].From)
}
}
func TestJSEmitter_AnonymousHandlerFallsBackToEnclosingFn(t *testing.T) {
// An inline arrow handler has no named node, so the listen edge falls
// back to the enclosing function — and the topic node still appears.
src := `function boot(emitter) {
emitter.on('tick', () => { doWork(); });
}
`
fix := runJSExtractFixture(t, "a.js", src)
if got := len(fix.nodesByKind[graph.KindEvent]); got != 1 {
t.Fatalf("anonymous-handler emitter should still produce 1 topic node, got %d", got)
}
listens := fix.edgesByKind[graph.EdgeListensOn]
if len(listens) != 1 {
t.Fatalf("want 1 EdgeListensOn, got %d", len(listens))
}
if listens[0].From != "a.js::boot" {
t.Errorf("anon handler listen From = %q (want enclosing fn a.js::boot)", listens[0].From)
}
}
func TestJSEmitter_ImportGatedPathStillWins(t *testing.T) {
// With the `events` import the import-gated pub/sub path classifies the
// call, so the emitter-literal fallback must NOT also fire (one node).
src := `const EventEmitter = require('events');
function boot(emitter) {
emitter.on('ready', onReady);
emitter.emit('ready');
}
`
fix := runJSExtractFixture(t, "g.js", src)
events := fix.nodesByKind[graph.KindEvent]
if len(events) != 1 {
t.Fatalf("want exactly 1 topic node (no fallback double-emit), got %d: %+v", len(events), events)
}
if events[0].ID != "event::pubsub::eventemitter::ready" {
t.Errorf("topic id = %q (want the import-gated pubsub node)", events[0].ID)
}
}
func TestJSEmitter_TemplateLiteralEventSkipped(t *testing.T) {
// A computed / template-literal event name has no stable literal, so
// no emitter topic node is produced.
src := "function boot(emitter) {\n emitter.on(`evt-${id}`, cb);\n}\n"
fix := runJSExtractFixture(t, "t.js", src)
if got := len(fix.nodesByKind[graph.KindEvent]); got != 0 {
t.Errorf("template-literal event must produce no topic node, got %d", got)
}
}
func TestTSEmitter_LiteralFallback(t *testing.T) {
src := `function boot(bus: any) {
bus.on('open', onOpen);
bus.emit('open');
}
function onOpen() {}
`
fix := runTSExtractFixture(t, "ws.ts", src)
events := fix.nodesByKind[graph.KindEvent]
if len(events) != 1 || events[0].ID != "event::emitter::bus::open" {
t.Fatalf("want event::emitter::bus::open, got %+v", events)
}
listens := fix.edgesByKind[graph.EdgeListensOn]
if len(listens) != 1 || listens[0].From != "ws.ts::onOpen" {
t.Errorf("listen From = %v (want ws.ts::onOpen)", listens)
}
}