9fa0bf90 by David LaPalomento

Integrate peg-based parser into qunit tests

Add the peg parser generation step to the gruntfile. Include the generated parser in the test harness page. Update many of the m3u8 tests to work with the new parser. There are a number of tests still failing. I believe this is because parts of the grammar are not sufficiently flexible to handle some optional parameters. For instance, #EXT-X-BYTE-RANGE is being glommed incorrectly into the #EXTINF definition and that's throwing off parsing. This commit is a progress checkpoint; things are definitely not working correctly.
1 parent 3f975913
'use strict';
var peg = require('pegjs');
module.exports = function(grunt) {
// Project configuration.
......@@ -12,7 +14,7 @@ module.exports = function(grunt) {
' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */\n',
// Task configuration.
clean: {
files: ['dist']
files: ['build', 'dist']
},
concat: {
options: {
......@@ -95,8 +97,19 @@ module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('peg', 'generate the manifest parser', function() {
var parser = peg.buildParser(grunt.file.read('src/m3u8/m3u8.pegjs'));
grunt.file.write('build/m3u8-parser.js',
'window.videojs.hls.M3U8Parser = ' + parser.toSource());
});
// Default task.
grunt.registerTask('default',
['jshint', 'qunit', 'clean', 'concat', 'uglify']);
['peg',
'jshint',
'qunit',
'clean',
'concat',
'uglify']);
};
......
......@@ -15,6 +15,7 @@
"grunt-contrib-jshint": "~0.6.0",
"grunt-contrib-qunit": "~0.2.0",
"grunt-contrib-concat": "~0.3.0",
"grunt-contrib-nodeunit": "~0.1.2",
"grunt-contrib-uglify": "~0.2.0",
"grunt-contrib-watch": "~0.4.0",
"grunt-contrib-clean": "~0.4.0",
......
......@@ -269,13 +269,13 @@ number "number"
/ parts:(int) _ { return parts; }
resolution
= width:int "x" height:int { return {resolution: {width: width, height: height}}; }
= width:int "x" height:int { return {width: width, height: height}; }
int
= first:digit19 rest:digits { return parseInt(first + rest.join(''), 10); }
/ digit:digit { return parseInt(digit, 10); }
/ neg:"-" first:digit19 rest:digits { return parseInt(neg + first + rest.join(''), 10); }
/ neg:"-" digit { return parseInt(neg + digit, 10); }
/ neg:"-" digit:digit { return parseInt(neg + digit, 10); }
hexint
= "0x" hexDigits:hexDigit+ { return '0x' + hexDigits.join(''); }
......
(function (window) {
var
M3U8Parser = window.videojs.hls.M3U8Parser;
var parser = window.videojs.hls.M3U8Parser;
window.videojs.hls.ManifestController = function() {
var self = this;
......@@ -22,12 +22,8 @@
window.vjs.get(manifestUrl, self.onManifestLoadComplete, self.onManifestLoadError);
};
self.parseManifest = function(dataAsString) {
self.parser = new M3U8Parser();
self.parser.directory = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/.exec(self.url).slice(1)[1];
self.data = self.parser.parse(dataAsString);
return self.data;
self.parseManifest = function(manifest) {
return parser.parse(manifest);
};
self.onManifestLoadComplete = function(response) {
......
(function(window) {
(function(window, console) {
var
Handlebars = this.Handlebars,
manifestController = this.manifestController,
......@@ -12,7 +12,7 @@
});
/*
Manfiest controller
Manifest controller
*/
module('manifest controller', {
......@@ -36,14 +36,14 @@
var data = manifestController.parseManifest(window.brightcove_playlist_data);
ok(data);
equal(data.playlistItems.length, 4, 'Has correct rendition count');
equal(data.playlistItems[0].bandwidth, 240000, 'First rendition index bandwidth is correct');
equal(data.playlistItems[0]["program-id"], 1, 'First rendition index program-id is correct');
equal(data.playlistItems[0].resolution.width, 396, 'First rendition index resolution width is correct');
equal(data.playlistItems[0].resolution.height, 224, 'First rendition index resolution height is correct');
equal(data.playlists.length, 4, 'Has correct rendition count');
equal(data.playlists[0].attributes.bandwidth, 240000, 'First rendition index bandwidth is correct');
equal(data.playlists[0].attributes.programId, 1, 'First rendition index program-id is correct');
equal(data.playlists[0].attributes.resolution.width, 396, 'First rendition index resolution width is correct');
equal(data.playlists[0].attributes.resolution.height, 224, 'First rendition index resolution height is correct');
});
test('should get a manifest from hermes', function() {
test('should get a manifest from an external URL', function() {
manifestController.loadManifest('http://example.com/16x9-master.m3u8',
function(responseData) {
ok(responseData);
......@@ -60,7 +60,7 @@
module('m3u8 parser', {
setup: function() {
m3u8parser = new window.videojs.hls.M3U8Parser();
m3u8parser = window.videojs.hls.M3U8Parser;
}
});
......@@ -77,16 +77,14 @@
var data = m3u8parser.parse(window.playlistData);
notEqual(data, null, 'data is not NULL');
equal(data.invalidReasons.length, 0, 'Errors object should not be empty.');
equal(data.hasValidM3UTag, true, 'data has valid EXTM3U');
equal(data.openTag, true, 'data has valid EXTM3U');
equal(data.targetDuration, 10, 'data has correct TARGET DURATION');
equal(data.allowCache, "NO", 'acceptable ALLOW CACHE');
equal(data.isPlaylist, false, 'data is parsed as a PLAYLIST as expected');
equal(data.allowCache, undefined, 'ALLOW-CACHE is not present in the manifest');
equal(data.playlistType, "VOD", 'acceptable PLAYLIST TYPE');
equal(data.mediaItems.length, 16, 'acceptable mediaItem count');
equal(data.segments.length, 17, 'there are 17 segments in the manifest');
equal(data.mediaSequence, 0, 'MEDIA SEQUENCE is correct');
equal(data.totalDuration, -1, "ZEN TOTAL DURATION is unknown as expected");
equal(data.hasEndTag, true, 'should have ENDLIST tag');
equal(data.totalDuration, undefined, "no total duration is specified");
equal(data.closeTag, true, 'should have ENDLIST tag');
});
/*3.4.7. EXT-X-PLAYLIST-TYPE
......@@ -111,7 +109,7 @@
data = m3u8parser.parse(playlistData);
notEqual(data, null, 'data is not NULL');
equal(data.invalidReasons.length, 0, 'Errors object should not be empty.');
//equal(data.invalidReasons.length, 0, 'Errors object should not be empty.');
equal(data.playlistType, "VOD", 'acceptable PLAYLIST TYPE');
});
......@@ -122,11 +120,11 @@
playlistData = playlistTemplate(testData),
data = m3u8parser.parse(playlistData);
notEqual(data, null, 'data is not NULL');
equal(data.invalidReasons.length, 0, 'Errors object should not be empty.');
//equal(data.invalidReasons.length, 0, 'Errors object should not be empty.');
equal(data.playlistType, "EVENT", 'acceptable PLAYLIST TYPE');
});
test('should have assumed VOD playlist type if not defined', function() {
test('handles a missing playlist type', function() {
var
playlistTemplate = Handlebars.compile(window.playlist_type_template),
testData = {},
......@@ -134,9 +132,9 @@
data = m3u8parser.parse(playlistData);
notEqual(data, null, 'data is not NULL');
equal(data.invalidReasons.length, 0, 'Errors object should not be empty.');
equal(data.warnings, 'EXT-X-PLAYLIST-TYPE was empty or missing. Assuming VOD');
equal(data.playlistType, "VOD", 'acceptable PLAYLIST TYPE');
//equal(data.invalidReasons.length, 0, 'Errors object should not be empty.');
//equal(data.warnings, 'EXT-X-PLAYLIST-TYPE was empty or missing. Assuming VOD');
equal(data.playlistType, undefined, 'no PLAYLIST TYPE present');
});
test('should have an invalid reason due to invalid playlist type', function() {
......@@ -146,20 +144,20 @@
playlistData = playlistTemplate(testData),
data = m3u8parser.parse(playlistData);
notEqual(data, null, 'data is not NULL');
equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
equal(data.invalidReasons[0], 'Invalid Playlist Type Value: \'baklsdhfajsdf\'');
//equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
//equal(data.invalidReasons[0], 'Invalid Playlist Type Value: \'baklsdhfajsdf\'');
});
test('should have assumed VOD playlist type is empty', function() {
test('handles an empty playlist type', function() {
var
playlistTemplate = Handlebars.compile(window.playlist_type_template),
testData = {playlistType: ''},
playlistData = playlistTemplate(testData),
data = m3u8parser.parse(playlistData);
notEqual(data, null, 'data is not NULL');
equal(data.invalidReasons.length, 0, 'Errors object should not be empty.');
equal(data.warnings, 'EXT-X-PLAYLIST-TYPE was empty or missing. Assuming VOD');
equal(data.playlistType, "VOD", 'acceptable PLAYLIST TYPE');
//equal(data.invalidReasons.length, 0, 'Errors object should not be empty.');
//equal(data.warnings, 'EXT-X-PLAYLIST-TYPE was empty or missing. Assuming VOD');
equal(data.playlistType, '', 'PLAYLIST TYPE is the empty string');
});
/*3.4.2. EXT-X-TARGETDURATION
......@@ -187,7 +185,7 @@
data = m3u8parser.parse(playlistData);
notEqual(data, null, 'data is not NULL');
equal(data.targetDuration, 10, 'data has correct TARGET DURATION');
equal(data.invalidReasons.length, 0, 'data has 1 invalid reasons');
//equal(data.invalidReasons.length, 0, 'data has 1 invalid reasons');
});
test('NaN target duration', function() {
......@@ -199,9 +197,9 @@
console.log(playlistData);
console.log(data.targetDuration);
notEqual(data, null, 'data is not NULL');
notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
equal(data.invalidReasons.length, 1, 'data has 0 invalid reasons');
equal(data.invalidReasons[0], 'Invalid Target Duration Value: \'NaN\'');
// notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
// equal(data.invalidReasons.length, 1, 'data has 0 invalid reasons');
// equal(data.invalidReasons[0], 'Invalid Target Duration Value: \'NaN\'');
});
test('empty target duration', function() {
......@@ -213,9 +211,9 @@
console.log(playlistData);
console.log(data.targetDuration);
notEqual(data, null, 'data is not NULL');
notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
equal(data.invalidReasons[0], 'Invalid Target Duration Value: \'NaN\'');
// notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
// equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
// equal(data.invalidReasons[0], 'Invalid Target Duration Value: \'NaN\'');
});
test('undefined target duration', function() {
......@@ -227,9 +225,9 @@
console.log(playlistData);
console.log(data.targetDuration);
notEqual(data, null, 'data is not NULL');
notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
equal(data.invalidReasons[0], 'Invalid Target Duration Value: \'undefined\'');
// notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
// equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
// equal(data.invalidReasons[0], 'Invalid Target Duration Value: \'undefined\'');
});
......@@ -241,9 +239,9 @@
data = m3u8parser.parse(playlistData);
notEqual(data, null, 'data is not NULL');
notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
equal(data.invalidReasons[0], 'Invalid Target Duration Value: 4 is lower than segments');
// notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
// equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
// equal(data.invalidReasons[0], 'Invalid Target Duration Value: 4 is lower than segments');
});
/*3.4.3. EXT-X-MEDIA-SEQUENCE
......@@ -277,8 +275,8 @@
data = m3u8parser.parse(playlistData);
notEqual(data, null, 'data is not NULL');
notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
equal(data.invalidReasons.length, 0, 'Errors object should not be empty.');
// notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
// equal(data.invalidReasons.length, 0, 'Errors object should not be empty.');
equal(data.mediaSequence, 0, 'MEDIA SEQUENCE is correct');
});
......@@ -290,8 +288,8 @@
data = m3u8parser.parse(playlistData);
notEqual(data, null, 'data is not NULL');
notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
equal(data.invalidReasons.length, 0, 'Errors object should not be empty.');
// notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
// equal(data.invalidReasons.length, 0, 'Errors object should not be empty.');
equal(data.mediaSequence, 0, 'MEDIA SEQUENCE tags after the first should be ignored');
});
......@@ -303,9 +301,9 @@
data = m3u8parser.parse(playlistData);
notEqual(data, null, 'data is not NULL');
notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
equal(data.invalidReasons.length, 0, 'Errors object should not be empty.');
equal(data.mediaSequence, 0, 'MEDIA SEQUENCE should default to 0 when not present.');
// notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
// equal(data.invalidReasons.length, 0, 'Errors object should not be empty.');
equal(data.mediaSequence, undefined, 'MEDIA SEQUENCE is undefined');
});
test('media sequence is empty in the playlist', function() {
......@@ -316,9 +314,9 @@
data = m3u8parser.parse(playlistData);
notEqual(data, null, 'data is not NULL');
notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
equal(data.mediaSequence, 0, 'Invalid Media Sequence Value: \'\'');
// notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
// equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
equal(data.mediaSequence, '', 'media sequence is the empty string');
});
test('media sequence is high (non-zero in first file) in the playlist', function() {
......@@ -329,12 +327,12 @@
data = m3u8parser.parse(playlistData);
notEqual(data, null, 'data is not NULL');
notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
equal(data.invalidReasons[0], 'Invalid Media Sequence Value: \'1\'');
// notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
// equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
// equal(data.invalidReasons[0], 'Invalid Media Sequence Value: \'1\'');
});
test('media sequence (-1) in the playlist', function() {
test('handles invalid media sequence numbers in the playlist', function() {
var
playlistTemplate = Handlebars.compile(window.playlist_media_sequence_template),
testData = {mediaSequence: '-1'},
......@@ -342,9 +340,10 @@
data = m3u8parser.parse(playlistData);
notEqual(data, null, 'data is not NULL');
notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
equal(data.invalidReasons[0], 'Invalid Media Sequence Value: \'-1\'');
// notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
// equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
// equal(data.invalidReasons[0], 'Invalid Media Sequence Value: \'-1\'');
equal(data.mediaSequence, -1, 'negative media sequence numbers don\'t break parsing');
});
test('media sequence invalid (string) in the playlist', function() {
......@@ -355,27 +354,30 @@
data = m3u8parser.parse(playlistData);
notEqual(data, null, 'data is not NULL');
notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
equal(data.invalidReasons[0], 'Invalid Media Sequence Value: \'asdfkasdkfl\'');
// notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
// equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
// equal(data.invalidReasons[0], 'Invalid Media Sequence Value: \'asdfkasdkfl\'');
});
module('brightcove playlist', {
module('Representative Playlist', {
setup: function() {
m3u8parser = new window.videojs.hls.M3U8Parser();
m3u8parser = window.videojs.hls.M3U8Parser;
}
});
test('should parse a brightcove manifest data', function() {
test('should parse real manifest data', function() {
var data = m3u8parser.parse(window.brightcove_playlist_data);
ok(data);
equal(data.playlistItems.length, 4, 'Has correct rendition count');
equal(data.isPlaylist, true, 'data is parsed as a PLAYLIST as expected');
equal(data.playlistItems[0].bandwidth, 240000, 'First rendition index bandwidth is correct');
equal(data.playlistItems[0]["program-id"], 1, 'First rendition index program-id is correct');
equal(data.playlistItems[0].resolution.width, 396, 'First rendition index resolution width is correct');
equal(data.playlistItems[0].resolution.height, 224, 'First rendition index resolution height is correct');
equal(data.playlists.length, 4, 'has correct playlist count');
equal(data.playlists[0].attributes.bandwidth, 240000, 'first rendition index bandwidth is correct');
equal(data.playlists[0].attributes.programId, 1, 'first rendition index program-id is correct');
equal(data.playlists[0].attributes.resolution.width,
396,
'first rendition index resolution width is correct');
equal(data.playlists[0].attributes.resolution.height,
224,
'first rendition index resolution height is correct');
});
......@@ -410,8 +412,8 @@
data = m3u8parser.parse(playlistData);
notEqual(data, null, 'data is not NULL');
notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
equal(data.invalidReasons.length, 0, 'Errors object should not be empty.');
// notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
// equal(data.invalidReasons.length, 0, 'Errors object should not be empty.');
});
test('test valid extinf without associated segment in playlist', function() {
......@@ -422,8 +424,8 @@
data = m3u8parser.parse(playlistData);
notEqual(data, null, 'data is not NULL');
notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
// notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
// equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
//equal(data.invalidReasons[0], 'Invalid Segment Data: \'#EXTINF missing segment\'');
});
......@@ -436,8 +438,8 @@
data = m3u8parser.parse(playlistData);
notEqual(data, null, 'data is not NULL');
notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
// notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
// equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
});
//its best practice that every extinf have the same value, but its not required
......@@ -449,8 +451,8 @@
data = m3u8parser.parse(playlistData);
notEqual(data, null, 'data is not NULL');
notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
equal(data.invalidReasons.length, 0, 'Errors object should not be empty.');
// notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
// equal(data.invalidReasons.length, 0, 'Errors object should not be empty.');
});
//extinf values must be below the target duration
......@@ -462,9 +464,9 @@
data = m3u8parser.parse(playlistData);
notEqual(data, null, 'data is not NULL');
notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
equal(data.invalidReasons[0], 'Invalid Segment Data: \'#EXTINF value higher than #TARGETDURATION\'');
// notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
// equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
// equal(data.invalidReasons[0], 'Invalid Segment Data: \'#EXTINF value higher than #TARGETDURATION\'');
});
//extinf values must be below the target duration
......@@ -476,9 +478,9 @@
data = m3u8parser.parse(playlistData);
notEqual(data, null, 'data is not NULL');
notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
equal(data.invalidReasons[0], 'Invalid Segment Data: \'#EXTINF value not an integer\'');
// notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
// equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
// equal(data.invalidReasons[0], 'Invalid Segment Data: \'#EXTINF value not an integer\'');
});
//extinf values must be below the target duration
......@@ -490,8 +492,8 @@
data = m3u8parser.parse(playlistData);
notEqual(data, null, 'data is not NULL');
notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
equal(data.invalidReasons.length, 0, 'Errors object should not be empty.');
// notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
// equal(data.invalidReasons.length, 0, 'Errors object should not be empty.');
});
//extinf values must be below the target duration
......@@ -503,9 +505,9 @@
data = m3u8parser.parse(playlistData);
notEqual(data, null, 'data is not NULL');
notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
equal(data.invalidReasons[0], 'Invalid Segment Data: \'#EXTINF value empty\'');
// notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
// equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
// equal(data.invalidReasons[0], 'Invalid Segment Data: \'#EXTINF value empty\'');
});
/*
......@@ -528,8 +530,8 @@
data = m3u8parser.parse(playlistData);
notEqual(data, null, 'data is not NULL');
notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
equal(data.invalidReasons.length, 0, 'Errors object should not be empty.');
// notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
// equal(data.invalidReasons.length, 0, 'Errors object should not be empty.');
equal(data.allowCache, 'YES', 'EXT-X-ALLOW-CACHE should be YES');
});
......@@ -541,8 +543,8 @@
data = m3u8parser.parse(playlistData);
notEqual(data, null, 'data is not NULL');
notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
equal(data.invalidReasons.length, 0, 'Errors object should not be empty.');
// notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
// equal(data.invalidReasons.length, 0, 'Errors object should not be empty.');
equal(data.allowCache, 'NO', 'EXT-X-ALLOW-CACHE should be NO');
});
......@@ -554,9 +556,9 @@
data = m3u8parser.parse(playlistData);
notEqual(data, null, 'data is not NULL');
notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
equal(data.invalidReasons[0], 'Invalid EXT-X-ALLOW-CACHE value: \'YESTERDAYNO\'');
// notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
// equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
// equal(data.invalidReasons[0], 'Invalid EXT-X-ALLOW-CACHE value: \'YESTERDAYNO\'');
equal(data.allowCache, 'YES', 'EXT-X-ALLOW-CACHE should default to YES.');
});
......@@ -568,9 +570,9 @@
data = m3u8parser.parse(playlistData);
notEqual(data, null, 'data is not NULL');
notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
equal(data.invalidReasons[0], 'Invalid EXT-X-ALLOW-CACHE value: \'\'');
// notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
// equal(data.invalidReasons.length, 1, 'data has 1 invalid reasons');
// equal(data.invalidReasons[0], 'Invalid EXT-X-ALLOW-CACHE value: \'\'');
equal(data.allowCache, 'YES', 'EXT-X-ALLOW-CACHE should default to YES.');
});
......@@ -582,8 +584,8 @@
data = m3u8parser.parse(playlistData);
notEqual(data, null, 'data is not NULL');
notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
equal(data.invalidReasons.length, 1, 'No EXT-X-ALLOW-CACHE specified. Default: YES.');
// notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
// equal(data.invalidReasons.length, 1, 'No EXT-X-ALLOW-CACHE specified. Default: YES.');
equal(data.allowCache, 'YES', 'EXT-X-ALLOW-CACHE should default to YES');
});
......@@ -595,13 +597,13 @@
data = m3u8parser.parse(playlistData);
notEqual(data, null, 'data is not NULL');
notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
equal(data.invalidReasons.length, 0, 'Errors object should be empty.');
//notEqual(data.invalidReasons, null, 'invalidReasons is not NULL');
//equal(data.invalidReasons.length, 0, 'Errors object should be empty.');
//TODO: Validate the byteRange info
equal(data.mediaItems.length, 16, '16 segments should have been parsed.');
equal(data.mediaItems[0].byterange, testData.byteRange, 'byteRange incorrect.');
equal(data.mediaItems[1].byterange, testData.byteRange1, 'byteRange1 incorrect.');
equal(data.mediaItems[15].byterange, testData.byteRange2, 'byteRange2 incorrect.');
equal(data.segments.length, 16, '16 segments should have been parsed.');
equal(data.segments[0].byterange, testData.byteRange, 'byteRange incorrect.');
equal(data.segments[1].byterange, testData.byteRange1, 'byteRange1 incorrect.');
equal(data.segments[15].byterange, testData.byteRange2, 'byteRange2 incorrect.');
});
test('test EXT-X-BYTERANGE used but version is < 4', function() {
......@@ -612,11 +614,11 @@
data = m3u8parser.parse(playlistData);
notEqual(data, null, 'data is not NULL');
equal(data.mediaItems.length, 16, '16 segments should have been parsed.');
notEqual(data.invalidReasons, null, 'there should be an error');
equal(data.invalidReasons.length, 1, 'there should be 1 error');
//TODO: Validate the byteRange info
equal(data.invalidReasons[0], 'EXT-X-BYTERANGE used but version is < 4.')
equal(data.segments.length, 16, '16 segments should have been parsed.');
// notEqual(data.invalidReasons, null, 'there should be an error');
// equal(data.invalidReasons.length, 1, 'there should be 1 error');
// //TODO: Validate the byteRange info
// equal(data.invalidReasons[0], 'EXT-X-BYTERANGE used but version is < 4.');x
});
})(this);
\ No newline at end of file
})(window, window.console);
......
......@@ -44,7 +44,7 @@ window.playlistData = '#EXTM3U\n'+
'hls_450k_video.ts\n' +
'#EXTINF:10,\n' +
'#EXT-X-BYTERANGE:468684@7108092\n' +
'hls_450k_video.ts' +
'hls_450k_video.ts\n' +
'#EXTINF:10,\n' +
'#EXT-X-BYTERANGE:444996@7576776\n' +
'hls_450k_video.ts\n' +
......
......@@ -46,7 +46,7 @@ window.playlist_byte_range = '#EXTM3U\n'+
'hls_450k_video.ts\n' +
'#EXTINF:10,\n' +
'#EXT-X-BYTERANGE:468684@7108092\n' +
'hls_450k_video.ts' +
'hls_450k_video.ts\n' +
'#EXTINF:10,\n' +
'#EXT-X-BYTERANGE:444996@7576776\n' +
'hls_450k_video.ts\n' +
......
var fs = require('fs');
var path = require('path');
var manifest = fs.readFileSync(__dirname + '/fixtures/prog_index.m3u8').toString();
var parser = require('../src/m3u8/m3u8-generated.js');
var parsed = parser.parse(manifest);
console.log(parsed);
......@@ -24,7 +24,7 @@
<!-- M3U8 -->
<script src="../src/m3u8/m3u8.js"></script>
<script src="../src/m3u8/m3u8-tag-types.js"></script>
<script src="../src/m3u8/m3u8-parser.js"></script>
<script src="../build/m3u8-parser.js"></script>
<script src="../src/manifest-controller.js"></script>
<!-- M3U8 TEST DATA -->
<script src="manifest/playlistM3U8data.js"></script>
......@@ -43,6 +43,7 @@
<script src="../src/bin-utils.js"></script>
<!-- Test cases -->
<script src="video-js-hls_test.js"></script>
<script src="exp-golomb_test.js"></script>
<script src="flv-tag_test.js"></script>
......