1package ytdl
2
3import (
4	"os"
5	"reflect"
6	"strings"
7	"testing"
8
9	"github.com/stretchr/testify/assert"
10	"github.com/stretchr/testify/require"
11)
12
13var formats = FormatList{
14	&Format{Itag: *getItag(18)},
15	&Format{Itag: *getItag(22)},
16	&Format{Itag: *getItag(34)},
17	&Format{Itag: *getItag(37)},
18	&Format{Itag: *getItag(133)},
19	&Format{Itag: *getItag(139)},
20}
21
22type formatListTestCase struct {
23	Key             FormatKey
24	FilterValues    interface{}
25	ExpectedFormats FormatList
26}
27
28func TestFilter(t *testing.T) {
29	cases := []formatListTestCase{
30		{
31			FormatExtensionKey,
32			[]interface{}{"mp4"},
33			FormatList{formats[0], formats[1], formats[3], formats[4], formats[5]},
34		},
35		{
36			FormatResolutionKey,
37			[]interface{}{"360p", "720p"},
38			FormatList{formats[0], formats[1]},
39		},
40		{
41			FormatItagKey,
42			[]interface{}{"22", "37"},
43			FormatList{formats[1], formats[3]},
44		},
45		{
46			FormatAudioBitrateKey,
47			[]interface{}{"96", "128"},
48			FormatList{formats[0], formats[2]},
49		},
50		{
51			FormatResolutionKey,
52			[]interface{}{""},
53			FormatList{formats[5]},
54		},
55		{
56			FormatAudioBitrateKey,
57			[]interface{}{"0"},
58			FormatList{formats[4]},
59		},
60		{
61			FormatResolutionKey,
62			[]interface{}{},
63			nil,
64		},
65	}
66
67	for _, v := range cases {
68		f := formats.Filter(v.Key, v.FilterValues.([]interface{}))
69		if !reflect.DeepEqual(v.ExpectedFormats, f) {
70			t.Error("Format filter test case failed expected", v.ExpectedFormats, "got", f)
71		}
72	}
73}
74
75func TestExtremes(t *testing.T) {
76
77	cases := []formatListTestCase{
78		{
79			FormatResolutionKey,
80			true,
81			FormatList{formats[3]},
82		},
83		{
84			FormatResolutionKey,
85			false,
86			FormatList{formats[5]},
87		},
88		{
89			FormatAudioBitrateKey,
90			true,
91			FormatList{formats[1], formats[3]},
92		},
93		{
94			FormatAudioBitrateKey,
95			false,
96			FormatList{formats[4]},
97		},
98		{
99			FormatItagKey,
100			true,
101			formats,
102		},
103	}
104	for _, v := range cases {
105		f := formats.Extremes(v.Key, v.FilterValues.(bool))
106		if !reflect.DeepEqual(v.ExpectedFormats, f) {
107			t.Error("Format filter test case failed expected", v.ExpectedFormats, "got", f)
108		}
109	}
110}
111
112func TestSubtract(t *testing.T) {
113	cases := []formatListTestCase{
114		{
115			FormatExtensionKey,
116			[]interface{}{"mp4"},
117			FormatList{formats[2]},
118		},
119		{
120			FormatResolutionKey,
121			[]interface{}{"480p", "360p", "240p", ""},
122			FormatList{formats[1], formats[3]},
123		},
124		{
125			FormatResolutionKey,
126			[]interface{}{},
127			formats,
128		},
129	}
130	for _, v := range cases {
131		f := formats.Subtract(formats.Filter(v.Key, v.FilterValues.([]interface{})))
132		if !reflect.DeepEqual(v.ExpectedFormats, f) {
133			t.Error("Format filter test case failed expected", v.ExpectedFormats, "got", f)
134		}
135	}
136}
137
138func TestSort(t *testing.T) {
139	cases := []formatListTestCase{
140		{
141			FormatResolutionKey,
142			formats,
143			FormatList{
144				formats[5],
145				formats[4],
146				formats[0],
147				formats[2],
148				formats[1],
149				formats[3],
150			},
151		},
152		{
153			FormatAudioBitrateKey,
154			formats,
155			FormatList{
156				formats[4],
157				formats[5],
158				formats[0],
159				formats[2],
160				formats[1],
161				formats[3],
162			},
163		},
164	}
165
166	for _, v := range cases {
167		sorted := v.FilterValues.(FormatList).Copy()
168		sorted.Sort(v.Key, false)
169		if !reflect.DeepEqual(v.ExpectedFormats, sorted) {
170			t.Error("FormatList sort failed")
171		}
172	}
173}
174
175func TestCopy(t *testing.T) {
176	if !reflect.DeepEqual(formats, formats.Copy()) {
177		t.Error("Copying format list failed")
178	}
179}
180
181func TestParseStreamList(t *testing.T) {
182	require := require.New(t)
183	assert := assert.New(t)
184	client := newTestClient(t)
185
186	file, err := os.Open("fixtures/stream_map.txt")
187	require.NoError(err)
188	defer file.Close()
189
190	formats := FormatList{}
191	const adaptive = false
192	client.addFormatsByQueryStrings(&formats, file, adaptive)
193
194	require.Len(formats, 2)
195	format := formats[0]
196	assert.Equal(22, format.Number)
197	assert.Equal("mp4", format.Itag.Extension)
198	assert.Equal("720p", format.Itag.Resolution)
199	assert.Equal("H.264", format.Itag.VideoEncoding)
200	assert.Equal("aac", format.Itag.AudioEncoding)
201	assert.Equal(192, format.Itag.AudioBitrate)
202	assert.Len(format.url, 769)
203}
204
205func TestParseStreamListEmpty(t *testing.T) {
206	client := newTestClient(t)
207	formats := FormatList{}
208	const adaptive = false
209	client.addFormatsByQueryStrings(&formats, strings.NewReader(""), adaptive)
210	assert.Len(t, formats, 0)
211}
212