aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xsrc/scripts/pyolian/testgenerator.py145
-rw-r--r--src/tests/automated/automated.template137
2 files changed, 282 insertions, 0 deletions
diff --git a/src/scripts/pyolian/testgenerator.py b/src/scripts/pyolian/testgenerator.py
new file mode 100755
index 0000000000..d6c4f3afc7
--- /dev/null
+++ b/src/scripts/pyolian/testgenerator.py
@@ -0,0 +1,145 @@
+#!/usr/bin/env python3
+# encoding: utf-8
+
+import os
+import datetime
+import eolian
+import pyratemp
+from copy import copy
+
+# Use .eo files from the source tree (not the installed ones)
+script_path = os.path.dirname(os.path.realpath(__file__))
+root_path = os.path.abspath(os.path.join(script_path, '..', '..', '..'))
+SCAN_FOLDER = os.path.join(root_path, 'src', 'lib')
+
+# create main eolian state
+eolian_db = eolian.Eolian_State()
+if not isinstance(eolian_db, eolian.Eolian_State):
+ raise(RuntimeError('Eolian, failed to create Eolian state'))
+
+# eolian source tree scan
+if not eolian_db.directory_add(SCAN_FOLDER):
+ raise(RuntimeError('Eolian, failed to scan source directory'))
+
+# Parse all known eo files
+if not eolian_db.all_eot_files_parse():
+ raise(RuntimeError('Eolian, failed to parse all EOT files'))
+
+if not eolian_db.all_eo_files_parse():
+ raise(RuntimeError('Eolian, failed to parse all EO files'))
+
+# cleanup the database on exit
+import atexit
+def cleanup_db():
+ global eolian_db
+ del eolian_db
+atexit.register(cleanup_db)
+
+
+def zeronull_parameters_get(parameters, cparam=[]):
+ return [ cparams[i] if i < len(cparams) else 'NULL' if param.type.is_ptr else "0" for i, param in enumerate(parameters) ]
+
+def load_file(filename):
+ if os.path.isfile(filename):
+ with open(filename, "r") as f:
+ return f.read()
+ return None
+
+"""
+It will find methods and functions with owned return and without other params
+"""
+def custom_loads(cls, filedir):
+ cls.custom = load_file(os.path.join(filedir, "custom.c"))
+ cls.init = load_file(os.path.join(filedir, "init.c"))
+ cls.shutdown = load_file(os.path.join(filedir, "shutdown.c"))
+
+ for func in cls.methods:
+ func.init = load_file(os.path.join(filedir, func.name, "init.c"))
+ func.shutdown = load_file(os.path.join(filedir, func.name, "shutdown.c"))
+ func.arg_init = load_file(os.path.join(filedir, func.name, "arg_init.c")) or "/* Zero/NULL args init */"
+ func.arg_shutdown = load_file(os.path.join(filedir, func.name, "arg_shutdown.c")) or "/* Zero/NULL args shutdown */"
+
+ for func in cls.properties:
+ if func.getter_scope:
+ func.init = load_file(os.path.join(filedir, '{}_get'.format(func.name), "init.c"))
+ func.shutdown = load_file(os.path.join(filedir, '{}_get'.format(func.name), "shutdown.c"))
+ func.arg_get_init = load_file(os.path.join(filedir, '{}_get'.format(func.name), "arg_init.c")) or "/* Zero/NULL args getter init */"
+ func.arg_get_shutdown = load_file(os.path.join(filedir, '{}_set'.format(func.name), "arg_shutdown.c")) or "/* Zero/NULL args getter shutdown */"
+
+ if func.setter_scope:
+ func.init = load_file(os.path.join(filedir, '{}_set'.format(func.name), "init.c"))
+ func.shutdown = load_file(os.path.join(filedir, '{}_set'.format(func.name), "shutdown.c"))
+ func.arg_set_init = load_file(os.path.join(filedir, '{}_set'.format(func.name), "arg_init.c")) or "/* Zero/NULL args setter init */"
+ func.arg_set_shutdown = load_file(os.path.join(filedir, '{}_set'.format(func.name), "arg_shutdown.c")) or "/* Zero/NULL args setter shutdown */"
+
+class Template(pyratemp.Template):
+
+ def __init__(self, filename, encoding='utf-8',
+ loader_class=pyratemp.LoaderFile,
+ parser_class=pyratemp.Parser,
+ renderer_class=pyratemp.Renderer,
+ eval_class=pyratemp.EvalPseudoSandbox):
+
+ global_ctx = {}
+ global_ctx.update({
+ # Template info
+ 'date': datetime.datetime.now(),
+ 'template_file': os.path.basename(filename),
+ })
+
+ self.template_filename = filename
+ pyratemp.Template.__init__(self, filename=filename, encoding=encoding,
+ data=global_ctx,
+ loader_class=loader_class,
+ parser_class=parser_class,
+ renderer_class=renderer_class,
+ eval_class=eval_class)
+
+ def render(self, cls, filename=None, verbose=True):
+ # Build the context for the template
+ ctx = {}
+ ctx['cls'] = cls
+
+ if verbose and filename:
+ print("rendering: {} => {}".format(
+ self.template_filename, filename))
+
+ # render with the augmented context
+ output = self(**ctx)
+
+ if filename is not None:
+ # write to file
+ with open(filename, "w") as f:
+ f.write(output)
+ else:
+ # or print to stdout
+ print(output)
+
+
+if __name__ == '__main__':
+ import argparse
+
+ parser = argparse.ArgumentParser(description='Pyolian search owned functions.')
+ parser.add_argument('testcase', help='The TestCase Name to use. (REQUIRED)')
+ parser.add_argument('classname', help='The Class Name to use. (REQUIRED)')
+
+ args = parser.parse_args()
+
+ testdir = os.path.join(root_path, 'src', 'tests', args.testcase)
+ template = os.path.join(testdir, "{}.template".format(args.testcase))
+ if not os.path.isfile(template):
+ template = os.path.join(testdir, "automated.template")
+
+ clsname = args.classname
+
+ cls = eolian_db.class_by_name_get(clsname)
+ if cls:
+ custom_loads(cls, os.path.join(testdir, cls.c_name.lower()))
+ filename = os.path.join(testdir, "{}_test.c".format(cls.c_name.lower()))
+
+ t = Template(template)
+ t.render(cls, filename)
+ else:
+ print("Did not find Eolian Class: {}".format(clsname))
+
+
diff --git a/src/tests/automated/automated.template b/src/tests/automated/automated.template
new file mode 100644
index 0000000000..ef13addbdd
--- /dev/null
+++ b/src/tests/automated/automated.template
@@ -0,0 +1,137 @@
+<!--(macro init)-->
+ /** init **/
+ fail_if(!eina_init(), "ERROR: Cannot init Eina!\n");
+ fail_if(!ecore_init(), "ERROR: Cannot init Ecore!\n");
+ fail_if(!efl_object_init(), "ERROR: Cannot init EO!\n");
+ fail_if(!eio_init(), "ERROR: Cannot init EIO!\n");
+
+ <!--(if exists("mfunc") and mfunc!= None)-->
+ ${mfunc}$
+ <!--(elif exists("mcls") and mcls!= None)-->
+ ${mcls}$
+ <!--(else)-->
+ Eo *obj = efl_add(${cls.c_name}$, NULL);
+ fail_if(!obj, "ERROR: Cannot init ${cls.full_name}$!\n");
+ <!--(end)-->
+<!--(end)-->
+<!--(macro shutdown)-->
+ /** shutdown **/
+ <!--(if exists("mfunc") and mfunc != None)-->
+ ${mfunc}$
+ <!--(elif exists("mcls") and mcls != None)-->
+ ${mcls}$
+ <!--(end)-->
+ efl_unref(obj);
+ eio_shutdown();
+ ecore_shutdown();
+ eina_shutdown();
+<!--(end)-->
+<!--(macro args_declaration)-->
+ <!--(for arg in args)-->
+ ${arg.type.c_type_return}$ arg_${arg.name}$ = <!--(if arg.type.is_ptr or arg.type.type == arg.type.type.CLASS or arg.type.builtin_type == arg.type.builtin_type.STRING)-->NULL<!--(elif arg.type.builtin_type == arg.type.builtin_type.ANY_VALUE)-->EINA_VALUE_EMPTY<!--(else)-->0<!--(end)-->;
+ <!--(end)-->
+<!--(end)-->
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "${cls.c_name.lower()}$_suite.h"
+#include "../efl_check.h"
+
+static const Efl_Test_Case etc[] = {
+ { "${cls.c_name}$", automated_test_${cls.c_name.lower()}$},
+ { NULL, NULL }
+};
+<!--(if cls.custom != None)-->
+
+${cls.custom}$
+<!--(end)-->
+
+START_TEST(automated_test_${cls.c_name.lower()}$_smoke)
+{
+${init(mcls=cls.init)}$
+${shutdown(mcls=cls.shutdown)}$
+}
+END_TEST
+
+<!--(for func in cls.methods)-->
+START_TEST(automated_test_${func.full_c_method_name}$)
+{
+${args_declaration(args=func.parameters)}$${init(mcls=cls.init,mfunc=func.init)}$
+${func.arg_init}$
+ <!--(if func.method_return_type)-->${func.method_return_type.c_type_return}$ r = <!--(end)-->${func.full_c_method_name}$(obj<!--(for arg in func.parameters)-->, arg_${arg.name}$<!--(end)-->);
+${func.arg_shutdown}$
+${shutdown(mcls=cls.shutdown,mfunc=func.shutdown)}$
+}
+END_TEST
+
+<!--(end)-->
+
+<!--(for func in cls.properties)-->
+ <!--(if func.getter_scope)-->
+START_TEST(automated_test_${func.full_c_getter_name}$)
+{
+ <!--(if len(list(func.getter_values)) > 1)-->
+${args_declaration(args=func.getter_values)}$
+ <!--(end)-->
+${args_declaration(args=func.getter_keys)}$${init(mcls=cls.init,mfunc=func.init)}$
+${func.arg_get_init}$
+ <!--(if len(list(func.getter_values)) == 1)-->
+ ${list(func.getter_values)[0].type.c_type_return}$ r = ${func.full_c_getter_name}$(obj<!--(for arg in func.getter_keys)-->arg_${arg.name}$<!--(end)-->);
+ <!--(else)-->
+ ${func.full_c_getter_name}$(obj<!--(for arg in func.getter_values)-->, &arg_${arg.name}$<!--(end)--><!--(for arg in func.getter_keys)-->, arg_${arg.name}$<!--(end)-->);
+ <!--(end)-->
+${func.arg_get_shutdown}$
+${shutdown(mcustom=cls.shutdown,mfunc=func.shutdown)}$
+}
+END_TEST
+
+ <!--(end)-->
+ <!--(if func.setter_scope)-->
+START_TEST(automated_test_${func.full_c_setter_name}$)
+{
+${args_declaration(args=func.setter_keys)}$${args_declaration(args=func.setter_values)}$${init(mcls=cls.init,mfunc=func.init)}$
+${func.arg_set_init}$
+ ${func.full_c_getter_name}$(obj<!--(for arg in func.setter_values)-->, &arg_${arg.name}$<!--(end)--><!--(for arg in func.setter_keys)-->, arg_${arg.name}$<!--(end)-->);
+${func.arg_set_shutdown}$
+${shutdown(mcls=cls.shutdown,mfunc=func.shutdown)}$
+}
+END_TEST
+
+ <!--(end)-->
+<!--(end)-->
+void automated_test_${cls.c_name.lower()}$(TCase *tc)
+{
+ tcase_add_test(tc, automated_test_${cls.c_name.lower()}$_smoke);
+
+ <!--(for func in cls.methods)-->
+ tcase_add_test(tc, automated_test_${func.full_c_method_name}$);
+ <!--(end)-->
+ <!--(for func in cls.properties)-->
+ <!--(if func.getter_scope)-->
+ tcase_add_test(tc, automated_test_${func.full_c_getter_name}$);
+ <!--(end)-->
+ <!--(if func.setter_scope)-->
+ tcase_add_test(tc, automated_test_${func.full_c_setter_name}$);
+ <!--(end)-->
+ <!--(end)-->
+}
+
+int
+main(int argc, char **argv)
+{
+ int failed_count;
+
+ if (!_efl_test_option_disp(argc, argv, etc))
+ return 0;
+
+#ifdef NEED_RUN_IN_TREE
+ putenv("EFL_RUN_IN_TREE=1");
+#endif
+
+ failed_count = _efl_suite_build_and_run(argc - 1, (const char **)argv + 1,
+ "${cls.c_name}$", etc);
+
+ return (failed_count == 0) ? 0 : 255;
+}
+