clienttest.cpp
来自「funambol window mobile客户端源代码」· C++ 代码 · 共 1,496 行 · 第 1/5 页
CPP
1,496 行
/*
* Funambol is a mobile platform developed by Funambol, Inc.
* Copyright (C) 2003 - 2007 Funambol, Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by
* the Free Software Foundation with the addition of the following permission
* added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
* WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE
* WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program 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 General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program; if not, see http://www.gnu.org/licenses or write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA.
*
* You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite
* 305, Redwood City, CA 94063, USA, or at email address info@funambol.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License
* version 3, these Appropriate Legal Notices must retain the display of the
* "Powered by Funambol" logo. If the display of the logo is not reasonably
* feasible for technical reasons, the Appropriate Legal Notices must display
* the words "Powered by Funambol".
*/
/** @cond API */
/** @addtogroup ClientTest */
/** @{ */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#ifdef ENABLE_INTEGRATION_TESTS
#include "ClientTest.h"
#include "base/globalsdef.h"
#include "base/test.h"
#include "base/util/StringBuffer.h"
#include <memory>
#include <vector>
#include <utility>
#include <sstream>
#include <iomanip>
#include <fstream>
#include <iostream>
#include <algorithm>
USE_NAMESPACE
/** utility function to iterate over different kinds of items in a sync source */
static std::list<std::string> listAnyItems(
SyncSource *source,
SyncItem * (SyncSource::*first)(),
SyncItem * (SyncSource::*next)() )
{
SyncItem *item = NULL;
std::list<std::string> res;
CPPUNIT_ASSERT(source);
CPPUNIT_ASSERT(!source->getReport() || source->getReport()->getState() != SOURCE_ERROR);
SOURCE_ASSERT_NO_FAILURE(source, item = (source->*first)());
while ( item ) {
const char *key = item->getKey();
SOURCE_ASSERT(source, key);
SOURCE_ASSERT(source, key[0]);
res.push_back(key);
delete item;
SOURCE_ASSERT_NO_FAILURE(source, item = (source->*next)());
}
return res;
}
static std::list<std::string> listNewItems( SyncSource *source )
{
std::list<std::string> res = listAnyItems(
source,
&SyncSource::getFirstNewItem,
&SyncSource::getNextNewItem );
return res;
}
static std::list<std::string> listUpdatedItems( SyncSource *source )
{
std::list<std::string> res = listAnyItems(
source,
&SyncSource::getFirstUpdatedItem,
&SyncSource::getNextUpdatedItem );
return res;
}
static std::list<std::string> listDeletedItems( SyncSource *source )
{
std::list<std::string> res = listAnyItems(
source,
&SyncSource::getFirstDeletedItem,
&SyncSource::getNextDeletedItem );
return res;
}
static std::list<std::string> listItems( SyncSource *source )
{
std::list<std::string> res = listAnyItems(
source,
&SyncSource::getFirstItem,
&SyncSource::getNextItem );
return res;
}
std::list<std::string> listItemsOfType(SyncSource *source, itemType type)
{
std::list<std::string> res;
switch(type) {
case NEW_ITEMS:
res = listNewItems(source);
break;
case UPDATED_ITEMS:
res = listUpdatedItems(source);
break;
case DELETED_ITEMS:
res = listDeletedItems(source);
break;
case TOTAL_ITEMS:
res = listItems(source);
break;
default:
CPPUNIT_ASSERT(false);
break;
}
return res;
}
static int countNewItems( SyncSource *source ) { return listNewItems(source).size(); }
static int countUpdatedItems( SyncSource *source ) { return listUpdatedItems(source).size(); }
static int countDeletedItems( SyncSource *source ) { return listDeletedItems(source).size(); }
static int countItems( SyncSource *source ) { return listItems(source).size(); }
int countItemsOfType(SyncSource *source, itemType type) { return listItemsOfType(source, type).size(); }
static void importItem(SyncSource *source, std::string &data)
{
CPPUNIT_ASSERT(source);
if (data.size()) {
SyncItem item;
item.setData( data.c_str(), (long)data.size() );
item.setDataType( TEXT("raw") );
int status = STC_OK;
SOURCE_ASSERT_NO_FAILURE(source, status = source->addItem(item));
CPPUNIT_ASSERT(status == STC_OK || status == STC_ITEM_ADDED);
CPPUNIT_ASSERT(item.getKey() != 0);
CPPUNIT_ASSERT(wcslen(item.getKey()) > 0);
}
}
/** adds the supported tests to the instance itself */
void LocalTests::addTests() {
if (config.createSourceA) {
ADD_TEST(LocalTests, testOpen);
ADD_TEST(LocalTests, testIterateTwice);
if (config.insertItem) {
ADD_TEST(LocalTests, testSimpleInsert);
ADD_TEST(LocalTests, testLocalDeleteAll);
ADD_TEST(LocalTests, testComplexInsert);
if (config.updateItem) {
ADD_TEST(LocalTests, testLocalUpdate);
if (config.createSourceB) {
ADD_TEST(LocalTests, testChanges);
}
}
if (config.import &&
config.dump &&
config.compare &&
config.testcases) {
ADD_TEST(LocalTests, testImport);
ADD_TEST(LocalTests, testImportDelete);
}
if (config.templateItem &&
config.uniqueProperties) {
ADD_TEST(LocalTests, testManyChanges);
}
if (config.parentItem &&
config.childItem) {
ADD_TEST(LocalTests, testLinkedItemsParent);
ADD_TEST(LocalTests, testLinkedItemsChild);
ADD_TEST(LocalTests, testLinkedItemsParentChild);
ADD_TEST(LocalTests, testLinkedItemsChildParent);
ADD_TEST(LocalTests, testLinkedItemsChildChangesParent);
ADD_TEST(LocalTests, testLinkedItemsRemoveParentFirst);
ADD_TEST(LocalTests, testLinkedItemsRemoveNormal);
ADD_TEST(LocalTests, testLinkedItemsInsertParentTwice);
ADD_TEST(LocalTests, testLinkedItemsInsertChildTwice);
ADD_TEST(LocalTests, testLinkedItemsParentUpdate);
ADD_TEST(LocalTests, testLinkedItemsUpdateChild);
ADD_TEST(LocalTests, testLinkedItemsInsertBothUpdateChild);
ADD_TEST(LocalTests, testLinkedItemsInsertBothUpdateParent);
}
}
}
}
std::string LocalTests::insert(CreateSource createSource, const char *data, bool relaxed) {
std::string uid;
// create source
std::auto_ptr<SyncSource> source(createSource());
CPPUNIT_ASSERT(source.get() != 0);
// count number of already existing items
SOURCE_ASSERT(source.get(), source->beginSync() == 0);
int numItems = 0;
CPPUNIT_ASSERT_NO_THROW(numItems = countItems(source.get()));
SyncItem item;
item.setData(data, (long)strlen(data));
int status = STC_OK;
SOURCE_ASSERT_NO_FAILURE(source.get(), status = source->addItem(item));
CPPUNIT_ASSERT(item.getKey() != 0);
CPPUNIT_ASSERT(wcslen(item.getKey()) > 0);
uid = item.getKey();
SOURCE_ASSERT(source.get(), source->endSync() == 0);
// delete source again
CPPUNIT_ASSERT_NO_THROW(source.reset());
if (!relaxed) {
// two possible results:
// - a new item was added
// - the item was matched against an existing one
CPPUNIT_ASSERT_NO_THROW(source.reset(createSource()));
CPPUNIT_ASSERT(source.get() != 0);
SOURCE_ASSERT(source.get(), source->beginSync() == 0);
CPPUNIT_ASSERT(status == STC_OK || status == STC_ITEM_ADDED || status == STC_CONFLICT_RESOLVED_WITH_MERGE);
CPPUNIT_ASSERT_EQUAL(numItems + (status == STC_CONFLICT_RESOLVED_WITH_MERGE ? 0 : 1),
countItems(source.get()));
CPPUNIT_ASSERT(countNewItems(source.get()) == 0);
CPPUNIT_ASSERT(countUpdatedItems(source.get()) == 0);
CPPUNIT_ASSERT(countDeletedItems(source.get()) == 0);
SOURCE_ASSERT(source.get(), source->endSync() == 0 );
CPPUNIT_ASSERT_NO_THROW(source.reset());
}
#if 0
/* source.createItem() is a SyncEvolution extension which cannot be used here */
SyncItem *sameItem;
SOURCE_ASSERT_NO_FAILURE(
source,
sameItem = source.createItem(item.getKey(), item.getState()));
CPPUNIT_ASSERT(sameItem != 0);
CPPUNIT_ASSERT(!strcmp( sameItem->getKey(), item.getKey()));
delete sameItem;
#endif
return uid;
}
/** deletes specific item locally via sync source */
static std::string updateItem(CreateSource createSource, const std::string &uid, const char *data) {
std::string newuid;
CPPUNIT_ASSERT(createSource.createSource);
// create source
std::auto_ptr<SyncSource> source(createSource());
CPPUNIT_ASSERT(source.get() != 0);
SOURCE_ASSERT(source.get(), source->beginSync() == 0);
// insert item
SyncItem item;
item.setKey(uid.c_str());
item.setData(data, (long)strlen(data) + 1);
item.setDataType(TEXT(""));
SOURCE_ASSERT_EQUAL(source.get(), (int)STC_OK, source->updateItem(item));
SOURCE_ASSERT(source.get(), item.getKey());
newuid = item.getKey();
SOURCE_ASSERT(source.get(), source->endSync() == 0);
CPPUNIT_ASSERT_NO_THROW(source.reset());
return newuid;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?