From 78dea30b3348aca420bbabf0c93bf1fb734224b8 Mon Sep 17 00:00:00 2001 From: Borewit Date: Sun, 13 Aug 2017 21:31:06 +0200 Subject: [PATCH] Improve unit tests --- src/mp4/MP4Parser.ts | 4 -- test/test-asf.ts | 32 +++++++++--- test/test-flac.ts | 101 ++++++++++++++++++------------------ test/test-m4a.ts | 118 +++++++++++++++++++++++++++---------------- test/test-ogg.ts | 33 ++++++++++-- 5 files changed, 179 insertions(+), 109 deletions(-) diff --git a/src/mp4/MP4Parser.ts b/src/mp4/MP4Parser.ts index 348d7aceb..99f353e58 100644 --- a/src/mp4/MP4Parser.ts +++ b/src/mp4/MP4Parser.ts @@ -338,10 +338,6 @@ class NameAtom implements Token.IGetToken { */ export class MP4Parser implements ITokenParser { - public static getInstance(): MP4Parser { - return new MP4Parser(); - } - private static Types: { [index: number]: string } = { 0: 'uint8', 1: 'text', diff --git a/test/test-asf.ts b/test/test-asf.ts index 379a78938..0f31d01da 100644 --- a/test/test-asf.ts +++ b/test/test-asf.ts @@ -4,7 +4,7 @@ import * as mm from '../src'; import {INativeTagDict} from "../lib/index"; import * as path from 'path'; import GUID from "../lib/asf/GUID"; -import {AsfTagMap} from "../lib/asf/AsfTagMap"; +import * as fs from 'fs-extra'; const t = assert; @@ -22,7 +22,7 @@ describe("ASF", () => { }); }); - it("should parse ASF", () => { + describe("parse", () => { const filePath = path.join(__dirname, 'samples', 'asf.wma'); @@ -49,14 +49,32 @@ describe("ASF", () => { t.deepEqual(native.REPLAYGAIN_TRACK_GAIN, ['-4.7 dB'], 'native: REPLAYGAIN_TRACK_GAIN'); } - return mm.parseFile(filePath, {native: true}).then((result) => { + it("should decode an ASF audio file (.wma)", () => { - checkFormat(result.format); + return mm.parseFile(filePath, {native: true}).then((result) => { - checkCommon(result.common); + checkFormat(result.format); + + checkCommon(result.common); + + t.ok(result.native && result.native.asf, 'should include native ASF tags'); + checkNative(mm.orderTags(result.native.asf)); + }); + + }); + + it("should decode from ASF from a stream (audio/x-ms-wma)", () => { + + const stream = fs.createReadStream(filePath); + + return mm.parseStream(stream, 'audio/x-ms-wma', {native: true}).then((metadata) => { + checkFormat(metadata.format); + checkCommon(metadata.common); + checkNative(mm.orderTags(metadata.native.asf)); + }).then(() => { + stream.close(); + }); - t.ok(result.native && result.native.asf, 'should include native ASF tags'); - checkNative(mm.orderTags(result.native.asf)); }); }); diff --git a/test/test-flac.ts b/test/test-flac.ts index 5cf51f070..ff94afd34 100644 --- a/test/test-flac.ts +++ b/test/test-flac.ts @@ -11,67 +11,70 @@ describe("FLAC decoding", () => { const filename = 'flac.flac'; const filePath = path.join(__dirname, 'samples', filename); - it("should decode", () => { + function checkFormat(format) { + t.strictEqual(format.dataformat, 'flac', 'format.tag_type'); + t.strictEqual(format.headerType, 'vorbis', 'format.tag_type'); + t.strictEqual(format.duration, 271.7733333333333, 'format.duration'); + t.strictEqual(format.sampleRate, 44100, 'format.sampleRate = 44.1 kHz'); + t.strictEqual(format.bitsPerSample, 16, 'format.bitsPerSample = 16 bit'); + t.strictEqual(format.numberOfChannels, 2, 'format.numberOfChannels 2 (stereo)'); + } - function checkFormat(format) { - t.strictEqual(format.dataformat, 'flac', 'format.tag_type'); - t.strictEqual(format.headerType, 'vorbis', 'format.tag_type'); - t.strictEqual(format.duration, 271.7733333333333, 'format.duration'); - t.strictEqual(format.sampleRate, 44100, 'format.sampleRate = 44.1 kHz'); - t.strictEqual(format.bitsPerSample, 16, 'format.bitsPerSample = 16 bit'); - t.strictEqual(format.numberOfChannels, 2, 'format.numberOfChannels 2 (stereo)'); - } + function checkCommon(common) { + t.strictEqual(common.title, 'Brian Eno', 'common.title'); + t.deepEqual(common.artists, ['MGMT'], 'common.artist'); + t.strictEqual(common.albumartist, undefined, 'common.albumartist'); + t.strictEqual(common.album, 'Congratulations', 'common.album'); + t.strictEqual(common.year, 2010, 'common.year'); + t.deepEqual(common.track, {no: 7, of: null}, 'common.track'); + t.deepEqual(common.disk, {no: null, of: null}, 'common.disk'); + t.deepEqual(common.genre, ['Alt. Rock'], 'genre'); + t.strictEqual(common.picture[0].format, 'jpg', 'common.picture format'); + t.strictEqual(common.picture[0].data.length, 175668, 'common.picture length'); + } - function checkCommon(common) { - t.strictEqual(common.title, 'Brian Eno', 'common.title'); - t.deepEqual(common.artists, ['MGMT'], 'common.artist'); - t.strictEqual(common.albumartist, undefined, 'common.albumartist'); - t.strictEqual(common.album, 'Congratulations', 'common.album'); - t.strictEqual(common.year, 2010, 'common.year'); - t.deepEqual(common.track, {no: 7, of: null}, 'common.track'); - t.deepEqual(common.disk, {no: null, of: null}, 'common.disk'); - t.deepEqual(common.genre, ['Alt. Rock'], 'genre'); - t.strictEqual(common.picture[0].format, 'jpg', 'common.picture format'); - t.strictEqual(common.picture[0].data.length, 175668, 'common.picture length'); - } + function checkNative(vorbis) { + // Compare expectedCommonTags with result.common + t.deepEqual(vorbis.TITLE, ['Brian Eno'], 'vorbis.TITLE'); + t.deepEqual(vorbis.ARTIST, ['MGMT'], 'vorbis.ARTIST'); + t.deepEqual(vorbis.DATE, ['2010'], 'vorbis.DATE'); + t.deepEqual(vorbis.TRACKNUMBER, ['07'], 'vorbis.TRACKNUMBER'); + t.deepEqual(vorbis.GENRE, ['Alt. Rock'], 'vorbis.GENRE'); + t.deepEqual(vorbis.COMMENT, ['EAC-Secure Mode'], 'vorbis.COMMENT'); + const pic = vorbis.METADATA_BLOCK_PICTURE[0]; - function checkNative(vorbis) { - // Compare expectedCommonTags with result.common - t.deepEqual(vorbis.TITLE, ['Brian Eno'], 'vorbis.TITLE'); - t.deepEqual(vorbis.ARTIST, ['MGMT'], 'vorbis.ARTIST'); - t.deepEqual(vorbis.DATE, ['2010'], 'vorbis.DATE'); - t.deepEqual(vorbis.TRACKNUMBER, ['07'], 'vorbis.TRACKNUMBER'); - t.deepEqual(vorbis.GENRE, ['Alt. Rock'], 'vorbis.GENRE'); - t.deepEqual(vorbis.COMMENT, ['EAC-Secure Mode'], 'vorbis.COMMENT'); - const pic = vorbis.METADATA_BLOCK_PICTURE[0]; + t.strictEqual(pic.type, 'Cover (front)', 'raw METADATA_BLOCK_PICTUREtype'); + t.strictEqual(pic.format, 'image/jpeg', 'raw METADATA_BLOCK_PICTURE format'); + t.strictEqual(pic.description, '', 'raw METADATA_BLOCK_PICTURE description'); + t.strictEqual(pic.width, 450, 'raw METADATA_BLOCK_PICTURE width'); + t.strictEqual(pic.height, 450, 'raw METADATA_BLOCK_PICTURE height'); + t.strictEqual(pic.colour_depth, 24, 'raw METADATA_BLOCK_PICTURE colour depth'); + t.strictEqual(pic.indexed_color, 0, 'raw METADATA_BLOCK_PICTURE indexed_color'); + t.strictEqual(pic.data.length, 175668, 'raw METADATA_BLOCK_PICTURE length'); + } - t.strictEqual(pic.type, 'Cover (front)', 'raw METADATA_BLOCK_PICTUREtype'); - t.strictEqual(pic.format, 'image/jpeg', 'raw METADATA_BLOCK_PICTURE format'); - t.strictEqual(pic.description, '', 'raw METADATA_BLOCK_PICTURE description'); - t.strictEqual(pic.width, 450, 'raw METADATA_BLOCK_PICTURE width'); - t.strictEqual(pic.height, 450, 'raw METADATA_BLOCK_PICTURE height'); - t.strictEqual(pic.colour_depth, 24, 'raw METADATA_BLOCK_PICTURE colour depth'); - t.strictEqual(pic.indexed_color, 0, 'raw METADATA_BLOCK_PICTURE indexed_color'); - t.strictEqual(pic.data.length, 175668, 'raw METADATA_BLOCK_PICTURE length'); - } + it("should decode a FLAC audio file (.flac)", () => { return mm.parseFile(filePath, {native: true}).then((metadata) => { checkFormat(metadata.format); checkCommon(metadata.common); checkNative(mm.orderTags(metadata.native.vorbis)); - }).then(() => { - // Parse stream - const stream = fs.createReadStream(filePath); + }); + + }); + + it("should decode from a FLAC audio stream (audio/flac)", () => { - return mm.parseStream(stream, 'audio/flac', {native: true}).then((metadata) => { - checkFormat(metadata.format); - checkCommon(metadata.common); - checkNative(mm.orderTags(metadata.native.vorbis)); - }).then(() => { - stream.close(); - }); + const stream = fs.createReadStream(filePath); + return mm.parseStream(stream, 'audio/flac', {native: true}).then((metadata) => { + checkFormat(metadata.format); + checkCommon(metadata.common); + checkNative(mm.orderTags(metadata.native.vorbis)); + }).then(() => { + stream.close(); }); }); + }); diff --git a/test/test-m4a.ts b/test/test-m4a.ts index 82eca039a..edbb8f57f 100644 --- a/test/test-m4a.ts +++ b/test/test-m4a.ts @@ -2,58 +2,88 @@ import {} from "mocha"; import {assert} from 'chai'; import * as mm from '../src'; import * as path from 'path'; +import * as fs from 'fs-extra'; const t = assert; -it("should decode iTunes-style M4A tags", () => { +describe("Read MPEG-4 audio files with iTunes metadata", () => { const filename = 'id4.m4a'; const filePath = path.join(__dirname, 'samples', filename); - return mm.parseFile(filePath, {duration: true, native: true}).then((result) => { - - t.strictEqual(result.format.duration, 2.2058956916099772, 'format.duration'); - - t.strictEqual(result.common.title, 'Voodoo People (Pendulum Remix)', 'title'); - t.strictEqual(result.common.artist, 'The Prodigy', 'artist'); - t.strictEqual(result.common.albumartist, 'Pendulum', 'albumartist'); - t.strictEqual(result.common.album, 'Voodoo People', 'album'); - t.strictEqual(result.common.year, 2005, 'year'); - t.strictEqual(result.common.track.no, 1, 'track no'); - t.strictEqual(result.common.track.of, 12, 'track of'); - t.strictEqual(result.common.disk.no, 1, 'disk no'); - t.strictEqual(result.common.disk.of, 1, 'disk of'); - t.strictEqual(result.common.genre[0], 'Electronic', 'genre'); - t.strictEqual(result.common.picture[0].format, 'jpg', 'picture 0 format'); - t.strictEqual(result.common.picture[0].data.length, 196450, 'picture 0 length'); - t.strictEqual(result.common.picture[1].format, 'jpg', 'picture 1 format'); - t.strictEqual(result.common.picture[1].data.length, 196450, 'picture 1 length'); - - const native = result.native['iTunes MP4']; + function checkFormat(format) { + assert.strictEqual(format.headerType, 'iTunes MP4', 'format.headerType'); + t.strictEqual(format.duration, 2.2058956916099772, 'format.duration'); + assert.strictEqual(format.sampleRate, 44100, 'format.sampleRate = 44.1 kHz'); + } + + function checkCommon(common) { + t.strictEqual(common.title, 'Voodoo People (Pendulum Remix)', 'title'); + t.strictEqual(common.artist, 'The Prodigy', 'artist'); + t.strictEqual(common.albumartist, 'Pendulum', 'albumartist'); + t.strictEqual(common.album, 'Voodoo People', 'album'); + t.strictEqual(common.year, 2005, 'year'); + t.strictEqual(common.track.no, 1, 'track no'); + t.strictEqual(common.track.of, 12, 'track of'); + t.strictEqual(common.disk.no, 1, 'disk no'); + t.strictEqual(common.disk.of, 1, 'disk of'); + t.strictEqual(common.genre[0], 'Electronic', 'genre'); + t.strictEqual(common.picture[0].format, 'jpg', 'picture 0 format'); + t.strictEqual(common.picture[0].data.length, 196450, 'picture 0 length'); + t.strictEqual(common.picture[1].format, 'jpg', 'picture 1 format'); + t.strictEqual(common.picture[1].data.length, 196450, 'picture 1 length'); + } + + function checkNativeTags(native) { + t.ok(native, 'Native m4a tags should be present'); - let i = 0; - t.deepEqual(native[i++], {id: 'trkn', value: '1/12'}, 'm4a.trkn'); - t.deepEqual(native[i++], {id: 'disk', value: '1/1'}, 'm4a.disk'); - t.deepEqual(native[i++], {id: 'tmpo', value: 0}, 'm4a.tmpo'); - t.deepEqual(native[i++], {id: 'gnre', value: 'Electronic'}, 'm4a.gnre'); - t.deepEqual(native[i++], {id: 'stik', value: 1}, 'm4a.stik'); - t.deepEqual(native[i++], {id: '©alb', value: 'Voodoo People'}, 'm4a.©alb'); - t.deepEqual(native[i++], {id: 'aART', value: 'Pendulum'}, 'm4a.aART'); - t.deepEqual(native[i++], {id: '©ART', value: 'The Prodigy'}, 'm4a.©ART'); - t.deepEqual(native[i++], {id: '©cmt', value: '(Pendulum Remix)'}, 'm4a.©cmt'); - t.deepEqual(native[i++], {id: '©wrt', value: 'Liam Howlett'}, 'm4a.©wrt'); - t.deepEqual(native[i++], { - id: '----:com.apple.iTunes:iTunNORM', - value: ' 0000120A 00001299 00007365 0000712F 0002D88B 0002D88B 00007F2B 00007F2C 0003C770 0001F5C7' - }, 'm4a.----:com.apple.iTunes:iTunNORM'); - t.deepEqual(native[i++], {id: '©nam', value: 'Voodoo People (Pendulum Remix)'}, 'm4a.©nam'); - t.deepEqual(native[i++], {id: '©too', value: 'Lavf52.36.0'}, 'm4a.©too'); - t.deepEqual(native[i++], {id: '©day', value: '2005'}, 'm4a.@day'); - - const covr = native[i]; - t.strictEqual(covr.id, 'covr', 'm4a.covr'); - t.strictEqual(covr.value.format, 'image/jpeg', 'm4a.covr.format'); - t.strictEqual(covr.value.data.length, 196450, 'm4a.covr.data.length'); + t.deepEqual(native.trkn, ['1/12'], 'm4a.trkn'); + t.deepEqual(native.disk, ['1/1'], 'm4a.disk'); + t.deepEqual(native.tmpo, [0], 'm4a.tmpo'); + t.deepEqual(native.gnre, ['Electronic'], 'm4a.gnre'); + t.deepEqual(native.stik, [1], 'm4a.stik'); + t.deepEqual(native['©alb'], ['Voodoo People'], 'm4a.©alb'); + t.deepEqual(native.aART, ['Pendulum'], 'm4a.aART'); + t.deepEqual(native['©ART'], ['The Prodigy'], 'm4a.©ART'); + t.deepEqual(native['©cmt'], ['(Pendulum Remix)'], 'm4a.©cmt'); + t.deepEqual(native['©wrt'], ['Liam Howlett'], 'm4a.©wrt'); + t.deepEqual(native['----:com.apple.iTunes:iTunNORM'], [' 0000120A 00001299 00007365 0000712F 0002D88B 0002D88B 00007F2B 00007F2C 0003C770 0001F5C7'], 'm4a.----:com.apple.iTunes:iTunNORM'); + t.deepEqual(native['©nam'], ['Voodoo People (Pendulum Remix)'], 'm4a.©nam'); + t.deepEqual(native['©too'], ['Lavf52.36.0'], 'm4a.©too'); + t.deepEqual(native['©day'], ['2005'], 'm4a.@day'); + + // Check album art + t.isDefined(native.covr); + t.strictEqual(native.covr[0].format, 'image/jpeg', 'm4a.covr.format'); + t.strictEqual(native.covr[0].data.length, 196450, 'm4a.covr.data.length'); + } + + it("should decode a MPEG-4 audio file with iTunes metadata (.m4a)", () => { + + return mm.parseFile(filePath, {native: true}).then((metadata) => { + + const native = metadata.native['iTunes MP4']; + t.ok(native, 'Native m4a tags should be present'); + + checkFormat(metadata.format); + checkCommon(metadata.common); + checkNativeTags(mm.orderTags(native)); + }); + + }); + + it("should decode from a MPEG-4 audio stream with iTunes metadata (audio/mp4)", () => { + + const stream = fs.createReadStream(filePath); + + return mm.parseStream(stream, 'audio/mp4', {native: true}).then((metadata) => { + checkFormat(metadata.format); + checkCommon(metadata.common); + checkNativeTags(mm.orderTags(metadata.native['iTunes MP4'])); + }).then(() => { + stream.close(); + }); + }); }); diff --git a/test/test-ogg.ts b/test/test-ogg.ts index 6e3ff5326..1e0fa4c72 100644 --- a/test/test-ogg.ts +++ b/test/test-ogg.ts @@ -2,8 +2,11 @@ import {} from "mocha"; import {assert} from 'chai'; import * as mm from '../src'; import * as path from 'path'; +import * as fs from 'fs-extra'; -it("should decode ogg audio-file", () => { +describe("Parsing Ogg Vorbis", function() { + + this.timeout(15000); // It takes a log time to parse, due to sync errors and assumption it is VBR (which is caused by the funny 224 kbps frame) const filename = 'oggy.ogg'; const filePath = path.join(__dirname, 'samples', filename); @@ -51,10 +54,30 @@ it("should decode ogg audio-file", () => { assert.strictEqual(cover.data[cover.data.length - 2], 255, 'vorbis.METADATA_BLOCK_PICTURE data -2'); } - return mm.parseFile(filePath, {native: true}).then((result) => { - checkFormat(result.format); - checkCommon(result.common); - checkVorbisTags(mm.orderTags(result.native.vorbis)); + it("should decode an Ogg Vorbis audio file (.ogg)", () => { + + return mm.parseFile(filePath, {native: true}).then((metadata) => { + checkFormat(metadata.format); + checkCommon(metadata.common); + checkVorbisTags(mm.orderTags(metadata.native.vorbis)); + }); + + }); + + it("should decode from an Ogg Vorbis audio stream (audio/ogg)", function() { + + this.skip(); // ToDo + + const stream = fs.createReadStream(filePath); + + return mm.parseStream(stream, 'audio/ogg', {native: true}).then((metadata) => { + checkFormat(metadata.format); + checkCommon(metadata.common); + checkVorbisTags(mm.orderTags(metadata.native.vorbis)); + }).then(() => { + stream.close(); + }); + }); });