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
124 lines
3.5 KiB
Go
124 lines
3.5 KiB
Go
package parser
|
|
|
|
import (
|
|
"sync"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"github.com/zzet/gortex/internal/parser/tsitter/golang"
|
|
"github.com/zzet/gortex/internal/parser/tsitter/python"
|
|
)
|
|
|
|
func TestParseFile_Go(t *testing.T) {
|
|
src := []byte(`package main
|
|
|
|
func Hello() {
|
|
fmt.Println("hello")
|
|
}
|
|
`)
|
|
tree, err := ParseFile(src, golang.GetLanguage())
|
|
require.NoError(t, err)
|
|
defer tree.Close()
|
|
|
|
root := tree.RootNode()
|
|
assert.Equal(t, "source_file", root.Type())
|
|
assert.True(t, root.ChildCount() > 0)
|
|
}
|
|
|
|
func TestRunQuery_GoFunction(t *testing.T) {
|
|
src := []byte(`package main
|
|
|
|
func Hello() {}
|
|
func World(x int) string { return "" }
|
|
`)
|
|
tree, err := ParseFile(src, golang.GetLanguage())
|
|
require.NoError(t, err)
|
|
defer tree.Close()
|
|
|
|
pattern := `(function_declaration name: (identifier) @func.name) @func.def`
|
|
results, err := RunQuery(pattern, golang.GetLanguage(), tree.RootNode(), src)
|
|
require.NoError(t, err)
|
|
require.Len(t, results, 2)
|
|
|
|
assert.Equal(t, "Hello", results[0].Captures["func.name"].Text)
|
|
assert.Equal(t, "World", results[1].Captures["func.name"].Text)
|
|
}
|
|
|
|
func TestRunQuery_NoMatches(t *testing.T) {
|
|
src := []byte(`package main
|
|
|
|
var x = 42
|
|
`)
|
|
tree, err := ParseFile(src, golang.GetLanguage())
|
|
require.NoError(t, err)
|
|
defer tree.Close()
|
|
|
|
pattern := `(function_declaration name: (identifier) @func.name) @func.def`
|
|
results, err := RunQuery(pattern, golang.GetLanguage(), tree.RootNode(), src)
|
|
require.NoError(t, err)
|
|
assert.Empty(t, results)
|
|
}
|
|
|
|
func TestParseFile_InvalidSource(t *testing.T) {
|
|
// tree-sitter is error-tolerant; it returns a tree even for garbage input.
|
|
src := []byte(`{{{{{not valid go at all!!!!`)
|
|
tree, err := ParseFile(src, golang.GetLanguage())
|
|
require.NoError(t, err)
|
|
defer tree.Close()
|
|
|
|
root := tree.RootNode()
|
|
assert.NotNil(t, root) // just verify it doesn't crash
|
|
}
|
|
|
|
// TestParseFile_PoolGrammarSwitch verifies that a pooled parser, after
|
|
// parsing one grammar, correctly re-binds to a different grammar on the
|
|
// next checkout — the exact failure mode the legacy smacker pool hit.
|
|
func TestParseFile_PoolGrammarSwitch(t *testing.T) {
|
|
goSrc := []byte("package main\n\nfunc Hello() {}\n")
|
|
pySrc := []byte("def hello():\n return 1\n")
|
|
|
|
for i := 0; i < 20; i++ {
|
|
goTree, err := ParseFile(goSrc, golang.GetLanguage())
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "source_file", goTree.RootNode().Type())
|
|
assert.False(t, goTree.RootNode().HasError())
|
|
goTree.Close()
|
|
|
|
pyTree, err := ParseFile(pySrc, python.GetLanguage())
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "module", pyTree.RootNode().Type())
|
|
assert.False(t, pyTree.RootNode().HasError())
|
|
pyTree.Close()
|
|
}
|
|
}
|
|
|
|
// TestParseFile_PoolConcurrent exercises the parser pool from many
|
|
// goroutines at once. Run under -race, it proves checkout/return is
|
|
// data-race free and that concurrent callers never share a live parser.
|
|
func TestParseFile_PoolConcurrent(t *testing.T) {
|
|
srcs := [][]byte{
|
|
[]byte("package a\n\nfunc A() int { return 1 }\n"),
|
|
[]byte("package b\n\nfunc B() string { return \"\" }\n"),
|
|
[]byte("package c\n\ntype C struct{ X int }\n"),
|
|
}
|
|
var wg sync.WaitGroup
|
|
for i := 0; i < 64; i++ {
|
|
wg.Add(1)
|
|
go func(n int) {
|
|
defer wg.Done()
|
|
src := srcs[n%len(srcs)]
|
|
tree, err := ParseFile(src, golang.GetLanguage())
|
|
if err != nil {
|
|
t.Errorf("concurrent parse %d: %v", n, err)
|
|
return
|
|
}
|
|
defer tree.Close()
|
|
if tree.RootNode().Type() != "source_file" {
|
|
t.Errorf("concurrent parse %d: unexpected root %q", n, tree.RootNode().Type())
|
|
}
|
|
}(i)
|
|
}
|
|
wg.Wait()
|
|
}
|