[gnome-music] Album and Artists View basic playback



commit 056b47441cc8c744dd033ac4b55a5ca997c56821
Author: Vadim Rutkovsky <vrutkovs redhat com>
Date:   Mon May 6 14:05:49 2013 +0200

    Album and Artists View basic playback

 src/view.js                    |    6 +-
 src/widgets.js                 |    9 ++-
 tests/tests_albumArt.js        |  145 ------------------------------------
 tests/tests_albumPlayback.js   |  158 ++++++++++++++++++++++++++++++++++++++++
 tests/tests_artistsPlayback.js |  146 +++++++++++++++++++++++++++++++++++++
 5 files changed, 315 insertions(+), 149 deletions(-)
---
diff --git a/src/view.js b/src/view.js
index 8d35d42..b3a007c 100644
--- a/src/view.js
+++ b/src/view.js
@@ -449,8 +449,8 @@ const Artists = new Lang.Class({
         var iter = this._model.get_iter (path)[1];
         var artist = this._model.get_value (iter, 0);
         var albums = this._artists[artist.toLowerCase()]["albums"]
-        var artistAlbums = new Widgets.ArtistAlbums(artist, albums, this.player);
-        this._artistAlbumsWidget.add(artistAlbums);
+        this.artistAlbums = new Widgets.ArtistAlbums(artist, albums, this.player);
+        this._artistAlbumsWidget.add(this.artistAlbums);
         //this._artistAlbumsWidget.update(artist, albums);
     },
 
@@ -473,11 +473,13 @@ const Artists = new Lang.Class({
         );
         }
         this._artists[artist.toLowerCase()]["albums"].push(item)
+        this.emit("artist-added");
     },
 
     populate: function () {
         if(grilo.tracker != null) {
             grilo.populateArtists(this._offset, Lang.bind(this, this._addItem, null));
+            //FIXME: We're emitting this too early, need to wait for all artists to be filled in
         }
     },
 });
