forked from enlightenment/efl
Compare commits
4 Commits
master
...
devs/lauro
Author | SHA1 | Date |
---|---|---|
Taehyub Kim | 8ca4dd068c | |
Larry Lira | 98d7ee312b | |
Lauro Moura | 0a9441da15 | |
Lauro Moura | 1e7ec9dd16 |
|
@ -732,6 +732,23 @@ class Class(Object):
|
|||
def extensions(self):
|
||||
return Iterator(Class, lib.eolian_class_extensions_get(self))
|
||||
|
||||
@cached_property
|
||||
def extensions_hierarchy(self):
|
||||
visited = set()
|
||||
queue = [ext for ext in self.extensions]
|
||||
|
||||
while queue:
|
||||
current = queue.pop()
|
||||
|
||||
if current in visited:
|
||||
continue
|
||||
|
||||
visited.add(current)
|
||||
|
||||
queue.extend(current.extensions)
|
||||
|
||||
return visited
|
||||
|
||||
@cached_property
|
||||
def inherits_full(self):
|
||||
li = []
|
||||
|
@ -739,6 +756,7 @@ class Class(Object):
|
|||
def do_class_recursive(cls):
|
||||
if cls.parent:
|
||||
li.append(cls.parent)
|
||||
do_class_recursive(cls.parent)
|
||||
for other in cls.extensions:
|
||||
if other not in li:
|
||||
li.append(other)
|
||||
|
|
|
@ -846,6 +846,8 @@ class EvalPseudoSandbox:
|
|||
"complex" : builtins.complex,
|
||||
"dict" : builtins.dict,
|
||||
"enumerate" : builtins.enumerate,
|
||||
"filter" : builtins.filter,
|
||||
"next" : builtins.next,
|
||||
"float" : builtins.float,
|
||||
"int" : builtins.int,
|
||||
"list" : builtins.list,
|
||||
|
|
|
@ -699,3 +699,16 @@ class TestEolianExpression(object):
|
|||
# exp.binary_operator # TODO find a better test (only works for BINARY expr)
|
||||
# exp.binary_lhs # TODO find a better test (only works for BINARY expr)
|
||||
# exp.binary_rhs # TODO find a better test (only works for BINARY expr)
|
||||
|
||||
class TestEolianInherits(object):
|
||||
def test_inherits_full(self, eolian_db):
|
||||
cls = eolian_db.class_by_name_get('Efl.Ui.Widget')
|
||||
assert 'Efl.Object' in cls.inherits_full
|
||||
|
||||
def test_extensions_hierarchy(self, eolian_db):
|
||||
cls = eolian_db.class_by_name_get('Efl.Ui.Widget')
|
||||
|
||||
# inherited extension
|
||||
assert any(x.name == 'Efl.Gfx.Stack' for x in cls.extensions_hierarchy)
|
||||
# direct extension
|
||||
assert any(x.name == 'Efl.Access.Object' for x in cls.extensions_hierarchy)
|
||||
|
|
|
@ -0,0 +1,146 @@
|
|||
|
||||
Testgen: Template-based Eolian tests generator
|
||||
===============================================================================
|
||||
|
||||
Testgen is a Python Script using the Pyolian to generate tests rendering
|
||||
templates with custom files, this can be a easy way to expand the
|
||||
API test coveraged.
|
||||
|
||||
Testgen can generate tests C and to other bingings languages only
|
||||
adding new language specialized templates.
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
There is nothing to install to use the generator, everything is included in
|
||||
the efl source tree and it is intended to work directly inside the tree,
|
||||
usually at efl tests compilation time (make check).
|
||||
|
||||
The only requirement is that **the source tree must be already built** (not
|
||||
installed) because pyolian search the eolian .so/.dll inside the source tree.
|
||||
|
||||
If you built the efl tree in a custom location (fe, you build out-of-tree) you
|
||||
can tell pyolian where to find the built eolian .so files using the
|
||||
`EOLIAN_SO_DIR` environment variable.
|
||||
|
||||
|
||||
Command line usage
|
||||
==================
|
||||
|
||||
The simplest way to use the generator is from the command line, using the
|
||||
`src/scripts/testgen/testgen.py` command, the `--help` option state:
|
||||
|
||||
```
|
||||
usage: testgen.py [-h] testname suitename filename [eofiles [eofiles ...]]
|
||||
|
||||
Eolian Test Generator.
|
||||
|
||||
positional arguments:
|
||||
testname The Test Name used to find custom and template files. (REQUIRED)
|
||||
suitename The Suite Name used to find custom files. (REQUIRED)
|
||||
filename Generated test file destination. (REQUIRED)
|
||||
eofiles The Eolian Files to use.
|
||||
|
||||
optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
```
|
||||
Use .c extension in <filename> to generate C tests or .cs to CSharp
|
||||
|
||||
To test this generator in `src/scripts/testgen` you can run:
|
||||
```
|
||||
./testgen.py automated efl efl_automated_test.c efl_loop.eo
|
||||
```
|
||||
This will rendere the automated tests using files in `src/tests/automated` with
|
||||
suite name `efl_automated` and with Efl.Loop Class as Test Case
|
||||
`efl_automated_efl_loop_test`
|
||||
|
||||
or run:
|
||||
```
|
||||
./testgen.py automated eio eio_automated_test.c eio_sentry.eo eio_model.eo
|
||||
```
|
||||
This will rendere with suite name `eio_automated` and with Eio.Sentry and
|
||||
Eio.Model Class as Test Cases `eio_automated_eio_sentry_test` and
|
||||
`eio_automated_eio_model_test`
|
||||
|
||||
|
||||
How customise a Generated Test
|
||||
==============================
|
||||
|
||||
Testgen use the filesystem to find custom files if you need customise a test,
|
||||
add/write follow files in src/tests:
|
||||
|
||||
Suite custom files
|
||||
* `src/test/<testname>/`
|
||||
|-> <suitename>_custom.c #add include files, functions or structs
|
||||
|-> <suitename>_init.c #add code in SUITE_INIT
|
||||
|-> <suitename>_shutdown.c #add code in SUITE_SHUTDOWN
|
||||
|
||||
Class Test case custom files
|
||||
* `src/test/<testname>/<class_name>/` #use lowercase and `_` separator
|
||||
|-> custom.c #add include files, functions or structs
|
||||
|-> init.c #add default way to create the object of this class
|
||||
|-> shutdown.c #add default way to free the object
|
||||
|
||||
Funtions Tests
|
||||
- Tests methodes custom files
|
||||
* `src/test/<testname>/<class_name>/<method_name>`
|
||||
|-> arg_init.c #initialize method arguments (arg_<argument_name>)
|
||||
|-> init.c #add how to create the object (replace default)
|
||||
|-> arg_shutdown.c #free arguments
|
||||
|-> shutdown.c #add how to free the object (replace default)
|
||||
|
||||
- Tests properties custom files
|
||||
* `src/test/<testname>/<class_name>/<property_name>`
|
||||
| -- Property Get --
|
||||
|-> arg_get_init.c #initialize property get arguments (arg_<argument_name>)
|
||||
|-> get_init.c #how to create the object (replace default)
|
||||
|-> arg_get_shutdown.c #free arguments
|
||||
|-> get_shutdown.c #how to free the object (replace default)
|
||||
| -- Property Set --
|
||||
|-> arg_set_init.c #initialize propety set arguments (arg_<argument_name>)
|
||||
|-> set_init.c #how to create the object (replace default)
|
||||
|-> arg_set_shutdown.c #free arguments
|
||||
|-> set_shutdown.c #how to free the object (replace default)
|
||||
|
||||
Event Tests
|
||||
- Tests Events custom files
|
||||
* `src/test/<testname>/<class_name>/<event_name>/`
|
||||
|-> init.cs #add how to initialize the objects
|
||||
|-> custom.cs #add customizations in callback
|
||||
|-> shutdown.cs #add shutdown or any method to call the event
|
||||
|
||||
to make some custom files you only need a code using:
|
||||
`parent` -> default name of parent object defined as `Eo *`
|
||||
`obj` -> default name of current object
|
||||
`arg_<name>` -> replace <name> with functions arguments name
|
||||
|
||||
you can use custom.c (suite or class) to add specilized code, structs and callbacks
|
||||
|
||||
-- Use `*.cs` to Emono/CSharp generated code --
|
||||
|
||||
Some class or function test don't need a test in some Suite, you can disable test generated
|
||||
of it with a blank file as following:
|
||||
|
||||
use lowercase and `_` as separator
|
||||
`src/test/<testname>/<class_name>` #don't generate test for <class_name>
|
||||
`src/test/<testname>/<class_name>/method_name` #don't generate test for <method_name>
|
||||
`src/test/<testname>/<class_name>/<property_name>` #don't generate test for this property
|
||||
`src/test/<testname>/<class_name>/<property_name>_get` #don't generate test for this property get
|
||||
`src/test/<testname>/<class_name>/<property_name>_set` #don't generate test for this property set
|
||||
|
||||
|
||||
Where to find more info
|
||||
=======================
|
||||
|
||||
* read the Pyolian README file in EFL scripts
|
||||
* read the eolian.py file (it declare the full eolian API)
|
||||
* read the generator.py file (it's super simple)
|
||||
* read the original [pyratemp docs](https://www.simple-is-better.org/template/pyratemp.html)
|
||||
|
||||
|
||||
Note
|
||||
====
|
||||
|
||||
This markdown file is mirrored in efl src tree (src/scripts/pyolian) and in
|
||||
phab wiki (phab.enlightenment.org/w/pyolian). Don't forget to update the other
|
||||
if you change one!
|
|
@ -0,0 +1,307 @@
|
|||
#!/usr/bin/env python3
|
||||
# encoding: utf-8
|
||||
from enum import IntEnum, IntFlag
|
||||
|
||||
from testgen import name_helpers
|
||||
|
||||
|
||||
class Function_List_Type(IntFlag):
|
||||
OWN = 1
|
||||
IMPLEMENTS = 2 # Overrides
|
||||
EXTENSIONS = 4 # Interfaces/Mixins
|
||||
INHERITED = 8 # Inherited but not overriden methods and classes
|
||||
INHERITS_FULL = 4 & 8
|
||||
|
||||
|
||||
class EKeys:
|
||||
def __init__(self, ext):
|
||||
self.ext = ext
|
||||
self.dicttypes = {}
|
||||
self.keywords = []
|
||||
self.verbs = []
|
||||
self.blacklist = ["efl_constructor"]
|
||||
self.keyloads = ["init", "shutdown", "custom"]
|
||||
self.implementsbl = ["construtor", "destructor", "finalize"]
|
||||
self.funclist = Function_List_Type.OWN | Function_List_Type.IMPLEMENTS
|
||||
|
||||
def type_convert(self, eotype):
|
||||
return eotype.name
|
||||
|
||||
def event_convert(self, event):
|
||||
return event.c_macro
|
||||
|
||||
def print_arg(self, eoarg):
|
||||
return "arg_{}".format(eoarg.name)
|
||||
|
||||
def format_name(self, func):
|
||||
return self.name
|
||||
|
||||
|
||||
class EMonoKeys(EKeys):
|
||||
def __init__(self, ext):
|
||||
super().__init__(ext)
|
||||
self.funclist = (
|
||||
Function_List_Type.OWN
|
||||
| Function_List_Type.IMPLEMENTS
|
||||
| Function_List_Type.EXTENSIONS
|
||||
)
|
||||
self.dicttypes = {
|
||||
"byte": "sbyte",
|
||||
"llong": "long",
|
||||
"int8": "sbyte",
|
||||
"int16": "short",
|
||||
"int32": "int",
|
||||
"int64": "long",
|
||||
"ssize": "long",
|
||||
"ubyte": "byte",
|
||||
"ullong": "ulong",
|
||||
"uint8": "byte",
|
||||
"uint16": "ushort",
|
||||
"uint32": "uint",
|
||||
"uint64": "ulong",
|
||||
"size": "ulong",
|
||||
"ptrdiff": "long",
|
||||
"intptr": "System.IntPtr",
|
||||
"uintptr": "System.IntPtr",
|
||||
"void_ptr": "System.IntPtr",
|
||||
"void": "System.IntPtr", # only if is out/inout
|
||||
"Error": "Eina.Error",
|
||||
"string": "System.String",
|
||||
"mstring": "System.String",
|
||||
"stringshare": "System.String",
|
||||
"any_value": "Eina.Value",
|
||||
"any_value_ref": "Eina.Value"
|
||||
# complex Types
|
||||
,
|
||||
"list": "Eina.List",
|
||||
"inlist": "Eina.Inlist",
|
||||
"array": "Eina.Array",
|
||||
"inarray": "Eina.Inarray",
|
||||
"hash": "Eina.Hash",
|
||||
"promise": "int",
|
||||
"future": "int",
|
||||
"iterator": "Eina.Iterator",
|
||||
"accessor": "Eina.Accessor",
|
||||
"strbuf": "Eina.Strbuf",
|
||||
"Efl.Class": "System.Type",
|
||||
"rw_slice": "Eina.RwSlice",
|
||||
"slice": "Eina.Slice",
|
||||
}
|
||||
|
||||
self.keywords = [
|
||||
"delete",
|
||||
"do",
|
||||
"lock",
|
||||
"event",
|
||||
"in",
|
||||
"object",
|
||||
"interface",
|
||||
"string",
|
||||
"internal",
|
||||
"fixed",
|
||||
"base",
|
||||
]
|
||||
|
||||
self.verbs = [
|
||||
"add",
|
||||
"get",
|
||||
"is",
|
||||
"del",
|
||||
"thaw",
|
||||
"freeze",
|
||||
"save",
|
||||
"wait",
|
||||
"eject",
|
||||
"raise",
|
||||
"lower",
|
||||
"load",
|
||||
"dup",
|
||||
"reset",
|
||||
"unload",
|
||||
"close",
|
||||
"set",
|
||||
"interpolate",
|
||||
"has",
|
||||
"grab",
|
||||
"check",
|
||||
"find",
|
||||
"ungrab",
|
||||
"unset",
|
||||
"clear",
|
||||
"pop",
|
||||
"new",
|
||||
"peek",
|
||||
"push",
|
||||
"update",
|
||||
"show",
|
||||
"move",
|
||||
"hide",
|
||||
"calculate",
|
||||
"resize",
|
||||
"attach",
|
||||
"pack",
|
||||
"unpack",
|
||||
"emit",
|
||||
"call",
|
||||
"append",
|
||||
"apply",
|
||||
"bind",
|
||||
"cancel",
|
||||
"copy",
|
||||
"create",
|
||||
"cut",
|
||||
"delete",
|
||||
"deselect",
|
||||
"detach",
|
||||
"do",
|
||||
"gen",
|
||||
"insert",
|
||||
"iterate",
|
||||
"join",
|
||||
"leave",
|
||||
"limit",
|
||||
"paste",
|
||||
"parse",
|
||||
"prepend",
|
||||
"process",
|
||||
"query",
|
||||
"refresh",
|
||||
"remove",
|
||||
"register",
|
||||
"reject",
|
||||
"release",
|
||||
"reply",
|
||||
"send",
|
||||
"select",
|
||||
"serialize",
|
||||
"steal",
|
||||
"sync",
|
||||
"toggle",
|
||||
"unbind",
|
||||
"unregister"
|
||||
]
|
||||
|
||||
self.blacklist = [
|
||||
"efl_event_callback_array_priority_add",
|
||||
"efl_event_callback_forwarder_priority_add",
|
||||
"efl_player_playback_position_get",
|
||||
"efl_text_font_source",
|
||||
"efl_ui_focus_manager_focus_get",
|
||||
"efl_ui_widget_focus",
|
||||
"efl_ui_text_password",
|
||||
"elm_interface_scrollable_repeat_events",
|
||||
"elm_wdg_item_del",
|
||||
"elm_wdg_item_focus",
|
||||
"elm_interface_scrollable_mirrored_set",
|
||||
"evas_obj_table_mirrored",
|
||||
"edje_obj_load_error_get",
|
||||
"efl_ui_focus_user_parent_get",
|
||||
"efl_canvas_object_scale", # duplicated signature
|
||||
"efl_access_parent_get",
|
||||
"efl_access_name",
|
||||
"efl_access_root_get",
|
||||
"efl_access_type_get",
|
||||
"efl_access_role_get",
|
||||
"efl_access_action_description",
|
||||
"efl_access_image_description",
|
||||
"efl_access_component_layer_get", # duplicated signature
|
||||
"efl_access_component_alpha_get",
|
||||
"efl_access_component_size_get",
|
||||
"efl_ui_spin_button_loop_get",
|
||||
"efl_ui_list_model_size_get",
|
||||
"efl_ui_list_relayout_layout_do",
|
||||
"efl_constructor",
|
||||
]
|
||||
|
||||
self.struct_blacklist = [
|
||||
"Efl.Event_Description",
|
||||
"Eina.Binbuf",
|
||||
"Eina.Strbuf",
|
||||
"Eina.Slice",
|
||||
"Eina.Rw_Slice",
|
||||
"Eina.Promise",
|
||||
"Eina.Value",
|
||||
"Eina.Value_Type",
|
||||
"Eina.Future",
|
||||
]
|
||||
|
||||
def escape_keyword(self, key):
|
||||
key = "kw_{}".format(key) if key in self.keywords else key
|
||||
return "{}Add".format(key) if key == "Finalize" else key
|
||||
|
||||
def direction_get(self, param):
|
||||
direction = param.direction
|
||||
|
||||
if direction == direction.INOUT:
|
||||
return "ref"
|
||||
elif direction != direction.IN:
|
||||
if param.type.name in ("slice", "rw_slice"):
|
||||
return "ref"
|
||||
else:
|
||||
return "out"
|
||||
elif (direction == direction.IN) and param.type.is_ptr:
|
||||
if param.type.typedecl and (
|
||||
param.type.typedecl.type == param.type.typedecl.type.STRUCT
|
||||
):
|
||||
return "ref" if param.type.name not in self.struct_blacklist else None
|
||||
|
||||
return None
|
||||
|
||||
def klass_name(self, eotype):
|
||||
*namespaces, name = eotype.name.split(".")
|
||||
namespaces = [self.escape_keyword(x.lower()) for x in namespaces]
|
||||
is_interface = eotype.type == eotype.type.CLASS
|
||||
k_name = ("I" if is_interface else "") + name
|
||||
return ".".join(namespaces + [k_name])
|
||||
|
||||
def type_convert(self, eotype):
|
||||
if eotype.type == eotype.type.VOID:
|
||||
return "System.IntPtr"
|
||||
|
||||
new_type = self.dicttypes.get(
|
||||
eotype.name, name_helpers.type_managed_name(eotype)
|
||||
)
|
||||
if new_type not in ("Eina.RwSlice", "Eina.Slice") and eotype.base_type:
|
||||
# Stringshare is a special case where its C# type differs if inside or outside
|
||||
# a container:
|
||||
# - Non-contained stringshares are directly converted to strings.
|
||||
# - Contained stringshares are kept as the container parameter as a tag to
|
||||
# marshal the value correctly whem adding/removing items from the container.
|
||||
if eotype.base_type.name == "stringshare":
|
||||
base_type = "Eina.Stringshare"
|
||||
else:
|
||||
base_type = self.dicttypes.get(
|
||||
eotype.base_type.name,
|
||||
name_helpers.type_managed_name(eotype.base_type),
|
||||
)
|
||||
new_type = "{}<{}>".format(new_type, base_type)
|
||||
|
||||
return new_type
|
||||
|
||||
def event_convert(self, event):
|
||||
return "{}Evt".format("".join([i.capitalize() for i in event.name.split(",")]))
|
||||
|
||||
def print_arg(self, eoarg):
|
||||
r = super().print_arg(eoarg)
|
||||
prefix = self.direction_get(eoarg) or None
|
||||
|
||||
return " ".join([prefix, r]) if prefix else r
|
||||
|
||||
def format_name(self, func):
|
||||
names = func.comp.name.split("_")
|
||||
|
||||
if func.type == func.type.METHOD and names[-1] in self.verbs:
|
||||
names.insert(0, names.pop())
|
||||
|
||||
fname = "".join([name.capitalize() for name in names])
|
||||
|
||||
if func.type == func.type.METHOD:
|
||||
fname = self.escape_keyword(fname)
|
||||
|
||||
return fname
|
||||
|
||||
|
||||
def GetKey(ext):
|
||||
if ext == ".cs":
|
||||
return EMonoKeys(ext)
|
||||
return EKeys(ext)
|
|
@ -0,0 +1,92 @@
|
|||
#!/usr/bin/env python3
|
||||
# encoding: utf-8
|
||||
|
||||
"""Helper module with naming rules for the C# binding."""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
# Hackish way of detecting pyolian...
|
||||
script_path = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
if "EFL_DIR" in os.environ:
|
||||
root_path = os.environ["EFL_DIR"]
|
||||
else:
|
||||
root_path = os.path.abspath(os.path.join(script_path, "..", "..", ".."))
|
||||
|
||||
sys.path.insert(0, os.path.join(root_path, "src", "scripts"))
|
||||
|
||||
from pyolian import eolian
|
||||
|
||||
|
||||
def remove_underlines(name):
|
||||
"""Removes underlines from name"""
|
||||
return name.replace("_", "")
|
||||
|
||||
|
||||
def managed_name(name):
|
||||
"""Replaces underlines and capitalize first letter of each word"""
|
||||
|
||||
words = name.split("_")
|
||||
return "".join(word[0].upper() + word[1:] for word in words)
|
||||
|
||||
|
||||
def managed_namespaces(namespaces):
|
||||
"""Converts an eolian list of namespaces into the managed namespace"""
|
||||
return ".".join(remove_underlines(nsp) for nsp in namespaces)
|
||||
|
||||
|
||||
def class_managed_name(cls):
|
||||
"""Gets the full managed name of the given eolian class"""
|
||||
ret = managed_namespaces(cls.namespaces)
|
||||
|
||||
if ret:
|
||||
ret += "."
|
||||
|
||||
if cls.type in (eolian.Eolian_Class_Type.INTERFACE, eolian.Eolian_Class_Type.MIXIN):
|
||||
ret += "I"
|
||||
|
||||
ret += remove_underlines(cls.short_name)
|
||||
|
||||
if ret == "Efl.Class":
|
||||
return "System.Type"
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def type_managed_name(type):
|
||||
"""Gets the full managed name of a given type."""
|
||||
if type.type == eolian.Eolian_Type_Type.CLASS:
|
||||
return class_managed_name(type.class_)
|
||||
|
||||
ret = managed_namespaces(type.namespaces)
|
||||
|
||||
if ret:
|
||||
ret += "."
|
||||
|
||||
ret += remove_underlines(type.short_name)
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
# Need to pass the class as it is not accessible from Event in Pyolian
|
||||
def event_args_managed_name(event, cls):
|
||||
"""Gets the full managed name of the event arguments struct"""
|
||||
if event.type is None:
|
||||
return "System.EventArgs"
|
||||
|
||||
ret = class_managed_name(cls)
|
||||
|
||||
return ret + managed_name(event.myname) + "EventArgs"
|
||||
|
||||
|
||||
def event_managed_short_name(event):
|
||||
"""Gets the managed short name of an event"""
|
||||
|
||||
return managed_name(event.name.replace(",", "_")) + "Event"
|
||||
|
||||
|
||||
def enum_field_managed_name(field):
|
||||
"""Gets the managed name of an Enum field"""
|
||||
|
||||
return managed_name(field.name)
|
|
@ -0,0 +1,291 @@
|
|||
import itertools
|
||||
import os
|
||||
from pyolian.eolian import Eolian_Function_Type, Eolian_Class_Type, Eolian_Object_Scope
|
||||
from .ekeys import GetKey, Function_List_Type
|
||||
from pyolian import eolian
|
||||
|
||||
from testgen import name_helpers
|
||||
|
||||
|
||||
class BaseItem:
|
||||
def __init__(self, path, keys, prefix=""):
|
||||
self.path = path
|
||||
self.keys = keys
|
||||
self.prefix = prefix
|
||||
|
||||
def __getattr__(self, attr):
|
||||
if not attr.split("_")[-1] in self.keys.keyloads:
|
||||
raise AttributeError("Error getting {}".format(attr))
|
||||
|
||||
filename = os.path.join(self.path, self.prefix + attr) + self.keys.ext
|
||||
if os.path.isfile(filename):
|
||||
with open(filename, "r") as f:
|
||||
return f.read()
|
||||
return None
|
||||
|
||||
|
||||
class ComItem(BaseItem):
|
||||
def __init__(self, comp, path, keys):
|
||||
super().__init__(path, keys)
|
||||
self.comp = comp
|
||||
|
||||
def __getattr__(self, attr):
|
||||
if hasattr(self.comp, attr):
|
||||
return getattr(self.comp, attr)
|
||||
return super().__getattr__(attr)
|
||||
|
||||
|
||||
class FuncItem(ComItem):
|
||||
def __init__(self, comp, path, keys):
|
||||
super().__init__(comp, os.path.join(path, comp.name), keys)
|
||||
|
||||
self.has_getter = (
|
||||
comp.type in (Eolian_Function_Type.PROP_GET, Eolian_Function_Type.PROPERTY)
|
||||
and comp.full_c_getter_name not in keys.blacklist
|
||||
and comp.getter_scope == Eolian_Object_Scope.PUBLIC
|
||||
and not os.path.isfile("{}_get".format(os.path.join(path, comp.name)))
|
||||
)
|
||||
self.has_setter = (
|
||||
comp.type in (Eolian_Function_Type.PROP_SET, Eolian_Function_Type.PROPERTY)
|
||||
and comp.full_c_setter_name not in keys.blacklist
|
||||
and comp.setter_scope == Eolian_Object_Scope.PUBLIC
|
||||
and not os.path.isfile("{}_set".format(os.path.join(path, comp.name)))
|
||||
)
|
||||
|
||||
self.is_enum = (
|
||||
lambda arg: arg.type
|
||||
and arg.type.typedecl
|
||||
and arg.type.typedecl.type == arg.type.typedecl.type.ENUM
|
||||
)
|
||||
self.is_number = lambda arg: arg.type and arg.type.builtin_type in (
|
||||
arg.type.builtin_type.INT,
|
||||
arg.type.builtin_type.UINT,
|
||||
arg.type.builtin_type.LONG,
|
||||
arg.type.builtin_type.ULONG,
|
||||
arg.type.builtin_type.LLONG,
|
||||
arg.type.builtin_type.ULLONG,
|
||||
arg.type.builtin_type.INT8,
|
||||
arg.type.builtin_type.UINT8,
|
||||
arg.type.builtin_type.INT16,
|
||||
arg.type.builtin_type.UINT16,
|
||||
arg.type.builtin_type.INT32,
|
||||
arg.type.builtin_type.UINT32,
|
||||
arg.type.builtin_type.INT64,
|
||||
arg.type.builtin_type.UINT64,
|
||||
arg.type.builtin_type.INT128,
|
||||
arg.type.builtin_type.UINT128,
|
||||
)
|
||||
|
||||
@property
|
||||
def getter_args(self):
|
||||
return itertools.chain(self.getter_values, self.getter_keys)
|
||||
|
||||
@property
|
||||
def setter_args(self):
|
||||
return itertools.chain(self.setter_values, self.setter_keys)
|
||||
|
||||
@property
|
||||
def format_name(self):
|
||||
return self.keys.format_name(self)
|
||||
|
||||
|
||||
class EventItem(ComItem):
|
||||
def __init__(self, comp, path, keys):
|
||||
self.myname = comp.name.replace(",", "_")
|
||||
super().__init__(comp, os.path.join(path, self.myname), keys)
|
||||
self.format_name = self.keys.event_convert(self)
|
||||
|
||||
|
||||
class ClassItem(ComItem):
|
||||
def __init__(self, comp, path, keys):
|
||||
self.myname = os.path.splitext(comp.file)[0]
|
||||
super().__init__(comp, os.path.join(path, self.myname), keys)
|
||||
|
||||
def mfilter(f):
|
||||
if f.full_c_method_name in self.keys.blacklist:
|
||||
return False
|
||||
|
||||
if os.path.isfile(os.path.join(self.path, f.name)):
|
||||
return False
|
||||
|
||||
if f.type == Eolian_Function_Type.PROPERTY:
|
||||
if f.getter_scope != Eolian_Object_Scope.PUBLIC:
|
||||
scope = f.setter_scope
|
||||
else:
|
||||
scope = f.getter_scope
|
||||
else:
|
||||
scope = f.scope_get(f.type)
|
||||
|
||||
if scope != Eolian_Object_Scope.PUBLIC:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
if self.keys.funclist & Function_List_Type.OWN:
|
||||
self._methods = {
|
||||
m.name: FuncItem(m, self.path, keys)
|
||||
for m in self.comp.methods
|
||||
if mfilter(m)
|
||||
}
|
||||
self._properties = {
|
||||
p.name: FuncItem(p, self.path, keys)
|
||||
for p in self.comp.properties
|
||||
if mfilter(p)
|
||||
}
|
||||
self._events = {
|
||||
e.name: EventItem(e, self.path, keys) for e in self.comp.events
|
||||
}
|
||||
else:
|
||||
self._methods = {}
|
||||
self._properties = {}
|
||||
self._events = {}
|
||||
|
||||
if self.keys.funclist & Function_List_Type.IMPLEMENTS:
|
||||
for imp in comp.implements:
|
||||
|
||||
if (
|
||||
imp.namespace == self.name
|
||||
or imp.short_name.lower() in self.keys.implementsbl
|
||||
):
|
||||
continue
|
||||
|
||||
f = imp.function
|
||||
|
||||
if not mfilter(f):
|
||||
continue
|
||||
|
||||
if f.type == Eolian_Function_Type.METHOD:
|
||||
if f.name in self._methods:
|
||||
continue
|
||||
self._methods[f.name] = FuncItem(f, self.path, keys)
|
||||
elif f.type in (
|
||||
Eolian_Function_Type.PROPERTY,
|
||||
Eolian_Function_Type.PROP_GET,
|
||||
Eolian_Function_Type.PROP_SET,
|
||||
):
|
||||
if f.name in self._properties:
|
||||
continue
|
||||
self._properties[f.name] = FuncItem(f, self.path, keys)
|
||||
|
||||
parents = []
|
||||
|
||||
if self.keys.funclist & Function_List_Type.INHERITS_FULL:
|
||||
# Use inherits full to get inherited interfaces too
|
||||
parents = self.comp.inherits_full
|
||||
else:
|
||||
if self.keys.funclist & Function_List_Type.EXTENSIONS:
|
||||
parents = self.comp.extensions_hierarchy
|
||||
|
||||
if self.keys.funclist & Function_List_Type.INHERITED:
|
||||
if parents:
|
||||
parents = itertools.chain(self.comp.hierarchy, parents)
|
||||
else:
|
||||
parents = self.comp.hierarchy
|
||||
|
||||
for eoclass in parents:
|
||||
for f in filter(mfilter, eoclass.methods):
|
||||
if f.name in self._methods:
|
||||
continue
|
||||
self._methods[f.name] = FuncItem(f, self.path, keys)
|
||||
for f in filter(mfilter, eoclass.properties):
|
||||
if f.name in self._properties:
|
||||
continue
|
||||
self._properties[f.name] = FuncItem(f, self.path, keys)
|
||||
|
||||
@property
|
||||
def properties(self):
|
||||
return filter(lambda p: p.has_setter or p.has_getter, self._properties.values())
|
||||
|
||||
@property
|
||||
def properties_get(self):
|
||||
return filter(lambda p: p.has_getter, self._properties.values())
|
||||
|
||||
@property
|
||||
def properties_set(self):
|
||||
return filter(lambda p: p.has_setter, self._properties.values())
|
||||
|
||||
@property
|
||||
def methods(self):
|
||||
return self._methods.values()
|
||||
|
||||
@property
|
||||
def events(self):
|
||||
return self._events.values()
|
||||
|
||||
def __iter__(self):
|
||||
return itertools.chain(self.methods, self.properties)
|
||||
|
||||
|
||||
class SuiteGen(BaseItem):
|
||||
def __init__(self, name, testname, filename, path, template=None):
|
||||
keys = GetKey(os.path.splitext(filename)[1])
|
||||
super().__init__(path, keys, name + "_")
|
||||
self.name = name
|
||||
self.testname = testname
|
||||
self.fullname = "_".join([name, testname]) if testname else name
|
||||
self.filename = filename
|
||||
self.template = template
|
||||
self.clslist = []
|
||||
|
||||
if not self.template:
|
||||
script_path = os.path.dirname(os.path.realpath(__file__))
|
||||
self.template = os.path.join(
|
||||
script_path, "testgenerator{}.template".format(self.keys.ext)
|
||||
)
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self.clslist)
|
||||
|
||||
def type_convert(self, eotype):
|
||||
if eotype.type == eolian.Eolian_Type_Type.CLASS:
|
||||
return name_helpers.class_managed_name(eotype.class_)
|
||||
|
||||
if eotype.typedecl:
|
||||
return name_helpers.type_managed_name(eotype)
|
||||
|
||||
return self.keys.type_convert(eotype)
|
||||
|
||||
def constructor_params(self, cls):
|
||||
ret = []
|
||||
|
||||
constructors = itertools.chain(
|
||||
cls.constructors, *[base.constructors for base in cls.inherits_full]
|
||||
)
|
||||
|
||||
for constructor in constructors:
|
||||
# Skip optional constructors for now
|
||||
if constructor.is_optional:
|
||||
continue
|
||||
func = constructor.function
|
||||
|
||||
if func.type == eolian.Eolian_Function_Type.PROPERTY:
|
||||
first_param = list(func.setter_values)[0]
|
||||
else:
|
||||
first_param = list(func.parameters)[0]
|
||||
param_type = first_param.type
|
||||
|
||||
ret.append("default({})".format(name_helpers.type_managed_name(param_type)))
|
||||
|
||||
return (", " if ret else "") + ", ".join(ret)
|
||||
|
||||
def print_arg(self, eoarg):
|
||||
return self.keys.print_arg(eoarg)
|
||||
|
||||
def intersect(self, a, b):
|
||||
return list(set(a) & set(b))
|
||||
|
||||
def loadFiles(self, eolian_db, eofiles):
|
||||
self.clslist.clear()
|
||||
for eofile in eofiles:
|
||||
eocls = eolian_db.class_by_file_get(os.path.basename(eofile))
|
||||
if not eocls or eocls.type != Eolian_Class_Type.REGULAR:
|
||||
continue
|
||||
self.loadObj(eocls)
|
||||
|
||||
def loadObj(self, eocls):
|
||||
cls = ClassItem(eocls, self.path, self.keys)
|
||||
if not os.path.isfile(cls.path):
|
||||
cls.myfullname = "{}_{}".format(self.fullname, cls.myname)
|
||||
self.clslist.append(cls)
|
||||
else:
|
||||
print("removing {} Class from generated list".format(cls.name))
|
|
@ -0,0 +1,125 @@
|
|||
#!/usr/bin/env python3
|
||||
# encoding: utf-8
|
||||
|
||||
import os
|
||||
import sys
|
||||
import datetime
|
||||
|
||||
|
||||
script_path = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
if "EFL_DIR" in os.environ:
|
||||
root_path = os.environ["EFL_DIR"]
|
||||
else:
|
||||
root_path = os.path.abspath(os.path.join(script_path, "..", "..", ".."))
|
||||
|
||||
sys.path.insert(0, os.path.join(root_path, "src", "scripts"))
|
||||
|
||||
from pyolian import eolian
|
||||
from pyolian import pyratemp
|
||||
from testgen.suitegen import SuiteGen
|
||||
from testgen import name_helpers
|
||||
|
||||
# Use .eo files from the source tree (not the installed ones)
|
||||
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)
|
||||
|
||||
|
||||
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, suite, verbose=True):
|
||||
# Build the context for the template
|
||||
ctx = {}
|
||||
ctx["suite"] = suite
|
||||
ctx["name_helpers"] = name_helpers
|
||||
# render with the augmented context
|
||||
output = self(**ctx)
|
||||
|
||||
if suite.filename is not None:
|
||||
# write to file
|
||||
with open(suite.filename, "w") as f:
|
||||
f.write(output)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description="Eolian Test Generator.")
|
||||
parser.add_argument(
|
||||
"testname",
|
||||
help="The Test Name used to find custom and template files. (REQUIRED)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"suitename", help="The Suite Name used to find custom files. (REQUIRED)"
|
||||
)
|
||||
parser.add_argument("filename", help="Generated test file destination. (REQUIRED)")
|
||||
parser.add_argument("eofiles", nargs="*", help="The Eolian Files to use.")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
testdir = os.path.join(root_path, "src", "tests", args.testname)
|
||||
|
||||
suite = SuiteGen(args.suitename, args.testname, args.filename, testdir)
|
||||
suite.loadFiles(eolian_db, args.eofiles)
|
||||
|
||||
t = Template(suite.template)
|
||||
# try:
|
||||
t.render(suite)
|
||||
# except:
|
||||
# print("ERROR RENDERING - Cannot create file: {}".format(suite.filename))
|
|
@ -0,0 +1,187 @@
|
|||
<!--(macro m_show)-->
|
||||
<!--(if mshow)-->
|
||||
${mshow}$#!
|
||||
<!--(end)-->
|
||||
<!--(end)-->
|
||||
<!--(macro init)-->
|
||||
Eo *parent = NULL;
|
||||
Eo *obj = NULL;
|
||||
|
||||
<!--(if exists("mfunc") and mfunc!= None)-->
|
||||
${mfunc}$
|
||||
<!--(elif exists("mcls") and mcls!= None)-->
|
||||
${mcls}$
|
||||
<!--(else)-->
|
||||
obj = efl_add_ref(${cls.c_macro}$, parent);
|
||||
fail_if(!obj, "ERROR: Cannot init ${cls.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);
|
||||
<!--(end)-->
|
||||
<!--(macro arg_default)-->
|
||||
<!--(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)-->;
|
||||
<!--(end)-->
|
||||
<!--(macro args_declaration)-->
|
||||
<!--(for arg in args)-->
|
||||
<!--(if arg.type.typedecl and arg.type.typedecl.type == arg.type.typedecl.type.FUNCTION_POINTER)-->
|
||||
void * arg_${arg.name}$_data = NULL;
|
||||
${arg.type.c_type_param}$ arg_${arg.name}$ = NULL;
|
||||
Eina_Free_Cb arg_${arg.name}$_free_cb = NULL;
|
||||
<!--(else)-->
|
||||
${arg.type.c_type_param}$ arg_${arg.name}$ = ${arg_default(arg=arg)}$
|
||||
<!--(end)-->
|
||||
<!--(end)-->
|
||||
<!--(end)-->
|
||||
<!--(macro print_arg)-->
|
||||
<!--(if arg.type.typedecl and arg.type.typedecl.type == arg.type.typedecl.type.FUNCTION_POINTER)-->
|
||||
arg_${arg.name}$_data, arg_${arg.name}$, arg_${arg.name}$_free_cb
|
||||
<!--(else)-->
|
||||
<!--(if arg.direction in (arg.direction.OUT, arg.direction.INOUT))-->&<!--(end)-->arg_${arg.name}$
|
||||
<!--(end)-->
|
||||
<!--(end)-->
|
||||
<!--(macro arg_self)-->
|
||||
<!--(if not func.is_class)-->
|
||||
obj
|
||||
<!--(end)-->
|
||||
<!--(end)-->
|
||||
<!--(macro print_comma)-->
|
||||
<!--(if i > 0 or not is_class)-->
|
||||
,
|
||||
<!--(end)-->
|
||||
<!--(end)-->
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <check.h>
|
||||
#include "efl_check.h"
|
||||
${m_show(mshow=suite.custom)}$#!
|
||||
#include <Elementary.h>
|
||||
|
||||
<!--(for cls in suite)-->
|
||||
void ${cls.myfullname}$_test(TCase *tc);
|
||||
<!--(end)-->
|
||||
|
||||
static const Efl_Test_Case etc[] = {
|
||||
<!--(for cls in suite)-->
|
||||
{ "${suite.name.capitalize()}$ ${suite.testname.capitalize()}$ ${cls.myname.capitalize()}$", ${cls.myfullname}$_test },
|
||||
<!--(end)-->
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
<!--(for cls in suite)-->
|
||||
|
||||
/**************** TEST CASE ${cls.c_macro}$ ****************/
|
||||
${m_show(mshow=cls.custom)}$#!
|
||||
|
||||
START_TEST(${cls.myfullname}$_smoke)
|
||||
{
|
||||
${init(mcls=cls.init)}$
|
||||
${shutdown(mcls=cls.shutdown)}$
|
||||
}
|
||||
END_TEST
|
||||
|
||||
<!--(for func in cls.methods)-->
|
||||
START_TEST(${cls.myfullname}$_${func.full_c_method_name}$)
|
||||
{
|
||||
${args_declaration(args=func.parameters)}$${init(mcls=cls.init,mfunc=func.init)}$
|
||||
${m_show(mshow=func.arg_init)}$#!
|
||||
<!--(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)-->);
|
||||
<!--(if func.method_return_type)-->(void)r;<!--(end)-->
|
||||
${m_show(mshow=func.arg_shutdown)}$#!
|
||||
${shutdown(mcls=cls.shutdown,mfunc=func.shutdown)}$
|
||||
}
|
||||
END_TEST
|
||||
|
||||
<!--(end)-->
|
||||
|
||||
<!--(for func in cls.properties)-->
|
||||
<!--(if func.has_getter)-->
|
||||
START_TEST(${cls.myfullname}$_${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.get_init)}$
|
||||
${m_show(mshow=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)-->);
|
||||
(void)r;
|
||||
<!--(else)-->
|
||||
${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)-->);
|
||||
<!--(end)-->
|
||||
${m_show(mshow=func.arg_get_shutdown)}$#!
|
||||
${shutdown(mcls=cls.shutdown,mfunc=func.get_shutdown)}$
|
||||
}
|
||||
END_TEST
|
||||
|
||||
<!--(end)-->
|
||||
<!--(if func.has_setter)-->
|
||||
START_TEST(${cls.myfullname}$_${func.full_c_setter_name}$)
|
||||
{
|
||||
${args_declaration(args=func.setter_keys)}$${args_declaration(args=func.setter_values)}$${init(mcls=cls.init,mfunc=func.set_init)}$
|
||||
${m_show(mshow=func.arg_set_init)}$#!
|
||||
${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)-->);
|
||||
${m_show(mshow=func.arg_set_shutdown)}$#!
|
||||
${shutdown(mcls=cls.shutdown,mfunc=func.set_shutdown)}$
|
||||
}
|
||||
END_TEST
|
||||
|
||||
<!--(end)-->
|
||||
<!--(end)-->
|
||||
void ${cls.myfullname}$_test(TCase *tc)
|
||||
{
|
||||
tcase_add_test(tc, ${cls.myfullname}$_smoke);
|
||||
<!--(for func in cls.methods)-->
|
||||
tcase_add_test(tc, ${cls.myfullname}$_${func.full_c_method_name}$);
|
||||
<!--(end)-->
|
||||
<!--(for func in cls.properties_get)-->
|
||||
tcase_add_test(tc, ${cls.myfullname}$_${func.full_c_getter_name}$);
|
||||
<!--(end)-->
|
||||
<!--(for func in cls.properties_set)-->
|
||||
tcase_add_test(tc, ${cls.myfullname}$_${func.full_c_setter_name}$);
|
||||
<!--(end)-->
|
||||
}
|
||||
<!--(end)-->
|
||||
|
||||
SUITE_INIT(${suite.name}$)
|
||||
{
|
||||
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");
|
||||
${m_show(mshow=suite.init)}$#!
|
||||
}
|
||||
|
||||
SUITE_SHUTDOWN(${suite.name}$)
|
||||
{
|
||||
${m_show(mshow=suite.shutdown)}$#!
|
||||
ecore_shutdown();
|
||||
eina_shutdown();
|
||||
}
|
||||
|
||||
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,
|
||||
"${suite.fullname}$", etc, SUITE_INIT_FN(${suite.name}$), SUITE_SHUTDOWN_FN(${suite.name}$));
|
||||
|
||||
return (failed_count == 0) ? 0 : 255;
|
||||
}
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
<!--(macro m_show)-->
|
||||
<!--(if mshow)-->
|
||||
${mshow}$#!
|
||||
<!--(end)-->
|
||||
<!--(end)-->
|
||||
<!--(macro def_obj)-->${name_helpers.class_managed_name(param.type.class_)}$ arg_${param.name}$ = null;<!--(end)-->
|
||||
<!--(macro def_param)-->
|
||||
<!--(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)-->
|
||||
<!--(end)-->
|
||||
<!--(macro def_params)-->
|
||||
<!--(for p in parameters)-->
|
||||
${def_param(param=p)}$
|
||||
<!--(end)-->
|
||||
<!--(end)-->
|
||||
<!--(macro meth_target)-->
|
||||
<!--(if func.is_class)-->${name_helpers.class_managed_name(cls)}$<!--(else)-->obj<!--(end)-->
|
||||
<!--(end)-->
|
||||
using System;
|
||||
|
||||
namespace TestSuite
|
||||
{
|
||||
<!--(if suite.custom)-->${suite.custom}$<!--(end)-->
|
||||
<!--(for cls in suite)-->
|
||||
/**************** TEST CASE ${cls.c_macro}$ ****************/
|
||||
class Test${cls.name.replace('.','')}$
|
||||
{
|
||||
|
||||
${name_helpers.class_managed_name(cls)}$ obj;
|
||||
${m_show(mshow=cls.custom)}$#!
|
||||
|
||||
public void SetUp()
|
||||
{
|
||||
${m_show(mshow=suite.init)}$#!
|
||||
<!--(if cls.init)-->
|
||||
${cls.init}$
|
||||
<!--(else)-->
|
||||
obj = new ${name_helpers.class_managed_name(cls)}$(null${suite.constructor_params(cls)}$);
|
||||
<!--(end)-->
|
||||
}
|
||||
|
||||
public void TearDown()
|
||||
{
|
||||
${m_show(mshow=suite.shutdown)}$#!
|
||||
<!--(if cls.shutdown)-->
|
||||
${cls.shutdown}$
|
||||
<!--(else)-->
|
||||
obj.Dispose();
|
||||
obj = null;
|
||||
<!--(end)-->
|
||||
}
|
||||
|
||||
public void smoke()
|
||||
{
|
||||
}
|
||||
|
||||
#! METHODS
|
||||
<!--(for func in cls.methods)-->
|
||||
public void ${func.name}$()
|
||||
{
|
||||
<!--(if len(list(func.parameters)) > 0)-->
|
||||
${def_params(parameters=func.parameters)}$
|
||||
<!--(end)-->
|
||||
${m_show(mshow=func.arg_init)}$#!
|
||||
${m_show(mshow=func.init)}$#!
|
||||
<!--(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])}$);
|
||||
${m_show(mshow=func.arg_shutdown)}$#!
|
||||
${m_show(mshow=func.shutdown)}$#!
|
||||
}
|
||||
|
||||
<!--(end)-->
|
||||
#! PROPERTIES FUNCTION GET
|
||||
<!--(for func in cls.properties)-->
|
||||
<!--(if func.has_getter)-->
|
||||
public void ${func.name}$_pget()
|
||||
{
|
||||
<!--(if func.getter_return_type or len(list(func.getter_values)) > 1)-->
|
||||
${def_params(parameters=func.getter_values)}$
|
||||
<!--(end)-->
|
||||
<!--(if len(list(func.getter_keys)) > 0)-->
|
||||
${def_params(parameters=func.getter_keys)}$
|
||||
<!--(end)-->
|
||||
${m_show(mshow=func.arg_get_init)}$#!
|
||||
${m_show(mshow=func.get_init)}$#!
|
||||
<!--(if not func.getter_return_type and len(list(func.getter_values)) == 1)-->
|
||||
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])}$);
|
||||
<!--(else)-->
|
||||
<!--(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])}$);
|
||||
<!--(end)-->
|
||||
${m_show(mshow=func.arg_get_shutdown)}$#!
|
||||
${m_show(mshow=func.get_shutdown)}$#!
|
||||
}
|
||||
|
||||
<!--(end)-->
|
||||
#! PROPERTIES FUNCTION SET
|
||||
<!--(if func.has_setter)-->
|
||||
public void ${func.name}$_pset()
|
||||
{
|
||||
${def_params(parameters=func.setter_values)}$
|
||||
<!--(if len(list(func.setter_keys)) > 0)-->
|
||||
${def_params(parameters=func.setter_keys)}$
|
||||
<!--(end)-->
|
||||
${m_show(mshow=func.arg_set_init)}$#!
|
||||
${m_show(mshow=func.set_init)}$#!
|
||||
${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)])}$);
|
||||
${m_show(mshow=func.arg_set_shutdown)}$#!
|
||||
${m_show(mshow=func.set_shutdown)}$#!
|
||||
}
|
||||
|
||||
<!--(end)-->
|
||||
<!--(end)-->
|
||||
}
|
||||
<!--(end)-->
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
#include <Ecore.h>
|
||||
#include <Ecore_Audio.h>
|
||||
#include <Ecore_File.h>
|
|
@ -0,0 +1,2 @@
|
|||
int _rinit = ecore_audio_init();
|
||||
ck_assert_int_eq(_rinit, 1);
|
|
@ -0,0 +1 @@
|
|||
arg_input = efl_add(ECORE_AUDIO_IN_CLASS, NULL);
|
|
@ -0,0 +1 @@
|
|||
arg_input = efl_add(ECORE_AUDIO_IN_CLASS, NULL);
|
|
@ -0,0 +1,3 @@
|
|||
#ifdef _WIN32
|
||||
obj = efl_add_ref(ECORE_AUDIO_OUT_WASAPI_CLASS, parent);
|
||||
fail_if(!obj, "ERROR: Cannot init Ecore.Audio.Out.Wasapi!\n")
|
|
@ -0,0 +1,3 @@
|
|||
#else
|
||||
(void)parent;
|
||||
#endif
|
|
@ -0,0 +1,3 @@
|
|||
#include <cairo/Ector_Cairo.h>
|
||||
#include <software/Ector_Software.h>
|
||||
#include <gl/Ector_GL.h>
|
|
@ -0,0 +1 @@
|
|||
fail_if(!ector_init(), "ERROR: Cannot init Ector!\n");
|
|
@ -0,0 +1,2 @@
|
|||
Ector_Surface *surface = efl_add(ECTOR_CAIRO_SOFTWARE_SURFACE_CLASS, NULL);
|
||||
obj = efl_add_ref(ECTOR_RENDERER_CAIRO_SHAPE_CLASS, parent, ector_renderer_surface_set(efl_added, surface));
|
|
@ -0,0 +1 @@
|
|||
ector_shutdown();
|
|
@ -0,0 +1 @@
|
|||
#define EFL_CANVAS_LAYOUT_BETA
|
|
@ -0,0 +1,2 @@
|
|||
fail_if(!ecore_evas_init(), "ERROR: Cannot init Ecore Evas!\n");
|
||||
fail_if(!edje_init(), "ERROR: Cannot init Edje!\n");
|
|
@ -0,0 +1,2 @@
|
|||
edje_shutdown();
|
||||
ecore_evas_shutdown();
|
|
@ -0,0 +1,9 @@
|
|||
parent = evas_new();
|
||||
evas_output_method_set(parent, evas_render_method_lookup("buffer"));
|
||||
Evas_Engine_Info *einfo = evas_engine_info_get(parent);
|
||||
evas_engine_info_set(parent, einfo);
|
||||
|
||||
evas_output_size_set(parent, 500, 500);
|
||||
evas_output_viewport_set(parent, 0, 0, 500, 500);
|
||||
|
||||
(void)obj;
|
|
@ -0,0 +1,9 @@
|
|||
parent = evas_new();
|
||||
evas_output_method_set(parent, evas_render_method_lookup("buffer"));
|
||||
Evas_Engine_Info *einfo = evas_engine_info_get(parent);
|
||||
evas_engine_info_set(parent, einfo);
|
||||
|
||||
evas_output_size_set(parent, 500, 500);
|
||||
evas_output_viewport_set(parent, 0, 0, 500, 500);
|
||||
|
||||
(void)obj;
|
|
@ -0,0 +1,8 @@
|
|||
parent = evas_new();
|
||||
evas_output_method_set(parent, evas_render_method_lookup("buffer"));
|
||||
Evas_Engine_Info *einfo = evas_engine_info_get(parent);
|
||||
evas_engine_info_set(parent, einfo);
|
||||
|
||||
evas_output_size_set(parent, 500, 500);
|
||||
evas_output_viewport_set(parent, 0, 0, 500, 500);
|
||||
(void)obj;
|
|
@ -0,0 +1,8 @@
|
|||
parent = evas_new();
|
||||
evas_output_method_set(parent, evas_render_method_lookup("buffer"));
|
||||
Evas_Engine_Info *einfo = evas_engine_info_get(parent);
|
||||
evas_engine_info_set(parent, einfo);
|
||||
|
||||
evas_output_size_set(parent, 500, 500);
|
||||
evas_output_viewport_set(parent, 0, 0, 500, 500);
|
||||
(void)obj;
|
|
@ -0,0 +1,8 @@
|
|||
parent = evas_new();
|
||||
evas_output_method_set(parent, evas_render_method_lookup("buffer"));
|
||||
Evas_Engine_Info *einfo = evas_engine_info_get(parent);
|
||||
evas_engine_info_set(parent, einfo);
|
||||
|
||||
evas_output_size_set(parent, 500, 500);
|
||||
evas_output_viewport_set(parent, 0, 0, 500, 500);
|
||||
(void)obj;
|
|
@ -0,0 +1,8 @@
|
|||
parent = evas_new();
|
||||
evas_output_method_set(parent, evas_render_method_lookup("buffer"));
|
||||
Evas_Engine_Info *einfo = evas_engine_info_get(parent);
|
||||
evas_engine_info_set(parent, einfo);
|
||||
|
||||
evas_output_size_set(parent, 500, 500);
|
||||
evas_output_viewport_set(parent, 0, 0, 500, 500);
|
||||
(void)obj;
|
|
@ -0,0 +1,2 @@
|
|||
obj = efl_add(EFL_CANVAS_VIDEO_CLASS, parent, efl_canvas_object_legacy_ctor(efl_added));
|
||||
fail_if(!obj, "Error: Canot get obj!\n");
|
|
@ -0,0 +1,9 @@
|
|||
int argc = 2;
|
||||
char *argv[] = { "efl_ui_suite", "test" };
|
||||
(void)parent;
|
||||
|
||||
_EFL_APP_VERSION_SET();
|
||||
obj = efl_app_get();
|
||||
efl_event_callback_add(obj, EFL_LOOP_EVENT_ARGUMENTS, efl_main, NULL);
|
||||
fail_if(!ecore_init_ex(argc, argv));
|
||||
__EFL_MAIN_CONSTRUCTOR;
|
|
@ -0,0 +1,3 @@
|
|||
efl_loop_exit_code_process(r);
|
||||
__EFL_MAIN_DESTRUCTOR;
|
||||
ecore_shutdown_ex();
|
|
@ -0,0 +1,5 @@
|
|||
EAPI_MAIN void
|
||||
efl_main(void *data EINA_UNUSED, const Efl_Event *ev)
|
||||
{
|
||||
efl_loop_quit(ev->object, EINA_VALUE_EMPTY);
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
arg_time = 0.5;
|
|
@ -0,0 +1 @@
|
|||
(void)parent;
|
|
@ -0,0 +1 @@
|
|||
#include <Eio.h>
|
|
@ -0,0 +1 @@
|
|||
fail_if(!eio_init(), "ERROR: Cannot init Eio!\n");
|
|
@ -0,0 +1 @@
|
|||
eio_shutdown();
|
|
@ -0,0 +1 @@
|
|||
fail_if(eldbus_init() < 0, "ERROR: Cannot init Eldbus!\n");
|
|
@ -0,0 +1 @@
|
|||
eldbus_shutdown();
|
|
@ -0,0 +1,2 @@
|
|||
#include "Emotion.h"
|
||||
#include "Evas_Internal.h"
|
|
@ -0,0 +1,3 @@
|
|||
fail_if(!ecore_evas_init(), "ERROR: Cannot init ECore Evas!\n");
|
||||
fail_if(!emotion_init(), "ERROR: Cannot init Emotion!\n");
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
// efl_unref(parent);
|
||||
// ecore_evas_free(ee);
|
||||
emotion_shutdown();
|
||||
// ecore_evas_shutdown();
|
|
@ -0,0 +1 @@
|
|||
#include "efl_canvas_surface.h"
|
Loading…
Reference in New Issue