summaryrefslogtreecommitdiff
path: root/tests/test_spec.py
blob: a379f24f0bc57e2d897528ae43aa30493f9f873e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# coding: utf-8

"""
Creates a unittest.TestCase for the tests defined in the mustache spec.

We did not call this file something like "test_spec.py" to avoid matching
nosetests's default regular expression "(?:^|[\b_\./-])[Tt]est".
This allows us to exclude the spec test cases by default when running
nosetests.  To include the spec tests, one can use the following option,
for example--

    nosetests -i spec

"""

import glob
import os.path
import unittest
import yaml

from pystache.renderer import Renderer


def code_constructor(loader, node):
    value = loader.construct_mapping(node)
    return eval(value['python'], {})

yaml.add_constructor(u'!code', code_constructor)

specs = os.path.join(os.path.dirname(__file__), '..', 'ext', 'spec', 'specs')
specs = glob.glob(os.path.join(specs, '*.yml'))

class MustacheSpec(unittest.TestCase):
    pass

def buildTest(testData, spec_filename):

    name = testData['name']
    description  = testData['desc']

    test_name = "%s (%s)" % (name, spec_filename)

    def test(self):
        template = testData['template']
        partials = testData.has_key('partials') and testData['partials'] or {}
        expected = testData['expected']
        data     = testData['data']

        renderer = Renderer(partials=partials)
        actual = renderer.render(template, data)
        actual = actual.encode('utf-8')

        message = """%s

  Template: \"""%s\"""

  Expected: %s
  Actual:   %s

  Expected: \"""%s\"""
  Actual:   \"""%s\"""
  """ % (description, template, repr(expected), repr(actual), expected, actual)

        self.assertEquals(actual, expected, message)

    # The name must begin with "test" for nosetests test discovery to work.
    test.__name__ = 'test: "%s"' % test_name

    return test

for spec in specs:
    file_name  = os.path.basename(spec)

    for test in yaml.load(open(spec))['tests']:
        test = buildTest(test, file_name)
        setattr(MustacheSpec, test.__name__, test)
        # Prevent this variable from being interpreted as another test.
        del(test)

if __name__ == '__main__':
    unittest.main()