[Pkg-javascript-commits] [node-music-library-index] 01/02: Imported Upstream version 1.2.1
Andrew Kelley
andrewrk-guest at moszumanska.debian.org
Mon Jun 30 05:58:08 UTC 2014
This is an automated email from the git hooks/post-receive script.
andrewrk-guest pushed a commit to branch master
in repository node-music-library-index.
commit ef68aea9be2a3f76bf29452c81052e6524175eb3
Author: Andrew Kelley <superjoe30 at gmail.com>
Date: Mon Jun 30 05:46:41 2014 +0000
Imported Upstream version 1.2.1
---
.gitignore | 1 +
.jshintrc | 73 +++++++++
README.md | 95 ++++++++++++
index.js | 308 +++++++++++++++++++++++++++++++++++++
package.json | 28 ++++
test/benchmark.js | 35 +++++
test/test.js | 448 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 988 insertions(+)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..07e6e47
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/node_modules
diff --git a/.jshintrc b/.jshintrc
new file mode 100644
index 0000000..7cb9418
--- /dev/null
+++ b/.jshintrc
@@ -0,0 +1,73 @@
+{
+ // Settings
+ "passfail" : false, // Stop on first error.
+ "maxerr" : 100, // Maximum errors before stopping.
+
+
+ // Predefined globals whom JSHint will ignore.
+ "browser" : false, // Standard browser globals e.g. `window`, `document`.
+ "predef" : [ // extra globals
+ "describe",
+ "beforeEach",
+ "afterEach",
+ "it"
+ ],
+
+ "node" : true,
+ "rhino" : false,
+ "couch" : false,
+ "wsh" : false, // Windows Scripting Host.
+
+ "jquery" : false,
+ "prototypejs" : false,
+ "mootools" : false,
+ "dojo" : false,
+
+
+
+ // Development.
+ "debug" : true, // Allow debugger statements e.g. browser breakpoints.
+ "devel" : true, // Allow development statements e.g. `console.log();`.
+
+
+ // EcmaScript 5.
+ "es5" : true, // Allow EcmaScript 5 syntax.
+ "strict" : false, // Require `use strict` pragma in every file.
+ "globalstrict" : true, // Allow global "use strict" (also enables 'strict').
+
+
+ // The Good Parts.
+ "asi" : true, // Tolerate Automatic Semicolon Insertion (no semicolons).
+ "laxbreak" : false, // Tolerate unsafe line breaks e.g. `return [\n] x` without semicolons.
+ "laxcomma" : true,
+ "bitwise" : false, // Prohibit bitwise operators (&, |, ^, etc.).
+ "boss" : true, // Tolerate assignments inside if, for & while. Usually conditions & loops are for comparison, not assignments.
+ "curly" : false, // Require {} for every new block or scope.
+ "eqeqeq" : true, // Require triple equals i.e. `===`.
+ "eqnull" : true, // Tolerate use of `== null`.
+ "evil" : false, // Tolerate use of `eval`.
+ "expr" : false, // Tolerate `ExpressionStatement` as Programs.
+ "forin" : false, // Prohibt `for in` loops without `hasOwnProperty`.
+ "immed" : true, // Require immediate invocations to be wrapped in parens e.g. `( function(){}() );`
+ "latedef" : false, // Prohibit variable use before definition.
+ "loopfunc" : false, // Allow functions to be defined within loops.
+ "noarg" : true, // Prohibit use of `arguments.caller` and `arguments.callee`.
+ "regexp" : false, // Prohibit `.` and `[^...]` in regular expressions.
+ "regexdash" : false, // Tolerate unescaped last dash i.e. `[-...]`.
+ "scripturl" : false, // Tolerate script-targeted URLs.
+ "shadow" : false, // Allows re-define variables later in code e.g. `var x=1; x=2;`.
+ "supernew" : false, // Tolerate `new function () { ... };` and `new Object;`.
+ "undef" : true, // Require all non-global variables be declared before they are used.
+
+
+ // Persone styling prefrences.
+ "newcap" : true, // Require capitalization of all constructor functions e.g. `new F()`.
+ "noempty" : true, // Prohibit use of empty blocks.
+ "nonew" : true, // Prohibit use of constructors for side-effects.
+ "nomen" : false, // Prohibit use of initial or trailing underbars in names.
+ "onevar" : false, // Allow only one `var` statement per function.
+ "plusplus" : false, // Prohibit use of `++` & `--`.
+ "sub" : false, // Tolerate all forms of subscript notation besides dot notation e.g. `dict['key']` instead of `dict.key`.
+ "trailing" : true, // Prohibit trailing whitespaces.
+ "white" : false // Check against strict whitespace and indentation rules.
+}
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..fbdb5d3
--- /dev/null
+++ b/README.md
@@ -0,0 +1,95 @@
+# Music Library Index
+
+Given track metadata objects, constructs a searchable object model.
+This module is used both in the client and the server of
+[Groove Basin](https://github.com/superjoe30/groovebasin).
+
+## Features
+
+ * Sort order ignores 'a', 'an' and 'the' in artists, albums, and names.
+ * Sorting and searching is case insensitive and
+ [diacritics-insensitive](https://github.com/superjoe30/diacritics).
+ * Searching uses word-based filtering (this is how most music player
+ applications implement filtering) on all track fields.
+ * Distinguishes albums by name, date, and album artist.
+ * Produces these indexes:
+ * Artists in sorted order
+ - For each of these artists, albums in sorted order.
+ - For each of these albums, tracks in sorted order.
+ * Albums in sorted order
+ - For each of these albums, tracks in sorted order.
+ * Tracks by user-defined key.
+ * Artists by library-defined key.
+ * Albums by library-defined key.
+
+## Usage
+
+```js
+var MusicLibraryIndex = require('music-library-index');
+var library = new MusicLibraryIndex();
+
+library.addTrack({
+ key: "Anberlin/Never Take Friendship Personal/02. Paperthin Hymn.mp3",
+ name: "Paperthin Hymn",
+ artistName: "Anberlin",
+ albumName: "Never Take Friendship Personal",
+ year: 2005,
+ genre: "Other",
+ track: 2,
+ albumArtistName: "Anberlin",
+});
+
+library.addTrack({
+ key: "Anberlin/Never Take Friendship Personal/08. The Feel Good Drag.mp3",
+ name: "The Feel Good Drag",
+ artistName: "Anberlin",
+ albumName: "Never Take Friendship Personal",
+ year: 2005,
+ genre: "Other",
+ track: 8,
+ albumArtistName: "Anberlin",
+});
+
+library.rebuild();
+
+console.log(library.artistList[0]);
+console.log(library.trackTable);
+```
+
+## Tests
+
+```
+ basic index building
+ ✓ trackTable
+ ✓ artistList
+ ✓ albumList
+ ✓ searching
+
+ compilation album
+ ✓ filed in various artists
+
+ tracks from same album missing year metadata
+ ✓ still knows they're in the same album
+
+ different albums with same name
+ ✓ detects that they are different
+
+ album with a few tracks by different artists
+ ✓ only creates one album
+
+ album by an artist
+ ✓ should be filed under the artist
+
+ album by an artist
+ ✓ sorts by disc before track
+
+ album artist with no album
+ ✓ shouldn't be various artists
+
+ unknown artist, unknown album
+ ✓ should be put into the same album
+ ✓ searching should not affect anything
+
+ album with album artist
+ ✓ shouldn't be various artists
+```
diff --git a/index.js b/index.js
new file mode 100644
index 0000000..d62b9af
--- /dev/null
+++ b/index.js
@@ -0,0 +1,308 @@
+var removeDiacritics = require('diacritics').remove;
+
+module.exports = MusicLibraryIndex;
+
+MusicLibraryIndex.defaultPrefixesToStrip = [/^\s*the\s+/, /^\s*a\s+/,
+ /^\s*an\s+/];
+MusicLibraryIndex.defaultVariousArtistsKey = "VariousArtists";
+MusicLibraryIndex.defaultVariousArtistsName = "Various Artists";
+MusicLibraryIndex.defaultSearchFields = ['artistName', 'albumArtistName',
+ 'albumName', 'name'];
+
+function MusicLibraryIndex(options) {
+ options = options || {};
+ this.searchFields = options.searchFields ||
+ MusicLibraryIndex.defaultSearchFields;
+ this.variousArtistsKey = options.variousArtistsKey ||
+ MusicLibraryIndex.defaultVariousArtistsKey;
+ this.variousArtistsName = options.variousArtistsName ||
+ MusicLibraryIndex.defaultVariousArtistsName;
+ this.prefixesToStrip = options.prefixesToStrip ||
+ MusicLibraryIndex.defaultPrefixesToStrip;
+
+ this.artistComparator = this.artistComparator.bind(this);
+ this.albumComparator = this.albumComparator.bind(this);
+ this.trackComparator = this.trackComparator.bind(this);
+ this.clear();
+}
+
+MusicLibraryIndex.prototype.stripPrefixes = function(str) {
+ for (var i = 0; i < this.prefixesToStrip.length; i += 1) {
+ var regex = this.prefixesToStrip[i];
+ str = str.replace(regex, '');
+ break;
+ }
+ return str;
+};
+
+MusicLibraryIndex.prototype.sortableTitle = function(title) {
+ return this.stripPrefixes(formatSearchable(title));
+};
+
+MusicLibraryIndex.prototype.titleCompare = function(a, b) {
+ var _a = this.sortableTitle(a);
+ var _b = this.sortableTitle(b);
+ if (_a < _b) {
+ return -1;
+ } else if (_a > _b) {
+ return 1;
+ } else {
+ if (a < b) {
+ return -1;
+ } else if (a > b) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+};
+
+MusicLibraryIndex.prototype.trackComparator = function(a, b) {
+ if (a.disc < b.disc) {
+ return -1;
+ } else if (a.disc > b.disc) {
+ return 1;
+ } else if (a.track < b.track) {
+ return -1;
+ } else if (a.track > b.track) {
+ return 1;
+ } else {
+ return this.titleCompare(a.name, b.name);
+ }
+}
+
+MusicLibraryIndex.prototype.albumComparator = function(a, b) {
+ if (a.year < b.year) {
+ return -1;
+ } else if (a.year > b.year) {
+ return 1;
+ } else {
+ return this.titleCompare(a.name, b.name);
+ }
+}
+
+MusicLibraryIndex.prototype.artistComparator = function(a, b) {
+ return this.titleCompare(a.name, b.name);
+}
+
+MusicLibraryIndex.prototype.getAlbumKey = function(track) {
+ var artistName = track.albumArtistName ||
+ (track.compilation ? this.variousArtistsName : track.artistName);
+ return formatSearchable(track.albumName + "\n" + artistName);
+};
+
+MusicLibraryIndex.prototype.getArtistKey = function(artistName) {
+ return formatSearchable(artistName);
+};
+
+MusicLibraryIndex.prototype.clear = function() {
+ this.trackTable = {};
+ this.artistTable = {};
+ this.artistList = [];
+ this.albumTable = {};
+ this.albumList = [];
+ this.dirty = false;
+ this.dirtyAlbumTable = false;
+};
+
+MusicLibraryIndex.prototype.rebuildAlbumTable = function() {
+ if (!this.dirtyAlbumTable) return;
+
+ // builds everything from trackTable
+ this.artistTable = {};
+ this.artistList = [];
+ this.albumTable = {};
+ this.albumList = [];
+ var thisAlbumList = this.albumList;
+ for (var trackKey in this.trackTable) {
+ var track = this.trackTable[trackKey];
+ this.trackTable[track.key] = track;
+
+ var searchTags = "";
+ for (var i = 0; i < this.searchFields.length; i += 1) {
+ searchTags += track[this.searchFields[i]] + "\n";
+ }
+ track.searchTags = formatSearchable(searchTags);
+
+ if (track.albumArtistName === this.variousArtistsName) {
+ track.albumArtistName = "";
+ track.compilation = true;
+ }
+ track.albumArtistName = track.albumArtistName || "";
+
+ var albumKey = this.getAlbumKey(track);
+ var album = getOrCreate(albumKey, this.albumTable, createAlbum);
+ track.album = album;
+ album.trackList.push(track);
+ if (album.year == null) {
+ album.year = track.year;
+ }
+ }
+
+ this.dirtyAlbumTable = false;
+
+ function createAlbum() {
+ var album = {
+ name: track.albumName,
+ year: track.year,
+ trackList: [],
+ key: albumKey,
+ };
+ thisAlbumList.push(album);
+ return album;
+ }
+};
+
+MusicLibraryIndex.prototype.rebuild = function() {
+ if (!this.dirty) return;
+ this.rebuildAlbumTable();
+ this.albumList.sort(this.albumComparator);
+
+ var albumArtistName, artistKey, artist;
+ var albumKey, track, album;
+ var i;
+ for (albumKey in this.albumTable) {
+ album = this.albumTable[albumKey];
+ var albumArtistSet = {};
+ album.trackList.sort(this.trackComparator);
+ albumArtistName = "";
+ var isCompilation = false;
+ for (i = 0; i < album.trackList.length; i += 1) {
+ track = album.trackList[i];
+ track.index = i;
+ if (track.albumArtistName) {
+ albumArtistName = track.albumArtistName;
+ albumArtistSet[this.getArtistKey(albumArtistName)] = true;
+ }
+ if (!albumArtistName) albumArtistName = track.artistName;
+ albumArtistSet[this.getArtistKey(albumArtistName)] = true;
+ isCompilation = isCompilation || track.compilation;
+ }
+ if (isCompilation || moreThanOneKey(albumArtistSet)) {
+ albumArtistName = this.variousArtistsName;
+ artistKey = this.variousArtistsKey;
+ for (i = 0; i < album.trackList.length; i += 1) {
+ track = album.trackList[i];
+ track.compilation = true;
+ }
+ } else {
+ artistKey = this.getArtistKey(albumArtistName);
+ }
+ artist = getOrCreate(artistKey, this.artistTable, createArtist);
+ album.artist = artist;
+ artist.albumList.push(album);
+ }
+
+ this.artistList = [];
+ var variousArtist = null;
+ for (artistKey in this.artistTable) {
+ artist = this.artistTable[artistKey];
+ artist.albumList.sort(this.albumComparator);
+ for (i = 0; i < artist.albumList.length; i += 1) {
+ album = artist.albumList[i];
+ album.index = i;
+ }
+ if (artist.key === this.variousArtistsKey) {
+ variousArtist = artist;
+ } else {
+ this.artistList.push(artist);
+ }
+ }
+ this.artistList.sort(this.artistComparator);
+ if (variousArtist) {
+ this.artistList.unshift(variousArtist);
+ }
+ for (i = 0; i < this.artistList.length; i += 1) {
+ artist = this.artistList[i];
+ artist.index = i;
+ }
+
+ this.dirty = false;
+
+ function createArtist() {
+ return {
+ name: albumArtistName,
+ albumList: [],
+ key: artistKey,
+ };
+ }
+}
+
+MusicLibraryIndex.prototype.addTrack = function(track) {
+ var oldTrack = this.trackTable[track.key];
+ this.dirty = this.dirty ||
+ oldTrack == null ||
+ oldTrack.artistName !== track.artistName ||
+ oldTrack.albumArtistName !== track.albumArtistName ||
+ oldTrack.albumName !== track.albumName ||
+ oldTrack.track !== track.track ||
+ oldTrack.disc !== track.disc ||
+ oldTrack.year !== track.year;
+ this.dirtyAlbumTable = this.dirty;
+ this.trackTable[track.key] = track;
+}
+
+MusicLibraryIndex.prototype.removeTrack = function(key) {
+ delete this.trackTable[key];
+ this.dirty = true;
+ this.dirtyAlbumTable = true;
+}
+
+MusicLibraryIndex.prototype.search = function(query) {
+ query = query.trim();
+
+ var searchResults = new MusicLibraryIndex({
+ searchFields: this.searchFields,
+ variousArtistsKey: this.variousArtistsKey,
+ variousArtistsName: this.variousArtistsName,
+ prefixesToStrip: this.prefixesToStrip,
+ });
+
+ var words = formatSearchable(query).split(/\s+/);
+
+ var track;
+ for (var trackKey in this.trackTable) {
+ track = this.trackTable[trackKey];
+ if (testMatch()) {
+ searchResults.trackTable[track.key] = track;
+ }
+ }
+ searchResults.dirty = true;
+ searchResults.dirtyAlbumTable = true;
+ searchResults.rebuild();
+
+ return searchResults;
+
+ function testMatch() {
+ for (var i = 0; i < words.length; i += 1) {
+ var word = words[i];
+ if (track.searchTags.indexOf(word) === -1) {
+ return false;
+ }
+ }
+ return true;
+ }
+};
+
+function getOrCreate(key, table, initObjFunc) {
+ var result = table[key];
+ if (result == null) {
+ result = initObjFunc();
+ table[key] = result;
+ }
+ return result;
+}
+
+function moreThanOneKey(object){
+ var count = -2;
+ for (var k in object) {
+ if (!++count) {
+ return true;
+ }
+ }
+ return false;
+}
+
+function formatSearchable(str) {
+ return removeDiacritics(str).toLowerCase();
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..31fcac4
--- /dev/null
+++ b/package.json
@@ -0,0 +1,28 @@
+{
+ "name": "music-library-index",
+ "version": "1.2.1",
+ "description": "build a searchable javascript object model given track metadata objects",
+ "main": "index.js",
+ "scripts": {
+ "test": "mocha --reporter spec test/test.js"
+ },
+ "author": "Andrew Kelley <superjoe30 at gmail.com>",
+ "license": "MIT",
+ "dependencies": {
+ "diacritics": "~1.2.0"
+ },
+ "devDependencies": {
+ "mocha": "^1.17.1"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/superjoe30/node-music-library-index.git"
+ },
+ "bugs": {
+ "url": "https://github.com/superjoe30/node-music-library-index/issues"
+ },
+ "homepage": "https://github.com/superjoe30/node-music-library-index",
+ "directories": {
+ "test": "test"
+ }
+}
diff --git a/test/benchmark.js b/test/benchmark.js
new file mode 100644
index 0000000..5a9f0f2
--- /dev/null
+++ b/test/benchmark.js
@@ -0,0 +1,35 @@
+// usage: node benchmark.js path/to/index.json ["search query" ...]
+
+var fs = require('fs');
+var MusicLibraryIndex = require('../');
+
+var indexPath = process.argv[2];
+fs.readFile(indexPath, function(err, data) {
+ if (err) throw err;
+
+ var input = JSON.parse(data);
+ var library = new MusicLibraryIndex();
+ for (var key in input) {
+ library.addTrack(input[key]);
+ }
+ timed("rebuild()", function() {
+ library.rebuild();
+ });
+ for (var i = 3; i < process.argv.length; i++) {
+ timedSearch(process.argv[i]);
+ }
+
+ function timedSearch(query) {
+ timed("search(" + JSON.stringify(query) + ")", function() {
+ library.search(query);
+ });
+ }
+});
+
+function timed(name, func) {
+ process.stdout.write(name + "...");
+ var start = new Date();
+ func();
+ var duration = new Date() - start;
+ console.log(duration + "ms");
+}
diff --git a/test/test.js b/test/test.js
new file mode 100644
index 0000000..8ae2ab8
--- /dev/null
+++ b/test/test.js
@@ -0,0 +1,448 @@
+var assert = require('assert');
+var MusicLibraryIndex = require('../');
+
+describe("basic index building", function() {
+ var library = new MusicLibraryIndex();
+
+ library.addTrack({
+ key: "Anberlin/Never Take Friendship Personal/02. Paperthin Hymn.mp3",
+ name: "Paperthin Hymn",
+ artistName: "Anberlin",
+ albumName: "Never Take Friendship Personal",
+ year: 2005,
+ genre: "Other",
+ track: 2,
+ albumArtistName: "Anberlin",
+ });
+
+ library.addTrack({
+ key: "Anberlin/Never Take Friendship Personal/08. The Feel Good Drag.mp3",
+ name: "The Feel Good Drag",
+ artistName: "Anberlin",
+ albumName: "Never Take Friendship Personal",
+ year: 2005,
+ genre: "Other",
+ track: 8,
+ albumArtistName: "Anberlin",
+ });
+
+ library.rebuild();
+
+ it("trackTable", function() {
+ var track = library.trackTable["Anberlin/Never Take Friendship Personal/08. The Feel Good Drag.mp3"];
+ assert.strictEqual(track.name, "The Feel Good Drag");
+ assert.strictEqual(track.artistName, "Anberlin");
+ assert.strictEqual(track.album.name, "Never Take Friendship Personal");
+ assert.strictEqual(track.year, 2005);
+ });
+
+ it("artistList", function() {
+ assert.strictEqual(library.artistList.length, 1);
+ var artist = library.artistList[0];
+ assert.strictEqual(artist.name, "Anberlin");
+ assert.strictEqual(artist.index, 0);
+ assert.strictEqual(artist.albumList.length, 1);
+ var album = artist.albumList[0];
+ assert.strictEqual(album.name, "Never Take Friendship Personal");
+ assert.strictEqual(album.year, 2005);
+ assert.strictEqual(album.index, 0);
+ assert.strictEqual(album.trackList.length, 2);
+ assert.strictEqual(album.trackList[0].name, "Paperthin Hymn");
+ assert.strictEqual(album.trackList[0].index, 0);
+ assert.strictEqual(album.trackList[1].name, "The Feel Good Drag");
+ assert.strictEqual(album.trackList[1].index, 1);
+ });
+
+ it("albumList", function() {
+ assert.strictEqual(library.albumList.length, 1);
+ var album = library.albumList[0];
+ assert.strictEqual(album.name, "Never Take Friendship Personal");
+ assert.strictEqual(album.year, 2005);
+ assert.strictEqual(album.index, 0);
+ assert.strictEqual(album.trackList.length, 2);
+ assert.strictEqual(album.trackList[0].name, "Paperthin Hymn");
+ assert.strictEqual(album.trackList[0].index, 0);
+ assert.strictEqual(album.trackList[1].name, "The Feel Good Drag");
+ assert.strictEqual(album.trackList[1].index, 1);
+ });
+
+ it("searching", function() {
+ var results = library.search("never drag");
+
+ assert.strictEqual(results.albumList.length, 1);
+ assert.strictEqual(results.albumList[0].trackList.length, 1);
+ assert.strictEqual(results.albumList[0].trackList[0].name, "The Feel Good Drag");
+ });
+});
+
+describe("compilation album", function() {
+ var library = new MusicLibraryIndex();
+
+ library.addTrack({
+ key: "jqvq-tpiu",
+ name: "No News Is Good News",
+ artistName: "New Found Glory",
+ albumName: "2004 Warped Tour Compilation [Disc 1]",
+ year: 2004,
+ disc: 1,
+ discCount: 2,
+ genre: "Alternative & Punk",
+ albumArtistName: "Various Artists",
+ track: 1,
+ });
+
+ library.addTrack({
+ key: "dldd-itve",
+ name: "American Errorist (I Hate Hate Haters)",
+ artistName: "NOFX",
+ albumName: "2004 Warped Tour Compilation [Disc 1]",
+ year: 2004,
+ disc: 1,
+ discCount: 2,
+ genre: "Alternative & Punk",
+ albumArtistName: "Various Artists",
+ track: 2,
+ });
+
+ library.addTrack({
+ key: "ukjv-ndsz",
+ name: "Fire Down Below",
+ artistName: "Alkaline Trio",
+ albumName: "2007 Warped Tour Compilation [Disc 1]",
+ compilation: true,
+ year: 2007,
+ genre: "Alternative & Punk",
+ track: 1,
+ trackCount: 25,
+ });
+
+ library.addTrack({
+ key: "gfkt-esqz",
+ name: "Requiem For Dissent",
+ artistName: "Bad Religion",
+ albumName: "2007 Warped Tour Compilation [Disc 1]",
+ compilation: true,
+ year: 2007,
+ genre: "Alternative & Punk",
+ track: 2,
+ trackCount: 25,
+ });
+
+ library.rebuild();
+
+ it("filed in various artists", function() {
+ assert.strictEqual(library.albumList.length, 2);
+ assert.strictEqual(library.artistList.length, 1);
+ var artist = library.artistList[0];
+ assert.strictEqual(artist.name, "Various Artists");
+ assert.strictEqual(artist.albumList.length, 2);
+ assert.strictEqual(library.albumList.length, 2);
+ assert.strictEqual(library.trackTable["jqvq-tpiu"].albumArtistName, "");
+ assert.strictEqual(library.trackTable["dldd-itve"].albumArtistName, "");
+ assert.strictEqual(library.trackTable["ukjv-ndsz"].albumArtistName, "");
+ assert.strictEqual(library.trackTable["gfkt-esqz"].albumArtistName, "");
+ });
+});
+
+describe("tracks from same album missing year metadata", function() {
+ var library = new MusicLibraryIndex();
+
+ library.addTrack({
+ key: "wwxj-unhr",
+ name: "Dog-Eared Page",
+ artistName: "The Matches",
+ albumName: "E. Von Dahl Killed the Locals",
+ year: 2004,
+ genre: "Punk",
+ track: 1,
+ });
+
+ library.addTrack({
+ key: "xekw-lvne",
+ name: "Audio Blood",
+ artistName: "The Matches",
+ albumName: "E. Von Dahl Killed the Locals",
+ // missing year
+ genre: "Rock",
+ track: 2,
+ });
+
+ library.addTrack({
+ key: "lpka-dugc",
+ name: "Chain Me Free",
+ artistName: "The Matches",
+ albumName: "E. Von Dahl Killed the Locals",
+ year: 2004,
+ genre: "Rock",
+ track: 3,
+ });
+
+ library.rebuild();
+
+ it("still knows they're in the same album", function() {
+ assert.strictEqual(library.albumList.length, 1);
+ assert.strictEqual(library.albumList[0].year, 2004);
+ assert.strictEqual(library.trackTable["xekw-lvne"].album.year, 2004);
+ });
+});
+
+describe("different albums with same name", function() {
+ var library = new MusicLibraryIndex();
+
+ library.addTrack({
+ key: "sbao-lcvn",
+ name: "6:00",
+ artistName: "Dream Theater",
+ albumName: "Awake",
+ year: 1994,
+ genre: "Progressive Rock",
+ track: 1,
+ });
+
+ library.addTrack({
+ key: "qtru-gdtp",
+ name: "Awake",
+ artistName: "Godsmack",
+ albumName: "Awake",
+ year: 2000,
+ genre: "Rock",
+ track: 2,
+ });
+
+ library.rebuild();
+
+ it("detects that they are different", function() {
+ assert.strictEqual(library.albumList.length, 2);
+ });
+});
+
+describe("album with a few tracks by different artists", function() {
+ var library = new MusicLibraryIndex();
+
+ library.addTrack({
+ key: "ikoe-nujf",
+ name: "Paperthin Hymn",
+ artistName: "Anberlin",
+ albumArtistName: "Anberlin",
+ albumName: "Never Take Friendship Personal",
+ year: 2005,
+ genre: "Other",
+ track: 2,
+ });
+
+ library.addTrack({
+ key: "msnq-swpc",
+ name: "The Feel Good Drag",
+ artistName: "Anberlin, some other band",
+ albumArtistName: "Anberlin",
+ albumName: "Never Take Friendship Personal",
+ year: 2005,
+ genre: "Other",
+ track: 8,
+ });
+
+
+ library.rebuild();
+
+ it("only creates one album", function() {
+ assert.strictEqual(library.albumList.length, 1);
+ });
+});
+
+describe("album by an artist", function() {
+ var library = new MusicLibraryIndex();
+
+ library.addTrack({
+ key: "ynji-lcfu",
+ name: "The Truth",
+ artistName: "Relient K",
+ albumName: "Apathetic ep",
+ track: 1,
+ trackCount: 7,
+ });
+
+ library.addTrack({
+ key: "lxed-bsor",
+ name: "Apathetic Way to Be",
+ artistName: "Relient K",
+ albumName: "Apathetic ep",
+ track: 2,
+ trackCount: 7,
+ });
+
+
+ library.rebuild();
+
+ it("should be filed under the artist", function() {
+ assert.strictEqual(library.artistList.length, 1);
+ assert.strictEqual(library.artistList[0].name, "Relient K");
+ });
+});
+
+describe("album by an artist", function() {
+ var library = new MusicLibraryIndex();
+ library.addTrack({
+ key: "jqvq-tpiu",
+ name: "No News Is Good News",
+ artistName: "New Found Glory",
+ albumName: "2004 Warped Tour Compilation",
+ year: 2004,
+ disc: 1,
+ discCount: 2,
+ genre: "Alternative & Punk",
+ albumArtistName: "Various Artists",
+ track: 1,
+ });
+
+ library.addTrack({
+ key: "dldd-itve",
+ name: "American Errorist (I Hate Hate Haters)",
+ artistName: "NOFX",
+ albumName: "2004 Warped Tour Compilation",
+ year: 2004,
+ disc: 1,
+ discCount: 2,
+ genre: "Alternative & Punk",
+ albumArtistName: "Various Artists",
+ track: 2,
+ });
+
+ library.addTrack({
+ key: "ukjv-ndsz",
+ name: "Fire Down Below",
+ artistName: "Alkaline Trio",
+ albumName: "2004 Warped Tour Compilation",
+ disc: 2,
+ compilation: true,
+ year: 2004,
+ genre: "Alternative & Punk",
+ track: 1,
+ trackCount: 25,
+ });
+
+ library.addTrack({
+ key: "gfkt-esqz",
+ name: "Requiem For Dissent",
+ artistName: "Bad Religion",
+ albumName: "2004 Warped Tour Compilation",
+ disc: 2,
+ compilation: true,
+ year: 2004,
+ genre: "Alternative & Punk",
+ track: 2,
+ trackCount: 25,
+ });
+
+ library.rebuild();
+
+ it("sorts by disc before track", function() {
+ assert.strictEqual(library.albumList[0].trackList[0].name, "No News Is Good News");
+ assert.strictEqual(library.albumList[0].trackList[1].name, "American Errorist (I Hate Hate Haters)");
+ assert.strictEqual(library.albumList[0].trackList[2].name, "Fire Down Below");
+ assert.strictEqual(library.albumList[0].trackList[3].name, "Requiem For Dissent");
+ });
+});
+
+describe("album artist with no album", function() {
+ var library = new MusicLibraryIndex();
+
+ var id = '5a89ea73-71aa-4c22-97a5-3b3509131cca';
+ library.addTrack({
+ key: id,
+ name: 'I Miss You',
+ artistName: 'Blink 182',
+ composerName: '',
+ performerName: '',
+ albumArtistName: 'blink-182',
+ albumName: '',
+ compilation: false,
+ track: 3,
+ duration: 227.6815,
+ year: 2003,
+ genre: 'Rock',
+ });
+
+ library.rebuild();
+
+ it("shouldn't be various artists", function() {
+ assert.notStrictEqual(library.trackTable[id].albumArtistName, "Various Artists");
+ });
+});
+
+describe("unknown artist, unknown album", function() {
+ var library = new MusicLibraryIndex();
+
+ library.addTrack({
+ key: 'imnd-sxde',
+ name: '01 Shining Armor',
+ artistName: '',
+ albumArtistName: '',
+ albumName: '',
+ });
+
+ library.addTrack({
+ key: 'jakg-nbfg',
+ name: '02 Weird Kids',
+ artistName: '',
+ albumArtistName: '',
+ albumName: '',
+ });
+
+ library.rebuild();
+ var results = library;
+
+ it("should be put into the same album", check);
+
+ library.search("n");
+ results = library.search("");
+
+ it("searching should not affect anything", check);
+
+ function check() {
+ assert.strictEqual(results.artistList.length, 1);
+ assert.strictEqual(results.artistList[0].albumList.length, 1);
+ assert.strictEqual(results.artistList[0].albumList[0].trackList.length, 2);
+ assert.strictEqual(results.artistList[0].albumList[0].trackList[0].album.trackList.length, 2);
+ }
+});
+
+describe("album with album artist", function() {
+ var library = new MusicLibraryIndex();
+
+ var id1 = 'imnd-sxde';
+ library.addTrack({
+ key: id1,
+ name: 'Palladio',
+ artistName: 'Escala',
+ albumArtistName: 'Escala',
+ albumName: 'Escala',
+ track: 1,
+ });
+
+ var id2 = 'vewu-hqbx';
+ library.addTrack({
+ key: id2,
+ name: 'Requiem for a Tower',
+ artistName: 'Escala',
+ albumArtistName: 'Escala',
+ albumName: 'Escala',
+ track: 2,
+ });
+
+ var id3 = 'ixbc-oshh';
+ library.addTrack({
+ key: id3,
+ name: 'Kashmir',
+ artistName: 'Escala; Slash',
+ albumArtistName: 'Escala',
+ albumName: 'Escala',
+ track: 3,
+ });
+ library.rebuild();
+
+ it("shouldn't be various artists", function() {
+ assert.strictEqual(library.trackTable[id1].albumArtistName, "Escala");
+ assert.strictEqual(library.trackTable[id2].albumArtistName, "Escala");
+ assert.strictEqual(library.artistList.length, 1);
+ });
+});
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-music-library-index.git
More information about the Pkg-javascript-commits
mailing list