Add tests for encoders

and some refactoring
This commit is contained in:
Ritiek Malhotra
2020-03-17 17:58:44 +05:30
parent 29005f24ed
commit dae76a0abb
12 changed files with 210 additions and 21 deletions

View File

@@ -1,13 +1,15 @@
import subprocess import subprocess
import os import os
from logzero import logger as log from logzero import logger as log
from spotdl.encode import EncoderBase from spotdl.encode import EncoderBase
from spotdl.encode.exceptions import EncoderNotFoundError from spotdl.encode.exceptions import EncoderNotFoundError
from spotdl.encode.exceptions import AvconvNotFoundError from spotdl.encode.exceptions import AvconvNotFoundError
class EncoderAvconv(EncoderBase): class EncoderAvconv(EncoderBase):
def __init__(self, encoder_path="avconv"): def __init__(self, encoder_path="avconv"):
print("Using EncoderAvconv is deprecated and will be removed" print("Using EncoderAvconv is deprecated and will be removed",
"in future versions. Use EncoderFFmpeg instead.") "in future versions. Use EncoderFFmpeg instead.")
encoder_path = encoder_path encoder_path = encoder_path
_loglevel = "-loglevel 0" _loglevel = "-loglevel 0"

View File

@@ -0,0 +1,58 @@
from spotdl.encode import EncoderBase
from spotdl.encode.exceptions import AvconvNotFoundError
from spotdl.encode.encoders import EncoderAvconv
import pytest
class TestEncoderAvconv:
def test_subclass(self):
assert issubclass(EncoderAvconv, EncoderBase)
def test_avconv_not_found_error(self):
with pytest.raises(AvconvNotFoundError):
EncoderAvconv(encoder_path="/a/nonexistent/path")
class TestEncodingDefaults:
def encode_command(input_file, output_file):
command = [
'avconv', '-y', '-loglevel', '0',
'-i', input_file,
'-ab', '192k',
output_file,
]
return command
@pytest.mark.parametrize("files, expected_command", [
(("test.m4a", "test.mp3"), encode_command("test.m4a", "test.mp3")),
(("abc.m4a", "cba.webm"), encode_command("abc.m4a", "cba.webm")),
(("bla bla.m4a", "ble ble.m4a"), encode_command("bla bla.m4a", "ble ble.m4a")),
(("😛.m4a", "• tongue.flac"), encode_command("😛.m4a", "• tongue.flac")),
])
def test_generate_encode_command(self, files, expected_command):
encoder = EncoderAvconv()
assert encoder._generate_encode_command(*files) == expected_command
class TestEncodingInDebugMode:
def debug_encode_command(input_file, output_file):
command = [
'avconv', '-y', '-loglevel', 'debug',
'-i', input_file,
'-ab', '192k',
output_file,
]
return command
@pytest.mark.parametrize("files, expected_command", [
(("test.m4a", "test.mp3"), debug_encode_command("test.m4a", "test.mp3")),
(("abc.m4a", "cba.webm"), debug_encode_command("abc.m4a", "cba.webm")),
(("bla bla.m4a", "ble ble.m4a"), debug_encode_command("bla bla.m4a", "ble ble.m4a")),
(("😛.m4a", "• tongue.flac"), debug_encode_command("😛.m4a", "• tongue.flac")),
])
def test_generate_encode_command_with_debug(self, files, expected_command):
encoder = EncoderAvconv()
encoder.set_debuglog()
assert encoder._generate_encode_command(*files) == expected_command

View File

