Bug 1162 - Re-works the tests/ to use the glib-2.16 unit testing

framework

	* configure.ac:
	* tests/*:
	The tests have been reorganised into different categories: conformance,
	interactive and micro benchmarks.
	- conformance tests can be run as part of automated tests
	- interactive tests are basically all the existing tests
	- micro benchmarks focus on a single performance metric

	I converted the timeline tests to conformance tests and also added some
	tests from Neil Roberts and Ebassi.

	Note: currently only the conformance tests use the glib test APIs,
	though the micro benchmarks should too.

	The other change is to make the unit tests link into monolithic binaries
	which makes the build time for unit tests considerably faster. To deal
	with the extra complexity this adds to debugging individual tests I
	have added some sugar to the makefiles so all the tests can be run
	directly via a symlink and when an individual test is run this way,
	then a note is printed to the terminal explaining exactly how that test
	may be debugged using GDB.

	There is a convenience make rule: 'make test-report', that will run all
	the conformance tests and hopefully even open the results in your web
	browser. It skips some of the slower timeline tests, but you can run
	those using 'make full-report'
This commit is contained in:
Robert Bragg 2008-11-07 19:32:28 +00:00
parent 7c6ae80bfe
commit 603f936745
74 changed files with 1434 additions and 718 deletions

View File

@ -1,3 +1,35 @@
2008-11-07 Robert Bragg <robert@linux.intel.com>
Bug 1162 - Re-works the tests/ to use the glib-2.16 unit testing
framework
* configure.ac:
* tests/*:
The tests have been reorganised into different categories: conformance,
interactive and micro benchmarks.
- conformance tests can be run as part of automated tests
- interactive tests are basically all the existing tests
- micro benchmarks focus on a single performance metric
I converted the timeline tests to conformance tests and also added some
tests from Neil Roberts and Ebassi.
Note: currently only the conformance tests use the glib test APIs,
though the micro benchmarks should too.
The other change is to make the unit tests link into monolithic binaries
which makes the build time for unit tests considerably faster. To deal
with the extra complexity this adds to debugging individual tests I
have added some sugar to the makefiles so all the tests can be run
directly via a symlink and when an individual test is run this way,
then a note is printed to the terminal explaining exactly how that test
may be debugged using GDB.
There is a convenience make rule: 'make test-report', that will run all
the conformance tests and hopefully even open the results in your web
browser. It skips some of the slower timeline tests, but you can run
those using 'make full-report'
2008-11-07 Emmanuele Bassi <ebassi@linux.intel.com> 2008-11-07 Emmanuele Bassi <ebassi@linux.intel.com>
* clutter/clutter-media.c: Improve documentation of the * clutter/clutter-media.c: Improve documentation of the

View File

@ -21,6 +21,10 @@ clutter-$(CLUTTER_API_VERSION).pc: clutter.pc
clutter-$(CLUTTER_FLAVOUR)-$(CLUTTER_API_VERSION).pc: clutter.pc clutter-$(CLUTTER_FLAVOUR)-$(CLUTTER_API_VERSION).pc: clutter.pc
@cp $< $@ @cp $< $@
.PHONY: test-report full-report
test-report full-report:
$(MAKE) -C tests/conform $(@)
pkgconfig_DATA = $(pcfiles) pkgconfig_DATA = $(pcfiles)
pkgconfigdir = $(libdir)/pkgconfig pkgconfigdir = $(libdir)/pkgconfig

View File

@ -56,7 +56,7 @@ AC_SUBST(CLUTTER_LT_LDFLAGS)
dnl ======================================================================== dnl ========================================================================
# Checks for programs. # Checks for programs.
AC_PROG_CC AM_PROG_CC_C_O
#_AM_DEPENDENCIES([OBJC]) #_AM_DEPENDENCIES([OBJC])
#AC_PROG_OBJC #AC_PROG_OBJC
AC_DISABLE_STATIC AC_DISABLE_STATIC
@ -520,7 +520,7 @@ fi
AC_SUBST(JSON_PREFIX) AC_SUBST(JSON_PREFIX)
AM_CONDITIONAL(LOCAL_JSON_GLIB, test "x$have_json" = "xno") AM_CONDITIONAL(LOCAL_JSON_GLIB, test "x$have_json" = "xno")
CLUTTER_REQUIRES="pangocairo >= 1.18 gobject-2.0 >= 2.14 gthread-2.0 gmodule-no-export-2.0 $BACKEND_PC_FILES $JSON_GLIB_PC" CLUTTER_REQUIRES="pangocairo >= 1.18 gobject-2.0 >= 2.16 gthread-2.0 gmodule-no-export-2.0 $BACKEND_PC_FILES $JSON_GLIB_PC"
if test "x$imagebackend" = "xgdk-pixbuf"; then if test "x$imagebackend" = "xgdk-pixbuf"; then
CLUTTER_REQUIRES="$CLUTTER_REQUIRES gdk-pixbuf-2.0" CLUTTER_REQUIRES="$CLUTTER_REQUIRES gdk-pixbuf-2.0"
@ -663,6 +663,11 @@ AC_CONFIG_FILES([
clutter/json/Makefile clutter/json/Makefile
clutter/pango/Makefile clutter/pango/Makefile
tests/Makefile tests/Makefile
tests/conform/Makefile
tests/data/Makefile
tests/interactive/Makefile
tests/micro-bench/Makefile
tests/tools/Makefile
doc/Makefile doc/Makefile
doc/reference/Makefile doc/reference/Makefile
doc/reference/clutter/Makefile doc/reference/clutter/Makefile

View File

@ -1,78 +1,15 @@
noinst_PROGRAMS = test-textures test-events test-offscreen test-scale \
test-actors test-behave test-text test-entry test-project \
test-perspective test-rotate test-depth \
test-threads test-timeline test-timeline-dup-frames \
test-timeline-interpolate test-timeline-rewind \
test-timeline-smoothness \
test-threads test-timeline test-score test-script \
test-model test-grab test-effects test-fullscreen \
test-shader test-unproject test-viewport test-fbo \
test-opacity test-multistage \
test-cogl-primitives test-cogl-tex-tile \
test-cogl-tex-convert test-cogl-tex-foreign \
test-cogl-tex-getset test-cogl-offscreen \
test-cogl-tex-polygon test-stage-read-pixels \
test-random-text test-clip test-paint-wrapper \
test-texture-quality test-entry-auto test-layout \
test-invariants test-label-cache test-pick
if X11_TESTS SUBDIRS = data conform interactive micro-bench tools
noinst_PROGRAMS += test-pixmap
noinst_PROGRAMS += test-devices
endif
INCLUDES = -I$(top_srcdir)/ -I$(top_srcdir)/clutter -I$(top_builddir)/clutter EXTRA_DIST = README
LDADD = $(top_builddir)/clutter/libclutter-@CLUTTER_FLAVOUR@-@CLUTTER_MAJORMINOR@.la
AM_CFLAGS = $(CLUTTER_CFLAGS)
AM_LDFLAGS = $(CLUTTER_LIBS)
test_textures_SOURCES = test-textures.c .PHONY: test conform
test_events_SOURCES = test-events.c test conform:
test_offscreen_SOURCES = test-offscreen.c $(MAKE) -C ./conform test
test_scale_SOURCES = test-scale.c .PHONY: test-report full-report
test_actors_SOURCES = test-actors.c test-report full-report:
test_grab_SOURCES = test-grab.c $(MAKE) -C ./conform $(@)
test_behave_SOURCES = test-behave.c
test_text_SOURCES = test-text.c # run make test as part of make check
test_entry_SOURCES = test-entry.c check-local: test
test_project_SOURCES = test-project.c
test_unproject_SOURCES = test-unproject.c
test_perspective_SOURCES = test-perspective.c
test_rotate_SOURCES = test-rotate.c
test_depth_SOURCES = test-depth.c
test_threads_SOURCES = test-threads.c
test_timeline_SOURCES = test-timeline.c
test_timeline_dup_frames_SOURCES = test-timeline-dup-frames.c
test_timeline_interpolate_SOURCES = test-timeline-interpolate.c
test_timeline_rewind_SOURCES = test-timeline-rewind.c
test_timeline_smoothness_SOURCES = test-timeline-smoothness.c
test_shader_SOURCES = test-shader.c
test_score_SOURCES = test-score.c
test_script_SOURCES = test-script.c
test_model_SOURCES = test-model.c
test_effects_SOURCES = test-effects.c
test_fullscreen_SOURCES = test-fullscreen.c
test_viewport_SOURCES = test-viewport.c
test_fbo_SOURCES = test-fbo.c
test_opacity_SOURCES = test-opacity.c
test_multistage_SOURCES = test-multistage.c
test_pixmap_SOURCES = test-pixmap.c
test_pixmap_LDFLAGS = -lXcomposite
test_cogl_primitives_SOURCES = test-cogl-primitives.c
test_cogl_tex_tile_SOURCES = test-cogl-tex-tile.c
test_cogl_tex_convert_SOURCES = test-cogl-tex-convert.c
test_cogl_tex_foreign_SOURCES = test-cogl-tex-foreign.c
test_cogl_tex_getset_SOURCES = test-cogl-tex-getset.c
test_cogl_offscreen_SOURCES = test-cogl-offscreen.c
test_stage_read_pixels_SOURCES = test-stage-read-pixels.c
test_random_text_SOURCES = test-random-text.c
test_paint_wrapper_SOURCES = test-paint-wrapper.c
test_texture_quality_SOURCES = test-texture-quality.c
test_entry_auto_SOURCES = test-entry-auto.c
test_layout_SOURCES = test-layout.c
test_invariants_SOURCES = test-invariants.c
test_devices_SOURCES = test-devices.c
test_label_cache_SOURCES = test-label-cache.c
test_pick_SOURCES = test-pick.c
EXTRA_DIST = redhand.png test-script.json

12
tests/README Normal file
View File

@ -0,0 +1,12 @@
Outline of test categories:
The conform/ tests should be non-interactive unit-tests that verify a single feature is behaving as documented. See conform/ADDING_NEW_TESTS for more details.
The micro-bench/ tests should be focused perfomance test, ideally testing a single metric. Please never forget that these tests are synthetec and if you are using them then you understand what metric is being tested. They probably don't reflect any real world application loads and the intention is that you use these tests once you have already determined the crux of your problem and need focused feedback that your changes are indeed improving matters. There is no exit status requirements for these tests, but they should give clear feedback as to their performance. If the framerate is the feedback metric, then the test should forcibly enable FPS debugging.
The interactive/ tests are any tests whos status can not be determined without a user looking at some visual output, or providing some manual input etc. This covers most of the original Clutter tests. Ideally some of these tests will be migrated into the conformance/ directory so they can be used in automated nightly tests.
Other notes:
All tests should ideally include a detailed description in the source explaining exactly what the test is for, how the test was designed to work, and possibly a rationale for the aproach taken for testing.

View File

@ -0,0 +1,31 @@
How:
----
You should including the following at the top of your new unit test:
#include "test-conform-common.h"
Instead of a main () function add an entry point with a prototype as follows:
void
test_blah (TestConformSimpleFixture *fixture,
gconstpointer data)
{
}
Add a TEST_CONFORM_SIMPLE() entry in test-conform-main.c
Notes:
------
NB: A test fails if it exists. (regardless of the exist status)
Don't call clutter_init since that is handled in test-conform-common.c
Make sure you clean up *everything* you create. Noteable things you might miss
include timelines, behaviours, and all actors you add to the stage. This is important because otherwise you can cause cascading failures in other tests.
Use stage = clutter_stage_new () with a corresponding clutter_actor_destroy instead of clutter_stage_get_default ().

52
tests/conform/Makefile.am Normal file
View File

@ -0,0 +1,52 @@
noinst_PROGRAMS = test-conformance
test_conformance_SOURCES = \
test-conform-main.c \
test-conform-common.c \
test-conform-common.h \
\
test-timeline-dup-frames.c \
test-timeline-interpolate.c \
test-timeline-rewind.c \
test-timeline-smoothness.c \
test-timeline.c \
test-pick.c \
test-label-cache.c \
test-clutter-entry.c \
test-clutter-rectangle.c \
test-clutter-fixed.c
# For convenience, this provides a way to easily run individual unit tests:
.PHONY: wrappers
wrappers: test-conformance
for i in `./test-conformance -l`; \
do \
ln -sf $(top_srcdir)/tests/conform/wrapper.sh `basename $$i`; \
done
# NB: BUILT_SOURCES here a misnomer. We aren't building source, just inserting
# a phony rule that will generate symlink scripts for running individual tests
BUILT_SOURCES = wrappers
test_conformance_CFLAGS = \
-I$(top_srcdir)/ \
-I$(top_srcdir)/clutter \
-I$(top_builddir)/clutter \
$(CLUTTER_CFLAGS)
test_conformance_LDADD = $(top_builddir)/clutter/libclutter-@CLUTTER_FLAVOUR@-@CLUTTER_MAJORMINOR@.la
.PHONY: test test-report full-report
test:
gtester -o=test-conformance-results.xml ./test-conformance
test-report:
gtester -o=test-conformance-results.xml -k ./test-conformance \
&& gtester-report test-conformance-results.xml > test-conformance-results.html \
&& gnome-open ./test-conformance-results.html
full-report:
gtester -o=test-conformance-results.xml -k -m=slow ./test-conformance \
&& gtester-report test-conformance-results.xml > test-conformance-results.html \
&& gnome-open ./test-conformance-results.html
EXTRA_DIST = ADDING_NEW_TESTS

View File

@ -0,0 +1,370 @@
#include <glib.h>
#include <clutter/clutter.h>
#include <string.h>
#include "test-conform-common.h"
typedef struct {
gunichar unichar;
const char bytes[6];
gint nbytes;
} TestData;
const TestData
test_data[] = {
{ 0xe4, "\xc3\xa4", 2 }, /* LATIN SMALL LETTER A WITH DIAERESIS */
{ 0x2665, "\xe2\x99\xa5", 3 } /* BLACK HEART SUIT */
};
void
test_entry_utf8_validation (TestConformSimpleFixture *fixture,
gconstpointer data)
{
int i;
for (i = 0; i < G_N_ELEMENTS (test_data); i++)
{
const TestData *t = &test_data[i];
gunichar unichar;
char bytes[6];
int nbytes;
g_assert (g_unichar_validate (t->unichar));
nbytes = g_unichar_to_utf8 (t->unichar, bytes);
bytes[nbytes] = '\0';
g_assert (nbytes == t->nbytes);
g_assert (memcmp (t->bytes, bytes, nbytes) == 0);
unichar = g_utf8_get_char_validated (bytes, nbytes);
g_assert (unichar == t->unichar);
}
}
static int
get_nbytes (ClutterEntry *entry)
{
const char *s = clutter_entry_get_text (entry);
return strlen (s);
}
static int
get_nchars (ClutterEntry *entry)
{
const char *s = clutter_entry_get_text (entry);
g_assert (g_utf8_validate (s, -1, NULL));
return g_utf8_strlen (s, -1);
}
#define DONT_MOVE_CURSOR (-2)
static void
insert_unichar (ClutterEntry *entry, gunichar unichar, int position)
{
if (position > DONT_MOVE_CURSOR)
{
clutter_entry_set_cursor_position (entry, position);
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, position);
}
clutter_entry_insert_unichar (entry, unichar);
}
void
test_entry_empty (TestConformSimpleFixture *fixture,
gconstpointer data)
{
ClutterEntry *entry = CLUTTER_ENTRY (clutter_entry_new ());
g_assert (clutter_entry_get_text (entry) == NULL);
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, -1);
clutter_actor_destroy (CLUTTER_ACTOR (entry));
}
void
test_entry_set_empty (TestConformSimpleFixture *fixture,
gconstpointer data)
{
ClutterEntry *entry = CLUTTER_ENTRY (clutter_entry_new ());
/* annoyingly slightly different from initially empty */
clutter_entry_set_text (entry, "");
g_assert_cmpint (get_nchars (entry), ==, 0);
g_assert_cmpint (get_nbytes (entry), ==, 0);
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, -1);
clutter_actor_destroy (CLUTTER_ACTOR (entry));
}
void
test_entry_set_text (TestConformSimpleFixture *fixture,
gconstpointer data)
{
ClutterEntry *entry = CLUTTER_ENTRY (clutter_entry_new ());
clutter_entry_set_text (entry, "abcdef");
g_assert_cmpint (get_nchars (entry), ==, 6);
g_assert_cmpint (get_nbytes (entry), ==, 6);
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, -1);
clutter_entry_set_cursor_position (entry, 5);
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, 5);
clutter_entry_set_text (entry, "");
/* FIXME: cursor position should be -1?
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, -1);
*/
clutter_actor_destroy (CLUTTER_ACTOR (entry));
}
void
test_entry_append_some (TestConformSimpleFixture *fixture,
gconstpointer data)
{
ClutterEntry *entry = CLUTTER_ENTRY (clutter_entry_new ());
int i;
for (i = 0; i < G_N_ELEMENTS (test_data); i++)
{
const TestData *t = &test_data[i];
int j;
for (j = 1; j <= 4; j++)
{
insert_unichar (entry, t->unichar, DONT_MOVE_CURSOR);
g_assert_cmpint (get_nchars (entry), ==, j);
g_assert_cmpint (get_nbytes (entry), ==, j * t->nbytes);
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, -1);
}
clutter_entry_set_text (entry, "");
}
clutter_actor_destroy (CLUTTER_ACTOR (entry));
}
void
test_entry_prepend_some (TestConformSimpleFixture *fixture,
gconstpointer data)
{
ClutterEntry *entry = CLUTTER_ENTRY (clutter_entry_new ());
int i;
for (i = 0; i < G_N_ELEMENTS (test_data); i++)
{
const TestData *t = &test_data[i];
int j;
clutter_entry_insert_unichar (entry, t->unichar);
g_assert_cmpint (get_nchars (entry), ==, 1);
g_assert_cmpint (get_nbytes (entry), ==, 1 * t->nbytes);
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, -1);
for (j = 2; j <= 4; j++)
{
insert_unichar (entry, t->unichar, 0);
g_assert_cmpint (get_nchars (entry), ==, j);
g_assert_cmpint (get_nbytes (entry), ==, j * t->nbytes);
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, 1);
}
clutter_entry_set_text (entry, "");
}
clutter_actor_destroy (CLUTTER_ACTOR (entry));
}
void
test_entry_insert (TestConformSimpleFixture *fixture,
gconstpointer data)
{
ClutterEntry *entry = CLUTTER_ENTRY (clutter_entry_new ());
int i;
for (i = 0; i < G_N_ELEMENTS (test_data); i++)
{
const TestData *t = &test_data[i];
clutter_entry_insert_unichar (entry, t->unichar);
clutter_entry_insert_unichar (entry, t->unichar);
insert_unichar (entry, t->unichar, 1);
g_assert_cmpint (get_nchars (entry), ==, 3);
g_assert_cmpint (get_nbytes (entry), ==, 3 * t->nbytes);
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, 2);
clutter_entry_set_text (entry, "");
}
clutter_actor_destroy (CLUTTER_ACTOR (entry));
}
void
test_entry_delete_chars (TestConformSimpleFixture *fixture,
gconstpointer data)
{
ClutterEntry *entry = CLUTTER_ENTRY (clutter_entry_new ());
int i;
for (i = 0; i < G_N_ELEMENTS (test_data); i++)
{
const TestData *t = &test_data[i];
int j;
for (j = 0; j < 4; j++)
clutter_entry_insert_unichar (entry, t->unichar);
clutter_entry_set_cursor_position (entry, 2);
clutter_entry_delete_chars (entry, 1);
g_assert_cmpint (get_nchars (entry), ==, 3);
g_assert_cmpint (get_nbytes (entry), ==, 3 * t->nbytes);
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, 1);
clutter_entry_set_cursor_position (entry, 2);
clutter_entry_delete_chars (entry, 1);
g_assert_cmpint (get_nchars (entry), ==, 2);
g_assert_cmpint (get_nbytes (entry), ==, 2 * t->nbytes);
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, 1);
clutter_entry_set_text (entry, "");
}
clutter_actor_destroy (CLUTTER_ACTOR (entry));
}
void
test_entry_delete_text (TestConformSimpleFixture *fixture,
gconstpointer data)
{
ClutterEntry *entry = CLUTTER_ENTRY (clutter_entry_new ());
int i;
for (i = 0; i < G_N_ELEMENTS (test_data); i++)
{
const TestData *t = &test_data[i];
int j;
for (j = 0; j < 4; j++)
clutter_entry_insert_unichar (entry, t->unichar);
clutter_entry_set_cursor_position (entry, 3);
clutter_entry_delete_text (entry, 2, 4);
g_assert_cmpint (get_nchars (entry), ==, 2);
g_assert_cmpint (get_nbytes (entry), ==, 2 * t->nbytes);
/* FIXME: cursor position should be -1?
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, -1);
*/
clutter_entry_set_text (entry, "");
}
clutter_actor_destroy (CLUTTER_ACTOR (entry));
}
static void
init_event (ClutterKeyEvent *event)
{
event->type = CLUTTER_KEY_PRESS;
event->time = 0; /* not needed */
event->flags = CLUTTER_EVENT_FLAG_SYNTHETIC;
event->stage = NULL; /* not needed */
event->source = NULL; /* not needed */
event->modifier_state = 0;
event->hardware_keycode = 0; /* not needed */
}
static void
send_keyval (ClutterEntry *entry, int keyval)
{
ClutterKeyEvent event;
init_event (&event);
event.keyval = keyval;
event.unicode_value = 0; /* should be ignored for cursor keys etc. */
clutter_entry_handle_key_event (entry, &event);
}
static inline void
send_unichar (ClutterEntry *entry, gunichar unichar)
{
ClutterKeyEvent event;
init_event (&event);
event.keyval = 0; /* should be ignored for printable characters */
event.unicode_value = unichar;
clutter_entry_handle_key_event (entry, &event);
}
void
test_entry_cursor (TestConformSimpleFixture *fixture,
gconstpointer data)
{
ClutterEntry *entry = CLUTTER_ENTRY (clutter_entry_new ());
int i;
for (i = 0; i < G_N_ELEMENTS (test_data); i++)
{
const TestData *t = &test_data[i];
int j;
for (j = 0; j < 4; ++j)
clutter_entry_insert_unichar (entry, t->unichar);
clutter_entry_set_cursor_position (entry, 2);
/* test cursor moves and is clamped */
send_keyval (entry, CLUTTER_Left);
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, 1);
send_keyval (entry, CLUTTER_Left);
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, 0);
send_keyval (entry, CLUTTER_Left);
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, 0);
/* delete text containing the cursor */
clutter_entry_set_cursor_position (entry, 3);
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, 3);
clutter_entry_delete_text (entry, 2, 4);
send_keyval (entry, CLUTTER_Left);
/* FIXME: cursor position should be -1?
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, -1);
*/
clutter_entry_set_text (entry, "");
}
clutter_actor_destroy (CLUTTER_ACTOR (entry));
}
void
test_entry_event (TestConformSimpleFixture *fixture,
gconstpointer data)
{
ClutterEntry *entry = CLUTTER_ENTRY (clutter_entry_new ());
int i;
for (i = 0; i < G_N_ELEMENTS (test_data); i++)
{
const TestData *t = &test_data[i];
send_unichar (entry, t->unichar);
g_assert_cmpint (get_nchars (entry), ==, 1);
g_assert_cmpint (get_nbytes (entry), ==, 1 * t->nbytes);
g_assert_cmpint (clutter_entry_get_cursor_position (entry), ==, -1);
clutter_entry_set_text (entry, "");
}
clutter_actor_destroy (CLUTTER_ACTOR (entry));
}

