Re: g_test with mainloop integration?



On 07/01/2008, Mikkel Kamstrup Erlandsen <mikkel kamstrup gmail com> wrote:
> On 06/01/2008, Mikkel Kamstrup Erlandsen <mikkel kamstrup gmail com> wrote:
> > On 06/01/2008, muppet <scott asofyet org> wrote:
> > >
> > > On Jan 5, 2008, at 6:46 PM, Mikkel Kamstrup Erlandsen wrote:
> > >
> > > > The wait_for_signal() method process the main loop until a signal is
> > > > emitted on a given object - or maybe until a timeout is reached[1].
> > > > The whole idea about that method is that it should be possible to
> > > > write your tests without using callbacks. This will help make the
> > > > tests more expressive and easily maintained.
> > > >
> > > > To flag that some test case should run in a main loop you use some
> > > > special way of registering it. Like add_test_with_main_loop. There are
> > > > a lot of open questions on that one... Fx:
> > > > - Should all three functions, setup, test_run, and teardown, be run
> > > > in the mainloop, or just test_run()
> > > > - Should the mainloop process events in between calling the three
> > > > functions?
> > > >
> > > > For my purpose I think it would be nice if I could call wait_for
> > > > signal() in setup() as well, but I could live without it.
> > > >
> > > > The biggest problem I see is how to pass the signal args back to the
> > > > test case. I have no idea on how to solve that.
> > >
> > >
> > > I don't think you really need to worry about having
> > > add_test_with_main_loop() if your wait_for_signal() creates its own
> > > main loop, so long as you don't do anything funky with main loop
> > > contexts.
> > >
> > > As for passing the signal arguments back to the caller, you can do
> > > this by using a custom GClosure with a marshaler that simply copies
> > > all the arguments passed in.
> > >
> > > The attached code does this.  The interesting bits are
> > >
> > >    /* the one that does the actual work */
> > >    gboolean wait_for_signal_values (GObject * object,
> > >                                     gint max_wait_ms,
> > >                                     guint signal_id,
> > >                                     GQuark detail,
> > >                                     GValue * return_value,
> > >                                     GValueArray ** param_values);
> > >
> > >    /* varargs interface intended to be easier to use. */
> > >    gboolean wait_for_signal (GObject * object,
> > >                              gint max_wait_ms,
> > >                              const gchar * detailed_signal,
> > >                              ...)
> > >
> > > and lets you write code like
> > >
> > >      obj = g_object_new (SOME_TYPE_OBJECT, 0);
> > >      some_object_queue_blam (SOME_OBJECT (obj), 250);
> > >      if (wait_for_signal (obj, 2000, "blam", 2, &strval, &ival)) {
> > >          g_print ("okay 1  -> \"%s\", %d\n", strval, ival);
> > >          g_free (strval);
> > >      } else
> > >          g_print ("not okay 1\n");
> > >
> > >
> > > The most verbose part is the switch on the fundamental type of the
> > > parameters in wait_for_signal(); if anybody knows how to golf that,
> > > please do.
> > >
> >
> > Wow, thanks muppet. You just made my day :-)
> >
> > I do need my test method to run in a main loop though, because some of
> > the methods I call before wait_for_signal requires a main loop.
> >
> > It does not look to hard to change though. I will have a closer look
> > at this tonight.
> >
>
> I was just including muppet's code as a patch to gtestutils and
> friends, but then it occured to me that the code inherently relies on
> gobject. This means that it cannot go in gtestutils without breaking
> glib layering.
>
> My only idea on how to solve that atm is to create a g_object_test
> namespace and make the test utilities involving gobjects go there.
>
> Any comments?

I created a patch to integrate this with glib/gobject. Attached to
http://bugzilla.gnome.org/show_bug.cgi?id=508394

muppet: I assume that it is ok to license your code under LGPL. You
are noted as author in the headers.

Cheers,
Mikkel


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