diff --git a/test/test_chordpro/test_parser.py b/test/test_chordpro/test_parser.py index 2bdd15aa..8f857156 100644 --- a/test/test_chordpro/test_parser.py +++ b/test/test_chordpro/test_parser.py @@ -16,22 +16,15 @@ LANGUAGES = { 'sgc': 'chordpro', } -class TestParsingRendering(unittest.TestCase): - """Test parsing and rendering""" +class FileTestMeta(type): + """Metaclass that creates on-the-fly test function according to files. - maxDiff = None + See the :class:`FileTest` documentation for more information. + """ - def test_all(self): - """Test of chorpro parser, and several renderers. + def __init__(cls, name, bases, nmspc): + super().__init__(name, bases, nmspc) - For any given `foo.source`, it is parsed as a chordpro file, and - should be rendered as `foo.sgc` with the chordpro renderer, and - `foo.tex` with the latex renderer. - """ - config = DEFAULT_CONFIG.copy() - config.update({ - 'encoding': 'utf8', - }) for source in sorted(glob.glob(os.path.join( os.path.dirname(__file__), '*.source', @@ -41,15 +34,47 @@ class TestParsingRendering(unittest.TestCase): destname = "{}.{}".format(base, dest) if not os.path.exists(destname): continue - with open(destname, 'r', encoding='utf8') as expectfile: - chordproname = "{}.source".format(base) - config['filename'] = chordproname - with disable_logging(): - with self.subTest(base=os.path.basename(base), format=dest): - self.assertMultiLineEqual( - ChordproSong(None, chordproname, config).render( - output=chordproname, - output_format=LANGUAGES[dest], - ).strip(), - expectfile.read().strip(), - ) + setattr( + cls, + "test_{}_{}".format(os.path.basename(base), dest), + cls._create_test(base, dest), + ) + + @staticmethod + def _create_test(base, dest): + """Return a function testing that `base` compilation in `dest` format. + """ + + def test_parse_render(self): + """Test that `base` is correctly parsed and rendered.""" + if base is None or dest is None: + return + destname = "{}.{}".format(base, dest) + with open(destname, 'r', encoding='utf8') as expectfile: + chordproname = "{}.source".format(base) + with disable_logging(): + self.assertMultiLineEqual( + ChordproSong(None, chordproname, DEFAULT_CONFIG).render( + output=chordproname, + output_format=LANGUAGES[dest], + ).strip(), + expectfile.read().strip(), + ) + + test_parse_render.__doc__ = ( + "Test that '{base}' is correctly parsed and rendererd into '{format}' format." + ).format(base=os.path.basename(base), format=dest) + return test_parse_render + +class FileTest(unittest.TestCase, metaclass=FileTestMeta): + """Test of chorpro parser, and several renderers. + + For any given `foo.source`, it is parsed as a chordpro file, and should be + rendered as `foo.sgc` with the chordpro renderer, and `foo.tex` with the + latex renderer. + + This class does nothing by itself, but its metaclass populates it with test + methods testing parser and renderers. + """ + + maxDiff = None