View File

@ -0,0 +1,18 @@
#include <stdio.h>
#include <clutter/clutter.h>
#include "test-conform-common.h"
void
test_fixed_constants (TestConformSimpleFixture *fixture,
gconstpointer data)
{
g_assert_cmpint (CFX_ONE, ==, CLUTTER_FLOAT_TO_FIXED (1.0));
g_assert_cmpint (CFX_ONE, ==, CLUTTER_INT_TO_FIXED (1));
g_assert_cmpint (CFX_HALF, ==, CLUTTER_FLOAT_TO_FIXED (0.5));
g_assert_cmpfloat (CLUTTER_FIXED_TO_FLOAT (CFX_ONE), ==, 1.0);
g_assert_cmpfloat (CLUTTER_FIXED_TO_FLOAT (CFX_HALF), ==, 0.5);
}

View File

@ -0,0 +1,56 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glib/gtestutils.h>
#include <clutter/clutter.h>
#include "test-conform-common.h"
void
test_rect_set_size (TestConformSimpleFixture *fixture,
gconstpointer data)
{
ClutterActor *rect = clutter_rectangle_new ();
/* initial positioning */
g_assert_cmpint (clutter_actor_get_x (rect), ==, 0);
g_assert_cmpint (clutter_actor_get_y (rect), ==, 0);
clutter_actor_set_size (rect, 100, 100);
/* make sure that changing the size does not affect the
* rest of the bounding box
*/
g_assert_cmpint (clutter_actor_get_x (rect), ==, 0);
g_assert_cmpint (clutter_actor_get_y (rect), ==, 0);
g_assert_cmpint (clutter_actor_get_width (rect), ==, 100);
g_assert_cmpint (clutter_actor_get_height (rect), ==, 100);
clutter_actor_destroy (rect);
}
void
test_rect_set_color (TestConformSimpleFixture *fixture,
gconstpointer data)
{
ClutterActor *rect = clutter_rectangle_new ();
ClutterColor white = { 255, 255, 255, 255 };
ClutterColor black = { 0, 0, 0, 255 };
ClutterColor check = { 0, };
clutter_rectangle_set_color (CLUTTER_RECTANGLE (rect), &black);
clutter_rectangle_get_color (CLUTTER_RECTANGLE (rect), &check);
g_assert_cmpint (check.blue, ==, black.blue);
clutter_rectangle_set_color (CLUTTER_RECTANGLE (rect), &white);
clutter_rectangle_get_color (CLUTTER_RECTANGLE (rect), &check);
g_assert_cmpint (check.green, ==, white.green);
g_assert_cmpint (clutter_actor_get_opacity (rect), ==, white.alpha);
clutter_actor_destroy (rect);
}

