Go-based FM stereo transmitter with RDS, Windows-first and cross-platform
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

75 řádky
2.5KB

  1. package config
  2. import (
  3. "os"
  4. "path/filepath"
  5. "testing"
  6. )
  7. func TestDefaultValidate(t *testing.T) {
  8. if err := Default().Validate(); err != nil { t.Fatalf("default invalid: %v", err) }
  9. }
  10. func TestLoadAndValidate(t *testing.T) {
  11. dir := t.TempDir()
  12. path := filepath.Join(dir, "config.json")
  13. os.WriteFile(path, []byte(`{"audio":{"toneLeftHz":900,"toneRightHz":1700,"toneAmplitude":0.3},"fm":{"frequencyMHz":99.9},"backend":{"kind":"file","outputPath":"out.f32"},"control":{"listenAddress":"127.0.0.1:8088"}}`), 0o644)
  14. cfg, err := Load(path)
  15. if err != nil { t.Fatalf("load: %v", err) }
  16. if cfg.Audio.ToneLeftHz != 900 { t.Fatalf("unexpected left tone: %v", cfg.Audio.ToneLeftHz) }
  17. }
  18. func TestValidateRejectsBadFrequency(t *testing.T) {
  19. cfg := Default(); cfg.FM.FrequencyMHz = 200
  20. if err := cfg.Validate(); err == nil { t.Fatal("expected error") }
  21. }
  22. func TestValidateRejectsBadPreEmphasis(t *testing.T) {
  23. cfg := Default(); cfg.FM.PreEmphasisTauUS = 150
  24. if err := cfg.Validate(); err == nil { t.Fatal("expected error") }
  25. }
  26. func TestDefaultPreEmphasis(t *testing.T) {
  27. if Default().FM.PreEmphasisTauUS != 50 { t.Fatal("expected 50") }
  28. }
  29. func TestDefaultFMModulation(t *testing.T) {
  30. cfg := Default()
  31. if !cfg.FM.FMModulationEnabled { t.Fatal("expected true") }
  32. if cfg.FM.MaxDeviationHz != 75000 { t.Fatal("expected 75000") }
  33. }
  34. func TestParsePI(t *testing.T) {
  35. tests := []struct{ in string; want uint16; ok bool }{
  36. {"1234", 0x1234, true},
  37. {"0xBEEF", 0xBEEF, true},
  38. {"0XCAFE", 0xCAFE, true},
  39. {" 0x2345 ", 0x2345, true},
  40. {"", 0, false},
  41. {"nope", 0, false},
  42. }
  43. for _, tt := range tests {
  44. got, err := ParsePI(tt.in)
  45. if tt.ok && err != nil { t.Fatalf("ParsePI(%q): %v", tt.in, err) }
  46. if !tt.ok && err == nil { t.Fatalf("ParsePI(%q): expected error", tt.in) }
  47. if tt.ok && got != tt.want { t.Fatalf("ParsePI(%q): got %x want %x", tt.in, got, tt.want) }
  48. }
  49. }
  50. func TestValidateRejectsInvalidPI(t *testing.T) {
  51. cfg := Default(); cfg.RDS.PI = "nope"
  52. if err := cfg.Validate(); err == nil { t.Fatal("expected error for invalid PI") }
  53. }
  54. func TestValidateRejectsEmptyPI(t *testing.T) {
  55. cfg := Default(); cfg.RDS.PI = ""
  56. if err := cfg.Validate(); err == nil { t.Fatal("expected error for empty PI") }
  57. }
  58. func TestEffectiveDeviceRate(t *testing.T) {
  59. cfg := Default()
  60. if cfg.EffectiveDeviceRate() != float64(cfg.FM.CompositeRateHz) { t.Fatal("expected composite rate when device rate is 0") }
  61. cfg.Backend.DeviceSampleRateHz = 912000
  62. if cfg.EffectiveDeviceRate() != 912000 { t.Fatal("expected 912000") }
  63. }