chore(sdd): handoff snapshot — ledger, briefs, reports, review packages + HANDOFF.md for cross-machine continuation
This commit is contained in:
1 parent
acfba19fc2
commit
b934571b97
25 files changed
+17590
No files matched your search
@@ -0,0 +1,145 @@
|
||||
# Review package: 8306c6b..HEAD
|
||||
|
||||
## Commits
|
||||
ae9f3b6 fix(audio): NullSink-Verwurf-Zeile im CLI-Pfad sichtbar machen
|
||||
|
||||
## Files changed
|
||||
cmd/talk/say.go | 2 +-
|
||||
cmd/talk/say_test.go | 7 ++++++-
|
||||
internal/audio/audio.go | 12 +++++++-----
|
||||
internal/audio/audio_test.go | 17 +++++++++++++++--
|
||||
internal/langdetect/detect.go | 2 +-
|
||||
internal/langdetect/detect_test.go | 1 +
|
||||
6 files changed, 31 insertions(+), 10 deletions(-)
|
||||
|
||||
## Diff
|
||||
cmd/talk/say.go --- Go
|
||||
106 return exitFailure
|
||||
107 }
|
||||
108
|
||||
109 sink, err := audio.NewSink(cfg.Audio.Sink, stderr)
|
||||
110 if err != nil {
|
||||
111 fmt.Fprintf(stderr, "talk: %v\n", err)
|
||||
112 return exitFailure
|
||||
|
||||
cmd/talk/say_test.go --- 1/2 --- Go
|
||||
52 52
|
||||
53 // TestSayArgumentMitNullSink: `talk 53 // TestSayArgumentMitNullSink: `talk
|
||||
.. "Hallo Welt"` läuft mit .. "Hallo Welt"` läuft mit
|
||||
54 // TALK_AUDIO_SINK=null tonlos durch 54 // TALK_AUDIO_SINK=null tonlos durch
|
||||
.. (Abnahmekriterium) — Synthese läuft .. (Abnahmekriterium) — Synthese läuft
|
||||
55 // (fake espeak wurde gerufen), die 55 // (fake espeak wurde gerufen), und
|
||||
.. Wiedergabe wird verworfen. .. die Wiedergabe wird mit sichtbarer
|
||||
.. 56 // Verwurf-Zeile auf stderr verworfe
|
||||
.. .. n (extern beobachtbares Verhalten de
|
||||
.. .. s
|
||||
.. 57 // null-Sinks auf dem CLI-Pfad).
|
||||
56 func TestSayArgumentMitNullSink(t *t 58 func TestSayArgumentMitNullSink(t *t
|
||||
.. esting.T) { .. esting.T) {
|
||||
57 seen := withFakeEspeak(t) 59 seen := withFakeEspeak(t)
|
||||
58 setGetenv(t, map[string]string{" 60 setGetenv(t, map[string]string{"
|
||||
.. TALK_AUDIO_SINK": "null"}) .. TALK_AUDIO_SINK": "null"})
|
||||
|
||||
cmd/talk/say_test.go --- 2/2 --- Go
|
||||
65 67 if _, err := os.Stat(seen); err != nil {
|
||||
66 68 t.Errorf("Synthese lief nicht (fake espeak nicht gerufen): %v", err)
|
||||
67 69 }
|
||||
.. 70 if !strings.Contains(errBuf.String(), "verworfen (null sink)") {
|
||||
.. 71 t.Errorf("stderr = %q, will Verwurf-Zeile des null-Sinks (Synthese war erfolgreich)", errBuf.String())
|
||||
.. 72 }
|
||||
68 73 }
|
||||
69 74
|
||||
70 75 // TestSaySubcommandWieDefault: `talk say "Text"` verhält sich wie der
|
||||
|
||||
internal/audio/audio.go --- Go
|
||||
24 } 24 }
|
||||
25 25
|
||||
26 // NewSink liefert den Sink zum konf 26 // NewSink liefert den Sink zum konf
|
||||
.. igurierten Namen ("oto" oder "null") .. igurierten Namen ("oto" oder "null")
|
||||
.. . .. .
|
||||
.. 27 // log ist ein optionaler Log-Output
|
||||
.. .. — die CLI übergibt ihr stderr, über
|
||||
.. .. den
|
||||
.. 28 // der null-Sink seine Verwurf-Zeile
|
||||
.. .. schreibt (nil = still verwerfen); d
|
||||
.. .. er
|
||||
27 // Unbekannte Namen sind ein klarer 29 // oto-Sink braucht kein Log. Unbeka
|
||||
.. Fehler. .. nnte Namen sind ein klarer Fehler.
|
||||
28 func NewSink(name string) (Sink, err 30 func NewSink(name string, log io.Wri
|
||||
.. or) { .. ter) (Sink, error) {
|
||||
29 switch name { 31 switch name {
|
||||
30 case NameOto: 32 case NameOto:
|
||||
31 return OtoSink{}, nil 33 return OtoSink{}, nil
|
||||
32 case NameNull: 34 case NameNull:
|
||||
33 return NullSink{}, nil 35 return NullSink{W: log}, nil
|
||||
34 default: 36 default:
|
||||
35 return nil, fmt.Errorf("unbe 37 return nil, fmt.Errorf("unbe
|
||||
.. kannter audio sink %q (erlaubt: %q, .. kannter audio sink %q (erlaubt: %q,
|
||||
.. %q)", name, NameOto, NameNull) .. %q)", name, NameOto, NameNull)
|
||||
36 } 38 }
|
||||
37 } 39 }
|
||||
38 40
|
||||
39 // NullSink verwirft jede Ansage ohn 41 // NullSink verwirft jede Ansage ohn
|
||||
.. e Ton — für CI, Server und Tests. Wu .. e Ton — für CI, Server und Tests. Wu
|
||||
.. rde .. rde
|
||||
40 // ein W gesetzt, loggt Play eine Ze 42 // ein W gesetzt (NewSink reicht daf
|
||||
.. ile darüber (der CLI-Pfad hängt stde .. ür den Log-Output der CLI durch), lo
|
||||
.. rr .. ggt
|
||||
41 // an, damit „läuft ohne Ton durch" 43 // Play eine Zeile darüber, damit „l
|
||||
.. auch sichtbar bleibt). .. äuft ohne Ton durch" sichtbar bleibt
|
||||
.. .. .
|
||||
42 type NullSink struct { 44 type NullSink struct {
|
||||
43 W io.Writer // optionaler Log-Ou 45 W io.Writer // optionaler Log-Ou
|
||||
.. tput; nil = still verwerfen .. tput; nil = still verwerfen
|
||||
44 } 46 }
|
||||
|
||||
internal/audio/audio_test.go --- Go
|
||||
115 115
|
||||
116 116 func TestNewSink(t *testing.T) {
|
||||
117 117 for _, name := range []string{NameOto, NameNull} {
|
||||
118 118 s, err := NewSink(name, nil)
|
||||
119 119 if err != nil {
|
||||
120 120 t.Fatalf("NewSink(%q): %v", name, err)
|
||||
121 121 }
|
||||
122 122 if s.Name() != name {
|
||||
123 123 t.Errorf("NewSink(%q).Name() = %q", name, s.Name())
|
||||
124 124 }
|
||||
125 125 }
|
||||
126 126 if _, err := NewSink("mpv", nil); err == nil {
|
||||
127 127 t.Error("NewSink(\"mpv\") soll fehlschlagen")
|
||||
128 128 }
|
||||
... 129 t.Run("null-Sink loggt über den Factory-Writer", func(t *testing.T) {
|
||||
... 130 var buf bytes.Buffer
|
||||
... 131 s, err := NewSink(NameNull, &buf)
|
||||
... 132 if err != nil {
|
||||
... 133 t.Fatalf("NewSink(%q): %v", NameNull, err)
|
||||
... 134 }
|
||||
... 135 if err := s.Play(context.Background(), []byte("audio")); err != nil {
|
||||
... 136 t.Fatalf("Play: %v", err)
|
||||
... 137 }
|
||||
... 138 if !strings.Contains(buf.String(), "verworfen (null sink)") {
|
||||
... 139 t.Errorf("Log = %q, will Verwurf-Zeile über den Factory-Writer", buf.String())
|
||||
... 140 }
|
||||
... 141 })
|
||||
129 142 }
|
||||
130 143
|
||||
131 144 func TestNullSinkVerwirftUndLoggt(t *testing.T) {
|
||||
|
||||
internal/langdetect/detect.go --- Go
|
||||
68 "finished": {}, "started": {}, "completed": {}, "error": {},
|
||||
69 "warning": {}, "thanks": {}, "you": {}, "your": {},
|
||||
70 "we": {}, "it": {}, "this": {}, "that": {}, "these": {},
|
||||
71 "those": {}, "was": {}, "were": {}, "are": {}, "be": {},
|
||||
72 "been": {}, "has": {}, "have": {}, "had": {}, "can": {},
|
||||
73 "will": {}, "would": {}, "should": {}, "could": {}, "just": {},
|
||||
74 "only": {}, "still": {}, "already": {}, "now": {}, "today": {},
|
||||
|
||||
internal/langdetect/detect_test.go --- Go
|
||||
15 15 {"nur whitespace", " \n\t ", "de"},
|
||||
16 16 {"nur interpunktion", "!!! ??? ...", "de"},
|
||||
17 17 {"deutsch satz", "Der Build wurde erfolgreich abgeschlossen und das Deployment ist fertig.", "de"},
|
||||
.. 18 {"deutsch frage mit was", "Was macht er?", "de"},
|
||||
18 19 {"deutsch umlaute", "Größe früh Ärzteübung — schön daß es klappt", "de"},
|
||||
19 20 {"ß alleine", "weiß", "de"},
|
||||
20 21 {"englisch satz", "The build has finished and the deployment is done.", "en"},
|
||||
|
||||
Reference in new issue
Block a user