9628b848 by David LaPalomento

Add "parser" support for more m3u8 tags

Regexes and tests for m3u8 tags that are likely to be relevant to playback. High-level m3u8 tests are still failing because their is still no "interpretation" of the incoming parse stream.
1 parent 98b95881
1 (function(parseInt, undefined) { 1 (function(parseInt, undefined) {
2 var Stream, Tokenizer, Parser; 2 var
3 parseAttributes = function(attributes) {
4 var
5 attrs = attributes.split(','),
6 i = attrs.length,
7 result = {},
8 attr;
9 while (i--) {
10 attr = attrs[i].split('=');
11 result[attr[0]] = attr[1];
12 }
13 return result;
14 },
15 Stream,
16 Tokenizer,
17 Parser;
3 18
4 Stream = function() { 19 Stream = function() {
5 var listeners = {}; 20 var listeners = {};
...@@ -107,6 +122,122 @@ ...@@ -107,6 +122,122 @@
107 this.trigger('data', event); 122 this.trigger('data', event);
108 return; 123 return;
109 } 124 }
125 match = (/^#EXT-X-TARGETDURATION:?([0-9.]*)?/).exec(line);
126 if (match) {
127 event = {
128 type: 'tag',
129 tagType: 'targetduration'
130 };
131 if (match[1]) {
132 event.duration = parseInt(match[1], 10);
133 }
134 this.trigger('data', event);
135 return;
136 }
137 match = (/^#EXT-X-VERSION:?([0-9.]*)?/).exec(line);
138 if (match) {
139 event = {
140 type: 'tag',
141 tagType: 'version'
142 };
143 if (match[1]) {
144 event.version = parseInt(match[1], 10);
145 }
146 this.trigger('data', event);
147 return;
148 }
149 match = (/^#EXT-X-MEDIA-SEQUENCE:?([0-9.]*)?/).exec(line);
150 if (match) {
151 event = {
152 type: 'tag',
153 tagType: 'media-sequence'
154 };
155 if (match[1]) {
156 event.number = parseInt(match[1], 10);
157 }
158 this.trigger('data', event);
159 return;
160 }
161 match = (/^#EXT-X-PLAYLIST-TYPE:?(.*)?$/).exec(line);
162 if (match) {
163 event = {
164 type: 'tag',
165 tagType: 'playlist-type'
166 };
167 if (match[1]) {
168 event.playlistType = match[1];
169 }
170 this.trigger('data', event);
171 return;
172 }
173 match = (/^#EXT-X-BYTERANGE:?([0-9.]*)?@?([0-9.]*)?/).exec(line);
174 if (match) {
175 event = {
176 type: 'tag',
177 tagType: 'byterange'
178 };
179 if (match[1]) {
180 event.length = parseInt(match[1], 10);
181 }
182 if (match[2]) {
183 event.offset = parseInt(match[2], 10);
184 }
185 this.trigger('data', event);
186 return;
187 }
188 match = (/^#EXT-X-ALLOW-CACHE:?(YES|NO)?/).exec(line);
189 if (match) {
190 event = {
191 type: 'tag',
192 tagType: 'allow-cache'
193 };
194 if (match[1]) {
195 event.allowed = !(/NO/).test(match[1]);
196 }
197 this.trigger('data', event);
198 return;
199 }
200 match = (/^#EXT-X-STREAM-INF:?(.*)$/).exec(line);
201 if (match) {
202 event = {
203 type: 'tag',
204 tagType: 'stream-inf'
205 };
206 if (match[1]) {
207 event.attributes = parseAttributes(match[1]);
208
209 if (event.attributes.RESOLUTION) {
210 (function() {
211 var
212 split = event.attributes.RESOLUTION.split('x'),
213 resolution = {};
214 if (split[0]) {
215 resolution.width = parseInt(split[0], 10);
216 }
217 if (split[1]) {
218 resolution.height = parseInt(split[1], 10);
219 }
220 event.attributes.RESOLUTION = resolution;
221 })();
222 }
223 if (event.attributes.BANDWIDTH) {
224 event.attributes.BANDWIDTH = parseInt(event.attributes.BANDWIDTH, 10);
225 }
226 if (event.attributes['PROGRAM-ID']) {
227 event.attributes['PROGRAM-ID'] = parseInt(event.attributes['PROGRAM-ID'], 10);
228 }
229 }
230 this.trigger('data', event);
231 return;
232 }
233 match = (/^#EXT-X-ENDLIST/).exec(line);
234 if (match) {
235 this.trigger('data', {
236 type: 'tag',
237 tagType: 'endlist'
238 });
239 return;
240 }
110 241
111 // unknown tag type 242 // unknown tag type
112 this.trigger('data', { 243 this.trigger('data', {
......
...@@ -39,11 +39,11 @@ ...@@ -39,11 +39,11 @@
39 var data = manifestController.parseManifest(window.brightcove_playlist_data); 39 var data = manifestController.parseManifest(window.brightcove_playlist_data);
40 40
41 ok(data); 41 ok(data);
42 equal(data.playlists.length, 4, 'Has correct rendition count'); 42 strictEqual(data.playlists.length, 4, 'Has correct rendition count');
43 equal(data.playlists[0].attributes.bandwidth, 240000, 'First rendition index bandwidth is correct'); 43 strictEqual(data.playlists[0].attributes.bandwidth, 240000, 'First rendition index bandwidth is correct');
44 equal(data.playlists[0].attributes.programId, 1, 'First rendition index program-id is correct'); 44 strictEqual(data.playlists[0].attributes.programId, 1, 'First rendition index program-id is correct');
45 equal(data.playlists[0].attributes.resolution.width, 396, 'First rendition index resolution width is correct'); 45 strictEqual(data.playlists[0].attributes.resolution.width, 396, 'First rendition index resolution width is correct');
46 equal(data.playlists[0].attributes.resolution.height, 224, 'First rendition index resolution height is correct'); 46 strictEqual(data.playlists[0].attributes.resolution.height, 224, 'First rendition index resolution height is correct');
47 }); 47 });
48 48
49 test('should get a manifest from an external URL', function() { 49 test('should get a manifest from an external URL', function() {
...@@ -81,9 +81,9 @@ ...@@ -81,9 +81,9 @@
81 }); 81 });
82 tokenizer.push('#EXTM3U\nmovie.ts\n'); 82 tokenizer.push('#EXTM3U\nmovie.ts\n');
83 83
84 equal(2, lines.length, 'two lines are ready'); 84 strictEqual(2, lines.length, 'two lines are ready');
85 equal('#EXTM3U', lines.shift(), 'the first line is the first token'); 85 strictEqual('#EXTM3U', lines.shift(), 'the first line is the first token');
86 equal('movie.ts', lines.shift(), 'the second line is the second token'); 86 strictEqual('movie.ts', lines.shift(), 'the second line is the second token');
87 }); 87 });
88 test('empty lines become empty strings', function() { 88 test('empty lines become empty strings', function() {
89 var lines = []; 89 var lines = [];
...@@ -92,9 +92,9 @@ ...@@ -92,9 +92,9 @@
92 }); 92 });
93 tokenizer.push('\n\n'); 93 tokenizer.push('\n\n');
94 94
95 equal(2, lines.length, 'two lines are ready'); 95 strictEqual(2, lines.length, 'two lines are ready');
96 equal('', lines.shift(), 'the first line is empty'); 96 strictEqual('', lines.shift(), 'the first line is empty');
97 equal('', lines.shift(), 'the second line is empty'); 97 strictEqual('', lines.shift(), 'the second line is empty');
98 }); 98 });
99 test('handles lines broken across appends', function() { 99 test('handles lines broken across appends', function() {
100 var lines = []; 100 var lines = [];
...@@ -102,12 +102,12 @@ ...@@ -102,12 +102,12 @@
102 lines.push(line); 102 lines.push(line);
103 }); 103 });
104 tokenizer.push('#EXTM'); 104 tokenizer.push('#EXTM');
105 equal(0, lines.length, 'no lines are ready'); 105 strictEqual(0, lines.length, 'no lines are ready');
106 106
107 tokenizer.push('3U\nmovie.ts\n'); 107 tokenizer.push('3U\nmovie.ts\n');
108 equal(2, lines.length, 'two lines are ready'); 108 strictEqual(2, lines.length, 'two lines are ready');
109 equal('#EXTM3U', lines.shift(), 'the first line is the first token'); 109 strictEqual('#EXTM3U', lines.shift(), 'the first line is the first token');
110 equal('movie.ts', lines.shift(), 'the second line is the second token'); 110 strictEqual('movie.ts', lines.shift(), 'the second line is the second token');
111 }); 111 });
112 test('stops sending events after deregistering', function() { 112 test('stops sending events after deregistering', function() {
113 var 113 var
...@@ -123,12 +123,12 @@ ...@@ -123,12 +123,12 @@
123 tokenizer.on('data', temporary); 123 tokenizer.on('data', temporary);
124 tokenizer.on('data', permanent); 124 tokenizer.on('data', permanent);
125 tokenizer.push('line one\n'); 125 tokenizer.push('line one\n');
126 equal(temporaryLines.length, permanentLines.length, 'both callbacks receive the event'); 126 strictEqual(temporaryLines.length, permanentLines.length, 'both callbacks receive the event');
127 127
128 ok(tokenizer.off('data', temporary), 'a listener was removed'); 128 ok(tokenizer.off('data', temporary), 'a listener was removed');
129 tokenizer.push('line two\n'); 129 tokenizer.push('line two\n');
130 equal(1, temporaryLines.length, 'no new events are received'); 130 strictEqual(1, temporaryLines.length, 'no new events are received');
131 equal(2, permanentLines.length, 'new events are still received'); 131 strictEqual(2, permanentLines.length, 'new events are still received');
132 }); 132 });
133 133
134 module('M3U8 Parser', { 134 module('M3U8 Parser', {
...@@ -148,8 +148,8 @@ ...@@ -148,8 +148,8 @@
148 tokenizer.push(manifest); 148 tokenizer.push(manifest);
149 149
150 ok(element, 'an event was triggered'); 150 ok(element, 'an event was triggered');
151 equal(element.type, 'comment', 'the type is comment'); 151 strictEqual(element.type, 'comment', 'the type is comment');
152 equal(element.text, 152 strictEqual(element.text,
153 manifest.slice(1, manifest.length - 1), 153 manifest.slice(1, manifest.length - 1),
154 'the comment text is parsed'); 154 'the comment text is parsed');
155 }); 155 });
...@@ -163,8 +163,8 @@ ...@@ -163,8 +163,8 @@
163 tokenizer.push(manifest); 163 tokenizer.push(manifest);
164 164
165 ok(element, 'an event was triggered'); 165 ok(element, 'an event was triggered');
166 equal(element.type, 'uri', 'the type is uri'); 166 strictEqual(element.type, 'uri', 'the type is uri');
167 equal(element.uri, 167 strictEqual(element.uri,
168 manifest.substring(0, manifest.length - 1), 168 manifest.substring(0, manifest.length - 1),
169 'the uri text is parsed'); 169 'the uri text is parsed');
170 }); 170 });
...@@ -178,11 +178,13 @@ ...@@ -178,11 +178,13 @@
178 tokenizer.push(manifest); 178 tokenizer.push(manifest);
179 179
180 ok(element, 'an event was triggered'); 180 ok(element, 'an event was triggered');
181 equal(element.type, 'tag', 'the type is tag'); 181 strictEqual(element.type, 'tag', 'the type is tag');
182 equal(element.data, 182 strictEqual(element.data,
183 manifest.slice(4, manifest.length - 1), 183 manifest.slice(4, manifest.length - 1),
184 'unknown tag data is preserved'); 184 'unknown tag data is preserved');
185 }); 185 });
186
187 // #EXTM3U
186 test('parses #EXTM3U tags', function() { 188 test('parses #EXTM3U tags', function() {
187 var 189 var
188 manifest = '#EXTM3U\n', 190 manifest = '#EXTM3U\n',
...@@ -193,9 +195,11 @@ ...@@ -193,9 +195,11 @@
193 tokenizer.push(manifest); 195 tokenizer.push(manifest);
194 196
195 ok(element, 'an event was triggered'); 197 ok(element, 'an event was triggered');
196 equal(element.type, 'tag', 'the line type is tag'); 198 strictEqual(element.type, 'tag', 'the line type is tag');
197 equal(element.tagType, 'm3u', 'the tag type is m3u'); 199 strictEqual(element.tagType, 'm3u', 'the tag type is m3u');
198 }); 200 });
201
202 // #EXTINF
199 test('parses minimal #EXTINF tags', function() { 203 test('parses minimal #EXTINF tags', function() {
200 var 204 var
201 manifest = '#EXTINF\n', 205 manifest = '#EXTINF\n',
...@@ -206,8 +210,8 @@ ...@@ -206,8 +210,8 @@
206 tokenizer.push(manifest); 210 tokenizer.push(manifest);
207 211
208 ok(element, 'an event was triggered'); 212 ok(element, 'an event was triggered');
209 equal(element.type, 'tag', 'the line type is tag'); 213 strictEqual(element.type, 'tag', 'the line type is tag');
210 equal(element.tagType, 'inf', 'the tag type is inf'); 214 strictEqual(element.tagType, 'inf', 'the tag type is inf');
211 }); 215 });
212 test('parses #EXTINF tags with durations', function() { 216 test('parses #EXTINF tags with durations', function() {
213 var 217 var
...@@ -219,18 +223,18 @@ ...@@ -219,18 +223,18 @@
219 tokenizer.push(manifest); 223 tokenizer.push(manifest);
220 224
221 ok(element, 'an event was triggered'); 225 ok(element, 'an event was triggered');
222 equal(element.type, 'tag', 'the line type is tag'); 226 strictEqual(element.type, 'tag', 'the line type is tag');
223 equal(element.tagType, 'inf', 'the tag type is inf'); 227 strictEqual(element.tagType, 'inf', 'the tag type is inf');
224 equal(element.duration, 15, 'the duration is parsed'); 228 strictEqual(element.duration, 15, 'the duration is parsed');
225 ok(!('title' in element), 'no title is parsed'); 229 ok(!('title' in element), 'no title is parsed');
226 230
227 manifest = '#EXTINF:21,\n' 231 manifest = '#EXTINF:21,\n'
228 tokenizer.push(manifest); 232 tokenizer.push(manifest);
229 233
230 ok(element, 'an event was triggered'); 234 ok(element, 'an event was triggered');
231 equal(element.type, 'tag', 'the line type is tag'); 235 strictEqual(element.type, 'tag', 'the line type is tag');
232 equal(element.tagType, 'inf', 'the tag type is inf'); 236 strictEqual(element.tagType, 'inf', 'the tag type is inf');
233 equal(element.duration, 21, 'the duration is parsed'); 237 strictEqual(element.duration, 21, 'the duration is parsed');
234 ok(!('title' in element), 'no title is parsed'); 238 ok(!('title' in element), 'no title is parsed');
235 }); 239 });
236 test('parses #EXTINF tags with a duration and title', function() { 240 test('parses #EXTINF tags with a duration and title', function() {
...@@ -243,13 +247,302 @@ ...@@ -243,13 +247,302 @@
243 tokenizer.push(manifest); 247 tokenizer.push(manifest);
244 248
245 ok(element, 'an event was triggered'); 249 ok(element, 'an event was triggered');
246 equal(element.type, 'tag', 'the line type is tag'); 250 strictEqual(element.type, 'tag', 'the line type is tag');
247 equal(element.tagType, 'inf', 'the tag type is inf'); 251 strictEqual(element.tagType, 'inf', 'the tag type is inf');
248 equal(element.duration, 13, 'the duration is parsed'); 252 strictEqual(element.duration, 13, 'the duration is parsed');
249 equal(element.title, 253 strictEqual(element.title,
250 manifest.substring(manifest.indexOf(',') + 1, manifest.length - 1), 254 manifest.substring(manifest.indexOf(',') + 1, manifest.length - 1),
251 'the title is parsed'); 255 'the title is parsed');
252 }); 256 });
257
258 // #EXT-X-TARGETDURATION
259 test('parses minimal #EXT-X-TARGETDURATION tags', function() {
260 var
261 manifest = '#EXT-X-TARGETDURATION\n',
262 element;
263 parser.on('data', function(elem) {
264 element = elem;
265 });
266 tokenizer.push(manifest);
267
268 ok(element, 'an event was triggered');
269 strictEqual(element.type, 'tag', 'the line type is tag');
270 strictEqual(element.tagType, 'targetduration', 'the tag type is targetduration');
271 ok(!('duration' in element), 'no duration is parsed');
272 });
273 test('parses #EXT-X-TARGETDURATION with duration', function() {
274 var
275 manifest = '#EXT-X-TARGETDURATION:47\n',
276 element;
277 parser.on('data', function(elem) {
278 element = elem;
279 });
280 tokenizer.push(manifest);
281
282 ok(element, 'an event was triggered');
283 strictEqual(element.type, 'tag', 'the line type is tag');
284 strictEqual(element.tagType, 'targetduration', 'the tag type is targetduration');
285 strictEqual(element.duration, 47, 'the duration is parsed');
286 });
287
288 // #EXT-X-VERSION
289 test('parses minimal #EXT-X-VERSION tags', function() {
290 var
291 manifest = '#EXT-X-VERSION:\n',
292 element;
293 parser.on('data', function(elem) {
294 element = elem;
295 });
296 tokenizer.push(manifest);
297
298 ok(element, 'an event was triggered');
299 strictEqual(element.type, 'tag', 'the line type is tag');
300 strictEqual(element.tagType, 'version', 'the tag type is version');
301 ok(!('version' in element), 'no version is present');
302 });
303 test('parses #EXT-X-VERSION with a version', function() {
304 var
305 manifest = '#EXT-X-VERSION:99\n',
306 element;
307 parser.on('data', function(elem) {
308 element = elem;
309 });
310 tokenizer.push(manifest);
311
312 ok(element, 'an event was triggered');
313 strictEqual(element.type, 'tag', 'the line type is tag');
314 strictEqual(element.tagType, 'version', 'the tag type is version');
315 strictEqual(element.version, 99, 'the version is parsed');
316 });
317
318 // #EXT-X-MEDIA-SEQUENCE
319 test('parses minimal #EXT-X-MEDIA-SEQUENCE tags', function() {
320 var
321 manifest = '#EXT-X-MEDIA-SEQUENCE\n',
322 element;
323 parser.on('data', function(elem) {
324 element = elem;
325 });
326 tokenizer.push(manifest);
327
328 ok(element, 'an event was triggered');
329 strictEqual(element.type, 'tag', 'the line type is tag');
330 strictEqual(element.tagType, 'media-sequence', 'the tag type is media-sequence');
331 ok(!('number' in element), 'no number is present');
332 });
333 test('parses #EXT-X-MEDIA-SEQUENCE with sequence numbers', function() {
334 var
335 manifest = '#EXT-X-MEDIA-SEQUENCE:109\n',
336 element;
337 parser.on('data', function(elem) {
338 element = elem;
339 });
340 tokenizer.push(manifest);
341
342 ok(element, 'an event was triggered');
343 strictEqual(element.type, 'tag', 'the line type is tag');
344 strictEqual(element.tagType, 'media-sequence', 'the tag type is media-sequence');
345 ok(element.number, 109, 'the number is parsed');
346 });
347
348 // #EXT-X-PLAYLIST-TYPE
349 test('parses minimal #EXT-X-PLAYLIST-TYPE tags', function() {
350 var
351 manifest = '#EXT-X-PLAYLIST-TYPE:\n',
352 element;
353 parser.on('data', function(elem) {
354 element = elem;
355 });
356 tokenizer.push(manifest);
357
358 ok(element, 'an event was triggered');
359 strictEqual(element.type, 'tag', 'the line type is tag');
360 strictEqual(element.tagType, 'playlist-type', 'the tag type is playlist-type');
361 ok(!('playlistType' in element), 'no playlist type is present');
362 });
363 test('parses #EXT-X-PLAYLIST-TYPE with mutability info', function() {
364 var
365 manifest = '#EXT-X-PLAYLIST-TYPE:EVENT\n',
366 element;
367 parser.on('data', function(elem) {
368 element = elem;
369 });
370 tokenizer.push(manifest);
371
372 ok(element, 'an event was triggered');
373 strictEqual(element.type, 'tag', 'the line type is tag');
374 strictEqual(element.tagType, 'playlist-type', 'the tag type is playlist-type');
375 strictEqual(element.playlistType, 'EVENT', 'the playlist type is EVENT');
376
377 manifest = '#EXT-X-PLAYLIST-TYPE:VOD\n';
378 tokenizer.push(manifest);
379 ok(element, 'an event was triggered');
380 strictEqual(element.type, 'tag', 'the line type is tag');
381 strictEqual(element.tagType, 'playlist-type', 'the tag type is playlist-type');
382 strictEqual(element.playlistType, 'VOD', 'the playlist type is VOD');
383
384 manifest = '#EXT-X-PLAYLIST-TYPE:nonsense\n';
385 tokenizer.push(manifest);
386 ok(element, 'an event was triggered');
387 strictEqual(element.type, 'tag', 'the line type is tag');
388 strictEqual(element.tagType, 'playlist-type', 'the tag type is playlist-type');
389 strictEqual(element.playlistType, 'nonsense', 'the playlist type is parsed');
390 });
391
392 // #EXT-X-BYTERANGE
393 test('parses minimal #EXT-X-BYTERANGE tags', function() {
394 var
395 manifest = '#EXT-X-BYTERANGE\n',
396 element;
397 parser.on('data', function(elem) {
398 element = elem;
399 });
400 tokenizer.push(manifest);
401
402 ok(element, 'an event was triggered');
403 strictEqual(element.type, 'tag', 'the line type is tag');
404 strictEqual(element.tagType, 'byterange', 'the tag type is byterange');
405 ok(!('length' in element), 'no length is present');
406 ok(!('offset' in element), 'no offset is present');
407 });
408 test('parses #EXT-X-BYTERANGE with length and offset', function() {
409 var
410 manifest = '#EXT-X-BYTERANGE:45\n',
411 element;
412 parser.on('data', function(elem) {
413 element = elem;
414 });
415 tokenizer.push(manifest);
416
417 ok(element, 'an event was triggered');
418 strictEqual(element.type, 'tag', 'the line type is tag');
419 strictEqual(element.tagType, 'byterange', 'the tag type is byterange');
420 strictEqual(element.length, 45, 'length is parsed');
421 ok(!('offset' in element), 'no offset is present');
422
423 manifest = '#EXT-X-BYTERANGE:108@16\n';
424 tokenizer.push(manifest);
425 ok(element, 'an event was triggered');
426 strictEqual(element.type, 'tag', 'the line type is tag');
427 strictEqual(element.tagType, 'byterange', 'the tag type is byterange');
428 strictEqual(element.length, 108, 'length is parsed');
429 strictEqual(element.offset, 16, 'offset is parsed');
430 });
431
432 // #EXT-X-ALLOW-CACHE
433 test('parses minimal #EXT-X-ALLOW-CACHE tags', function() {
434 var
435 manifest = '#EXT-X-ALLOW-CACHE:\n',
436 element;
437 parser.on('data', function(elem) {
438 element = elem;
439 });
440 tokenizer.push(manifest);
441
442 ok(element, 'an event was triggered');
443 strictEqual(element.type, 'tag', 'the line type is tag');
444 strictEqual(element.tagType, 'allow-cache', 'the tag type is allow-cache');
445 ok(!('allowed' in element), 'no allowed is present');
446 });
447 test('parses valid #EXT-X-ALLOW-CACHE tags', function() {
448 var
449 manifest = '#EXT-X-ALLOW-CACHE:YES\n',
450 element;
451 parser.on('data', function(elem) {
452 element = elem;
453 });
454 tokenizer.push(manifest);
455
456 ok(element, 'an event was triggered');
457 strictEqual(element.type, 'tag', 'the line type is tag');
458 strictEqual(element.tagType, 'allow-cache', 'the tag type is allow-cache');
459 ok(element.allowed, 'allowed is parsed');
460
461 manifest = '#EXT-X-ALLOW-CACHE:NO\n';
462 tokenizer.push(manifest);
463
464 ok(element, 'an event was triggered');
465 strictEqual(element.type, 'tag', 'the line type is tag');
466 strictEqual(element.tagType, 'allow-cache', 'the tag type is allow-cache');
467 ok(!element.allowed, 'allowed is parsed');
468 });
469 // #EXT-X-STREAM-INF
470 test('parses minimal #EXT-X-STREAM-INF tags', function() {
471 var
472 manifest = '#EXT-X-STREAM-INF\n',
473 element;
474 parser.on('data', function(elem) {
475 element = elem;
476 });
477 tokenizer.push(manifest);
478
479 ok(element, 'an event was triggered');
480 strictEqual(element.type, 'tag', 'the line type is tag');
481 strictEqual(element.tagType, 'stream-inf', 'the tag type is stream-inf');
482 ok(!('attributes' in element), 'no attributes are present');
483 });
484 test('parses #EXT-X-STREAM-INF with common attributes', function() {
485 var
486 manifest = '#EXT-X-STREAM-INF:BANDWIDTH=14400\n',
487 element;
488 parser.on('data', function(elem) {
489 element = elem;
490 });
491 tokenizer.push(manifest);
492
493 ok(element, 'an event was triggered');
494 strictEqual(element.type, 'tag', 'the line type is tag');
495 strictEqual(element.tagType, 'stream-inf', 'the tag type is stream-inf');
496 strictEqual(element.attributes.BANDWIDTH, 14400, 'bandwidth is parsed');
497
498 manifest = '#EXT-X-STREAM-INF:PROGRAM-ID=7\n';
499 tokenizer.push(manifest);
500
501 ok(element, 'an event was triggered');
502 strictEqual(element.type, 'tag', 'the line type is tag');
503 strictEqual(element.tagType, 'stream-inf', 'the tag type is stream-inf');
504 strictEqual(element.attributes['PROGRAM-ID'], 7, 'program-id is parsed');
505
506 manifest = '#EXT-X-STREAM-INF:RESOLUTION=396x224\n';
507 tokenizer.push(manifest);
508
509 ok(element, 'an event was triggered');
510 strictEqual(element.type, 'tag', 'the line type is tag');
511 strictEqual(element.tagType, 'stream-inf', 'the tag type is stream-inf');
512 strictEqual(element.attributes.RESOLUTION.width, 396, 'width is parsed');
513 strictEqual(element.attributes.RESOLUTION.height, 224, 'heigth is parsed');
514 });
515 test('parses #EXT-X-STREAM-INF with arbitrary attributes', function() {
516 var
517 manifest = '#EXT-X-STREAM-INF:NUMERIC=24,ALPHA=Value,MIXED=123abc\n',
518 element;
519 parser.on('data', function(elem) {
520 element = elem;
521 });
522 tokenizer.push(manifest);
523
524 ok(element, 'an event was triggered');
525 strictEqual(element.type, 'tag', 'the line type is tag');
526 strictEqual(element.tagType, 'stream-inf', 'the tag type is stream-inf');
527 strictEqual(element.attributes.NUMERIC, '24', 'numeric attributes are parsed');
528 strictEqual(element.attributes.ALPHA, 'Value', 'alphabetic attributes are parsed');
529 strictEqual(element.attributes.MIXED, '123abc', 'mixed attributes are parsed');
530 });
531 // #EXT-X-ENDLIST
532 test('parses #EXT-X-ENDLIST tags', function() {
533 var
534 manifest = '#EXT-X-ENDLIST\n',
535 element;
536 parser.on('data', function(elem) {
537 element = elem;
538 });
539 tokenizer.push(manifest);
540
541 ok(element, 'an event was triggered');
542 strictEqual(element.type, 'tag', 'the line type is tag');
543 strictEqual(element.tagType, 'endlist', 'the tag type is stream-inf');
544 });
545
253 test('ignores empty lines', function() { 546 test('ignores empty lines', function() {
254 var 547 var
255 manifest = '\n', 548 manifest = '\n',
...@@ -290,15 +583,15 @@ ...@@ -290,15 +583,15 @@
290 }); 583 });
291 tokenizer.push(window.playlistData); 584 tokenizer.push(window.playlistData);
292 585
293 notEqual(data, null, 'data is not NULL'); 586 notStrictEqual(data, null, 'data is not NULL');
294 equal(data.openTag, true, 'data has valid EXTM3U'); 587 strictEqual(data.openTag, true, 'data has valid EXTM3U');
295 equal(data.targetDuration, 10, 'data has correct TARGET DURATION'); 588 strictEqual(data.targetDuration, 10, 'data has correct TARGET DURATION');
296 equal(data.allowCache, undefined, 'ALLOW-CACHE is not present in the manifest'); 589 strictEqual(data.allowCache, undefined, 'ALLOW-CACHE is not present in the manifest');
297 equal(data.playlistType, "VOD", 'acceptable PLAYLIST TYPE'); 590 strictEqual(data.playlistType, "VOD", 'acceptable PLAYLIST TYPE');
298 equal(data.segments.length, 17, 'there are 17 segments in the manifest'); 591 strictEqual(data.segments.length, 17, 'there are 17 segments in the manifest');
299 equal(data.mediaSequence, 0, 'MEDIA SEQUENCE is correct'); 592 strictEqual(data.mediaSequence, 0, 'MEDIA SEQUENCE is correct');
300 equal(data.totalDuration, undefined, "no total duration is specified"); 593 strictEqual(data.totalDuration, undefined, "no total duration is specified");
301 equal(data.closeTag, true, 'should have ENDLIST tag'); 594 strictEqual(data.closeTag, true, 'should have ENDLIST tag');
302 }); 595 });
303 596
304 /*3.4.7. EXT-X-PLAYLIST-TYPE 597 /*3.4.7. EXT-X-PLAYLIST-TYPE
...@@ -314,9 +607,9 @@ ...@@ -314,9 +607,9 @@
314 607
315 The EXT-X-PLAYLIST-TYPE tag MUST NOT appear in a Master Playlist. 608 The EXT-X-PLAYLIST-TYPE tag MUST NOT appear in a Master Playlist.
316 */ 609 */
317 610
318 test('should have parsed VOD playlist type', function() { 611 test('should have parsed VOD playlist type', function() {
319 var 612 var
320 playlistTemplate = Handlebars.compile(window.playlist_type_template), 613 playlistTemplate = Handlebars.compile(window.playlist_type_template),
321 testData = {playlistType: 'VOD'}, 614 testData = {playlistType: 'VOD'},
322 playlistData = playlistTemplate(testData), 615 playlistData = playlistTemplate(testData),
...@@ -326,13 +619,13 @@ ...@@ -326,13 +619,13 @@
326 }); 619 });
327 tokenizer.push(window.playlistData); 620 tokenizer.push(window.playlistData);
328 621
329 notEqual(data, null, 'data is not NULL'); 622 notStrictEqual(data, null, 'data is not NULL');
330 //equal(data.invalidReasons.length, 0, 'Errors object should not be empty.'); 623 //strictEqual(data.invalidReasons.length, 0, 'Errors object should not be empty.');
331 equal(data.playlistType, "VOD", 'acceptable PLAYLIST TYPE'); 624 strictEqual(data.playlistType, "VOD", 'acceptable PLAYLIST TYPE');
332 }); 625 });
333 626
334 test('should have parsed EVENT playlist type', function() { 627 test('should have parsed EVENT playlist type', function() {
335 var 628 var
336 playlistTemplate = Handlebars.compile(window.playlist_type_template), 629 playlistTemplate = Handlebars.compile(window.playlist_type_template),
337 testData = {playlistType: 'EVENT'}, 630 testData = {playlistType: 'EVENT'},
338 playlistData = playlistTemplate(testData), 631 playlistData = playlistTemplate(testData),
...@@ -342,13 +635,13 @@ ...@@ -342,13 +635,13 @@
342 }); 635 });
343 tokenizer.push(window.playlistData); 636 tokenizer.push(window.playlistData);
344 637
345 notEqual(data, null, 'data is not NULL'); 638 notStrictEqual(data, null, 'data is not NULL');
346 //equal(data.invalidReasons.length, 0, 'Errors object should not be empty.'); 639 //strictEqual(data.invalidReasons.length, 0, 'Errors object should not be empty.');
347 equal(data.playlistType, "EVENT", 'acceptable PLAYLIST TYPE'); 640 strictEqual(data.playlistType, "EVENT", 'acceptable PLAYLIST TYPE');
348 }); 641 });
349 642
350 test('handles a missing playlist type', function() { 643 test('handles a missing playlist type', function() {
351 var 644 var
352 playlistTemplate = Handlebars.compile(window.playlist_type_template), 645 playlistTemplate = Handlebars.compile(window.playlist_type_template),
353 testData = {}, 646 testData = {},
354 playlistData = playlistTemplate(testData), 647 playlistData = playlistTemplate(testData),
...@@ -358,21 +651,21 @@ ...@@ -358,21 +651,21 @@
358 }); 651 });
359 tokenizer.push(window.playlistData); 652 tokenizer.push(window.playlistData);
360 653
361 notEqual(data, null, 'data is not NULL'); 654 notStrictEqual(data, null, 'data is not NULL');
362 //equal(data.invalidReasons.length, 0, 'Errors object should not be empty.'); 655 //strictEqual(data.invalidReasons.length, 0, 'Errors object should not be empty.');
363 //equal(data.warnings, 'EXT-X-PLAYLIST-TYPE was empty or missing. Assuming VOD'); 656 //strictEqual(data.warnings, 'EXT-X-PLAYLIST-TYPE was empty or missing. Assuming VOD');
364 equal(data.playlistType, undefined, 'no PLAYLIST TYPE present'); 657 strictEqual(data.playlistType, undefined, 'no PLAYLIST TYPE present');
365 }); 658 });
366 659
367 test('should have an invalid reason due to invalid playlist type', function() { 660 test('should have an invalid reason due to invalid playlist type', function() {
368 var 661 var
369 playlistTemplate = Handlebars.compile(window.playlist_type_template), 662 playlistTemplate = Handlebars.compile(window.playlist_type_template),
370 testData = {playlistType: 'baklsdhfajsdf'}, 663 testData = {playlistType: 'baklsdhfajsdf'},
371 playlistData = playlistTemplate(testData), 664 playlistData = playlistTemplate(testData),
372 data = m3u8parser.parse(playlistData); 665 data = m3u8parser.parse(playlistData);
373 notEqual(data, null, 'data is not NULL'); 666 notStrictEqual(data, null, 'data is not NULL');
374 //equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons'); 667 //strictEqual(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
375 //equal(data.invalidReasons[0], 'Invalid Playlist Type Value: \'baklsdhfajsdf\''); 668 //strictEqual(data.invalidReasons[0], 'Invalid Playlist Type Value: \'baklsdhfajsdf\'');
376 }); 669 });
377 670
378 // test('handles an empty playlist type', function() { 671 // test('handles an empty playlist type', function() {
...@@ -381,10 +674,10 @@ ...@@ -381,10 +674,10 @@
381 // testData = {playlistType: ''}, 674 // testData = {playlistType: ''},
382 // playlistData = playlistTemplate(testData), 675 // playlistData = playlistTemplate(testData),
383 // data = m3u8parser.parse(playlistData); 676 // data = m3u8parser.parse(playlistData);
384 // notEqual(data, null, 'data is not NULL'); 677 // notStrictEqual(data, null, 'data is not NULL');
385 // //equal(data.invalidReasons.length, 0, 'Errors object should not be empty.'); 678 // //strictEqual(data.invalidReasons.length, 0, 'Errors object should not be empty.');
386 // //equal(data.warnings, 'EXT-X-PLAYLIST-TYPE was empty or missing. Assuming VOD'); 679 // //strictEqual(data.warnings, 'EXT-X-PLAYLIST-TYPE was empty or missing. Assuming VOD');
387 // equal(data.playlistType, '', 'PLAYLIST TYPE is the empty string'); 680 // strictEqual(data.playlistType, '', 'PLAYLIST TYPE is the empty string');
388 // }); 681 // });
389 682
390 /*3.4.2. EXT-X-TARGETDURATION 683 /*3.4.2. EXT-X-TARGETDURATION
...@@ -405,72 +698,72 @@ ...@@ -405,72 +698,72 @@
405 */ 698 */
406 699
407 test('valid target duration', function() { 700 test('valid target duration', function() {
408 var 701 var
409 playlistTemplate = Handlebars.compile(window.playlist_target_duration_template), 702 playlistTemplate = Handlebars.compile(window.playlist_target_duration_template),
410 testData = {targetDuration: '10'}, 703 testData = {targetDuration: '10'},
411 playlistData = playlistTemplate(testData), 704 playlistData = playlistTemplate(testData),
412 data = m3u8parser.parse(playlistData); 705 data = m3u8parser.parse(playlistData);
413 notEqual(data, null, 'data is not NULL'); 706 notStrictEqual(data, null, 'data is not NULL');
414 equal(data.targetDuration, 10, 'data has correct TARGET DURATION'); 707 strictEqual(data.targetDuration, 10, 'data has correct TARGET DURATION');
415 //equal(data.invalidReasons.length, 0, 'data has 1 invalid reasons'); 708 //strictEqual(data.invalidReasons.length, 0, 'data has 1 invalid reasons');
416 }); 709 });
417 710
418 test('NaN target duration', function() { 711 test('NaN target duration', function() {
419 var 712 var
420 playlistTemplate = Handlebars.compile(window.playlist_target_duration_template), 713 playlistTemplate = Handlebars.compile(window.playlist_target_duration_template),
421 testData = {targetDuration: 'string'}, 714 testData = {targetDuration: 'string'},
422 playlistData = playlistTemplate(testData), 715 playlistData = playlistTemplate(testData),
423 data = m3u8parser.parse(playlistData); 716 data = m3u8parser.parse(playlistData);
424 console.log(playlistData); 717 console.log(playlistData);
425 console.log(data.targetDuration); 718 console.log(data.targetDuration);
426 notEqual(data, null, 'data is not NULL'); 719 notStrictEqual(data, null, 'data is not NULL');
427 // notEqual(data.invalidReasons, null, 'invalidReasons is not NULL'); 720 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
428 // equal(data.invalidReasons.length, 1, 'data has 0 invalid reasons'); 721 // strictEqual(data.invalidReasons.length, 1, 'data has 0 invalid reasons');
429 // equal(data.invalidReasons[0], 'Invalid Target Duration Value: \'NaN\''); 722 // strictEqual(data.invalidReasons[0], 'Invalid Target Duration Value: \'NaN\'');
430 }); 723 });
431 724
432 test('empty target duration', function() { 725 test('empty target duration', function() {
433 var 726 var
434 playlistTemplate = Handlebars.compile(window.playlist_target_duration_template), 727 playlistTemplate = Handlebars.compile(window.playlist_target_duration_template),
435 testData = {targetDuration: '\'\''}, 728 testData = {targetDuration: '\'\''},
436 playlistData = playlistTemplate(testData), 729 playlistData = playlistTemplate(testData),
437 data = m3u8parser.parse(playlistData); 730 data = m3u8parser.parse(playlistData);
438 console.log(playlistData); 731 console.log(playlistData);
439 console.log(data.targetDuration); 732 console.log(data.targetDuration);
440 notEqual(data, null, 'data is not NULL'); 733 notStrictEqual(data, null, 'data is not NULL');
441 // notEqual(data.invalidReasons, null, 'invalidReasons is not NULL'); 734 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
442 // equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons'); 735 // strictEqual(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
443 // equal(data.invalidReasons[0], 'Invalid Target Duration Value: \'NaN\''); 736 // strictEqual(data.invalidReasons[0], 'Invalid Target Duration Value: \'NaN\'');
444 }); 737 });
445 738
446 test('undefined target duration', function() { 739 test('undefined target duration', function() {
447 var 740 var
448 playlistTemplate = Handlebars.compile(window.playlist_target_duration_template), 741 playlistTemplate = Handlebars.compile(window.playlist_target_duration_template),
449 testData = {}, 742 testData = {},
450 playlistData = playlistTemplate(testData), 743 playlistData = playlistTemplate(testData),
451 data = m3u8parser.parse(playlistData); 744 data = m3u8parser.parse(playlistData);
452 console.log(playlistData); 745 console.log(playlistData);
453 console.log(data.targetDuration); 746 console.log(data.targetDuration);
454 notEqual(data, null, 'data is not NULL'); 747 notStrictEqual(data, null, 'data is not NULL');
455 // notEqual(data.invalidReasons, null, 'invalidReasons is not NULL'); 748 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
456 // equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons'); 749 // strictEqual(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
457 // equal(data.invalidReasons[0], 'Invalid Target Duration Value: \'undefined\''); 750 // strictEqual(data.invalidReasons[0], 'Invalid Target Duration Value: \'undefined\'');
458 751
459 }); 752 });
460 753
461 test('target duration lower than segment', function() { 754 test('target duration lower than segment', function() {
462 var 755 var
463 playlistTemplate = Handlebars.compile(window.playlist_target_duration_template), 756 playlistTemplate = Handlebars.compile(window.playlist_target_duration_template),
464 testData = {targetDuration: '4'}, 757 testData = {targetDuration: '4'},
465 playlistData = playlistTemplate(testData), 758 playlistData = playlistTemplate(testData),
466 data = m3u8parser.parse(playlistData); 759 data = m3u8parser.parse(playlistData);
467 760
468 notEqual(data, null, 'data is not NULL'); 761 notStrictEqual(data, null, 'data is not NULL');
469 // notEqual(data.invalidReasons, null, 'invalidReasons is not NULL'); 762 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
470 // equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons'); 763 // strictEqual(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
471 // equal(data.invalidReasons[0], 'Invalid Target Duration Value: 4 is lower than segments'); 764 // strictEqual(data.invalidReasons[0], 'Invalid Target Duration Value: 4 is lower than segments');
472 }); 765 });
473 766
474 /*3.4.3. EXT-X-MEDIA-SEQUENCE 767 /*3.4.3. EXT-X-MEDIA-SEQUENCE
475 768
476 Each media segment in a Playlist has a unique integer sequence 769 Each media segment in a Playlist has a unique integer sequence
...@@ -489,48 +782,48 @@ ...@@ -489,48 +782,48 @@
489 MEDIA-SEQUENCE tag then the sequence number of the first segment in 782 MEDIA-SEQUENCE tag then the sequence number of the first segment in
490 the playlist SHALL be considered to be 0. A client MUST NOT assume 783 the playlist SHALL be considered to be 0. A client MUST NOT assume
491 that segments with the same sequence number in different Media 784 that segments with the same sequence number in different Media
492 Playlists contain matching content. 785 Playlists contain matching content.
493 786
494 A media URI is not required to contain its sequence number. 787 A media URI is not required to contain its sequence number.
495 */ 788 */
496 789
497 test('media sequence is valid in the playlist', function() { 790 test('media sequence is valid in the playlist', function() {
498 var 791 var
499 playlistTemplate = Handlebars.compile(window.playlist_media_sequence_template), 792 playlistTemplate = Handlebars.compile(window.playlist_media_sequence_template),
500 testData = {mediaSequence: '0'}, 793 testData = {mediaSequence: '0'},
501 playlistData = playlistTemplate(testData), 794 playlistData = playlistTemplate(testData),
502 data = m3u8parser.parse(playlistData); 795 data = m3u8parser.parse(playlistData);
503 796
504 notEqual(data, null, 'data is not NULL'); 797 notStrictEqual(data, null, 'data is not NULL');
505 // notEqual(data.invalidReasons, null, 'invalidReasons is not NULL'); 798 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
506 // equal(data.invalidReasons.length, 0, 'Errors object should not be empty.'); 799 // strictEqual(data.invalidReasons.length, 0, 'Errors object should not be empty.');
507 equal(data.mediaSequence, 0, 'MEDIA SEQUENCE is correct'); 800 strictEqual(data.mediaSequence, 0, 'MEDIA SEQUENCE is correct');
508 }); 801 });
509 802
510 test('media sequence is encountered twice in the playlist', function() { 803 test('media sequence is encountered twice in the playlist', function() {
511 var 804 var
512 playlistTemplate = Handlebars.compile(window.playlist_media_sequence_template), 805 playlistTemplate = Handlebars.compile(window.playlist_media_sequence_template),
513 testData = {mediaSequence: '0', mediaSequence1: '1'}, 806 testData = {mediaSequence: '0', mediaSequence1: '1'},
514 playlistData = playlistTemplate(testData), 807 playlistData = playlistTemplate(testData),
515 data = m3u8parser.parse(playlistData); 808 data = m3u8parser.parse(playlistData);
516 809
517 notEqual(data, null, 'data is not NULL'); 810 notStrictEqual(data, null, 'data is not NULL');
518 // notEqual(data.invalidReasons, null, 'invalidReasons is not NULL'); 811 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
519 // equal(data.invalidReasons.length, 0, 'Errors object should not be empty.'); 812 // strictEqual(data.invalidReasons.length, 0, 'Errors object should not be empty.');
520 equal(data.mediaSequence, 0, 'MEDIA SEQUENCE tags after the first should be ignored'); 813 strictEqual(data.mediaSequence, 0, 'MEDIA SEQUENCE tags after the first should be ignored');
521 }); 814 });
522 815
523 test('media sequence is undefined in the playlist', function() { 816 test('media sequence is undefined in the playlist', function() {
524 var 817 var
525 playlistTemplate = Handlebars.compile(window.playlist_media_sequence_template), 818 playlistTemplate = Handlebars.compile(window.playlist_media_sequence_template),
526 testData = {mediaSequence: ''}, 819 testData = {mediaSequence: ''},
527 playlistData = playlistTemplate(testData), 820 playlistData = playlistTemplate(testData),
528 data = m3u8parser.parse(playlistData); 821 data = m3u8parser.parse(playlistData);
529 822
530 notEqual(data, null, 'data is not NULL'); 823 notStrictEqual(data, null, 'data is not NULL');
531 // notEqual(data.invalidReasons, null, 'invalidReasons is not NULL'); 824 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
532 // equal(data.invalidReasons.length, 0, 'Errors object should not be empty.'); 825 // strictEqual(data.invalidReasons.length, 0, 'Errors object should not be empty.');
533 equal(data.mediaSequence, undefined, 'MEDIA SEQUENCE is undefined'); 826 strictEqual(data.mediaSequence, undefined, 'MEDIA SEQUENCE is undefined');
534 }); 827 });
535 828
536 // test('media sequence is empty in the playlist', function() { 829 // test('media sequence is empty in the playlist', function() {
...@@ -540,50 +833,50 @@ ...@@ -540,50 +833,50 @@
540 // playlistData = playlistTemplate(testData), 833 // playlistData = playlistTemplate(testData),
541 // data = m3u8parser.parse(playlistData); 834 // data = m3u8parser.parse(playlistData);
542 835
543 // notEqual(data, null, 'data is not NULL'); 836 // notStrictEqual(data, null, 'data is not NULL');
544 // // notEqual(data.invalidReasons, null, 'invalidReasons is not NULL'); 837 // // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
545 // // equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons'); 838 // // strictEqual(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
546 // equal(data.mediaSequence, '', 'media sequence is the empty string'); 839 // strictEqual(data.mediaSequence, '', 'media sequence is the empty string');
547 // }); 840 // });
548 841
549 test('media sequence is high (non-zero in first file) in the playlist', function() { 842 test('media sequence is high (non-zero in first file) in the playlist', function() {
550 var 843 var
551 playlistTemplate = Handlebars.compile(window.playlist_media_sequence_template), 844 playlistTemplate = Handlebars.compile(window.playlist_media_sequence_template),
552 testData = {mediaSequence: '1'}, 845 testData = {mediaSequence: '1'},
553 playlistData = playlistTemplate(testData), 846 playlistData = playlistTemplate(testData),
554 data = m3u8parser.parse(playlistData); 847 data = m3u8parser.parse(playlistData);
555 848
556 notEqual(data, null, 'data is not NULL'); 849 notStrictEqual(data, null, 'data is not NULL');
557 // notEqual(data.invalidReasons, null, 'invalidReasons is not NULL'); 850 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
558 // equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons'); 851 // strictEqual(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
559 // equal(data.invalidReasons[0], 'Invalid Media Sequence Value: \'1\''); 852 // strictEqual(data.invalidReasons[0], 'Invalid Media Sequence Value: \'1\'');
560 }); 853 });
561 854
562 test('handles invalid media sequence numbers in the playlist', function() { 855 test('handles invalid media sequence numbers in the playlist', function() {
563 var 856 var
564 playlistTemplate = Handlebars.compile(window.playlist_media_sequence_template), 857 playlistTemplate = Handlebars.compile(window.playlist_media_sequence_template),
565 testData = {mediaSequence: '-1'}, 858 testData = {mediaSequence: '-1'},
566 playlistData = playlistTemplate(testData), 859 playlistData = playlistTemplate(testData),
567 data = m3u8parser.parse(playlistData); 860 data = m3u8parser.parse(playlistData);
568 861
569 notEqual(data, null, 'data is not NULL'); 862 notStrictEqual(data, null, 'data is not NULL');
570 // notEqual(data.invalidReasons, null, 'invalidReasons is not NULL'); 863 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
571 // equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons'); 864 // strictEqual(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
572 // equal(data.invalidReasons[0], 'Invalid Media Sequence Value: \'-1\''); 865 // strictEqual(data.invalidReasons[0], 'Invalid Media Sequence Value: \'-1\'');
573 equal(data.mediaSequence, -1, 'negative media sequence numbers don\'t break parsing'); 866 strictEqual(data.mediaSequence, -1, 'negative media sequence numbers don\'t break parsing');
574 }); 867 });
575 868
576 test('media sequence invalid (string) in the playlist', function() { 869 test('media sequence invalid (string) in the playlist', function() {
577 var 870 var
578 playlistTemplate = Handlebars.compile(window.playlist_media_sequence_template), 871 playlistTemplate = Handlebars.compile(window.playlist_media_sequence_template),
579 testData = {mediaSequence: 'asdfkasdkfl'}, 872 testData = {mediaSequence: 'asdfkasdkfl'},
580 playlistData = playlistTemplate(testData), 873 playlistData = playlistTemplate(testData),
581 data = m3u8parser.parse(playlistData); 874 data = m3u8parser.parse(playlistData);
582 875
583 notEqual(data, null, 'data is not NULL'); 876 notStrictEqual(data, null, 'data is not NULL');
584 // notEqual(data.invalidReasons, null, 'invalidReasons is not NULL'); 877 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
585 // equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons'); 878 // strictEqual(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
586 // equal(data.invalidReasons[0], 'Invalid Media Sequence Value: \'asdfkasdkfl\''); 879 // strictEqual(data.invalidReasons[0], 'Invalid Media Sequence Value: \'asdfkasdkfl\'');
587 }); 880 });
588 881
589 module('Representative Playlist', { 882 module('Representative Playlist', {
...@@ -596,13 +889,13 @@ ...@@ -596,13 +889,13 @@
596 var data = m3u8parser.parse(window.brightcove_playlist_data); 889 var data = m3u8parser.parse(window.brightcove_playlist_data);
597 890
598 ok(data); 891 ok(data);
599 equal(data.playlists.length, 4, 'has correct playlist count'); 892 strictEqual(data.playlists.length, 4, 'has correct playlist count');
600 equal(data.playlists[0].attributes.bandwidth, 240000, 'first rendition index bandwidth is correct'); 893 strictEqual(data.playlists[0].attributes.bandwidth, 240000, 'first rendition index bandwidth is correct');
601 equal(data.playlists[0].attributes.programId, 1, 'first rendition index program-id is correct'); 894 strictEqual(data.playlists[0].attributes.programId, 1, 'first rendition index program-id is correct');
602 equal(data.playlists[0].attributes.resolution.width, 895 strictEqual(data.playlists[0].attributes.resolution.width,
603 396, 896 396,
604 'first rendition index resolution width is correct'); 897 'first rendition index resolution width is correct');
605 equal(data.playlists[0].attributes.resolution.height, 898 strictEqual(data.playlists[0].attributes.resolution.height,
606 224, 899 224,
607 'first rendition index resolution height is correct'); 900 'first rendition index resolution height is correct');
608 901
...@@ -630,111 +923,111 @@ ...@@ -630,111 +923,111 @@
630 file, when rounded to the nearest integer, MUST be less than or equal 923 file, when rounded to the nearest integer, MUST be less than or equal
631 to the target duration. 924 to the target duration.
632 */ 925 */
633 926
634 test('test valid extinf values in playlist', function() { 927 test('test valid extinf values in playlist', function() {
635 var 928 var
636 playlistTemplate = Handlebars.compile(window.playlist_extinf_template), 929 playlistTemplate = Handlebars.compile(window.playlist_extinf_template),
637 testData = {version: 4, extInf: '10', extInf1: '10', extInf2: '10', segment: 'hls_450k_video.ts'}, 930 testData = {version: 4, extInf: '10', extInf1: '10', extInf2: '10', segment: 'hls_450k_video.ts'},
638 playlistData = playlistTemplate(testData), 931 playlistData = playlistTemplate(testData),
639 data = m3u8parser.parse(playlistData); 932 data = m3u8parser.parse(playlistData);
640 933
641 notEqual(data, null, 'data is not NULL'); 934 notStrictEqual(data, null, 'data is not NULL');
642 // notEqual(data.invalidReasons, null, 'invalidReasons is not NULL'); 935 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
643 // equal(data.invalidReasons.length, 0, 'Errors object should not be empty.'); 936 // strictEqual(data.invalidReasons.length, 0, 'Errors object should not be empty.');
644 }); 937 });
645 938
646 test('test valid extinf without associated segment in playlist', function() { 939 test('test valid extinf without associated segment in playlist', function() {
647 var 940 var
648 playlistTemplate = Handlebars.compile(window.playlist_extinf_template), 941 playlistTemplate = Handlebars.compile(window.playlist_extinf_template),
649 testData = {version: 4, extInf: '10', extInf1: '10', extInf2: '10'}, 942 testData = {version: 4, extInf: '10', extInf1: '10', extInf2: '10'},
650 playlistData = playlistTemplate(testData), 943 playlistData = playlistTemplate(testData),
651 data = m3u8parser.parse(playlistData); 944 data = m3u8parser.parse(playlistData);
652 945
653 notEqual(data, null, 'data is not NULL'); 946 notStrictEqual(data, null, 'data is not NULL');
654 // notEqual(data.invalidReasons, null, 'invalidReasons is not NULL'); 947 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
655 // equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons'); 948 // strictEqual(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
656 //equal(data.invalidReasons[0], 'Invalid Segment Data: \'#EXTINF missing segment\''); 949 //strictEqual(data.invalidReasons[0], 'Invalid Segment Data: \'#EXTINF missing segment\'');
657 }); 950 });
658 951
659 // 952 //
660 test('test invalid extinf values in playlist', function() { 953 test('test invalid extinf values in playlist', function() {
661 var 954 var
662 playlistTemplate = Handlebars.compile(window.playlist_extinf_template), 955 playlistTemplate = Handlebars.compile(window.playlist_extinf_template),
663 testData = {version: 4, extInf: 'asdf', extInf1: '10', extInf2: '10', segment: 'hls_450k_video.ts'}, 956 testData = {version: 4, extInf: 'asdf', extInf1: '10', extInf2: '10', segment: 'hls_450k_video.ts'},
664 playlistData = playlistTemplate(testData), 957 playlistData = playlistTemplate(testData),
665 data = m3u8parser.parse(playlistData); 958 data = m3u8parser.parse(playlistData);
666 959
667 notEqual(data, null, 'data is not NULL'); 960 notStrictEqual(data, null, 'data is not NULL');
668 // notEqual(data.invalidReasons, null, 'invalidReasons is not NULL'); 961 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
669 // equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons'); 962 // strictEqual(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
670 }); 963 });
671 964
672 //its best practice that every extinf have the same value, but its not required 965 //its best practice that every extinf have the same value, but its not required
673 test('test inconsistent extinf values in playlist below target duration', function() { 966 test('test inconsistent extinf values in playlist below target duration', function() {
674 var 967 var
675 playlistTemplate = Handlebars.compile(window.playlist_extinf_template), 968 playlistTemplate = Handlebars.compile(window.playlist_extinf_template),
676 testData = {version: 4, extInf: '10', extInf1: '7', extInf2: '10', segment: 'hls_450k_video.ts'}, 969 testData = {version: 4, extInf: '10', extInf1: '7', extInf2: '10', segment: 'hls_450k_video.ts'},
677 playlistData = playlistTemplate(testData), 970 playlistData = playlistTemplate(testData),
678 data = m3u8parser.parse(playlistData); 971 data = m3u8parser.parse(playlistData);
679 972
680 notEqual(data, null, 'data is not NULL'); 973 notStrictEqual(data, null, 'data is not NULL');
681 // notEqual(data.invalidReasons, null, 'invalidReasons is not NULL'); 974 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
682 // equal(data.invalidReasons.length, 0, 'Errors object should not be empty.'); 975 // strictEqual(data.invalidReasons.length, 0, 'Errors object should not be empty.');
683 }); 976 });
684 977
685 //extinf values must be below the target duration 978 //extinf values must be below the target duration
686 test('test inconsistent extinf values in playlist above target duration', function() { 979 test('test inconsistent extinf values in playlist above target duration', function() {
687 var 980 var
688 playlistTemplate = Handlebars.compile(window.playlist_extinf_template), 981 playlistTemplate = Handlebars.compile(window.playlist_extinf_template),
689 testData = {version: 4, extInf: '10', extInf1: '7', extInf2: '10', segment: 'hls_450k_video.ts'}, 982 testData = {version: 4, extInf: '10', extInf1: '7', extInf2: '10', segment: 'hls_450k_video.ts'},
690 playlistData = playlistTemplate(testData), 983 playlistData = playlistTemplate(testData),
691 data = m3u8parser.parse(playlistData); 984 data = m3u8parser.parse(playlistData);
692 985
693 notEqual(data, null, 'data is not NULL'); 986 notStrictEqual(data, null, 'data is not NULL');
694 // notEqual(data.invalidReasons, null, 'invalidReasons is not NULL'); 987 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
695 // equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons'); 988 // strictEqual(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
696 // equal(data.invalidReasons[0], 'Invalid Segment Data: \'#EXTINF value higher than #TARGETDURATION\''); 989 // strictEqual(data.invalidReasons[0], 'Invalid Segment Data: \'#EXTINF value higher than #TARGETDURATION\'');
697 }); 990 });
698 991
699 //extinf values must be below the target duration 992 //extinf values must be below the target duration
700 test('test floating-point values not accepted with version 3', function() { 993 test('test floating-point values not accepted with version 3', function() {
701 var 994 var
702 playlistTemplate = Handlebars.compile(window.playlist_extinf_template), 995 playlistTemplate = Handlebars.compile(window.playlist_extinf_template),
703 testData = {version: 3, extInf: '10.5', extInf1: '10.5', extInf2: '10.5', segment: 'hls_450k_video.ts'}, 996 testData = {version: 3, extInf: '10.5', extInf1: '10.5', extInf2: '10.5', segment: 'hls_450k_video.ts'},
704 playlistData = playlistTemplate(testData), 997 playlistData = playlistTemplate(testData),
705 data = m3u8parser.parse(playlistData); 998 data = m3u8parser.parse(playlistData);
706 999
707 notEqual(data, null, 'data is not NULL'); 1000 notStrictEqual(data, null, 'data is not NULL');
708 // notEqual(data.invalidReasons, null, 'invalidReasons is not NULL'); 1001 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
709 // equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons'); 1002 // strictEqual(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
710 // equal(data.invalidReasons[0], 'Invalid Segment Data: \'#EXTINF value not an integer\''); 1003 // strictEqual(data.invalidReasons[0], 'Invalid Segment Data: \'#EXTINF value not an integer\'');
711 }); 1004 });
712 1005
713 //extinf values must be below the target duration 1006 //extinf values must be below the target duration
714 test('test floating-point values accepted with version 4', function() { 1007 test('test floating-point values accepted with version 4', function() {
715 var 1008 var
716 playlistTemplate = Handlebars.compile(window.playlist_extinf_template), 1009 playlistTemplate = Handlebars.compile(window.playlist_extinf_template),
717 testData = {version: 4, extInf: '10.5', extInf1: '10.5', extInf2: '10.5', segment: 'hls_450k_video.ts'}, 1010 testData = {version: 4, extInf: '10.5', extInf1: '10.5', extInf2: '10.5', segment: 'hls_450k_video.ts'},
718 playlistData = playlistTemplate(testData), 1011 playlistData = playlistTemplate(testData),
719 data = m3u8parser.parse(playlistData); 1012 data = m3u8parser.parse(playlistData);
720 1013
721 notEqual(data, null, 'data is not NULL'); 1014 notStrictEqual(data, null, 'data is not NULL');
722 // notEqual(data.invalidReasons, null, 'invalidReasons is not NULL'); 1015 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
723 // equal(data.invalidReasons.length, 0, 'Errors object should not be empty.'); 1016 // strictEqual(data.invalidReasons.length, 0, 'Errors object should not be empty.');
724 }); 1017 });
725 1018
726 //extinf values must be below the target duration 1019 //extinf values must be below the target duration
727 test('test empty EXTINF values', function() { 1020 test('test empty EXTINF values', function() {
728 var 1021 var
729 playlistTemplate = Handlebars.compile(window.playlist_extinf_template), 1022 playlistTemplate = Handlebars.compile(window.playlist_extinf_template),
730 testData = {version: 4, extInf: '', extInf1: '10.5', extInf2: '10.5', segment: 'hls_450k_video.ts'}, 1023 testData = {version: 4, extInf: '', extInf1: '10.5', extInf2: '10.5', segment: 'hls_450k_video.ts'},
731 playlistData = playlistTemplate(testData), 1024 playlistData = playlistTemplate(testData),
732 data = m3u8parser.parse(playlistData); 1025 data = m3u8parser.parse(playlistData);
733 1026
734 notEqual(data, null, 'data is not NULL'); 1027 notStrictEqual(data, null, 'data is not NULL');
735 // notEqual(data.invalidReasons, null, 'invalidReasons is not NULL'); 1028 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
736 // equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons'); 1029 // strictEqual(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
737 // equal(data.invalidReasons[0], 'Invalid Segment Data: \'#EXTINF value empty\''); 1030 // strictEqual(data.invalidReasons[0], 'Invalid Segment Data: \'#EXTINF value empty\'');
738 }); 1031 });
739 1032
740 /* 1033 /*
...@@ -748,45 +1041,45 @@ ...@@ -748,45 +1041,45 @@
748 1041
749 #EXT-X-ALLOW-CACHE:<YES|NO> 1042 #EXT-X-ALLOW-CACHE:<YES|NO>
750 */ 1043 */
751 1044
752 test('test EXT-X-ALLOW-CACHE YES', function() { 1045 test('test EXT-X-ALLOW-CACHE YES', function() {
753 var 1046 var
754 playlistTemplate = Handlebars.compile(window.playlist_allow_cache), 1047 playlistTemplate = Handlebars.compile(window.playlist_allow_cache),
755 testData = {version: 4, allowCache: 'YES'}, 1048 testData = {version: 4, allowCache: 'YES'},
756 playlistData = playlistTemplate(testData), 1049 playlistData = playlistTemplate(testData),
757 data = m3u8parser.parse(playlistData); 1050 data = m3u8parser.parse(playlistData);
758 1051
759 notEqual(data, null, 'data is not NULL'); 1052 notStrictEqual(data, null, 'data is not NULL');
760 // notEqual(data.invalidReasons, null, 'invalidReasons is not NULL'); 1053 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
761 // equal(data.invalidReasons.length, 0, 'Errors object should not be empty.'); 1054 // strictEqual(data.invalidReasons.length, 0, 'Errors object should not be empty.');
762 equal(data.allowCache, 'YES', 'EXT-X-ALLOW-CACHE should be YES'); 1055 strictEqual(data.allowCache, 'YES', 'EXT-X-ALLOW-CACHE should be YES');
763 }); 1056 });
764 1057
765 test('test EXT-X-ALLOW-CACHE NO', function() { 1058 test('test EXT-X-ALLOW-CACHE NO', function() {
766 var 1059 var
767 playlistTemplate = Handlebars.compile(window.playlist_allow_cache), 1060 playlistTemplate = Handlebars.compile(window.playlist_allow_cache),
768 testData = {version: 4, allowCache: 'NO'}, 1061 testData = {version: 4, allowCache: 'NO'},
769 playlistData = playlistTemplate(testData), 1062 playlistData = playlistTemplate(testData),
770 data = m3u8parser.parse(playlistData); 1063 data = m3u8parser.parse(playlistData);
771 1064
772 notEqual(data, null, 'data is not NULL'); 1065 notStrictEqual(data, null, 'data is not NULL');
773 // notEqual(data.invalidReasons, null, 'invalidReasons is not NULL'); 1066 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
774 // equal(data.invalidReasons.length, 0, 'Errors object should not be empty.'); 1067 // strictEqual(data.invalidReasons.length, 0, 'Errors object should not be empty.');
775 equal(data.allowCache, 'NO', 'EXT-X-ALLOW-CACHE should be NO'); 1068 strictEqual(data.allowCache, 'NO', 'EXT-X-ALLOW-CACHE should be NO');
776 }); 1069 });
777 1070
778 test('test EXT-X-ALLOW-CACHE invalid, default to YES', function() { 1071 test('test EXT-X-ALLOW-CACHE invalid, default to YES', function() {
779 var 1072 var
780 playlistTemplate = Handlebars.compile(window.playlist_allow_cache), 1073 playlistTemplate = Handlebars.compile(window.playlist_allow_cache),
781 testData = {version: 4, allowCache: 'YESTERDAYNO'}, 1074 testData = {version: 4, allowCache: 'YESTERDAYNO'},
782 playlistData = playlistTemplate(testData), 1075 playlistData = playlistTemplate(testData),
783 data = m3u8parser.parse(playlistData); 1076 data = m3u8parser.parse(playlistData);
784 1077
785 notEqual(data, null, 'data is not NULL'); 1078 notStrictEqual(data, null, 'data is not NULL');
786 // notEqual(data.invalidReasons, null, 'invalidReasons is not NULL'); 1079 // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
787 // equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons'); 1080 // strictEqual(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
788 // equal(data.invalidReasons[0], 'Invalid EXT-X-ALLOW-CACHE value: \'YESTERDAYNO\''); 1081 // strictEqual(data.invalidReasons[0], 'Invalid EXT-X-ALLOW-CACHE value: \'YESTERDAYNO\'');
789 equal(data.allowCache, 'YES', 'EXT-X-ALLOW-CACHE should default to YES.'); 1082 strictEqual(data.allowCache, 'YES', 'EXT-X-ALLOW-CACHE should default to YES.');
790 }); 1083 });
791 1084
792 // test('test EXT-X-ALLOW-CACHE empty, default to YES', function() { 1085 // test('test EXT-X-ALLOW-CACHE empty, default to YES', function() {
...@@ -796,26 +1089,26 @@ ...@@ -796,26 +1089,26 @@
796 // playlistData = playlistTemplate(testData), 1089 // playlistData = playlistTemplate(testData),
797 // data = m3u8parser.parse(playlistData); 1090 // data = m3u8parser.parse(playlistData);
798 1091
799 // notEqual(data, null, 'data is not NULL'); 1092 // notStrictEqual(data, null, 'data is not NULL');
800 // // notEqual(data.invalidReasons, null, 'invalidReasons is not NULL'); 1093 // // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
801 // // equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons'); 1094 // // strictEqual(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
802 // // equal(data.invalidReasons[0], 'Invalid EXT-X-ALLOW-CACHE value: \'\''); 1095 // // strictEqual(data.invalidReasons[0], 'Invalid EXT-X-ALLOW-CACHE value: \'\'');
803 // equal(data.allowCache, 'YES', 'EXT-X-ALLOW-CACHE should default to YES.'); 1096 // strictEqual(data.allowCache, 'YES', 'EXT-X-ALLOW-CACHE should default to YES.');
804 // }); 1097 // });
805 1098
806 // test('test EXT-X-ALLOW-CACHE missing, default to YES', function() { 1099 // test('test EXT-X-ALLOW-CACHE missing, default to YES', function() {
807 // var 1100 // var
808 // playlistTemplate = Handlebars.compile(window.playlist_allow_cache), 1101 // playlistTemplate = Handlebars.compile(window.playlist_allow_cache),
809 // testData = {version: 4}, 1102 // testData = {version: 4},
810 // playlistData = playlistTemplate(testData), 1103 // playlistData = playlistTemplate(testData),
811 // data = m3u8parser.parse(playlistData); 1104 // data = m3u8parser.parse(playlistData);
812 1105
813 // notEqual(data, null, 'data is not NULL'); 1106 // notStrictEqual(data, null, 'data is not NULL');
814 // // notEqual(data.invalidReasons, null, 'invalidReasons is not NULL'); 1107 // // notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
815 // // equal(data.invalidReasons.length, 1, 'No EXT-X-ALLOW-CACHE specified. Default: YES.'); 1108 // // strictEqual(data.invalidReasons.length, 1, 'No EXT-X-ALLOW-CACHE specified. Default: YES.');
816 // equal(data.allowCache, 'YES', 'EXT-X-ALLOW-CACHE should default to YES'); 1109 // strictEqual(data.allowCache, 'YES', 'EXT-X-ALLOW-CACHE should default to YES');
817 // }); 1110 // });
818 1111
819 // test('test EXT-X-BYTERANGE valid', function() { 1112 // test('test EXT-X-BYTERANGE valid', function() {
820 // var 1113 // var
821 // playlistTemplate = Handlebars.compile(window.playlist_byte_range), 1114 // playlistTemplate = Handlebars.compile(window.playlist_byte_range),
...@@ -823,14 +1116,14 @@ ...@@ -823,14 +1116,14 @@
823 // playlistData = playlistTemplate(testData), 1116 // playlistData = playlistTemplate(testData),
824 // data = m3u8parser.parse(playlistData); 1117 // data = m3u8parser.parse(playlistData);
825 1118
826 // notEqual(data, null, 'data is not NULL'); 1119 // notStrictEqual(data, null, 'data is not NULL');
827 // //notEqual(data.invalidReasons, null, 'invalidReasons is not NULL'); 1120 // //notStrictEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
828 // //equal(data.invalidReasons.length, 0, 'Errors object should be empty.'); 1121 // //strictEqual(data.invalidReasons.length, 0, 'Errors object should be empty.');
829 // //TODO: Validate the byteRange info 1122 // //TODO: Validate the byteRange info
830 // equal(data.segments.length, 16, '16 segments should have been parsed.'); 1123 // strictEqual(data.segments.length, 16, '16 segments should have been parsed.');
831 // equal(data.segments[0].byterange, testData.byteRange, 'byteRange incorrect.'); 1124 // strictEqual(data.segments[0].byterange, testData.byteRange, 'byteRange incorrect.');
832 // equal(data.segments[1].byterange, testData.byteRange1, 'byteRange1 incorrect.'); 1125 // strictEqual(data.segments[1].byterange, testData.byteRange1, 'byteRange1 incorrect.');
833 // equal(data.segments[15].byterange, testData.byteRange2, 'byteRange2 incorrect.'); 1126 // strictEqual(data.segments[15].byterange, testData.byteRange2, 'byteRange2 incorrect.');
834 // }); 1127 // });
835 1128
836 // test('test EXT-X-BYTERANGE used but version is < 4', function() { 1129 // test('test EXT-X-BYTERANGE used but version is < 4', function() {
...@@ -840,12 +1133,12 @@ ...@@ -840,12 +1133,12 @@
840 // playlistData = playlistTemplate(testData), 1133 // playlistData = playlistTemplate(testData),
841 // data = m3u8parser.parse(playlistData); 1134 // data = m3u8parser.parse(playlistData);
842 1135
843 // notEqual(data, null, 'data is not NULL'); 1136 // notStrictEqual(data, null, 'data is not NULL');
844 // equal(data.segments.length, 16, '16 segments should have been parsed.'); 1137 // strictEqual(data.segments.length, 16, '16 segments should have been parsed.');
845 // // notEqual(data.invalidReasons, null, 'there should be an error'); 1138 // // notStrictEqual(data.invalidReasons, null, 'there should be an error');
846 // // equal(data.invalidReasons.length, 1, 'there should be 1 error'); 1139 // // strictEqual(data.invalidReasons.length, 1, 'there should be 1 error');
847 // // //TODO: Validate the byteRange info 1140 // // //TODO: Validate the byteRange info
848 // // equal(data.invalidReasons[0], 'EXT-X-BYTERANGE used but version is < 4.');x 1141 // // strictEqual(data.invalidReasons[0], 'EXT-X-BYTERANGE used but version is < 4.');x
849 // }); 1142 // });
850 1143
851 })(window, window.console); 1144 })(window, window.console);
......