diff --git a/src/widgets.js b/src/widgets.js
index 4a4ee35..8bfc4ec 100644
--- a/src/widgets.js
+++ b/src/widgets.js
@@ -241,7 +241,7 @@ const ArtistAlbums = new Lang.Class({
         this.ui.add_from_resource('/org/gnome/music/ArtistAlbumsWidget.ui');
         this.set_border_width(0);
         this.ui.get_object("artist").set_label(this.artist);
-        var widgets = [];
+        this.widgets = [];
 
         this.model = Gtk.ListStore.new([
                 GObject.TYPE_STRING, /*title*/
@@ -258,10 +258,11 @@ const ArtistAlbums = new Lang.Class({
         for (var i=0; i < albums.length; i++) {
             let widget = new ArtistAlbumWidget(artist, albums[i], this.player, this.model)
             this.pack_start(widget, false, false, 32);
-            widgets.push(widget);
+            this.widgets.push(widget);
         }
         this.show_all();
         this.player.connect('playlist-item-changed', Lang.bind(this, this.updateModel));
+        this.emit("albums-loaded");
     },
 
     updateModel: function(player, playlist, currentIter){
@@ -296,6 +297,7 @@ const ArtistAlbums = new Lang.Class({
 
     },
 });
+Signals.addSignalMethods(ArtistAlbums.prototype);
 
 const ArtistAlbumWidget = new Lang.Class({
     Name: "ArtistAlbumWidget",
@@ -360,11 +362,13 @@ const ArtistAlbumWidget = new Lang.Class({
                     songWidget.nowPlayingSign.set_no_show_all("true");
                 }
                 this.ui.get_object("grid1").show_all();
+                this.emit("tracks-loaded");
             }
         }));
 
         this.pack_start(this.ui.get_object("ArtistAlbumWidget"), true, true, 0);
         this.show_all();
+        this.emit("artist-album-loaded");
     },
     trackSelected: function(widget, iter) {
         this.player.stop();
@@ -373,3 +377,4 @@ const ArtistAlbumWidget = new Lang.Class({
     },
 
 });
+Signals.addSignalMethods(ArtistAlbumWidget.prototype);
diff --git a/tests/tests_albumArt.js b/tests/tests_albumArt.js
index 9740f48..224a115 100755
--- a/tests/tests_albumArt.js
+++ b/tests/tests_albumArt.js
@@ -10,9 +10,6 @@ imports.searchPath.unshift('../libgd');
 imports.searchPath.unshift('../data');
 const AlbumArtCache = imports.src.albumArtCache.AlbumArtCache
 const GLib = imports.gi.GLib;
-const Gio = imports.gi.Gio;
-const Gtk = imports.gi.Gtk;
-const Gdk = imports.gi.Gdk;
 const Lang = imports.lang;
 
 
@@ -79,146 +76,4 @@ function testStripInvalidEntries_Spaces() {
     assertEquals('Unknown Artist', albumArtCache.stripInvalidEntities("Unknown^^@(*  ) Artist"))
 }
 
-function registerResources() {
-    let resource = Gio.Resource.load('../data/gnome-music.gresource');
-    resource._register();
-
-    let cssFile = Gio.File.new_for_uri('resource:///org/gnome/music/application.css');
-    let provider = new Gtk.CssProvider();
-    provider.load_from_file(cssFile);
-    Gtk.init(null, 0);
-    Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),
-                                             provider,
-                                             Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
-}
-
-function getAlbumView() {
-    registerResources();
-
-    const AlbumView = imports.view.Albums;
-    const Toolbar = imports.toolbar;
-    const Player = imports.player;
-    let toolbar = new Toolbar.Toolbar();
-    let player = new Player.Player();
-    return new AlbumView(toolbar, player);
-}
-
-function testAlbumViewCountIsNotEmpty() {
-    var Mainloop = imports.mainloop;
-    const View = imports.view;
-    const Widgets = imports.widgets;
-    let albumView = getAlbumView();
-    // Wait for albums to load, run mainloop
-    albumView.connect("album-art-updated", Lang.bind(this, function(){
-        //FIXME: Here we try to quit the mainloop for each album
-        //this causes exceptions and should be handled correctly
-        try {
-            Mainloop.quit('testMainloop');
-        } catch(Exception) {}
-    }));
-    Mainloop.run('testMainloop');
-    // Loaded, ready to go
-
-    // Check that no more than 50 and no less than 0 albums were loaded
-    if (!(albumView._offset > 0 && albumView._offset < 51))
-        fail('albumView._offset="'+albumView._offset +'"')
-
-    // The album has title and artist displayed (not null values)
-    let firstAlbumIter = albumView._model.get_iter_first()[1];
-    let firstAlbumPath = albumView._model.get_path(firstAlbumIter);
-    let album = albumView._model.get_value(firstAlbumIter, 2);
-    let artist = albumView._model.get_value(firstAlbumIter, 3);
-    log("  First album is '"+album+"' by '"+artist+"'")
-    assertNotNull(album)
-    assertNotNull(artist)
-
-    // Select first album
-    let albumWidget = albumView._albumWidget;
-    albumWidget.connect("loaded", Lang.bind(this, function(){
-        Mainloop.quit('testMainloop');
-    }));
-    Mainloop.idle_add(function() {
-        albumView.view.emit('item-activated', "0", firstAlbumPath);
-    })
-    Mainloop.run('testMainloop');
-    // Album view loaded
-
-    // Make sure that the same artist and album are displayed
-    let artist2 = albumWidget.ui.get_object("artist_label").label;
-    assertEquals(artist, artist2)
-    let album2 = albumWidget.ui.get_object("title_label").label;
-    assertEquals(album, album2)
-
-    // Make sure that year is either ---- or more that 1000 (at least)
-    let year = albumWidget.ui.get_object("released_label_info").label;
-    if (year != '----')
-        assertTrue(year > 1000)
-
-    // Wait for tracks to be added
-    albumWidget.connect('track-added', Lang.bind(this, function(){
-        Mainloop.quit('testMainloop');
-    }))
-    Mainloop.run('testMainloop');
-
-    // FIXME: wait for all tracks to be added, for now operate on the first one
-    let model = albumWidget.model;
-    let iter = model.get_iter_first()[1];
-    let title = model.get_value(iter, 0);
-    assertNotNull(title)
-    assertEquals(title, model.get_value(iter, 5).get_title())
-    log("  First track is '"+title+"'")
-
-    // Buttons are disabled
-    let player = albumWidget.player;
-    assertFalse(player.prevBtn.get_sensitive())
-    assertFalse(player.playBtn.get_sensitive())
-    assertFalse(player.nextBtn.get_sensitive())
-
-    // Artist and track labels are empty
-    assertEquals(player.artistLabel.get_label(), "")
-    assertEquals(player.titleLabel.get_label(), "")
-
-    // Progress scale is not initialized (undefined range)
-    assertEquals(player.progressScale.range, undefined)
-
-    // Duration labels are set to "00:00"
-    assertEquals(player.songTotalTimeLabel.get_label(), "00:00")
-    assertEquals(player.songPlaybackTimeLabel.get_label(), "00:00")
-
-    // Select the first song and remember its markup
-    let firstTrackIter = albumWidget.model.get_iter_first()[1];
-    let firstTrackMarkup = albumWidget.model.get_value(firstTrackIter, 0);
-    let firstTrackPath = albumWidget.model.get_path(firstTrackIter);
-    albumWidget.view.emit("item-activated", "0", firstTrackPath);
-
-    // Buttons become enabled
-    assertTrue(player.prevBtn.get_sensitive())
-    assertTrue(player.playBtn.get_sensitive())
-    assertTrue(player.nextBtn.get_sensitive())
-
-    // Scale value is set to 0
-    assertEquals(player.progressScale.get_value(), 0)
-
-    // Track markup is updated
-    let newTrackMarkup = albumWidget.model.get_value(firstTrackIter, 0);
-    assertEquals(newTrackMarkup, "<b>" + firstTrackMarkup + "</b>");
-
-    // Nowplaying icon is displayed for this track
-    assertTrue(albumWidget.model.get_value(firstTrackIter, 3))
-
-    // Artist and track labels are updated
-    assertEquals(player.artistLabel.get_label(), artist)
-    assertEquals(player.titleLabel.get_label(), title)
-
-    // Other tracks don't contain <b> or <span> and don't display now playing icon
-    let tracksIter = firstTrackIter.copy();
-    while(albumWidget.model.iter_next(tracksIter)) {
-        let trackMarkup = albumWidget.model.get_value(tracksIter, 0);
-        assertTrue(trackMarkup.indexOf("<b>") == -1)
-        assertTrue(trackMarkup.indexOf("<span>") == -1)
-        assertFalse(albumWidget.model.get_value(tracksIter, 3))
-    }
-}
-
 gjstestRun();
-
diff --git a/tests/tests_albumPlayback.js b/tests/tests_albumPlayback.js
new file mode 100644
index 0000000..5420b91
--- /dev/null
+++ b/tests/tests_albumPlayback.js
@@ -0,0 +1,158 @@
+// application/javascript;version=1.8
+if (!('assertEquals' in this)) { /* allow running this test standalone */
+    imports.lang.copyPublicProperties(imports.jsUnit, this);
+    gjstestRun = function() { return imports.jsUnit.gjstestRun(window); };
+}
+
+imports.searchPath.unshift('..');
+imports.searchPath.unshift('../src');
+imports.searchPath.unshift('../libgd');
+imports.searchPath.unshift('../data');
+const Gio = imports.gi.Gio;
+const Gtk = imports.gi.Gtk;
+const Gdk = imports.gi.Gdk;
+const Lang = imports.lang;
+
+
+function registerResources() {
+    let resource = Gio.Resource.load('../data/gnome-music.gresource');
+    resource._register();
+
+    let cssFile = Gio.File.new_for_uri('resource:///org/gnome/music/application.css');
+    let provider = new Gtk.CssProvider();
+    provider.load_from_file(cssFile);
+    Gtk.init(null, 0);
+    Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),
+                                             provider,
+                                             Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
+}
+
+function getAlbumView() {
+    registerResources();
+
+    const AlbumView = imports.view.Albums;
+    const Toolbar = imports.toolbar;
+    const Player = imports.player;
+    let toolbar = new Toolbar.Toolbar();
+    let player = new Player.Player();
+    return new AlbumView(toolbar, player);
+}
+
+function testAlbumViewPlayback() {
+    var Mainloop = imports.mainloop;
+    const View = imports.view;
+    const Widgets = imports.widgets;
+    let albumView = getAlbumView();
+    // Wait for albums to load, run mainloop
+    albumView.connect("album-art-updated", Lang.bind(this, function(){
+        //FIXME: Here we try to quit the mainloop for each album
+        //this causes exceptions and should be handled correctly
+        try {
+            Mainloop.quit('testMainloop');
+        } catch(Exception) {}
+    }));
+    Mainloop.run('testMainloop');
+    // Loaded, ready to go
+
+    // Check that no more than 50 and no less than 0 albums were loaded
+    if (!(albumView._offset > 0 && albumView._offset < 51))
+        fail('albumView._offset="'+albumView._offset +'"')
+
+    // The album has title and artist displayed (not null values)
+    let firstAlbumIter = albumView._model.get_iter_first()[1];
+    let firstAlbumPath = albumView._model.get_path(firstAlbumIter);
+    let album = albumView._model.get_value(firstAlbumIter, 2);
+    let artist = albumView._model.get_value(firstAlbumIter, 3);
+    log("  First album is '"+album+"' by '"+artist+"'")
+    assertNotNull(album)
+    assertNotNull(artist)
+
+    // Select first album
+    let albumWidget = albumView._albumWidget;
+    albumWidget.connect("loaded", Lang.bind(this, function(){
+        Mainloop.quit('testMainloop');
+    }));
+    Mainloop.idle_add(function() {
+        albumView.view.emit('item-activated', "0", firstAlbumPath);
+    })
+    Mainloop.run('testMainloop');
+    // Album view loaded
+
+    // Make sure that the same artist and album are displayed
+    let artist2 = albumWidget.ui.get_object("artist_label").label;
+    assertEquals(artist, artist2)
+    let album2 = albumWidget.ui.get_object("title_label").label;
+    assertEquals(album, album2)
+
+    // Make sure that year is either ---- or more that 1000 (at least)
+    let year = albumWidget.ui.get_object("released_label_info").label;
+    if (year != '----')
+        assertTrue(year > 1000)
+
+    // Wait for tracks to be added
+    albumWidget.connect('track-added', Lang.bind(this, function(){
+        Mainloop.quit('testMainloop');
+    }))
+    Mainloop.run('testMainloop');
+
+    // FIXME: wait for all tracks to be added, for now operate on the first one
+    let model = albumWidget.model;
+    let iter = model.get_iter_first()[1];
+    let title = model.get_value(iter, 0);
+    assertNotNull(title);
+    assertEquals(title, model.get_value(iter, 5).get_title())
+    log("  First track is '"+title+"'")
+
+    // Buttons are disabled
+    let player = albumWidget.player;
+    assertFalse(player.prevBtn.get_sensitive())
+    assertFalse(player.playBtn.get_sensitive())
+    assertFalse(player.nextBtn.get_sensitive())
+
+    // Artist and track labels are empty
+    assertEquals(player.artistLabel.get_label(), "")
+    assertEquals(player.titleLabel.get_label(), "")
+
+    // Progress scale is not initialized (undefined range)
+    assertEquals(player.progressScale.range, undefined)
+
+    // Duration labels are set to "00:00"
+    assertEquals(player.songTotalTimeLabel.get_label(), "00:00")
+    assertEquals(player.songPlaybackTimeLabel.get_label(), "00:00")
+
+    // Select the first song and remember its markup
+    let firstTrackIter = albumWidget.model.get_iter_first()[1];
+    let firstTrackMarkup = albumWidget.model.get_value(firstTrackIter, 0);
+    let firstTrackPath = albumWidget.model.get_path(firstTrackIter);
+    albumWidget.view.emit("item-activated", "0", firstTrackPath);
+
+    // Buttons become enabled
+    assertTrue(player.prevBtn.get_sensitive())
+    assertTrue(player.playBtn.get_sensitive())
+    assertTrue(player.nextBtn.get_sensitive())
+
+    // Scale value is set to 0
+    assertEquals(player.progressScale.get_value(), 0)
+
+    // Track markup is updated
+    let newTrackMarkup = albumWidget.model.get_value(firstTrackIter, 0);
+    assertEquals(newTrackMarkup, "<b>" + firstTrackMarkup + "</b>");
+
+    // Nowplaying icon is displayed for this track
+    assertTrue(albumWidget.model.get_value(firstTrackIter, 3))
+
+    // Artist and track labels are updated
+    assertEquals(player.artistLabel.get_label(), artist)
+    assertEquals(player.titleLabel.get_label(), title)
+
+    // Other tracks don't contain <b> or <span> and don't display now playing icon
+    let tracksIter = firstTrackIter.copy();
+    while(albumWidget.model.iter_next(tracksIter)) {
+        let trackMarkup = albumWidget.model.get_value(tracksIter, 0);
+        assertTrue(trackMarkup.indexOf("<b>") == -1)
+        assertTrue(trackMarkup.indexOf("<span>") == -1)
+        assertFalse(albumWidget.model.get_value(tracksIter, 3))
+    }
+}
+
+gjstestRun();
diff --git a/tests/tests_artistsPlayback.js b/tests/tests_artistsPlayback.js
new file mode 100644
index 0000000..4eebb71
--- /dev/null
+++ b/tests/tests_artistsPlayback.js
@@ -0,0 +1,146 @@
+// application/javascript;version=1.8
+if (!('assertEquals' in this)) { /* allow running this test standalone */
+    imports.lang.copyPublicProperties(imports.jsUnit, this);
+    gjstestRun = function() { return imports.jsUnit.gjstestRun(window); };
+}
+
+imports.searchPath.unshift('..');
+imports.searchPath.unshift('../src');
+imports.searchPath.unshift('../libgd');
+imports.searchPath.unshift('../data');
+const Gio = imports.gi.Gio;
+const Gtk = imports.gi.Gtk;
+const Gdk = imports.gi.Gdk;
+const Lang = imports.lang;
+
+
+function registerResources() {
+    let resource = Gio.Resource.load('../data/gnome-music.gresource');
+    resource._register();
+
+    let cssFile = Gio.File.new_for_uri('resource:///org/gnome/music/application.css');
+    let provider = new Gtk.CssProvider();
+    provider.load_from_file(cssFile);
+    Gtk.init(null, 0);
+    Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),
+                                             provider,
+                                             Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
+}
+
+function getArtistView() {
+    registerResources();
+
+    const ArtistView = imports.view.Artists;
+    const Toolbar = imports.toolbar;
+    const Player = imports.player;
+    let toolbar = new Toolbar.Toolbar();
+    let player = new Player.Player();
+    return new ArtistView(toolbar, player);
+}
+
+function testArtistsViewPlayback() {
+    var Mainloop = imports.mainloop;
+    const View = imports.view;
+    const Widgets = imports.widgets;
+    let artistView = getArtistView();
+
+    artistView.connect("artist-added", Lang.bind(this, function(){
+        //FIXME: Here we try to quit the mainloop for each album
+        //this causes exceptions and should be handled correctly
+        try {
+            Mainloop.quit('testMainloop');
+        } catch(Exception) {}
+    }));
+    Mainloop.run('testMainloop');
+    // Loaded, ready to go
+
+    // Check that no more than 50 and no less than 0 artists were loaded
+    if (!(artistView._offset > 0 && artistView._offset < 51))
+        fail('artistView._offset="'+artistView._offset +'"')
+
+    // The album has title and artist displayed (not null values)
+    let firstArtistIter = artistView._model.get_iter_first()[1];
+    let firstArtistPath = artistView._model.get_path(firstArtistIter);
+    let artist = artistView._model.get_value(firstArtistIter, 0);
+    log("  First artist is '"+artist+"'")
+    assertNotNull(artist)
+
+    // Select first artist
+    artistView.view.emit('item-activated', "0", firstArtistPath);
+    let artistAlbumsWidget = artistView.artistAlbums;
+    assertTrue(artistAlbumsWidget.widgets.length > 0);
+
+    // Verify album title
+    let artistAlbumWidget = artistAlbumsWidget.widgets[0];
+    let albumTitle = artistAlbumWidget.album.get_title();
+    assertNotNull(albumTitle);
+    log("  First album is '" + albumTitle + "'")
+    assertEquals(artistAlbumWidget.ui.get_object("title").get_label(), albumTitle);
+
+    // Wait for all tracks to be added
+    artistAlbumWidget.connect("tracks-loaded", Lang.bind(this, function(){
+        Mainloop.quit('testMainloop1');
+    }));
+    Mainloop.run('testMainloop1');
+    assertTrue(artistAlbumWidget.tracks.length > 0);
+    let firstTrack = artistAlbumWidget.tracks[0];
+    let trackTitle = firstTrack.get_title();
+    log("  First track is '"+trackTitle+"'")
+
+    let player = artistAlbumWidget.player;
+    assertFalse(player.prevBtn.get_sensitive())
+    assertFalse(player.playBtn.get_sensitive())
+    assertFalse(player.nextBtn.get_sensitive())
+
+    // Artist and track labels are empty
+    assertEquals(player.artistLabel.get_label(), "")
+    assertEquals(player.titleLabel.get_label(), "")
+
+    // Progress scale is not initialized (undefined range)
+    assertEquals(player.progressScale.range, undefined)
+
+    // Duration labels are set to "00:00"
+    assertEquals(player.songTotalTimeLabel.get_label(), "00:00")
+    assertEquals(player.songPlaybackTimeLabel.get_label(), "00:00")
+
+    // Select the first song and remember its markup
+    let model = artistAlbumWidget.model;
+    let firstTrackIter = firstTrack.songWidget.iter;
+    let firstTrackMarkup = model.get_value(firstTrackIter, 0);
+    // Get songwidget and click on title
+    firstTrack.songWidget.emit("button-release-event", null)
+
+    // Wait for track to be played
+
+
+    // Buttons become enabled
+    assertTrue(player.prevBtn.get_sensitive())
+    assertTrue(player.playBtn.get_sensitive())
+    assertTrue(player.nextBtn.get_sensitive())
+
+    // Scale value is set to 0
+    assertEquals(player.progressScale.get_value(), 0)
+
+    // Track markup is updated
+    let newTrackMarkup = firstTrack.songWidget.title.get_label();
+    assertEquals(newTrackMarkup, "<b>" + firstTrackMarkup + "</b>");
+
+    // Nowplaying icon is displayed for this track
+    assertTrue(firstTrack.songWidget.nowPlayingSign.get_visible())
+
+    // Artist and track labels are updated
+    assertEquals(player.artistLabel.get_label(), artist)
+    assertEquals(player.titleLabel.get_label(), trackTitle)
+
+    // Other tracks don't contain <b> or <span> and don't display now playing icon
+    let tracksIter = firstTrackIter.copy();
+    while(model.iter_next(tracksIter)) {
+        let track = model.get_value(tracksIter, 5);
+        let trackMarkup = track.songWidget.title.get_label();
+        assertTrue(trackMarkup.indexOf("<b>") == -1)
+        assertTrue(trackMarkup.indexOf("grey") == -1)
+        assertFalse(track.songWidget.nowPlayingSign.get_visible())
+    }
+}
+
+gjstestRun();


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]