[folks/648811-dummy-backend-rebase1: 33/41] dummy: Allow PersonaStore operations to be delayed via the mock callbacks



commit 9987a27e2a2583d404de1105b9bd8787a065ef81
Author: Philip Withnall <philip withnall collabora co uk>
Date:   Wed Nov 6 18:30:23 2013 +0000

    dummy: Allow PersonaStore operations to be delayed via the mock callbacks

 backends/dummy/lib/dummy-persona-store.vala |   96 +++++++++++++++++++++++----
 1 files changed, 84 insertions(+), 12 deletions(-)
---
diff --git a/backends/dummy/lib/dummy-persona-store.vala b/backends/dummy/lib/dummy-persona-store.vala
index 3f76b54..34f6f9d 100644
--- a/backends/dummy/lib/dummy-persona-store.vala
+++ b/backends/dummy/lib/dummy-persona-store.vala
@@ -242,6 +242,49 @@ public class FolksDummy.PersonaStore : Folks.PersonaStore
     }
 
   /**
+   * Delay for the given number of milliseconds.
+   *
+   * This implements an asynchronous delay (which should be yielded on) until
+   * the given number of milliseconds has elapsed.
+   *
+   * If ``delay`` is negative, this function returns immediately. If it is
+   * zero, this function returns in an idle callback.
+   *
+   * @param delay number of milliseconds to delay for
+   * @since UNRELEASED
+   */
+  private async void _implement_mock_delay (int delay)
+    {
+      if (delay < 0)
+        {
+          /* No delay. */
+          return;
+        }
+      else if (delay == 0)
+        {
+          /* Idle delay. */
+          Idle.add (() =>
+            {
+              this._implement_mock_delay.callback ();
+              return false;
+            });
+
+          yield;
+        }
+      else
+        {
+          /* Timed delay. */
+          Timeout.add (delay, () =>
+            {
+              this._implement_mock_delay.callback ();
+              return false;
+            });
+
+          yield;
+        }
+    }
+
+  /**
    * Type of a mock function for { link PersonaStore.add_persona_from_details}.
    *
    * See { link FolksDummy.PersonaStore.add_persona_from_details_mock}.
@@ -250,9 +293,12 @@ public class FolksDummy.PersonaStore : Folks.PersonaStore
    * the details passed to { link PersonaStore.add_persona_from_details}.
    * @throws PersonaStoreError to be thrown from
    * { link PersonaStore.add_persona_from_details}
+   * @returns delay to apply to the add persona operation (negative delays
+   * complete synchronously; zero delays complete in an idle callback; positive
+   * delays complete after that many milliseconds)
    * @since UNRELEASED
    */
-  public delegate void AddPersonaFromDetailsMock (Persona persona)
+  public delegate int AddPersonaFromDetailsMock (Persona persona)
       throws PersonaStoreError;
 
   /**
@@ -265,6 +311,12 @@ public class FolksDummy.PersonaStore : Folks.PersonaStore
    * function, adding the given persona will succeed. This is useful for testing
    * error handling of calls to { link PersoneStore.add_persona_from_details}.
    *
+   * The value returned by this function gives a delay which is imposed for
+   * completion of the { link PersonaStore.add_persona_from_details} call.
+   * Negative delays result in the call completing synchronously, zero delays
+   * result in completion in an idle callback, and positive delays result in
+   * completion after that many milliseconds.
+   *
    * If this is ``null``, all calls to
    * { link PersonaStore.add_persona_from_details} will succeed.
    *
@@ -551,11 +603,13 @@ public class FolksDummy.PersonaStore : Folks.PersonaStore
                 }
             }
         }
-      /* Allow the caller to inject failures into add_persona_from_details()
-       * by providing a mock function which can throw errors as appropriate. */
+
+      /* Allow the caller to inject failures and delays into
+       * add_persona_from_details() by providing a mock function. */
       if (this.add_persona_from_details_mock != null)
         {
-          this.add_persona_from_details_mock (persona);
+          var delay = this.add_persona_from_details_mock (persona);
+          yield this._implement_mock_delay (delay);
         }
 
       /* No simulated failure: continue adding the persona. */
