4 test_parse_empty (void)
6 GtkCssProvider *provider;
10 provider = gtk_css_provider_new ();
12 res = gtk_css_provider_load_from_data (provider, "", -1, &error);
15 g_assert_no_error (error);
16 g_clear_error (&error);
18 g_object_unref (provider);
24 GtkCssProvider *provider;
28 const gchar *valid[] = {
29 "@import \"" SRCDIR "/test.css\";",
30 "@import '" SRCDIR "/test.css';",
31 "@import url(\"" SRCDIR "/test.css\");",
32 "@import url('" SRCDIR "/test.css');",
33 "@import\nurl (\t\"" SRCDIR "/test.css\" ) ;",
34 "@define-color bg_color #f9a039;",
35 "@define-color color @bg_color;",
36 "@define-color color rgb(100, 99, 88);",
37 "@define-color color rgba(50%, 50%, 50%, 0.5);",
38 "@define-color color lighter(#f9a039);",
39 "@define-color color darker ( @blue ) ;",
40 "@define-color color shade(@blue, 1.3);",
41 "@define-color color alpha(@blue, 1.3);",
42 "@define-color color mix(@blue, @red, 0.2);",
43 "@define-color color red;",
44 "@define-color color mix(shade (#121212, 0.5), mix (rgb(10%,20%,100%), @blue,0.5), 0.2);",
45 "@define-color blue @blue;",
46 "@define-color blue123_a-b #123;",
47 "@binding-set gtk-emacs-menu { bind \"<ctrl>n\" { \"move-current\" (next) }; };",
48 "@binding-set gtk-emacs-text-view {\n"
49 " bind \"<ctrl>u\" { \"move-cursor\" (paragraph-ends, -1, 0)\n"
50 " \"delete-from-cursor\" (paragraph-ends, 1) };\n"
52 "@binding-set test {\n"
53 " bind \"<ctrl>space\" { \"set-anchor\" () };\n"
54 " unbind \"<ctrl>v\";\n"
59 const gchar *invalid[] = {
60 "@import " SRCDIR "/test.css ;",
61 "@import url ( \"" SRCDIR "/test.css\" xyz );",
64 "@import url(\"abc');",
66 "@define_color blue red;",
67 "@define-color blue #12234;",
68 "@define-color blue #12g234;",
69 "@define-color blue @@;",
70 "@define-color blue 5!#%4@DG$##x;",
71 "@define-color color mix(@red, @blue, @green);",
72 "@define-color color mix(@blue, 0.2, @red);",
73 "@define-color color mix(0.2, @blue, @red);",
74 "@define-color color mix(@blue, @red);",
75 "@define-color color mix(@blue);",
76 "@define-color color mix();",
77 "@define-color color rgba(50%, 50%, 50%);",
78 "@define-color color rgb(50%, a);",
79 "@define-color 1col rgb(50%, a);",
80 "@three-dee { some other crap };",
81 "@binding-set \"foo\";",
82 "@binding-set foo { bind key { \"action\"() }; };",
83 "@binding-set foo { bind key { \"action\"() }; };",
84 "@binding-set foo { bind \"key\" { action() }; };",
85 "@binding-set foo { bind \"key\"; };",
86 "@binding-set foo { unbind \"key\" { \"bla\" () }; };",
91 for (i = 0; valid[i]; i++)
93 provider = gtk_css_provider_new ();
94 res = gtk_css_provider_load_from_data (provider, valid[i], -1, &error);
96 g_print ("parsing '%s': got unexpected error: %s\n", valid[i], error->message);
97 g_assert_no_error (error);
100 g_object_unref (provider);
103 for (i = 0; invalid[i]; i++)
105 provider = gtk_css_provider_new ();
106 res = gtk_css_provider_load_from_data (provider, invalid[i], -1, &error);
107 g_assert_error (error, GTK_CSS_PROVIDER_ERROR, GTK_CSS_PROVIDER_ERROR_FAILED);
109 g_object_unref (provider);
110 g_clear_error (&error);
115 test_parse_selectors (void)
117 GtkCssProvider *provider;
121 const gchar *valid[] = {
128 "tab:first-child {}",
130 "tab:nth-child(first) {}",
131 "tab:nth-child(last) {}",
132 "tab:nth-child(even) {}",
133 "tab:nth-child(odd) {}",
136 ".some-class.another-class {}",
137 ".some-class .another-class {}",
149 "E:active:prelight {}",
150 "* > .notebook tab:first-child .label:focused {}",
152 "E, F /* comment here */ {}",
153 "E,/* comment here */ F {}",
158 const gchar *invalid[] = {
159 /* nth-child and similar pseudo classes can only
160 * be used with regions, not with types
164 "E:nth-child(first) {}",
165 "E:nth-child(last) {}",
166 "E:nth-child(even) {}",
167 "E:nth-child(odd) {}",
169 /* widget state pseudo-classes can only be used for
177 for (i = 0; valid[i]; i++)
179 provider = gtk_css_provider_new ();
180 res = gtk_css_provider_load_from_data (provider, valid[i], -1, &error);
182 g_print ("parsing '%s': got unexpected error: %s\n", valid[i], error->message);
183 g_assert_no_error (error);
186 g_object_unref (provider);
189 for (i = 0; invalid[i]; i++)
191 provider = gtk_css_provider_new ();
192 res = gtk_css_provider_load_from_data (provider, invalid[i], -1, &error);
193 g_assert_error (error, GTK_CSS_PROVIDER_ERROR, GTK_CSS_PROVIDER_ERROR_FAILED);
195 g_object_unref (provider);
196 g_clear_error (&error);
201 test_parse_declarations (void)
203 GtkCssProvider *provider;
207 const gchar *valid[] = {
209 "* { font: Sans 15 }",
210 "* { font: Sans 15; }",
213 "* { /* just a comment */ }",
214 "* { /* multi\nline\ncomment */ }",
215 "* { font: /* comment here */ Sans 15 }",
216 "* { color: red; background-color: shade (@bg_color, 0.5) }",
218 "* { margin: 5 10 }",
219 "* { margin: 5 10 3 }",
220 "* { margin: 5 10 3 5 }",
222 "* { padding: 5 10 }",
223 "* { border-width: 5; border-radius: 10 }",
224 "* { border-color: #ff00ff }",
225 "* { engine: clearlooks }",
226 "* { background-image: -gtk-gradient (linear, \n"
227 " left top, right top, \n"
228 " from (#fff), to (#000)) }",
229 "* { background-image: -gtk-gradient (linear, \n"
230 " 0.0 0.5, 0.5 1.0, \n"
232 " color-stop (0.5, #f00),\n"
234 "* { background-image: -gtk-gradient (radial, \n"
235 " center center, 0.2, \n"
236 " center center, 0.8, \n"
237 " color-stop (0.0,#fff),\n"
238 " color-stop (1.0,#000))}\n",
239 "* { border-image: url (\"" SRCDIR "/test.png\") 3 4 3 4 stretch }",
240 "* { border-image: url (\"" SRCDIR "/test.png\") 3 4 3 4 repeat stretch}",
241 "* { transition: 150ms ease-in-out }",
242 "* { transition: 1s linear loop }",
246 const gchar *invalid[] = {
248 "* { color:green; color }",
249 "* { color:red; color; color:green }",
250 "* { color:green; color: }",
251 "* { color:red; color:; color:green }",
252 "* { color:green; color{;color:maroon} }",
253 "* { color:red; color{;color:maroon}; color:green }",
254 "* { content: 'Hello",
259 for (i = 0; valid[i]; i++)
261 provider = gtk_css_provider_new ();
262 res = gtk_css_provider_load_from_data (provider, valid[i], -1, &error);
264 g_print ("parsing '%s': got unexpected error: %s\n", valid[i], error->message);
265 g_assert_no_error (error);
268 g_object_unref (provider);
271 for (i = 0; invalid[i]; i++)
273 provider = gtk_css_provider_new ();
274 res = gtk_css_provider_load_from_data (provider, invalid[i], -1, &error);
275 g_assert_error (error, GTK_CSS_PROVIDER_ERROR, GTK_CSS_PROVIDER_ERROR_FAILED);
277 g_object_unref (provider);
278 g_clear_error (&error);
286 GtkWidgetPath *path2;
288 GtkRegionFlags flags;
290 path = gtk_widget_path_new ();
291 g_assert_cmpint (gtk_widget_path_length (path), ==, 0);
293 pos = gtk_widget_path_append_type (path, GTK_TYPE_WINDOW);
294 g_assert_cmpint (pos, ==, 0);
295 g_assert_cmpint (gtk_widget_path_length (path), ==, 1);
296 g_assert (gtk_widget_path_iter_get_object_type (path, 0) == GTK_TYPE_WINDOW);
297 g_assert (gtk_widget_path_is_type (path, GTK_TYPE_WIDGET));
298 g_assert (gtk_widget_path_iter_get_name (path, 0) == NULL);
300 pos = gtk_widget_path_append_type (path, GTK_TYPE_WIDGET);
301 g_assert_cmpint (pos, ==, 1);
302 g_assert_cmpint (gtk_widget_path_length (path), ==, 2);
303 gtk_widget_path_iter_set_object_type (path, pos, GTK_TYPE_BUTTON);
304 g_assert (gtk_widget_path_is_type (path, GTK_TYPE_BUTTON));
305 g_assert (gtk_widget_path_has_parent (path, GTK_TYPE_WIDGET));
306 g_assert (gtk_widget_path_has_parent (path, GTK_TYPE_WINDOW));
307 g_assert (!gtk_widget_path_has_parent (path, GTK_TYPE_DIALOG));
308 g_assert (gtk_widget_path_iter_get_name (path, 1) == NULL);
310 gtk_widget_path_iter_set_name (path, 1, "name");
311 g_assert (gtk_widget_path_iter_has_name (path, 1, "name"));
313 gtk_widget_path_iter_add_class (path, 1, "class1");
314 gtk_widget_path_iter_add_class (path, 1, "class2");
315 g_assert (gtk_widget_path_iter_has_class (path, 1, "class1"));
316 g_assert (gtk_widget_path_iter_has_class (path, 1, "class2"));
317 g_assert (!gtk_widget_path_iter_has_class (path, 1, "class3"));
319 path2 = gtk_widget_path_copy (path);
320 g_assert (gtk_widget_path_iter_has_class (path2, 1, "class1"));
321 g_assert (gtk_widget_path_iter_has_class (path2, 1, "class2"));
322 g_assert (!gtk_widget_path_iter_has_class (path2, 1, "class3"));
323 gtk_widget_path_free (path2);
325 gtk_widget_path_iter_remove_class (path, 1, "class2");
326 g_assert (gtk_widget_path_iter_has_class (path, 1, "class1"));
327 g_assert (!gtk_widget_path_iter_has_class (path, 1, "class2"));
328 gtk_widget_path_iter_clear_classes (path, 1);
329 g_assert (!gtk_widget_path_iter_has_class (path, 1, "class1"));
331 gtk_widget_path_iter_add_region (path, 1, "tab", 0);
332 gtk_widget_path_iter_add_region (path, 1, "title", GTK_REGION_EVEN | GTK_REGION_FIRST);
334 g_assert (gtk_widget_path_iter_has_region (path, 1, "tab", &flags) &&
336 g_assert (gtk_widget_path_iter_has_region (path, 1, "title", &flags) &&
337 flags == (GTK_REGION_EVEN | GTK_REGION_FIRST));
338 g_assert (!gtk_widget_path_iter_has_region (path, 1, "extension", NULL));
340 path2 = gtk_widget_path_copy (path);
341 g_assert (gtk_widget_path_iter_has_region (path2, 1, "tab", &flags) &&
343 g_assert (gtk_widget_path_iter_has_region (path2, 1, "title", &flags) &&
344 flags == (GTK_REGION_EVEN | GTK_REGION_FIRST));
345 g_assert (!gtk_widget_path_iter_has_region (path2, 1, "extension", NULL));
346 gtk_widget_path_free (path2);
348 gtk_widget_path_free (path);
354 GtkStyleContext *context;
356 GtkCssProvider *provider;
363 provider = gtk_css_provider_new ();
365 gdk_rgba_parse (&expected, "#fff");
367 context = gtk_style_context_new ();
369 path = gtk_widget_path_new ();
370 gtk_widget_path_append_type (path, GTK_TYPE_WINDOW);
371 gtk_widget_path_append_type (path, GTK_TYPE_BOX);
372 gtk_widget_path_append_type (path, GTK_TYPE_BUTTON);
373 gtk_widget_path_iter_set_name (path, 0, "mywindow");
374 gtk_widget_path_iter_add_class (path, 2, "button");
375 gtk_style_context_set_path (context, path);
376 gtk_widget_path_free (path);
378 gtk_style_context_add_provider (context,
379 GTK_STYLE_PROVIDER (provider),
380 GTK_STYLE_PROVIDER_PRIORITY_USER);
382 data = "* { color: #fff }";
383 gtk_css_provider_load_from_data (provider, data, -1, &error);
384 g_assert_no_error (error);
385 gtk_style_context_invalidate (context);
386 gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
387 g_assert (gdk_rgba_equal (&color, &expected));
389 data = "* { color: #f00 }\n"
390 "GtkButton { color: #fff }";
391 gtk_css_provider_load_from_data (provider, data, -1, &error);
392 g_assert_no_error (error);
393 gtk_style_context_invalidate (context);
394 gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
395 g_assert (gdk_rgba_equal (&color, &expected));
397 data = "* { color: #f00 }\n"
398 "GtkButton { color: #fff }\n"
399 "GtkWindow > GtkButton { color: #000 }";
400 gtk_css_provider_load_from_data (provider, data, -1, &error);
401 g_assert_no_error (error);
402 gtk_style_context_invalidate (context);
403 gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
404 g_assert (gdk_rgba_equal (&color, &expected));
406 data = "* { color: #f00 }\n"
407 ".button { color: #fff }";
408 gtk_css_provider_load_from_data (provider, data, -1, &error);
409 g_assert_no_error (error);
410 gtk_style_context_invalidate (context);
411 gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
412 g_assert (gdk_rgba_equal (&color, &expected));
414 data = "* { color: #f00 }\n"
415 "GtkButton { color: #000 }\n"
416 ".button { color: #fff }";
417 gtk_css_provider_load_from_data (provider, data, -1, &error);
418 g_assert_no_error (error);
419 gtk_style_context_invalidate (context);
420 gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
421 g_assert (gdk_rgba_equal (&color, &expected));
423 data = "* { color: #f00 }\n"
424 "GtkButton { color: #000 }\n"
425 "GtkWindow GtkButton { color: #fff }";
426 gtk_css_provider_load_from_data (provider, data, -1, &error);
427 g_assert_no_error (error);
428 gtk_style_context_invalidate (context);
429 gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
430 g_assert (gdk_rgba_equal (&color, &expected));
432 data = "* { color: #f00 }\n"
433 ".button { color: #000 }\n"
434 "GtkWindow .button { color: #fff }";
435 gtk_css_provider_load_from_data (provider, data, -1, &error);
436 g_assert_no_error (error);
437 gtk_style_context_invalidate (context);
438 gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
439 g_assert (gdk_rgba_equal (&color, &expected));
441 data = "* { color: #f00 }\n"
442 "* .button { color: #000 }\n"
443 "#mywindow .button { color: #fff }";
444 gtk_css_provider_load_from_data (provider, data, -1, &error);
445 g_assert_no_error (error);
446 gtk_style_context_invalidate (context);
447 gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
448 g_assert (gdk_rgba_equal (&color, &expected));
450 data = "* { color: #f00 }\n"
451 "GtkWindow .button { color: #000 }\n"
452 "GtkWindow#mywindow .button { color: #fff }";
453 gtk_css_provider_load_from_data (provider, data, -1, &error);
454 g_assert_no_error (error);
455 gtk_style_context_invalidate (context);
456 gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
457 g_assert (gdk_rgba_equal (&color, &expected));
459 data = "* { color: #f00 }\n"
460 "GtkWindow .button { color: #fff }\n"
461 "GObject .button { color: #000 }";
462 gtk_css_provider_load_from_data (provider, data, -1, &error);
463 g_assert_no_error (error);
464 gtk_style_context_invalidate (context);
465 gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
466 g_assert (gdk_rgba_equal (&color, &expected));
468 g_object_unref (provider);
469 g_object_unref (context);
473 test_style_property (void)
475 GtkStyleContext *context;
477 GtkCssProvider *provider;
485 provider = gtk_css_provider_new ();
487 context = gtk_style_context_new ();
489 path = gtk_widget_path_new ();
490 gtk_widget_path_append_type (path, GTK_TYPE_WINDOW);
491 gtk_widget_path_append_type (path, GTK_TYPE_BOX);
492 gtk_widget_path_append_type (path, GTK_TYPE_BUTTON);
493 gtk_style_context_set_path (context, path);
494 gtk_widget_path_free (path);
495 gtk_style_context_set_state (context, GTK_STATE_FLAG_PRELIGHT);
497 /* Since we set the prelight state on the context, we expect
498 * only the third selector to match, even though the second one
499 * has higher specificity, and the fourth one comes later.
501 * In particular, we want to verify that widget style properties and
502 * CSS properties follow the same matching rules, ie we expect
503 * color to be #003 and child-displacement-x to be 3.
505 data = "GtkButton:insensitive { color: #001; -GtkButton-child-displacement-x: 1 }\n"
506 "GtkBox GtkButton:selected { color: #002; -GtkButton-child-displacement-x: 2 }\n"
507 "GtkButton:prelight { color: #003; -GtkButton-child-displacement-x: 3 }\n"
508 "GtkButton:focused { color: #004; -GtkButton-child-displacement-x: 4 }\n";
509 gtk_css_provider_load_from_data (provider, data, -1, &error);
510 g_assert_no_error (error);
511 gtk_style_context_add_provider (context,
512 GTK_STYLE_PROVIDER (provider),
513 GTK_STYLE_PROVIDER_PRIORITY_USER);
515 gtk_style_context_invalidate (context);
517 gtk_style_context_get_color (context, GTK_STATE_FLAG_PRELIGHT, &color);
518 gdk_rgba_parse (&expected, "#003");
519 g_assert (gdk_rgba_equal (&color, &expected));
521 gtk_style_context_get_style (context, "child-displacement-x", &x, NULL);
523 g_assert_cmpint (x, ==, 3);
525 g_object_unref (provider);
526 g_object_unref (context);
530 test_basic_properties (void)
532 GtkStyleContext *context;
536 PangoFontDescription *font;
538 context = gtk_style_context_new ();
539 path = gtk_widget_path_new ();
540 gtk_style_context_set_path (context, path);
541 gtk_widget_path_free (path);
543 gtk_style_context_get (context, 0,
545 "background-color", &bg_color,
548 g_assert (color != NULL);
549 g_assert (bg_color != NULL);
550 g_assert (font != NULL);
552 gdk_rgba_free (color);
553 gdk_rgba_free (bg_color);
554 pango_font_description_free (font);
556 g_object_unref (context);
560 main (int argc, char *argv[])
562 gtk_init (NULL, NULL);
563 g_test_init (&argc, &argv, NULL);
565 g_test_add_func ("/style/parse/empty", test_parse_empty);
566 g_test_add_func ("/style/parse/at", test_parse_at);
567 g_test_add_func ("/style/parse/selectors", test_parse_selectors);
568 g_test_add_func ("/style/parse/declarations", test_parse_declarations);
569 g_test_add_func ("/style/path", test_path);
570 g_test_add_func ("/style/match", test_match);
571 g_test_add_func ("/style/style-property", test_style_property);
572 g_test_add_func ("/style/basic", test_basic_properties);
574 return g_test_run ();