echonest: test different methods to fetch songs

This commit is contained in:
Thomas Scholtes 2014-12-02 11:19:47 +01:00
parent f4fdd66b81
commit 575740f5a5
2 changed files with 107 additions and 28 deletions

3
.gitignore vendored
View file

@ -7,6 +7,7 @@
.tox
.coverage
.idea
.ackrc
# file patterns
@ -32,4 +33,6 @@ beets.egg-info/*
build/*
docs/_build/*
man
htmlcov/*
.noseids
*.egg

View file

@ -13,9 +13,10 @@
# included in all copies or substantial portions of the Software.
import os.path
from mock import Mock, patch
from _common import unittest
from _common import unittest, RSRC
from helper import TestHelper
from beets.library import Item
@ -30,6 +31,8 @@ class EchonestCliTest(unittest.TestCase, TestHelper):
self.setup_beets()
self.load_plugins('echonest')
# Prevent 'beet echonest' from writing files
self.config['import']['write'] = False
def tearDown(self):
self.teardown_beets()
@ -38,49 +41,122 @@ class EchonestCliTest(unittest.TestCase, TestHelper):
@patch.object(Item, 'write')
@patch('pyechonest.song.profile')
@patch('pyechonest.track.track_from_id')
def test_store_data(self, echonest_track, echonest_profile, item_write):
profile = Mock(
artist_name='artist',
title='title',
id='echonestid',
audio_summary={
'duration': 10,
'energy': 0.5,
'liveness': 0.5,
'loudness': 0.5,
'speechiness': 0.5,
'danceability': 0.5,
'tempo': 120,
'key': 2,
'mode': 0
},
)
def test_mbid_profile(self, echonest_track, echonest_profile, item_write):
"""Retrieve song info from MusicBrainz ID."""
item = self.add_item(title='title', length=10, mb_trackid='1')
profile = self.profile(item, energy=0.5, tempo=120, key=2, mode=0)
echonest_profile.return_value = [profile]
echonest_track.return_value = Mock(song_id='echonestid')
item = Item(
mb_trackid='01234',
artist='artist',
title='title',
length=10,
)
item.add(self.lib)
self.assertNotIn('danceability', item)
self.assertNotIn('energy', item)
self.assertNotEqual(item['bpm'], 120)
self.assertNotIn('initialkey', item)
self.run_command('echonest')
item.load()
self.assertEqual(item['danceability'], 0.5)
self.assertEqual(item['liveness'], 0.5)
self.assertEqual(item['energy'], 0.5)
self.assertEqual(item['bpm'], 120)
self.assertEqual(item['initial_key'], 'C#m')
@patch('pyechonest.track.track_from_id')
@patch('pyechonest.song.search')
def test_song_search(self, echonest_search, echonest_track):
item = self.add_item(title='title', length=10, mb_trackid='1')
echonest_search.return_value = [self.profile(item, energy=0.1)]
echonest_track.return_value = []
self.run_command('echonest')
item.load()
self.assertEqual(item['energy'], 0.1)
self.assertEqual(1, echonest_track.call_count)
@patch('pyechonest.song.profile')
@patch('pyechonest.song.search')
@patch('pyechonest.track.track_from_filename')
def test_analyze(self, echonest_track, echonest_search, echonest_profile):
item = self.add_item(title='title', length=10,
path=os.path.join(RSRC, 'min.mp3'))
echonest_search.return_value = []
echonest_profile.return_value = [self.profile(item, energy=0.2)]
echonest_track.return_value = self.track(item)
self.run_command('echonest')
item.load()
self.assertEqual(item['energy'], 0.2)
self.assertEqual(1, echonest_search.call_count)
self.assertEqual(item.path,
echonest_track.call_args[1]['filename'])
@patch('pyechonest.song.profile')
@patch('pyechonest.song.search')
@patch('pyechonest.track.track_from_filename')
def test_analyze_convert(self, echonest_track, echonest_search,
echonest_profile):
item = self.add_item(title='title', length=10, format='FLAC',
path=os.path.join(RSRC, 'min.flac'))
echonest_search.return_value = []
echonest_profile.return_value = [self.profile(item, energy=0.2)]
echonest_track.return_value = self.track(item)
self.run_command('echonest')
item.load()
self.assertEqual(item['energy'], 0.2)
# Assert uploaded file was converted
self.assertNotEqual(item.path,
echonest_track.call_args[1]['filename'])
@patch('pyechonest.song.profile')
@patch('pyechonest.song.search')
@patch('pyechonest.track.track_from_filename')
# Force truncation
@patch('beetsplug.echonest.UPLOAD_MAX_SIZE', 0)
def test_analyze_truncate(self, echonest_track, echonest_search,
echonest_profile):
item = self.add_item(title='title', length=10, format='MP3',
path=os.path.join(RSRC, 'min.mp3'))
echonest_search.return_value = []
echonest_profile.return_value = [self.profile(item, energy=0.2)]
echonest_track.return_value = self.track(item)
self.run_command('echonest')
item.load()
self.assertEqual(item['energy'], 0.2)
self.assertEqual(1, echonest_search.call_count)
self.assertNotEqual(item.path,
echonest_track.call_args[1]['filename'])
def test_custom_field_range_query(self):
item = Item(liveness=2.2)
item.add(self.lib)
item = self.lib.items('liveness:2.2..3').get()
self.assertEqual(item['liveness'], 2.2)
def profile(self, item, **values):
"""Return a mock Echonest Profile object.
The fields are set to match the item. Additional values are
passed to the `audio_summary` dictionary of the profile.
"""
audio_summary = {'duration': item.length}
audio_summary.update(values)
return Mock(
artist_name=item.artist,
title=item.title,
id='echonestid',
audio_summary=audio_summary
)
def track(self, item, **values):
"""Return a mock Echonest Track object.
"""
values.update(
duration=item.length,
artist_name=item.artist,
title=item.title,
song_id='echonestid',
)
return Mock(**values)
def suite():
return unittest.TestLoader().loadTestsFromName(__name__)