codec_test.mx raw
1 package protocol
2
3 import "testing"
4
5 // The codec-spec table from FEATURES_MUSIC.md, verbatim.
6 func TestCodecSpecTable(t *testing.T) {
7 type vec struct {
8 spec string
9 mime string
10 }
11 vecs := []vec{
12 {"mp3-128kbps-VBR", "audio/mpeg"},
13 {"mp3-320kbps-CBR", "audio/mpeg"},
14 {"aac-256kbps-VBR", "audio/mp4"},
15 {"ogg-vorbis-q8", "audio/ogg"},
16 {"opus-96kbps", "audio/ogg"},
17 {"flac-16bit-44.1kHz", "audio/flac"},
18 {"flac-24bit-96kHz", "audio/flac"},
19 {"wav-24bit-48kHz", "audio/wav"},
20 {"alac-16bit-44.1kHz", "audio/mp4"},
21 }
22 for _, v := range vecs {
23 c, err := ParseCodecSpec(v.spec)
24 if err != nil {
25 t.Fatalf("%s: %s", v.spec, err.Error())
26 }
27 if c.String() != v.spec {
28 t.Fatalf("%s: re-rendered as %q", v.spec, c.String())
29 }
30 if m := MediaType(c.Codec); m != v.mime {
31 t.Fatalf("%s: media type %q, want %q", v.spec, m, v.mime)
32 }
33 }
34 }
35
36 func TestCodecSpecFields(t *testing.T) {
37 c, err := ParseCodecSpec("mp3-128kbps-VBR")
38 if err != nil {
39 t.Fatal(err.Error())
40 }
41 if c.Codec != "mp3" || c.Bitrate != 128 || c.Mode != "VBR" {
42 t.Fatalf("parsed %+v", c)
43 }
44 if c.BitDepth != 0 || c.Quality != 0 || c.SampleRate != "" {
45 t.Fatalf("lossy spec carries lossless fields: %+v", c)
46 }
47 if c.IsLossless() {
48 t.Fatal("mp3 reported as lossless")
49 }
50
51 l, err := ParseCodecSpec("flac-24bit-96kHz")
52 if err != nil {
53 t.Fatal(err.Error())
54 }
55 if l.Codec != "flac" || l.BitDepth != 24 || l.SampleRate != "96" {
56 t.Fatalf("parsed %+v", l)
57 }
58 if !l.IsLossless() {
59 t.Fatal("flac reported as lossy")
60 }
61
62 // A codec name may contain a dash: the form is read from the right.
63 o, err := ParseCodecSpec("ogg-vorbis-q8")
64 if err != nil {
65 t.Fatal(err.Error())
66 }
67 if o.Codec != "ogg-vorbis" || o.Quality != 8 {
68 t.Fatalf("parsed %+v", o)
69 }
70
71 b, err := ParseCodecSpec("aac-256kbps-ABR")
72 if err != nil {
73 t.Fatal(err.Error())
74 }
75 if b.Codec != "aac" || b.Bitrate != 256 || b.Mode != "ABR" {
76 t.Fatalf("parsed %+v", b)
77 }
78 }
79
80 func TestCodecSpecRejects(t *testing.T) {
81 for _, s := range []string{
82 "",
83 "mp3",
84 "mp3-",
85 "mp3-kbps",
86 "mp3-128kbps-XYZ",
87 "flac-24bit-kHz",
88 "flac-24bit-96Mhz",
89 "opus-q",
90 "opus-96kbps-VBR-CBR",
91 } {
92 if _, err := ParseCodecSpec(s); err == nil {
93 t.Errorf("ParseCodecSpec(%q) accepted a bad spec", s)
94 }
95 }
96 }
97
98 func TestSplitDash(t *testing.T) {
99 f := splitDash("flac-24bit-96kHz")
100 if len(f) != 3 || f[0] != "flac" || f[1] != "24bit" || f[2] != "96kHz" {
101 t.Fatalf("split = %v", f)
102 }
103 if got := splitDash(""); got != nil {
104 t.Fatalf("split of empty = %v", got)
105 }
106 }
107
108 func TestIsDecimal(t *testing.T) {
109 for _, s := range []string{"0", "44.1", "96", "192.5"} {
110 if !isDecimal(s) {
111 t.Errorf("isDecimal(%q) = false", s)
112 }
113 }
114 for _, s := range []string{"", ".", ".5", "5.", "4.4.1", "4,1", "-1", "x"} {
115 if isDecimal(s) {
116 t.Errorf("isDecimal(%q) = true", s)
117 }
118 }
119 }
120