summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLarry Lira <larry@expertisesolutions.com.br>2018-09-04 20:47:23 -0300
committerLauro Moura <lauromoura@expertisesolutions.com.br>2019-10-24 21:16:23 -0300
commit33893ffc74909de4b6357f0b05d10354661401df (patch)
treed2b18d12596e3c919cc1c49f77453b48e4938d12
parentca0052f9cf4f4e862a89b57c907d7f311aa99694 (diff)
eolian: Added Eolian test generatordevs/lauromoura/tcautomated-squashed
The test generator allows templates to be used to generate boilerplate for unit tests Some automated tests were giving different results regarding @cref Slices
-rw-r--r--src/scripts/pyolian/pyratemp.py2
-rw-r--r--src/scripts/testgen/README.md146
-rw-r--r--src/scripts/testgen/__init__.py0
-rw-r--r--src/scripts/testgen/ekeys.py272
-rw-r--r--src/scripts/testgen/name_helpers.py92
-rw-r--r--src/scripts/testgen/suitegen.py291
-rwxr-xr-xsrc/scripts/testgen/testgen.py125
-rw-r--r--src/scripts/testgen/testgenerator.c.template187
-rw-r--r--src/scripts/testgen/testgenerator.cs.template113
-rw-r--r--src/tests/automated/ecore_audio_custom.c3
-rw-r--r--src/tests/automated/ecore_audio_init.c2
-rw-r--r--src/tests/automated/ecore_audio_out/input_attach/arg_init.c1
-rw-r--r--src/tests/automated/ecore_audio_out/input_detach/arg_init.c1
-rw-r--r--src/tests/automated/ecore_audio_out_wasapi/init.c3
-rw-r--r--src/tests/automated/ecore_audio_out_wasapi/shutdown.c3
-rw-r--r--src/tests/automated/ector_custom.c3
-rw-r--r--src/tests/automated/ector_init.c1
-rw-r--r--src/tests/automated/ector_renderer_cairo_shape/init.c2
-rw-r--r--src/tests/automated/ector_shutdown.c1
-rw-r--r--src/tests/automated/edje_custom.c1
-rw-r--r--src/tests/automated/edje_init.c2
-rw-r--r--src/tests/automated/edje_shutdown.c2
-rw-r--r--src/tests/automated/efl_canvas_layout_part/init.c9
-rw-r--r--src/tests/automated/efl_canvas_layout_part_box/init.c9
-rw-r--r--src/tests/automated/efl_canvas_layout_part_external/init.c8
-rw-r--r--src/tests/automated/efl_canvas_layout_part_swallow/init.c8
-rw-r--r--src/tests/automated/efl_canvas_layout_part_table/init.c8
-rw-r--r--src/tests/automated/efl_canvas_layout_part_text/init.c8
-rw-r--r--src/tests/automated/efl_canvas_video/init.c2
-rw-r--r--src/tests/automated/efl_loop/begin/init.c9
-rw-r--r--src/tests/automated/efl_loop/begin/shutdown.c3
-rw-r--r--src/tests/automated/efl_loop/custom.c5
-rw-r--r--src/tests/automated/efl_loop/timeout/arg_init.c1
-rw-r--r--src/tests/automated/efl_text_markup_util/init.c1
-rw-r--r--src/tests/automated/eio_custom.c1
-rw-r--r--src/tests/automated/eio_init.c1
-rw-r--r--src/tests/automated/eio_shutdown.c1
-rw-r--r--src/tests/automated/eldbus_init.c1
-rw-r--r--src/tests/automated/eldbus_shutdown.c1
-rw-r--r--src/tests/automated/emotion_custom.c2
-rw-r--r--src/tests/automated/emotion_init.c3
-rw-r--r--src/tests/automated/emotion_shutdown.c4
-rw-r--r--src/tests/automated/evas_custom.c1
43 files changed, 1339 insertions, 0 deletions
diff --git a/src/scripts/pyolian/pyratemp.py b/src/scripts/pyolian/pyratemp.py
index c28e260..1ddfb77 100644
--- a/src/scripts/pyolian/pyratemp.py
+++ b/src/scripts/pyolian/pyratemp.py
@@ -846,6 +846,8 @@ class EvalPseudoSandbox:
846 "complex" : builtins.complex, 846 "complex" : builtins.complex,
847 "dict" : builtins.dict, 847 "dict" : builtins.dict,
848 "enumerate" : builtins.enumerate, 848 "enumerate" : builtins.enumerate,
849 "filter" : builtins.filter,
850 "next" : builtins.next,
849 "float" : builtins.float, 851 "float" : builtins.float,
850 "int" : builtins.int, 852 "int" : builtins.int,
851 "list" : builtins.list, 853 "list" : builtins.list,
diff --git a/src/scripts/testgen/README.md b/src/scripts/testgen/README.md
new file mode 100644
index 0000000..4531f63
--- /dev/null
+++ b/src/scripts/testgen/README.md
@@ -0,0 +1,146 @@
1
2Testgen: Template-based Eolian tests generator
3===============================================================================
4
5Testgen is a Python Script using the Pyolian to generate tests rendering
6templates with custom files, this can be a easy way to expand the
7API test coveraged.
8
9Testgen can generate tests C and to other bingings languages only
10adding new language specialized templates.
11
12Installation
13============
14
15There is nothing to install to use the generator, everything is included in
16the efl source tree and it is intended to work directly inside the tree,
17usually at efl tests compilation time (make check).
18
19The only requirement is that **the source tree must be already built** (not
20installed) because pyolian search the eolian .so/.dll inside the source tree.
21
22If you built the efl tree in a custom location (fe, you build out-of-tree) you
23can tell pyolian where to find the built eolian .so files using the
24`EOLIAN_SO_DIR` environment variable.
25
26
27Command line usage
28==================
29
30The simplest way to use the generator is from the command line, using the
31`src/scripts/testgen/testgen.py` command, the `--help` option state:
32
33```
34usage: testgen.py [-h] testname suitename filename [eofiles [eofiles ...]]
35
36Eolian Test Generator.
37
38positional arguments:
39 testname The Test Name used to find custom and template files. (REQUIRED)
40 suitename The Suite Name used to find custom files. (REQUIRED)
41 filename Generated test file destination. (REQUIRED)
42 eofiles The Eolian Files to use.
43
44optional arguments:
45 -h, --help show this help message and exit
46```
47Use .c extension in <filename> to generate C tests or .cs to CSharp
48
49To test this generator in `src/scripts/testgen` you can run:
50```
51./testgen.py automated efl efl_automated_test.c efl_loop.eo
52```
53This will rendere the automated tests using files in `src/tests/automated` with
54suite name `efl_automated` and with Efl.Loop Class as Test Case
55`efl_automated_efl_loop_test`
56
57or run:
58```
59./testgen.py automated eio eio_automated_test.c eio_sentry.eo eio_model.eo
60```
61This will rendere with suite name `eio_automated` and with Eio.Sentry and
62Eio.Model Class as Test Cases `eio_automated_eio_sentry_test` and
63`eio_automated_eio_model_test`
64
65
66How customise a Generated Test
67==============================
68
69Testgen use the filesystem to find custom files if you need customise a test,
70add/write follow files in src/tests:
71
72 Suite custom files
73 * `src/test/<testname>/`
74 |-> <suitename>_custom.c #add include files, functions or structs
75 |-> <suitename>_init.c #add code in SUITE_INIT
76 |-> <suitename>_shutdown.c #add code in SUITE_SHUTDOWN
77
78 Class Test case custom files
79 * `src/test/<testname>/<class_name>/` #use lowercase and `_` separator
80 |-> custom.c #add include files, functions or structs
81 |-> init.c #add default way to create the object of this class
82 |-> shutdown.c #add default way to free the object
83
84Funtions Tests
85- Tests methodes custom files
86 * `src/test/<testname>/<class_name>/<method_name>`
87 |-> arg_init.c #initialize method arguments (arg_<argument_name>)
88 |-> init.c #add how to create the object (replace default)
89 |-> arg_shutdown.c #free arguments
90 |-> shutdown.c #add how to free the object (replace default)
91
92- Tests properties custom files
93 * `src/test/<testname>/<class_name>/<property_name>`
94 | -- Property Get --
95 |-> arg_get_init.c #initialize property get arguments (arg_<argument_name>)
96 |-> get_init.c #how to create the object (replace default)
97 |-> arg_get_shutdown.c #free arguments
98 |-> get_shutdown.c #how to free the object (replace default)
99 | -- Property Set --
100 |-> arg_set_init.c #initialize propety set arguments (arg_<argument_name>)
101 |-> set_init.c #how to create the object (replace default)
102 |-> arg_set_shutdown.c #free arguments
103 |-> set_shutdown.c #how to free the object (replace default)
104
105Event Tests
106- Tests Events custom files
107 * `src/test/<testname>/<class_name>/<event_name>/`
108 |-> init.cs #add how to initialize the objects
109 |-> custom.cs #add customizations in callback
110 |-> shutdown.cs #add shutdown or any method to call the event
111
112to make some custom files you only need a code using:
113 `parent` -> default name of parent object defined as `Eo *`
114 `obj` -> default name of current object
115 `arg_<name>` -> replace <name> with functions arguments name
116
117you can use custom.c (suite or class) to add specilized code, structs and callbacks
118
119-- Use `*.cs` to Emono/CSharp generated code --
120
121Some class or function test don't need a test in some Suite, you can disable test generated
122of it with a blank file as following:
123
124use lowercase and `_` as separator
125`src/test/<testname>/<class_name>` #don't generate test for <class_name>
126`src/test/<testname>/<class_name>/method_name` #don't generate test for <method_name>
127`src/test/<testname>/<class_name>/<property_name>` #don't generate test for this property
128`src/test/<testname>/<class_name>/<property_name>_get` #don't generate test for this property get
129`src/test/<testname>/<class_name>/<property_name>_set` #don't generate test for this property set
130
131
132Where to find more info
133=======================
134
135 * read the Pyolian README file in EFL scripts
136 * read the eolian.py file (it declare the full eolian API)
137 * read the generator.py file (it's super simple)
138 * read the original [pyratemp docs](https://www.simple-is-better.org/template/pyratemp.html)
139
140
141Note
142====
143
144This markdown file is mirrored in efl src tree (src/scripts/pyolian) and in
145phab wiki (phab.enlightenment.org/w/pyolian). Don't forget to update the other
146if you change one!
diff --git a/src/scripts/testgen/__init__.py b/src/scripts/testgen/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/scripts/testgen/__init__.py
diff --git a/src/scripts/testgen/ekeys.py b/src/scripts/testgen/ekeys.py
new file mode 100644
index 0000000..42d9889
--- /dev/null
+++ b/src/scripts/testgen/ekeys.py
@@ -0,0 +1,272 @@
1#!/usr/bin/env python3
2# encoding: utf-8
3from enum import IntEnum, IntFlag
4
5from testgen import name_helpers
6
7
8class Function_List_Type(IntFlag):
9 OWN = 1
10 IMPLEMENTS = 2 # Overrides
11 EXTENSIONS = 4 # Interfaces/Mixins
12 INHERITED = 8 # Inherited but not overriden methods and classes
13 INHERITS_FULL = 4 & 8
14
15
16class EKeys:
17 def __init__(self, ext):
18 self.ext = ext
19 self.dicttypes = {}
20 self.keywords = []
21 self.verbs = []
22 self.blacklist = ["efl_constructor"]
23 self.keyloads = ["init", "shutdown", "custom"]
24 self.implementsbl = ["construtor", "destructor", "finalize"]
25 self.funclist = Function_List_Type.OWN | Function_List_Type.IMPLEMENTS
26
27 def type_convert(self, eotype):
28 return eotype.name
29
30 def event_convert(self, event):
31 return event.c_macro
32
33 def print_arg(self, eoarg):
34 return "arg_{}".format(eoarg.name)
35
36 def format_name(self, func):
37 return self.name
38
39
40class EMonoKeys(EKeys):
41 def __init__(self, ext):
42 super().__init__(ext)
43 self.funclist = (
44 Function_List_Type.OWN
45 | Function_List_Type.IMPLEMENTS
46 | Function_List_Type.EXTENSIONS
47 )
48 self.dicttypes = {
49 "byte": "sbyte",
50 "llong": "long",
51 "int8": "sbyte",
52 "int16": "short",
53 "int32": "int",
54 "int64": "long",
55 "ssize": "long",
56 "ubyte": "byte",
57 "ullong": "ulong",
58 "uint8": "byte",
59 "uint16": "ushort",
60 "uint32": "uint",
61 "uint64": "ulong",
62 "size": "ulong",
63 "ptrdiff": "long",
64 "intptr": "System.IntPtr",
65 "uintptr": "System.IntPtr",
66 "void_ptr": "System.IntPtr",
67 "void": "System.IntPtr", # only if is out/inout
68 "Error": "Eina.Error",
69 "string": "System.String",
70 "mstring": "System.String",
71 "stringshare": "System.String",
72 "any_value": "Eina.Value",
73 "any_value_ptr": "Eina.Value"
74 # complex Types
75 ,
76 "list": "Eina.List",
77 "inlist": "Eina.Inlist",
78 "array": "Eina.Array",
79 "inarray": "Eina.Inarray",
80 "hash": "Eina.Hash",
81 "promise": "int",
82 "future": "int",
83 "iterator": "Eina.Iterator",
84 "accessor": "Eina.Accessor",
85 "strbuf": "Eina.Strbuf",
86 "Efl.Class": "System.Type",
87 "rw_slice": "Eina.RwSlice",
88 "slice": "Eina.Slice",
89 }
90
91 self.keywords = [
92 "delete",
93 "do",
94 "lock",
95 "event",
96 "in",
97 "object",
98 "interface",
99 "string",
100 "internal",
101 "fixed",
102 "base",
103 ]
104
105 self.verbs = [
106 "add",
107 "get",
108 "is",
109 "del",
110 "thaw",
111 "freeze",
112 "save",
113 "wait",
114 "eject",
115 "raise",
116 "lower",
117 "load",
118 "dup",
119 "reset",
120 "unload",
121 "close",
122 "set",
123 "interpolate",
124 "has",
125 "grab",
126 "check",
127 "find",
128 "ungrab",
129 "unset",
130 "clear",
131 "pop",
132 "new",
133 "peek",
134 "push",
135 "update",
136 "show",
137 "move",
138 "hide",
139 "calculate",
140 "resize",
141 "attach",
142 "pack",
143 "unpack",
144 "emit",
145 "call",
146 "append",
147 ]
148
149 self.blacklist = [
150 "efl_event_callback_array_priority_add",
151 "efl_event_callback_forwarder_priority_add",
152 "efl_player_position_get",
153 "efl_text_font_source",
154 "efl_ui_focus_manager_focus_get",
155 "efl_ui_widget_focus",
156 "efl_ui_text_password",
157 "elm_interface_scrollable_repeat_events",
158 "elm_wdg_item_del",
159 "elm_wdg_item_focus",
160 "elm_interface_scrollable_mirrored_set",
161 "evas_obj_table_mirrored",
162 "edje_obj_load_error_get",
163 "efl_ui_focus_user_parent_get",
164 "efl_canvas_object_scale", # duplicated signature
165 "efl_access_parent_get",
166 "efl_access_name",
167 "efl_access_root_get",
168 "efl_access_type_get",
169 "efl_access_role_get",
170 "efl_access_action_description",
171 "efl_access_image_description",
172 "efl_access_component_layer_get", # duplicated signature
173 "efl_access_component_alpha_get",
174 "efl_access_component_size_get",
175 "efl_ui_spin_button_loop_get",
176 "efl_ui_list_model_size_get",
177 "efl_ui_list_relayout_layout_do",
178 "efl_constructor",
179 ]
180
181 self.struct_blacklist = [
182 "Efl.Event_Description",
183 "Eina.Binbuf",
184 "Eina.Strbuf",
185 "Eina.Slice",
186 "Eina.Rw_Slice",
187 "Eina.Promise",
188 "Eina.Value",
189 "Eina.Value_Type",
190 "Eina.Future",
191 ]
192
193 def escape_keyword(self, key):
194 key = "kw_{}".format(key) if key in self.keywords else key
195 return "{}Add".format(key) if key == "Finalize" else key
196
197 def direction_get(self, param):
198 direction = param.direction
199
200 if direction == direction.INOUT:
201 return "ref"
202 elif direction != direction.IN:
203 if param.type.name in ("slice", "rw_slice"):
204 return "ref"
205 else:
206 return "out"
207 elif (direction == direction.IN) and param.type.is_ptr:
208 if param.type.typedecl and (
209 param.type.typedecl.type == param.type.typedecl.type.STRUCT
210 ):
211 return "ref" if param.type.name not in self.struct_blacklist else None
212
213 return None
214
215 def klass_name(self, eotype):
216 *namespaces, name = eotype.name.split(".")
217 namespaces = [self.escape_keyword(x.lower()) for x in namespaces]
218 is_interface = eotype.type == eotype.type.CLASS
219 k_name = ("I" if is_interface else "") + name
220 return ".".join(namespaces + [k_name])
221
222 def type_convert(self, eotype):
223 if eotype.type == eotype.type.VOID:
224 return "System.IntPtr"
225
226 new_type = self.dicttypes.get(
227 eotype.name, name_helpers.type_managed_name(eotype)
228 )
229 if new_type not in ("Eina.RwSlice", "Eina.Slice") and eotype.base_type:
230 # Stringshare is a special case where its C# type differs if inside or outside
231 # a container:
232 # - Non-contained stringshares are directly converted to strings.
233 # - Contained stringshares are kept as the container parameter as a tag to
234 # marshal the value correctly whem adding/removing items from the container.
235 if eotype.base_type.name == "stringshare":
236 base_type = "Eina.Stringshare"
237 else:
238 base_type = self.dicttypes.get(
239 eotype.base_type.name,
240 name_helpers.type_managed_name(eotype.base_type),
241 )
242 new_type = "{}<{}>".format(new_type, base_type)
243
244 return new_type
245
246 def event_convert(self, event):
247 return "{}Evt".format("".join([i.capitalize() for i in event.name.split(",")]))
248
249 def print_arg(self, eoarg):
250 r = super().print_arg(eoarg)
251 prefix = self.direction_get(eoarg) or None
252
253 return " ".join([prefix, r]) if prefix else r
254
255 def format_name(self, func):
256 names = func.comp.name.split("_")
257
258 if func.type == func.type.METHOD and names[-1] in self.verbs:
259 names.insert(0, names.pop())
260
261 fname = "".join([name.capitalize() for name in names])
262
263 if func.type == func.type.METHOD:
264 fname = self.escape_keyword(fname)
265
266 return fname
267
268
269def GetKey(ext):
270 if ext == ".cs":
271 return EMonoKeys(ext)
272 return EKeys(ext)
diff --git a/src/scripts/testgen/name_helpers.py b/src/scripts/testgen/name_helpers.py
new file mode 100644
index 0000000..e03ad23
--- /dev/null
+++ b/src/scripts/testgen/name_helpers.py
@@ -0,0 +1,92 @@
1#!/usr/bin/env python3
2# encoding: utf-8
3
4"""Helper module with naming rules for the C# binding."""
5
6import os
7import sys
8
9# Hackish way of detecting pyolian...
10script_path = os.path.dirname(os.path.realpath(__file__))
11
12if "EFL_DIR" in os.environ:
13 root_path = os.environ["EFL_DIR"]
14else:
15 root_path = os.path.abspath(os.path.join(script_path, "..", "..", ".."))
16
17sys.path.insert(0, os.path.join(root_path, "src", "scripts"))
18
19from pyolian import eolian
20
21
22def remove_underlines(name):
23 """Removes underlines from name"""
24 return name.replace("_", "")
25
26
27def managed_name(name):
28 """Replaces underlines and capitalize first letter of each word"""
29
30 words = name.split("_")
31 return "".join(word[0].upper() + word[1:] for word in words)
32
33
34def managed_namespaces(namespaces):
35 """Converts an eolian list of namespaces into the managed namespace"""
36 return ".".join(remove_underlines(nsp) for nsp in namespaces)
37
38
39def class_managed_name(cls):
40 """Gets the full managed name of the given eolian class"""
41 ret = managed_namespaces(cls.namespaces)
42
43 if ret:
44 ret += "."
45
46 if cls.type in (eolian.Eolian_Class_Type.INTERFACE, eolian.Eolian_Class_Type.MIXIN):
47 ret += "I"
48
49 ret += remove_underlines(cls.short_name)
50
51 if ret == "Efl.Class":
52 return "System.Type"
53
54 return ret
55
56
57def type_managed_name(type):
58 """Gets the full managed name of a given type."""
59 if type.type == eolian.Eolian_Type_Type.CLASS:
60 return class_managed_name(type.class_)
61
62 ret = managed_namespaces(type.namespaces)
63
64 if ret:
65 ret += "."
66
67 ret += remove_underlines(type.short_name)
68
69 return ret
70
71
72# Need to pass the class as it is not accessible from Event in Pyolian
73def event_args_managed_name(event, cls):
74 """Gets the full managed name of the event arguments struct"""
75 if event.type is None:
76 return "System.EventArgs"
77
78 ret = class_managed_name(cls)
79
80 return ret + managed_name(event.myname) + "Evt_Args"
81
82
83def event_managed_short_name(event):
84 """Gets the managed short name of an event"""
85
86 return managed_name(event.name.replace(",", "_")) + "Evt"
87
88
89def enum_field_managed_name(field):
90 """Gets the managed name of an Enum field"""
91
92 return managed_name(field.name)
diff --git a/src/scripts/testgen/suitegen.py b/src/scripts/testgen/suitegen.py
new file mode 100644
index 0000000..5551eab
--- /dev/null
+++ b/src/scripts/testgen/suitegen.py
@@ -0,0 +1,291 @@
1import itertools
2import os
3from pyolian.eolian import Eolian_Function_Type, Eolian_Class_Type, Eolian_Object_Scope
4from .ekeys import GetKey, Function_List_Type
5from pyolian import eolian
6
7from testgen import name_helpers
8
9
10class BaseItem:
11 def __init__(self, path, keys, prefix=""):
12 self.path = path
13 self.keys = keys
14 self.prefix = prefix
15
16 def __getattr__(self, attr):
17 if not attr.split("_")[-1] in self.keys.keyloads:
18 raise AttributeError("Error getting {}".format(attr))
19
20 filename = os.path.join(self.path, self.prefix + attr) + self.keys.ext
21 if os.path.isfile(filename):
22 with open(filename, "r") as f:
23 return f.read()
24 return None
25
26
27class ComItem(BaseItem):
28 def __init__(self, comp, path, keys):
29 super().__init__(path, keys)
30 self.comp = comp
31
32 def __getattr__(self, attr):
33 if hasattr(self.comp, attr):
34 return getattr(self.comp, attr)
35 return super().__getattr__(attr)
36
37
38class FuncItem(ComItem):
39 def __init__(self, comp, path, keys):
40 super().__init__(comp, os.path.join(path, comp.name), keys)
41
42 self.has_getter = (
43 comp.type in (Eolian_Function_Type.PROP_GET, Eolian_Function_Type.PROPERTY)
44 and comp.full_c_getter_name not in keys.blacklist
45 and comp.getter_scope == Eolian_Object_Scope.PUBLIC
46 and not os.path.isfile("{}_get".format(os.path.join(path, comp.name)))
47 )
48 self.has_setter = (
49 comp.type in (Eolian_Function_Type.PROP_SET, Eolian_Function_Type.PROPERTY)
50 and comp.full_c_setter_name not in keys.blacklist
51 and comp.setter_scope == Eolian_Object_Scope.PUBLIC
52 and not os.path.isfile("{}_set".format(os.path.join(path, comp.name)))
53 )
54
55 self.is_enum = (
56 lambda arg: arg.type
57 and arg.type.typedecl
58 and arg.type.typedecl.type == arg.type.typedecl.type.ENUM
59 )
60 self.is_number = lambda arg: arg.type and arg.type.builtin_type in (
61 arg.type.builtin_type.INT,
62 arg.type.builtin_type.UINT,
63 arg.type.builtin_type.LONG,
64 arg.type.builtin_type.ULONG,
65 arg.type.builtin_type.LLONG,
66 arg.type.builtin_type.ULLONG,
67 arg.type.builtin_type.INT8,
68 arg.type.builtin_type.UINT8,
69 arg.type.builtin_type.INT16,
70 arg.type.builtin_type.UINT16,
71 arg.type.builtin_type.INT32,
72 arg.type.builtin_type.UINT32,
73 arg.type.builtin_type.INT64,
74 arg.type.builtin_type.UINT64,
75 arg.type.builtin_type.INT128,
76 arg.type.builtin_type.UINT128,
77 )
78
79 @property
80 def getter_args(self):
81 return itertools.chain(self.getter_values, self.getter_keys)
82
83 @property
84 def setter_args(self):
85 return itertools.chain(self.setter_values, self.setter_keys)
86
87 @property
88 def format_name(self):
89 return self.keys.format_name(self)
90
91
92class EventItem(ComItem):
93 def __init__(self, comp, path, keys):
94 self.myname = comp.name.replace(",", "_")
95 super().__init__(comp, os.path.join(path, self.myname), keys)
96 self.format_name = self.keys.event_convert(self)
97
98
99class ClassItem(ComItem):
100 def __init__(self, comp, path, keys):
101 self.myname = os.path.splitext(comp.file)[0]
102 super().__init__(comp, os.path.join(path, self.myname), keys)
103
104 def mfilter(f):
105 if f.full_c_method_name in self.keys.blacklist:
106 return False
107
108 if os.path.isfile(os.path.join(self.path, f.name)):
109 return False
110
111 if f.type == Eolian_Function_Type.PROPERTY:
112 if f.getter_scope != Eolian_Object_Scope.PUBLIC:
113 scope = f.setter_scope
114 else:
115 scope = f.getter_scope
116 else:
117 scope = f.scope_get(f.type)
118
119 if scope != Eolian_Object_Scope.PUBLIC:
120 return False
121
122 return True
123
124 if self.keys.funclist & Function_List_Type.OWN:
125 self._methods = {
126 m.name: FuncItem(m, self.path, keys)
127 for m in self.comp.methods
128 if mfilter(m)
129 }
130 self._properties = {
131 p.name: FuncItem(p, self.path, keys)
132 for p in self.comp.properties
133 if mfilter(p)
134 }
135 self._events = {
136 e.name: EventItem(e, self.path, keys) for e in self.comp.events
137 }
138 else:
139 self._methods = {}
140 self._properties = {}
141 self._events = {}
142
143 if self.keys.funclist & Function_List_Type.IMPLEMENTS:
144 for imp in comp.implements:
145
146 if (
147 imp.namespace == self.name
148 or imp.short_name.lower() in self.keys.implementsbl
149 ):
150 continue
151
152 f = imp.function
153
154 if not mfilter(f):
155 continue
156
157 if f.type == Eolian_Function_Type.METHOD:
158 if f.name in self._methods:
159 continue
160 self._methods[f.name] = FuncItem(f, self.path, keys)
161 elif f.type in (
162 Eolian_Function_Type.PROPERTY,
163 Eolian_Function_Type.PROP_GET,
164 Eolian_Function_Type.PROP_SET,
165 ):
166 if f.name in self._properties:
167 continue
168 self._properties[f.name] = FuncItem(f, self.path, keys)
169
170 parents = []
171
172 if self.keys.funclist & Function_List_Type.INHERITS_FULL:
173 # Use inherits full to get inherited interfaces too
174 parents = self.comp.inherits_full
175 else:
176 if self.keys.funclist & Function_List_Type.EXTENSIONS:
177 parents = self.comp.extensions_hierarchy
178
179 if self.keys.funclist & Function_List_Type.INHERITED:
180 if parents:
181 parents = itertools.chain(self.comp.hierarchy, parents)
182 else:
183 parents = self.comp.hierarchy
184
185 for eoclass in parents:
186 for f in filter(mfilter, eoclass.methods):
187 if f.name in self._methods:
188 continue
189 self._methods[f.name] = FuncItem(f, self.path, keys)
190 for f in filter(mfilter, eoclass.properties):
191 if f.name in self._properties:
192 continue
193 self._properties[f.name] = FuncItem(f, self.path, keys)
194
195 @property
196 def properties(self):
197 return filter(lambda p: p.has_setter or p.has_getter, self._properties.values())
198
199 @property
200 def properties_get(self):
201 return filter(lambda p: p.has_getter, self._properties.values())
202
203 @property
204 def properties_set(self):
205 return filter(lambda p: p.has_setter, self._properties.values())
206
207 @property
208 def methods(self):
209 return self._methods.values()
210
211 @property
212 def events(self):
213 return self._events.values()
214
215 def __iter__(self):
216 return itertools.chain(self.methods, self.properties)
217
218
219class SuiteGen(BaseItem):
220 def __init__(self, name, testname, filename, path, template=None):
221 keys = GetKey(os.path.splitext(filename)[1])
222 super().__init__(path, keys, name + "_")
223 self.name = name
224 self.testname = testname
225 self.fullname = "_".join([name, testname]) if testname else name
226 self.filename = filename
227 self.template = template
228 self.clslist = []
229
230 if not self.template:
231 script_path = os.path.dirname(os.path.realpath(__file__))
232 self.template = os.path.join(
233 script_path, "testgenerator{}.template".format(self.keys.ext)
234 )
235
236 def __iter__(self):
237 return iter(self.clslist)
238
239 def type_convert(self, eotype):
240 if eotype.type == eolian.Eolian_Type_Type.CLASS:
241 return name_helpers.class_managed_name(eotype.class_)
242
243 if eotype.typedecl:
244 return name_helpers.type_managed_name(eotype)
245
246 return self.keys.type_convert(eotype)
247
248 def constructor_params(self, cls):
249 ret = []
250
251 constructors = itertools.chain(
252 cls.constructors, *[base.constructors for base in cls.inherits_full]
253 )
254
255 for constructor in constructors:
256 # Skip optional constructors for now
257 if constructor.is_optional:
258 continue
259 func = constructor.function
260
261 if func.type == eolian.Eolian_Function_Type.PROPERTY:
262 first_param = list(func.setter_values)[0]
263 else:
264 first_param = list(func.parameters)[0]
265 param_type = first_param.type
266
267 ret.append("default({})".format(name_helpers.type_managed_name(param_type)))
268
269 return (", " if ret else "") + ", ".join(ret)
270
271 def print_arg(self, eoarg):
272 return self.keys.print_arg(eoarg)
273
274 def intersect(self, a, b):
275 return list(set(a) & set(b))
276
277 def loadFiles(self, eolian_db, eofiles):
278 self.clslist.clear()
279 for eofile in eofiles:
280 eocls = eolian_db.class_by_file_get(os.path.basename(eofile))
281 if not eocls or eocls.type != Eolian_Class_Type.REGULAR:
282 continue
283 self.loadObj(eocls)
284
285 def loadObj(self, eocls):
286 cls = ClassItem(eocls, self.path, self.keys)
287 if not os.path.isfile(cls.path):
288 cls.myfullname = "{}_{}".format(self.fullname, cls.myname)
289 self.clslist.append(cls)
290 else:
291 print("removing {} Class from generated list".format(cls.name))
diff --git a/src/scripts/testgen/testgen.py b/src/scripts/testgen/testgen.py
new file mode 100755
index 0000000..24ec001
--- /dev/null
+++ b/src/scripts/testgen/testgen.py
@@ -0,0 +1,125 @@
1#!/usr/bin/env python3
2# encoding: utf-8
3
4import os
5import sys
6import datetime
7
8
9script_path = os.path.dirname(os.path.realpath(__file__))
10
11if "EFL_DIR" in os.environ:
12 root_path = os.environ["EFL_DIR"]
13else:
14 root_path = os.path.abspath(os.path.join(script_path, "..", "..", ".."))
15
16sys.path.insert(0, os.path.join(root_path, "src", "scripts"))
17
18from pyolian import eolian
19from pyolian import pyratemp
20from testgen.suitegen import SuiteGen
21from testgen import name_helpers
22
23# Use .eo files from the source tree (not the installed ones)
24SCAN_FOLDER = os.path.join(root_path, "src", "lib")
25
26# create main eolian state
27eolian_db = eolian.Eolian_State()
28if not isinstance(eolian_db, eolian.Eolian_State):
29 raise (RuntimeError("Eolian, failed to create Eolian state"))
30
31# eolian source tree scan
32if not eolian_db.directory_add(SCAN_FOLDER):
33 raise (RuntimeError("Eolian, failed to scan source directory"))
34
35# Parse all known eo files
36if not eolian_db.all_eot_files_parse():
37 raise (RuntimeError("Eolian, failed to parse all EOT files"))
38
39if not eolian_db.all_eo_files_parse():
40 raise (RuntimeError("Eolian, failed to parse all EO files"))
41
42# cleanup the database on exit
43import atexit
44
45
46def cleanup_db():
47 global eolian_db
48 del eolian_db
49
50
51atexit.register(cleanup_db)
52
53
54class Template(pyratemp.Template):
55 def __init__(
56 self,
57 filename,
58 encoding="utf-8",
59 loader_class=pyratemp.LoaderFile,
60 parser_class=pyratemp.Parser,
61 renderer_class=pyratemp.Renderer,
62 eval_class=pyratemp.EvalPseudoSandbox,
63 ):
64
65 global_ctx = {}
66 global_ctx.update(
67 {
68 # Template info
69 "date": datetime.datetime.now(),
70 "template_file": os.path.basename(filename),
71 }
72 )
73
74 self.template_filename = filename
75 pyratemp.Template.__init__(
76 self,
77 filename=filename,
78 encoding=encoding,
79 data=global_ctx,
80 loader_class=loader_class,
81 parser_class=parser_class,
82 renderer_class=renderer_class,
83 eval_class=eval_class,
84 )
85
86 def render(self, suite, verbose=True):
87 # Build the context for the template
88 ctx = {}
89 ctx["suite"] = suite
90 ctx["name_helpers"] = name_helpers
91 # render with the augmented context
92 output = self(**ctx)
93
94 if suite.filename is not None:
95 # write to file
96 with open(suite.filename, "w") as f:
97 f.write(output)
98
99
100if __name__ == "__main__":
101 import argparse
102
103 parser = argparse.ArgumentParser(description="Eolian Test Generator.")
104 parser.add_argument(
105 "testname",
106 help="The Test Name used to find custom and template files. (REQUIRED)",
107 )
108 parser.add_argument(
109 "suitename", help="The Suite Name used to find custom files. (REQUIRED)"
110 )
111 parser.add_argument("filename", help="Generated test file destination. (REQUIRED)")
112 parser.add_argument("eofiles", nargs="*", help="The Eolian Files to use.")
113
114 args = parser.parse_args()
115
116 testdir = os.path.join(root_path, "src", "tests", args.testname)
117
118 suite = SuiteGen(args.suitename, args.testname, args.filename, testdir)
119 suite.loadFiles(eolian_db, args.eofiles)
120
121 t = Template(suite.template)
122 # try:
123 t.render(suite)
124# except:
125# print("ERROR RENDERING - Cannot create file: {}".format(suite.filename))
diff --git a/src/scripts/testgen/testgenerator.c.template b/src/scripts/testgen/testgenerator.c.template
new file mode 100644
index 0000000..99fc76d
--- /dev/null
+++ b/src/scripts/testgen/testgenerator.c.template
@@ -0,0 +1,187 @@
1<!--(macro m_show)-->
2 <!--(if mshow)-->
3${mshow}$#!
4 <!--(end)-->
5<!--(end)-->
6<!--(macro init)-->
7 Eo *parent = NULL;
8 Eo *obj = NULL;
9
10 <!--(if exists("mfunc") and mfunc!= None)-->
11${mfunc}$
12 <!--(elif exists("mcls") and mcls!= None)-->
13${mcls}$
14 <!--(else)-->
15 obj = efl_add_ref(${cls.c_macro}$, parent);
16 fail_if(!obj, "ERROR: Cannot init ${cls.name}$!\n");
17 <!--(end)-->
18<!--(end)-->
19<!--(macro shutdown)-->
20 /** shutdown **/
21 <!--(if exists("mfunc") and mfunc != None)-->
22${mfunc}$
23 <!--(elif exists("mcls") and mcls != None)-->
24${mcls}$
25 <!--(end)-->
26 efl_unref(obj);
27<!--(end)-->
28<!--(macro arg_default)-->
29 <!--(if arg.type.name == "__builtin_free_cb" or 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<!--(elif arg.type.typedecl and arg.type.typedecl.type == arg.type.typedecl.type.STRUCT )-->{}<!--(else)-->0<!--(end)-->;
30<!--(end)-->
31<!--(macro args_declaration)-->
32 <!--(for arg in args)-->
33 <!--(if arg.type.typedecl and arg.type.typedecl.type == arg.type.typedecl.type.FUNCTION_POINTER)-->
34 void * arg_${arg.name}$_data = NULL;
35 ${arg.type.c_type_param}$ arg_${arg.name}$ = NULL;
36 Eina_Free_Cb arg_${arg.name}$_free_cb = NULL;
37 <!--(else)-->
38 ${arg.type.c_type_param}$ arg_${arg.name}$ = ${arg_default(arg=arg)}$
39 <!--(end)-->
40 <!--(end)-->
41<!--(end)-->
42<!--(macro print_arg)-->
43 <!--(if arg.type.typedecl and arg.type.typedecl.type == arg.type.typedecl.type.FUNCTION_POINTER)-->
44arg_${arg.name}$_data, arg_${arg.name}$, arg_${arg.name}$_free_cb
45 <!--(else)-->
46 <!--(if arg.direction in (arg.direction.OUT, arg.direction.INOUT))-->&<!--(end)-->arg_${arg.name}$
47 <!--(end)-->
48<!--(end)-->
49<!--(macro arg_self)-->
50 <!--(if not func.is_class)-->
51 obj
52 <!--(end)-->
53<!--(end)-->
54<!--(macro print_comma)-->
55 <!--(if i > 0 or not is_class)-->
56 ,
57 <!--(end)-->
58<!--(end)-->
59
60#ifdef HAVE_CONFIG_H
61# include <config.h>
62#endif
63
64#include <check.h>
65#include "efl_check.h"
66${m_show(mshow=suite.custom)}$#!
67#include <Elementary.h>
68
69<!--(for cls in suite)-->
70void ${cls.myfullname}$_test(TCase *tc);
71<!--(end)-->
72
73static const Efl_Test_Case etc[] = {
74<!--(for cls in suite)-->
75 { "${suite.name.capitalize()}$ ${suite.testname.capitalize()}$ ${cls.myname.capitalize()}$", ${cls.myfullname}$_test },
76<!--(end)-->
77 { NULL, NULL }
78};
79
80<!--(for cls in suite)-->
81
82/**************** TEST CASE ${cls.c_macro}$ ****************/
83${m_show(mshow=cls.custom)}$#!
84
85START_TEST(${cls.myfullname}$_smoke)
86{
87${init(mcls=cls.init)}$
88${shutdown(mcls=cls.shutdown)}$
89}
90END_TEST
91
92 <!--(for func in cls.methods)-->
93START_TEST(${cls.myfullname}$_${func.full_c_method_name}$)
94{
95${args_declaration(args=func.parameters)}$${init(mcls=cls.init,mfunc=func.init)}$
96${m_show(mshow=func.arg_init)}$#!
97 <!--(if func.method_return_type)-->${func.method_return_type.c_type_return}$ r = <!--(end)-->${func.full_c_method_name}$(${arg_self(func=func)}$<!--(for i, arg in enumerate(func.parameters))-->${print_comma(i=i, is_class=func.is_class)}$${print_arg(arg=arg)}$<!--(end)-->);
98 <!--(if func.method_return_type)-->(void)r;<!--(end)-->
99${m_show(mshow=func.arg_shutdown)}$#!
100${shutdown(mcls=cls.shutdown,mfunc=func.shutdown)}$
101}
102END_TEST
103
104 <!--(end)-->
105
106 <!--(for func in cls.properties)-->
107 <!--(if func.has_getter)-->
108START_TEST(${cls.myfullname}$_${func.full_c_getter_name}$)
109{
110 <!--(if len(list(func.getter_values)) > 1)-->
111${args_declaration(args=func.getter_values)}$
112 <!--(end)-->
113${args_declaration(args=func.getter_keys)}$${init(mcls=cls.init,mfunc=func.get_init)}$
114${m_show(mshow=func.arg_get_init)}$#!
115 <!--(if len(list(func.getter_values)) == 1)-->
116 ${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)-->);
117 (void)r;
118 <!--(else)-->
119 ${func.full_c_getter_name}$(obj<!--(for arg in func.getter_keys)-->, arg_${arg.name}$<!--(end)--><!--(for arg in func.getter_values)-->, &arg_${arg.name}$<!--(end)-->);
120 <!--(end)-->
121${m_show(mshow=func.arg_get_shutdown)}$#!
122${shutdown(mcls=cls.shutdown,mfunc=func.get_shutdown)}$
123}
124END_TEST
125
126 <!--(end)-->
127 <!--(if func.has_setter)-->
128START_TEST(${cls.myfullname}$_${func.full_c_setter_name}$)
129{
130${args_declaration(args=func.setter_keys)}$${args_declaration(args=func.setter_values)}$${init(mcls=cls.init,mfunc=func.set_init)}$
131${m_show(mshow=func.arg_set_init)}$#!
132 ${func.full_c_setter_name}$(obj<!--(for arg in func.setter_keys)-->, arg_${arg.name}$<!--(end)--><!--(for arg in func.setter_values)-->, arg_${arg.name}$<!--(end)-->);
133${m_show(mshow=func.arg_set_shutdown)}$#!
134${shutdown(mcls=cls.shutdown,mfunc=func.set_shutdown)}$
135}
136END_TEST
137
138 <!--(end)-->
139 <!--(end)-->
140void ${cls.myfullname}$_test(TCase *tc)
141{
142 tcase_add_test(tc, ${cls.myfullname}$_smoke);
143 <!--(for func in cls.methods)-->
144 tcase_add_test(tc, ${cls.myfullname}$_${func.full_c_method_name}$);
145 <!--(end)-->
146 <!--(for func in cls.properties_get)-->
147 tcase_add_test(tc, ${cls.myfullname}$_${func.full_c_getter_name}$);
148 <!--(end)-->
149 <!--(for func in cls.properties_set)-->
150 tcase_add_test(tc, ${cls.myfullname}$_${func.full_c_setter_name}$);
151 <!--(end)-->
152}
153<!--(end)-->
154
155SUITE_INIT(${suite.name}$)
156{
157 fail_if(!eina_init(), "ERROR: Cannot init Eina!\n");
158 fail_if(!ecore_init(), "ERROR: Cannot init Ecore!\n");
159 fail_if(!efl_object_init(), "ERROR: Cannot init EO!\n");
160${m_show(mshow=suite.init)}$#!
161}
162
163SUITE_SHUTDOWN(${suite.name}$)
164{
165${m_show(mshow=suite.shutdown)}$#!
166 ecore_shutdown();
167 eina_shutdown();
168}
169
170int
171main(int argc, char **argv)
172{
173 int failed_count;
174
175 if (!_efl_test_option_disp(argc, argv, etc))
176 return 0;
177
178#ifdef NEED_RUN_IN_TREE
179 putenv("EFL_RUN_IN_TREE=1");
180#endif
181
182 failed_count = _efl_suite_build_and_run(argc - 1, (const char **)argv + 1,
183 "${suite.fullname}$", etc, SUITE_INIT_FN(${suite.name}$), SUITE_SHUTDOWN_FN(${suite.name}$));
184
185 return (failed_count == 0) ? 0 : 255;
186}
187
diff --git a/src/scripts/testgen/testgenerator.cs.template b/src/scripts/testgen/testgenerator.cs.template
new file mode 100644
index 0000000..c2085e8
--- /dev/null
+++ b/src/scripts/testgen/testgenerator.cs.template
@@ -0,0 +1,113 @@
1<!--(macro m_show)-->
2 <!--(if mshow)-->
3${mshow}$#!
4 <!--(end)-->
5<!--(end)-->
6<!--(macro def_obj)-->${name_helpers.class_managed_name(param.type.class_)}$ arg_${param.name}$ = null;<!--(end)-->
7<!--(macro def_param)-->
8 <!--(if param.type.type == param.type.type.CLASS)-->${def_obj(param=param)}$<!--(else)-->${suite.type_convert(param.type)}$ arg_${param.name}$ = default(${suite.type_convert(param.type)}$);<!--(end)-->
9<!--(end)-->
10<!--(macro def_params)-->
11 <!--(for p in parameters)-->
12 ${def_param(param=p)}$
13 <!--(end)-->
14<!--(end)-->
15<!--(macro meth_target)-->
16 <!--(if func.is_class)-->${name_helpers.class_managed_name(cls)}$<!--(else)-->obj<!--(end)-->
17<!--(end)-->
18using System;
19
20namespace TestSuite
21{
22<!--(if suite.custom)-->${suite.custom}$<!--(end)-->
23<!--(for cls in suite)-->
24/**************** TEST CASE ${cls.c_macro}$ ****************/
25class Test${cls.name.replace('.','')}$
26{
27
28 ${name_helpers.class_managed_name(cls)}$ obj;
29${m_show(mshow=cls.custom)}$#!
30
31 public void SetUp()
32 {
33${m_show(mshow=suite.init)}$#!
34 <!--(if cls.init)-->
35${cls.init}$
36 <!--(else)-->
37 obj = new ${name_helpers.class_managed_name(cls)}$(null${suite.constructor_params(cls)}$);
38 <!--(end)-->
39 }
40
41 public void TearDown()
42 {
43${m_show(mshow=suite.shutdown)}$#!
44 <!--(if cls.shutdown)-->
45${cls.shutdown}$
46 <!--(else)-->
47 obj.Dispose();
48 obj = null;
49 <!--(end)-->
50 }
51
52 public void smoke()
53 {
54 }
55
56#! METHODS
57 <!--(for func in cls.methods)-->
58 public void ${func.name}$()
59 {
60 <!--(if len(list(func.parameters)) > 0)-->
61${def_params(parameters=func.parameters)}$
62 <!--(end)-->
63${m_show(mshow=func.arg_init)}$#!
64${m_show(mshow=func.init)}$#!
65 <!--(if func.method_return_type)-->var r = <!--(end)-->${meth_target(func=func, cls=cls)}$.${func.format_name}$(${', '.join([ suite.print_arg(p) for p in func.parameters])}$);
66${m_show(mshow=func.arg_shutdown)}$#!
67${m_show(mshow=func.shutdown)}$#!
68 }
69
70 <!--(end)-->
71#! PROPERTIES FUNCTION GET
72 <!--(for func in cls.properties)-->
73 <!--(if func.has_getter)-->
74 public void ${func.name}$_pget()
75 {
76 <!--(if func.getter_return_type or len(list(func.getter_values)) > 1)-->
77${def_params(parameters=func.getter_values)}$
78 <!--(end)-->
79 <!--(if len(list(func.getter_keys)) > 0)-->
80${def_params(parameters=func.getter_keys)}$
81 <!--(end)-->
82${m_show(mshow=func.arg_get_init)}$#!
83${m_show(mshow=func.get_init)}$#!
84 <!--(if not func.getter_return_type and len(list(func.getter_values)) == 1)-->
85 var arg_${list(func.getter_values)[0].name}$ = ${meth_target(func=func, cls=cls)}$.Get${func.format_name}$(${', '.join(['arg_{}'.format(param.name) for param in func.getter_keys])}$);
86 <!--(else)-->
87 <!--(if func.getter_return_type)-->var r = <!--(end)-->${meth_target(func=func, cls=cls)}$.Get${func.format_name}$(${', '.join([suite.print_arg(p) for p in func.getter_keys] + ['out arg_{}'.format(p.name) for p in func.getter_values])}$);
88 <!--(end)-->
89${m_show(mshow=func.arg_get_shutdown)}$#!
90${m_show(mshow=func.get_shutdown)}$#!
91 }
92
93 <!--(end)-->
94#! PROPERTIES FUNCTION SET
95 <!--(if func.has_setter)-->
96 public void ${func.name}$_pset()
97 {
98${def_params(parameters=func.setter_values)}$
99 <!--(if len(list(func.setter_keys)) > 0)-->
100${def_params(parameters=func.setter_keys)}$
101 <!--(end)-->
102${m_show(mshow=func.arg_set_init)}$#!
103${m_show(mshow=func.set_init)}$#!
104 ${meth_target(func=func, cls=cls)}$.Set${func.format_name}$(${', '.join([suite.print_arg(p) for p in list(func.setter_keys) + list(func.setter_values)])}$);
105${m_show(mshow=func.arg_set_shutdown)}$#!
106${m_show(mshow=func.set_shutdown)}$#!
107 }
108
109 <!--(end)-->
110 <!--(end)-->
111}
112<!--(end)-->
113}
diff --git a/src/tests/automated/ecore_audio_custom.c b/src/tests/automated/ecore_audio_custom.c
new file mode 100644
index 0000000..538ed42
--- /dev/null
+++ b/src/tests/automated/ecore_audio_custom.c
@@ -0,0 +1,3 @@
1#include <Ecore.h>
2#include <Ecore_Audio.h>
3#include <Ecore_File.h>
diff --git a/src/tests/automated/ecore_audio_init.c b/src/tests/automated/ecore_audio_init.c
new file mode 100644
index 0000000..3dd8aec
--- /dev/null
+++ b/src/tests/automated/ecore_audio_init.c
@@ -0,0 +1,2 @@
1 int _rinit = ecore_audio_init();
2 ck_assert_int_eq(_rinit, 1);
diff --git a/src/tests/automated/ecore_audio_out/input_attach/arg_init.c b/src/tests/automated/ecore_audio_out/input_attach/arg_init.c
new file mode 100644
index 0000000..fcebbe0
--- /dev/null
+++ b/src/tests/automated/ecore_audio_out/input_attach/arg_init.c
@@ -0,0 +1 @@
arg_input = efl_add(ECORE_AUDIO_IN_CLASS, NULL);
diff --git a/src/tests/automated/ecore_audio_out/input_detach/arg_init.c b/src/tests/automated/ecore_audio_out/input_detach/arg_init.c
new file mode 100644
index 0000000..fcebbe0
--- /dev/null
+++ b/src/tests/automated/ecore_audio_out/input_detach/arg_init.c
@@ -0,0 +1 @@
arg_input = efl_add(ECORE_AUDIO_IN_CLASS, NULL);
diff --git a/src/tests/automated/ecore_audio_out_wasapi/init.c b/src/tests/automated/ecore_audio_out_wasapi/init.c
new file mode 100644
index 0000000..da9426d
--- /dev/null
+++ b/src/tests/automated/ecore_audio_out_wasapi/init.c
@@ -0,0 +1,3 @@
1#ifdef _WIN32
2 obj = efl_add_ref(ECORE_AUDIO_OUT_WASAPI_CLASS, parent);
3 fail_if(!obj, "ERROR: Cannot init Ecore.Audio.Out.Wasapi!\n")
diff --git a/src/tests/automated/ecore_audio_out_wasapi/shutdown.c b/src/tests/automated/ecore_audio_out_wasapi/shutdown.c
new file mode 100644
index 0000000..23fe0f1
--- /dev/null
+++ b/src/tests/automated/ecore_audio_out_wasapi/shutdown.c
@@ -0,0 +1,3 @@
1#else
2(void)parent;
3#endif
diff --git a/src/tests/automated/ector_custom.c b/src/tests/automated/ector_custom.c
new file mode 100644
index 0000000..0ff115b
--- /dev/null
+++ b/src/tests/automated/ector_custom.c
@@ -0,0 +1,3 @@
1#include <cairo/Ector_Cairo.h>
2#include <software/Ector_Software.h>
3#include <gl/Ector_GL.h>
diff --git a/src/tests/automated/ector_init.c b/src/tests/automated/ector_init.c
new file mode 100644
index 0000000..b0006b6
--- /dev/null
+++ b/src/tests/automated/ector_init.c
@@ -0,0 +1 @@
fail_if(!ector_init(), "ERROR: Cannot init Ector!\n");
diff --git a/src/tests/automated/ector_renderer_cairo_shape/init.c b/src/tests/automated/ector_renderer_cairo_shape/init.c
new file mode 100644
index 0000000..e0d899f
--- /dev/null
+++ b/src/tests/automated/ector_renderer_cairo_shape/init.c
@@ -0,0 +1,2 @@
1Ector_Surface *surface = efl_add(ECTOR_CAIRO_SOFTWARE_SURFACE_CLASS, NULL);
2obj = efl_add_ref(ECTOR_RENDERER_CAIRO_SHAPE_CLASS, parent, ector_renderer_surface_set(efl_added, surface));
diff --git a/src/tests/automated/ector_shutdown.c b/src/tests/automated/ector_shutdown.c
new file mode 100644
index 0000000..2428e6e
--- /dev/null
+++ b/src/tests/automated/ector_shutdown.c
@@ -0,0 +1 @@
ector_shutdown();
diff --git a/src/tests/automated/edje_custom.c b/src/tests/automated/edje_custom.c
new file mode 100644
index 0000000..edbf1b7
--- /dev/null
+++ b/src/tests/automated/edje_custom.c
@@ -0,0 +1 @@
#define EFL_CANVAS_LAYOUT_BETA
diff --git a/src/tests/automated/edje_init.c b/src/tests/automated/edje_init.c
new file mode 100644
index 0000000..4e81da1
--- /dev/null
+++ b/src/tests/automated/edje_init.c
@@ -0,0 +1,2 @@
1 fail_if(!ecore_evas_init(), "ERROR: Cannot init Ecore Evas!\n");
2 fail_if(!edje_init(), "ERROR: Cannot init Edje!\n");
diff --git a/src/tests/automated/edje_shutdown.c b/src/tests/automated/edje_shutdown.c
new file mode 100644
index 0000000..450dda7
--- /dev/null
+++ b/src/tests/automated/edje_shutdown.c
@@ -0,0 +1,2 @@
1 edje_shutdown();
2 ecore_evas_shutdown();
diff --git a/src/tests/automated/efl_canvas_layout_part/init.c b/src/tests/automated/efl_canvas_layout_part/init.c
new file mode 100644
index 0000000..7d4a56a
--- /dev/null
+++ b/src/tests/automated/efl_canvas_layout_part/init.c
@@ -0,0 +1,9 @@
1 parent = evas_new();
2 evas_output_method_set(parent, evas_render_method_lookup("buffer"));
3 Evas_Engine_Info *einfo = evas_engine_info_get(parent);
4 evas_engine_info_set(parent, einfo);
5
6 evas_output_size_set(parent, 500, 500);
7 evas_output_viewport_set(parent, 0, 0, 500, 500);
8
9 (void)obj;
diff --git a/src/tests/automated/efl_canvas_layout_part_box/init.c b/src/tests/automated/efl_canvas_layout_part_box/init.c
new file mode 100644
index 0000000..7d4a56a
--- /dev/null
+++ b/src/tests/automated/efl_canvas_layout_part_box/init.c
@@ -0,0 +1,9 @@
1 parent = evas_new();
2 evas_output_method_set(parent, evas_render_method_lookup("buffer"));
3 Evas_Engine_Info *einfo = evas_engine_info_get(parent);
4 evas_engine_info_set(parent, einfo);
5
6 evas_output_size_set(parent, 500, 500);
7 evas_output_viewport_set(parent, 0, 0, 500, 500);
8
9 (void)obj;
diff --git a/src/tests/automated/efl_canvas_layout_part_external/init.c b/src/tests/automated/efl_canvas_layout_part_external/init.c
new file mode 100644
index 0000000..b42f732
--- /dev/null
+++ b/src/tests/automated/efl_canvas_layout_part_external/init.c
@@ -0,0 +1,8 @@
1 parent = evas_new();
2 evas_output_method_set(parent, evas_render_method_lookup("buffer"));
3 Evas_Engine_Info *einfo = evas_engine_info_get(parent);
4 evas_engine_info_set(parent, einfo);
5
6 evas_output_size_set(parent, 500, 500);
7 evas_output_viewport_set(parent, 0, 0, 500, 500);
8 (void)obj;
diff --git a/src/tests/automated/efl_canvas_layout_part_swallow/init.c b/src/tests/automated/efl_canvas_layout_part_swallow/init.c
new file mode 100644
index 0000000..b42f732
--- /dev/null
+++ b/src/tests/automated/efl_canvas_layout_part_swallow/init.c
@@ -0,0 +1,8 @@
1 parent = evas_new();
2 evas_output_method_set(parent, evas_render_method_lookup("buffer"));
3 Evas_Engine_Info *einfo = evas_engine_info_get(parent);
4 evas_engine_info_set(parent, einfo);
5
6 evas_output_size_set(parent, 500, 500);
7 evas_output_viewport_set(parent, 0, 0, 500, 500);
8 (void)obj;
diff --git a/src/tests/automated/efl_canvas_layout_part_table/init.c b/src/tests/automated/efl_canvas_layout_part_table/init.c
new file mode 100644
index 0000000..b42f732
--- /dev/null
+++ b/src/tests/automated/efl_canvas_layout_part_table/init.c
@@ -0,0 +1,8 @@
1 parent = evas_new();
2 evas_output_method_set(parent, evas_render_method_lookup("buffer"));
3 Evas_Engine_Info *einfo = evas_engine_info_get(parent);
4 evas_engine_info_set(parent, einfo);
5
6 evas_output_size_set(parent, 500, 500);
7 evas_output_viewport_set(parent, 0, 0, 500, 500);
8 (void)obj;
diff --git a/src/tests/automated/efl_canvas_layout_part_text/init.c b/src/tests/automated/efl_canvas_layout_part_text/init.c
new file mode 100644
index 0000000..b42f732
--- /dev/null
+++ b/src/tests/automated/efl_canvas_layout_part_text/init.c
@@ -0,0 +1,8 @@
1 parent = evas_new();
2 evas_output_method_set(parent, evas_render_method_lookup("buffer"));
3 Evas_Engine_Info *einfo = evas_engine_info_get(parent);
4 evas_engine_info_set(parent, einfo);
5
6 evas_output_size_set(parent, 500, 500);
7 evas_output_viewport_set(parent, 0, 0, 500, 500);
8 (void)obj;
diff --git a/src/tests/automated/efl_canvas_video/init.c b/src/tests/automated/efl_canvas_video/init.c
new file mode 100644
index 0000000..f75bda2
--- /dev/null
+++ b/src/tests/automated/efl_canvas_video/init.c
@@ -0,0 +1,2 @@
1 obj = efl_add(EFL_CANVAS_VIDEO_CLASS, parent, efl_canvas_object_legacy_ctor(efl_added));
2 fail_if(!obj, "Error: Canot get obj!\n");
diff --git a/src/tests/automated/efl_loop/begin/init.c b/src/tests/automated/efl_loop/begin/init.c
new file mode 100644
index 0000000..78fbba3
--- /dev/null
+++ b/src/tests/automated/efl_loop/begin/init.c
@@ -0,0 +1,9 @@
1int argc = 2;
2char *argv[] = { "efl_ui_suite", "test" };
3(void)parent;
4
5_EFL_APP_VERSION_SET();
6obj = efl_app_get();
7efl_event_callback_add(obj, EFL_LOOP_EVENT_ARGUMENTS, efl_main, NULL);
8fail_if(!ecore_init_ex(argc, argv));
9__EFL_MAIN_CONSTRUCTOR;
diff --git a/src/tests/automated/efl_loop/begin/shutdown.c b/src/tests/automated/efl_loop/begin/shutdown.c
new file mode 100644
index 0000000..1f57878
--- /dev/null
+++ b/src/tests/automated/efl_loop/begin/shutdown.c
@@ -0,0 +1,3 @@
1efl_loop_exit_code_process(r);
2__EFL_MAIN_DESTRUCTOR;
3ecore_shutdown_ex();
diff --git a/src/tests/automated/efl_loop/custom.c b/src/tests/automated/efl_loop/custom.c
new file mode 100644
index 0000000..f7df130
--- /dev/null
+++ b/src/tests/automated/efl_loop/custom.c
@@ -0,0 +1,5 @@
1EAPI_MAIN void
2efl_main(void *data EINA_UNUSED, const Efl_Event *ev)
3{
4 efl_loop_quit(ev->object, EINA_VALUE_EMPTY);
5}
diff --git a/src/tests/automated/efl_loop/timeout/arg_init.c b/src/tests/automated/efl_loop/timeout/arg_init.c
new file mode 100644
index 0000000..e2e28fb
--- /dev/null
+++ b/src/tests/automated/efl_loop/timeout/arg_init.c
@@ -0,0 +1 @@
arg_time = 0.5;
diff --git a/src/tests/automated/efl_text_markup_util/init.c b/src/tests/automated/efl_text_markup_util/init.c
new file mode 100644
index 0000000..4d5230d
--- /dev/null
+++ b/src/tests/automated/efl_text_markup_util/init.c
@@ -0,0 +1 @@
(void)parent;
diff --git a/src/tests/automated/eio_custom.c b/src/tests/automated/eio_custom.c
new file mode 100644
index 0000000..7f57ce1
--- /dev/null
+++ b/src/tests/automated/eio_custom.c
@@ -0,0 +1 @@
#include <Eio.h>
diff --git a/src/tests/automated/eio_init.c b/src/tests/automated/eio_init.c
new file mode 100644
index 0000000..2787098
--- /dev/null
+++ b/src/tests/automated/eio_init.c
@@ -0,0 +1 @@
fail_if(!eio_init(), "ERROR: Cannot init Eio!\n");
diff --git a/src/tests/automated/eio_shutdown.c b/src/tests/automated/eio_shutdown.c
new file mode 100644
index 0000000..fad342e
--- /dev/null
+++ b/src/tests/automated/eio_shutdown.c
@@ -0,0 +1 @@
eio_shutdown();
diff --git a/src/tests/automated/eldbus_init.c b/src/tests/automated/eldbus_init.c
new file mode 100644
index 0000000..dcfbbec
--- /dev/null
+++ b/src/tests/automated/eldbus_init.c
@@ -0,0 +1 @@
fail_if(eldbus_init() < 0, "ERROR: Cannot init Eldbus!\n");
diff --git a/src/tests/automated/eldbus_shutdown.c b/src/tests/automated/eldbus_shutdown.c
new file mode 100644
index 0000000..f307707
--- /dev/null
+++ b/src/tests/automated/eldbus_shutdown.c
@@ -0,0 +1 @@
eldbus_shutdown();
diff --git a/src/tests/automated/emotion_custom.c b/src/tests/automated/emotion_custom.c
new file mode 100644
index 0000000..811c994
--- /dev/null
+++ b/src/tests/automated/emotion_custom.c
@@ -0,0 +1,2 @@
1#include "Emotion.h"
2#include "Evas_Internal.h"
diff --git a/src/tests/automated/emotion_init.c b/src/tests/automated/emotion_init.c
new file mode 100644
index 0000000..f6d1d03
--- /dev/null
+++ b/src/tests/automated/emotion_init.c
@@ -0,0 +1,3 @@
1 fail_if(!ecore_evas_init(), "ERROR: Cannot init ECore Evas!\n");
2 fail_if(!emotion_init(), "ERROR: Cannot init Emotion!\n");
3
diff --git a/src/tests/automated/emotion_shutdown.c b/src/tests/automated/emotion_shutdown.c
new file mode 100644
index 0000000..e82aef7
--- /dev/null
+++ b/src/tests/automated/emotion_shutdown.c
@@ -0,0 +1,4 @@
1// efl_unref(parent);
2// ecore_evas_free(ee);
3 emotion_shutdown();
4// ecore_evas_shutdown();
diff --git a/src/tests/automated/evas_custom.c b/src/tests/automated/evas_custom.c
new file mode 100644
index 0000000..6cd14a5
--- /dev/null
+++ b/src/tests/automated/evas_custom.c
@@ -0,0 +1 @@
#include "efl_canvas_surface.h"