Testing Guide
This guide covers how to test code that uses chisel, including test helpers, fixtures, and mocking strategies.
Test Helpers
Chisel provides test utilities in github.com/zoobz-io/chisel/testing:
import (
"testing"
"github.com/zoobz-io/chisel"
chitesting "github.com/zoobz-io/chisel/testing"
)
func TestChunking(t *testing.T) {
chunks := getChunks() // your code
// Assert chunk count
chitesting.AssertChunkCount(t, chunks, 3)
// Assert symbol exists
chitesting.AssertHasSymbol(t, chunks, "UserService")
// Assert kind exists
chitesting.AssertHasKind(t, chunks, chisel.KindClass)
}
Available Helpers
| Function | Description |
|---|---|
AssertChunkCount(t, chunks, n) | Fails if len(chunks) != n |
AssertHasSymbol(t, chunks, sym) | Fails if no chunk has symbol sym |
AssertHasKind(t, chunks, kind) | Fails if no chunk has kind kind |
FindBySymbol(chunks, sym) | Returns first chunk with symbol, or nil |
FindByKind(chunks, kind) | Returns first chunk with kind, or nil |
CountByKind(chunks, kind) | Returns count of chunks with kind |
Testing Chunk Output
For detailed assertions, use FindBySymbol or FindByKind:
func TestAuthenticateFunction(t *testing.T) {
source := []byte(`
func Authenticate(user, pass string) (*User, error) {
// implementation
}
`)
provider := golang.New()
chunks, err := provider.Chunk(context.Background(), "auth.go", source)
if err != nil {
t.Fatal(err)
}
chunk := chitesting.FindBySymbol(chunks, "Authenticate")
if chunk == nil {
t.Fatal("Authenticate not found")
}
if chunk.Kind != chisel.KindFunction {
t.Errorf("Kind = %v, want function", chunk.Kind)
}
if chunk.StartLine != 2 {
t.Errorf("StartLine = %d, want 2", chunk.StartLine)
}
}
Table-Driven Tests
For comprehensive coverage, use table-driven tests:
func TestProviderChunking(t *testing.T) {
tests := []struct {
name string
source string
wantSyms []string
wantKind chisel.Kind
}{
{
name: "function",
source: "func Add(a, b int) int { return a + b }",
wantSyms: []string{"Add"},
wantKind: chisel.KindFunction,
},
{
name: "method",
source: "func (c *Calc) Add(n int) { c.v += n }",
wantSyms: []string{"Calc.Add"},
wantKind: chisel.KindMethod,
},
}
provider := golang.New()
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
src := "package main\n" + tt.source
chunks, err := provider.Chunk(context.Background(), "test.go", []byte(src))
if err != nil {
t.Fatal(err)
}
for _, sym := range tt.wantSyms {
chitesting.AssertHasSymbol(t, chunks, sym)
}
chitesting.AssertHasKind(t, chunks, tt.wantKind)
})
}
}
Mocking Providers
For unit testing code that consumes chunks, mock the provider:
type mockProvider struct {
chunks []chisel.Chunk
err error
}
func (m *mockProvider) Chunk(ctx context.Context, filename string, content []byte) ([]chisel.Chunk, error) {
return m.chunks, m.err
}
func (m *mockProvider) Language() chisel.Language {
return chisel.Go
}
func TestChunkProcessor(t *testing.T) {
mock := &mockProvider{
chunks: []chisel.Chunk{
{Symbol: "Test", Kind: chisel.KindFunction, StartLine: 1, EndLine: 5},
},
}
processor := NewProcessor(mock)
result := processor.Process(context.Background(), "test.go", []byte("..."))
// Assert on result
}
Testing Error Handling
Test that your code handles parsing errors gracefully:
func TestInvalidSource(t *testing.T) {
provider := golang.New()
// Invalid Go syntax
source := []byte("func broken( {")
_, err := provider.Chunk(context.Background(), "bad.go", source)
if err == nil {
t.Error("expected error for invalid syntax")
}
}
Fixture Files
For complex test cases, use fixture files:
testdata/
├── simple.go
├── complex.go
└── expected/
├── simple.json
└── complex.json
func TestFixtures(t *testing.T) {
files, _ := filepath.Glob("testdata/*.go")
for _, file := range files {
t.Run(filepath.Base(file), func(t *testing.T) {
source, _ := os.ReadFile(file)
chunks, err := provider.Chunk(ctx, file, source)
if err != nil {
t.Fatal(err)
}
// Compare against expected output
expected := loadExpected(t, file)
assertChunksEqual(t, chunks, expected)
})
}
}
Benchmarking
Chisel includes benchmarks in testing/benchmarks/. Run them with:
go test -bench=. github.com/zoobz-io/chisel/testing/benchmarks -benchmem
To add benchmarks for your own code:
func BenchmarkMyProcessor(b *testing.B) {
provider := golang.New()
source := loadLargeFile()
b.ResetTimer()
for i := 0; i < b.N; i++ {
chunks, _ := provider.Chunk(context.Background(), "large.go", source)
processChunks(chunks)
}
}
Next Steps
- Troubleshooting — Common issues and solutions
- API Reference — Function signatures