Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
run: go build -o gortex ./cmd/gortex/

- name: Test
run: go test -race -coverprofile=coverage.out ./...
run: go test -race -timeout=20m -coverprofile=coverage.out ./...

- name: Upload coverage
if: matrix.os == 'ubuntu-latest' && matrix.go-version == '1.26'
Expand Down Expand Up @@ -116,4 +116,4 @@ jobs:
go-version-file: go.mod

- name: Run benchmarks
run: go test -bench=. -benchmem -count=1 -benchtime=1s ./internal/parser/languages/ ./internal/query/ ./internal/graph/
run: go test -bench=. -benchmem -count=1 -benchtime=1s -timeout=20m ./internal/parser/languages/ ./internal/query/ ./internal/graph/
5 changes: 1 addition & 4 deletions internal/mcp/analyze_scope_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ import (
"github.com/zzet/gortex/internal/config"
"github.com/zzet/gortex/internal/graph"
"github.com/zzet/gortex/internal/indexer"
"github.com/zzet/gortex/internal/parser"
"github.com/zzet/gortex/internal/parser/languages"
"github.com/zzet/gortex/internal/query"
"github.com/zzet/gortex/internal/search"
)
Expand Down Expand Up @@ -81,8 +79,7 @@ func newAnalyzeServer(t *testing.T, flagOn bool, repos ...analyzeRepoSpec) (*Ser
require.NoError(t, err)

g := graph.New()
reg := parser.NewRegistry()
languages.RegisterAll(reg)
reg := testRegistry()
bm := search.NewBM25()
mi := indexer.NewMultiIndexer(g, reg, bm, cm, zap.NewNop())
_, err = mi.IndexScoped("", "")
Expand Down
6 changes: 3 additions & 3 deletions internal/mcp/callback_callers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ import (
// navTestEng adapts a graph.Store to the engineLike surface navCallers needs.
type navTestEng struct{ g graph.Store }

func (e navTestEng) GetSymbol(id string) *graph.Node { return e.g.GetNode(id) }
func (e navTestEng) GetOutEdges(id string) []*graph.Edge { return e.g.GetOutEdges(id) }
func (e navTestEng) GetInEdges(id string) []*graph.Edge { return e.g.GetInEdges(id) }
func (e navTestEng) GetSymbol(id string) *graph.Node { return e.g.GetNode(id) }
func (e navTestEng) GetOutEdges(id string) []*graph.Edge { return e.g.GetOutEdges(id) }
func (e navTestEng) GetInEdges(id string) []*graph.Edge { return e.g.GetInEdges(id) }

// TestCallbackRegistrationCallers is part of the C3 named set: a function
// registered as a callback (a callback-registration reference edge) shows up
Expand Down
5 changes: 1 addition & 4 deletions internal/mcp/change_contract_lenses_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ import (
"github.com/zzet/gortex/internal/config"
"github.com/zzet/gortex/internal/graph"
"github.com/zzet/gortex/internal/indexer"
"github.com/zzet/gortex/internal/parser"
"github.com/zzet/gortex/internal/parser/languages"
"github.com/zzet/gortex/internal/query"
)

Expand Down Expand Up @@ -65,8 +63,7 @@ func Bar() int { return Foo(21) }
`), 0o644))

g := graph.New()
reg := parser.NewRegistry()
languages.RegisterAll(reg)
reg := testRegistry()
cfg := config.Default()
idx := indexer.New(g, reg, cfg.Index, zap.NewNop())
_, err := idx.Index(dir)
Expand Down
5 changes: 1 addition & 4 deletions internal/mcp/change_contract_strategy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ import (
"github.com/zzet/gortex/internal/config"
"github.com/zzet/gortex/internal/graph"
"github.com/zzet/gortex/internal/indexer"
"github.com/zzet/gortex/internal/parser"
"github.com/zzet/gortex/internal/parser/languages"
"github.com/zzet/gortex/internal/query"
)

Expand Down Expand Up @@ -53,8 +51,7 @@ func Wide(a, b, c, d, e, f int) int {
require.NoError(t, os.WriteFile(filepath.Join(dir, "big.go"), []byte(src), 0o644))

g := graph.New()
reg := parser.NewRegistry()
languages.RegisterAll(reg)
reg := testRegistry()
cfg := config.Default()
idx := indexer.New(g, reg, cfg.Index, zap.NewNop())
_, err := idx.Index(dir)
Expand Down
5 changes: 1 addition & 4 deletions internal/mcp/determinism_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ import (
"github.com/zzet/gortex/internal/config"
"github.com/zzet/gortex/internal/graph"
"github.com/zzet/gortex/internal/indexer"
"github.com/zzet/gortex/internal/parser"
"github.com/zzet/gortex/internal/parser/languages"
"github.com/zzet/gortex/internal/query"
)

Expand All @@ -40,8 +38,7 @@ func setupDeterminismServer(t *testing.T) *Server {
require.NoError(t, os.WriteFile(filepath.Join(dir, "handlers.go"), []byte(src.String()), 0o644))

g := graph.New()
reg := parser.NewRegistry()
languages.RegisterAll(reg)
reg := testRegistry()
cfg := config.Default()
idx := indexer.New(g, reg, cfg.Index, zap.NewNop())
_, err := idx.Index(dir)
Expand Down
8 changes: 4 additions & 4 deletions internal/mcp/dynamic_boundary_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ import (
func TestDynamicBoundaryEmitsSiteFormKeyCandidates(t *testing.T) {
body := strings.Join([]string{
"def route(self, name, payload):", // line 10 (startLine)
" handler = getattr(self, name)", // 11 reflection, key=name
" return self.handlers[action](payload)", // 12 computed_member, key=action
" # self.bus.emit('ignored.in.comment')", // 13 comment — must be skipped
" self.bus.emit('user.created', payload)", // 14 event_bus, key=user.created
" handler = getattr(self, name)", // 11 reflection, key=name
" return self.handlers[action](payload)", // 12 computed_member, key=action
" # self.bus.emit('ignored.in.comment')", // 13 comment — must be skipped
" self.bus.emit('user.created', payload)", // 14 event_bus, key=user.created
}, "\n")

// Stub candidate resolver: 'name' resolves to two handler symbols, one of
Expand Down
8 changes: 4 additions & 4 deletions internal/mcp/ensure_fresh_self_heal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@ import (
"github.com/stretchr/testify/require"
"go.uber.org/zap"

"os"
"path/filepath"

"github.com/zzet/gortex/internal/config"
"github.com/zzet/gortex/internal/graph"
"github.com/zzet/gortex/internal/indexer"
"github.com/zzet/gortex/internal/parser"
"github.com/zzet/gortex/internal/parser/languages"
"github.com/zzet/gortex/internal/query"
"github.com/zzet/gortex/internal/search"
"os"
"path/filepath"
)

// TestEnsureFresh_MultiRepoSelfHealsStaleFile is the regression test for the
Expand Down Expand Up @@ -82,8 +83,7 @@ func TestEnsureFresh_SingleRepoSelfHealsStaleFile(t *testing.T) {
[]byte("package main\n\nfunc Hello() {}\n"), 0o644))

g := graph.New()
reg := parser.NewRegistry()
languages.RegisterAll(reg)
reg := testRegistry()
idx := indexer.New(g, reg, config.Default().Index, zap.NewNop())
_, err := idx.Index(dir)
require.NoError(t, err)
Expand Down
4 changes: 2 additions & 2 deletions internal/mcp/memories_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,8 @@ func TestSurface_RanksSymbolAnchorAbovePinned(t *testing.T) {
})
// Symbol anchor match — should rank above pinned.
anchorID, _ := mm.Save(persistence.MemoryEntry{
Body: "anchor match",
SymbolIDs: []string{"pkg/foo.go::Bar"},
Body: "anchor match",
SymbolIDs: []string{"pkg/foo.go::Bar"},
Importance: 3,
})

Expand Down
9 changes: 3 additions & 6 deletions internal/mcp/overlay_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ import (
"github.com/zzet/gortex/internal/daemon"
"github.com/zzet/gortex/internal/graph"
"github.com/zzet/gortex/internal/indexer"
"github.com/zzet/gortex/internal/parser"
"github.com/zzet/gortex/internal/parser/languages"
"github.com/zzet/gortex/internal/query"
)

Expand Down Expand Up @@ -49,8 +47,7 @@ func Caller() {
`), 0o644))

