From: <svn...@op...> - 2009-06-23 15:15:54
|
Author: bellmich Date: Tue Jun 23 17:15:30 2009 New Revision: 1114 URL: http://libsyncml.opensync.org/changeset/1114 Log: - added tests for SmlDevInfDataStore - fixed API flaws uncovered by the tests of SmlDevInfDataStore Added: trunk/tests/check_dev_inf_data_store.c Modified: trunk/libsyncml/data_sync_api/data_sync_devinf.c trunk/libsyncml/dev_inf_api/sml_dev_inf_data_store.c trunk/libsyncml/dev_inf_api/sml_dev_inf_data_store.h trunk/libsyncml/parser/sml_xml_parse.c trunk/tests/CMakeLists.txt trunk/tests/support.h Modified: trunk/libsyncml/data_sync_api/data_sync_devinf.c ============================================================================== --- trunk/libsyncml/data_sync_api/data_sync_devinf.c Tue Jun 23 17:13:55 2009 (r1113) +++ trunk/libsyncml/data_sync_api/data_sync_devinf.c Tue Jun 23 17:15:30 2009 (r1114) @@ -511,7 +511,8 @@ ctype = sml_dev_inf_content_type_new(cttype, verct, &gerror); \ if (!ctype) \ goto error; \ - sml_dev_inf_data_store_set_rx_pref(ds, ctype); \ + if (!sml_dev_inf_data_store_set_rx_pref(ds, ctype, &gerror)) \ + goto error; \ g_object_unref(ctype); \ ctype = NULL; @@ -519,7 +520,8 @@ ctype = sml_dev_inf_content_type_new(cttype, verct, &gerror); \ if (!ctype) \ goto error; \ - sml_dev_inf_data_store_set_tx_pref(ds, ctype); \ + if (!sml_dev_inf_data_store_set_tx_pref(ds, ctype, &gerror)) \ + goto error; \ g_object_unref(ctype); \ ctype = NULL; @@ -617,11 +619,12 @@ sml_dev_inf_data_store_set_sync_cap(ds, SML_DEVINF_SYNCTYPE_SLOW_SYNC, TRUE); // server alerted sync means that the client has to interpret alerts !!! // FIXME: we receive alerts but we do nothing with it - if (smlDsServerGetServerType(datastore->server) == SML_DS_CLIENT) + if (smlDsServerGetServerType(datastore->server) == SML_DS_CLIENT) { // smlDevInfDataStoreSetSyncCap(ds, SML_DEVINF_SYNCTYPE_ONE_WAY_FROM_CLIENT, TRUE); smlTrace(TRACE_INTERNAL, "%s: SyncML clients only support SLOW and TWO WAY SYNC", __func__); - else + } else { sml_dev_inf_data_store_set_sync_cap(ds, SML_DEVINF_SYNCTYPE_SERVER_ALERTED_SYNC, TRUE); + } smlDevInfAddDataStore(devinf, ds); smlTrace(TRACE_EXIT, "%s - content type newly added to devinf", __func__); Modified: trunk/libsyncml/dev_inf_api/sml_dev_inf_data_store.c ============================================================================== --- trunk/libsyncml/dev_inf_api/sml_dev_inf_data_store.c Tue Jun 23 17:13:55 2009 (r1113) +++ trunk/libsyncml/dev_inf_api/sml_dev_inf_data_store.c Tue Jun 23 17:15:30 2009 (r1114) @@ -162,6 +162,26 @@ static void sml_dev_inf_data_store_finalize (GObject *object) { + SmlDevInfDataStore *self = (SmlDevInfDataStore *) object; + g_free(self->priv->source_ref); + g_free(self->priv->display_name); + g_object_unref(self->priv->rx_pref); + g_object_unref(self->priv->tx_pref); + while(self->priv->rx) { + SmlDevInfContentType *ct = self->priv->rx->data; + self->priv->rx = g_list_remove(self->priv->rx, ct); + g_object_unref(ct); + } + while(self->priv->tx) { + SmlDevInfContentType *ct = self->priv->tx->data; + self->priv->tx = g_list_remove(self->priv->tx, ct); + g_object_unref(ct); + } + /* all pointers must be NULL */ + self->priv->source_ref = NULL; + self->priv->display_name = NULL; + self->priv->rx_pref = NULL; + self->priv->tx_pref = NULL; G_OBJECT_CLASS (sml_dev_inf_data_store_parent_class)->finalize (object); } @@ -499,17 +519,21 @@ * * Sets the property. */ -void +gboolean sml_dev_inf_data_store_set_rx_pref (SmlDevInfDataStore *self, - SmlDevInfContentType* rx_pref) + SmlDevInfContentType* rx_pref, + GError **error) { - g_return_if_fail (SML_IS_DEV_INF_DATA_STORE (self)); - g_return_if_fail (SML_IS_DEV_INF_CONTENT_TYPE (rx_pref)); + CHECK_ERROR_REF + sml_return_val_error_if_fail (SML_IS_DEV_INF_DATA_STORE (self), FALSE, error, SML_ERROR_GENERIC, "There is no SmlDevInfDataStore object."); + sml_return_val_error_if_fail (rx_pref, FALSE, error, SML_ERROR_GENERIC, "The SmlDevInfContentType object is missing."); + sml_return_val_error_if_fail (SML_IS_DEV_INF_CONTENT_TYPE (rx_pref), FALSE, error, SML_ERROR_GENERIC, "The RxPref parameter must be a SmlDevInfContentType object."); if (self->priv->rx_pref) g_object_unref (self->priv->rx_pref); g_object_ref (rx_pref); self->priv->rx_pref = rx_pref; + return TRUE; } /** @@ -534,17 +558,21 @@ * * Sets the property. */ -void +gboolean sml_dev_inf_data_store_set_tx_pref (SmlDevInfDataStore *self, - SmlDevInfContentType* tx_pref) + SmlDevInfContentType* tx_pref, + GError **error) { - g_return_if_fail (SML_IS_DEV_INF_DATA_STORE (self)); - g_return_if_fail (SML_IS_DEV_INF_CONTENT_TYPE (tx_pref)); + CHECK_ERROR_REF + sml_return_val_error_if_fail (SML_IS_DEV_INF_DATA_STORE (self), FALSE, error, SML_ERROR_GENERIC, "There is no SmlDevInfDataStore object."); + sml_return_val_error_if_fail (tx_pref, FALSE, error, SML_ERROR_GENERIC, "The SmlDevInfContentType object is missing."); + sml_return_val_error_if_fail (SML_IS_DEV_INF_CONTENT_TYPE (tx_pref), FALSE, error, SML_ERROR_GENERIC, "The TxPref parameter must be a SmlDevInfContentType object."); if (self->priv->tx_pref) g_object_unref (self->priv->tx_pref); g_object_ref (tx_pref); self->priv->tx_pref = tx_pref; + return TRUE; } /** @@ -750,6 +778,12 @@ SmlDevInfSyncCap sync_cap) { g_return_val_if_fail (SML_IS_DEV_INF_DATA_STORE (self), FALSE); + + /* If no SyncCap is set then the SyncCap is unknown. */ + if (sync_cap == SML_DEVINF_SYNCTYPE_UNKNOWN && + self->priv->sync_cap == SML_DEVINF_SYNCTYPE_UNKNOWN) + return TRUE; + return self->priv->sync_cap & sync_cap ? TRUE : FALSE; } @@ -766,10 +800,21 @@ gboolean supported) { g_return_if_fail (SML_IS_DEV_INF_DATA_STORE (self)); - if (supported) - self->priv->sync_cap = self->priv->sync_cap | sync_cap; - else - self->priv->sync_cap = self->priv->sync_cap & ~sync_cap; + + if (sync_cap == SML_DEVINF_SYNCTYPE_UNKNOWN) { + if (supported) { + self->priv->sync_cap = 0; + } else { + /* Ignore but warn on senseless configuration ... */ + g_warning("You cannot disabled an unknown SyncCap in a data store of the device information."); + } + } else { + if (supported) { + self->priv->sync_cap = self->priv->sync_cap | sync_cap; + } else { + self->priv->sync_cap = self->priv->sync_cap & ~sync_cap; + } + } } /** @@ -805,15 +850,17 @@ /** * sml_dev_inf_data_store_is_compliant: * @self: A #SmlDevInfDataStore - * - * Gets the property. + * @error: A #GError + * + * This is the only function of this class where you have not to provide a pointer to the error parameter. + * If you only want to know if the data store is already compliant + * then you can ignore the error. * * Return value: */ gboolean sml_dev_inf_data_store_is_compliant (SmlDevInfDataStore *self, GError **error) { - CHECK_ERROR_REF sml_return_val_error_if_fail (SML_IS_DEV_INF_DATA_STORE (self), FALSE, error, SML_ERROR_GENERIC, "There is no SmlDevInfDataStore object."); sml_return_val_error_if_fail (self->priv->source_ref != NULL, FALSE, error, SML_ERROR_GENERIC, "The SourceRef must be set."); Modified: trunk/libsyncml/dev_inf_api/sml_dev_inf_data_store.h ============================================================================== --- trunk/libsyncml/dev_inf_api/sml_dev_inf_data_store.h Tue Jun 23 17:13:55 2009 (r1113) +++ trunk/libsyncml/dev_inf_api/sml_dev_inf_data_store.h Tue Jun 23 17:15:30 2009 (r1114) @@ -71,9 +71,9 @@ gsize sml_dev_inf_data_store_get_max_guid_size (SmlDevInfDataStore *self); void sml_dev_inf_data_store_set_max_guid_size (SmlDevInfDataStore *self, gsize max_guid_size); SmlDevInfContentType* sml_dev_inf_data_store_get_rx_pref (SmlDevInfDataStore *self); -void sml_dev_inf_data_store_set_rx_pref (SmlDevInfDataStore *self, SmlDevInfContentType* rx_pref); +gboolean sml_dev_inf_data_store_set_rx_pref (SmlDevInfDataStore *self, SmlDevInfContentType* rx_pref, GError **error); SmlDevInfContentType* sml_dev_inf_data_store_get_tx_pref (SmlDevInfDataStore *self); -void sml_dev_inf_data_store_set_tx_pref (SmlDevInfDataStore *self, SmlDevInfContentType* tx_pref); +gboolean sml_dev_inf_data_store_set_tx_pref (SmlDevInfDataStore *self, SmlDevInfContentType* tx_pref, GError **error); gsize sml_dev_inf_data_store_get_max_id (SmlDevInfDataStore *self); void sml_dev_inf_data_store_set_max_id (SmlDevInfDataStore *self, gsize max_id); gsize sml_dev_inf_data_store_get_max_mem (SmlDevInfDataStore *self); Modified: trunk/libsyncml/parser/sml_xml_parse.c ============================================================================== --- trunk/libsyncml/parser/sml_xml_parse.c Tue Jun 23 17:13:55 2009 (r1113) +++ trunk/libsyncml/parser/sml_xml_parse.c Tue Jun 23 17:15:30 2009 (r1114) @@ -2603,6 +2603,8 @@ CHECK_ERROR_REF smlAssert(parser); smlAssert(datastore); + + GError *gerror = NULL; while (1) { if (!_smlXmlParserStep(parser)) { @@ -2642,6 +2644,10 @@ return TRUE; error: + if (gerror) { + smlErrorSet(error, gerror->code, "%s", gerror->message); + g_error_free(gerror); + } smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error)); return FALSE; } @@ -3273,12 +3279,14 @@ if (!sml_dev_inf_data_store_add_tx(datastore, ct, &gerror)) goto error; } else if (!strcmp(SML_ELEMENT_RXPREF, element)) { - sml_dev_inf_data_store_set_rx_pref(datastore, ct); + if (!sml_dev_inf_data_store_set_rx_pref(datastore, ct, &gerror)) + goto error; } else if (!strcmp(SML_ELEMENT_TX, element)) { if (!sml_dev_inf_data_store_add_tx(datastore, ct, &gerror)) goto error; } else if (!strcmp(SML_ELEMENT_TXPREF, element)) { - sml_dev_inf_data_store_set_tx_pref(datastore, ct); + if (!sml_dev_inf_data_store_set_tx_pref(datastore, ct, &gerror)) + goto error; } else { smlErrorSet(error, SML_ERROR_GENERIC, "The element %s is an unknown Rx/Tx element.", element); goto error; Modified: trunk/tests/CMakeLists.txt ============================================================================== --- trunk/tests/CMakeLists.txt Tue Jun 23 17:13:55 2009 (r1113) +++ trunk/tests/CMakeLists.txt Tue Jun 23 17:15:30 2009 (r1114) @@ -253,7 +253,7 @@ SML_ADD_TESTCASE( san_parse_error7 ) SML_END_TEST() - SML_START_TEST( "DevInf" devinf check_devinf.c ${TEST_TARGET_LIBRARIES} ) + SML_START_TEST( "DevInfHelper" devinf check_devinf.c ${TEST_TARGET_LIBRARIES} ) IF( ENABLE_HTTP ) SML_ADD_TESTCASE( devinf_crash ) SML_ADD_TESTCASE( devinf_result ) @@ -296,6 +296,16 @@ SML_ADD_TESTCASE( dev_inf_ctcap_references ) SML_END_TEST() + SML_START_TEST( "DevInfDataStore" dev_inf_data_store check_dev_inf_data_store.c ${TEST_TARGET_LIBRARIES} ) + SML_ADD_TESTCASE( dev_inf_data_store_create ) + SML_ADD_TESTCASE( dev_inf_data_store_empty_set ) + SML_ADD_TESTCASE( dev_inf_data_store_empty_get ) + SML_ADD_TESTCASE( dev_inf_data_store_filled_set ) + SML_ADD_TESTCASE( dev_inf_data_store_filled_get ) + SML_ADD_TESTCASE( dev_inf_data_store_compliance ) + SML_ADD_TESTCASE( dev_inf_data_store_references ) + SML_END_TEST() + SML_START_TEST( "Sync" sync check_sync.c ${TEST_TARGET_LIBRARIES} ) IF ( ENABLE_HTTP ) SML_ADD_TESTCASE( sync_multi_start ) Added: trunk/tests/check_dev_inf_data_store.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ trunk/tests/check_dev_inf_data_store.c Tue Jun 23 17:15:30 2009 (r1114) @@ -0,0 +1,496 @@ +/* + * libsyncml - A syncml protocol implementation + * Copyright (C) 2009 Michael Bell <mic...@op...> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "tests/support.h" + +#include <libsyncml/dev_inf_api/sml_dev_inf_data_store.h> + +/* +is_compliant => separat + +source_ref +rx/tx/_pref +properpties + hierarchical sync + memory management max_id, mex_mem, shared_mem + sync_cap + display_nae + max_guid +*/ + +START_TEST (dev_inf_data_store_create) +{ + GError *error = NULL; + SmlDevInfDataStore *datastore = sml_dev_inf_data_store_new(NULL, &error); + sml_fail_unless(datastore == NULL, "The source reference must be set."); + sml_fail_unless(error != NULL, "The error must be set on failure."); + g_error_free(error); + error = NULL; + + datastore = sml_dev_inf_data_store_new("contacts", &error); + sml_fail_unless(datastore != NULL, "%s", error?error->message:"No GError set."); + g_object_unref(datastore); +} +END_TEST + +START_TEST (dev_inf_data_store_empty_set) +{ + GError *error = NULL; + SmlDevInfDataStore *datastore = sml_dev_inf_data_store_new("Contacts", &error); + sml_fail_unless(datastore != NULL, NULL); + + /* enforce SourceRef name */ + + sml_fail_unless(sml_dev_inf_data_store_set_source_ref(datastore, NULL, &error) == FALSE, "A data store must have a SourceRef."); + sml_fail_unless(error != NULL, "The error must be set if an error appears."); + g_error_free(error); + error = NULL; + + sml_fail_unless(sml_dev_inf_data_store_set_source_ref(datastore, "", &error) == FALSE, "A data store must have a SourceRef."); + sml_fail_unless(error != NULL, "The error must be set if an error appears."); + g_error_free(error); + error = NULL; + + /* the following parameters can be NULL or 0 */ + + sml_fail_unless(sml_dev_inf_data_store_set_display_name(datastore, NULL, &error), "%s", error?error->message:"No GError set."); + sml_dev_inf_data_store_set_max_guid_size(datastore, 0); + sml_dev_inf_data_store_set_max_id(datastore, 0); + sml_dev_inf_data_store_set_supports_hierarchical_sync(datastore, TRUE); + sml_dev_inf_data_store_set_supports_hierarchical_sync(datastore, FALSE); + + /* The unknown SyncCap removes all configured SyncCaps. */ + + sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_UNKNOWN, TRUE); + sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_UNKNOWN, FALSE); + + /* RxPref/TxPref must be set */ + + sml_fail_unless(sml_dev_inf_data_store_set_rx_pref(datastore, NULL, &error) == FALSE, "A data store must have a RxPref."); + sml_fail_unless(error != NULL, "The error must be set if an error appears."); + g_error_free(error); + error = NULL; + + sml_fail_unless(sml_dev_inf_data_store_set_tx_pref(datastore, NULL, &error) == FALSE, "A data store must have a TxPref."); + sml_fail_unless(error != NULL, "The error must be set if an error appears."); + g_error_free(error); + error = NULL; + + /* Rx/Tx does not accept empty values */ + + sml_fail_unless(sml_dev_inf_data_store_add_rx(datastore, NULL, &error) == FALSE, "Rx content type must be not empty."); + sml_fail_unless(error != NULL, "The error must be set if an error appears."); + g_error_free(error); + error = NULL; + + sml_fail_unless(sml_dev_inf_data_store_add_tx(datastore, NULL, &error) == FALSE, "Tx content type must be not empty."); + sml_fail_unless(error != NULL, "The error must be set if an error appears."); + g_error_free(error); + error = NULL; + + g_object_unref(datastore); +} +END_TEST + +START_TEST (dev_inf_data_store_empty_get) +{ + GError *error = NULL; + SmlDevInfDataStore *datastore = sml_dev_inf_data_store_new("Contacts", &error); + sml_fail_unless(datastore != NULL, NULL); + + SmlDevInfContentType *ct = sml_dev_inf_content_type_new("text/x-vcard", "2.1", &error); + sml_fail_unless(ct != NULL, "%s", error?error->message:"No GError set."); + + /* enforce SourceRef name */ + + sml_fail_unless(sml_dev_inf_data_store_set_source_ref(datastore, NULL, &error) == FALSE, "A data store must have a SourceRef."); + sml_fail_unless(error != NULL, "The error must be set if an error appears."); + g_error_free(error); + error = NULL; + const gchar *source_ref = sml_dev_inf_data_store_get_source_ref(datastore); + sml_fail_unless(source_ref != NULL, "The SourceRef must always be available."); + sml_fail_unless(strcmp(source_ref, "Contacts") == 0, "The original SourceRef was damaged."); + + /* the following parameters can be NULL or 0 */ + + sml_fail_unless(sml_dev_inf_data_store_get_display_name(datastore) == NULL, "The default display name is empty."); + sml_fail_unless(sml_dev_inf_data_store_set_display_name(datastore, NULL, &error), "%s", error?error->message:"No GError set."); + sml_fail_unless(sml_dev_inf_data_store_get_display_name(datastore) == NULL, "The default display name was overwritten."); + + sml_fail_unless(sml_dev_inf_data_store_get_max_guid_size(datastore) == 0, "The default MaxGUIDSize is 0."); + sml_dev_inf_data_store_set_max_guid_size(datastore, 0); + sml_fail_unless(sml_dev_inf_data_store_get_max_guid_size(datastore) == 0, "The default MaxGUIDSize was overwritten"); + + sml_fail_unless(sml_dev_inf_data_store_get_max_id(datastore) == 0, "The default MaxID is 0."); + sml_dev_inf_data_store_set_max_id(datastore, 0); + sml_fail_unless(sml_dev_inf_data_store_get_max_id(datastore) == 0, "The default MaxID was overwritten"); + + sml_fail_unless(sml_dev_inf_data_store_get_supports_hierarchical_sync(datastore) == FALSE, "The default SupportsHierarchicalSync is FALSE."); + sml_dev_inf_data_store_set_supports_hierarchical_sync(datastore, TRUE); + sml_fail_unless(sml_dev_inf_data_store_get_supports_hierarchical_sync(datastore) == TRUE, "SupportsHierarchicalSync must be TRUE."); + sml_dev_inf_data_store_set_supports_hierarchical_sync(datastore, FALSE); + sml_fail_unless(sml_dev_inf_data_store_get_supports_hierarchical_sync(datastore) == FALSE, "SupportsHierarchicalSync must be FALSE."); + + /* The unknown SyncCap is set if no other SynCap is set. */ + + sml_fail_unless(sml_dev_inf_data_store_get_sync_cap(datastore, SML_DEVINF_SYNCTYPE_UNKNOWN) == TRUE, "The default SyncCap is no SyncCap."); + sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_UNKNOWN, TRUE); + sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_UNKNOWN, FALSE); + sml_fail_unless(sml_dev_inf_data_store_get_sync_cap(datastore, SML_DEVINF_SYNCTYPE_UNKNOWN) == TRUE, "The default SyncCap was overwritten."); + + /* RxPref/TxPref must be set */ + + sml_fail_unless(sml_dev_inf_data_store_get_rx_pref(datastore) == NULL, "The default RxPref is NULL."); + sml_fail_unless(sml_dev_inf_data_store_set_rx_pref(datastore, NULL, &error) == FALSE, "A data store must have a RxPref."); + sml_fail_unless(error != NULL, "The error must be set if an error appears."); + g_error_free(error); + error = NULL; + sml_fail_unless(sml_dev_inf_data_store_get_rx_pref(datastore) == NULL, "The default RxPref is NULL."); + sml_fail_unless(sml_dev_inf_data_store_set_rx_pref(datastore, ct, &error) == TRUE, "%s", error?error->message:"No GError set."); + sml_fail_unless(sml_dev_inf_data_store_get_rx_pref(datastore) == ct, "The RxPref was not set correctly."); + sml_fail_unless(sml_dev_inf_data_store_set_rx_pref(datastore, NULL, &error) == FALSE, "A data store must have a RxPref."); + sml_fail_unless(error != NULL, "The error must be set if an error appears."); + g_error_free(error); + error = NULL; + sml_fail_unless(sml_dev_inf_data_store_get_rx_pref(datastore) == ct, "The RxPref was overwritten."); + + sml_fail_unless(sml_dev_inf_data_store_get_tx_pref(datastore) == NULL, "The default TxPref is NULL."); + sml_fail_unless(sml_dev_inf_data_store_set_tx_pref(datastore, NULL, &error) == FALSE, "A data store must have a TxPref."); + sml_fail_unless(error != NULL, "The error must be set if an error appears."); + g_error_free(error); + error = NULL; + sml_fail_unless(sml_dev_inf_data_store_get_tx_pref(datastore) == NULL, "The default TxPref is NULL."); + sml_fail_unless(sml_dev_inf_data_store_set_tx_pref(datastore, ct, &error) == TRUE, "%s", error?error->message:"No GError set."); + sml_fail_unless(sml_dev_inf_data_store_get_tx_pref(datastore) == ct, "The TxPref was not set correctly."); + sml_fail_unless(sml_dev_inf_data_store_set_tx_pref(datastore, NULL, &error) == FALSE, "A data store must have a TxPref."); + sml_fail_unless(error != NULL, "The error must be set if an error appears."); + g_error_free(error); + error = NULL; + sml_fail_unless(sml_dev_inf_data_store_get_tx_pref(datastore) == ct, "The TxPref was overwritten."); + + /* Rx/Tx does not accept empty values */ + + sml_fail_unless(sml_dev_inf_data_store_num_rx(datastore) == 0, "The default Rx list is empty."); + sml_fail_unless(sml_dev_inf_data_store_add_rx(datastore, NULL, &error) == FALSE, "Rx content type must be not empty."); + sml_fail_unless(error != NULL, "The error must be set if an error appears."); + g_error_free(error); + error = NULL; + sml_fail_unless(sml_dev_inf_data_store_num_rx(datastore) == 0, "The default Rx list must be still empty."); + sml_fail_unless(sml_dev_inf_data_store_add_rx(datastore, ct, &error) == TRUE, "%s", error?error->message:"No GError set."); + sml_fail_unless(sml_dev_inf_data_store_num_rx(datastore) == 1, "There is a new content type in the Rx list."); + sml_fail_unless(sml_dev_inf_data_store_add_rx(datastore, NULL, &error) == FALSE, "Rx content type must be not empty."); + sml_fail_unless(error != NULL, "The error must be set if an error appears."); + g_error_free(error); + error = NULL; + sml_fail_unless(sml_dev_inf_data_store_num_rx(datastore) == 1, "There is still one content type in the Rx list."); + + sml_fail_unless(sml_dev_inf_data_store_num_tx(datastore) == 0, "The default Tx list is empty."); + sml_fail_unless(sml_dev_inf_data_store_add_tx(datastore, NULL, &error) == FALSE, "Tx content type must be not empty."); + sml_fail_unless(error != NULL, "The error must be set if an error appears."); + g_error_free(error); + error = NULL; + sml_fail_unless(sml_dev_inf_data_store_num_tx(datastore) == 0, "The default Tx list must be still empty."); + sml_fail_unless(sml_dev_inf_data_store_add_tx(datastore, ct, &error) == TRUE, "%s", error?error->message:"No GError set."); + sml_fail_unless(sml_dev_inf_data_store_num_tx(datastore) == 1, "There is a new content type in the Tx list."); + sml_fail_unless(sml_dev_inf_data_store_add_tx(datastore, NULL, &error) == FALSE, "Tx content type must be not empty."); + sml_fail_unless(error != NULL, "The error must be set if an error appears."); + g_error_free(error); + error = NULL; + sml_fail_unless(sml_dev_inf_data_store_num_tx(datastore) == 1, "There is still one content type in the Tx list."); + + g_object_unref(ct); + g_object_unref(datastore); +} +END_TEST + +START_TEST (dev_inf_data_store_filled_set) +{ + GError *error = NULL; + SmlDevInfDataStore *datastore = sml_dev_inf_data_store_new("Contacts", &error); + sml_fail_unless(datastore != NULL, NULL); + + SmlDevInfContentType *ct = sml_dev_inf_content_type_new("text/x-vcard", "2.1", &error); + sml_fail_unless(ct != NULL, "%s", error?error->message:"No GError set."); + + /* enforce SourceRef name */ + + sml_fail_unless(sml_dev_inf_data_store_set_source_ref(datastore, "AddressBook", &error), "%s", error?error->message:"No GError set."); + sml_fail_unless(sml_dev_inf_data_store_set_source_ref(datastore, NULL, &error) == FALSE, "A data store must have a SourceRef."); + sml_fail_unless(error != NULL, "The error must be set if an error appears."); + g_error_free(error); + error = NULL; + + /* the following parameters can be NULL or 0 */ + + sml_fail_unless(sml_dev_inf_data_store_set_display_name(datastore, "address book", &error), "%s", error?error->message:"No GError set."); + + sml_dev_inf_data_store_set_max_guid_size(datastore, 128); + sml_dev_inf_data_store_set_max_guid_size(datastore, 0); + + sml_dev_inf_data_store_set_max_id(datastore, 1000000000); + sml_dev_inf_data_store_set_max_id(datastore, 0); + + sml_dev_inf_data_store_set_supports_hierarchical_sync(datastore, TRUE); + sml_dev_inf_data_store_set_supports_hierarchical_sync(datastore, FALSE); + + /* The unknown SyncCap is set if no other SynCap is set. */ + + sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_TWO_WAY, TRUE); + sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_SLOW_SYNC, TRUE); + sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_TWO_WAY, FALSE); + sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_UNKNOWN, FALSE); /* has no effect */ + sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_UNKNOWN, TRUE); /* deletes all SyncCaps */ + + /* RxPref/TxPref must be set */ + + sml_fail_unless(sml_dev_inf_data_store_set_rx_pref(datastore, ct, &error) == TRUE, "%s", error?error->message:"No GError set."); + sml_fail_unless(sml_dev_inf_data_store_set_tx_pref(datastore, ct, &error) == TRUE, "%s", error?error->message:"No GError set."); + + /* Rx/Tx does not accept empty values */ + + sml_fail_unless(sml_dev_inf_data_store_add_rx(datastore, ct, &error) == TRUE, "%s", error?error->message:"No GError set."); + sml_fail_unless(sml_dev_inf_data_store_add_rx(datastore, NULL, &error) == FALSE, "Rx content type must be not empty."); + sml_fail_unless(error != NULL, "The error must be set if an error appears."); + g_error_free(error); + error = NULL; + sml_fail_unless(sml_dev_inf_data_store_add_rx(datastore, ct, &error) == TRUE, "%s", error?error->message:"No GError set."); + + sml_fail_unless(sml_dev_inf_data_store_add_tx(datastore, ct, &error) == TRUE, "%s", error?error->message:"No GError set."); + sml_fail_unless(sml_dev_inf_data_store_add_tx(datastore, NULL, &error) == FALSE, "Tx content type must be not empty."); + sml_fail_unless(error != NULL, "The error must be set if an error appears."); + g_error_free(error); + error = NULL; + sml_fail_unless(sml_dev_inf_data_store_add_tx(datastore, ct, &error) == TRUE, "%s", error?error->message:"No GError set."); + + g_object_unref(ct); + g_object_unref(datastore); +} +END_TEST + +START_TEST (dev_inf_data_store_filled_get) +{ + GError *error = NULL; + SmlDevInfDataStore *datastore = sml_dev_inf_data_store_new("Contacts", &error); + sml_fail_unless(datastore != NULL, NULL); + + SmlDevInfContentType *ct = sml_dev_inf_content_type_new("text/x-vcard", "2.1", &error); + sml_fail_unless(ct != NULL, "%s", error?error->message:"No GError set."); + + /* enforce SourceRef name */ + + sml_fail_unless(sml_dev_inf_data_store_set_source_ref(datastore, "AddressBook", &error), "%s", error?error->message:"No GError set."); + const gchar *source_ref = sml_dev_inf_data_store_get_source_ref(datastore); + sml_fail_unless(source_ref != NULL, "The SourceRef must always be available."); + sml_fail_unless(strcmp(source_ref, "AddressBook") == 0, "The SourceRef was not copied correctly."); + + sml_fail_unless(sml_dev_inf_data_store_set_source_ref(datastore, NULL, &error) == FALSE, "A data store must have a SourceRef."); + sml_fail_unless(error != NULL, "The error must be set if an error appears."); + g_error_free(error); + error = NULL; + source_ref = sml_dev_inf_data_store_get_source_ref(datastore); + sml_fail_unless(source_ref != NULL, "The SourceRef was erased."); + sml_fail_unless(strcmp(source_ref, "AddressBook") == 0, "The SourceRef was overwritten."); + + /* the following parameters can be NULL or 0 */ + + sml_fail_unless(sml_dev_inf_data_store_set_display_name(datastore, "address book", &error), "%s", error?error->message:"No GError set."); + const gchar *display_name = sml_dev_inf_data_store_get_display_name(datastore); + sml_fail_unless(display_name != NULL, "The DisplayName was erased."); + sml_fail_unless(strcmp(display_name, "address book") == 0, "The DisplayName was not copied correctly."); + + sml_dev_inf_data_store_set_max_guid_size(datastore, 128); + sml_fail_unless(sml_dev_inf_data_store_get_max_guid_size(datastore) == 128, "The MaxGUIDSize was not copied correctly."); + sml_dev_inf_data_store_set_max_guid_size(datastore, 0); + sml_fail_unless(sml_dev_inf_data_store_get_max_guid_size(datastore) == 0, "The MaxGUIDSize was not copied correctly."); + + sml_dev_inf_data_store_set_max_id(datastore, 1000000000); + sml_fail_unless(sml_dev_inf_data_store_get_max_id(datastore) == 1000000000, "The MaxID was not copied correctly."); + sml_dev_inf_data_store_set_max_id(datastore, 0); + sml_fail_unless(sml_dev_inf_data_store_get_max_id(datastore) == 0, "The MaxID was not copied correctly."); + + sml_dev_inf_data_store_set_supports_hierarchical_sync(datastore, TRUE); + sml_fail_unless(sml_dev_inf_data_store_get_supports_hierarchical_sync(datastore) == TRUE, "SupportsHierarchicalSync must be TRUE."); + sml_dev_inf_data_store_set_supports_hierarchical_sync(datastore, FALSE); + sml_fail_unless(sml_dev_inf_data_store_get_supports_hierarchical_sync(datastore) == FALSE, "SupportsHierarchicalSync must be FALSE."); + + /* The unknown SyncCap is set if no other SynCap is set. */ + + sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_TWO_WAY, TRUE); + sml_fail_unless(sml_dev_inf_data_store_get_sync_cap(datastore, SML_DEVINF_SYNCTYPE_TWO_WAY) == TRUE, "The Two-Way SyncCap was lost."); + sml_fail_unless(sml_dev_inf_data_store_get_sync_cap(datastore, SML_DEVINF_SYNCTYPE_UNKNOWN) == FALSE, "There must be a Two-Way SyncCap."); + + sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_SLOW_SYNC, TRUE); + sml_fail_unless(sml_dev_inf_data_store_get_sync_cap(datastore, SML_DEVINF_SYNCTYPE_SLOW_SYNC) == TRUE, "The Slow-Sync SyncCap was lost."); + sml_fail_unless(sml_dev_inf_data_store_get_sync_cap(datastore, SML_DEVINF_SYNCTYPE_TWO_WAY) == TRUE, "The Two-Way SyncCap was lost."); + sml_fail_unless(sml_dev_inf_data_store_get_sync_cap(datastore, SML_DEVINF_SYNCTYPE_UNKNOWN) == FALSE, "There must be two SyncCaps."); + + sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_TWO_WAY, FALSE); + sml_fail_unless(sml_dev_inf_data_store_get_sync_cap(datastore, SML_DEVINF_SYNCTYPE_TWO_WAY) == FALSE, "The Two-Way SyncCap was not removed."); + sml_fail_unless(sml_dev_inf_data_store_get_sync_cap(datastore, SML_DEVINF_SYNCTYPE_SLOW_SYNC) == TRUE, "The Slow-Sync SyncCap was lost."); + sml_fail_unless(sml_dev_inf_data_store_get_sync_cap(datastore, SML_DEVINF_SYNCTYPE_UNKNOWN) == FALSE, "There must be a Slow-Sync SyncCap."); + + sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_UNKNOWN, FALSE); /* has no effect */ + sml_fail_unless(sml_dev_inf_data_store_get_sync_cap(datastore, SML_DEVINF_SYNCTYPE_SLOW_SYNC) == TRUE, "The Slow-Sync SyncCap was lost."); + sml_fail_unless(sml_dev_inf_data_store_get_sync_cap(datastore, SML_DEVINF_SYNCTYPE_UNKNOWN) == FALSE, "There must be a Slow-Sync SyncCap."); + + sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_UNKNOWN, TRUE); /* deletes all SyncCaps */ + sml_fail_unless(sml_dev_inf_data_store_get_sync_cap(datastore, SML_DEVINF_SYNCTYPE_SLOW_SYNC) == FALSE, "The Slow-Sync SyncCap was not removed."); + sml_fail_unless(sml_dev_inf_data_store_get_sync_cap(datastore, SML_DEVINF_SYNCTYPE_UNKNOWN) == TRUE, "The default SyncCap was restored."); + + /* RxPref/TxPref must be set */ + + sml_fail_unless(sml_dev_inf_data_store_set_rx_pref(datastore, ct, &error) == TRUE, "%s", error?error->message:"No GError set."); + sml_fail_unless(sml_dev_inf_data_store_get_rx_pref(datastore) == ct, "The RxPref was not set correctly."); + + sml_fail_unless(sml_dev_inf_data_store_set_tx_pref(datastore, ct, &error) == TRUE, "%s", error?error->message:"No GError set."); + sml_fail_unless(sml_dev_inf_data_store_get_tx_pref(datastore) == ct, "The TxPref was not set correctly."); + + /* Rx/Tx does not accept empty values */ + + sml_fail_unless(sml_dev_inf_data_store_add_rx(datastore, ct, &error) == TRUE, "%s", error?error->message:"No GError set."); + sml_fail_unless(sml_dev_inf_data_store_num_rx(datastore) == 1, "There is a new content type in the Rx list."); + sml_fail_unless(sml_dev_inf_data_store_add_rx(datastore, NULL, &error) == FALSE, "Rx content type must be not empty."); + sml_fail_unless(error != NULL, "The error must be set if an error appears."); + g_error_free(error); + error = NULL; + sml_fail_unless(sml_dev_inf_data_store_num_rx(datastore) == 1, "There is still one content type in the Rx list."); + sml_fail_unless(sml_dev_inf_data_store_add_rx(datastore, ct, &error) == TRUE, "%s", error?error->message:"No GError set."); + sml_fail_unless(sml_dev_inf_data_store_num_rx(datastore) == 2, "There are two content types in the Rx list."); + + sml_fail_unless(sml_dev_inf_data_store_add_tx(datastore, ct, &error) == TRUE, "%s", error?error->message:"No GError set."); + sml_fail_unless(sml_dev_inf_data_store_num_tx(datastore) == 1, "There is a new content type in the Tx list."); + sml_fail_unless(sml_dev_inf_data_store_add_tx(datastore, NULL, &error) == FALSE, "Tx content type must be not empty."); + sml_fail_unless(error != NULL, "The error must be set if an error appears."); + g_error_free(error); + error = NULL; + sml_fail_unless(sml_dev_inf_data_store_num_tx(datastore) == 1, "There is still one content type in the Tx list."); + sml_fail_unless(sml_dev_inf_data_store_add_tx(datastore, ct, &error) == TRUE, "%s", error?error->message:"No GError set."); + sml_fail_unless(sml_dev_inf_data_store_num_tx(datastore) == 2, "There are two content types in the Tx list."); + + g_object_unref(ct); + g_object_unref(datastore); +} +END_TEST + +START_TEST (dev_inf_data_store_compliance) +{ + GError *error = NULL; + SmlDevInfDataStore *datastore = sml_dev_inf_data_store_new("Contacts", &error); + sml_fail_unless(datastore != NULL, NULL); + + SmlDevInfContentType *ct = sml_dev_inf_content_type_new("text/x-vcard", "2.1", &error); + sml_fail_unless(ct != NULL, "%s", error?error->message:"No GError set."); + + /* The compliance function will be tested first + * always with the error paramater present. */ + + /* missing RxPref, TxPref and SyncCap */ + + sml_fail_unless(sml_dev_inf_data_store_is_compliant(datastore, &error) == FALSE, "RxPref, TxPref and one SyncCap are required."); + sml_fail_unless(error != NULL, "The error must be set if an error appears."); + g_error_free(error); + error = NULL; + + /* missing RxPref and TxPref */ + + sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_TWO_WAY, TRUE); + sml_fail_unless(sml_dev_inf_data_store_is_compliant(datastore, &error) == FALSE, "RxPref and TxPref are required."); + sml_fail_unless(error != NULL, "The error must be set if an error appears."); + g_error_free(error); + error = NULL; + + /* missing TxPref and SyncCap */ + + sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_UNKNOWN, TRUE); + sml_fail_unless(sml_dev_inf_data_store_set_rx_pref(datastore, ct, &error), "%s", error?error->message:"No GError set."); + sml_fail_unless(sml_dev_inf_data_store_is_compliant(datastore, &error) == FALSE, "TxPref and one SyncCap are required."); + sml_fail_unless(error != NULL, "The error must be set if an error appears."); + g_error_free(error); + error = NULL; + + /* missing TxPref */ + + sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_TWO_WAY, TRUE); + sml_fail_unless(sml_dev_inf_data_store_is_compliant(datastore, &error) == FALSE, "TxPref is required."); + sml_fail_unless(error != NULL, "The error must be set if an error appears."); + g_error_free(error); + error = NULL; + + /* missing SyncCap */ + + sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_UNKNOWN, TRUE); + sml_fail_unless(sml_dev_inf_data_store_set_tx_pref(datastore, ct, &error), "%s", error?error->message:"No GError set."); + sml_fail_unless(sml_dev_inf_data_store_is_compliant(datastore, &error) == FALSE, "One SyncCap is required."); + sml_fail_unless(error != NULL, "The error must be set if an error appears."); + g_error_free(error); + error = NULL; + + /* correct */ + + sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_TWO_WAY, TRUE); + sml_fail_unless(sml_dev_inf_data_store_is_compliant(datastore, &error) == TRUE, "%s", error?error->message:"No GError set."); + + /* The compliance function will be tested now + * always without the error paramater. */ + + /* cleanup datastore because RxPref cannot be removed from the object */ + g_object_unref(datastore); + datastore = sml_dev_inf_data_store_new("Contacts", &error); + + /* missing RxPref and SyncCap */ + + sml_fail_unless(sml_dev_inf_data_store_set_tx_pref(datastore, ct, &error), "%s", error?error->message:"No GError set."); + sml_fail_unless(sml_dev_inf_data_store_is_compliant(datastore, NULL) == FALSE, "RxPref and one SyncCap are required."); + + /* missing RxPref */ + + sml_dev_inf_data_store_set_sync_cap(datastore, SML_DEVINF_SYNCTYPE_SLOW_SYNC, TRUE); + sml_fail_unless(sml_dev_inf_data_store_is_compliant(datastore, NULL) == FALSE, "RxPref is required."); + + /* correct */ + + sml_fail_unless(sml_dev_inf_data_store_set_rx_pref(datastore, ct, &error), "%s", error?error->message:"No GError set."); + sml_fail_unless(sml_dev_inf_data_store_is_compliant(datastore, NULL) == TRUE, "All requirements should be present."); + + g_object_unref(ct); + g_object_unref(datastore); +} +END_TEST + +START_TEST (dev_inf_data_store_references) +{ + GError *error = NULL; + SmlDevInfDataStore *datastore = sml_dev_inf_data_store_new("Contacts", &error); + sml_fail_unless(datastore != NULL, NULL); + + g_object_ref(datastore); + + sml_fail_unless(sml_dev_inf_data_store_get_source_ref(datastore) != NULL, "The source reference was not set."); + + g_object_unref(datastore); + + sml_fail_unless(sml_dev_inf_data_store_get_source_ref(datastore) != NULL, "The source reference is already cleaned up."); + + g_object_unref(datastore); +} +END_TEST + +@SML_TESTCASE_CODE@ + Modified: trunk/tests/support.h ============================================================================== --- trunk/tests/support.h Tue Jun 23 17:13:55 2009 (r1113) +++ trunk/tests/support.h Tue Jun 23 17:15:30 2009 (r1114) @@ -99,7 +99,7 @@ SmlDevInfContentType *ct = NULL; \ ct = sml_dev_inf_content_type_new(cttype, verct, &gerror); \ sml_fail_unless(ct != NULL, "%s", gerror?gerror->message:"No GError set."); \ - sml_dev_inf_data_store_set_rx_pref(datastore, ct); \ + sml_fail_unless(sml_dev_inf_data_store_set_rx_pref(datastore, ct, &gerror), "%s", gerror?gerror->message:"No GError set."); \ g_object_unref(ct); \ ct = NULL; \ } @@ -110,7 +110,7 @@ SmlDevInfContentType *ct = NULL; \ ct = sml_dev_inf_content_type_new(cttype, verct, &gerror); \ sml_fail_unless(ct != NULL, "%s", gerror?gerror->message:"No GError set."); \ - sml_dev_inf_data_store_set_tx_pref(datastore, ct); \ + sml_fail_unless(sml_dev_inf_data_store_set_tx_pref(datastore, ct, &gerror), "%s", gerror?gerror->message:"No GError set."); \ g_object_unref(ct); \ ct = NULL; \ } |