146 lines
7.4 KiB
Diff
146 lines
7.4 KiB
Diff
# 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"},
|
|
|