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 + -
显示快捷键?