csharp: Add some tests

Summary:
- Wrappers losing C# ref while alive in Eo
- Inherited instances being collected

Also cleanup GC and loop queue before each test

Reviewers: vitor.sousa

Reviewed By: vitor.sousa

Subscribers: cedric, #reviewers, #committers

Tags: #efl

Differential Revision: https://phab.enlightenment.org/D9063
This commit is contained in:
Lauro Moura 2019-05-31 17:34:59 -03:00 committed by Vitor Sousa
parent 37941b757d
commit 937da0b12c
9 changed files with 189 additions and 2 deletions

View File

@ -69,7 +69,8 @@ efl_mono_test_eolian_files = \
tests/efl_mono/dummy_inherit_helper.eo \
tests/efl_mono/dummy_child.eo \
tests/efl_mono/dummy_part_holder.eo \
tests/efl_mono/dummy_numberwrapper.eo
tests/efl_mono/dummy_numberwrapper.eo \
tests/efl_mono/dummy_event_manager.eo
efl_mono_test_files = \
$(efl_mono_test_eolian_files) \
@ -395,6 +396,7 @@ check_LTLIBRARIES += tests/efl_mono/libefl_mono_native_test.la
tests_efl_mono_libefl_mono_native_test_la_SOURCES = \
tests/efl_mono/dummy_child.c \
tests/efl_mono/dummy_event_manager.c \
tests/efl_mono/dummy_inherit_helper.c \
tests/efl_mono/dummy_interfaces.c \
tests/efl_mono/dummy_numberwrapper.c \
@ -418,6 +420,11 @@ tests/efl_mono/dummy_child.c: \
$(efl_mono_test_eolian_h) \
tests/efl_mono/libefl_mono_native_test.h
tests/efl_mono/dummy_event_manager.c: \
$(efl_mono_test_eolian_c) \
$(efl_mono_test_eolian_h) \
tests/efl_mono/libefl_mono_native_test.h
tests/efl_mono/dummy_inherit_helper.c: \
$(efl_mono_test_eolian_c) \
$(efl_mono_test_eolian_h) \
@ -447,6 +454,7 @@ tests/efl_mono/dummy_test_object.c: \
efl_mono_test_eolian_mono_files = tests/efl_mono/dummy_test_object.eo.cs \
tests/efl_mono/dummy_test_iface.eo.cs \
tests/efl_mono/dummy_child.eo.cs \
tests/efl_mono/dummy_event_manager.eo.cs \
tests/efl_mono/dummy_part_holder.eo.cs \
tests/efl_mono/dummy_numberwrapper.eo.cs \
tests/efl_mono/dummy_inherit_iface.eo.cs \

View File

@ -110,6 +110,20 @@ class TestEoInherit
Efl.Object loop = new MyObject();
Test.Assert(loop.NativeHandle != System.IntPtr.Zero);
}
private static WeakReference CreateCollectableInherited()
{
var obj = new MyObject();
return new WeakReference(obj);
}
public static void inherited_collected()
{
var wref = CreateCollectableInherited();
Test.CollectAndIterate();
Test.AssertNull(wref.Target);
}
}
class TestEoNames

View File

@ -274,4 +274,57 @@ class TestEventNaming
}
}
class TestEventWithDeadWrappers
{
private static WeakReference AttachToManager(Dummy.EventManager manager,
EventHandler<Dummy.TestObjectEvtWithIntEvt_Args> cb)
{
var obj = new Dummy.TestObject();
manager.Emitter = obj;
obj.EvtWithIntEvt += cb;
return new WeakReference(obj);
}
public static void test_event_from_c_owned_wrapper()
{
// Set upon object instantiation
WeakReference wref = null;
// Checks in the callback called
bool callbackCalled = false;
int received = -1;
// attach to evt with int
EventHandler<Dummy.TestObjectEvtWithIntEvt_Args> cb = (object sender, Dummy.TestObjectEvtWithIntEvt_Args args) => {
callbackCalled = true;
received = args.arg;
Test.Assert(Object.ReferenceEquals(sender, wref.Target));
};
Dummy.EventManager manager = new Dummy.EventManager();
wref = AttachToManager(manager, cb);
Test.CollectAndIterate();
manager.EmitWithInt(42);
Test.CollectAndIterate();
Test.Assert(callbackCalled, "Callback must have been called.");
Test.AssertEquals(42, received, "Wrong value received.");
// Cleanup checks
manager.Release();
// Make sure the released wrapper is collected and release the Eo object
Test.CollectAndIterate();
Test.AssertNull(wref.Target);
}
}
}

View File

@ -42,6 +42,9 @@ class TestMain
if (localTestCase == setUp || localTestCase == tearDown)
continue;
// Cleanup garbage collector and job queue
Test.CollectAndIterate(1);
Console.WriteLine("[ RUN ] " + testCase.Name + "." + localTestCase.Name);
bool caseResult = true;

View File

@ -196,6 +196,20 @@ public static class Test
if (reference == null)
throw new AssertionException($"Assertion failed: {file}:{line} ({member}) {msg}");
}
/// <summary>Runs a number of garbage collections and iterate the main loop.
/// The iteration is needed to make sure objects collected in the GC thread
/// are efl_unref'd in the main thread.</summary>
public static void CollectAndIterate(int iterations=1000)
{
for (int i = 0; i < iterations; i++)
{
System.GC.Collect();
}
System.GC.WaitForPendingFinalizers();
Efl.App.AppMain.Iterate();
}
}

View File

@ -0,0 +1,55 @@
#include "libefl_mono_native_test.h"
typedef struct Dummy_Event_Manager_Data
{
Eo* emitter;
} Dummy_Event_Manager_Data;
static Efl_Object*
_dummy_event_manager_efl_object_constructor(Eo *obj, EINA_UNUSED Dummy_Event_Manager_Data *pd)
{
efl_constructor(efl_super(obj, DUMMY_EVENT_MANAGER_CLASS));
return obj;
}
static void
_dummy_event_manager_efl_object_destructor(Eo *obj, Dummy_Event_Manager_Data *pd)
{
if (pd->emitter != 0)
efl_unref(pd->emitter);
efl_destructor(efl_super(obj, DUMMY_EVENT_MANAGER_CLASS));
}
static void
_dummy_event_manager_emitter_set(EINA_UNUSED Eo *obj, Dummy_Event_Manager_Data *pd, Eo *emitter)
{
pd->emitter = emitter;
}
static Eina_Bool
_dummy_event_manager_emit_with_int(EINA_UNUSED Eo *obj, Dummy_Event_Manager_Data *pd, int data)
{
if (pd->emitter)
efl_event_callback_call(pd->emitter, DUMMY_TEST_OBJECT_EVENT_EVT_WITH_INT, &data);
else
{
EINA_LOG_ERR("Trying to emit event without an emitter.");
return EINA_FALSE;
}
return EINA_TRUE;
}
static void
_dummy_event_manager_release(EINA_UNUSED Eo *obj, Dummy_Event_Manager_Data *pd)
{
if (!pd->emitter)
return;
efl_unref(pd->emitter);
}
#include "dummy_event_manager.eo.c"

View File

@ -0,0 +1,29 @@
import eina_types;
class @beta Dummy.Event_Manager extends Efl.Object {
methods {
@property emitter {
set {
}
values {
emitter: Efl.Object @owned;
}
}
emit_with_int {
params {
data: int;
}
return: bool;
}
release {
}
}
implements {
Efl.Object.constructor;
Efl.Object.destructor;
}
}

View File

@ -54,6 +54,7 @@
#include "dummy_child.eo.h"
#include "dummy_inherit_helper.eo.h"
#include "dummy_part_holder.eo.h"
#include "dummy_event_manager.eo.h"
#include <interfaces/efl_part.eo.h>

View File

@ -1,4 +1,13 @@
eo_files = ['dummy_child.eo', 'dummy_numberwrapper.eo', 'dummy_test_object.eo', 'dummy_test_iface.eo', 'dummy_inherit_helper.eo', 'dummy_inherit_iface.eo', 'dummy_part_holder.eo']
eo_files = [
'dummy_child.eo',
'dummy_numberwrapper.eo',
'dummy_test_object.eo',
'dummy_test_iface.eo',
'dummy_inherit_helper.eo',
'dummy_inherit_iface.eo',
'dummy_part_holder.eo',
'dummy_event_manager.eo',
]
eo_file_targets = []
@ -23,6 +32,7 @@ efl_mono_native_test = library('efl_mono_native_test',
'dummy_numberwrapper.c',
'dummy_part_holder.c',
'dummy_test_object.c',
'dummy_event_manager.c',
],
dependencies : [ecore, eo, efl],
)