Renderable Templates

When you need to be able to create specific types of files for your tool (e.g. ini/config files, scripts, etc) in a parameterized way, use renderable templates.

Note

The Renderable, RenderedFile, and SimpleFile classes all use the Jinja2 templating system. See its documentation for any specific questions pertaining to the templates themselves.

class RenderedFile(filename='')[source]

A file that will be rendered to disk.

This class represents a file that, upon rendering, will appear on disk. By default, any attribute (instance or class) will appear in the context of the template. E.g., having an attribute of self.foo will make the foo variable exist within the template.

This class provides a “content” variable and should serve as an area of the template that can be appended to on a per-test basis. Use the add_content() method in order to add more content to the template at the time of render. This allows for content to be added over a period of time either as subsequent calls in the same test, through the setUp, or setUp calls in multiple classes (via inheritance).

Subclasses can override the get_context() method in order to alter the context (variable scope) provided to the template on render. See the get_context() method’s documentation for more details.

While this class can be used by itself (note that the instances attributes template and template_dirs must be set before rendering!) the intended use is to subclass this class and define class-level attributes for template and template_dirs. This makes it so that a base class can point to a common template directory (through the template_dirs attribute) and all subclasses of it can supply the template attribute in order to determine which template to choose.

Parameters:filename (str) – the full path to where the file should exist on disk when rendered

Examples:

# tests/environment.py
# assume that the templates directory is:
# tests/templates
from granite.environment import RenderedFile
from granite.testcase import TestCase, TempProjectMixin


class MyRenderedFile(RenderedFile):
    template_dirs = [
        os.path.join(os.path.dirname(__file__), 'templates')]


# assume that tests/templates/template.py exists
# and looks something like this:
print('Hello!')
print(
    '''
     {{ content }}
    '''
)
print('This test is currently running: {{ id }}')

class PythonScript(MyRenderedFile):
    template = 'template.py'


class MyTestCase(TempProjectMixin, TestCase):
    def setUp(self):
        super(MyTestCase, self).setUp()
        self.script = PythonScript(
            os.path.join(self.temp_project.path, 'my_file.py'))
        self.script.add_content('My name is Aaron')

    def test_the_thing(self):
        # setting the `id` attribute provides the `id`
        # context variable in the template
        self.script.id = self.id()
        self.script.render()
        with open(self.script.full_name) as f:
            self.assertEqual(
                f.read(),
                """
                print('Hello!')
                print(
                    '''
                    My name is Aaron
                    '''
                )
                print('This test is currently running: test_the_thing')
                """
            )
ADD_NEWLINE = True

Determines whether a newline should be added at the end of the file or not. When generating C code to be compiled by the ARM/GCC compiler, this makes the compiler happy. Defaults to True. Set to False to disable.

DISABLE_ESCAPING = False

By default, the value in the “content” template variable is escaped. This makes adding content for script/language files (via add_content()) much easier to read and maintain as script/language files usually interpret the special esacped characters differently. Set this attribute to True in order to disable this functionality.

WRITE_MODE = 'w'

When rendering the file, defaults to non-binary mode. Set this to ‘wb’ or something similar for different behavior when writing the rendered contents to a file.

add_content(content)[source]

Adds a string to the “content” variable available to the template.

Parameters:content (str or List[str]) – a single string or a list of strings to add to the content variable.
filename = ''

The name of the rendered file (without the path)

full_name = ''

the full path to the file

get_context()[source]

Gets the context needed for rendering the file associated with this instance.

A context is simply the template’s scope of variables and functions.

Returns:
the variable names and their values; the scope to appear in
the template
Return type:dict
path = ''

The path to this rendered file (without the filename itself)

render()[source]

Renders the template and writes the contents to disk to this instance’s filename.