parser

package
v1.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 11, 2025 License: MIT Imports: 23 Imported by: 0

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

Examples

Constants

View Source
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
)
View Source
const MaxTreeDepth = tspool.MaxTreeDepth

Variables

View Source
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")
)
View Source
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

func FindChildByType(node *sitter.Node, nodeType string) *sitter.Node

FindChildByType returns the first direct child with the given node type.

func FindChildrenByType

func FindChildrenByType(node *sitter.Node, nodeType string) []*sitter.Node

FindChildrenByType returns all direct children with the given node type.

func GetLocation

func GetLocation(node *sitter.Node, filename string) domain.Location

GetLocation converts a tree-sitter node position to a domain.Location. Line numbers are converted to 1-based indexing.

func GetNodeText

func GetNodeText(node *sitter.Node, source []byte) (result string)

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

func ParseWithPool(ctx context.Context, lang domain.Language, source []byte) (*sitter.Tree, error)

ParseWithPool parses source using a pooled parser. Caller must close the returned tree.

func WalkTree

func WalkTree(node *sitter.Node, visitor func(*sitter.Node) bool)

WalkTree recursively visits all nodes in the AST. The visitor function returns false to stop traversing into children.

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.

func (ScanError) Error

func (e ScanError) Error() string

Error implements the error interface.

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 WithMaxFileSize

func WithMaxFileSize(size int64) ScanOption

WithMaxFileSize sets the maximum file size to process.

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 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

func (s *Scanner) Scan(ctx context.Context, src source.Source) (*ScanResult, error)

Scan performs the complete scanning process:

  1. Discover and parse config files
  2. Build project scope
  3. Discover test files
  4. Detect framework for each file
  5. 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

func NewTSParser(lang domain.Language) *TSParser

NewTSParser creates a new tree-sitter parser for the given language.

func (*TSParser) Parse

func (p *TSParser) Parse(ctx context.Context, source []byte) (*sitter.Tree, error)

Parse parses the source code and returns the AST tree.

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.
gtest
Package gtest implements Google Test framework support for C++ test files.
Package gtest implements Google Test framework support for C++ test files.
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.
kotest
Package kotest implements Kotest test framework support for Kotlin test files.
Package kotest implements Kotest test framework support for Kotlin test files.
minitest
Package minitest implements Minitest test framework support for Ruby test files.
Package minitest implements Minitest test framework support for Ruby test files.
mstest
Package mstest implements MSTest framework support for C# test files.
Package mstest implements MSTest framework support for C# 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.
phpunit
Package phpunit implements PHPUnit test framework support for PHP test files.
Package phpunit implements PHPUnit test framework support for PHP 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/configutil
Package configutil provides shared utilities for parsing framework config files.
Package configutil provides shared utilities for parsing framework config 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/kotlinast
Package kotlinast provides shared Kotlin AST traversal utilities for test framework parsers.
Package kotlinast provides shared Kotlin AST traversal utilities for test framework parsers.
shared/phpast
Package phpast provides shared PHP AST traversal utilities for test framework parsers.
Package phpast provides shared PHP 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.
shared/swiftast
Package swiftast provides shared Swift AST traversal utilities for test framework parsers.
Package swiftast provides shared Swift AST traversal utilities for test framework parsers.
testng
Package testng implements TestNG test framework support for Java test files.
Package testng implements TestNG test framework support for Java test files.
xctest
Package xctest implements XCTest framework support for Swift test files.
Package xctest implements XCTest framework support for Swift test files.
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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL