mirror of
https://github.com/brl/mutter.git
synced 2024-12-25 12:32:05 +00:00
60e2f8ed5b
It's the conformance test suite: there's no need to namespace the files, just like there's no need to namespace the units. This commit does not change the Cogl tests: they will be moved to Cogl over time, and it's easier to do if we leave them as they are.
339 lines
9.3 KiB
C
339 lines
9.3 KiB
C
#include <clutter/clutter.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "test-conform-common.h"
|
|
|
|
#define TEST_FONT "Sans 10"
|
|
|
|
typedef struct _CallbackData CallbackData;
|
|
|
|
struct _CallbackData
|
|
{
|
|
ClutterActor *stage;
|
|
ClutterActor *label;
|
|
gint offset;
|
|
gboolean test_failed;
|
|
|
|
gint extents_x;
|
|
gint extents_y;
|
|
gint extents_width;
|
|
gint extents_height;
|
|
GSList *run_attributes;
|
|
GSList *default_attributes;
|
|
CallbackData *next;
|
|
};
|
|
|
|
|
|
static gint
|
|
attribute_lookup_func (gconstpointer data,
|
|
gconstpointer user_data)
|
|
{
|
|
AtkAttribute *lookup_attr = (AtkAttribute*) user_data;
|
|
AtkAttribute *at = (AtkAttribute *) data;
|
|
if (!data)
|
|
return -1;
|
|
if (!g_strcmp0 (at->name, lookup_attr->name))
|
|
return g_strcmp0 (at->value, lookup_attr->value);
|
|
return -1;
|
|
}
|
|
|
|
/* check l1 is a sub-set of l2 */
|
|
static gboolean
|
|
compare_lists (GSList* l1, GSList* l2)
|
|
{
|
|
gboolean fail = FALSE;
|
|
|
|
if (l2 && !l1)
|
|
return TRUE;
|
|
|
|
while (l1)
|
|
{
|
|
AtkAttribute *at = (AtkAttribute *) l1->data;
|
|
GSList* result = g_slist_find_custom ((GSList*) l2,
|
|
(gconstpointer) at,
|
|
attribute_lookup_func);
|
|
if (!result)
|
|
{
|
|
fail = TRUE;
|
|
break;
|
|
}
|
|
l1 = g_slist_next (l1);
|
|
}
|
|
|
|
return fail;
|
|
}
|
|
|
|
static void
|
|
dump_attribute_set (AtkAttributeSet *at_set)
|
|
{
|
|
GSList *attrs = (GSList*) at_set;
|
|
|
|
while (attrs) {
|
|
AtkAttribute *at = (AtkAttribute *) attrs->data;
|
|
g_print ("text attribute %s = %s\n", at->name, at->value);
|
|
attrs = g_slist_next (attrs);
|
|
}
|
|
|
|
}
|
|
|
|
static gboolean
|
|
check_result (CallbackData *data)
|
|
{
|
|
gboolean fail = FALSE;
|
|
gchar *text = NULL;
|
|
const gchar *expected_text = NULL;
|
|
AtkObject *object = NULL;
|
|
AtkText *cally_text = NULL;
|
|
gunichar unichar;
|
|
gunichar expected_char;
|
|
gint x, y, width, height;
|
|
gint pos;
|
|
AtkAttributeSet *at_set = NULL;
|
|
GSList *attrs;
|
|
gint start = -1;
|
|
gint end = -1;
|
|
|
|
object = atk_gobject_accessible_for_object (G_OBJECT (data->label));
|
|
cally_text = ATK_TEXT (object);
|
|
|
|
if (!cally_text) {
|
|
g_print("no text\n");
|
|
return TRUE;
|
|
}
|
|
|
|
text = atk_text_get_text (cally_text, 0, -1);
|
|
expected_text = clutter_text_get_text (CLUTTER_TEXT (data->label));
|
|
|
|
if (g_strcmp0 (expected_text, text) != 0)
|
|
{
|
|
if (g_test_verbose ())
|
|
g_print ("text value differs %s vs %s\n", expected_text, text);
|
|
fail = TRUE;
|
|
}
|
|
|
|
unichar = atk_text_get_character_at_offset (cally_text, data->offset);
|
|
expected_char = g_utf8_get_char (g_utf8_offset_to_pointer (text, data->offset));
|
|
if (expected_char != unichar)
|
|
{
|
|
if (g_test_verbose ())
|
|
g_print ("text af offset differs\n");
|
|
fail = TRUE;
|
|
}
|
|
|
|
atk_text_get_character_extents (cally_text, data->offset, &x, &y, &width, &height,
|
|
ATK_XY_WINDOW);
|
|
if (x != data->extents_x)
|
|
{
|
|
if (g_test_verbose ())
|
|
g_print ("extents x position at index 0 differs (current value=%d)\n", x);
|
|
fail = TRUE;
|
|
}
|
|
if (y != data->extents_y)
|
|
{
|
|
if (g_test_verbose ())
|
|
g_print ("extents y position at index 0 differs (current value=%d)\n", y);
|
|
fail = TRUE;
|
|
}
|
|
if (width != data->extents_width)
|
|
{
|
|
if (g_test_verbose ())
|
|
g_print ("extents width at index 0 differs (current value=%d)\n", width);
|
|
fail = TRUE;
|
|
}
|
|
if (height != data->extents_height)
|
|
{
|
|
if (g_test_verbose ())
|
|
g_print ("extents height at index 0 differs (current value=%d)\n", height);
|
|
fail = TRUE;
|
|
}
|
|
|
|
pos = atk_text_get_offset_at_point (cally_text, x, y, ATK_XY_WINDOW);
|
|
if (pos != data->offset)
|
|
{
|
|
if (g_test_verbose ())
|
|
g_print ("offset at position (%d, %d) differs (current value=%d)\n", x,
|
|
y, pos);
|
|
fail = TRUE;
|
|
}
|
|
|
|
at_set = atk_text_get_run_attributes (cally_text, 0,
|
|
&start, &end);
|
|
if (start != 0)
|
|
{
|
|
if (g_test_verbose ())
|
|
g_print ("run attributes start offset is not 0: %d\n", start);
|
|
fail = TRUE;
|
|
}
|
|
if (end != g_utf8_strlen (text, -1))
|
|
{
|
|
if (g_test_verbose ())
|
|
g_print ("run attributes end offset is not text length: %d\n", end);
|
|
fail = TRUE;
|
|
}
|
|
|
|
attrs = (GSList*) at_set;
|
|
fail = compare_lists (attrs, data->run_attributes);
|
|
if (fail && g_test_verbose ())
|
|
{
|
|
g_print ("run attributes mismatch\n");
|
|
dump_attribute_set (attrs);
|
|
}
|
|
|
|
at_set = atk_text_get_default_attributes (cally_text);
|
|
attrs = (GSList*) at_set;
|
|
fail = compare_lists (attrs, data->default_attributes);
|
|
if (fail && g_test_verbose ())
|
|
{
|
|
g_print ("default attributes mismatch\n");
|
|
dump_attribute_set (attrs);
|
|
}
|
|
|
|
g_free (text);
|
|
text = NULL;
|
|
|
|
if (fail)
|
|
{
|
|
if (g_test_verbose ())
|
|
g_print ("FAIL\n");
|
|
data->test_failed = TRUE;
|
|
}
|
|
else if (g_test_verbose ())
|
|
g_print ("pass\n");
|
|
|
|
return fail;
|
|
}
|
|
|
|
static gboolean
|
|
do_tests (CallbackData *data)
|
|
{
|
|
while (data)
|
|
{
|
|
gboolean result = check_result (data);
|
|
g_assert (result == FALSE);
|
|
data = data->next;
|
|
}
|
|
|
|
clutter_main_quit ();
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static GSList*
|
|
build_attribute_set (const gchar* first_attribute, ...)
|
|
{
|
|
AtkAttributeSet *return_set = g_slist_alloc ();
|
|
va_list args;
|
|
const gchar *name;
|
|
const gchar *value;
|
|
gint i = 0;
|
|
|
|
value = first_attribute;
|
|
va_start (args, first_attribute);
|
|
|
|
while (value)
|
|
{
|
|
if ((i> 0) && (i % 2 != 0))
|
|
{
|
|
AtkAttribute *at = g_malloc (sizeof (AtkAttribute));
|
|
at->name = g_strdup (name);
|
|
at->value = g_strdup (value);
|
|
return_set = g_slist_prepend (return_set, at);
|
|
}
|
|
i++;
|
|
name = g_strdup (value);
|
|
value = va_arg (args, gchar*);
|
|
}
|
|
va_end (args);
|
|
return return_set;
|
|
}
|
|
|
|
void
|
|
cally_text (void)
|
|
{
|
|
CallbackData data;
|
|
CallbackData data1;
|
|
GSList* default_attributes = build_attribute_set ("left-margin", "0",
|
|
"right-margin", "0",
|
|
"indent", "0",
|
|
"invisible", "false",
|
|
"editable", "false",
|
|
"pixels-above-lines", "0",
|
|
"pixels-below-lines", "0",
|
|
"pixels-inside-wrap", "0",
|
|
"bg-full-height", "0",
|
|
"bg-stipple", "false",
|
|
"fg-stipple", "false",
|
|
"fg-color", "0,0,0",
|
|
"wrap-mode", "word",
|
|
"justification", "left",
|
|
"size", "10",
|
|
"weight", "400",
|
|
"family-name", "Sans",
|
|
"stretch", "normal",
|
|
"variant", "normal",
|
|
"style", "normal",
|
|
"language", "en-us",
|
|
"direction", "ltr",
|
|
NULL);
|
|
|
|
memset (&data, 0, sizeof (data));
|
|
|
|
data.stage = clutter_stage_new ();
|
|
|
|
data.default_attributes = default_attributes;
|
|
data.run_attributes = build_attribute_set ("fg-color", "0,0,0", NULL);
|
|
|
|
data.label = clutter_text_new_with_text (TEST_FONT, "Lorem ipsum dolor sit amet");
|
|
|
|
clutter_container_add (CLUTTER_CONTAINER (data.stage), data.label, NULL);
|
|
data.offset = 6;
|
|
data.extents_x = 64;
|
|
data.extents_y = 99;
|
|
data.extents_width = 3;
|
|
data.extents_height = 17;
|
|
clutter_actor_set_position (data.label, 20, 100);
|
|
|
|
memset (&data1, 0, sizeof (data1));
|
|
data1.stage = data.stage;
|
|
data1.default_attributes = default_attributes;
|
|
data1.run_attributes = build_attribute_set ("bg-color", "0,65535,0",
|
|
"fg-color", "65535,65535,0",
|
|
"strikethrough", "true", NULL);
|
|
|
|
data1.label = clutter_text_new_with_text (TEST_FONT, "");
|
|
clutter_text_set_markup (CLUTTER_TEXT(data1.label), "<span fgcolor=\"#FFFF00\" bgcolor=\"#00FF00\"><s>Lorem ipsum dolor sit amet</s></span>");
|
|
|
|
clutter_container_add (CLUTTER_CONTAINER (data1.stage), data1.label, NULL);
|
|
data1.offset = 10;
|
|
data1.extents_x = 90;
|
|
data1.extents_y = 199;
|
|
data1.extents_width = 13;
|
|
data1.extents_height = 17;
|
|
clutter_actor_set_position (data1.label, 20, 200);
|
|
data.next = &data1;
|
|
|
|
clutter_actor_show (data.stage);
|
|
clutter_threads_add_idle ((GSourceFunc) do_tests, &data);
|
|
clutter_main ();
|
|
|
|
clutter_actor_destroy (data.stage);
|
|
|
|
if (g_test_verbose ())
|
|
g_print ("\nOverall result: ");
|
|
|
|
if (g_test_verbose ())
|
|
{
|
|
if (data.test_failed)
|
|
g_print ("FAIL\n");
|
|
else
|
|
g_print ("pass\n");
|
|
}
|
|
else
|
|
{
|
|
g_assert (data.test_failed != TRUE);
|
|
g_assert (data1.test_failed != TRUE);
|
|
}
|
|
}
|
|
|