g := graph.New()
reg := parser.NewRegistry()
languages.RegisterAll(reg)
reg := testRegistry()
cfg := config.Default()
idx := indexer.New(g, reg, cfg.Index, zap.NewNop())
_, err := idx.Index(dir)
Expand Down Expand Up @@ -348,8 +345,8 @@ func Target() {}

ctx := WithSessionID(context.Background(), sessID)
res := callToolByName(t, srv, ctx, "get_symbol_source", map[string]any{
"id": "target.go::Target",
"context_lines": 10,
"id": "target.go::Target",
"context_lines": 10,
})
require.False(t, res.IsError, "get_symbol_source: %s", toolText(res))
require.Contains(t, toolText(res), "EditorSentinel",
Expand Down
6 changes: 3 additions & 3 deletions internal/mcp/pack_delta_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ func TestExtractPackViewAndDiff(t *testing.T) {
), false)

current := extractPackView(packResult(
symEntry("a.go::A", 1, "func A() {}"), // unchanged
symEntry("b.go::B", 5, "func B() { changed }"), // changed body
symEntry("c.go::C", 9, "func C() {}"), // added
symEntry("a.go::A", 1, "func A() {}"), // unchanged
symEntry("b.go::B", 5, "func B() { changed }"), // changed body
symEntry("c.go::C", 9, "func C() {}"), // added
), true)

