aboutsummaryrefslogtreecommitdiffstats
path: root/test/__init__.py
blob: 1cb1ad0495e7c094f15bc75b4bd749c6d854471c (plain) (blame)
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# -*- coding: utf-8 -*-  IGNORE:C0111
from __future__ import absolute_import, print_function, unicode_literals
import logging
import yamlish
import yaml
import tempfile
import textwrap

INPUT = 1
OUTPUT = 2

#logging.basicConfig(level=logging.DEBUG)

def _generate_test_name(source):
    """
    Clean up human-friendly test name into a method name.
    """
    out = source.replace(' ', '_').replace(':', '').replace(',', '').lower()
    return "test_%s" % out


def _create_input_test(test_src, tested_function, options=None):
    """
    Decorate tested function to be used as a method for TestCase.
    """
    def do_test_expected(self):
        """
        Execute a test by calling a tested_function on test_src data.
        """
        self.maxDiff = None

        got = ""
        if 'error' in test_src:
            self.assertRaises(test_src['error'], tested_function,
                              test_src['in'], options)
        else:
            want = test_src['out']
            got = tested_function(test_src['in'], options)
            logging.debug('got = type %s', type(got))
            logging.debug("test_src['out'] = %s", unicode(test_src['out']))
            self.assertEqual(got, want, """Result matches
            expected = %s

            observed = %s
            """ % (want, got))

    return do_test_expected


def _create_output_test(test_src, tested_function, options=None):
    """
    Decorate tested function to be used as a method for TestCase.
    """
    def do_test_expected(self):
        """
        Execute a test by calling a tested_function on test_src data.
        """
        self.maxDiff = None

        # We currently don't throw any exceptions in Writer, so this
        # this is always false
        if 'error' in test_src:
            self.assertRaises(test_src['error'], yamlish.dumps, test_src['in'], options)                
        else:
            logging.debug("out:\n%s", textwrap.dedent(test_src['out']))
            want = yaml.load(textwrap.dedent(test_src['out']))
            logging.debug("want:\n%s", want)
            with tempfile.NamedTemporaryFile() as test_file:
                tested_function(test_src['in'], test_file)
                test_file.seek(0)
                got_str = test_file.read()
                logging.debug("got_str = %s", got_str)
                got = yaml.load(got_str)
                self.assertEqual(got, want, "Result matches")

    return do_test_expected


def generate_testsuite(test_data, test_case_shell, test_fce, direction=INPUT,
                         options=None):
    """
    Generate tests from the test data, class to build upon and function
    to use for testing.
    """
    for in_test in test_data:
        if ('skip' in in_test) and in_test['skip']:
            logging.debug("test %s skipped!", in_test['name'])
            continue
        name = _generate_test_name(in_test['name'])
        if direction == INPUT:
            test_method = _create_input_test(in_test, test_fce, options=options)
        elif direction == OUTPUT:
            test_method = _create_output_test(in_test, test_fce, options=options)
        test_method.__name__ = str('test_%s' % name)
        setattr(test_case_shell, test_method.__name__, test_method)