Merge lp:~macslow/notify-osd/abstract-notification-object into lp:notify-osd/trunk

Proposed by Mirco Müller
Status: Merged
Approved by: Mirco Müller
Approved revision: 357
Merged at revision: not available
Proposed branch: lp:~macslow/notify-osd/abstract-notification-object
Merge into: lp:notify-osd/trunk
Diff against target: None lines
To merge this branch: bzr merge lp:~macslow/notify-osd/abstract-notification-object
Reviewer Review Type Date Requested Status
Mirco Müller (community) Approve
Review via email: mp+9194@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Mirco Müller (macslow) wrote :

Please review this abstract notification object meant for further refactoring notify-osd, separating this info out of bubble and stack thus avoiding redundancy and data-inconsistency.

357. By Mirco Müller

added handling and storing of urgency-level to abstract notification object

Revision history for this message
Aurélien Gâteau (agateau) wrote :

Le jeudi 23 juillet 2009 16:20:21, Mirco Müller a écrit :
> Mirco Müller has proposed merging
> lp:~macslow/notify-osd/abstract-notification-object into lp:notify-osd.
>
> Requested reviews:
> Notify OSD Developers (notify-osd-developers)
>
> Please review this abstract notification object meant for further
> refactoring notify-osd, separating this info out of bubble and stack thus
> avoiding redundancy and data-inconsistency.

Looks good, but I would have done the sanity checks in a more aggressive way:
If you call notification_get_id(NULL), I think it's a better to assert and
exit. While it feels like a good idea to avoid exiting, chances are high the
caller code will look like this:

  int id = notification_get_id(n);
  do_something(id);

And you may end up with do_something() behaving strangely because id is -1 and
you forgot to check its value.

If you turn your sanity checks into assert(), notification_get_id() will
crash, bringing you closer to the root of the problem.

If you feel asserting is too strong, then at least use the g_return_if_fail()
and g_return_val_if_fail() macros, which will output something to stderr when
returning (and make code more compact :)).

Aurelien

Revision history for this message
Mirco Müller (macslow) wrote :

> Le jeudi 23 juillet 2009 16:20:21, Mirco Müller a écrit :
> > Mirco Müller has proposed merging
> > lp:~macslow/notify-osd/abstract-notification-object into lp:notify-osd.
> >
> > Requested reviews:
> > Notify OSD Developers (notify-osd-developers)
> >
> > Please review this abstract notification object meant for further
> > refactoring notify-osd, separating this info out of bubble and stack thus
> > avoiding redundancy and data-inconsistency.
>
> Looks good, but I would have done the sanity checks in a more aggressive way:
> ...

I agree being stricter there makes sense. It's calls meant to be used only internally of notify-osd anyway, so catching flaws early on and as close to the root of the problem as possible is something I want to enforce.

I'll make the sanity-checks g_assert()s and merge it to trunk.

Revision history for this message
Mirco Müller (macslow) wrote :

