|
|
|
"""Tests for the content plugins."""
|
|
|
|
|
|
|
|
# pylint: disable=too-few-public-methods
|
|
|
|
|
|
|
|
import glob
|
|
|
|
import os
|
|
|
|
import unittest
|
|
|
|
import yaml
|
|
|
|
|
|
|
|
from pkg_resources import resource_filename
|
|
|
|
|
|
|
|
from patacrep import content, files
|
|
|
|
from patacrep.content import song, section, setcounter, songsection, tex
|
|
|
|
from patacrep.songbook import prepare_songbook
|
|
|
|
|
|
|
|
from .. import logging_reduced
|
|
|
|
from .. import dynamic # pylint: disable=unused-import
|
|
|
|
|
|
|
|
class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest):
|
|
|
|
"""Test of the content plugins.
|
|
|
|
|
|
|
|
For any given `foo.source`, it parses the content as a yaml "content"
|
|
|
|
argument of a .yaml file.
|
|
|
|
It controls that the generated file list is equal to the one in `foo.control`.
|
|
|
|
"""
|
|
|
|
|
|
|
|
maxDiff = None
|
|
|
|
config = None
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def _iter_testmethods(cls):
|
|
|
|
"""Iterate over dynamically generated test methods"""
|
|
|
|
for source in sorted(glob.glob(os.path.join(
|
|
|
|
os.path.dirname(__file__),
|
|
|
|
'*.source',
|
|
|
|
))):
|
|
|
|
base = source[:-len(".source")]
|
|
|
|
yield (
|
|
|
|
"test_content_{}".format(os.path.basename(base)),
|
|
|
|
cls._create_content_test(base),
|
|
|
|
)
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def _create_content_test(cls, base):
|
|
|
|
"""Return a function that tests that `base.source` produces the correct file list"""
|
|
|
|
|
|
|
|
def test_content(self):
|
|
|
|
"""Test that `base.source` produces the correct file list"""
|
|
|
|
sourcename = "{}.source".format(base)
|
|
|
|
with open(sourcename, mode="r", encoding="utf8") as sourcefile:
|
|
|
|
sbcontent = yaml.load(sourcefile)
|
|
|
|
|
|
|
|
outputdir = os.path.dirname(base)
|
|
|
|
config = cls._generate_config(sbcontent, outputdir, base)
|
|
|
|
|
|
|
|
with logging_reduced('patacrep.content.song'):
|
|
|
|
expandedlist = content.process_content(sbcontent, config)
|
|
|
|
sourcelist = [cls._clean_path(elem) for elem in expandedlist]
|
|
|
|
|
|
|
|
controlname = "{}.control".format(base)
|
|
|
|
if not os.path.exists(controlname):
|
|
|
|
raise Exception("Missing control:" + str(sourcelist).replace("'", '"'))
|
|
|
|
with open(controlname, mode="r", encoding="utf8") as controlfile:
|
|
|
|
controllist = [
|
|
|
|
elem.replace("@TEST_FOLDER@", files.path2posix(resource_filename(__name__, "")))
|
|
|
|
for elem in yaml.load(controlfile)
|
|
|
|
]
|
|
|
|
|
|
|
|
self.assertEqual(controllist, sourcelist)
|
|
|
|
|
|
|
|
test_content.__doc__ = (
|
|
|
|
"Test that '{base}.source' produces the correct file list"""
|
|
|
|
).format(base=os.path.basename(base))
|
|
|
|
return test_content
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def _clean_path(cls, elem):
|
|
|
|
"""Shorten the path relative to the `songs` directory"""
|
|
|
|
|
|
|
|
latex_command_classes = (
|
|
|
|
section.Section,
|
|
|
|
songsection.SongSection,
|
|
|
|
setcounter.CounterSetter,
|
|
|
|
)
|
|
|
|
if isinstance(elem, latex_command_classes):
|
|
|
|
return elem.render(None)[1:]
|
|
|
|
|
|
|
|
elif isinstance(elem, song.SongRenderer):
|
|
|
|
songpath = os.path.join(os.path.dirname(__file__), 'datadir', 'songs')
|
|
|
|
return files.path2posix(files.relpath(elem.song.fullpath, songpath))
|
|
|
|
|
|
|
|
elif isinstance(elem, tex.LaTeX):
|
|
|
|
return files.path2posix(elem.filename)
|
|
|
|
|
|
|
|
else:
|
|
|
|
return str(elem.file_entry())
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def _generate_config(cls, sbcontent, outputdir, base):
|
|
|
|
"""Generate the config to process the content"""
|
|
|
|
|
|
|
|
# Load the default songbook config
|
|
|
|
config = prepare_songbook(
|
|
|
|
{'book':{'datadir':['datadir', 'datadir_zippedcontent']}, 'content': sbcontent},
|
|
|
|
outputdir,
|
|
|
|
base,
|
|
|
|
outputdir
|
|
|
|
)
|
|
|
|
|
|
|
|
return config
|