@@ -577,9 +631,12 @@ public class FolksDummy.PersonaStore : Folks.PersonaStore
    * @param persona the persona being removed from the store
    * @throws PersonaStoreError to be thrown from
    * { link PersonaStore.remove_persona}
+   * @returns delay to apply to the remove persona operation (negative delays
+   * complete synchronously; zero delays complete in an idle callback; positive
+   * delays complete after that many milliseconds)
    * @since UNRELEASED
    */
-  public delegate void RemovePersonaMock (Persona persona)
+  public delegate int RemovePersonaMock (Persona persona)
       throws PersonaStoreError;
 
   /**
@@ -592,6 +649,12 @@ public class FolksDummy.PersonaStore : Folks.PersonaStore
    * function, removing the given persona will succeed. This is useful for
    * testing error handling of calls to { link PersoneStore.remove_persona}.
    *
+   * The value returned by this function gives a delay which is imposed for
+   * completion of the { link PersonaStore.remove_persona} call.
+   * Negative delays result in the call completing synchronously, zero delays
+   * result in completion in an idle callback, and positive delays result in
+   * completion after that many milliseconds.
+   *
    * If this is ``null``, all calls to { link PersonaStore.remove_persona} will
    * succeed.
    *
@@ -632,11 +695,11 @@ public class FolksDummy.PersonaStore : Folks.PersonaStore
               "Persona store has not yet been prepared.");
         }
 
-      /* Allow the caller to inject failures into remove_persona()
-       * by providing a mock function which can throw errors as appropriate. */
+      /* Allow the caller to inject failures and delays. */
       if (this.remove_persona_mock != null)
         {
-          this.remove_persona_mock ((FolksDummy.Persona) persona);
+          var delay = this.remove_persona_mock ((FolksDummy.Persona) persona);
+          yield this._implement_mock_delay (delay);
         }
 
       Persona? _persona = this._personas.get (persona.iid);
@@ -662,9 +725,12 @@ public class FolksDummy.PersonaStore : Folks.PersonaStore
    * See { link FolksDummy.PersonaStore.prepare_mock}.
    *
    * @throws PersonaStoreError to be thrown from { link PersonaStore.prepare}
+   * @returns delay to apply to the prepare operation (negative delays
+   * complete synchronously; zero delays complete in an idle callback; positive
+   * delays complete after that many milliseconds)
    * @since UNRELEASED
    */
-  public delegate void PrepareMock () throws PersonaStoreError;
+  public delegate int PrepareMock () throws PersonaStoreError;
 
   /**
    * Mock function for { link PersonaStore.prepare}.
@@ -678,6 +744,12 @@ public class FolksDummy.PersonaStore : Folks.PersonaStore
    * mock function). This is useful for testing error handling of calls to
    * { link PersoneStore.prepare}.
    *
+   * The value returned by this function gives a delay which is imposed for
+   * completion of the { link PersonaStore.prepare} call.
+   * Negative delays result in the call completing synchronously, zero delays
+   * result in completion in an idle callback, and positive delays result in
+   * completion after that many milliseconds.
+   *
    * If this is ``null``, all calls to { link PersonaStore.prepare} will
    * succeed.
    *
@@ -718,11 +790,11 @@ public class FolksDummy.PersonaStore : Folks.PersonaStore
         {
           this._prepare_pending = true;
 
-          /* Allow the caller to inject failures into prepare() by providing a
-           * mock function which can throw errors as appropriate. */
+          /* Allow the caller to inject failures and delays. */
           if (this.prepare_mock != null)
             {
-              this.prepare_mock ();
+              var delay = this.prepare_mock ();
+              yield this._implement_mock_delay (delay);
             }
 
           this._is_prepared = true;


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