@@ -1,5 +1,5 @@
from spotdl.encode import EncoderBase from spotdl.encode import EncoderBase
# from spotdl.encode import exceptions from spotdl.encode.exceptions import FFmpegNotFoundError
from spotdl.encode.encoders import EncoderFFmpeg from spotdl.encode.encoders import EncoderFFmpeg
import pytest import pytest
@@ -9,6 +9,10 @@ class TestEncoderFFmpeg:
def test_subclass(self): def test_subclass(self):
assert issubclass(EncoderFFmpeg, EncoderBase) assert issubclass(EncoderFFmpeg, EncoderBase)
def test_ffmpeg_not_found_error(self):
with pytest.raises(FFmpegNotFoundError):
EncoderFFmpeg(encoder_path="/a/nonexistent/path")
class TestEncodingDefaults: class TestEncodingDefaults:
def m4a_to_mp3_encoder(input_file, output_file): def m4a_to_mp3_encoder(input_file, output_file):

View File

@@ -1,8 +1,11 @@
from spotdl.encode import EncoderBase from spotdl.encode import EncoderBase
from spotdl.encode.exceptions import EncoderNotFoundError
import pytest import pytest
def test_abstract_base_class_encoderbase():
class TestAbstractBaseClass:
def test_error_abstract_base_class_encoderbase(self):
encoder_path = "ffmpeg" encoder_path = "ffmpeg"
_loglevel = "-hide_banner -nostats -v panic" _loglevel = "-hide_banner -nostats -v panic"
_additional_arguments = ["-b:a", "192k", "-vn"] _additional_arguments = ["-b:a", "192k", "-vn"]
@@ -11,3 +14,88 @@ def test_abstract_base_class_encoderbase():
# This abstract base class must be inherited from # This abstract base class must be inherited from
# for instantiation # for instantiation
EncoderBase(encoder_path, _loglevel, _additional_arguments) EncoderBase(encoder_path, _loglevel, _additional_arguments)
def test_inherit_abstract_base_class_encoderbase(self):
class EncoderKid(EncoderBase):
def __init__(self, encoder_path, _loglevel, _additional_arguments):
super().__init__(encoder_path, _loglevel, _additional_arguments)
def _generate_encode_command(self):
pass
def _generate_encoding_arguments(self):
pass
def get_encoding(self):
pass
def re_encode(self):
pass
def set_argument(self):
pass
def set_debuglog(self):
pass
encoder_path = "ffmpeg"
_loglevel = "-hide_banner -nostats -v panic"
_additional_arguments = ["-b:a", "192k", "-vn"]
EncoderKid(encoder_path, _loglevel, _additional_arguments)
class TestMethods:
class EncoderKid(EncoderBase):
def __init__(self, encoder_path, _loglevel, _additional_arguments):
super().__init__(encoder_path, _loglevel, _additional_arguments)
def _generate_encode_command(self, input_file, output_file):
pass
def _generate_encoding_arguments(self, input_encoding, output_encoding):
pass
def get_encoding(self, filename):
return super().get_encoding(filename)
def re_encode(self, input_encoding, output_encoding):
pass
def set_argument(self, argument):
super().set_argument(argument)
def set_debuglog(self):
pass
@pytest.fixture(scope="module")
def encoderkid(self):
encoder_path = "ffmpeg"
_loglevel = "-hide_banner -nostats -v panic"
_additional_arguments = []
encoderkid = self.EncoderKid(encoder_path, _loglevel, _additional_arguments)
return encoderkid
def test_set_argument(self, encoderkid):
encoderkid.set_argument("-parameter argument")
assert encoderkid._additional_arguments == [
"-parameter",
"argument",
]
@pytest.mark.parametrize("filename, encoding", [
("example.m4a", "m4a"),
("exampley.mp3", "mp3"),
("test 123.webm", "webm"),
("flakey.flac", "flac"),
])
def test_get_encoding(self, encoderkid, filename, encoding):
assert encoderkid.get_encoding(filename) == encoding
def test_encoder_not_found_error(self):
with pytest.raises(EncoderNotFoundError):
self.EncoderKid("/a/nonexistent/path", "0", [])

View File