View File

@ -0,0 +1,29 @@
#include <clutter/clutter.h>
#include "test-conform-common.h"
/**
* test_conform_simple_fixture_setup:
*
* Initialise stuff before each test is run
*/
void
test_conform_simple_fixture_setup (TestConformSimpleFixture *fixture,
gconstpointer data)
{
/* const TestConformSharedState *shared_state = data; */
}
/**
* test_conform_simple_fixture_teardown:
*
* Cleanup stuff after each test has finished
*/
void
test_conform_simple_fixture_teardown (TestConformSimpleFixture *fixture,
gconstpointer data)
{
/* const TestConformSharedState *shared_state = data; */
}

View File

@ -0,0 +1,25 @@
/* Stuff you put in here is setup once in main() and gets passed around to
* all test functions and fixture setup/teardown functions in the data
* argument */
typedef struct _TestConformSharedState
{
int *argc_addr;
char ***argv_addr;
} TestConformSharedState;
/* This fixture structure is allocated by glib, and before running each test
* the test_conform_simple_fixture_setup func (see below) is called to
* initialise it, and test_conform_simple_fixture_teardown is called when
* the test is finished. */
typedef struct _TestConformSimpleFixture
{
/**/
} TestConformSimpleFixture;
void test_conform_simple_fixture_setup (TestConformSimpleFixture *fixture,
gconstpointer data);
void test_conform_simple_fixture_teardown (TestConformSimpleFixture *fixture,
gconstpointer data);

View File

@ -0,0 +1,81 @@
#include <clutter/clutter.h>
#include <glib.h>
#include <stdlib.h>
#include "test-conform-common.h"
/* This is a bit of sugar for adding new conformance tests:
*
* - It adds an extern function definition just to save maintaining a header
* that lists test entry points.
* - It sets up callbacks for a fixture, which lets us share initialization
* *code* between tests. (see test-conform-common.c)
* - It passes in a shared *data* pointer that is initialised once in main(),
* that gets passed to the fixture setup and test functions. (See the
* definition in test-conform-common.h)
*/
#define TEST_CONFORM_SIMPLE(NAMESPACE, FUNC) \
extern void FUNC (TestConformSimpleFixture *fixture, gconstpointer data); \
g_test_add ("/conform" NAMESPACE "/" #FUNC, \
TestConformSimpleFixture, \
shared_state, /* data argument for test */ \
test_conform_simple_fixture_setup, \
FUNC, \
test_conform_simple_fixture_teardown);
int
main (int argc, char **argv)
{
TestConformSharedState *shared_state = g_new0 (TestConformSharedState, 1);
g_test_init (&argc, &argv, NULL);
g_test_bug_base ("http://bugzilla.openedhand.com/show_bug.cgi?id=%s");
g_assert (clutter_init (shared_state->argc_addr, shared_state->argv_addr)
== CLUTTER_INIT_SUCCESS);
/* Initialise the state you need to share with everything.
*/
shared_state->argc_addr = &argc;
shared_state->argv_addr = &argv;
if (g_test_slow ())
{
TEST_CONFORM_SIMPLE ("/timeline", test_timeline_dup_frames);
TEST_CONFORM_SIMPLE ("/timeline", test_timeline_interpolate);
TEST_CONFORM_SIMPLE ("/timeline", test_timeline_rewind);
TEST_CONFORM_SIMPLE ("/timeline", test_timeline_smoothness);
}
TEST_CONFORM_SIMPLE ("/picking", test_pick);
TEST_CONFORM_SIMPLE ("/label", test_label_cache);
TEST_CONFORM_SIMPLE ("/entry", test_entry_utf8_validation);
TEST_CONFORM_SIMPLE ("/entry", test_entry_empty);
TEST_CONFORM_SIMPLE ("/entry", test_entry_set_empty);
TEST_CONFORM_SIMPLE ("/entry", test_entry_set_text);
TEST_CONFORM_SIMPLE ("/entry", test_entry_append_some);
TEST_CONFORM_SIMPLE ("/entry", test_entry_prepend_some);
TEST_CONFORM_SIMPLE ("/entry", test_entry_insert);
TEST_CONFORM_SIMPLE ("/entry", test_entry_delete_chars);
TEST_CONFORM_SIMPLE ("/entry", test_entry_delete_text);
TEST_CONFORM_SIMPLE ("/entry", test_entry_cursor);
TEST_CONFORM_SIMPLE ("/entry", test_entry_event);
TEST_CONFORM_SIMPLE ("/rectangle", test_rect_set_size);
TEST_CONFORM_SIMPLE ("/rectangle", test_rect_set_color);
TEST_CONFORM_SIMPLE ("/fixed", test_fixed_constants);
g_test_run ();
return EXIT_SUCCESS;
}

View File

@ -1,5 +1,8 @@
#include <clutter/clutter.h> #include <clutter/clutter.h>
#include <string.h> #include <string.h>
#include <stdlib.h>
#include "test-conform-common.h"
#define TEST_FONT "Sans 10" #define TEST_FONT "Sans 10"
@ -217,16 +220,15 @@ make_layout_like_label (ClutterLabel *label)
return new_layout; return new_layout;
} }
int void
main (int argc, char **argv) test_label_cache (TestConformSimpleFixture *fixture,
gconstpointer _data)
{ {
CallbackData data; CallbackData data;
int ret = 0; int ret = 0;
memset (&data, 0, sizeof (data)); memset (&data, 0, sizeof (data));
clutter_init (&argc, &argv);
data.stage = clutter_stage_get_default (); data.stage = clutter_stage_get_default ();
data.label = clutter_label_new_with_text (TEST_FONT, ""); data.label = clutter_label_new_with_text (TEST_FONT, "");
@ -248,10 +250,11 @@ main (int argc, char **argv)
if (data.test_failed) if (data.test_failed)
{ {
printf ("FAIL\n"); printf ("FAIL\n");
ret = 1; exit (1);
} }
else else
printf ("pass\n"); printf ("pass\n");
return ret; return;
} }

106
tests/conform/test-pick.c Normal file
View File

@ -0,0 +1,106 @@
#include <clutter/clutter.h>
#include "test-conform-common.h"
#define STAGE_WIDTH 320
#define STAGE_HEIGHT 200
#define ACTORS_X 12
#define ACTORS_Y 16
typedef struct _State State;
struct _State
{
ClutterActor *stage;
int y, x;
guint32 gids[ACTORS_X * ACTORS_Y];
guint actor_width, actor_height;
int ret;
};
static gboolean
on_timeout (State *state)
{
int y, x;
for (y = 0; y < ACTORS_Y; y++)
for (x = 0; x < ACTORS_X; x++)
{
gboolean pass = FALSE;
guint32 gid;
ClutterActor *actor
= clutter_stage_get_actor_at_pos (CLUTTER_STAGE (state->stage),
x * state->actor_width
+ state->actor_width / 2,
y * state->actor_height
+ state->actor_height / 2);
printf ("actor %u -> ", state->gids[y * ACTORS_X + x]);
if (actor == NULL)
printf ("NULL: FAIL\n");
else
{
gid = clutter_actor_get_gid (actor);
if (gid == state->gids[y * ACTORS_X + x])
pass = TRUE;
printf ("% 8i: %s\n", gid, pass ? "pass" : "FAIL");
}
if (!pass)
state->ret = 1;
}
clutter_main_quit ();
return FALSE;
}
void
test_pick (TestConformSimpleFixture *fixture,
gconstpointer data)
{
int y, x;
State state;
state.ret = 0;
state.stage = clutter_stage_new ();
clutter_actor_set_size (state.stage, STAGE_WIDTH, STAGE_HEIGHT);
state.actor_width = STAGE_WIDTH / ACTORS_X;
state.actor_height = STAGE_HEIGHT / ACTORS_Y;
for (y = 0; y < ACTORS_Y; y++)
for (x = 0; x < ACTORS_X; x++)
{
ClutterColor color = { x * 255 / (ACTORS_X - 1),
y * 255 / (ACTORS_Y - 1),
128, 255 };
ClutterGeometry geom = { x * state.actor_width, y * state.actor_height,
state.actor_width, state.actor_height };
ClutterActor *rect = clutter_rectangle_new_with_color (&color);
clutter_actor_set_geometry (rect, &geom);
clutter_container_add (CLUTTER_CONTAINER (state.stage), rect, NULL);
state.gids[y * ACTORS_X + x] = clutter_actor_get_gid (rect);
}
clutter_actor_show (state.stage);
g_timeout_add (250, (GSourceFunc) on_timeout, &state);
clutter_main ();
clutter_actor_destroy (state.stage);
printf ("end result: %s\n", state.ret ? "FAIL" : "pass");
if (state.ret)
exit (state.ret);
return;
}

View File

@ -2,6 +2,8 @@
#include <glib.h> #include <glib.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
#include "test-conform-common.h"
/* We use a nice slow timeline for this test since we /* We use a nice slow timeline for this test since we
* dont want the timeouts to interpolate the timeline * dont want the timeouts to interpolate the timeline
* forward multiple frames */ * forward multiple frames */
@ -23,17 +25,20 @@ new_frame_cb (ClutterTimeline *timeline,
{ {
gint current_frame = clutter_timeline_get_current_frame (state->timeline); gint current_frame = clutter_timeline_get_current_frame (state->timeline);
if (state->prev_frame != clutter_timeline_get_current_frame (state->timeline)) if (state->prev_frame
!= clutter_timeline_get_current_frame (state->timeline))
{ {
g_print("timeline previous frame=%-4i actual frame=%-4i (OK)\n", g_test_message ("timeline previous frame=%-4i "
state->prev_frame, "actual frame=%-4i (OK)\n",
current_frame); state->prev_frame,
current_frame);
} }
else else
{ {
g_print("timeline previous frame=%-4i actual frame=%-4i (FAILED)\n", g_test_message ("timeline previous frame=%-4i "
state->prev_frame, "actual frame=%-4i (FAILED)\n",
current_frame); state->prev_frame,
current_frame);
state->passed = FALSE; state->passed = FALSE;
} }
@ -44,45 +49,44 @@ new_frame_cb (ClutterTimeline *timeline,
static void static void
completed_cb (ClutterTimeline *timeline, completed_cb (ClutterTimeline *timeline,
TestState *state) TestState *state)
{ {
state->completion_count++; state->completion_count++;
if (state->completion_count == 2) if (state->completion_count == 2)
{ {
if (state->passed) if (state->passed)
{ {
g_print("Passed\n"); g_test_message ("Passed\n");
exit(EXIT_SUCCESS); clutter_main_quit ();
} }
else else
{ {
g_print("Failed\n"); g_test_message ("Failed\n");
exit(EXIT_FAILURE); exit (EXIT_FAILURE);
} }
} }
} }
int void
main(int argc, char **argv) test_timeline_dup_frames (TestConformSimpleFixture *fixture,
gconstpointer data)
{ {
TestState state; TestState state;
clutter_init(&argc, &argv);
state.timeline = state.timeline =
clutter_timeline_new (TEST_TIMELINE_FRAME_COUNT, clutter_timeline_new (TEST_TIMELINE_FRAME_COUNT,
TEST_TIMELINE_FPS); TEST_TIMELINE_FPS);
clutter_timeline_set_loop (state.timeline, TRUE); clutter_timeline_set_loop (state.timeline, TRUE);
g_signal_connect (G_OBJECT(state.timeline), g_signal_connect (G_OBJECT(state.timeline),
"new-frame", "new-frame",
G_CALLBACK(new_frame_cb), G_CALLBACK(new_frame_cb),
&state); &state);
g_signal_connect (G_OBJECT(state.timeline), g_signal_connect (G_OBJECT(state.timeline),
"completed", "completed",
G_CALLBACK(completed_cb), G_CALLBACK(completed_cb),
&state); &state);
state.prev_frame = -1; state.prev_frame = -1;
state.completion_count = 0; state.completion_count = 0;
@ -92,6 +96,6 @@ main(int argc, char **argv)
clutter_main(); clutter_main();
return EXIT_FAILURE; g_object_unref (state.timeline);
} }

View File

@ -2,6 +2,8 @@
#include <glib.h> #include <glib.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
#include "test-conform-common.h"
/* We ask for 1 frame per millisecond. /* We ask for 1 frame per millisecond.
* Whenever this rate can't be achieved then the timeline * Whenever this rate can't be achieved then the timeline
* will interpolate the number frames that should have * will interpolate the number frames that should have
@ -25,7 +27,7 @@ typedef struct _TestState {
static void static void
new_frame_cb (ClutterTimeline *timeline, new_frame_cb (ClutterTimeline *timeline,
gint frame_num, gint frame_num,
TestState *state) TestState *state)
{ {
GTimeVal current_time; GTimeVal current_time;
@ -49,39 +51,47 @@ new_frame_cb (ClutterTimeline *timeline,
* looping */ * looping */
if (state->expected_frame > TEST_TIMELINE_FRAME_COUNT) if (state->expected_frame > TEST_TIMELINE_FRAME_COUNT)
{ {
loop_overflow = state->expected_frame - TEST_TIMELINE_FRAME_COUNT; loop_overflow = state->expected_frame - TEST_TIMELINE_FRAME_COUNT;
state->expected_frame = TEST_TIMELINE_FRAME_COUNT; state->expected_frame = TEST_TIMELINE_FRAME_COUNT;
} }
if (current_frame >= (state->expected_frame-TEST_ERROR_TOLERANCE) if (current_frame >= (state->expected_frame-TEST_ERROR_TOLERANCE)
&& current_frame <= (state->expected_frame+TEST_ERROR_TOLERANCE)) && current_frame <= (state->expected_frame+TEST_ERROR_TOLERANCE))
{ {
g_print ("\nelapsed milliseconds=%-5li expected frame=%-4i actual frame=%-4i (OK)\n", g_test_message ("\nelapsed milliseconds=%-5li "
msec_diff, "expected frame=%-4i actual frame=%-4i (OK)\n",
state->expected_frame, msec_diff,
current_frame); state->expected_frame,
current_frame);
} }
else else
{ {
g_print ("\nelapsed milliseconds=%-5li expected frame=%-4i actual frame=%-4i (FAILED)\n", g_test_message ("\nelapsed milliseconds=%-5li "
msec_diff, "expected frame=%-4i actual frame=%-4i (FAILED)\n",
state->expected_frame, msec_diff,
current_frame); state->expected_frame,
current_frame);
state->passed = FALSE; state->passed = FALSE;
} }
if (step>0) if (step>0)
{ {
state->expected_frame = current_frame + (TEST_TIMELINE_FPS / 4); state->expected_frame = current_frame + (TEST_TIMELINE_FPS / 4);
g_print ("Sleeping for 250ms so next frame should be (%i + %i) = %i\n", g_test_message ("Sleeping for 250ms "
current_frame, (TEST_TIMELINE_FPS / 4), state->expected_frame); "so next frame should be (%i + %i) = %i\n",
current_frame,
(TEST_TIMELINE_FPS / 4),
state->expected_frame);
g_usleep (250000); g_usleep (250000);
} }
else else
{ {
state->expected_frame = current_frame + TEST_TIMELINE_FPS; state->expected_frame = current_frame + TEST_TIMELINE_FPS;
g_print ("Sleeping for 1sec so next frame should be (%i + %i) = %i\n", g_test_message ("Sleeping for 1sec "
current_frame, TEST_TIMELINE_FPS, state->expected_frame); "so next frame should be (%i + %i) = %i\n",
current_frame,
TEST_TIMELINE_FPS,
state->expected_frame);
g_usleep (1000000); g_usleep (1000000);
} }
@ -89,8 +99,9 @@ new_frame_cb (ClutterTimeline *timeline,
{ {
state->expected_frame += loop_overflow; state->expected_frame += loop_overflow;
state->expected_frame -= TEST_TIMELINE_FRAME_COUNT; state->expected_frame -= TEST_TIMELINE_FRAME_COUNT;
g_print ("End of timeline reached: Wrapping expected frame too %i\n", g_test_message ("End of timeline reached: "
state->expected_frame); "Wrapping expected frame too %i\n",
state->expected_frame);
} }
state->new_frame_counter++; state->new_frame_counter++;
@ -100,45 +111,44 @@ new_frame_cb (ClutterTimeline *timeline,
static void static void
completed_cb (ClutterTimeline *timeline, completed_cb (ClutterTimeline *timeline,
TestState *state) TestState *state)
{ {
state->completion_count++; state->completion_count++;
if (state->completion_count == 2) if (state->completion_count == 2)
{ {
if (state->passed) if (state->passed)
{ {
g_print("Passed\n"); g_test_message ("Passed\n");
exit(EXIT_SUCCESS); clutter_main_quit ();
} }
else else
{ {
g_print("Failed\n"); g_test_message ("Failed\n");
exit(EXIT_FAILURE); exit (EXIT_FAILURE);
} }
} }
} }
int void
main (int argc, char **argv) test_timeline_interpolate (TestConformSimpleFixture *fixture,
gconstpointer data)
{ {
TestState state; TestState state;
clutter_init (&argc, &argv);
state.timeline = state.timeline =
clutter_timeline_new (TEST_TIMELINE_FRAME_COUNT, clutter_timeline_new (TEST_TIMELINE_FRAME_COUNT,
TEST_TIMELINE_FPS); TEST_TIMELINE_FPS);
clutter_timeline_set_loop (state.timeline, TRUE); clutter_timeline_set_loop (state.timeline, TRUE);
g_signal_connect (G_OBJECT(state.timeline), g_signal_connect (G_OBJECT(state.timeline),
"new-frame", "new-frame",
G_CALLBACK(new_frame_cb), G_CALLBACK(new_frame_cb),
&state); &state);
g_signal_connect (G_OBJECT(state.timeline), g_signal_connect (G_OBJECT(state.timeline),
"completed", "completed",
G_CALLBACK(completed_cb), G_CALLBACK(completed_cb),
&state); &state);
state.completion_count = 0; state.completion_count = 0;
state.new_frame_counter = 0; state.new_frame_counter = 0;
@ -150,6 +160,6 @@ main (int argc, char **argv)
clutter_main(); clutter_main();
return EXIT_FAILURE; g_object_unref (state.timeline);
} }

View File

@ -2,6 +2,8 @@
#include <glib.h> #include <glib.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
#include "test-conform-common.h"
#define TEST_TIMELINE_FPS 10 #define TEST_TIMELINE_FPS 10
#define TEST_TIMELINE_FRAME_COUNT 5 #define TEST_TIMELINE_FRAME_COUNT 5
#define TEST_WATCHDOG_KICK_IN_SECONDS 10 #define TEST_WATCHDOG_KICK_IN_SECONDS 10
@ -15,18 +17,18 @@ typedef struct _TestState {
static gboolean static gboolean
watchdog_timeout (TestState *state) watchdog_timeout (TestState *state)
{ {
g_print ("Watchdog timer kicking in\n"); g_test_message ("Watchdog timer kicking in\n");
g_print ("rewind_count=%i\n", state->rewind_count); g_test_message ("rewind_count=%i\n", state->rewind_count);
if (state->rewind_count <= 3) if (state->rewind_count <= 3)
{ {
/* The test has hung */ /* The test has hung */
g_print ("Failed (This test shouldn't have hung!)\n"); g_test_message ("Failed (This test shouldn't have hung!)\n");
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
} }
else else
{ {
g_print ("Passed\n"); g_test_message ("Passed\n");
exit (EXIT_SUCCESS); clutter_main_quit ();
} }
return FALSE; return FALSE;
@ -42,8 +44,8 @@ new_frame_cb (ClutterTimeline *timeline,
if (current_frame == TEST_TIMELINE_FRAME_COUNT) if (current_frame == TEST_TIMELINE_FRAME_COUNT)
{ {
g_print ("new-frame signal recieved (end of timeline)\n"); g_test_message ("new-frame signal recieved (end of timeline)\n");
g_print ("Rewinding timeline\n"); g_test_message ("Rewinding timeline\n");
clutter_timeline_rewind (timeline); clutter_timeline_rewind (timeline);
state->rewind_count++; state->rewind_count++;
} }
@ -51,29 +53,28 @@ new_frame_cb (ClutterTimeline *timeline,
{ {
if (current_frame == 0) if (current_frame == 0)
{ {
g_print ("new-frame signal recieved (start of timeline)\n"); g_test_message ("new-frame signal recieved (start of timeline)\n");
} }
else else
{ {
g_print ("new-frame signal recieved (mid frame)\n"); g_test_message ("new-frame signal recieved (mid frame)\n");
} }
if (state->rewind_count >= 2) if (state->rewind_count >= 2)
{ {
g_print ("Sleeping for 1 second\n"); g_test_message ("Sleeping for 1 second\n");
g_usleep (1000000); g_usleep (1000000);
} }
} }
} }
int void
main (int argc, char **argv) test_timeline_rewind (TestConformSimpleFixture *fixture,
gconstpointer data)
{ {
TestState state; TestState state;
clutter_init (&argc, &argv);
state.timeline = state.timeline =
clutter_timeline_new (TEST_TIMELINE_FRAME_COUNT, clutter_timeline_new (TEST_TIMELINE_FRAME_COUNT,
TEST_TIMELINE_FPS); TEST_TIMELINE_FPS);
@ -81,7 +82,8 @@ main (int argc, char **argv)
"new-frame", "new-frame",
G_CALLBACK(new_frame_cb), G_CALLBACK(new_frame_cb),
&state); &state);
g_print ("Installing a watchdog timeout to determin if this test hangs\n"); g_test_message ("Installing a watchdog timeout "
"to determine if this test hangs\n");
g_timeout_add (TEST_WATCHDOG_KICK_IN_SECONDS*1000, g_timeout_add (TEST_WATCHDOG_KICK_IN_SECONDS*1000,
(GSourceFunc)watchdog_timeout, (GSourceFunc)watchdog_timeout,
&state); &state);
@ -91,6 +93,6 @@ main (int argc, char **argv)
clutter_main(); clutter_main();
return EXIT_FAILURE; g_object_unref (state.timeline);
} }

View File

@ -2,6 +2,8 @@
#include <glib.h> #include <glib.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
#include "test-conform-common.h"
#define TEST_TIMELINE_FPS 10 #define TEST_TIMELINE_FPS 10
#define TEST_TIMELINE_FRAME_COUNT 20 #define TEST_TIMELINE_FRAME_COUNT 20
#define TEST_ERROR_TOLERANCE 5 #define TEST_ERROR_TOLERANCE 5
@ -33,24 +35,25 @@ new_frame_cb (ClutterTimeline *timeline,
if (state->frame>0) if (state->frame>0)
{ {
frame_elapsed_ms = frame_elapsed_ms =
(current_time.tv_sec - state->prev_frame_time.tv_sec) * 1000; (current_time.tv_sec - state->prev_frame_time.tv_sec) * 1000;
frame_elapsed_ms += frame_elapsed_ms +=
(current_time.tv_usec - state->prev_frame_time.tv_usec)/1000; (current_time.tv_usec - state->prev_frame_time.tv_usec)/1000;
if (ABS(frame_elapsed_ms - (1000/TEST_TIMELINE_FPS)) if (ABS(frame_elapsed_ms - (1000/TEST_TIMELINE_FPS))
> TEST_ERROR_TOLERANCE) > TEST_ERROR_TOLERANCE)
{ {
state->passed = FALSE; state->passed = FALSE;
bump = " (BUMP)"; bump = " (BUMP)";
} }
} }
g_print ("timeline frame=%-2d total elapsed=%-4li(ms) since last frame=%-4li(ms)%s\n", g_test_message ("timeline frame=%-2d total elapsed=%-4li(ms) "
clutter_timeline_get_current_frame(state->timeline), "since last frame=%-4li(ms)%s\n",
total_elapsed_ms, clutter_timeline_get_current_frame(state->timeline),
frame_elapsed_ms, total_elapsed_ms,
bump); frame_elapsed_ms,
bump);
state->prev_frame_time = current_time; state->prev_frame_time = current_time;
state->frame++; state->frame++;
@ -59,45 +62,44 @@ new_frame_cb (ClutterTimeline *timeline,
static void static void
completed_cb (ClutterTimeline *timeline, completed_cb (ClutterTimeline *timeline,
TestState *state) TestState *state)
{ {
state->completion_count++; state->completion_count++;
if (state->completion_count == 2) if (state->completion_count == 2)
{ {
if (state->passed) if (state->passed)
{ {
g_print("Passed\n"); g_test_message ("Passed\n");
exit(EXIT_SUCCESS); clutter_main_quit ();
} }
else else
{ {
g_print("Failed\n"); g_test_message ("Failed\n");
exit(EXIT_FAILURE); exit (EXIT_FAILURE);
} }
} }
} }
int void
main(int argc, char **argv) test_timeline_smoothness (TestConformSimpleFixture *fixture,
gconstpointer data)
{ {
TestState state; TestState state;
clutter_init (&argc, &argv);
state.timeline = state.timeline =
clutter_timeline_new (TEST_TIMELINE_FRAME_COUNT, clutter_timeline_new (TEST_TIMELINE_FRAME_COUNT,
TEST_TIMELINE_FPS); TEST_TIMELINE_FPS);
clutter_timeline_set_loop (state.timeline, TRUE); clutter_timeline_set_loop (state.timeline, TRUE);
g_signal_connect (G_OBJECT(state.timeline), g_signal_connect (G_OBJECT(state.timeline),
"new-frame", "new-frame",
G_CALLBACK(new_frame_cb), G_CALLBACK(new_frame_cb),
&state); &state);
g_signal_connect (G_OBJECT(state.timeline), g_signal_connect (G_OBJECT(state.timeline),
"completed", "completed",
G_CALLBACK(completed_cb), G_CALLBACK(completed_cb),
&state); &state);
state.frame = 0; state.frame = 0;
state.completion_count = 0; state.completion_count = 0;
@ -108,6 +110,6 @@ main(int argc, char **argv)
clutter_main(); clutter_main();
return EXIT_FAILURE; g_object_unref (state.timeline);
} }

View File

@ -0,0 +1,140 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gmodule.h>
#include <clutter/clutter.h>
static void
timeline_1_complete (ClutterTimeline *timeline)
{
g_debug ("1: Completed");
}
static void
timeline_2_complete (ClutterTimeline *timeline)
{
g_debug ("2: Completed");
}
static void
timeline_3_complete (ClutterTimeline *timeline)
{
g_debug ("3: Completed");
}
static void
timeline_1_new_frame_cb (ClutterTimeline *timeline, gint frame_no)
{
g_debug ("1: Doing frame %d.", frame_no);
}
static void
timeline_2_new_frame_cb (ClutterTimeline *timeline, gint frame_no)
{
g_debug ("2: Doing frame %d.", frame_no);
}
static void
timeline_3_new_frame_cb (ClutterTimeline *timeline, gint frame_no)
{
g_debug ("3: Doing frame %d.", frame_no);
}
static void
timeline_1_marker_reached (ClutterTimeline *timeline,
const gchar *marker_name,
guint frame_num)
{
g_print ("1: Marker `%s' (%d) reached\n", marker_name, frame_num);
}
static void
timeline_2_marker_reached (ClutterTimeline *timeline,
const gchar *marker_name,
guint frame_num)
{
g_print ("2: Marker `%s' (%d) reached\n", marker_name, frame_num);
}
static void
timeline_3_marker_reached (ClutterTimeline *timeline,
const gchar *marker_name,
guint frame_num)
{
g_print ("3: Marker `%s' (%d) reached\n", marker_name, frame_num);
}
G_MODULE_EXPORT int
test_timeline_main (int argc, char **argv)
{
ClutterTimeline *timeline_1;
ClutterTimeline *timeline_2;
ClutterTimeline *timeline_3;
gchar **markers;
gsize n_markers;
clutter_init (&argc, &argv);
timeline_1 = clutter_timeline_new (10, 120);
clutter_timeline_add_marker_at_frame (timeline_1, "foo", 5);
clutter_timeline_add_marker_at_frame (timeline_1, "bar", 5);
clutter_timeline_add_marker_at_frame (timeline_1, "baz", 5);
markers = clutter_timeline_list_markers (timeline_1, 5, &n_markers);
g_assert (markers != NULL);
g_assert (n_markers == 3);
g_strfreev (markers);
timeline_2 = clutter_timeline_clone (timeline_1);
clutter_timeline_add_marker_at_frame (timeline_2, "bar", 2);
markers = clutter_timeline_list_markers (timeline_2, -1, &n_markers);
g_assert (markers != NULL);
g_assert (n_markers == 1);
g_assert (strcmp (markers[0], "bar") == 0);
g_strfreev (markers);
timeline_3 = clutter_timeline_clone (timeline_1);
clutter_timeline_set_direction (timeline_3, CLUTTER_TIMELINE_BACKWARD);
clutter_timeline_add_marker_at_frame (timeline_3, "baz", 8);
g_signal_connect (timeline_1,
"marker-reached", G_CALLBACK (timeline_1_marker_reached),
NULL);
g_signal_connect (timeline_1,
"new-frame", G_CALLBACK (timeline_1_new_frame_cb),
NULL);
g_signal_connect (timeline_1,
"completed", G_CALLBACK (timeline_1_complete),
NULL);
g_signal_connect (timeline_2,
"marker-reached::bar", G_CALLBACK (timeline_2_marker_reached),
NULL);
g_signal_connect (timeline_2,
"new-frame", G_CALLBACK (timeline_2_new_frame_cb),
NULL);
g_signal_connect (timeline_2,
"completed", G_CALLBACK (timeline_2_complete),
NULL);
g_signal_connect (timeline_3,
"marker-reached", G_CALLBACK (timeline_3_marker_reached),
NULL);
g_signal_connect (timeline_3,
"new-frame", G_CALLBACK (timeline_3_new_frame_cb),
NULL);
g_signal_connect (timeline_3,
"completed", G_CALLBACK (timeline_3_complete),
NULL);
clutter_timeline_start (timeline_1);
clutter_timeline_start (timeline_2);
clutter_timeline_start (timeline_3);
clutter_main ();
g_object_unref (timeline_1);
g_object_unref (timeline_2);
g_object_unref (timeline_3);
return EXIT_SUCCESS;
}

15
tests/conform/wrapper.sh Executable file
View File

@ -0,0 +1,15 @@
#!/bin/sh
UNIT_TEST=`basename $0`
UNIT_TEST_PATH=`./test-conformance -l |grep $UNIT_TEST`
echo "Running: gtester -p $UNIT_TEST_PATH ./test-conformance"
echo ""
gtester -p $UNIT_TEST_PATH ./test-conformance
echo ""
echo "NOTE: For debugging purposes, you can run this single test as follows:"
echo "$ libtool --mode=execute \\"
echo " gdb --eval-command=\"b $UNIT_TEST\" \\"
echo " --args ./test-conformance -p $UNIT_TEST_PATH"

5
tests/data/Makefile.am Normal file
View File

@ -0,0 +1,5 @@
EXTRA_DIST = \
redhand.png \
test-script.json

View File

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@ -0,0 +1,69 @@
UNIT_TESTS = \
test-textures.c \
test-events.c \
test-offscreen.c \
test-scale.c \
test-actors.c \
test-behave.c \
test-entry.c \
test-project.c \
test-perspective.c \
test-rotate.c \
test-depth.c \
test-threads.c \
test-score.c \
test-script.c \
test-model.c \
test-grab.c \
test-effects.c \
test-fullscreen.c \
test-shader.c \
test-unproject.c \
test-viewport test-fbo.c \
test-opacity.c \
test-multistage.c \
test-cogl-primitives.c \
test-cogl-tex-tile.c \
test-cogl-tex-convert.c \
test-cogl-tex-foreign.c \
test-cogl-tex-getset.c \
test-cogl-offscreen.c \
test-cogl-tex-polygon.c \
test-stage-read-pixels.c \
test-random-text.c \
test-clip.c \
test-paint-wrapper.c \
test-texture-quality.c \
test-entry-auto.c \
test-layout.c \
test-invariants.c
#FIXME - this is is a bit of a yukky way of ensuring the tests find our data:
test-script.json:
ln -sf $(top_srcdir)/tests/data/test-script.json
redhand.png:
ln -sf $(top_srcdir)/tests/data/redhand.png
# For convenience, this provides a way to easily run individual unit tests:
.PHONY: wrappers
wrappers: test-interactive
for i in $(UNIT_TESTS); \
do \
ln -sf $(top_srcdir)/tests/interactive/wrapper.sh $${i%*.c}; \
done
# NB: BUILT_SOURCES here a misnomer. We aren't building source, just inserting
# a phony rule that will generate symlink scripts for running individual tests
BUILT_SOURCES = wrappers redhand.png test-script.json
INCLUDES = -I$(top_srcdir)/ -I$(top_srcdir)/clutter -I$(top_builddir)/clutter
LDADD = $(top_builddir)/clutter/libclutter-@CLUTTER_FLAVOUR@-@CLUTTER_MAJORMINOR@.la
AM_CFLAGS = $(CLUTTER_CFLAGS)
AM_LDFLAGS = $(CLUTTER_LIBS)
noinst_PROGRAMS = test-interactive
test_interactive_SOURCES = \
test-main.c \
$(UNIT_TESTS)
test_interactive_LDFLAGS = -export-dynamic

View File

@ -8,6 +8,7 @@
#include <errno.h> #include <errno.h>
#include <stdlib.h> #include <stdlib.h>
#include <glib.h> #include <glib.h>
#include <gmodule.h>
#define TRAILS 0 #define TRAILS 0
#define NHANDS 6 #define NHANDS 6
@ -122,8 +123,8 @@ frame_cb (ClutterTimeline *timeline,
} }
} }
int G_MODULE_EXPORT int
main (int argc, char *argv[]) test_actors_main (int argc, char *argv[])
{ {
ClutterTimeline *timeline; ClutterTimeline *timeline;
ClutterAlpha *alpha; ClutterAlpha *alpha;

View File

@ -3,6 +3,7 @@
#include <string.h> #include <string.h>
#include <glib.h> #include <glib.h>
#include <gmodule.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
@ -67,8 +68,8 @@ typedef enum {
#define MAGIC 0.551784 #define MAGIC 0.551784
#define RADIUS 200 #define RADIUS 200
int G_MODULE_EXPORT int
main (int argc, char *argv[]) test_behave_main (int argc, char *argv[])
{ {
ClutterTimeline *timeline; ClutterTimeline *timeline;
ClutterAlpha *alpha; ClutterAlpha *alpha;

View File

@ -2,6 +2,7 @@
#include <math.h> #include <math.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <gmodule.h>
#define TL_SCALE 5.0f #define TL_SCALE 5.0f
@ -58,8 +59,8 @@ on_new_frame (ClutterTimeline *tl, int frame_num, CallbackData *data)
} }
} }
int G_MODULE_EXPORT int
main (int argc, char **argv) test_clip_main (int argc, char **argv)
{ {
ClutterGeometry geom; ClutterGeometry geom;
ClutterTimeline *tl; ClutterTimeline *tl;

View File

@ -1,5 +1,6 @@
#include <config.h> #include <config.h>
#include <glib.h> #include <glib.h>
#include <gmodule.h>
#include <stdlib.h> #include <stdlib.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
#include <cogl/cogl.h> #include <cogl/cogl.h>
@ -54,7 +55,7 @@ struct _TestCoglboxClass
void (*_test_coglbox4) (void); void (*_test_coglbox4) (void);
}; };
GType test_coglbox_get_type (void) G_GNUC_CONST; static GType test_coglbox_get_type (void) G_GNUC_CONST;
G_END_DECLS G_END_DECLS
@ -186,14 +187,14 @@ test_coglbox_class_init (TestCoglboxClass *klass)
g_type_class_add_private (gobject_class, sizeof (TestCoglboxPrivate)); g_type_class_add_private (gobject_class, sizeof (TestCoglboxPrivate));
} }
ClutterActor* static ClutterActor*
test_coglbox_new (void) test_coglbox_new (void)
{ {
return g_object_new (TEST_TYPE_COGLBOX, NULL); return g_object_new (TEST_TYPE_COGLBOX, NULL);
} }
int G_MODULE_EXPORT int
main (int argc, char *argv[]) test_cogl_offscreen_main (int argc, char *argv[])
{ {
ClutterActor *stage; ClutterActor *stage;
ClutterActor *coglbox; ClutterActor *coglbox;

View File

@ -1,5 +1,6 @@
#include <config.h> #include <config.h>
#include <glib.h> #include <glib.h>
#include <gmodule.h>
#include <stdlib.h> #include <stdlib.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
#include <cogl/cogl.h> #include <cogl/cogl.h>
@ -54,7 +55,7 @@ struct _TestCoglboxClass
void (*_test_coglbox4) (void); void (*_test_coglbox4) (void);
}; };
GType test_coglbox_get_type (void) G_GNUC_CONST; static GType test_coglbox_get_type (void) G_GNUC_CONST;
G_END_DECLS G_END_DECLS
@ -257,7 +258,7 @@ test_coglbox_class_init (TestCoglboxClass *klass)
g_type_class_add_private (gobject_class, sizeof (TestCoglboxPrivate)); g_type_class_add_private (gobject_class, sizeof (TestCoglboxPrivate));
} }
ClutterActor* static ClutterActor*
test_coglbox_new (void) test_coglbox_new (void)
{ {
return g_object_new (TEST_TYPE_COGLBOX, NULL); return g_object_new (TEST_TYPE_COGLBOX, NULL);
@ -266,8 +267,8 @@ test_coglbox_new (void)
#define SPIN() while (g_main_context_pending (NULL)) \ #define SPIN() while (g_main_context_pending (NULL)) \
g_main_context_iteration (NULL, FALSE); g_main_context_iteration (NULL, FALSE);
int G_MODULE_EXPORT int
main (int argc, char *argv[]) test_cogl_primitives_main (int argc, char *argv[])
{ {
ClutterActor *stage; ClutterActor *stage;
ClutterActor *coglbox; ClutterActor *coglbox;

View File

@ -1,5 +1,6 @@
#include <config.h> #include <config.h>
#include <glib.h> #include <glib.h>
#include <gmodule.h>
#include <stdlib.h> #include <stdlib.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
#include <cogl/cogl.h> #include <cogl/cogl.h>
@ -54,7 +55,7 @@ struct _TestCoglboxClass
void (*_test_coglbox4) (void); void (*_test_coglbox4) (void);
}; };
GType test_coglbox_get_type (void) G_GNUC_CONST; static GType test_coglbox_get_type (void) G_GNUC_CONST;
G_END_DECLS G_END_DECLS
@ -192,14 +193,14 @@ test_coglbox_class_init (TestCoglboxClass *klass)
g_type_class_add_private (gobject_class, sizeof (TestCoglboxPrivate)); g_type_class_add_private (gobject_class, sizeof (TestCoglboxPrivate));
} }
ClutterActor* static ClutterActor*
test_coglbox_new (void) test_coglbox_new (void)
{ {
return g_object_new (TEST_TYPE_COGLBOX, NULL); return g_object_new (TEST_TYPE_COGLBOX, NULL);
} }
int G_MODULE_EXPORT int
main (int argc, char *argv[]) test_cogl_tex_convert_main (int argc, char *argv[])
{ {
ClutterActor *stage; ClutterActor *stage;
ClutterActor *coglbox; ClutterActor *coglbox;

View File

@ -1,5 +1,6 @@
#include <config.h> #include <config.h>
#include <glib.h> #include <glib.h>
#include <gmodule.h>
#include <stdlib.h> #include <stdlib.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
#include <cogl/cogl.h> #include <cogl/cogl.h>
@ -54,7 +55,7 @@ struct _TestCoglboxClass
void (*_test_coglbox4) (void); void (*_test_coglbox4) (void);
}; };
GType test_coglbox_get_type (void) G_GNUC_CONST; static GType test_coglbox_get_type (void) G_GNUC_CONST;
G_END_DECLS G_END_DECLS
@ -182,14 +183,14 @@ test_coglbox_class_init (TestCoglboxClass *klass)
g_type_class_add_private (gobject_class, sizeof (TestCoglboxPrivate)); g_type_class_add_private (gobject_class, sizeof (TestCoglboxPrivate));
} }
ClutterActor* static ClutterActor*
test_coglbox_new (void) test_coglbox_new (void)
{ {
return g_object_new (TEST_TYPE_COGLBOX, NULL); return g_object_new (TEST_TYPE_COGLBOX, NULL);
} }
int G_MODULE_EXPORT int
main (int argc, char *argv[]) test_cogl_tex_foreign_main (int argc, char *argv[])
{ {
ClutterActor *stage; ClutterActor *stage;
ClutterActor *coglbox; ClutterActor *coglbox;

View File

@ -1,5 +1,6 @@
#include <config.h> #include <config.h>
#include <glib.h> #include <glib.h>
#include <gmodule.h>
#include <stdlib.h> #include <stdlib.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
#include <cogl/cogl.h> #include <cogl/cogl.h>
@ -54,7 +55,7 @@ struct _TestCoglboxClass
void (*_test_coglbox4) (void); void (*_test_coglbox4) (void);
}; };
GType test_coglbox_get_type (void) G_GNUC_CONST; static GType test_coglbox_get_type (void) G_GNUC_CONST;
G_END_DECLS G_END_DECLS
@ -240,14 +241,14 @@ test_coglbox_class_init (TestCoglboxClass *klass)
g_type_class_add_private (gobject_class, sizeof (TestCoglboxPrivate)); g_type_class_add_private (gobject_class, sizeof (TestCoglboxPrivate));
} }
ClutterActor* static ClutterActor*
test_coglbox_new (void) test_coglbox_new (void)
{ {
return g_object_new (TEST_TYPE_COGLBOX, NULL); return g_object_new (TEST_TYPE_COGLBOX, NULL);
} }
int G_MODULE_EXPORT int
main (int argc, char *argv[]) test_cogl_tex_getset_main (int argc, char *argv[])
{ {
ClutterActor *stage; ClutterActor *stage;
ClutterActor *coglbox; ClutterActor *coglbox;

View File

@ -1,5 +1,6 @@
#include <config.h> #include <config.h>
#include <glib.h> #include <glib.h>
#include <gmodule.h>
#include <stdlib.h> #include <stdlib.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
#include <cogl/cogl.h> #include <cogl/cogl.h>
@ -54,7 +55,7 @@ struct _TestCoglboxClass
void (*_test_coglbox4) (void); void (*_test_coglbox4) (void);
}; };
GType test_coglbox_get_type (void) G_GNUC_CONST; static GType test_coglbox_get_type (void) G_GNUC_CONST;
G_END_DECLS G_END_DECLS
@ -282,7 +283,7 @@ test_coglbox_class_init (TestCoglboxClass *klass)
g_type_class_add_private (gobject_class, sizeof (TestCoglboxPrivate)); g_type_class_add_private (gobject_class, sizeof (TestCoglboxPrivate));
} }
ClutterActor* static ClutterActor*
test_coglbox_new (void) test_coglbox_new (void)
{ {
return g_object_new (TEST_TYPE_COGLBOX, NULL); return g_object_new (TEST_TYPE_COGLBOX, NULL);
@ -334,8 +335,8 @@ make_toggle (const char *label_text, gboolean *toggle_val)
return group; return group;
} }
int G_MODULE_EXPORT int
main (int argc, char *argv[]) test_cogl_tex_polygon_main (int argc, char *argv[])
{ {
ClutterActor *stage; ClutterActor *stage;
ClutterActor *coglbox; ClutterActor *coglbox;

View File

@ -1,5 +1,6 @@
#include <config.h> #include <config.h>
#include <glib.h> #include <glib.h>
#include <gmodule.h>
#include <stdlib.h> #include <stdlib.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
#include <cogl/cogl.h> #include <cogl/cogl.h>
@ -54,7 +55,7 @@ struct _TestCoglboxClass
void (*_test_coglbox4) (void); void (*_test_coglbox4) (void);
}; };
GType test_coglbox_get_type (void) G_GNUC_CONST; static GType test_coglbox_get_type (void) G_GNUC_CONST;
G_END_DECLS G_END_DECLS
@ -177,7 +178,7 @@ test_coglbox_class_init (TestCoglboxClass *klass)
g_type_class_add_private (gobject_class, sizeof (TestCoglboxPrivate)); g_type_class_add_private (gobject_class, sizeof (TestCoglboxPrivate));
} }
ClutterActor* static ClutterActor*
test_coglbox_new (void) test_coglbox_new (void)
{ {
return g_object_new (TEST_TYPE_COGLBOX, NULL); return g_object_new (TEST_TYPE_COGLBOX, NULL);
@ -194,8 +195,8 @@ frame_cb (ClutterTimeline *timeline,
clutter_actor_queue_redraw (CLUTTER_ACTOR (data)); clutter_actor_queue_redraw (CLUTTER_ACTOR (data));
} }
int G_MODULE_EXPORT int
main (int argc, char *argv[]) test_cogl_tex_tile_main (int argc, char *argv[])
{ {
ClutterActor *stage; ClutterActor *stage;
ClutterActor *coglbox; ClutterActor *coglbox;

View File

@ -1,4 +1,5 @@
#include <stdlib.h> #include <stdlib.h>
#include <gmodule.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
/* each time the timeline animating the label completes, swap the direction */ /* each time the timeline animating the label completes, swap the direction */
@ -106,8 +107,8 @@ janus_group (const gchar *front_text,
} }
gint G_MODULE_EXPORT gint
main (int argc, char *argv[]) test_depth_main (int argc, char *argv[])
{ {
ClutterTimeline *timeline; ClutterTimeline *timeline;
ClutterBehaviour *d_behave; ClutterBehaviour *d_behave;

View File

@ -1,3 +1,4 @@
#include <gmodule.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
#include <clutter/x11/clutter-x11.h> #include <clutter/x11/clutter-x11.h>
@ -24,8 +25,8 @@ stage_motion_event_cb (ClutterActor *actor,
return FALSE; return FALSE;
} }
int G_MODULE_EXPORT int
main (int argc, char **argv) test_devices_main (int argc, char **argv)
{ {
ClutterActor *stage = NULL; ClutterActor *stage = NULL;
GSList *stage_devices = NULL; GSList *stage_devices = NULL;

View File

@ -1,11 +1,12 @@
#include <stdlib.h> #include <stdlib.h>
#include <gmodule.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
static ClutterEffectTemplate *tmpl = NULL; static ClutterEffectTemplate *tmpl = NULL;
static ClutterTimeline *timeline = NULL; static ClutterTimeline *timeline = NULL;
int G_MODULE_EXPORT int
main (int argc, char *argv[]) test_effects_main (int argc, char *argv[])
{ {
ClutterActor *stage, *actor; ClutterActor *stage, *actor;
ClutterContainer *container; ClutterContainer *container;

View File

@ -1,4 +1,4 @@
#include <gmodule.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
#include <string.h> #include <string.h>
@ -267,8 +267,8 @@ run (void (*test_func)(ClutterEntry *, const TestData *), const TestData *t)
clutter_actor_destroy (entry); clutter_actor_destroy (entry);
} }
int G_MODULE_EXPORT int
main (int argc, char **argv) test_entry_auto_main (int argc, char **argv)
{ {
int i; int i;

View File

@ -1,3 +1,4 @@
#include <gmodule.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
static void static void
@ -6,8 +7,8 @@ on_entry_activated (ClutterEntry *entry, gpointer null)
g_print ("Activated: %s\n", clutter_entry_get_text (entry)); g_print ("Activated: %s\n", clutter_entry_get_text (entry));
} }
int G_MODULE_EXPORT int
main (int argc, char *argv[]) test_entry_main (int argc, char *argv[])
{ {
ClutterActor *entry; ClutterActor *entry;
ClutterActor *stage; ClutterActor *stage;

View File

@ -1,3 +1,4 @@
#include <gmodule.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
#include <string.h> #include <string.h>
@ -189,8 +190,8 @@ input_cb (ClutterActor *actor,
return FALSE; return FALSE;
} }
int G_MODULE_EXPORT int
main (int argc, char *argv[]) test_events_main (int argc, char *argv[])
{ {
ClutterActor *stage, *actor, *focus_box, *group; ClutterActor *stage, *actor, *focus_box, *group;
ClutterColor rcol = { 0xff, 0, 0, 0xff}, ClutterColor rcol = { 0xff, 0, 0, 0xff},

View File

@ -26,6 +26,7 @@
#include <errno.h> #include <errno.h>
#include <stdlib.h> #include <stdlib.h>
#include <glib.h> #include <glib.h>
#include <gmodule.h>
ClutterActor* ClutterActor*
make_source(void) make_source(void)
@ -97,9 +98,8 @@ make_shader(void)
return shader; return shader;
} }
gint G_MODULE_EXPORT gint
main (gint argc, test_fbo_main (gint argc, gchar *argv[])
gchar *argv[])
{ {
ClutterColor blue = {0x33, 0x44, 0x55, 0xff}; ClutterColor blue = {0x33, 0x44, 0x55, 0xff};

View File

@ -1,4 +1,5 @@
#include <stdlib.h> #include <stdlib.h>
#include <gmodule.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
enum enum
@ -66,8 +67,8 @@ toggle_fullscreen (gpointer dummy)
return FALSE; return FALSE;
} }
int G_MODULE_EXPORT int
main (int argc, char *argv[]) test_fullscreen_main (int argc, char *argv[])
{ {
ClutterActor *stage; ClutterActor *stage;

View File

@ -1,3 +1,4 @@
#include <gmodule.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
static void static void
@ -144,8 +145,8 @@ cyan_press_cb (ClutterActor *actor,
int G_MODULE_EXPORT int
main (int argc, char *argv[]) test_grab_main (int argc, char *argv[])
{ {
ClutterActor *stage, *actor; ClutterActor *stage, *actor;
ClutterColor rcol = { 0xff, 0, 0, 0xff}, ClutterColor rcol = { 0xff, 0, 0, 0xff},

View File

@ -1,6 +1,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <gmodule.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
/* dummy unit testing API; to be replaced by GTest in 1.0 */ /* dummy unit testing API; to be replaced by GTest in 1.0 */
@ -173,9 +174,8 @@ test_show_on_set_parent (void)
clutter_actor_destroy (group); clutter_actor_destroy (group);
} }
int G_MODULE_EXPORT int
main (int argc, test_invariants_main (int argc, char *argv[])
char *argv[])
{ {
test_init (&argc, &argv); test_init (&argc, &argv);

View File

@ -1,6 +1,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <gmodule.h>
#include <cogl/cogl.h> #include <cogl/cogl.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
@ -743,9 +744,8 @@ relayout_on_frame (ClutterTimeline *timeline)
clutter_actor_queue_relayout (box); clutter_actor_queue_relayout (box);
} }
int G_MODULE_EXPORT int
main (int argc, test_layout_main (int argc, char *argv[])
char *argv[])
{ {
ClutterActor *stage, *instructions; ClutterActor *stage, *instructions;
gint i; gint i;

View File

@ -0,0 +1,37 @@
#include <glib.h>
#include <gmodule.h>
int
main (int argc, char **argv)
{
GModule *module;
char *unit_test;
char *main_symbol_name;
int (*unit_test_main) (int argc, char **argv);
int ret;
if (argc != 2)
g_error ("Usage: %s unit_test");
module = g_module_open (NULL, 0);
if (!module)
g_error ("Failed to open self for symbol lookup");
unit_test = g_path_get_basename (argv[1]);
main_symbol_name = g_strdup_printf ("%s_main", unit_test);
main_symbol_name = g_strdelimit (main_symbol_name, "-", '_');
if (!g_module_symbol (module, main_symbol_name, &unit_test_main))
g_error ("Failed to look up main symbol for the test: %s", unit_test);
ret = unit_test_main (argc - 1, argv + 1);
g_free (unit_test);
g_free (main_symbol_name);
g_module_close (module);
return ret;
}

View File

@ -1,3 +1,4 @@
#include <gmodule.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
#include <string.h> #include <string.h>
@ -205,8 +206,8 @@ on_filter_changed (ClutterModel *model)
g_print ("*** Filter Changed ***\n\n"); g_print ("*** Filter Changed ***\n\n");
} }
int G_MODULE_EXPORT int
main (int argc, char *argv[]) test_model_main (int argc, char *argv[])
{ {
ClutterModel *model; ClutterModel *model;

View File

@ -1,3 +1,4 @@
#include <gmodule.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
static gint n_stages = 1; static gint n_stages = 1;
@ -96,8 +97,8 @@ on_button_press (ClutterActor *actor,
return TRUE; return TRUE;
} }
int G_MODULE_EXPORT int
main (int argc, char *argv[]) test_multistage_main (int argc, char *argv[])
{ {
ClutterActor *stage_default; ClutterActor *stage_default;
ClutterActor *label; ClutterActor *label;

View File

@ -1,9 +1,10 @@
#include <gmodule.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
/* Very simple test just to see what happens setting up offscreen rendering */ /* Very simple test just to see what happens setting up offscreen rendering */
int G_MODULE_EXPORT int
main (int argc, char *argv[]) test_offscreen_main (int argc, char *argv[])
{ {
ClutterActor *stage; ClutterActor *stage;
gboolean offscreen; gboolean offscreen;

View File

@ -2,11 +2,12 @@
#include <stdio.h> #include <stdio.h>
#include <glib.h> #include <glib.h>
#include <gmodule.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
int G_MODULE_EXPORT int
main (int argc, char *argv[]) test_opacity_main (int argc, char *argv[])
{ {
ClutterActor *stage, *group1, *group2, *label, *rect; ClutterActor *stage, *group1, *group2, *label, *rect;
ClutterColor label_color = { 255, 0, 0, 128 }; ClutterColor label_color = { 255, 0, 0, 128 };

View File

@ -1,3 +1,4 @@
#include <gmodule.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
#if defined (_MSC_VER) && !defined (_USE_MATH_DEFINES) #if defined (_MSC_VER) && !defined (_USE_MATH_DEFINES)
@ -155,8 +156,8 @@ hand_post_paint (ClutterActor *actor,
hand_pre_paint_guard = FALSE; hand_pre_paint_guard = FALSE;
} }
int G_MODULE_EXPORT int
main (int argc, char *argv[]) test_paint_wrapper_main (int argc, char *argv[])
{ {
ClutterTimeline *timeline; ClutterTimeline *timeline;
ClutterAlpha *alpha; ClutterAlpha *alpha;

View File

@ -1,7 +1,8 @@
#include <gmodule.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
int G_MODULE_EXPORT int
main (int argc, char *argv[]) test_perspective_main (int argc, char *argv[])
{ {
ClutterActor *rect; ClutterActor *rect;
ClutterActor *stage; ClutterActor *stage;

View File

@ -2,6 +2,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <gmodule.h>
#if HAVE_CLUTTER_GLX #if HAVE_CLUTTER_GLX
@ -177,8 +178,8 @@ create_pixmap (guint *width, guint *height, guint *depth)
} }
# endif /* USE_GDKPIXBUF */ # endif /* USE_GDKPIXBUF */
int G_MODULE_EXPORT int
main (int argc, char **argv) test_pixmap_main (int argc, char **argv)
{ {
#ifdef USE_GDKPIXBUF #ifdef USE_GDKPIXBUF
GOptionContext *context; GOptionContext *context;

View File

@ -1,6 +1,7 @@
#include <clutter/clutter.h> #include <clutter/clutter.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <gmodule.h>
static ClutterActor *main_stage, *rect, *p[5]; static ClutterActor *main_stage, *rect, *p[5];
@ -93,7 +94,7 @@ find_handle_index (ClutterActor * a)
return -1; return -1;
} }
gboolean static gboolean
on_event (ClutterStage *stage, on_event (ClutterStage *stage,
ClutterEvent *event, ClutterEvent *event,
gpointer user_data) gpointer user_data)
@ -202,8 +203,8 @@ on_event (ClutterStage *stage,
} }
int G_MODULE_EXPORT int
main (int argc, char *argv[]) test_project_main (int argc, char *argv[])
{ {
ClutterActor *label; ClutterActor *label;

View File

@ -1,3 +1,4 @@
#include <gmodule.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
#include <stdlib.h> #include <stdlib.h>
@ -66,8 +67,8 @@ on_idle (gpointer data)
return TRUE; return TRUE;
} }
int G_MODULE_EXPORT int
main (int argc, char **argv) test_random_text_main (int argc, char **argv)
{ {
ClutterActor *stage; ClutterActor *stage;

View File

@ -3,11 +3,12 @@
#include <string.h> #include <string.h>
#include <glib.h> #include <glib.h>
#include <gmodule.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
int G_MODULE_EXPORT int
main (int argc, char *argv[]) test_rotate_main (int argc, char *argv[])
{ {
ClutterTimeline *timeline; ClutterTimeline *timeline;
ClutterAlpha *alpha; ClutterAlpha *alpha;

View File

@ -1,4 +1,5 @@
#include <stdlib.h> #include <stdlib.h>
#include <gmodule.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
static const ClutterGravity gravities[] = { static const ClutterGravity gravities[] = {
@ -28,8 +29,8 @@ on_timeline_completed (ClutterTimeline *cluttertimeline,
clutter_actor_move_anchor_point_from_gravity (actor, gravities[gindex]); clutter_actor_move_anchor_point_from_gravity (actor, gravities[gindex]);
} }
int G_MODULE_EXPORT int
main (int argc, char *argv[]) test_scale_main (int argc, char *argv[])
{ {
ClutterActor *stage, *rect; ClutterActor *stage, *rect;
ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff }; ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff };

View File

@ -1,5 +1,6 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <gmodule.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
static gint level = 1; static gint level = 1;
@ -34,8 +35,8 @@ on_timeline_completed (ClutterScore *score,
(gchar *) g_object_get_data (G_OBJECT (timeline), "timeline-name")); (gchar *) g_object_get_data (G_OBJECT (timeline), "timeline-name"));
} }
int G_MODULE_EXPORT int
main (int argc, char **argv) test_score_main (int argc, char **argv)
{ {
ClutterScore *score; ClutterScore *score;
ClutterTimeline *timeline_1; ClutterTimeline *timeline_1;

View File

@ -2,6 +2,7 @@
#include <stdio.h> #include <stdio.h>
#include <glib.h> #include <glib.h>
#include <gmodule.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
@ -101,8 +102,8 @@ red_button_press (ClutterActor *actor,
return TRUE; return TRUE;
} }
int G_MODULE_EXPORT int
main (int argc, char *argv[]) test_script_main (int argc, char *argv[])
{ {
GObject *stage, *blue_button, *red_button; GObject *stage, *blue_button, *red_button;
GError *error = NULL; GError *error = NULL;

View File

@ -6,6 +6,7 @@
#include <errno.h> #include <errno.h>
#include <stdlib.h> #include <stdlib.h>
#include <glib.h> #include <glib.h>
#include <gmodule.h>
/* Dynamic branching appeared in "Shader Model 3.0" that low-end IGPs /* Dynamic branching appeared in "Shader Model 3.0" that low-end IGPs
* don't support. * don't support.
@ -293,9 +294,8 @@ timeout_cb (gpointer data)
} }
#endif /* HAVE_COGL_GLES2 */ #endif /* HAVE_COGL_GLES2 */
gint G_MODULE_EXPORT gint
main (gint argc, test_shader_main (gint argc, gchar *argv[])
gchar *argv[])
{ {
ClutterActor *actor; ClutterActor *actor;
ClutterActor *stage; ClutterActor *stage;

View File

@ -1,3 +1,4 @@
#include <gmodule.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
#include <string.h> #include <string.h>
@ -124,8 +125,8 @@ on_motion (ClutterActor *stage, ClutterMotionEvent *event, CallbackData *data)
return FALSE; return FALSE;
} }
int G_MODULE_EXPORT int
main (int argc, char **argv) test_stage_read_pixels_main (int argc, char **argv)
{ {
CallbackData data; CallbackData data;

View File

@ -1,4 +1,5 @@
#include <stdlib.h> #include <stdlib.h>
#include <gmodule.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
/* each time the timeline animating the label completes, swap the direction */ /* each time the timeline animating the label completes, swap the direction */
@ -38,8 +39,8 @@ change_filter (gpointer actor)
return TRUE; return TRUE;
} }
gint G_MODULE_EXPORT gint
main (int argc, char *argv[]) test_texture_quality_main (int argc, char *argv[])
{ {
ClutterTimeline *timeline; ClutterTimeline *timeline;
ClutterBehaviour *depth_behavior; ClutterBehaviour *depth_behavior;

View File

@ -3,6 +3,7 @@
#endif #endif
#include <stdlib.h> #include <stdlib.h>
#include <gmodule.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
@ -53,8 +54,8 @@ make_rgba_data (int width, int height, int bpp, int has_alpha, int *rowstride_p)
#define SPIN() while (g_main_context_pending (NULL)) \ #define SPIN() while (g_main_context_pending (NULL)) \
g_main_context_iteration (NULL, FALSE); g_main_context_iteration (NULL, FALSE);
int G_MODULE_EXPORT int
main (int argc, char *argv[]) test_textures_main (int argc, char *argv[])
{ {
ClutterActor *texture; ClutterActor *texture;
ClutterActor *stage; ClutterActor *stage;

View File

@ -1,5 +1,6 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <gmodule.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
typedef struct typedef struct
@ -167,8 +168,8 @@ on_key_press_event (ClutterStage *stage,
} }
} }
int G_MODULE_EXPORT int
main (int argc, char *argv[]) test_threads_main (int argc, char *argv[])
{ {
ClutterActor *stage; ClutterActor *stage;
ClutterActor *rect; ClutterActor *rect;

View File

@ -3,6 +3,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <gmodule.h>
ClutterActor *label; ClutterActor *label;
@ -11,7 +12,7 @@ ClutterActor *label;
#define RECT_W 320 #define RECT_W 320
#define RECT_H 240 #define RECT_H 240
gboolean static gboolean
on_event (ClutterStage *stage, on_event (ClutterStage *stage,
ClutterEvent *event, ClutterEvent *event,
gpointer user_data) gpointer user_data)
@ -68,8 +69,8 @@ on_event (ClutterStage *stage,
} }
int G_MODULE_EXPORT int
main (int argc, char *argv[]) test_unproject_main (int argc, char *argv[])
{ {
gchar *txt; gchar *txt;
ClutterActor *rect, *stage, *label0; ClutterActor *rect, *stage, *label0;

View File

@ -3,11 +3,12 @@
#include <string.h> #include <string.h>
#include <glib.h> #include <glib.h>
#include <gmodule.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
int G_MODULE_EXPORT int
main (int argc, char *argv[]) test_viewport_main (int argc, char *argv[])
{ {
ClutterTimeline *timeline; ClutterTimeline *timeline;
ClutterAlpha *alpha; ClutterAlpha *alpha;

13
tests/interactive/wrapper.sh Executable file
View File

@ -0,0 +1,13 @@
#!/bin/sh
UNIT_TEST=`basename $0`
echo "Running ./test-interactive $UNIT_TEST $@"
echo ""
echo "NOTE: For debugging purposes, you can run this single test as follows:"
echo "$ libtool --mode=execute \\"
echo " gdb --eval-command=\"b `echo $UNIT_TEST|tr '-' '_'`_main\" \\"
echo " --args ./test-interactive $UNIT_TEST"
./test-interactive $UNIT_TEST "$@"

View File

@ -0,0 +1,10 @@
noinst_PROGRAMS = \
test-text
INCLUDES = -I$(top_srcdir)/ -I$(top_srcdir)/clutter -I$(top_builddir)/clutter
LDADD = $(top_builddir)/clutter/libclutter-@CLUTTER_FLAVOUR@-@CLUTTER_MAJORMINOR@.la
AM_CFLAGS = $(CLUTTER_CFLAGS) -DTESTS_DATA_DIR=$(top_srcdir)/tests/data/
AM_LDFLAGS = $(CLUTTER_LIBS)
test_text_SOURCES = test-text.c

View File

@ -1,99 +0,0 @@
#include <clutter/clutter.h>
#define STAGE_WIDTH 320
#define STAGE_HEIGHT 200
#define ACTORS_X 12
#define ACTORS_Y 16
typedef struct _Data Data;
struct _Data
{
ClutterActor *stage;
int y, x;
guint32 gids[ACTORS_X * ACTORS_Y];
guint actor_width, actor_height;
int ret;
};
static gboolean
on_timeout (Data *data)
{
int y, x;
for (y = 0; y < ACTORS_Y; y++)
for (x = 0; x < ACTORS_X; x++)
{
gboolean pass = FALSE;
guint32 gid;
ClutterActor *actor
= clutter_stage_get_actor_at_pos (CLUTTER_STAGE (data->stage),
x * data->actor_width
+ data->actor_width / 2,
y * data->actor_height
+ data->actor_height / 2);
printf ("actor %u -> ", data->gids[y * ACTORS_X + x]);
if (actor == NULL)
printf ("NULL: FAIL\n");
else
{
gid = clutter_actor_get_gid (actor);
if (gid == data->gids[y * ACTORS_X + x])
pass = TRUE;
printf ("% 8i: %s\n", gid, pass ? "pass" : "FAIL");
}
if (!pass)
data->ret = 1;
}
clutter_main_quit ();
return FALSE;
}
int
main (int argc, char **argv)
{
int y, x;
Data data;
data.ret = 0;
clutter_init (&argc, &argv);
data.stage = clutter_stage_get_default ();
clutter_actor_set_size (data.stage, STAGE_WIDTH, STAGE_HEIGHT);
data.actor_width = STAGE_WIDTH / ACTORS_X;
data.actor_height = STAGE_HEIGHT / ACTORS_Y;
for (y = 0; y < ACTORS_Y; y++)
for (x = 0; x < ACTORS_X; x++)
{
ClutterColor color = { x * 255 / (ACTORS_X - 1),
y * 255 / (ACTORS_Y - 1),
128, 255 };
ClutterGeometry geom = { x * data.actor_width, y * data.actor_height,
data.actor_width, data.actor_height };
ClutterActor *rect = clutter_rectangle_new_with_color (&color);
clutter_actor_set_geometry (rect, &geom);
clutter_container_add (CLUTTER_CONTAINER (data.stage), rect, NULL);
data.gids[y * ACTORS_X + x] = clutter_actor_get_gid (rect);
}
clutter_actor_show (data.stage);
g_timeout_add (250, (GSourceFunc) on_timeout, &data);
clutter_main ();
printf ("end result: %s\n", data.ret ? "FAIL" : "pass");
return data.ret;
}

View File

@ -1,293 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <clutter/clutter.h>
/* This test runs three timelines at 30 fps with 10 frames. Some of
the timelines have markers. Once the timelines are run it then
checks that all of the frames were hit, all of the markers were hit
and that the completed signal was fired. The timelines are then run
again but this time with a timeout source that introduces a
delay. This should cause some frames to be skipped. The test is run
again but only the markers and the completed signal is checked
for. */
#define FRAME_COUNT 10
typedef struct _TimelineData TimelineData;
struct _TimelineData
{
int timeline_num;
guint frame_hit_count[FRAME_COUNT + 1];
GSList *markers_hit;
guint completed_count;
};
static void
timeline_data_init (TimelineData *data, int timeline_num)
{
memset (data, 0, sizeof (TimelineData));
data->timeline_num = timeline_num;
}
static void
timeline_data_destroy (TimelineData *data)
{
g_slist_foreach (data->markers_hit, (GFunc) g_free, NULL);
g_slist_free (data->markers_hit);
}
static void
timeline_complete_cb (ClutterTimeline *timeline,
TimelineData *data)
{
printf ("%i: Completed\n", data->timeline_num);
data->completed_count++;
}
static void
timeline_new_frame_cb (ClutterTimeline *timeline,
gint frame_no,
TimelineData *data)
{
printf ("%i: Doing frame %d, delta = %i\n",
data->timeline_num, frame_no,
clutter_timeline_get_delta (timeline, NULL));
data->frame_hit_count[frame_no]++;
}
static void
timeline_marker_reached_cb (ClutterTimeline *timeline,
const gchar *marker_name,
guint frame_num,
TimelineData *data)
{
printf ("%i: Marker `%s' (%d) reached, delta = %i\n",
data->timeline_num, marker_name, frame_num,
clutter_timeline_get_delta (timeline, NULL));
data->markers_hit = g_slist_prepend (data->markers_hit,
g_strdup (marker_name));
}
static gboolean
check_timeline (ClutterTimeline *timeline,
TimelineData *data,
gboolean check_missed_frames)
{
gchar **markers;
gsize n_markers;
guint *marker_reached_count;
gboolean succeeded = TRUE;
GSList *node;
int i;
int missed_frame_count = 0;
int frame_offset;
if (clutter_timeline_get_direction (timeline) == CLUTTER_TIMELINE_BACKWARD)
frame_offset = 0;
else
frame_offset = 1;
markers = clutter_timeline_list_markers (timeline, -1, &n_markers);
marker_reached_count = g_new0 (guint, n_markers);
for (node = data->markers_hit; node; node = node->next)
{
for (i = 0; i < n_markers; i++)
if (!strcmp (node->data, markers[i]))
break;
if (i < n_markers)
marker_reached_count[i]++;
else
{
printf ("FAIL: unknown marker '%s' hit for %i\n",
(char *) node->data, data->timeline_num);
succeeded = FALSE;
}
}
for (i = 0; i < n_markers; i++)
if (marker_reached_count[i] != 1)
{
printf ("FAIL: marker '%s' hit %i times for %i\n",
markers[i], marker_reached_count[i], data->timeline_num);
succeeded = FALSE;
}
if (check_missed_frames)
{
for (i = 0; i < FRAME_COUNT; i++)
if (data->frame_hit_count[i + frame_offset] != 1)
missed_frame_count++;
if (missed_frame_count)
{
printf ("FAIL: missed %i frame%s for %i\n",
missed_frame_count, missed_frame_count == 1 ? "" : "s",
data->timeline_num);
succeeded = FALSE;
}
}
if (data->completed_count != 1)
{
printf ("FAIL: timeline %i completed %i times\n",
data->timeline_num, data->completed_count);
succeeded = FALSE;
}
g_strfreev (markers);
g_free (marker_reached_count);
return succeeded;
}
static gboolean
timeout_cb (gpointer data)
{
clutter_main_quit ();
return FALSE;
}
static gboolean
delay_cb (gpointer data)
{
/* Waste a bit of time so that it will skip frames */
g_usleep (G_USEC_PER_SEC * 66 / 1000);
return TRUE;
}
int
main (int argc, char **argv)
{
ClutterTimeline *timeline_1;
TimelineData data_1;
ClutterTimeline *timeline_2;
TimelineData data_2;
ClutterTimeline *timeline_3;
TimelineData data_3;
gchar **markers;
gsize n_markers;
int ret = EXIT_SUCCESS;
clutter_init (&argc, &argv);
timeline_data_init (&data_1, 1);
timeline_1 = clutter_timeline_new (FRAME_COUNT, 30);
clutter_timeline_add_marker_at_frame (timeline_1, "foo", 5);
clutter_timeline_add_marker_at_frame (timeline_1, "bar", 5);
clutter_timeline_add_marker_at_frame (timeline_1, "baz", 5);
clutter_timeline_add_marker_at_frame (timeline_1, "near-end-marker", 9);
clutter_timeline_add_marker_at_frame (timeline_1, "end-marker", 10);
markers = clutter_timeline_list_markers (timeline_1, 5, &n_markers);
g_assert (markers != NULL);
g_assert (n_markers == 3);
g_strfreev (markers);
timeline_data_init (&data_2, 2);
timeline_2 = clutter_timeline_clone (timeline_1);
clutter_timeline_add_marker_at_frame (timeline_2, "bar", 2);
markers = clutter_timeline_list_markers (timeline_2, -1, &n_markers);
g_assert (markers != NULL);
g_assert (n_markers == 1);
g_assert (strcmp (markers[0], "bar") == 0);
g_strfreev (markers);
timeline_data_init (&data_3, 3);
timeline_3 = clutter_timeline_clone (timeline_1);
clutter_timeline_set_direction (timeline_3, CLUTTER_TIMELINE_BACKWARD);
clutter_timeline_add_marker_at_frame (timeline_3, "foo", 5);
clutter_timeline_add_marker_at_frame (timeline_3, "baz", 8);
clutter_timeline_add_marker_at_frame (timeline_3, "near-end-marker", 1);
clutter_timeline_add_marker_at_frame (timeline_3, "end-marker", 0);
g_signal_connect (timeline_1,
"marker-reached", G_CALLBACK (timeline_marker_reached_cb),
&data_1);
g_signal_connect (timeline_1,
"new-frame", G_CALLBACK (timeline_new_frame_cb),
&data_1);
g_signal_connect (timeline_1,
"completed", G_CALLBACK (timeline_complete_cb),
&data_1);
g_signal_connect (timeline_2,
"marker-reached::bar",
G_CALLBACK (timeline_marker_reached_cb),
&data_2);
g_signal_connect (timeline_2,
"new-frame", G_CALLBACK (timeline_new_frame_cb),
&data_2);
g_signal_connect (timeline_2,
"completed", G_CALLBACK (timeline_complete_cb),
&data_2);
g_signal_connect (timeline_3,
"marker-reached", G_CALLBACK (timeline_marker_reached_cb),
&data_3);
g_signal_connect (timeline_3,
"new-frame", G_CALLBACK (timeline_new_frame_cb),
&data_3);
g_signal_connect (timeline_3,
"completed", G_CALLBACK (timeline_complete_cb),
&data_3);
printf ("Without delay...\n");
clutter_timeline_start (timeline_1);
clutter_timeline_start (timeline_2);
clutter_timeline_start (timeline_3);
clutter_threads_add_timeout (2000, timeout_cb, NULL);
clutter_main ();
if (!check_timeline (timeline_1, &data_1, TRUE))
ret = EXIT_FAILURE;
if (!check_timeline (timeline_2, &data_2, TRUE))
ret = EXIT_FAILURE;
if (!check_timeline (timeline_3, &data_3, TRUE))
ret = EXIT_FAILURE;
printf ("With delay...\n");
timeline_data_destroy (&data_1);
timeline_data_init (&data_1, 1);
timeline_data_destroy (&data_2);
timeline_data_init (&data_2, 2);
timeline_data_destroy (&data_3);
timeline_data_init (&data_3, 3);
clutter_timeline_start (timeline_1);
clutter_timeline_start (timeline_2);
clutter_timeline_start (timeline_3);
clutter_threads_add_timeout (2000, timeout_cb, NULL);
clutter_threads_add_timeout (99, delay_cb, NULL);
clutter_main ();
if (!check_timeline (timeline_1, &data_1, FALSE))
ret = EXIT_FAILURE;
if (!check_timeline (timeline_2, &data_2, FALSE))
ret = EXIT_FAILURE;
if (!check_timeline (timeline_3, &data_3, FALSE))
ret = EXIT_FAILURE;
g_object_unref (timeline_1);
g_object_unref (timeline_2);
g_object_unref (timeline_3);
timeline_data_destroy (&data_1);
timeline_data_destroy (&data_2);
timeline_data_destroy (&data_3);
printf ("Overall result: %s\n", ret == EXIT_SUCCESS ? "PASS" : "FAIL");
return ret;
}

2
tests/tools/Makefile.am Normal file
View File

@ -0,0 +1,2 @@
EXTRA_DIST = README

2
tests/tools/README Normal file
View File

@ -0,0 +1,2 @@
This is a place holder for tools such as gltrace like libraries