1 /* GStreamer
2  *
3  * unit tests for the navigation interface library
4  *
5  * Copyright (C) 2009 Jan Schmidt <thaytan@noraisin.net>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26 
27 #include <gst/check/gstcheck.h>
28 
29 #include <gst/video/navigation.h>
30 
31 #include <string.h>
32 
33 #define TEST_ELEMENT_TYPE (test_element_get_type())
34 
35 typedef struct TestElement TestElement;
36 typedef struct TestElementClass TestElementClass;
37 
38 struct TestElement
39 {
40   GstElement parent;
41 
42   GstNavigationEventType sent_type;
43   const gchar *sent_key;
44   gdouble sent_x, sent_y;
45   gint sent_button;
46   GstNavigationCommand sent_command;
47 };
48 
49 struct TestElementClass
50 {
51   GstElementClass parent_class;
52 };
53 
54 GType test_element_get_type (void);
55 
56 static void init_interface (GType type);
57 static void nav_send_event (GstNavigation * navigation,
58     GstStructure * structure);
59 
60 G_DEFINE_TYPE_WITH_CODE (TestElement, test_element, GST_TYPE_ELEMENT,
61     init_interface (g_define_type_id));
62 
63 static void
test_element_navigation_interface_init(GstNavigationInterface * iface)64 test_element_navigation_interface_init (GstNavigationInterface * iface)
65 {
66   iface->send_event = nav_send_event;
67 }
68 
69 static void
init_interface(GType type)70 init_interface (GType type)
71 {
72   static const GInterfaceInfo navigation_iface_info = {
73     (GInterfaceInitFunc) test_element_navigation_interface_init,
74     NULL,
75     NULL,
76   };
77 
78   g_type_add_interface_static (type, GST_TYPE_NAVIGATION,
79       &navigation_iface_info);
80 }
81 
82 static void
test_element_class_init(TestElementClass * klass)83 test_element_class_init (TestElementClass * klass)
84 {
85 }
86 
87 static void
test_element_init(TestElement * this)88 test_element_init (TestElement * this)
89 {
90 }
91 
92 static void
nav_send_event(GstNavigation * navigation,GstStructure * structure)93 nav_send_event (GstNavigation * navigation, GstStructure * structure)
94 {
95   GstEvent *event = gst_event_new_navigation (structure);
96   GstNavigationEventType etype = gst_navigation_event_get_type (event);
97   TestElement *self = (TestElement *) (navigation);
98 
99   fail_if (etype == GST_NAVIGATION_EVENT_INVALID,
100       "Received navigation event could not be parsed");
101   fail_unless (etype == self->sent_type,
102       "Received navigation event did not match sent");
103 
104   switch (etype) {
105     case GST_NAVIGATION_EVENT_KEY_PRESS:
106     case GST_NAVIGATION_EVENT_KEY_RELEASE:{
107       const gchar *key;
108       fail_unless (gst_navigation_event_parse_key_event (event, &key));
109       fail_unless (strcmp (key, self->sent_key) == 0);
110       break;
111     }
112     case GST_NAVIGATION_EVENT_MOUSE_BUTTON_PRESS:
113     case GST_NAVIGATION_EVENT_MOUSE_BUTTON_RELEASE:{
114       gint button;
115       gdouble x, y;
116       fail_unless (gst_navigation_event_parse_mouse_button_event (event,
117               &button, &x, &y));
118       fail_unless (button == self->sent_button);
119       fail_unless (x == self->sent_x);
120       fail_unless (y == self->sent_y);
121       break;
122     }
123     case GST_NAVIGATION_EVENT_MOUSE_MOVE:{
124       gdouble x, y;
125       fail_unless (gst_navigation_event_parse_mouse_move_event (event, &x, &y));
126       fail_unless (x == self->sent_x);
127       fail_unless (y == self->sent_y);
128       break;
129     }
130     case GST_NAVIGATION_EVENT_COMMAND:{
131       GstNavigationCommand cmd;
132       fail_unless (gst_navigation_event_parse_command (event, &cmd));
133       fail_unless (cmd == self->sent_command);
134     }
135     default:
136       break;
137   }
138 
139   gst_event_unref (event);
140 }
141 
GST_START_TEST(test_events)142 GST_START_TEST (test_events)
143 {
144   /* Create an empty GstElement that has a GstNavigation interface and then
145    * send some navigation events and validate them */
146   TestElement *test_element =
147       (TestElement *) g_object_new (TEST_ELEMENT_TYPE, NULL);
148   GstNavigationCommand cmds[] = {
149     GST_NAVIGATION_COMMAND_MENU1, GST_NAVIGATION_COMMAND_MENU2,
150     GST_NAVIGATION_COMMAND_MENU3, GST_NAVIGATION_COMMAND_MENU4,
151     GST_NAVIGATION_COMMAND_MENU5, GST_NAVIGATION_COMMAND_MENU6,
152     GST_NAVIGATION_COMMAND_MENU7, GST_NAVIGATION_COMMAND_LEFT,
153     GST_NAVIGATION_COMMAND_RIGHT, GST_NAVIGATION_COMMAND_UP,
154     GST_NAVIGATION_COMMAND_DOWN, GST_NAVIGATION_COMMAND_ACTIVATE,
155     GST_NAVIGATION_COMMAND_PREV_ANGLE, GST_NAVIGATION_COMMAND_NEXT_ANGLE
156   };
157   gint i;
158 
159   test_element->sent_type = GST_NAVIGATION_EVENT_KEY_PRESS;
160   test_element->sent_key = "1";
161   gst_navigation_send_key_event (GST_NAVIGATION (test_element), "key-press",
162       "1");
163 
164   test_element->sent_type = GST_NAVIGATION_EVENT_KEY_RELEASE;
165   test_element->sent_key = "2";
166   gst_navigation_send_key_event (GST_NAVIGATION (test_element), "key-release",
167       "2");
168 
169   test_element->sent_type = GST_NAVIGATION_EVENT_MOUSE_MOVE;
170   test_element->sent_x = 50;
171   test_element->sent_y = 100;
172   gst_navigation_send_mouse_event (GST_NAVIGATION (test_element), "mouse-move",
173       0, 50, 100);
174 
175   test_element->sent_type = GST_NAVIGATION_EVENT_MOUSE_BUTTON_PRESS;
176   test_element->sent_x = 10;
177   test_element->sent_y = 20;
178   test_element->sent_button = 1;
179   gst_navigation_send_mouse_event (GST_NAVIGATION (test_element),
180       "mouse-button-press", 1, 10, 20);
181 
182   for (i = 0; i < G_N_ELEMENTS (cmds); i++) {
183     test_element->sent_type = GST_NAVIGATION_EVENT_COMMAND;
184     test_element->sent_command = cmds[i];
185     gst_navigation_send_command (GST_NAVIGATION (test_element), cmds[i]);
186   }
187 
188   gst_object_unref (test_element);
189 }
190 
191 GST_END_TEST;
192 
GST_START_TEST(test_messages)193 GST_START_TEST (test_messages)
194 {
195   GstMessage *m;
196   /* GST_NAVIGATION_MESSAGE_MOUSE_OVER */
197   {
198     gboolean active;
199     m = gst_navigation_message_new_mouse_over (NULL, TRUE);
200     fail_if (m == NULL);
201     fail_unless (gst_navigation_message_get_type (m) ==
202         GST_NAVIGATION_MESSAGE_MOUSE_OVER);
203     fail_unless (GST_MESSAGE_SRC (m) == NULL);
204     fail_unless (gst_navigation_message_parse_mouse_over (m, &active));
205     fail_unless (active == TRUE);
206     gst_message_unref (m);
207 
208     m = gst_navigation_message_new_mouse_over (NULL, FALSE);
209     fail_if (m == NULL);
210     fail_unless (GST_MESSAGE_SRC (m) == NULL);
211     fail_unless (gst_navigation_message_get_type (m) ==
212         GST_NAVIGATION_MESSAGE_MOUSE_OVER);
213     fail_unless (gst_navigation_message_parse_mouse_over (m, &active));
214     fail_unless (active == FALSE);
215     gst_message_unref (m);
216   }
217 
218   /* GST_NAVIGATION_MESSAGE_COMMANDS_CHANGED */
219   {
220     m = gst_navigation_message_new_commands_changed (NULL);
221     fail_if (m == NULL);
222     fail_unless (GST_MESSAGE_SRC (m) == NULL);
223     fail_unless (gst_navigation_message_get_type (m) ==
224         GST_NAVIGATION_MESSAGE_COMMANDS_CHANGED);
225     gst_message_unref (m);
226   }
227 
228   /* GST_NAVIGATION_MESSAGE_ANGLES_CHANGED */
229   {
230     guint angle, angles;
231     m = gst_navigation_message_new_angles_changed (NULL, 1, 5);
232     fail_if (m == NULL);
233     fail_unless (GST_MESSAGE_SRC (m) == NULL);
234     fail_unless (gst_navigation_message_get_type (m) ==
235         GST_NAVIGATION_MESSAGE_ANGLES_CHANGED);
236     fail_unless (gst_navigation_message_parse_angles_changed (m, &angle,
237             &angles));
238     fail_unless (angle == 1);
239     fail_unless (angles == 5);
240     gst_message_unref (m);
241   }
242 }
243 
244 GST_END_TEST;
245 
GST_START_TEST(test_queries)246 GST_START_TEST (test_queries)
247 {
248   GstQuery *q;
249 
250   /* GST_NAVIGATION_QUERY_COMMANDS */
251   {
252     guint n;
253     GstNavigationCommand cmd;
254 
255     q = gst_navigation_query_new_commands ();
256     fail_unless (q != NULL);
257     fail_unless (gst_navigation_query_get_type (q) ==
258         GST_NAVIGATION_QUERY_COMMANDS);
259     gst_navigation_query_set_commands (q, 3, GST_NAVIGATION_COMMAND_LEFT,
260         GST_NAVIGATION_COMMAND_MENU1, GST_NAVIGATION_COMMAND_MENU5);
261     fail_unless (gst_navigation_query_parse_commands_length (q, &n));
262     fail_unless (n == 3);
263     fail_unless (gst_navigation_query_parse_commands_nth (q, 1, &cmd));
264     fail_unless (cmd == GST_NAVIGATION_COMMAND_MENU1);
265 
266     fail_unless (gst_navigation_query_parse_commands_length (q, NULL));
267     fail_unless (gst_navigation_query_parse_commands_nth (q, 2, NULL));
268 
269     gst_query_unref (q);
270   }
271 
272   /* GST_NAVIGATION_QUERY_ANGLES */
273   {
274     guint angle, angles;
275     q = gst_navigation_query_new_angles ();
276     fail_unless (q != NULL);
277     fail_unless (gst_navigation_query_get_type (q) ==
278         GST_NAVIGATION_QUERY_ANGLES);
279     gst_navigation_query_set_angles (q, 4, 8);
280     fail_unless (gst_navigation_query_parse_angles (q, &angle, &angles));
281     fail_unless (angle == 4);
282     fail_unless (angles == 8);
283 
284     fail_unless (gst_navigation_query_parse_angles (q, NULL, &angles));
285     fail_unless (gst_navigation_query_parse_angles (q, &angle, NULL));
286     fail_unless (gst_navigation_query_parse_angles (q, NULL, NULL));
287 
288     gst_query_unref (q);
289   }
290 
291 }
292 
293 GST_END_TEST;
294 
295 static Suite *
navigation_suite(void)296 navigation_suite (void)
297 {
298   Suite *s = suite_create ("navigation interface");
299   TCase *tc_chain = tcase_create ("notifications");
300 
301   suite_add_tcase (s, tc_chain);
302   tcase_add_test (tc_chain, test_events);
303   tcase_add_test (tc_chain, test_messages);
304   tcase_add_test (tc_chain, test_queries);
305 
306   return s;
307 }
308 
309 GST_CHECK_MAIN (navigation);
310