The old IPC Task system passed `any` through TaskHandler and
PerformAsync. Now that named Actions exist with typed signatures
(ActionHandler func(context.Context, Options) Result), the untyped
layer is dead weight.
Changes:
- type Task any removed (was in contract.go)
- type Task struct is now the composed sequence (action.go)
- PerformAsync takes (action string, opts Options) not (t Task)
- TaskHandler type removed — use c.Action("name", handler)
- RegisterTask removed — use c.Action("name", handler)
- PERFORM sugar removed — use c.Action("name").Run()
- ActionTaskStarted/Progress/Completed carry typed fields
(Action string, Options, Result) not any
ActionDef → Action rename also in this commit (same principle:
DTOs don't have Run() methods).
Co-Authored-By: Virgil <virgil@lethean.io>
127 lines
2.8 KiB
Go
127 lines
2.8 KiB
Go
package core_test
|
|
|
|
import (
|
|
"context"
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
|
|
. "dappco.re/go/core"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
// --- PerformAsync ---
|
|
|
|
func TestTask_PerformAsync_Good(t *testing.T) {
|
|
c := New()
|
|
var mu sync.Mutex
|
|
var result string
|
|
|
|
c.Action("work", func(_ context.Context, _ Options) Result {
|
|
mu.Lock()
|
|
result = "done"
|
|
mu.Unlock()
|
|
return Result{Value: "done", OK: true}
|
|
})
|
|
|
|
r := c.PerformAsync("work", NewOptions())
|
|
assert.True(t, r.OK)
|
|
assert.True(t, HasPrefix(r.Value.(string), "id-"), "should return task ID")
|
|
|
|
time.Sleep(100 * time.Millisecond)
|
|
|
|
mu.Lock()
|
|
assert.Equal(t, "done", result)
|
|
mu.Unlock()
|
|
}
|
|
|
|
func TestTask_PerformAsync_Good_Progress(t *testing.T) {
|
|
c := New()
|
|
c.Action("tracked", func(_ context.Context, _ Options) Result {
|
|
return Result{OK: true}
|
|
})
|
|
|
|
r := c.PerformAsync("tracked", NewOptions())
|
|
taskID := r.Value.(string)
|
|
c.Progress(taskID, 0.5, "halfway", "tracked")
|
|
}
|
|
|
|
func TestTask_PerformAsync_Good_Completion(t *testing.T) {
|
|
c := New()
|
|
completed := make(chan ActionTaskCompleted, 1)
|
|
|
|
c.Action("completable", func(_ context.Context, _ Options) Result {
|
|
return Result{Value: "output", OK: true}
|
|
})
|
|
|
|
c.RegisterAction(func(_ *Core, msg Message) Result {
|
|
if evt, ok := msg.(ActionTaskCompleted); ok {
|
|
completed <- evt
|
|
}
|
|
return Result{OK: true}
|
|
})
|
|
|
|
c.PerformAsync("completable", NewOptions())
|
|
|
|
select {
|
|
case evt := <-completed:
|
|
assert.True(t, evt.Result.OK)
|
|
assert.Equal(t, "output", evt.Result.Value)
|
|
case <-time.After(2 * time.Second):
|
|
t.Fatal("timed out waiting for completion")
|
|
}
|
|
}
|
|
|
|
func TestTask_PerformAsync_Bad_ActionNotRegistered(t *testing.T) {
|
|
c := New()
|
|
completed := make(chan ActionTaskCompleted, 1)
|
|
|
|
c.RegisterAction(func(_ *Core, msg Message) Result {
|
|
if evt, ok := msg.(ActionTaskCompleted); ok {
|
|
completed <- evt
|
|
}
|
|
return Result{OK: true}
|
|
})
|
|
|
|
c.PerformAsync("nonexistent", NewOptions())
|
|
|
|
select {
|
|
case evt := <-completed:
|
|
assert.False(t, evt.Result.OK, "unregistered action should fail")
|
|
case <-time.After(2 * time.Second):
|
|
t.Fatal("timed out")
|
|
}
|
|
}
|
|
|
|
func TestTask_PerformAsync_Bad_AfterShutdown(t *testing.T) {
|
|
c := New()
|
|
c.Action("work", func(_ context.Context, _ Options) Result { return Result{OK: true} })
|
|
|
|
c.ServiceStartup(context.Background(), nil)
|
|
c.ServiceShutdown(context.Background())
|
|
|
|
r := c.PerformAsync("work", NewOptions())
|
|
assert.False(t, r.OK)
|
|
}
|
|
|
|
// --- RegisterAction + RegisterActions (broadcast handlers) ---
|
|
|
|
func TestTask_RegisterAction_Good(t *testing.T) {
|
|
c := New()
|
|
called := false
|
|
c.RegisterAction(func(_ *Core, _ Message) Result {
|
|
called = true
|
|
return Result{OK: true}
|
|
})
|
|
c.ACTION(nil)
|
|
assert.True(t, called)
|
|
}
|
|
|
|
func TestTask_RegisterActions_Good(t *testing.T) {
|
|
c := New()
|
|
count := 0
|
|
h := func(_ *Core, _ Message) Result { count++; return Result{OK: true} }
|
|
c.RegisterActions(h, h)
|
|
c.ACTION(nil)
|
|
assert.Equal(t, 2, count)
|
|
}
|