Test assertions use the specific require helpers for errors, lengths,
JSON, and numeric values. Test setup completes before its server starts
so that a failed assertion stops the test goroutine, not a worker.
enable:
- errorlint
- gocritic
enable:
- errorlint
- gocritic
client := newModelClient(server.URL, ModelAPIKey(modelTestKey), agent.CacheKey(), filepath.Join(agent.dir, "usage.jsonl"))
ctx, cancel := context.WithCancel(t.Context())
done := make(chan error)
client := newModelClient(server.URL, ModelAPIKey(modelTestKey), agent.CacheKey(), filepath.Join(agent.dir, "usage.jsonl"))
ctx, cancel := context.WithCancel(t.Context())
done := make(chan error)
+ subagents := newTestSubagents(t)
go func() {
done <- daemonServe(ctx, listener, bot, whatsapp, schedules, func(notify func(Event)) (*TurnLoop, error) {
go func() {
done <- daemonServe(ctx, listener, bot, whatsapp, schedules, func(notify func(Event)) (*TurnLoop, error) {
- return newTurnLoop(agent, memory, newTestSubagents(t), whatsapp, schedules, client, clock, discardLog(), notify)
+ return newTurnLoop(agent, memory, subagents, whatsapp, schedules, client, clock, discardLog(), notify)
first, err := os.ReadFile(filepath.Join(root, "main", "2026-01-01.jsonl"))
require.NoError(t, err)
first, err := os.ReadFile(filepath.Join(root, "main", "2026-01-01.jsonl"))
require.NoError(t, err)
- require.Equal(t, `{"i":0,"kind":"user","text":"first day","size":9,"date":"2026-01-01T12:00:00Z"}`+"\n", string(first))
+ require.JSONEq(t, `{"i":0,"kind":"user","text":"first day","size":9,"date":"2026-01-01T12:00:00Z"}`+"\n", string(first))
second, err := os.ReadFile(filepath.Join(root, "main", "2026-01-02.jsonl"))
require.NoError(t, err)
second, err := os.ReadFile(filepath.Join(root, "main", "2026-01-02.jsonl"))
require.NoError(t, err)
- require.Equal(t, `{"i":1,"kind":"user","text":"second day","size":10,"date":"2026-01-02T12:00:00Z"}`+"\n", string(second))
+ require.JSONEq(t, `{"i":1,"kind":"user","text":"second day","size":10,"date":"2026-01-02T12:00:00Z"}`+"\n", string(second))
}
func TestLogAllowsOneWriter(t *testing.T) {
}
func TestLogAllowsOneWriter(t *testing.T) {
memory = replayRequireRestart(t, memory, root, clock)
require.Equal(t, messages, memory.log.Len())
memory = replayRequireRestart(t, memory, root, clock)
require.Equal(t, messages, memory.log.Len())
- require.Greater(t, batches, 0)
+ require.Positive(t, batches)
require.NoError(t, memory.Wait(t.Context()))
t.Logf("%d messages, %d nodes, %d batches in %s", messages, memory.tree.Count(), batches, time.Since(start).Round(time.Second))
require.NoError(t, memory.Wait(t.Context()))
t.Logf("%d messages, %d nodes, %d batches in %s", messages, memory.tree.Count(), batches, time.Since(start).Round(time.Second))
terminal.WaitFor(t, "[connected to OneChat]")
telegramWaitForSent(t, telegram, "ok")
terminal.WaitFor(t, "[connected to OneChat]")
telegramWaitForSent(t, telegram, "ok")
- require.Equal(t, float64(10), telegram.Calls()[0].params["offset"])
+ require.InDelta(t, float64(10), telegram.Calls()[0].params["offset"], 0)
require.NotContains(t, terminal.Output(), "handled before the restart")
require.Eventually(t, func() bool {
require.NotContains(t, terminal.Output(), "handled before the restart")
require.Eventually(t, func() bool {
require.LessOrEqual(t, telegramUTF16Units(text), telegramMessageUnits)
}
require.LessOrEqual(t, telegramUTF16Units(text), telegramMessageUnits)
}
- require.True(t, reply == strings.Join(fallback, "")+telegramUnescapeTags(rich[0]), "reply is not sent once and whole")
+ require.Equal(t, reply, strings.Join(fallback, "")+telegramUnescapeTags(rich[0]), "reply is not sent once and whole")
}
func TestRefusedEntitiesGoAgainAsPlainText(t *testing.T) {
}
func TestRefusedEntitiesGoAgainAsPlainText(t *testing.T) {
require.True(t, strings.HasPrefix(text, "0000xxx"))
require.True(t, strings.HasSuffix(text, "0999"+strings.Repeat("x", 995)+"\n"))
require.Contains(t, text, fmt.Sprintf("\n[... %d bytes cut ...]\n", 1000*1000-toolClipCharacters))
require.True(t, strings.HasPrefix(text, "0000xxx"))
require.True(t, strings.HasSuffix(text, "0999"+strings.Repeat("x", 995)+"\n"))
require.Contains(t, text, fmt.Sprintf("\n[... %d bytes cut ...]\n", 1000*1000-toolClipCharacters))
- require.Equal(t, toolClipCharacters+len(fmt.Sprintf("\n[... %d bytes cut ...]\n", 1000*1000-toolClipCharacters)), len(text))
+ require.Len(t, text, toolClipCharacters+len(fmt.Sprintf("\n[... %d bytes cut ...]\n", 1000*1000-toolClipCharacters)))
}
// ToolRecordingLog is a chat log that records each append and flush. The flush
}
// ToolRecordingLog is a chat log that records each append and flush. The flush
data, err := os.ReadFile(filepath.Join(root, "tree", "2026-01-01.jsonl"))
require.NoError(t, err)
data, err := os.ReadFile(filepath.Join(root, "tree", "2026-01-01.jsonl"))
require.NoError(t, err)
- require.Equal(t, `{"l":0,"i":1,"text":"reply: b","size":8}`+"\n", strings.SplitAfter(string(data), "\n")[0])
+ require.JSONEq(t, `{"l":0,"i":1,"text":"reply: b","size":8}`+"\n", strings.SplitAfter(string(data), "\n")[0])
tree, err = openTree(t.Context(), root, 2, clock.Now)
require.NoError(t, err)
tree, err = openTree(t.Context(), root, 2, clock.Now)
require.NoError(t, err)
import (
"context"
"encoding/json"
import (
"context"
"encoding/json"
"log"
"net/http"
"path/filepath"
"log"
"net/http"
"path/filepath"
t.Cleanup(func() {
cancel()
t.Cleanup(func() {
cancel()
- require.True(t, errors.Is(<-done, context.Canceled))
+ require.ErrorIs(t, <-done, context.Canceled)
require.NoError(t, memory.Close())
})
require.NoError(t, memory.Close())
})