Engine for LaTeX songbooks http://www.patacrep.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

122 lines
4.1 KiB

"""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 `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:
raise Exception(elem)
@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'}, 'content': sbcontent},
outputdir,
base,
outputdir
)
# Load the plugins
config['_content_plugins'] = files.load_plugins(
datadirs=config['_datadir'],
root_modules=['content'],
keyword='CONTENT_PLUGINS',
)
config['_song_plugins'] = files.load_plugins(
datadirs=config['_datadir'],
root_modules=['songs'],
keyword='SONG_RENDERERS',
)['tsg']
return config