From 8f8018ec81d4ea6e6a5e2f3d811daa57a31f6122 Mon Sep 17 00:00:00 2001 From: Marvin W Date: Sat, 27 Jun 2020 11:23:22 +0200 Subject: [PATCH] Fix async tests --- xmpp-vala/tests/common.vala | 4 +- xmpp-vala/tests/stanza.vala | 32 +++++++++++----- xmpp-vala/tests/testcase.vala | 69 +++++++++++++++++++++++++++++++++-- 3 files changed, 91 insertions(+), 14 deletions(-) diff --git a/xmpp-vala/tests/common.vala b/xmpp-vala/tests/common.vala index c616d2e7..47dbce0e 100644 --- a/xmpp-vala/tests/common.vala +++ b/xmpp-vala/tests/common.vala @@ -72,14 +72,14 @@ bool fail_if_not_eq_str(string? left, string? right, string? reason = null) { bool nullcheck = (left == null || right == null) && (left != null && right != null); if (left == null) left = "(null)"; if (right == null) right = "(null)"; - return fail_if_not(!nullcheck && left == right, @"$(reason + ": " ?? "")$left != $right"); + return fail_if_not(!nullcheck && left == right, @"$(reason + ": " ?? "")'$left' != '$right'"); } bool fail_if_eq_str(string? left, string? right, string? reason = null) { bool nullcheck = (left == null && right != null) || (left != null && right == null); if (left == null) left = "(null)"; if (right == null) right = "(null)"; - return fail_if(!nullcheck && left == right, @"$(reason + ": " ?? "")$left == $right"); + return fail_if(!nullcheck && left == right, @"$(reason + ": " ?? "")'$left' == '$right'"); } bool fail_if_not_eq_uint8_arr(uint8[] left, uint8[] right, string? reason = null) { diff --git a/xmpp-vala/tests/stanza.vala b/xmpp-vala/tests/stanza.vala index 13fc626f..19baef49 100644 --- a/xmpp-vala/tests/stanza.vala +++ b/xmpp-vala/tests/stanza.vala @@ -4,12 +4,12 @@ class StanzaTest : Gee.TestCase { public StanzaTest() { base("Stanza"); - add_test("node_one", () => { test_node_one.begin(); }); - add_test("typical_stream", () => { test_typical_stream.begin(); }); - add_test("ack_stream", () => { test_ack_stream.begin(); }); + add_async_test("node_one", (cb) => { test_node_one.begin(cb); }); + add_async_test("typical_stream", (cb) => { test_typical_stream.begin(cb); }); + add_async_test("ack_stream", (cb) => { test_ack_stream.begin(cb); }); } - private async void test_node_one() { + private async void test_node_one(Gee.TestCase.FinishCallback cb) { var node1 = new StanzaNode.build("test", "ns1_uri") .add_self_xmlns() .put_attribute("ns2", "ns2_uri", XMLNS_URI) @@ -23,9 +23,10 @@ class StanzaTest : Gee.TestCase { var node2 = yield new StanzaReader.for_string(xml1).read_node(); fail_if_not(node1.equals(node2)); fail_if_not_eq_str(node1.to_string(), node2.to_string()); + cb(); } - private async void test_typical_stream() { + private async void test_typical_stream(Gee.TestCase.FinishCallback cb) { var stream = """ reader.read_node(), 3, "end of stream should be reached"); + yield fail_if_not_end_of_stream(reader); + cb(); } - private async void test_ack_stream() { + private async void fail_if_not_end_of_stream(StanzaReader reader) { + try { + yield reader.read_node(); + fail_if_reached("end of stream should be reached"); + } catch (XmlError.EOF e) { + return; + } catch (Error e) { + fail_if_reached("Unexpected error"); + } + } + + private async void test_ack_stream(Gee.TestCase.FinishCallback cb) { var stream = """ reader.read_node(), 3, "end of stream should be reached"); + yield fail_if_not_end_of_stream(reader); + cb(); } } diff --git a/xmpp-vala/tests/testcase.vala b/xmpp-vala/tests/testcase.vala index cff0c47e..5be56128 100644 --- a/xmpp-vala/tests/testcase.vala +++ b/xmpp-vala/tests/testcase.vala @@ -26,13 +26,25 @@ public abstract class Gee.TestCase : Object { private Adaptor[] adaptors = new Adaptor[0]; public delegate void TestMethod (); + public delegate void FinishCallback (); + public delegate void AsyncTestMethod (FinishCallback cb); protected TestCase (string name) { this.suite = new GLib.TestSuite (name); } public void add_test (string name, owned TestMethod test) { - var adaptor = new Adaptor (name, (owned)test, this); + var adaptor = new DefaultAdaptor (name, (owned)test, this); + this.adaptors += adaptor; + + this.suite.add (new GLib.TestCase (adaptor.name, + adaptor.set_up, + adaptor.run, + adaptor.tear_down )); + } + + public void add_async_test (string name, owned AsyncTestMethod test, int timeout = 10000) { + var adaptor = new AsyncAdaptor (name, (owned)test, this, timeout); this.adaptors += adaptor; this.suite.add (new GLib.TestCase (adaptor.name, @@ -51,13 +63,19 @@ public abstract class Gee.TestCase : Object { return this.suite; } - private class Adaptor { + private interface Adaptor : Object { + public abstract void set_up (void* fixture); + public abstract void run (void* fixture); + public abstract void tear_down (void* fixture); + } + + private class DefaultAdaptor : Object, Adaptor { [CCode (notify = false)] public string name { get; private set; } private TestMethod test; private TestCase test_case; - public Adaptor (string name, + public DefaultAdaptor (string name, owned TestMethod test, TestCase test_case) { this.name = name; @@ -77,4 +95,49 @@ public abstract class Gee.TestCase : Object { this.test_case.tear_down (); } } + + private class AsyncAdaptor : Object, Adaptor { + [CCode (notify = false)] + public string name { get; private set; } + private AsyncTestMethod test; + private TestCase test_case; + private MainLoop main_loop; + private int timeout; + + public AsyncAdaptor (string name, + owned AsyncTestMethod test, + TestCase test_case, + int timeout) { + this.name = name; + this.test = (owned)test; + this.test_case = test_case; + this.timeout = timeout; + } + + public void set_up (void* fixture) { + this.test_case.set_up (); + main_loop = new MainLoop (); + } + + public void run (void* fixture) { + this.test (finish); + Timeout.add (timeout, finish_timeout); + main_loop.run (); + } + + public void finish () { + Idle.add (() => { main_loop.quit (); return false; }); + } + + public bool finish_timeout () { + Test.fail (); + Test.message (@"Timeout of $(timeout)ms reached."); + main_loop.quit (); + return false; + } + + public void tear_down (void* fixture) { + this.test_case.tear_down (); + } + } }