Files
kami d52f60c54e maven: fix test mocks for CalendarEvents interface (verification)
- Add CalendarEvents method to recordingAPI in auth_test.go
- Add CalendarEvents method to fakeCore in handlers_test.go

Co-Authored-By: opencode <opencode@anthropic.com>
2026-07-06 04:20:16 +04:00

139 lines
3.3 KiB
Go

package tts
import (
"context"
"testing"
"github.com/kami/maven/internal/audio"
"github.com/kami/maven/internal/worker"
)
type fakeSynthesizer struct{}
func (fakeSynthesizer) Synthesize(_ context.Context, req worker.SynthesizeReq) (worker.SynthesizeResp, error) {
if req.Text == "" {
return worker.SynthesizeResp{}, nil
}
pcm := make([]byte, 3200)
for i := 0; i < len(pcm)/2; i++ {
v := int16(i)
pcm[i*2] = byte(v)
pcm[i*2+1] = byte(v >> 8)
}
return worker.SynthesizeResp{Audio: audio.Audio{Format: audio.PCM16kMono, Bytes: pcm}}, nil
}
func TestStubProducesValidAudio(t *testing.T) {
t.Parallel()
s := NewStub()
a, err := s.Synthesize(context.Background(), "hi")
if err != nil {
t.Fatalf("Stub.Synthesize: %v", err)
}
if !a.Format.IsValid() {
t.Fatalf("format invalid: %+v", a.Format)
}
// 200ms @ 16k ⇒ 3200 samples ⇒ 6400 bytes.
if len(a.Bytes) != 6400 {
t.Fatalf("bytes len: %d, want 6400", len(a.Bytes))
}
// non-empty audio should not be all zeros (sine wave).
allZero := true
for _, b := range a.Bytes {
if b != 0 {
allZero = false
break
}
}
if allZero {
t.Fatalf("Stub audio is all zeros; should be a tone")
}
if a.Duration() < 0.19 || a.Duration() > 0.21 {
t.Fatalf("Duration: got %v, want ~0.2s", a.Duration())
}
}
func TestStubDifferentTextDifferentFreq(t *testing.T) {
t.Parallel()
s := NewStub()
a, _ := s.Synthesize(context.Background(), "a") // 'a' = 97
b, _ := s.Synthesize(context.Background(), "z") // 'z' = 122
// different first byte ⇒ different modulo ⇒ different tones; bytes differ.
if samePCM(a.Bytes, b.Bytes) {
t.Fatalf("expected different tones for 'a' vs 'z'")
}
}
func TestStubEmptyTextStillTones(t *testing.T) {
t.Parallel()
s := NewStub()
a, err := s.Synthesize(context.Background(), "")
if err != nil {
t.Fatalf("Stub.Synthesize: %v", err)
}
if len(a.Bytes) == 0 {
t.Fatalf("empty text should still produce tone (audible), got silence")
}
}
func TestRemoteForwardsToClient(t *testing.T) {
t.Parallel()
srv := worker.NewSynthesizerServer(t.TempDir()+"/tts.sock", fakeSynthesizer{})
if err := srv.Listen(); err != nil {
t.Fatalf("listen: %v", err)
}
defer srv.Close()
go srv.Serve()
c := worker.Dial(srv.Path())
defer c.Close()
r := NewRemote(c, "ru", "")
out, err := r.Synthesize(context.Background(), "hello")
if err != nil {
t.Fatalf("Remote.Synthesize: %v", err)
}
if !out.Format.IsValid() {
t.Fatalf("invalid format: %+v", out.Format)
}
if len(out.Bytes) != 3200 {
t.Fatalf("bytes len: %d, want 3200", len(out.Bytes))
}
}
func TestRemoteErrorWraps(t *testing.T) {
t.Parallel()
// a transcriber-only server ⇒ ErrUnknownMethod on Synthesize.
srv := worker.NewServer(t.TempDir()+"/tts.sock", &fakeErrTranscriber{})
if err := srv.Listen(); err != nil {
t.Fatalf("listen: %v", err)
}
defer srv.Close()
go srv.Serve()
c := worker.Dial(srv.Path())
defer c.Close()
r := NewRemote(c, "ru", "")
_, err := r.Synthesize(context.Background(), "hello")
if err == nil {
t.Fatalf("want error, got nil")
}
}
type fakeErrTranscriber struct{}
func (fakeErrTranscriber) Transcribe(context.Context, worker.TranscribeReq) (worker.TranscribeResp, error) {
return worker.TranscribeResp{}, nil
}
func samePCM(a, b []byte) bool {
if len(a) != len(b) {
return false
}
for i := range a {
if a[i] != b[i] {
return false
}
}
return true
}