All PERFORM/RegisterTask/type Task any references replaced with named Action patterns. Every code example now uses the v0.8.0 API. - docs/messaging.md: full rewrite — ACTION/QUERY + named Actions + Task - docs/primitives.md: full rewrite — added Action, Task, Registry, Entitlement - docs/index.md: full rewrite — updated surface table, quick example, doc links - docs/getting-started.md: 2 RegisterTask+PERFORM blocks → Action pattern - docs/testing.md: 1 RegisterTask+PERFORM block → Action pattern An agent reading any doc file now gets compilable code. Co-Authored-By: Virgil <virgil@lethean.io>
116 lines
2.3 KiB
Markdown
116 lines
2.3 KiB
Markdown
---
|
|
title: Testing
|
|
description: Test naming and testing patterns used by CoreGO.
|
|
---
|
|
|
|
# Testing
|
|
|
|
The repository uses `github.com/stretchr/testify/assert` and a simple AX-friendly naming pattern.
|
|
|
|
## Test Names
|
|
|
|
Use:
|
|
|
|
- `_Good` for expected success
|
|
- `_Bad` for expected failure
|
|
- `_Ugly` for panics, degenerate input, and edge behavior
|
|
|
|
Examples from this repository:
|
|
|
|
```go
|
|
func TestNew_Good(t *testing.T) {}
|
|
func TestService_Register_Duplicate_Bad(t *testing.T) {}
|
|
func TestCore_Must_Ugly(t *testing.T) {}
|
|
```
|
|
|
|
## Start with a Small Core
|
|
|
|
```go
|
|
c := core.New(core.Options{
|
|
{Key: "name", Value: "test-core"},
|
|
})
|
|
```
|
|
|
|
Then register only the pieces your test needs.
|
|
|
|
## Test a Service
|
|
|
|
```go
|
|
started := false
|
|
|
|
c.Service("audit", core.Service{
|
|
OnStart: func() core.Result {
|
|
started = true
|
|
return core.Result{OK: true}
|
|
},
|
|
})
|
|
|
|
r := c.ServiceStartup(context.Background(), nil)
|
|
assert.True(t, r.OK)
|
|
assert.True(t, started)
|
|
```
|
|
|
|
## Test a Command
|
|
|
|
```go
|
|
c.Command("greet", core.Command{
|
|
Action: func(opts core.Options) core.Result {
|
|
return core.Result{Value: "hello " + opts.String("name"), OK: true}
|
|
},
|
|
})
|
|
|
|
r := c.Cli().Run("greet", "--name=world")
|
|
assert.True(t, r.OK)
|
|
assert.Equal(t, "hello world", r.Value)
|
|
```
|
|
|
|
## Test a Query or Task
|
|
|
|
```go
|
|
c.RegisterQuery(func(_ *core.Core, q core.Query) core.Result {
|
|
if q == "ping" {
|
|
return core.Result{Value: "pong", OK: true}
|
|
}
|
|
return core.Result{}
|
|
})
|
|
|
|
assert.Equal(t, "pong", c.QUERY("ping").Value)
|
|
```
|
|
|
|
```go
|
|
c.Action("compute", func(_ context.Context, _ core.Options) core.Result {
|
|
return core.Result{Value: 42, OK: true}
|
|
})
|
|
|
|
r := c.Action("compute").Run(context.Background(), core.NewOptions())
|
|
assert.Equal(t, 42, r.Value)
|
|
```
|
|
|
|
## Test Async Work
|
|
|
|
For `PerformAsync`, observe completion through the action bus.
|
|
|
|
```go
|
|
completed := make(chan core.ActionTaskCompleted, 1)
|
|
|
|
c.RegisterAction(func(_ *core.Core, msg core.Message) core.Result {
|
|
if event, ok := msg.(core.ActionTaskCompleted); ok {
|
|
completed <- event
|
|
}
|
|
return core.Result{OK: true}
|
|
})
|
|
```
|
|
|
|
Then wait with normal Go test tools such as channels, timers, or `assert.Eventually`.
|
|
|
|
## Use Real Temporary Paths
|
|
|
|
When testing `Fs`, `Data.Extract`, or other I/O helpers, use `t.TempDir()` and create realistic paths instead of mocking the filesystem by default.
|
|
|
|
## Repository Commands
|
|
|
|
```bash
|
|
core go test
|
|
core go test --run TestPerformAsync_Good
|
|
go test ./...
|
|
```
|