Documentation
¶
Overview ¶
Example ¶
package main
import (
"context"
"fmt"
"github.com/specvital/core/pkg/parser"
"github.com/specvital/core/pkg/source"
// Import strategies to register them with the default registry.
_ "github.com/specvital/core/pkg/parser/strategies/gotesting"
_ "github.com/specvital/core/pkg/parser/strategies/jest"
_ "github.com/specvital/core/pkg/parser/strategies/playwright"
_ "github.com/specvital/core/pkg/parser/strategies/vitest"
)
func main() {
ctx := context.Background()
// Create a source for the project directory
src, err := source.NewLocalSource("/path/to/project")
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
defer src.Close()
// Scan a project directory for test files
result, err := parser.Scan(ctx, src)
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
// Print discovered test files
for _, file := range result.Inventory.Files {
fmt.Printf("File: %s (framework: %s)\n", file.Path, file.Framework)
fmt.Printf(" Tests: %d\n", file.CountTests())
}
// Check for non-fatal errors
for _, scanErr := range result.Errors {
fmt.Printf("Warning: %v\n", scanErr)
}
}
Example (WithOptions) ¶
package main
import (
"context"
"fmt"
"time"
"github.com/specvital/core/pkg/parser"
"github.com/specvital/core/pkg/source"
// Import strategies to register them with the default registry.
_ "github.com/specvital/core/pkg/parser/strategies/gotesting"
_ "github.com/specvital/core/pkg/parser/strategies/jest"
_ "github.com/specvital/core/pkg/parser/strategies/playwright"
_ "github.com/specvital/core/pkg/parser/strategies/vitest"
)
func main() {
ctx := context.Background()
// Create a source for the project directory
src, err := source.NewLocalSource("/path/to/project")
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
defer src.Close()
// Scan with custom options
result, err := parser.Scan(ctx, src,
parser.WithWorkers(4), // Use 4 parallel workers
parser.WithTimeout(2*time.Minute), // Set 2 minute timeout
parser.WithExclude([]string{"fixtures"}), // Skip fixtures directory
parser.WithScanPatterns([]string{"**/*.test.ts"}), // Only *.test.ts files
)
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Found %d test files\n", len(result.Inventory.Files))
}
Index ¶
- Constants
- Variables
- func ClearQueryCache()
- func FindChildByType(node *sitter.Node, nodeType string) *sitter.Node
- func FindChildrenByType(node *sitter.Node, nodeType string) []*sitter.Node
- func GetLocation(node *sitter.Node, filename string) domain.Location
- func GetNodeText(node *sitter.Node, source []byte) (result string)
- func ParseWithPool(ctx context.Context, lang domain.Language, source []byte) (*sitter.Tree, error)
- func WalkTree(node *sitter.Node, visitor func(*sitter.Node) bool)
- type QueryResult
- type ScanError
- type ScanOption
- func WithExclude(patterns []string) ScanOption
- func WithExcludePatterns(patterns []string) ScanOption
- func WithLogLowConfidence(_ bool) ScanOptiondeprecated
- func WithMaxFileSize(size int64) ScanOption
- func WithMinConfidence(_ int) ScanOptiondeprecated
- func WithPatterns(patterns []string) ScanOption
- func WithRegistry(registry *framework.Registry) ScanOption
- func WithScanMaxFileSize(size int64) ScanOption
- func WithScanPatterns(patterns []string) ScanOption
- func WithTimeout(d time.Duration) ScanOption
- func WithWorkers(n int) ScanOption
- type ScanOptions
- type ScanResult
- type ScanStats
- type Scanner
- type TSParser
Examples ¶
Constants ¶
const ( // DefaultWorkers indicates that the scanner should use GOMAXPROCS as the worker count. DefaultWorkers = 0 // DefaultTimeout is the default scan timeout duration. DefaultTimeout = 5 * time.Minute // MaxWorkers is the maximum number of concurrent workers allowed. MaxWorkers = 1024 // DefaultMaxFileSize is the default maximum file size for scanning (10MB). DefaultMaxFileSize = 10 * 1024 * 1024 )
const MaxTreeDepth = tspool.MaxTreeDepth
Variables ¶
var ( // ErrScanCancelled is returned when scanning is cancelled via context. ErrScanCancelled = errors.New("scanner: scan cancelled") // ErrScanTimeout is returned when scanning exceeds the timeout duration. ErrScanTimeout = errors.New("scanner: scan timeout") )
var DefaultSkipPatterns = []string{
"node_modules",
".git",
"vendor",
"dist",
".next",
"__pycache__",
"coverage",
".cache",
}
DefaultSkipPatterns contains directory names that are skipped by default during scanning.
Functions ¶
func ClearQueryCache ¶
func ClearQueryCache()
ClearQueryCache removes all cached queries. Only for testing.
func FindChildByType ¶
FindChildByType returns the first direct child with the given node type.
func FindChildrenByType ¶
FindChildrenByType returns all direct children with the given node type.
func GetLocation ¶
GetLocation converts a tree-sitter node position to a domain.Location. Line numbers are converted to 1-based indexing.
func GetNodeText ¶
GetNodeText returns the source text for the given AST node. Returns empty string if the node's byte range exceeds the source length. Uses defensive bounds checking and panic recovery to handle edge cases.
func ParseWithPool ¶
ParseWithPool parses source using a pooled parser. Caller must close the returned tree.
Types ¶
type QueryResult ¶
type QueryResult struct {
// Node is the first captured node in this match.
Node *sitter.Node
// Captures maps capture names to their corresponding nodes.
Captures map[string]*sitter.Node
}
QueryResult contains the result of a tree-sitter query match.
func Query ¶
func Query(root *sitter.Node, source []byte, lang domain.Language, queryStr string) ([]QueryResult, error)
Query executes a tree-sitter query and returns all matches. The query is compiled fresh each time; for repeated queries, use QueryWithCache.
func QueryWithCache ¶
func QueryWithCache(root *sitter.Node, source []byte, lang domain.Language, queryStr string) ([]QueryResult, error)
QueryWithCache executes a query with cached compilation.
type ScanError ¶
type ScanError struct {
// Err is the underlying error.
Err error
// Path is the file path where the error occurred (may be empty for non-file errors).
Path string
// Phase indicates which phase the error occurred in.
// Values: "discovery", "config-parse", "detection", "parsing"
Phase string
}
ScanError represents an error that occurred during a specific phase of scanning.
type ScanOption ¶
type ScanOption func(*ScanOptions)
ScanOption is a functional option for configuring Scanner.
func WithExclude ¶
func WithExclude(patterns []string) ScanOption
WithExclude is an alias for WithExcludePatterns.
func WithExcludePatterns ¶ added in v1.2.0
func WithExcludePatterns(patterns []string) ScanOption
WithExcludePatterns adds directory patterns to skip during file discovery.
func WithLogLowConfidence
deprecated
added in
v1.2.0
func WithLogLowConfidence(_ bool) ScanOption
Deprecated: LogLowConfidence is no longer used with early-return detection. Kept for backward compatibility.
func WithMaxFileSize ¶
func WithMaxFileSize(size int64) ScanOption
WithMaxFileSize sets the maximum file size to process.
func WithMinConfidence
deprecated
added in
v1.2.0
func WithMinConfidence(_ int) ScanOption
Deprecated: MinConfidence is no longer used with early-return detection. Kept for backward compatibility.
func WithPatterns ¶
func WithPatterns(patterns []string) ScanOption
WithPatterns sets glob patterns to filter test files.
func WithRegistry ¶ added in v1.2.0
func WithRegistry(registry *framework.Registry) ScanOption
WithRegistry sets the framework registry to use.
func WithScanMaxFileSize ¶
func WithScanMaxFileSize(size int64) ScanOption
WithScanMaxFileSize is an alias for WithMaxFileSize.
func WithScanPatterns ¶
func WithScanPatterns(patterns []string) ScanOption
WithScanPatterns is an alias for WithPatterns.
func WithTimeout ¶
func WithTimeout(d time.Duration) ScanOption
WithTimeout sets the scan timeout duration. Negative values are ignored.
func WithWorkers ¶
func WithWorkers(n int) ScanOption
WithWorkers sets the number of concurrent file parsers. Negative values are ignored.
type ScanOptions ¶
type ScanOptions struct {
// Workers specifies the number of concurrent file parsers.
// Zero or negative values use runtime.GOMAXPROCS(0).
Workers int
// Timeout is the maximum duration for the entire scan operation.
// Zero or negative values use DefaultTimeout.
Timeout time.Duration
// ExcludePatterns specifies directory names to skip during file discovery.
// These are combined with DefaultSkipPatterns.
ExcludePatterns []string
// MaxFileSize is the maximum file size in bytes to process.
// Files larger than this are skipped.
MaxFileSize int64
// Patterns specifies glob patterns to filter test files.
// Empty means all test file candidates are processed.
Patterns []string
// Registry is the framework registry to use for detection.
// If nil, uses framework.DefaultRegistry().
Registry *framework.Registry
}
ScanOptions configures scanner behavior.
type ScanResult ¶
type ScanResult struct {
// Inventory contains all parsed test files.
Inventory *domain.Inventory
// Errors contains non-fatal errors encountered during scanning.
Errors []ScanError
// Stats provides scan statistics including confidence distribution.
Stats ScanStats
}
ScanResult contains the outcome of a scan operation.
func DetectTestFiles ¶
func DetectTestFiles(ctx context.Context, src source.Source, opts ...ScanOption) (*ScanResult, error)
Example ¶
package main
import (
"context"
"fmt"
"github.com/specvital/core/pkg/parser"
"github.com/specvital/core/pkg/source"
// Import strategies to register them with the default registry.
_ "github.com/specvital/core/pkg/parser/strategies/gotesting"
_ "github.com/specvital/core/pkg/parser/strategies/jest"
_ "github.com/specvital/core/pkg/parser/strategies/playwright"
_ "github.com/specvital/core/pkg/parser/strategies/vitest"
)
func main() {
ctx := context.Background()
// Create a source for the project directory
src, err := source.NewLocalSource("/path/to/project")
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
defer src.Close()
// Detect test files without parsing
result, err := parser.DetectTestFiles(ctx, src)
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Found %d test files:\n", len(result.Inventory.Files))
for _, file := range result.Inventory.Files {
fmt.Printf(" - %s\n", file.Path)
}
}
Example (WithPatterns) ¶
package main
import (
"context"
"fmt"
"github.com/specvital/core/pkg/parser"
"github.com/specvital/core/pkg/source"
// Import strategies to register them with the default registry.
_ "github.com/specvital/core/pkg/parser/strategies/gotesting"
_ "github.com/specvital/core/pkg/parser/strategies/jest"
_ "github.com/specvital/core/pkg/parser/strategies/playwright"
_ "github.com/specvital/core/pkg/parser/strategies/vitest"
)
func main() {
ctx := context.Background()
// Create a source for the project directory
src, err := source.NewLocalSource("/path/to/project")
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
defer src.Close()
// Detect only specific test files
result, err := parser.DetectTestFiles(ctx, src,
parser.WithPatterns([]string{"src/**/*.spec.ts"}),
parser.WithMaxFileSize(5*1024*1024), // 5MB max
)
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Found %d matching test files\n", len(result.Inventory.Files))
}
func Scan ¶
func Scan(ctx context.Context, src source.Source, opts ...ScanOption) (*ScanResult, error)
Example (TestInventory) ¶
package main
import (
"context"
"fmt"
"github.com/specvital/core/pkg/parser"
"github.com/specvital/core/pkg/source"
// Import strategies to register them with the default registry.
_ "github.com/specvital/core/pkg/parser/strategies/gotesting"
_ "github.com/specvital/core/pkg/parser/strategies/jest"
_ "github.com/specvital/core/pkg/parser/strategies/playwright"
_ "github.com/specvital/core/pkg/parser/strategies/vitest"
)
func main() {
ctx := context.Background()
// Create a source for the project directory
src, err := source.NewLocalSource("/path/to/project")
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
defer src.Close()
result, err := parser.Scan(ctx, src)
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
inv := result.Inventory
fmt.Printf("Project: %s\n", inv.RootPath)
fmt.Printf("Total test files: %d\n", len(inv.Files))
fmt.Printf("Total tests: %d\n", inv.CountTests())
// Iterate test structure
for _, file := range inv.Files {
fmt.Printf("\n%s (%s):\n", file.Path, file.Framework)
// Top-level tests
for _, test := range file.Tests {
fmt.Printf(" - %s [%d:%d]\n", test.Name, test.Location.StartLine, test.Location.EndLine)
}
// Test suites
for _, suite := range file.Suites {
fmt.Printf(" %s:\n", suite.Name)
for _, test := range suite.Tests {
fmt.Printf(" - %s\n", test.Name)
}
}
}
}
type ScanStats ¶ added in v1.2.0
type ScanStats struct {
// FilesScanned is the total number of test file candidates discovered.
FilesScanned int
// FilesMatched is the number of files that were successfully parsed.
FilesMatched int
// FilesFailed is the number of files that failed to parse.
FilesFailed int
// FilesSkipped is the number of files skipped due to low confidence or other reasons.
FilesSkipped int
// ConfidenceDist tracks detection confidence distribution.
// Keys: "definite", "moderate", "weak", "unknown"
ConfidenceDist map[string]int
// ConfigsFound is the number of config files discovered and parsed.
ConfigsFound int
// Duration is the total scan duration.
Duration time.Duration
}
ScanStats provides statistics about the scan operation.
type Scanner ¶ added in v1.2.0
type Scanner struct {
// contains filtered or unexported fields
}
Scanner performs framework detection and test file parsing. It integrates framework.Registry and detection.Detector for improved accuracy.
func NewScanner ¶ added in v1.2.0
func NewScanner(opts ...ScanOption) *Scanner
NewScanner creates a new scanner with the given options.
func (*Scanner) Scan ¶ added in v1.2.0
Scan performs the complete scanning process:
- Discover and parse config files
- Build project scope
- Discover test files
- Detect framework for each file
- Parse test files in parallel
The caller is responsible for calling src.Close() when done. For GitSource, failure to close will leak temporary directories.
func (*Scanner) ScanFiles ¶ added in v1.2.0
func (s *Scanner) ScanFiles(ctx context.Context, src source.Source, files []string) (*ScanResult, error)
ScanFiles scans specific files (for incremental/watch mode). This bypasses file discovery and directly scans the provided file paths.
The caller is responsible for calling src.Close() when done.
func (*Scanner) SetProjectScope ¶ added in v1.2.0
func (s *Scanner) SetProjectScope(scope *framework.AggregatedProjectScope)
SetProjectScope sets pre-parsed config information for remote sources. This is useful when scanning from sources without filesystem access (e.g., GitHub API).
type TSParser ¶
type TSParser struct {
// contains filtered or unexported fields
}
TSParser wraps a tree-sitter parser for a specific language.
func NewTSParser ¶
NewTSParser creates a new tree-sitter parser for the given language.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package framework provides a unified framework definition system for test framework detection and parsing.
|
Package framework provides a unified framework definition system for test framework detection and parsing. |
|
matchers
Package matchers provides reusable matcher implementations for framework detection.
|
Package matchers provides reusable matcher implementations for framework detection. |
|
strategies
|
|
|
all
Package all imports all parser strategies for side-effect registration.
|
Package all imports all parser strategies for side-effect registration. |
|
cargotest
Package cargotest implements Rust cargo test framework support.
|
Package cargotest implements Rust cargo test framework support. |
|
junit5
Package junit5 implements JUnit 5 (Jupiter) test framework support for Java test files.
|
Package junit5 implements JUnit 5 (Jupiter) test framework support for Java test files. |
|
nunit
Package nunit implements NUnit test framework support for C# test files.
|
Package nunit implements NUnit test framework support for C# test files. |
|
rspec
Package rspec implements RSpec test framework support for Ruby test files.
|
Package rspec implements RSpec test framework support for Ruby test files. |
|
shared/dotnetast
Package dotnetast provides shared C# AST traversal utilities for .NET test framework parsers.
|
Package dotnetast provides shared C# AST traversal utilities for .NET test framework parsers. |
|
shared/javaast
Package javaast provides shared Java AST traversal utilities for test framework parsers.
|
Package javaast provides shared Java AST traversal utilities for test framework parsers. |
|
shared/pyast
Package pyast provides shared Python AST traversal utilities for test framework parsers.
|
Package pyast provides shared Python AST traversal utilities for test framework parsers. |
|
shared/rubyast
Package rubyast provides utilities for working with Ruby AST nodes.
|
Package rubyast provides utilities for working with Ruby AST nodes. |
|
xunit
Package xunit implements xUnit test framework support for C# test files.
|
Package xunit implements xUnit test framework support for C# test files. |
|
Package tspool provides tree-sitter parsers for concurrent parsing.
|
Package tspool provides tree-sitter parsers for concurrent parsing. |