ayatana-commits team mailing list archive
-
ayatana-commits team
-
Mailing list archive
-
Message #00794
[Merge] lp:~ted/libindicate/variable-variants into lp:libindicate
Ted Gould has proposed merging lp:~ted/libindicate/variable-variants into lp:libindicate.
Requested reviews:
Indicator Applet Developers (indicator-applet-developers)
Making the dbus protocol use variants.
--
https://code.launchpad.net/~ted/libindicate/variable-variants/+merge/18367
Your team ayatana-commits is subscribed to branch lp:libindicate.
=== modified file 'libindicate/indicate-interface.xml'
--- libindicate/indicate-interface.xml 2009-09-08 21:56:49 +0000
+++ libindicate/indicate-interface.xml 2010-02-01 06:36:18 +0000
@@ -45,12 +45,12 @@
<method name="GetIndicatorProperty">
<arg type="u" name="id" direction="in" />
<arg type="s" name="property" direction="in" />
- <arg type="s" name="value" direction="out" />
+ <arg type="v" name="value" direction="out" />
</method>
<method name="GetIndicatorPropertyGroup">
<arg type="u" name="id" direction="in" />
<arg type="as" name="properties" direction="in" />
- <arg type="as" name="values" direction="out" />
+ <arg type="a{sv}" name="values" direction="out" />
</method>
<method name="GetIndicatorProperties">
<arg type="u" name="id" direction="in" />
=== modified file 'libindicate/indicator.c'
--- libindicate/indicator.c 2009-09-14 14:48:43 +0000
+++ libindicate/indicator.c 2010-02-01 06:36:18 +0000
@@ -60,8 +60,8 @@
G_DEFINE_TYPE (IndicateIndicator, indicate_indicator, G_TYPE_OBJECT);
static void indicate_indicator_finalize (GObject * object);
-static void set_property (IndicateIndicator * indicator, const gchar * key, const gchar * data);
-static const gchar * get_property (IndicateIndicator * indicator, const gchar * key);
+static void set_property (IndicateIndicator * indicator, const gchar * key, const GValue * data);
+static const GValue * get_property (IndicateIndicator * indicator, const gchar * key);
static GPtrArray * list_properties (IndicateIndicator * indicator);
@@ -166,6 +166,18 @@
return;
}
+/* A small little function to both clear the insides of a
+ value as well as the memory it itself uses. */
+static void
+_g_value_free (gpointer data)
+{
+ if (data == NULL) return;
+ GValue * value = (GValue*)data;
+ g_value_unset(value);
+ g_free(data);
+ return;
+}
+
static void
indicate_indicator_init (IndicateIndicator * indicator)
{
@@ -175,7 +187,7 @@
priv->is_visible = FALSE;
priv->is_displayed = FALSE;
- priv->properties = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
+ priv->properties = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, _g_value_free);
priv->server = indicate_server_ref_default();
priv->id = indicate_server_get_next_id(priv->server);
@@ -398,7 +410,11 @@
return;
}
- return class->set_property(indicator, key, data);
+ GValue strval = {0};
+ g_value_init(&strval, G_TYPE_STRING);
+ g_value_set_static_string(&strval, data);
+
+ return class->set_property(indicator, key, &strval);
}
/**
@@ -436,12 +452,16 @@
void
indicate_indicator_set_property_int (IndicateIndicator * indicator, const gchar * key, gint value)
{
- gchar * valuestr = g_strdup_printf("%d", value);
- if (valuestr != NULL) {
- indicate_indicator_set_property(indicator, key, valuestr);
+ IndicateIndicatorClass * class = INDICATE_INDICATOR_GET_CLASS(indicator);
+ if (class->set_property == NULL) {
+ return;
}
- g_free(valuestr);
- return;
+
+ GValue intval = {0};
+ g_value_init(&intval, G_TYPE_INT);
+ g_value_set_int(&intval, value);
+
+ return class->set_property(indicator, key, &intval);
}
/**
@@ -457,12 +477,27 @@
void
indicate_indicator_set_property_bool (IndicateIndicator * indicator, const gchar * key, gboolean value)
{
- if (value) {
- indicate_indicator_set_property(indicator, key, INDICATE_INDICATOR_VALUE_TRUE);
- } else {
- indicate_indicator_set_property(indicator, key, INDICATE_INDICATOR_VALUE_FALSE);
- }
- return;
+ IndicateIndicatorClass * class = INDICATE_INDICATOR_GET_CLASS(indicator);
+ if (class->set_property == NULL) {
+ return;
+ }
+
+ GValue boolval = {0};
+ g_value_init(&boolval, G_TYPE_BOOLEAN);
+ g_value_set_boolean(&boolval, value);
+
+ return class->set_property(indicator, key, &boolval);
+}
+
+void
+indicate_indicator_set_property_value (IndicateIndicator * indicator, const gchar * key, GValue * value)
+{
+ IndicateIndicatorClass * class = INDICATE_INDICATOR_GET_CLASS(indicator);
+ if (class->set_property == NULL) {
+ return;
+ }
+
+ return class->set_property(indicator, key, value);
}
/**
@@ -483,6 +518,18 @@
return NULL;
}
+ const GValue * val = class->get_property(indicator, key);
+ return g_value_get_string(val);
+}
+
+const GValue *
+indicate_indicator_get_property_value (IndicateIndicator * indicator, const gchar * key)
+{
+ IndicateIndicatorClass * class = INDICATE_INDICATOR_GET_CLASS(indicator);
+ if (class->get_property == NULL) {
+ return NULL;
+ }
+
return class->get_property(indicator, key);
}
@@ -508,36 +555,35 @@
}
static void
-set_property (IndicateIndicator * indicator, const gchar * key, const gchar * data)
+set_property (IndicateIndicator * indicator, const gchar * key, const GValue * data)
{
g_return_if_fail(INDICATE_IS_INDICATOR(indicator));
IndicateIndicatorPrivate * priv = INDICATE_INDICATOR_GET_PRIVATE(indicator);
- gchar * current = g_hash_table_lookup(priv->properties, key);
- if (current == NULL || g_strcmp0(current, data)) {
- /* If the value has changed or there is no value */
- gchar * newkey = g_strdup(key);
- /* g_debug("What is newkey? %s", newkey); */
- g_hash_table_insert(priv->properties, newkey, g_strdup(data));
- if (indicate_indicator_is_visible(indicator)) {
- /* g_debug("Indicator property modified: %s %s", key, data); */
- g_signal_emit(indicator, signals[MODIFIED], 0, key, TRUE);
- }
+ gchar * newkey = g_strdup(key);
+ GValue * newval = g_new0(GValue, 1);
+ g_value_init(newval, G_VALUE_TYPE(data));
+ g_value_copy(data, newval);
+
+ g_hash_table_replace(priv->properties, newkey, newval);
+
+ if (indicate_indicator_is_visible(indicator)) {
+ /* g_debug("Indicator property modified: %s", key); */
+ g_signal_emit(indicator, signals[MODIFIED], 0, key, TRUE);
}
return;
}
-static const gchar *
+static const GValue *
get_property (IndicateIndicator * indicator, const gchar * key)
{
g_return_val_if_fail(INDICATE_IS_INDICATOR(indicator), NULL);
IndicateIndicatorPrivate * priv = INDICATE_INDICATOR_GET_PRIVATE(indicator);
- // TODO: Think about whether we should be strdup'ing this. Seems like overkill, but might not be.
- return (const gchar *)g_hash_table_lookup(priv->properties, key);
+ return (const GValue *)g_hash_table_lookup(priv->properties, key);
}
static GPtrArray *
=== modified file 'libindicate/indicator.h'
--- libindicate/indicator.h 2009-09-14 14:48:43 +0000
+++ libindicate/indicator.h 2010-02-01 06:36:18 +0000
@@ -113,8 +113,8 @@
void (*displayed) (IndicateIndicator * indicator, gboolean displayed);
/* Subclassable functions */
- void (*set_property) (IndicateIndicator * indicator, const gchar * key, const gchar * data);
- const gchar * (*get_property) (IndicateIndicator * indicator, const gchar * key);
+ void (*set_property) (IndicateIndicator * indicator, const gchar * key, const GValue * data);
+ const GValue * (*get_property) (IndicateIndicator * indicator, const gchar * key);
GPtrArray * (*list_properties) (IndicateIndicator * indicator);
/* Reserver for future use */
@@ -149,8 +149,11 @@
void indicate_indicator_set_property_time (IndicateIndicator * indicator, const gchar * key, GTimeVal * time);
void indicate_indicator_set_property_int (IndicateIndicator * indicator, const gchar * key, gint value);
void indicate_indicator_set_property_bool (IndicateIndicator * indicator, const gchar * key, gboolean value);
+void indicate_indicator_set_property_value (IndicateIndicator * indicator, const gchar * key, GValue * value);
const gchar * indicate_indicator_get_property (IndicateIndicator * indicator, const gchar * key);
+const GValue * indicate_indicator_get_property_value (IndicateIndicator * indicator, const gchar * key);
+
GPtrArray * indicate_indicator_list_properties (IndicateIndicator * indicator);
/* Controling whether it's displayed */
=== modified file 'libindicate/listener.c'
--- libindicate/listener.c 2009-11-04 17:51:08 +0000
+++ libindicate/listener.c 2010-02-01 06:36:18 +0000
@@ -730,7 +730,7 @@
it nice to work with properties and the listener.
*/
static void
-get_property_cb (DBusGProxy *proxy, char * OUT_value, GError *error, gpointer userdata)
+get_property_cb (DBusGProxy *proxy, GValue OUT_value, GError *error, gpointer userdata)
{
get_property_t * get_property_data = (get_property_t *)userdata;
@@ -744,14 +744,14 @@
case PROPERTY_TYPE_STRING: {
/* Just pass the string along. */
indicate_listener_get_property_cb cb = (indicate_listener_get_property_cb)get_property_data->cb;
- cb(get_property_data->listener, get_property_data->server, get_property_data->indicator, get_property_data->property, OUT_value, get_property_data->data);
+ cb(get_property_data->listener, get_property_data->server, get_property_data->indicator, get_property_data->property, g_value_get_string(&OUT_value), get_property_data->data);
break;
}
case PROPERTY_TYPE_TIME: {
/* Convert it to a time val */
indicate_listener_get_property_time_cb cb = (indicate_listener_get_property_time_cb)get_property_data->cb;
GTimeVal time;
- if (g_time_val_from_iso8601(OUT_value, &time)) {
+ if (g_time_val_from_iso8601(g_value_get_string(&OUT_value), &time)) {
cb(get_property_data->listener, get_property_data->server, get_property_data->indicator, get_property_data->property, &time, get_property_data->data);
}
break;
@@ -759,20 +759,14 @@
case PROPERTY_TYPE_INT: {
/* Take the string and convert it to an integer */
indicate_listener_get_property_int_cb cb = (indicate_listener_get_property_int_cb)get_property_data->cb;
- if (OUT_value == NULL) break;
- gint intval = atoi(OUT_value);
- cb(get_property_data->listener, get_property_data->server, get_property_data->indicator, get_property_data->property, intval, get_property_data->data);
+ cb(get_property_data->listener, get_property_data->server, get_property_data->indicator, get_property_data->property, g_value_get_int(&OUT_value), get_property_data->data);
break;
}
case PROPERTY_TYPE_BOOL: {
/* Check to see if it's 'true', if not assume that
it's false */
indicate_listener_get_property_bool_cb cb = (indicate_listener_get_property_bool_cb)get_property_data->cb;
- if (g_strcmp0(OUT_value, INDICATE_INDICATOR_VALUE_TRUE) == 0) {
- cb(get_property_data->listener, get_property_data->server, get_property_data->indicator, get_property_data->property, TRUE, get_property_data->data);
- } else {
- cb(get_property_data->listener, get_property_data->server, get_property_data->indicator, get_property_data->property, FALSE, get_property_data->data);
- }
+ cb(get_property_data->listener, get_property_data->server, get_property_data->indicator, get_property_data->property, g_value_get_boolean(&OUT_value), get_property_data->data);
break;
}
}
=== modified file 'libindicate/listener.h'
--- libindicate/listener.h 2009-09-14 15:01:18 +0000
+++ libindicate/listener.h 2010-02-01 06:36:18 +0000
@@ -110,8 +110,8 @@
GType indicate_listener_get_type (void) G_GNUC_CONST;
-typedef void (*indicate_listener_get_property_cb) (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * property, gchar * propertydata, gpointer data);
-typedef void (*indicate_listener_get_property_time_cb) (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * property, GTimeVal * propertydata, gpointer data);
+typedef void (*indicate_listener_get_property_cb) (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * property, const gchar * propertydata, gpointer data);
+typedef void (*indicate_listener_get_property_time_cb) (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * property, const GTimeVal * propertydata, gpointer data);
typedef void (*indicate_listener_get_property_int_cb) (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * property, gint propertydata, gpointer data);
typedef void (*indicate_listener_get_property_bool_cb) (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * property, gboolean propertydata, gpointer data);
typedef void (*indicate_listener_get_server_property_cb) (IndicateListener * listener, IndicateListenerServer * server, gchar * value, gpointer data);
=== modified file 'libindicate/server.c'
--- libindicate/server.c 2009-09-17 15:00:42 +0000
+++ libindicate/server.c 2010-02-01 06:36:18 +0000
@@ -129,7 +129,7 @@
static gboolean get_indicator_count (IndicateServer * server, guint * count, GError **error);
static gboolean get_indicator_list (IndicateServer * server, GArray ** indicators, GError ** error);
static IndicateIndicator * get_indicator (IndicateServer * server, guint id, GError **error);
-static gboolean get_indicator_property (IndicateServer * server, guint id, gchar * property, gchar ** value, GError **error);
+static gboolean get_indicator_property (IndicateServer * server, guint id, gchar * property, GValue * value, GError **error);
static gboolean get_indicator_property_group (IndicateServer * server, guint id, GPtrArray * properties, gchar *** value, GError **error);
static gboolean get_indicator_properties (IndicateServer * server, guint id, gchar *** properties, GError **error);
static gboolean show_indicator_to_user (IndicateServer * server, guint id, GError ** error);
@@ -155,7 +155,7 @@
/* DBus API */
gboolean _indicate_server_get_indicator_count (IndicateServer * server, guint * count, GError **error);
gboolean _indicate_server_get_indicator_list (IndicateServer * server, GArray ** indicators, GError ** error);
-gboolean _indicate_server_get_indicator_property (IndicateServer * server, guint id, gchar * property, gchar ** value, GError **error);
+gboolean _indicate_server_get_indicator_property (IndicateServer * server, guint id, gchar * property, GValue * value, GError **error);
gboolean _indicate_server_get_indicator_property_group (IndicateServer * server, guint id, GPtrArray * properties, gchar *** value, GError **error);
gboolean _indicate_server_get_indicator_properties (IndicateServer * server, guint id, gchar *** properties, GError **error);
gboolean _indicate_server_show_indicator_to_user (IndicateServer * server, guint id, GError ** error);
@@ -1187,14 +1187,20 @@
}
static gboolean
-get_indicator_property (IndicateServer * server, guint id, gchar * property, gchar ** value, GError **error)
+get_indicator_property (IndicateServer * server, guint id, gchar * property, GValue * value, GError **error)
{
IndicateIndicator * indicator = get_indicator(server, id, error);
if (indicator == NULL) {
return FALSE;
}
- *value = g_strdup(indicate_indicator_get_property(indicator, property));
+ const GValue * ind_property = indicate_indicator_get_property_value(indicator, property);
+ if (ind_property == NULL) {
+ return FALSE;
+ }
+
+ g_value_init(value, G_VALUE_TYPE(ind_property));
+ g_value_copy(ind_property, value);
return TRUE;
}
@@ -1209,12 +1215,17 @@
GPtrArray * array = g_ptr_array_new();
int i;
for (i = 0; i < properties->len; i++) {
- const gchar * val = indicate_indicator_get_property(indicator, g_ptr_array_index(properties, i));
- if (val != NULL) {
- g_ptr_array_add(array, g_strdup(val));
- } else {
- g_ptr_array_add(array, g_strdup(""));
+ const GValue * ind_property = indicate_indicator_get_property_value(indicator, g_ptr_array_index(properties, i));
+
+ if (ind_property == NULL) {
+ continue;
}
+
+ GValue * value = g_new0(GValue, 1);
+ g_value_init(value, G_VALUE_TYPE(ind_property));
+ g_value_copy(ind_property, value);
+
+ g_ptr_array_add(array, value);
}
g_ptr_array_add(array, NULL);
*value = (gchar **)g_ptr_array_free(array, FALSE);
@@ -1339,7 +1350,7 @@
}
gboolean
-_indicate_server_get_indicator_property (IndicateServer * server, guint id, gchar * property, gchar ** value, GError **error)
+_indicate_server_get_indicator_property (IndicateServer * server, guint id, gchar * property, GValue * value, GError **error)
{
IndicateServerClass * class = INDICATE_SERVER_GET_CLASS(server);
=== modified file 'libindicate/server.h'
--- libindicate/server.h 2009-09-08 21:57:25 +0000
+++ libindicate/server.h 2010-02-01 06:36:18 +0000
@@ -150,7 +150,7 @@
/* Virtual Functions */
gboolean (*get_indicator_count) (IndicateServer * server, guint * count, GError **error);
gboolean (*get_indicator_list) (IndicateServer * server, GArray ** indicators, GError ** error);
- gboolean (*get_indicator_property) (IndicateServer * server, guint id, gchar * property, gchar ** value, GError **error);
+ gboolean (*get_indicator_property) (IndicateServer * server, guint id, gchar * property, GValue * value, GError **error);
gboolean (*get_indicator_property_group) (IndicateServer * server, guint id, GPtrArray * properties, gchar *** value, GError **error);
gboolean (*get_indicator_properties) (IndicateServer * server, guint id, gchar *** properties, GError **error);
gboolean (*show_indicator_to_user) (IndicateServer * server, guint id, GError ** error);
=== modified file 'tests/Makefile.am'
--- tests/Makefile.am 2009-12-10 15:13:43 +0000
+++ tests/Makefile.am 2010-02-01 06:36:18 +0000
@@ -37,6 +37,38 @@
$(LIBINDICATE_LIBS)
##########################
+# test properties
+##########################
+
+TESTS += test-properties
+check_PROGRAMS += test-properties-client test-properties-server
+
+test-properties: test-properties-client test-properties-server Makefile.am
+ @echo "#!/bin/sh" > $@
+ @echo "$(DBUS_RUNNER) --task ./test-properties-client --task-name Client --task ./test-properties-server --task-name Server" >> $@
+ @chmod +x $@
+
+test_properties_client_SOURCES = \
+ test-properties-client.c
+
+test_properties_client_CFLAGS = \
+ $(LIBINDICATE_CFLAGS) -I$(srcdir)/..
+
+test_properties_client_LDADD = \
+ ../libindicate/libindicate.la \
+ $(LIBINDICATE_LIBS)
+
+test_properties_server_SOURCES = \
+ test-properties-server.c
+
+test_properties_server_CFLAGS = \
+ $(LIBINDICATE_CFLAGS) -I$(srcdir)/..
+
+test_properties_server_LDADD = \
+ ../libindicate/libindicate.la \
+ $(LIBINDICATE_LIBS)
+
+##########################
# test interests
##########################
=== added file 'tests/test-properties-client.c'
--- tests/test-properties-client.c 1970-01-01 00:00:00 +0000
+++ tests/test-properties-client.c 2010-02-01 06:36:18 +0000
@@ -0,0 +1,36 @@
+
+#include <glib.h>
+#include "libindicate/indicator.h"
+
+static gboolean passed = TRUE;
+static GMainLoop * mainloop = NULL;
+
+static gboolean
+done_timeout_cb (gpointer data)
+{
+ g_debug("All done.");
+ g_main_loop_quit(mainloop);
+ return FALSE;
+}
+
+int
+main (int argc, char * argv)
+{
+ g_type_init();
+
+ IndicateIndicator * indicator = indicate_indicator_new();
+
+ indicate_indicator_set_property(indicator, "string-value", "my-value");
+ indicate_indicator_set_property_int(indicator, "int-value", 42);
+ indicate_indicator_set_property_bool(indicator, "bool-value", TRUE);
+ indicate_indicator_set_property_bool(indicator, "no-bool-value", FALSE);
+
+ indicate_indicator_show(indicator);
+
+ g_timeout_add_seconds(2, done_timeout_cb, indicator);
+
+ mainloop = g_main_loop_new(NULL, FALSE);
+ g_main_loop_run(mainloop);
+
+ return !passed;
+}
=== added file 'tests/test-properties-server.c'
--- tests/test-properties-server.c 1970-01-01 00:00:00 +0000
+++ tests/test-properties-server.c 2010-02-01 06:36:18 +0000
@@ -0,0 +1,95 @@
+
+#include <glib.h>
+#include "libindicate/listener.h"
+
+static gboolean passed = TRUE;
+static GMainLoop * mainloop = NULL;
+static gint tests = 0;
+
+static void
+string_cb (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * property, const gchar * propertydata, gpointer data)
+{
+ g_debug("Got string property '%s' value '%s'", property, propertydata);
+ if (g_strcmp0(propertydata, (gchar *)data)) {
+ passed = FALSE;
+ g_debug("\tExpecting '%s'", (gchar *)data);
+ }
+ tests--;
+ if (tests == 0) {
+ g_main_loop_quit(mainloop);
+ }
+ return;
+}
+
+static void
+int_cb (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * property, gint propertydata, gpointer data)
+{
+ g_debug("Got int property '%s' value '%d'", property, propertydata);
+ if (propertydata != GPOINTER_TO_INT(data)) {
+ passed = FALSE;
+ g_debug("\tExpecting '%d'", GPOINTER_TO_INT(data));
+ }
+ tests--;
+ if (tests == 0) {
+ g_main_loop_quit(mainloop);
+ }
+ return;
+}
+
+static void
+bool_cb (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * property, gboolean propertydata, gpointer data)
+{
+ g_debug("Got bool property '%s' value '%d'", property, propertydata);
+ if (propertydata != GPOINTER_TO_INT(data)) {
+ passed = FALSE;
+ g_debug("\tExpecting '%d'", GPOINTER_TO_INT(data));
+ }
+ tests--;
+ if (tests == 0) {
+ g_main_loop_quit(mainloop);
+ }
+ return;
+}
+
+static void
+indicator_added (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gpointer data)
+{
+ g_debug("Indicator Added: %s %d", INDICATE_LISTENER_SERVER_DBUS_NAME(server), indicate_listener_indicator_get_id(indicator));
+
+ indicate_listener_get_property(listener, server, indicator, "string-value", string_cb, "my-value");
+ tests++;
+ indicate_listener_get_property_int(listener, server, indicator, "int-value", int_cb, GINT_TO_POINTER(42));
+ tests++;
+ indicate_listener_get_property_bool(listener, server, indicator, "bool-value", bool_cb, GINT_TO_POINTER(TRUE));
+ tests++;
+ indicate_listener_get_property_bool(listener, server, indicator, "no-bool-value", bool_cb, GINT_TO_POINTER(FALSE));
+ tests++;
+
+ return;
+}
+
+static gboolean
+failed_cb (gpointer data)
+{
+ g_debug("Failed to get a server in 5 seconds.");
+ passed = FALSE;
+ g_main_loop_quit(mainloop);
+ return FALSE;
+}
+
+int
+main (int argc, char * argv)
+{
+ g_type_init();
+
+ IndicateListener * listener = indicate_listener_ref_default();
+
+ g_signal_connect(listener, INDICATE_LISTENER_SIGNAL_INDICATOR_ADDED, G_CALLBACK(indicator_added), NULL);
+
+ g_timeout_add_seconds(5, failed_cb, NULL);
+
+ mainloop = g_main_loop_new(NULL, FALSE);
+ g_main_loop_run(mainloop);
+
+ return !passed;
+}
Follow ups