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

154 lines
5.1 KiB
Go

package indexer
import (
"os/exec"
"path/filepath"
"testing"
"github.com/stretchr/testify/require"
"go.uber.org/zap"
"github.com/zzet/gortex/internal/config"
"github.com/zzet/gortex/internal/graph"
"github.com/zzet/gortex/internal/parser"
"github.com/zzet/gortex/internal/parser/languages"
)
func TestStripBOM(t *testing.T) {
body := []byte("package main\n")
require.Equal(t, body, stripBOM(append([]byte{0xEF, 0xBB, 0xBF}, body...))) // UTF-8
require.Equal(t, body, stripBOM(append([]byte{0xFF, 0xFE}, body...))) // UTF-16LE
require.Equal(t, body, stripBOM(append([]byte{0xFE, 0xFF}, body...))) // UTF-16BE
require.Equal(t, body, stripBOM(body)) // no BOM
require.Equal(t, []byte{}, stripBOM([]byte{})) // empty
}
func TestTransformPipeline_BOMStripIsBuiltIn(t *testing.T) {
p := newTransformPipeline(nil, zap.NewNop())
withBOM := append([]byte{0xEF, 0xBB, 0xBF}, []byte("package main\n")...)
require.Equal(t, []byte("package main\n"), p.run("x.go", withBOM))
}
func TestTransformPipeline_NilSafe(t *testing.T) {
var p *transformPipeline
require.Equal(t, []byte("x"), p.run("a.go", []byte("x")))
require.Equal(t, "", p.languageFor("a.go"))
}
func TestTransformPipeline_RuleWithNoCommandIgnored(t *testing.T) {
p := newTransformPipeline([]config.TransformRule{{Name: "broken"}}, zap.NewNop())
require.Len(t, p.transforms, 1) // only the built-in BOM stripper
}
func TestCommandTransform_Matches(t *testing.T) {
c := newCommandTransform(config.TransformRule{Extensions: []string{".SVG", ".pdf"}, Command: []string{"cat"}})
require.True(t, c.matches("logo.svg")) // case-insensitive
require.True(t, c.matches("doc.pdf"))
require.False(t, c.matches("main.go"))
all := newCommandTransform(config.TransformRule{Command: []string{"cat"}}) // no extensions → all
require.True(t, all.matches("anything.xyz"))
}
func TestCommandTransform_Apply(t *testing.T) {
requireBin(t, "sed")
c := newCommandTransform(config.TransformRule{
Command: []string{"sed", "s/foo/bar/g"},
})
out, err := c.apply("x.txt", []byte("foo foo"))
require.NoError(t, err)
require.Equal(t, "bar bar", string(out))
}
func TestCommandTransform_ApplyError(t *testing.T) {
c := newCommandTransform(config.TransformRule{Command: []string{"gortex-no-such-binary-xyz"}})
_, err := c.apply("x.txt", []byte("data"))
require.Error(t, err)
}
func TestTransformPipeline_FailingCommandKeepsBytes(t *testing.T) {
// A failing transform must not drop the file — earlier bytes win.
p := newTransformPipeline([]config.TransformRule{{
Name: "broken", Command: []string{"gortex-no-such-binary-xyz"},
}}, zap.NewNop())
require.Equal(t, []byte("untouched"), p.run("a.go", []byte("untouched")))
}
// TestIndex_TransformPipeline proves a transform rewrites bytes before
// extraction: the renamed symbol is the one that lands in the graph.
func TestIndex_TransformPipeline(t *testing.T) {
requireBin(t, "sed")
dir := t.TempDir()
writeFile(t, filepath.Join(dir, "main.go"), "package main\n\nfunc Original() {}\n")
g := graph.New()
reg := parser.NewRegistry()
reg.Register(languages.NewGoExtractor())
cfg := config.Default().Index
cfg.Workers = 1
cfg.Transforms = []config.TransformRule{{
Name: "rename", Extensions: []string{".go"},
Command: []string{"sed", "s/Original/Renamed/g"},
}}
idx := New(g, reg, cfg, zap.NewNop())
_, err := idx.Index(dir)
require.NoError(t, err)
require.NotEmpty(t, g.FindNodesByName("Renamed"), "transformed symbol must be indexed")
require.Empty(t, g.FindNodesByName("Original"), "pre-transform symbol must not be indexed")
}
// TestIndex_TransformAsLanguage proves a transform can re-type a file
// whose extension is not natively indexed.
func TestIndex_TransformAsLanguage(t *testing.T) {
requireBin(t, "cat")
dir := t.TempDir()
writeFile(t, filepath.Join(dir, "snippet.gocode"), "package main\n\nfunc Snippet() {}\n")
g := graph.New()
reg := parser.NewRegistry()
reg.Register(languages.NewGoExtractor())
cfg := config.Default().Index
cfg.Workers = 1
cfg.Transforms = []config.TransformRule{{
Name: "gocode-as-go", Extensions: []string{".gocode"},
Command: []string{"cat"}, AsLanguage: "go",
}}
idx := New(g, reg, cfg, zap.NewNop())
result, err := idx.Index(dir)
require.NoError(t, err)
require.Equal(t, 1, result.FileCount)
require.NotEmpty(t, g.FindNodesByName("Snippet"), ".gocode file must be indexed as Go")
}
func TestEffectiveLanguage(t *testing.T) {
g := graph.New()
reg := parser.NewRegistry()
reg.Register(languages.NewGoExtractor())
cfg := config.Default().Index
cfg.Transforms = []config.TransformRule{{
Name: "pdf", Extensions: []string{".pdf"},
Command: []string{"cat"}, AsLanguage: "markdown",
}}
idx := New(g, reg, cfg, zap.NewNop())
lang, ok := idx.effectiveLanguage("main.go", nil)
require.True(t, ok)
require.Equal(t, "go", lang)
lang, ok = idx.effectiveLanguage("doc.pdf", nil)
require.True(t, ok)
require.Equal(t, "markdown", lang)
_, ok = idx.effectiveLanguage("mystery.zzz", nil)
require.False(t, ok)
}
func requireBin(t *testing.T, name string) {
t.Helper()
if _, err := exec.LookPath(name); err != nil {
t.Skipf("%s not available on PATH", name)
}
}