@@ -6,6 +6,9 @@ import pytest
class TestEncoderNotFoundSubclass: class TestEncoderNotFoundSubclass:
def test_encoder_not_found_subclass(self):
assert issubclass(FFmpegNotFoundError, Exception)
def test_ffmpeg_not_found_subclass(self): def test_ffmpeg_not_found_subclass(self):
assert issubclass(FFmpegNotFoundError, EncoderNotFoundError) assert issubclass(FFmpegNotFoundError, EncoderNotFoundError)

View File

@@ -6,7 +6,7 @@ from abc import abstractmethod
class LyricBase(ABC): class LyricBase(ABC):
@abstractmethod @abstractmethod
def __init__(self, artist, song): def __init__(self, artist, track):
pass pass
@abstractmethod @abstractmethod

View File

@@ -8,13 +8,13 @@ BASE_URL = "https://genius.com"
class Genius(LyricBase): class Genius(LyricBase):
def __init__(self, artist, song): def __init__(self, artist, track):
self.artist = artist self.artist = artist
self.song = song self.track = track
self.base_url = BASE_URL self.base_url = BASE_URL
def _guess_lyric_url(self): def _guess_lyric_url(self):
query = "/{} {} lyrics".format(self.artist, self.song) query = "/{} {} lyrics".format(self.artist, self.track)
query = query.replace(" ", "-") query = query.replace(" ", "-")
encoded_query = urllib.request.quote(query) encoded_query = urllib.request.quote(query)
lyric_url = self.base_url + encoded_query lyric_url = self.base_url + encoded_query
@@ -28,7 +28,7 @@ class Genius(LyricBase):
except urllib.request.HTTPError: except urllib.request.HTTPError:
raise LyricsNotFoundError( raise LyricsNotFoundError(
"Could not find lyrics for {} - {} at URL: {}".format( "Could not find lyrics for {} - {} at URL: {}".format(
self.artist, self.song, url self.artist, self.track, url
) )
) )
else: else:

View File

@@ -5,13 +5,13 @@ from spotdl.lyrics.exceptions import LyricsNotFoundError
class LyricWikia(LyricBase): class LyricWikia(LyricBase):
def __init__(self, artist, song): def __init__(self, artist, track):
self.artist = artist self.artist = artist
self.song = song self.track = track
def get_lyrics(self, linesep="\n", timeout=None): def get_lyrics(self, linesep="\n", timeout=None):
try: try:
lyrics = lyricwikia.get_lyrics(self.artist, self.song, linesep, timeout) lyrics = lyricwikia.get_lyrics(self.artist, self.track, linesep, timeout)
except lyricwikia.LyricsNotFound as e: except lyricwikia.LyricsNotFound as e:
raise LyricsNotFoundError(e.args[0]) raise LyricsNotFoundError(e.args[0])
else: else:

View File

@@ -12,7 +12,7 @@ class TestGenius:
@pytest.fixture(scope="module") @pytest.fixture(scope="module")
def track(self): def track(self):
return Genius("artist", "song") return Genius("artist", "track")
def test_base_url(self, track): def test_base_url(self, track):
assert track.base_url == "https://genius.com" assert track.base_url == "https://genius.com"

View File

@@ -0,0 +1,5 @@
from spotdl.lyrics.exceptions import LyricsNotFoundError
def test_lyrics_not_found_subclass():
assert issubclass(LyricsNotFoundError, Exception)

View File

@@ -0,0 +1,29 @@
from spotdl.lyrics import LyricBase
import pytest
class TestAbstractBaseClass:
def test_error_abstract_base_class_lyricbase(self):
artist = "awesome artist"
track = "amazing track"
with pytest.raises(TypeError):
# This abstract base class must be inherited from
# for instantiation
LyricBase(artist, track)
def test_inherit_abstract_base_class_encoderbase(self):
class LyricKid(LyricBase):
def __init__(self, artist, track):
super().__init__(artist, track)
def get_lyrics(self):
pass
artist = "awesome artist"
track = "amazing track"
LyricKid(artist, track)