delta := diffPackViews(prior, current, "root1", "root2")
Expand Down
5 changes: 1 addition & 4 deletions internal/mcp/read_security_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,13 @@ import (
"github.com/zzet/gortex/internal/config"
"github.com/zzet/gortex/internal/graph"
"github.com/zzet/gortex/internal/indexer"
"github.com/zzet/gortex/internal/parser"
"github.com/zzet/gortex/internal/parser/languages"
"github.com/zzet/gortex/internal/query"
)

func newReadGuardServer(t *testing.T, repoRoot string) *Server {
t.Helper()
g := graph.New()
reg := parser.NewRegistry()
languages.RegisterAll(reg)
reg := testRegistry()
idx := indexer.New(g, reg, config.IndexConfig{}, zap.NewNop())
idx.SetRootPath(repoRoot)
return NewServer(query.NewEngine(g), g, idx, nil, zap.NewNop(), nil)
Expand Down
6 changes: 3 additions & 3 deletions internal/mcp/return_usage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,17 @@ func returnUsageServer(t *testing.T) (*Server, string) {
g.AddEdge(&graph.Edge{
From: "pkg/a.go::drop", To: fetch.ID, Kind: graph.EdgeCalls,
FilePath: "pkg/a.go", Line: 3,
Meta: map[string]any{graph.MetaReturnUsage: graph.ReturnUsageDiscarded},
Meta: map[string]any{graph.MetaReturnUsage: graph.ReturnUsageDiscarded},
})
g.AddEdge(&graph.Edge{
From: "pkg/a.go::keep", To: fetch.ID, Kind: graph.EdgeCalls,
FilePath: "pkg/a.go", Line: 9,
Meta: map[string]any{graph.MetaReturnUsage: graph.ReturnUsageAssigned},
Meta: map[string]any{graph.MetaReturnUsage: graph.ReturnUsageAssigned},
})
g.AddEdge(&graph.Edge{
From: "pkg/b.go::relay", To: fetch.ID, Kind: graph.EdgeCalls,
FilePath: "pkg/b.go", Line: 5,
Meta: map[string]any{graph.MetaReturnUsage: graph.ReturnUsageReturned},
Meta: map[string]any{graph.MetaReturnUsage: graph.ReturnUsageReturned},
})
g.AddEdge(&graph.Edge{
From: "pkg/b.go::opaque", To: fetch.ID, Kind: graph.EdgeCalls,
Expand Down
5 changes: 1 addition & 4 deletions internal/mcp/safe_delete_propagate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ import (
"github.com/zzet/gortex/internal/config"
"github.com/zzet/gortex/internal/graph"
"github.com/zzet/gortex/internal/indexer"
"github.com/zzet/gortex/internal/parser"
"github.com/zzet/gortex/internal/parser/languages"
"github.com/zzet/gortex/internal/query"
)

Expand Down Expand Up @@ -54,8 +52,7 @@ func Caller() {
`), 0o644))

g := graph.New()
reg := parser.NewRegistry()
languages.RegisterAll(reg)
reg := testRegistry()
cfg := config.Default()
idx := indexer.New(g, reg, cfg.Index, zap.NewNop())
_, err := idx.Index(dir)
Expand Down
14 changes: 4 additions & 10 deletions internal/mcp/scope_resolve_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ import (
"github.com/zzet/gortex/internal/config"
"github.com/zzet/gortex/internal/graph"
"github.com/zzet/gortex/internal/indexer"
"github.com/zzet/gortex/internal/parser"
"github.com/zzet/gortex/internal/parser/languages"
"github.com/zzet/gortex/internal/query"
"github.com/zzet/gortex/internal/search"
"github.com/zzet/gortex/internal/search/trigram"
Expand Down Expand Up @@ -77,8 +75,7 @@ func newSharedWorkspaceServer(t *testing.T, flagOn bool) sharedWSOptions {
require.NoError(t, err)

g := graph.New()
reg := parser.NewRegistry()
languages.RegisterAll(reg)
reg := testRegistry()
bm := search.NewBM25()
mi := indexer.NewMultiIndexer(g, reg, bm, cm, zap.NewNop())
_, err = mi.IndexScoped("", "")
Expand Down Expand Up @@ -116,8 +113,7 @@ func newSplitProjectWorkspaceServer(t *testing.T, flagOn bool) sharedWSOptions {
require.NoError(t, err)

g := graph.New()
reg := parser.NewRegistry()
languages.RegisterAll(reg)
reg := testRegistry()
bm := search.NewBM25()
mi := indexer.NewMultiIndexer(g, reg, bm, cm, zap.NewNop())
_, err = mi.IndexScoped("", "")
Expand Down Expand Up @@ -696,8 +692,7 @@ func newLoneRepoServer(t *testing.T, flagOn bool) (*Server, string) {
require.NoError(t, err)

g := graph.New()
reg := parser.NewRegistry()
languages.RegisterAll(reg)
reg := testRegistry()
bm := search.NewBM25()
mi := indexer.NewMultiIndexer(g, reg, bm, cm, zap.NewNop())
_, err = mi.IndexScoped("", "")
Expand Down Expand Up @@ -827,8 +822,7 @@ func newTwoRepoServer(t *testing.T) (*Server, string) {
require.NoError(t, err)

g := graph.New()
reg := parser.NewRegistry()
languages.RegisterAll(reg)
reg := testRegistry()
bm := search.NewBM25()
mi := indexer.NewMultiIndexer(g, reg, bm, cm, zap.NewNop())
_, err = mi.IndexScoped("", "")
Expand Down
8 changes: 3 additions & 5 deletions internal/mcp/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,12 @@ import (

"github.com/zzet/gortex/internal/graph"
"github.com/zzet/gortex/internal/indexer"
"github.com/zzet/gortex/internal/parser"
"github.com/zzet/gortex/internal/parser/languages"
"github.com/zzet/gortex/internal/query"

"github.com/zzet/gortex/internal/config"
"os"
"path/filepath"

"github.com/zzet/gortex/internal/config"
)

func setupTestServer(t *testing.T) (*Server, string) {
Expand All @@ -44,8 +43,7 @@ func helper() {}
`), 0o644)

g := graph.New()
reg := parser.NewRegistry()
languages.RegisterAll(reg)
reg := testRegistry()
cfg := config.Default()
idx := indexer.New(g, reg, cfg.Index, zap.NewNop())
_, err := idx.Index(dir)
Expand Down
28 changes: 28 additions & 0 deletions internal/mcp/testregistry_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package mcp

import (
"sync"

"github.com/zzet/gortex/internal/parser"
"github.com/zzet/gortex/internal/parser/languages"
)

// testRegistry returns a package-wide parser.Registry with every language
// extractor registered. RegisterAll recompiles ~30 tree-sitter grammar
// queries (measured ~345ms/call) — sharing one instance across this
// package's many test-server helpers avoids paying that cost at each of
// their call sites. Safe to share: no test in this package registers
// additional extractors on top of RegisterAll, mutates the registry, or
// runs in parallel with another.
var (
testRegistryOnce sync.Once
testRegistrySingleton *parser.Registry
)

func testRegistry() *parser.Registry {
testRegistryOnce.Do(func() {
testRegistrySingleton = parser.NewRegistry()
languages.RegisterAll(testRegistrySingleton)
})
return testRegistrySingleton
}
Loading
Loading