Ok, seems good.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/Makefile.am'
2--- src/Makefile.am 2009-07-22 14:00:39 +0000
3+++ src/Makefile.am 2009-07-23 12:04:41 +0000
4@@ -17,6 +17,7 @@
5 notify_osd_sources = \
6 bubble.c \
7 defaults.c \
8+ notification.c \
9 main.c \
10 observer.c \
11 stack.c \
12@@ -44,6 +45,7 @@
13 notify_osd_headers = \
14 bubble.h \
15 defaults.h \
16+ notification.h \
17 observer.h \
18 stack.h \
19 stack-glue.h \
20
21=== added file 'src/notification.c'
22--- src/notification.c 1970-01-01 00:00:00 +0000
23+++ src/notification.c 2009-07-23 14:09:08 +0000
24@@ -0,0 +1,443 @@
25+////////////////////////////////////////////////////////////////////////////////
26+//3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
27+// 10 20 30 40 50 60 70 80
28+//
29+// notify-osd
30+//
31+// notification.c - notification object storing attributes like title- and body-
32+// text, value, icon, id, sender-pid etc.
33+//
34+// Copyright 2009 Canonical Ltd.
35+//
36+// Authors:
37+// Mirco "MacSlow" Mueller <mirco.mueller@canonical.com>
38+//
39+// This program is free software: you can redistribute it and/or modify it
40+// under the terms of the GNU General Public License version 3, as published
41+// by the Free Software Foundation.
42+//
43+// This program is distributed in the hope that it will be useful, but
44+// WITHOUT ANY WARRANTY; without even the implied warranties of
45+// MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
46+// PURPOSE. See the GNU General Public License for more details.
47+//
48+// You should have received a copy of the GNU General Public License along
49+// with this program. If not, see <http://www.gnu.org/licenses/>.
50+//
51+////////////////////////////////////////////////////////////////////////////////
52+
53+#include "notification.h"
54+
55+#define RETURN_GCHAR(n, string) \
56+ if (!n)\
57+ return NULL;\
58+ if (!n->priv)\
59+ return NULL;\
60+ if (!n->priv->string)\
61+ return NULL;\
62+ if (!n->priv->string->str)\
63+ return NULL;\
64+ return n->priv->string->str;
65+
66+#define SET_GCHAR(n, string) \
67+ if (!n)\
68+ return;\
69+ if (!n->priv)\
70+ return;\
71+ _set_text (&n->priv->string, string);
72+
73+struct _notification_private_t
74+{
75+ gint id; // unique notification-id
76+ GString* title; // summary-text strdup'ed from setter
77+ GString* body; // body-text strdup'ed from setter
78+ gint value; // range: 0..100, special: -1, 101
79+ GString* icon_themename; // e.g. "notification-message-email"
80+ GString* icon_filename; // e.g. "/usr/share/icons/icon.png"
81+ GdkPixbuf* icon_pixbuf; // from setter memcpy'ed pixbuf
82+ gint onscreen_time; // time on-screen in ms
83+ GString* sender_name; // app-name, strdup'ed from setter
84+ gint sender_pid; // pid of sending application
85+ GTimeVal reception_timestamp; // timestamp of reception
86+};
87+
88+// a little utility function to help avoid code-duplication
89+void
90+_set_text (GString** string,
91+ gchar* text)
92+{
93+ // sanity checks
94+ if (!text)
95+ return;
96+
97+ // see if we already have a GString set
98+ if (*string)
99+ {
100+ GString* new_string = g_string_new (text);
101+
102+ // is the new text different from the stored one
103+ if (g_string_equal (*string, new_string))
104+ {
105+ // if not, free new one and leave everything untouched
106+ g_string_free (new_string, TRUE);
107+ return;
108+ }
109+ else
110+ {
111+ // if it is, delete old and store new one
112+ g_string_free (*string, TRUE);
113+ *string = new_string;
114+ }
115+ }
116+ else
117+ *string = g_string_new (text);
118+}
119+
120+notification_t*
121+notification_new ()
122+{
123+ notification_private_t* priv = NULL;
124+ notification_t* n = NULL;
125+
126+ priv = g_new0 (notification_private_t, 1);
127+ if (!priv)
128+ return NULL;
129+
130+ n = g_new0 (notification_t, 1);
131+ if (!n)
132+ return NULL;
133+
134+ n->priv = priv;
135+
136+ return n;
137+}
138+
139+void
140+notification_destroy (notification_t* n)
141+{
142+ // sanity checks
143+ if (!n)
144+ return;
145+
146+ if (!n->priv)
147+ {
148+ g_free ((gpointer) n);
149+ return;
150+ }
151+
152+ // free any allocated string of pixbuf
153+ if (n->priv->title)
154+ g_string_free (n->priv->title, TRUE);
155+
156+ if (n->priv->body)
157+ g_string_free (n->priv->body, TRUE);
158+
159+ if (n->priv->icon_themename)
160+ g_string_free (n->priv->icon_themename, TRUE);
161+
162+ if (n->priv->icon_filename)
163+ g_string_free (n->priv->icon_filename, TRUE);
164+
165+ if (n->priv->icon_pixbuf)
166+ g_object_unref ((gpointer) n->priv->icon_pixbuf);
167+
168+ if (n->priv->sender_name)
169+ g_string_free (n->priv->sender_name, TRUE);
170+
171+ // get rid of the main allocated structs
172+ g_free ((gpointer) n->priv);
173+ g_free ((gpointer) n);
174+}
175+
176+gint
177+notification_get_id (notification_t* n)
178+{
179+ // sanity checks
180+ if (!n)
181+ return -1;
182+
183+ if (!n->priv)
184+ return -1;
185+
186+ return n->priv->id;
187+}
188+
189+void
190+notification_set_id (notification_t* n,
191+ gint id)
192+{
193+ // sanity checks
194+ if (!n)
195+ return;
196+
197+ if (!n->priv)
198+ return;
199+
200+ // an id is not allowed to be negative
201+ if (id < 0)
202+ return;
203+
204+ n->priv->id = id;
205+}
206+
207+gchar*
208+notification_get_title (notification_t* n)
209+{
210+ RETURN_GCHAR (n, title)
211+}
212+
213+void
214+notification_set_title (notification_t* n,
215+ gchar* title)
216+{
217+ SET_GCHAR (n, title)
218+}
219+
220+gchar*
221+notification_get_body (notification_t* n)
222+{
223+ RETURN_GCHAR (n, body)
224+}
225+
226+void
227+notification_set_body (notification_t* n,
228+ gchar* body)
229+{
230+ SET_GCHAR (n, body)
231+}
232+
233+// the allowed range for stored values is -1..101, thus a return-value of -2
234+// indicates an error on behalf of the caller
235+gint
236+notification_get_value (notification_t* n)
237+{
238+ // sanity checks
239+ if (!n)
240+ return -2;
241+
242+ if (!n->priv)
243+ return -2;
244+
245+ return n->priv->value;
246+}
247+
248+void
249+notification_set_value (notification_t* n,
250+ gint value)
251+{
252+ // sanity checks
253+ if (!n)
254+ return;
255+
256+ if (!n->priv)
257+ return;
258+
259+ // don't store any values outside of allowed range -1..101
260+ if (value < NOTIFICATION_VALUE_MIN_ALLOWED)
261+ {
262+ n->priv->value = NOTIFICATION_VALUE_MIN_ALLOWED;
263+ return;
264+ }
265+
266+ if (value > NOTIFICATION_VALUE_MAX_ALLOWED)
267+ {
268+ n->priv->value = NOTIFICATION_VALUE_MAX_ALLOWED;
269+ return;
270+ }
271+
272+ n->priv->value = value;
273+}
274+
275+gchar*
276+notification_get_icon_themename (notification_t* n)
277+{
278+ RETURN_GCHAR (n, icon_themename)
279+}
280+
281+void
282+notification_set_icon_themename (notification_t* n,
283+ gchar* icon_themename)
284+{
285+ SET_GCHAR (n, icon_themename)
286+}
287+
288+gchar*
289+notification_get_icon_filename (notification_t* n)
290+{
291+ RETURN_GCHAR (n, icon_filename)
292+}
293+
294+void
295+notification_set_icon_filename (notification_t* n,
296+ gchar* icon_filename)
297+{
298+ SET_GCHAR (n, icon_filename)
299+}
300+
301+GdkPixbuf*
302+notification_get_icon_pixbuf (notification_t* n)
303+{
304+ // sanity checks
305+ if (!n)
306+ return NULL;
307+
308+ if (!n->priv)
309+ return NULL;
310+
311+ // see if we actually have an icon_pixbuf set
312+ if (!n->priv->icon_pixbuf)
313+ return NULL;
314+
315+ return n->priv->icon_pixbuf;
316+}
317+
318+void
319+notification_set_icon_pixbuf (notification_t* n,
320+ GdkPixbuf* icon_pixbuf)
321+{
322+ // sanity checks
323+ if (!n)
324+ return;
325+
326+ if (!n->priv)
327+ return;
328+
329+ if (!icon_pixbuf)
330+ return;
331+
332+ // free any previous stored pixbuf
333+ if (n->priv->icon_pixbuf)
334+ g_object_unref (n->priv->icon_pixbuf);
335+
336+ // create a new/private copy of the supplied pixbuf
337+ n->priv->icon_pixbuf = gdk_pixbuf_copy (icon_pixbuf);
338+}
339+
340+// a return-value of -1 indicates an error on behalf of the caller, a
341+// return-value of 0 would indicate that a notification has not been displayed
342+// yet
343+gint
344+notification_get_onscreen_time (notification_t* n)
345+{
346+ // sanity checks
347+ if (!n)
348+ return -1;
349+
350+ if (!n->priv)
351+ return -1;
352+
353+ return n->priv->onscreen_time;
354+}
355+
356+void
357+notification_set_onscreen_time (notification_t* n,
358+ gint onscreen_time)
359+{
360+ // sanity checks
361+ if (!n)
362+ return;
363+
364+ if (!n->priv)
365+ return;
366+
367+ // see if the caller is really stupid and passes a negative time
368+ if (onscreen_time < 0)
369+ return;
370+
371+ // onscreen-time can only increase not decrease
372+ if (n->priv->onscreen_time > onscreen_time)
373+ return;
374+
375+ // you made it upto here, congratulations... let's store the new value
376+ n->priv->onscreen_time = onscreen_time;
377+}
378+
379+gchar*
380+notification_get_sender_name (notification_t* n)
381+{
382+ RETURN_GCHAR (n, sender_name)
383+}
384+
385+void
386+notification_set_sender_name (notification_t* n,
387+ gchar* sender_name)
388+{
389+ SET_GCHAR (n, sender_name)
390+}
391+
392+// a return-value of -1 indicates an error on behalf of the caller, PIDs are
393+// never negative
394+gint
395+notification_get_sender_pid (notification_t* n)
396+{
397+ // sanity checks
398+ if (!n)
399+ return -1;
400+
401+ if (!n->priv)
402+ return -1;
403+
404+ return n->priv->sender_pid;
405+}
406+
407+void
408+notification_set_sender_pid (notification_t* n,
409+ gint sender_pid)
410+{
411+ // sanity checks
412+ if (!n)
413+ return;
414+
415+ if (!n->priv)
416+ return;
417+
418+ // it's hardly possible we'll get a notification from init, but anyway
419+ if (sender_pid < 1)
420+ return;
421+
422+ n->priv->sender_pid = sender_pid;
423+}
424+
425+// the caller only gets a pointer to the timestamp
426+GTimeVal*
427+notification_get_reception_timestamp (notification_t* n)
428+{
429+ // sanity checks
430+ if (!n)
431+ return NULL;
432+
433+ if (!n->priv)
434+ return NULL;
435+
436+ return &n->priv->reception_timestamp;
437+}
438+
439+void
440+notification_set_reception_timestamp (notification_t* n,
441+ GTimeVal* reception_timestamp)
442+{
443+ // sanity checks
444+ if (!n)
445+ return;
446+
447+ if (!n->priv)
448+ return;
449+
450+ // being overly cautious again
451+ if (!reception_timestamp)
452+ return;
453+
454+ // don't store older timestamp over newer one
455+ if (n->priv->reception_timestamp.tv_sec > reception_timestamp->tv_sec)
456+ return;
457+
458+ if (n->priv->reception_timestamp.tv_sec == reception_timestamp->tv_sec)
459+ if (n->priv->reception_timestamp.tv_usec >
460+ reception_timestamp->tv_usec)
461+ return;
462+
463+ // new timestamp certainly more current that stored one
464+ n->priv->reception_timestamp.tv_sec = reception_timestamp->tv_sec;
465+ n->priv->reception_timestamp.tv_usec = reception_timestamp->tv_usec;
466+}
467+
468
469=== added file 'src/notification.h'
470--- src/notification.h 1970-01-01 00:00:00 +0000
471+++ src/notification.h 2009-07-23 12:04:41 +0000
472@@ -0,0 +1,129 @@
473+////////////////////////////////////////////////////////////////////////////////
474+//3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
475+// 10 20 30 40 50 60 70 80
476+//
477+// notify-osd
478+//
479+// notification.h - notification object storing attributes like title- and body-
480+// text, value, icon, id, sender-pid etc.
481+//
482+// Copyright 2009 Canonical Ltd.
483+//
484+// Authors:
485+// Mirco "MacSlow" Mueller <mirco.mueller@canonical.com>
486+//
487+// This program is free software: you can redistribute it and/or modify it
488+// under the terms of the GNU General Public License version 3, as published
489+// by the Free Software Foundation.
490+//
491+// This program is distributed in the hope that it will be useful, but
492+// WITHOUT ANY WARRANTY; without even the implied warranties of
493+// MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
494+// PURPOSE. See the GNU General Public License for more details.
495+//
496+// You should have received a copy of the GNU General Public License along
497+// with this program. If not, see <http://www.gnu.org/licenses/>.
498+//
499+////////////////////////////////////////////////////////////////////////////////
500+
501+#ifndef _NOTIFICATION_H
502+#define _NOTIFICATION_H
503+
504+#define NOTIFICATION_VALUE_MIN_ALLOWED -1
505+#define NOTIFICATION_VALUE_MAX_ALLOWED 101
506+
507+#include <glib.h>
508+#include <gdk-pixbuf/gdk-pixbuf.h>
509+
510+typedef struct _notification_private_t notification_private_t;
511+
512+typedef struct _notification_t
513+{
514+ notification_private_t* priv;
515+} notification_t;
516+
517+notification_t*
518+notification_new ();
519+
520+void
521+notification_destroy (notification_t* n);
522+
523+gint
524+notification_get_id (notification_t* n);
525+
526+void
527+notification_set_id (notification_t* n,
528+ gint id);
529+
530+gchar*
531+notification_get_title (notification_t* n);
532+
533+void
534+notification_set_title (notification_t* n,
535+ gchar* title);
536+
537+gchar*
538+notification_get_body (notification_t* n);
539+
540+void
541+notification_set_body (notification_t* n,
542+ gchar* body);
543+
544+gint
545+notification_get_value (notification_t* n);
546+
547+void
548+notification_set_value (notification_t* n,
549+ gint value);
550+
551+gchar*
552+notification_get_icon_themename (notification_t* n);
553+
554+void
555+notification_set_icon_themename (notification_t* n,
556+ gchar* icon_themename);
557+
558+gchar*
559+notification_get_icon_filename (notification_t* n);
560+
561+void
562+notification_set_icon_filename (notification_t* n,
563+ gchar* icon_filename);
564+
565+GdkPixbuf*
566+notification_get_icon_pixbuf (notification_t* n);
567+
568+void
569+notification_set_icon_pixbuf (notification_t* n,
570+ GdkPixbuf* icon_pixbuf);
571+
572+gint
573+notification_get_onscreen_time (notification_t* n);
574+
575+void
576+notification_set_onscreen_time (notification_t* n,
577+ gint onscreen_time);
578+
579+gchar*
580+notification_get_sender_name (notification_t* n);
581+
582+void
583+notification_set_sender_name (notification_t* n,
584+ gchar* sender_name);
585+
586+gint
587+notification_get_sender_pid (notification_t* n);
588+
589+void
590+notification_set_sender_pid (notification_t* n,
591+ gint sender_pid);
592+
593+GTimeVal*
594+notification_get_reception_timestamp (notification_t* n);
595+
596+void
597+notification_set_reception_timestamp (notification_t* n,
598+ GTimeVal* reception_timestamp);
599+
600+#endif // _NOTIFICATION_H
601+
602
603=== modified file 'tests/Makefile.am'
604--- tests/Makefile.am 2009-07-22 14:00:39 +0000
605+++ tests/Makefile.am 2009-07-23 12:04:41 +0000
606@@ -18,6 +18,7 @@
607 test_modules_SOURCES = \
608 $(top_srcdir)/src/bubble.c \
609 $(top_srcdir)/src/defaults.c \
610+ $(top_srcdir)/src/notification.c \
611 $(top_srcdir)/src/observer.c \
612 $(top_srcdir)/src/stack.c \
613 $(top_srcdir)/src/dbus.c \
614@@ -40,6 +41,7 @@
615 test-withlib.c \
616 test-bubble.c \
617 test-defaults.c \
618+ test-notification.c \
619 test-observer.c \
620 test-i18n.c \
621 test-synchronous.c \
622
623=== modified file 'tests/test-modules-main.c'
624--- tests/test-modules-main.c 2009-04-03 13:19:09 +0000
625+++ tests/test-modules-main.c 2009-07-23 12:04:41 +0000
626@@ -34,6 +34,7 @@
627 */
628 GTestSuite *test_bubble_create_test_suite (void);
629 GTestSuite *test_defaults_create_test_suite (void);
630+GTestSuite *test_notification_create_test_suite (void);
631 GTestSuite *test_observer_create_test_suite (void);
632 GTestSuite *test_stack_create_test_suite (void);
633 GTestSuite *test_dbus_create_test_suite (void);
634@@ -59,6 +60,7 @@
635
636 g_test_suite_add_suite (suite, test_bubble_create_test_suite ());
637 g_test_suite_add_suite (suite, test_defaults_create_test_suite ());
638+ g_test_suite_add_suite (suite, test_notification_create_test_suite ());
639 g_test_suite_add_suite (suite, test_observer_create_test_suite ());
640 g_test_suite_add_suite (suite, test_stack_create_test_suite ());
641 g_test_suite_add_suite (suite, test_filtering_create_test_suite ());
642
643=== added file 'tests/test-notification.c'
644--- tests/test-notification.c 1970-01-01 00:00:00 +0000
645+++ tests/test-notification.c 2009-07-23 14:09:08 +0000
646@@ -0,0 +1,655 @@
647+////////////////////////////////////////////////////////////////////////////////
648+//3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
649+// 10 20 30 40 50 60 70 80
650+//
651+// notify-osd
652+//
653+// test-notification.c - implements unit-tests for exercising API of abstract
654+// notification object
655+//
656+// Copyright 2009 Canonical Ltd.
657+//
658+// Authors:
659+// Mirco "MacSlow" Mueller <mirco.mueller@canonical.com>
660+//
661+// This program is free software: you can redistribute it and/or modify it
662+// under the terms of the GNU General Public License version 3, as published
663+// by the Free Software Foundation.
664+//
665+// This program is distributed in the hope that it will be useful, but
666+// WITHOUT ANY WARRANTY; without even the implied warranties of
667+// MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
668+// PURPOSE. See the GNU General Public License for more details.
669+//
670+// You should have received a copy of the GNU General Public License along
671+// with this program. If not, see <http://www.gnu.org/licenses/>.
672+//
673+////////////////////////////////////////////////////////////////////////////////
674+
675+#define _XOPEN_SOURCE 500 // needed for usleep() from unistd.h
676+#include <unistd.h>
677+
678+#include "notification.h"
679+
680+static void
681+test_notification_new (void)
682+{
683+ notification_t* n = NULL;
684+
685+ // create new object
686+ n = notification_new ();
687+
688+ // test validity of main notification object
689+ g_assert (n != NULL);
690+
691+ // test validity of initialized non-pointer and zeroed values
692+ g_assert_cmpint (notification_get_id (n), ==, 0);
693+ g_assert_cmpint (notification_get_value (n), ==, 0);
694+ g_assert_cmpint (notification_get_onscreen_time (n), ==, 0);
695+ g_assert_cmpint (notification_get_sender_pid (n), ==, 0);
696+
697+ // clean up
698+ notification_destroy (n);
699+}
700+
701+static void
702+test_notification_destroy (void)
703+{
704+ notification_t* n = NULL;
705+
706+ // create new object
707+ n = notification_new ();
708+
709+ // test validity of main notification object
710+ g_assert (n != NULL);
711+
712+ // clean up
713+ notification_destroy (n);
714+ n = NULL;
715+
716+ // verify destruction notification object
717+ g_assert_cmpint (notification_get_id (n), ==, -1);
718+}
719+
720+static void
721+test_notification_setget_id (void)
722+{
723+ notification_t* n = NULL;
724+
725+ // create new object
726+ n = notification_new ();
727+
728+ // if nothing has been set yet it should return 0
729+ g_assert_cmpint (notification_get_id (n), ==, 0);
730+
731+ // a negative id should not be stored
732+ notification_set_id (n, -1);
733+ g_assert_cmpint (notification_get_id (n), >=, 0);
734+
735+ // smallest possible id is 0
736+ notification_set_id (n, 0);
737+ g_assert_cmpint (notification_get_id (n), ==, 0);
738+
739+ // largest possible id is G_MAXINT
740+ notification_set_id (n, G_MAXINT);
741+ g_assert_cmpint (notification_get_id (n), ==, G_MAXINT);
742+
743+ // clean up
744+ notification_destroy (n);
745+ n = NULL;
746+
747+ // after destruction setting an id should not crash and it should
748+ // yield -1
749+ notification_set_id (n, 42);
750+ g_assert_cmpint (notification_get_id (n), ==, -1);
751+}
752+
753+static void
754+test_notification_setget_title (void)
755+{
756+ notification_t* n = NULL;
757+
758+ // create new object
759+ n = notification_new ();
760+
761+ // if no title has been set yet it should return NULL
762+ g_assert (notification_get_title (n) == NULL);
763+
764+ // set an initial title-text and verify it
765+ notification_set_title (n, "Some title text");
766+ g_assert_cmpstr (notification_get_title (n), ==, "Some title text");
767+
768+ // set a new title-text and verify it
769+ notification_set_title (n, "The new summary");
770+ g_assert_cmpstr (notification_get_title (n), !=, "Some title text");
771+ g_assert_cmpstr (notification_get_title (n), ==, "The new summary");
772+
773+ // clean up
774+ notification_destroy (n);
775+ n = NULL;
776+
777+ // after destruction setting a title should not crash and it should
778+ // yield NULL
779+ notification_set_title (n, "Unsettable title");
780+ g_assert (notification_get_title (n) == NULL);
781+}
782+
783+static void
784+test_notification_setget_body (void)
785+{
786+ notification_t* n = NULL;
787+
788+ // create new object
789+ n = notification_new ();
790+
791+ // if no body has been set yet it should return NULL
792+ g_assert (notification_get_body (n) == NULL);
793+
794+ // set an initial body-text and verify it
795+ notification_set_body (n, "Example body text");
796+ g_assert_cmpstr (notification_get_body (n), ==, "Example body text");
797+
798+ // set a new body-text and verify it
799+ notification_set_body (n, "Some new body text");
800+ g_assert_cmpstr (notification_get_body (n), !=, "Example body text");
801+ g_assert_cmpstr (notification_get_body (n), ==, "Some new body text");
802+
803+ // clean up
804+ notification_destroy (n);
805+ n = NULL;
806+
807+ // after destruction setting a body should not crash and it should
808+ // yield NULL
809+ notification_set_body (n, "You'll not get this body-text");
810+ g_assert (notification_get_body (n) == NULL);
811+}
812+
813+static void
814+test_notification_setget_value (void)
815+{
816+ notification_t* n = NULL;
817+
818+ // create new object
819+ n = notification_new ();
820+
821+ // if no value has been set yet it should return 0
822+ g_assert_cmpint (notification_get_value (n), ==, 0);
823+
824+ // set an initial value and verify it
825+ notification_set_value (n, 25);
826+ g_assert_cmpint (notification_get_value (n), ==, 25);
827+
828+ // set a new value and verify it
829+ notification_set_value (n, 45);
830+ g_assert_cmpint (notification_get_value (n), !=, 25);
831+ g_assert_cmpint (notification_get_value (n), ==, 45);
832+
833+ // test allowed range
834+ notification_set_value (n, NOTIFICATION_VALUE_MAX_ALLOWED + 1);
835+ g_assert_cmpint (notification_get_value (n),
836+ ==,
837+ NOTIFICATION_VALUE_MAX_ALLOWED);
838+ notification_set_value (n, NOTIFICATION_VALUE_MIN_ALLOWED - 1);
839+ g_assert_cmpint (notification_get_value (n),
840+ ==,
841+ NOTIFICATION_VALUE_MIN_ALLOWED);
842+
843+ // clean up
844+ notification_destroy (n);
845+ n = NULL;
846+
847+ // after destruction setting a value should not crash and it should
848+ // yield -2
849+ notification_set_value (n, 50);
850+ g_assert_cmpint (notification_get_value (n), ==, -2);
851+}
852+
853+static void
854+test_notification_setget_icon_themename (void)
855+{
856+ notification_t* n = NULL;
857+
858+ // create new object
859+ n = notification_new ();
860+
861+ // if no icon-themename has been set yet it should return NULL
862+ g_assert (notification_get_icon_themename (n) == NULL);
863+
864+ // set an initial icon-themename and verify it
865+ notification_set_icon_themename (n, "notification-message-im");
866+ g_assert_cmpstr (notification_get_icon_themename (n),
867+ ==,
868+ "notification-message-im");
869+
870+ // set a new icon-themename and verify it
871+ notification_set_icon_themename (n, "notification-device-usb");
872+ g_assert_cmpstr (notification_get_icon_themename (n),
873+ !=,
874+ "notification-message-im");
875+ g_assert_cmpstr (notification_get_icon_themename (n),
876+ ==,
877+ "notification-device-usb");
878+
879+ // clean up
880+ notification_destroy (n);
881+ n = NULL;
882+
883+ // after destruction setting an icon-themename should not crash and it
884+ // should yield NULL
885+ notification_set_icon_themename (n, "notification-printer");
886+ g_assert (notification_get_icon_themename (n) == NULL);
887+}
888+
889+static void
890+test_notification_setget_icon_filename (void)
891+{
892+ notification_t* n = NULL;
893+
894+ // create new object
895+ n = notification_new ();
896+
897+ // if no icon-filename has been set yet it should return NULL
898+ g_assert (notification_get_icon_filename (n) == NULL);
899+
900+ // set an initial icon-filename and verify it
901+ notification_set_icon_filename (n, "/usr/share/icon/photo.png");
902+ g_assert_cmpstr (notification_get_icon_filename (n),
903+ ==,
904+ "/usr/share/icon/photo.png");
905+
906+ // set a new icon-filename and verify it
907+ notification_set_icon_filename (n, "/tmp/drawing.svg");
908+ g_assert_cmpstr (notification_get_icon_filename (n),
909+ !=,
910+ "/usr/share/icon/photo.png");
911+ g_assert_cmpstr (notification_get_icon_filename (n),
912+ ==,
913+ "/tmp/drawing.svg");
914+
915+ // passing an invalid/NULL pointer should not change the stored
916+ // icon-filename
917+ notification_set_icon_filename (n, NULL);
918+ g_assert_cmpstr (notification_get_icon_filename (n),
919+ ==,
920+ "/tmp/drawing.svg");
921+
922+ // pass an empty (but not NULL) strings
923+ notification_set_icon_filename (n, "");
924+ g_assert_cmpstr (notification_get_icon_filename (n),
925+ ==,
926+ "");
927+ notification_set_icon_filename (n, "\0");
928+ g_assert_cmpstr (notification_get_icon_filename (n),
929+ ==,
930+ "\0");
931+
932+ // clean up
933+ notification_destroy (n);
934+ n = NULL;
935+
936+ // after destruction setting an icon-filename should not crash and it
937+ // should yield NULL
938+ notification_set_icon_filename (n, "");
939+ g_assert (notification_get_icon_filename (n) == NULL);
940+}
941+
942+static void
943+test_notification_setget_icon_pixbuf (void)
944+{
945+ notification_t* n = NULL;
946+ GdkPixbuf* pixbuf = NULL;
947+
948+ // create new object
949+ n = notification_new ();
950+
951+ // if no icon-pixbuf has been set yet it should return NULL
952+ g_assert (notification_get_icon_pixbuf (n) == NULL);
953+
954+ // create pixbuf for testing
955+ pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, 100, 100);
956+
957+ // set an initial icon-pixbuf and verify it
958+ notification_set_icon_pixbuf (n, pixbuf);
959+ g_assert (notification_get_icon_pixbuf (n) != NULL);
960+
961+ // passing an invalid/NULL pointer should not change the stored
962+ // icon-pixbuf
963+ notification_set_icon_pixbuf (n, NULL);
964+ g_assert (notification_get_icon_pixbuf (n) != NULL);
965+
966+ // clean up
967+ notification_destroy (n);
968+ n = NULL;
969+
970+ // after destruction setting an icon-pixbuf should not crash and it
971+ // should yield NULL
972+ notification_set_icon_pixbuf (n, pixbuf);
973+ g_assert (notification_get_icon_pixbuf (n) == NULL);
974+
975+ // more clean up
976+ g_object_unref (pixbuf);
977+}
978+
979+static void
980+test_notification_setget_onscreen_time (void)
981+{
982+ notification_t* n = NULL;
983+
984+ // create new object
985+ n = notification_new ();
986+
987+ // if no onscreen-time has been set yet it should return 0
988+ g_assert_cmpint (notification_get_onscreen_time (n), ==, 0);
989+
990+ // setting a negative onscreen-time should fail
991+ notification_set_onscreen_time (n, -1);
992+ g_assert_cmpint (notification_get_onscreen_time (n), ==, 0);
993+
994+ // set an positive onscreen-time and verify it
995+ notification_set_onscreen_time (n, 1000);
996+ g_assert_cmpint (notification_get_onscreen_time (n), ==, 1000);
997+
998+ // set a new onscreen-time and verify it
999+ notification_set_onscreen_time (n, 5000);
1000+ g_assert_cmpint (notification_get_onscreen_time (n), !=, 1000);
1001+ g_assert_cmpint (notification_get_onscreen_time (n), ==, 5000);
1002+
1003+ // setting a new onscreen-time smaller than the currently stored one
1004+ // should fail
1005+ notification_set_onscreen_time (n, 4000);
1006+ g_assert_cmpint (notification_get_onscreen_time (n), ==, 5000);
1007+
1008+ // clean up
1009+ notification_destroy (n);
1010+ n = NULL;
1011+
1012+ // after destruction setting a value should not crash and it should
1013+ // yield -1
1014+ notification_set_onscreen_time (n, 500);
1015+ g_assert_cmpint (notification_get_onscreen_time (n), ==, -1);
1016+}
1017+
1018+static void
1019+test_notification_setget_sender_name (void)
1020+{
1021+ notification_t* n = NULL;
1022+
1023+ // create new object
1024+ n = notification_new ();
1025+
1026+ // if no sender-name has been set yet it should return NULL
1027+ g_assert (notification_get_sender_name (n) == NULL);
1028+
1029+ // set an initial sender-name and verify it
1030+ notification_set_sender_name (n, "evolution");
1031+ g_assert_cmpstr (notification_get_sender_name (n), ==, "evolution");
1032+
1033+ // set a new sender-name and verify it
1034+ notification_set_sender_name (n, "pidgin");
1035+ g_assert_cmpstr (notification_get_sender_name (n), !=, "evolution");
1036+ g_assert_cmpstr (notification_get_sender_name (n), ==, "pidgin");
1037+
1038+ // passing an invalid/NULL pointer should not change the stored
1039+ // sender-name
1040+ notification_set_sender_name (n, NULL);
1041+ g_assert_cmpstr (notification_get_sender_name (n), ==, "pidgin");
1042+
1043+ // pass an empty (but not NULL) strings
1044+ notification_set_sender_name (n, "");
1045+ g_assert_cmpstr (notification_get_sender_name (n), ==, "");
1046+ notification_set_sender_name (n, "\0");
1047+ g_assert_cmpstr (notification_get_sender_name (n), ==, "\0");
1048+
1049+ // clean up
1050+ notification_destroy (n);
1051+ n = NULL;
1052+
1053+ // after destruction setting an icon-filename should not crash and it
1054+ // should yield NULL
1055+ notification_set_sender_name (n, "banshee");
1056+ g_assert (notification_get_sender_name (n) == NULL);
1057+}
1058+
1059+static void
1060+test_notification_setget_sender_pid (void)
1061+{
1062+ notification_t* n = NULL;
1063+
1064+ // create new object
1065+ n = notification_new ();
1066+
1067+ // if nothing has been set yet it should return 0
1068+ g_assert_cmpint (notification_get_sender_pid (n), ==, 0);
1069+
1070+ // a negative pid makes no sense and should therefore not be stored
1071+ notification_set_sender_pid (n, -1);
1072+ g_assert_cmpint (notification_get_sender_pid (n), ==, 0);
1073+
1074+ // smallest possible pid is 1
1075+ notification_set_sender_pid (n, 1);
1076+ g_assert_cmpint (notification_get_sender_pid (n), ==, 1);
1077+
1078+ // largest possible id is G_MAXINT
1079+ notification_set_sender_pid (n, G_MAXINT);
1080+ g_assert_cmpint (notification_get_sender_pid (n), ==, G_MAXINT);
1081+
1082+ // a pid of 0 would mean something before the init process is sending us
1083+ // a notification, leave the stored pid untouched
1084+ notification_set_sender_pid (n, 0);
1085+ g_assert_cmpint (notification_get_sender_pid (n), ==, G_MAXINT);
1086+
1087+ // clean up
1088+ notification_destroy (n);
1089+ n = NULL;
1090+
1091+ // after destruction setting a pid should not crash and it should
1092+ // yield -1
1093+ notification_set_sender_pid (n, 42);
1094+ g_assert_cmpint (notification_get_sender_pid (n), ==, -1);
1095+}
1096+
1097+static void
1098+test_notification_setget_reception_timestamp (void)
1099+{
1100+ notification_t* n = NULL;
1101+ GTimeVal* tvptr = NULL;
1102+ GTimeVal tv_old;
1103+ GTimeVal tv_new;
1104+
1105+ // create new object
1106+ n = notification_new ();
1107+
1108+ // if no reception-time has been set yet it should return 0/0
1109+ tvptr = notification_get_reception_timestamp (n);
1110+ g_assert_cmpint (tvptr->tv_sec, ==, 0);
1111+ g_assert_cmpint (tvptr->tv_usec, ==, 0);
1112+
1113+ // ehm... well, get current time
1114+ g_get_current_time (&tv_old);
1115+
1116+ // store current time as reception-time and verify it
1117+ notification_set_reception_timestamp (n, &tv_old);
1118+ tvptr = notification_get_reception_timestamp (n);
1119+ g_assert_cmpint (tvptr->tv_sec, ==, tv_old.tv_sec);
1120+ g_assert_cmpint (tvptr->tv_usec, ==, tv_old.tv_usec);
1121+
1122+ // wait at least two seconds
1123+ sleep (2);
1124+
1125+ // get current time
1126+ g_get_current_time (&tv_new);
1127+
1128+ // trying to store an older timestamp over a newer one should fail
1129+ // second-granularity
1130+ notification_set_reception_timestamp (n, &tv_new);
1131+ notification_set_reception_timestamp (n, &tv_old);
1132+ tvptr = notification_get_reception_timestamp (n);
1133+ g_assert_cmpint (tvptr->tv_sec, !=, tv_old.tv_sec);
1134+ g_assert_cmpint (tvptr->tv_sec, ==, tv_new.tv_sec);
1135+
1136+ // get current time
1137+ g_get_current_time (&tv_old);
1138+ notification_set_reception_timestamp (n, &tv_old);
1139+
1140+ // wait some micro-seconds
1141+ usleep (10000);
1142+
1143+ // get current time
1144+ g_get_current_time (&tv_new);
1145+
1146+ // trying to store an older timestamp over a newer one should fail
1147+ // microsecond-granularity
1148+ notification_set_reception_timestamp (n, &tv_new);
1149+ notification_set_reception_timestamp (n, &tv_old);
1150+ tvptr = notification_get_reception_timestamp (n);
1151+ g_assert_cmpint (tvptr->tv_usec, !=, tv_old.tv_usec);
1152+ g_assert_cmpint (tvptr->tv_usec, ==, tv_new.tv_usec);
1153+
1154+ // clean up
1155+ notification_destroy (n);
1156+ n = NULL;
1157+
1158+ // after destruction setting a reception-time should not crash and it
1159+ // should yield NULL
1160+ notification_set_reception_timestamp (n, &tv_new);
1161+ g_assert (notification_get_reception_timestamp (n) == NULL);
1162+}
1163+
1164+GTestSuite *
1165+test_notification_create_test_suite (void)
1166+{
1167+ GTestSuite *ts = NULL;
1168+ GTestCase *tc = NULL;
1169+
1170+ ts = g_test_create_suite ("notification");
1171+ tc = g_test_create_case ("can create",
1172+ 0,
1173+ NULL,
1174+ NULL,
1175+ test_notification_new,
1176+ NULL);
1177+ g_test_suite_add (ts, tc);
1178+
1179+ g_test_suite_add (
1180+ ts,
1181+ g_test_create_case (
1182+ "can destroy",
1183+ 0,
1184+ NULL,
1185+ NULL,
1186+ test_notification_destroy,
1187+ NULL));
1188+
1189+ g_test_suite_add (
1190+ ts,
1191+ g_test_create_case (
1192+ "can set|get id",
1193+ 0,
1194+ NULL,
1195+ NULL,
1196+ test_notification_setget_id,
1197+ NULL));
1198+
1199+ g_test_suite_add (
1200+ ts,
1201+ g_test_create_case (
1202+ "can set|get title",
1203+ 0,
1204+ NULL,
1205+ NULL,
1206+ test_notification_setget_title,
1207+ NULL));
1208+
1209+ g_test_suite_add (
1210+ ts,
1211+ g_test_create_case (
1212+ "can set|get body",
1213+ 0,
1214+ NULL,
1215+ NULL,
1216+ test_notification_setget_body,
1217+ NULL));
1218+
1219+ g_test_suite_add (
1220+ ts,
1221+ g_test_create_case (
1222+ "can set|get value",
1223+ 0,
1224+ NULL,
1225+ NULL,
1226+ test_notification_setget_value,
1227+ NULL));
1228+
1229+ g_test_suite_add (
1230+ ts,
1231+ g_test_create_case (
1232+ "can set|get icon-themename",
1233+ 0,
1234+ NULL,
1235+ NULL,
1236+ test_notification_setget_icon_themename,
1237+ NULL));
1238+
1239+ g_test_suite_add (
1240+ ts,
1241+ g_test_create_case (
1242+ "can set|get icon-filename",
1243+ 0,
1244+ NULL,
1245+ NULL,
1246+ test_notification_setget_icon_filename,
1247+ NULL));
1248+
1249+ g_test_suite_add (
1250+ ts,
1251+ g_test_create_case (
1252+ "can set|get icon-pixbuf",
1253+ 0,
1254+ NULL,
1255+ NULL,
1256+ test_notification_setget_icon_pixbuf,
1257+ NULL));
1258+
1259+ g_test_suite_add (
1260+ ts,
1261+ g_test_create_case (
1262+ "can set|get onscreen-time",
1263+ 0,
1264+ NULL,
1265+ NULL,
1266+ test_notification_setget_onscreen_time,
1267+ NULL));
1268+
1269+ g_test_suite_add (
1270+ ts,
1271+ g_test_create_case (
1272+ "can set|get sender-name",
1273+ 0,
1274+ NULL,
1275+ NULL,
1276+ test_notification_setget_sender_name,
1277+ NULL));
1278+
1279+ g_test_suite_add (
1280+ ts,
1281+ g_test_create_case (
1282+ "can set|get sender-pid",
1283+ 0,
1284+ NULL,
1285+ NULL,
1286+ test_notification_setget_sender_pid,
1287+ NULL));
1288+
1289+ g_test_suite_add (
1290+ ts,
1291+ g_test_create_case (
1292+ "can set|get reception-timestamp",
1293+ 0,
1294+ NULL,
1295+ NULL,
1296+ test_notification_setget_reception_timestamp,
1297+ NULL));
1298+
1299+ return ts;
1300+}
1301+

Subscribers

People subscribed via source and target branches