summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2019-06-07 14:11:29 +0200
committerPatrick Steinhardt <ps@pks.im>2019-06-07 14:23:49 +0200
commit394951ad4c09c7bd08c5cb1bc8bc48f67d8024b9 (patch)
tree04266ba98f3796d12ce5c5580e9f4e7d0924ffdb
parente50d138e898dd034161663873f75716086266f86 (diff)
downloadlibgit2-394951ad4c09c7bd08c5cb1bc8bc48f67d8024b9.tar.gz
tests: allow for simple data-driven tests
Right now, we're not able to use data-driven tests at all. E.g. given a set of tests which we'd like to repeat with different test data, one has to hand-write any outer loop that iterates over the test data and then call each of the test functions. Next to being bothersome, this also has the downside that error reporting is quite lacking, as one never knows which test data actually produced failures. So let's implement the ability to re-run complete test modules with changing test data. To retain backwards compatibility and enable trivial addition of new runs with changed test data, we simply extend clar's generate.py. Instead of scanning for a single `_initialize` function, each test module may now implement multiple `_initialize_foo` functions. The generated test harness will then run all test functions for each of the provided initializer functions, making it possible to provide different test data inside of each of the initializer functions. Example: ``` void test_git_example__initialize_with_nonbare_repo(void) { g_repo = cl_git_sandbox_init("testrepo"); } void test_git_example__initialize_with_bare_repo(void) { g_repo = cl_git_sandbox_init("testrepo.git"); } void test_git_example__cleanup(void) { cl_git_sandbox_cleanup(); } void test_git_example__test1(void) { test1(); } void test_git_example__test2(void) { test2(); } ``` Executing this test module will cause the following output: ``` $ ./libgit2_clar -sgit::example git::example (with nonbare repo).. git::example (with bare repo).. ```
-rw-r--r--tests/generate.py43
1 files changed, 29 insertions, 14 deletions
diff --git a/tests/generate.py b/tests/generate.py
index 0a94d4952..572a57f86 100644
--- a/tests/generate.py
+++ b/tests/generate.py
@@ -24,8 +24,8 @@ class Module(object):
def render(self):
out = "\n".join("extern %s;" % cb['declaration'] for cb in self.module.callbacks) + "\n"
- if self.module.initialize:
- out += "extern %s;\n" % self.module.initialize['declaration']
+ for initializer in self.module.initializers:
+ out += "extern %s;\n" % initializer['declaration']
if self.module.cleanup:
out += "extern %s;\n" % self.module.cleanup['declaration']
@@ -41,7 +41,19 @@ class Module(object):
class InfoTemplate(Template):
def render(self):
- return Template(
+ templates = []
+
+ initializers = self.module.initializers
+ if len(initializers) == 0:
+ initializers = [ None ]
+
+ for initializer in initializers:
+ name = self.module.clean_name()
+ if initializer and initializer['short_name'].startswith('initialize_'):
+ variant = initializer['short_name'][len('initialize_'):]
+ name += " (%s)" % variant.replace('_', ' ')
+
+ template = Template(
r"""
{
"${clean_name}",
@@ -49,14 +61,17 @@ class Module(object):
${cleanup},
${cb_ptr}, ${cb_count}, ${enabled}
}"""
- ).substitute(
- clean_name = self.module.clean_name(),
- initialize = self._render_callback(self.module.initialize),
- cleanup = self._render_callback(self.module.cleanup),
- cb_ptr = "_clar_cb_%s" % self.module.name,
- cb_count = len(self.module.callbacks),
- enabled = int(self.module.enabled)
- )
+ ).substitute(
+ clean_name = name,
+ initialize = self._render_callback(initializer),
+ cleanup = self._render_callback(self.module.cleanup),
+ cb_ptr = "_clar_cb_%s" % self.module.name,
+ cb_count = len(self.module.callbacks),
+ enabled = int(self.module.enabled)
+ )
+ templates.append(template)
+
+ return ','.join(templates)
def __init__(self, name):
self.name = name
@@ -86,7 +101,7 @@ class Module(object):
regex = re.compile(TEST_FUNC_REGEX % self.name, re.MULTILINE)
self.callbacks = []
- self.initialize = None
+ self.initializers = []
self.cleanup = None
for (declaration, symbol, short_name) in regex.findall(contents):
@@ -96,8 +111,8 @@ class Module(object):
"symbol" : symbol
}
- if short_name == 'initialize':
- self.initialize = data
+ if short_name.startswith('initialize'):
+ self.initializers.append(data)
elif short_name == 'cleanup':
self.cleanup = data
else: