[geary/mjog/async-unit-test-improvements: 2/6] test/mock-object.vala: Add explicit support for mocking async calls



commit 749096cd38700e240d7cbc90848bb86e59e94626
Author: Michael Gratton <mike vee net>
Date:   Fri Apr 10 12:32:26 2020 +1000

    test/mock-object.vala: Add explicit support for mocking async calls
    
    Provide async equivalents of the `blah_call` methods, implement the
    given async behaviour of expected async calls.

 test/mock-object.vala | 131 +++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 109 insertions(+), 22 deletions(-)
---
diff --git a/test/mock-object.vala b/test/mock-object.vala
index c93d82a6..926441cb 100644
--- a/test/mock-object.vala
+++ b/test/mock-object.vala
@@ -221,7 +221,7 @@ public class ExpectedCall : GLib.Object {
  * assert_expectations} to ensure that the actual calls made matched
  * those expected.
  */
-public interface MockObject {
+public interface MockObject : GLib.Object {
 
 
     public static Object box_arg<T>(T value) {
@@ -256,39 +256,70 @@ public interface MockObject {
     }
 
     protected bool boolean_call(string name, Object[] args, bool default_return)
-        throws Error {
+        throws GLib.Error {
         ExpectedCall? expected = call_made(name, args);
+        return check_boolean_call(expected, default_return);
+    }
 
-        bool return_value = default_return;
-        if (expected.return_value != null) {
-            return_value = expected.return_value.get_boolean();
+    protected async bool boolean_call_async(string name,
+                                            Object[] args,
+                                            bool default_return)
+        throws GLib.Error {
+        ExpectedCall? expected = call_made(name, args);
+        if (async_call_yield(expected, this.boolean_call_async.callback)) {
+            yield;
         }
-        return return_value;
+        return check_boolean_call(expected, default_return);
     }
 
     protected R object_call<R>(string name, Object[] args, R default_return)
-        throws Error {
+        throws GLib.Error {
         ExpectedCall? expected = call_made(name, args);
+        return check_object_call(expected, default_return);
+    }
 
-        R? return_object = default_return;
-        if (expected.return_object != null) {
-            return_object = (R) expected.return_object;
+    protected async R object_call_async<R>(string name,
+                                           Object[] args,
+                                           R default_return)
+        throws GLib.Error {
+        ExpectedCall? expected = call_made(name, args);
+        if (async_call_yield(expected, this.object_call_async.callback)) {
+            yield;
         }
-        return return_object;
+        return check_object_call(expected, default_return);
     }
 
-    protected R object_or_throw_call<R>(string name, Object[] args, GLib.Error default_error)
+    protected R object_or_throw_call<R>(string name,
+                                        Object[] args,
+                                        GLib.Error default_error)
         throws GLib.Error {
         ExpectedCall? expected = call_made(name, args);
+        return check_object_or_throw_call(expected, default_error);
+    }
 
-        if (expected.return_object == null) {
-            throw default_error;
+    protected async R object_or_throw_call_async<R>(string name,
+                                                    Object[] args,
+                                                    GLib.Error default_error)
+        throws GLib.Error {
+        ExpectedCall? expected = call_made(name, args);
+        if (async_call_yield(expected, this.object_or_throw_call_async.callback)) {
+            yield;
         }
-        return expected.return_object;
+        return check_object_or_throw_call(expected, default_error);
     }
 
-    protected void void_call(string name, Object[] args) throws Error {
-        call_made(name, args);
+    protected void void_call(string name, Object[] args) throws GLib.Error {
+        ExpectedCall? expected = call_made(name, args);
+        check_for_exception(expected);
+    }
+
+    protected async void void_call_async(string name, Object[] args)
+        throws GLib.Error {
+        ExpectedCall? expected = call_made(name, args);
+        if (async_call_yield(expected, this.void_call_async.callback)) {
+            yield;
+        }
+        check_for_exception(expected);
     }
 
     private ExpectedCall? call_made(string name, Object[] args) throws Error {
@@ -301,11 +332,6 @@ public interface MockObject {
         }
 
         expected.called(args);
-
-        if (expected.throw_error != null) {
-            throw expected.throw_error;
-        }
-
         return expected;
     }
 
@@ -352,4 +378,65 @@ public interface MockObject {
         );
     }
 
+    private bool async_call_yield(ExpectedCall expected,
+                                  GLib.SourceFunc @callback) {
+        var @yield = false;
+        if (expected.async_behaviour != CONTINUE) {
+            expected.async_callback = @callback;
+            if (expected.async_behaviour == CONTINUE_AT_IDLE) {
+                GLib.Idle.add(() => {
+                        try {
+                            expected.async_resume();
+                        } catch (GLib.Error err) {
+                            critical(
+                                "Async call already resumed: %s", err.message
+                            );
+                        }
+                        return GLib.Source.REMOVE;
+                    });
+            }
+            @yield = true;
+        }
+        return @yield;
+    }
+
+    private inline bool check_boolean_call(ExpectedCall expected,
+                                           bool default_return)
+        throws GLib.Error {
+        check_for_exception(expected);
+        bool return_value = default_return;
+        if (expected.return_value != null) {
+            return_value = expected.return_value.get_boolean();
+        }
+        return return_value;
+    }
+
+    private inline R check_object_call<R>(ExpectedCall expected,
+                                          R default_return)
+        throws GLib.Error {
+        check_for_exception(expected);
+        R? return_object = default_return;
+        if (expected.return_object != null) {
+            return_object = (R) expected.return_object;
+        }
+        return return_object;
+    }
+
+    private inline R check_object_or_throw_call<R>(ExpectedCall expected,
+                                                   GLib.Error default_error)
+        throws GLib.Error {
+        check_for_exception(expected);
+        if (expected.return_object == null) {
+            throw default_error;
+        }
+        return expected.return_object;
+    }
+
+    private inline void check_for_exception(ExpectedCall expected)
+        throws GLib.Error {
+        if (expected.throw_error != null) {
+            throw expected.throw_error;
+        }
+    }
+
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]