clienttest.cpp

来自「funambol window mobile客户端源代码」· C++ 代码 · 共 1,496 行 · 第 1/5 页

CPP
1,496
字号
    testSimpleInsert();
    update(createSourceA, config.updateItem);
}

// complex sequence of changes
void LocalTests::testChanges() {
    // check additional requirements
    CPPUNIT_ASSERT(config.createSourceB);

    testLocalDeleteAll();
    testSimpleInsert();

    // clean changes in sync source B by creating and closing it
    std::auto_ptr<SyncSource> source;
    SOURCE_ASSERT_NO_FAILURE(source.get(), source.reset(createSourceB()));
    SOURCE_ASSERT_EQUAL(source.get(), 0, source->beginSync());
    SOURCE_ASSERT_EQUAL(source.get(), 0, source->endSync());
    CPPUNIT_ASSERT_NO_THROW(source.reset());

    // no new changes now
    SOURCE_ASSERT_NO_FAILURE(source.get(), source.reset(createSourceB()));
    SOURCE_ASSERT_EQUAL(source.get(), 0, source->beginSync());
    SOURCE_ASSERT_EQUAL(source.get(), 1, countItems(source.get()));
    SOURCE_ASSERT_EQUAL(source.get(), 0, countNewItems(source.get()));
    SOURCE_ASSERT_EQUAL(source.get(), 0, countUpdatedItems(source.get()));
    SOURCE_ASSERT_EQUAL(source.get(), 0, countDeletedItems(source.get()));
    std::auto_ptr<SyncItem> item;
    SOURCE_ASSERT_NO_FAILURE(source.get(), item.reset(source->getFirstItem()));
    SOURCE_ASSERT_EQUAL(source.get(), 0, source->endSync());
    CPPUNIT_ASSERT_NO_THROW(source.reset());

    // delete item again via sync source A
    deleteAll(createSourceA);
    SOURCE_ASSERT_NO_FAILURE(source.get(), source.reset(createSourceB()));
    SOURCE_ASSERT_EQUAL(source.get(), 0, source->beginSync());
    SOURCE_ASSERT_EQUAL(source.get(), 0, countItems(source.get()));
    SOURCE_ASSERT_EQUAL(source.get(), 0, countNewItems(source.get()));
    SOURCE_ASSERT_EQUAL(source.get(), 0, countUpdatedItems(source.get()));
    SOURCE_ASSERT_EQUAL(source.get(), 1, countDeletedItems(source.get()));
    std::auto_ptr<SyncItem> deletedItem;
    SOURCE_ASSERT_NO_FAILURE(source.get(), deletedItem.reset(source->getFirstDeletedItem()));
    CPPUNIT_ASSERT( wcslen( item->getKey() ) );
    CPPUNIT_ASSERT( wcslen( deletedItem->getKey() ) );
    CPPUNIT_ASSERT( !wcscmp( item->getKey(), deletedItem->getKey() ) );
    SOURCE_ASSERT_EQUAL(source.get(), 0, source->endSync());
    CPPUNIT_ASSERT_NO_THROW(source.reset());

    // insert another item via sync source A
    testSimpleInsert();
    SOURCE_ASSERT_NO_FAILURE(source.get(), source.reset(createSourceB()));
    SOURCE_ASSERT_EQUAL(source.get(), 0, source->beginSync());
    SOURCE_ASSERT_EQUAL(source.get(), 1, countItems(source.get()));
    SOURCE_ASSERT_EQUAL(source.get(), 1, countNewItems(source.get()));
    SOURCE_ASSERT_EQUAL(source.get(), 0, countUpdatedItems(source.get()));
    SOURCE_ASSERT_EQUAL(source.get(), 0, countDeletedItems(source.get()));
    SOURCE_ASSERT_NO_FAILURE(source.get(), item.reset(source->getFirstItem()));
    std::auto_ptr<SyncItem> newItem;
    SOURCE_ASSERT_NO_FAILURE(source.get(), newItem.reset(source->getFirstNewItem()));
    CPPUNIT_ASSERT( wcslen( item->getKey() ) );
    CPPUNIT_ASSERT( wcslen( newItem->getKey() ) );
    CPPUNIT_ASSERT( !wcscmp( item->getKey(), newItem->getKey() ) );
    SOURCE_ASSERT_EQUAL(source.get(), 0, source->endSync());
    CPPUNIT_ASSERT_NO_THROW(source.reset());

    // update item via sync source A
    update(createSourceA, config.updateItem);
    SOURCE_ASSERT_NO_FAILURE(source.get(), source.reset(createSourceB()));
    SOURCE_ASSERT_EQUAL(source.get(), 0, source->beginSync());
    SOURCE_ASSERT_EQUAL(source.get(), 1, countItems(source.get()));
    SOURCE_ASSERT_EQUAL(source.get(), 0, countNewItems(source.get()));
    SOURCE_ASSERT_EQUAL(source.get(), 1, countUpdatedItems(source.get()));
    SOURCE_ASSERT_EQUAL(source.get(), 0, countDeletedItems(source.get()));
    std::auto_ptr<SyncItem> updatedItem;
    SOURCE_ASSERT_NO_FAILURE(source.get(), updatedItem.reset(source->getFirstUpdatedItem()));
    CPPUNIT_ASSERT( wcslen( item->getKey() ) );
    CPPUNIT_ASSERT( wcslen( updatedItem->getKey() ) );
    CPPUNIT_ASSERT( !wcscmp( item->getKey(), updatedItem->getKey() ) );
    SOURCE_ASSERT_EQUAL(source.get(), 0, source->endSync());
    CPPUNIT_ASSERT_NO_THROW(source.reset());

    // start anew, then create and update an item -> should only be listed as new
    // or updated, but not both
    deleteAll(createSourceA);
    SOURCE_ASSERT_NO_FAILURE(source.get(), source.reset(createSourceB()));
    SOURCE_ASSERT_EQUAL(source.get(), 0, source->beginSync());
    SOURCE_ASSERT_EQUAL(source.get(), 0, source->endSync());
    testSimpleInsert();
    update(createSourceA, config.updateItem);
    SOURCE_ASSERT_NO_FAILURE(source.get(), source.reset(createSourceB()));
    SOURCE_ASSERT_EQUAL(source.get(), 0, source->beginSync());
    SOURCE_ASSERT_EQUAL(source.get(), 1, countItems(source.get()));
    SOURCE_ASSERT_EQUAL(source.get(), 1, countNewItems(source.get()) + countUpdatedItems(source.get()));
    SOURCE_ASSERT_EQUAL(source.get(), 0, countDeletedItems(source.get()));

    // start anew, then create, delete and recreate an item -> should only be listed as new or updated,
    // even if (as for calendar with UID) the same LUID gets reused
    deleteAll(createSourceA);
    SOURCE_ASSERT_NO_FAILURE(source.get(), source.reset(createSourceB()));
    SOURCE_ASSERT_EQUAL(source.get(), 0, source->beginSync());
    SOURCE_ASSERT_EQUAL(source.get(), 0, source->endSync());
    testSimpleInsert();
    deleteAll(createSourceA);
    testSimpleInsert();
    SOURCE_ASSERT_NO_FAILURE(source.get(), source.reset(createSourceB()));
    SOURCE_ASSERT_EQUAL(source.get(), 0, source->beginSync());
    SOURCE_ASSERT_EQUAL(source.get(), 1, countItems(source.get()));
    SOURCE_ASSERT_EQUAL(source.get(), 1, countNewItems(source.get()) + countUpdatedItems(source.get()));
    if (countDeletedItems(source.get()) == 1) {
        // It's not nice, but acceptable to send the LUID of a deleted item to a
        // server which has never seen that LUID. The LUID must not be the same as
        // the one we list as new or updated, though.
        SyncItem *deleted = source->getFirstDeletedItem();
        CPPUNIT_ASSERT(deleted);
        SyncItem *new_or_updated = source->getFirstNewItem();
        if (!new_or_updated) {
            new_or_updated = source->getFirstUpdatedItem();
        }
        CPPUNIT_ASSERT(new_or_updated);
        CPPUNIT_ASSERT(wcscmp(deleted->getKey(), new_or_updated->getKey()));
    } else {
        SOURCE_ASSERT_EQUAL(source.get(), 0, countDeletedItems(source.get()));
    }
}

// clean database, import file, then export again and compare
void LocalTests::testImport() {
    // check additional requirements
    CPPUNIT_ASSERT(config.import);
    CPPUNIT_ASSERT(config.dump);
    CPPUNIT_ASSERT(config.compare);
    CPPUNIT_ASSERT(config.testcases);

    testLocalDeleteAll();

    // import via sync source A
    std::auto_ptr<SyncSource> source;
    SOURCE_ASSERT_NO_FAILURE(source.get(), source.reset(createSourceA()));
    SOURCE_ASSERT_EQUAL(source.get(), 0, source->beginSync());
    SOURCE_ASSERT_EQUAL(source.get(), 0, config.import(client, *source.get(), config.testcases));
    SOURCE_ASSERT_EQUAL(source.get(), 0, source->endSync());
    CPPUNIT_ASSERT_NO_THROW(source.reset());

    // export again and compare against original file
    std::auto_ptr<SyncSource> copy;
    SOURCE_ASSERT_NO_FAILURE(copy.get(), copy.reset(createSourceA()));
    compareDatabases(config.testcases, *copy.get());
    CPPUNIT_ASSERT_NO_THROW(source.reset());
}

// same as testImport() with immediate delete
void LocalTests::testImportDelete() {
    testImport();

    // delete again, because it was observed that this did not
    // work right with calendars in SyncEvolution
    testLocalDeleteAll();
}

// test change tracking with large number of items
void LocalTests::testManyChanges() {
    // check additional requirements
    CPPUNIT_ASSERT(config.templateItem);
    CPPUNIT_ASSERT(config.uniqueProperties);

    deleteAll(createSourceA);

    // check that everything is empty, also resets change counter of sync source B
    std::auto_ptr<SyncSource> copy;
    SOURCE_ASSERT_NO_FAILURE(copy.get(), copy.reset(createSourceB()));
    SOURCE_ASSERT_EQUAL(copy.get(), 0, copy->beginSync());
    SOURCE_ASSERT_EQUAL(copy.get(), 0, countItems(copy.get()));
    SOURCE_ASSERT_EQUAL(copy.get(), 0, copy->endSync());
    CPPUNIT_ASSERT_NO_THROW(copy.reset());

    // now insert plenty of items
    int numItems = insertManyItems(createSourceA);

    // check that exactly this number of items is listed as new
    SOURCE_ASSERT_NO_FAILURE(copy.get(), copy.reset(createSourceB()));
    SOURCE_ASSERT_EQUAL(copy.get(), 0, copy->beginSync());
    SOURCE_ASSERT_EQUAL(copy.get(), numItems, countItems(copy.get()));
    SOURCE_ASSERT_EQUAL(copy.get(), numItems, countNewItems(copy.get()));
    SOURCE_ASSERT_EQUAL(copy.get(), 0, countUpdatedItems(copy.get()));
    SOURCE_ASSERT_EQUAL(copy.get(), 0, countDeletedItems(copy.get()));
    SOURCE_ASSERT_EQUAL(copy.get(), 0, copy->endSync());
    CPPUNIT_ASSERT_NO_THROW(copy.reset());

    // delete all items
    deleteAll(createSourceA);

    // verify again
    SOURCE_ASSERT_NO_FAILURE(copy.get(), copy.reset(createSourceB()));
    SOURCE_ASSERT_EQUAL(copy.get(), 0, copy->beginSync());
    SOURCE_ASSERT_EQUAL(copy.get(), 0, countItems(copy.get()));
    SOURCE_ASSERT_EQUAL(copy.get(), 0, countNewItems(copy.get()));
    SOURCE_ASSERT_EQUAL(copy.get(), 0, countUpdatedItems(copy.get()));
    SOURCE_ASSERT_EQUAL(copy.get(), numItems, countDeletedItems(copy.get()));
    SOURCE_ASSERT_EQUAL(copy.get(), 0, copy->endSync());
    CPPUNIT_ASSERT_NO_THROW(copy.reset());
}

template<class T, class V> int countEqual(const T &container,
                                          const V &value) {
    return count(container.begin(),
                 container.end(),
                 value);
}

// test inserting, removing and updating of parent + child item in
// various order plus change tracking
void LocalTests::testLinkedItemsParent() {
    // check additional requirements
    CPPUNIT_ASSERT(config.parentItem);
    CPPUNIT_ASSERT(config.childItem);

    deleteAll(createSourceA);
    std::string parent, child;
    std::auto_ptr<SyncSource> copy;

    // check that everything is empty, also resets change counter of sync source B
    SOURCE_ASSERT_NO_FAILURE(copy.get(), copy.reset(createSourceB()));
    SOURCE_ASSERT_EQUAL(copy.get(), 0, copy->beginSync());
    SOURCE_ASSERT_EQUAL(copy.get(), 0, countItems(copy.get()));
    SOURCE_ASSERT_EQUAL(copy.get(), 0, copy->endSync());
    CPPUNIT_ASSERT_NO_THROW(copy.reset());

    // now insert main item
    parent = insert(createSourceA, config.parentItem);

    // check that exactly the parent is listed as new
    SOURCE_ASSERT_NO_FAILURE(copy.get(), copy.reset(createSourceB()));
    SOURCE_ASSERT_EQUAL(copy.get(), 0, copy->beginSync());
    SOURCE_ASSERT_EQUAL(copy.get(), 1, countItems(copy.get()));
    SOURCE_ASSERT_EQUAL(copy.get(), 1, countNewItems(copy.get()));
    SOURCE_ASSERT_EQUAL(copy.get(), 0, countUpdatedItems(copy.get()));
    SOURCE_ASSERT_EQUAL(copy.get(), 0, countDeletedItems(copy.get()));
    SOURCE_ASSERT_EQUAL(copy.get(), 1, countEqual(listItems(copy.get()), parent));
    SOURCE_ASSERT_EQUAL(copy.get(), 0, copy->endSync());
    CPPUNIT_ASSERT_NO_THROW(copy.reset());

    // delete all items
    deleteAll(createSourceA);

    // verify again
    SOURCE_ASSERT_NO_FAILURE(copy.get(), copy.reset(createSourceB()));
    SOURCE_ASSERT_EQUAL(copy.get(), 0, copy->beginSync());
    SOURCE_ASSERT_EQUAL(copy.get(), 0, countItems(copy.get()));
    SOURCE_ASSERT_EQUAL(copy.get(), 0, countNewItems(copy.get()));
    SOURCE_ASSERT_EQUAL(copy.get(), 0, countUpdatedItems(copy.get()));
    SOURCE_ASSERT_EQUAL(copy.get(), 1, countDeletedItems(copy.get()));
    SOURCE_ASSERT_EQUAL(copy.get(), 1, countEqual(listDeletedItems(copy.get()), parent));
    SOURCE_ASSERT_EQUAL(copy.get(), 0, copy->endSync());
    CPPUNIT_ASSERT_NO_THROW(copy.reset());
}

// test inserting, removing and updating of parent + child item in
// various order plus change tracking
void LocalTests::testLinkedItemsChild() {
#if LINKED_ITEMS_RELAXED_SEMANTIC
    // check additional requirements
    CPPUNIT_ASSERT(config.parentItem);
    CPPUNIT_ASSERT(config.childItem);

    deleteAll(createSourceA);
    std::string parent, child;
    std::auto_ptr<SyncSource> copy;

    // check that everything is empty, also resets change counter of sync source B
    SOURCE_ASSERT_NO_FAILURE(copy.get(), copy.reset(createSourceB()));
    SOURCE_ASSERT_EQUAL(copy.get(), 0, copy->beginSync());
    SOURCE_ASSERT_EQUAL(copy.get(), 0, countItems(copy.get()));
    SOURCE_ASSERT_EQUAL(copy.get(), 0, copy->endSync());
    CPPUNIT_ASSERT_NO_THROW(copy.reset());

    // same as above for child item
    child = insert(createSourceA, config.childItem);

    SOURCE_ASSERT_NO_FAILURE(copy.get(), copy.reset(createSourceB()));
    SOURCE_ASSERT_EQUAL(copy.get(), 0, copy->beginSync());
    SOURCE_ASSERT_EQUAL(copy.get(), 1, countItems(copy.get()));
    SOURCE_ASSERT_EQUAL(copy.get(), 1, countNewItems(copy.get()));
    SOURCE_ASSERT_EQUAL(copy.get(), 0, countUpdatedItems(copy.get()));
    SOURCE_ASSERT_EQUAL(copy.get(), 0, countDeletedItems(copy.get()));
    SOURCE_ASSERT_EQUAL(copy.get(), 1, countEqual(listItems(copy.get()), child));
    SOURCE_ASSERT_EQUAL(copy.get(), 0, copy->endSync());
    CPPUNIT_ASSERT_NO_THROW(copy.reset());

    deleteAll(createSourceA);

    SOURCE_ASSERT_NO_FAILURE(copy.get(), copy.reset(createSourceB()));
    SOURCE_ASSERT_EQUAL(copy.get(), 0, copy->beginSync());
    SOURCE_ASSERT_EQUAL(copy.get(), 0, countItems(copy.get()));
    SOURCE_ASSERT_EQUAL(copy.get(), 0, countNewItems(copy.get()));
    SOURCE_ASSERT_EQUAL(copy.get(), 0, countUpdatedItems(copy.get()));
    SOURCE_ASSERT_EQUAL(copy.get(), 1, countDeletedItems(copy.get()));
    SOURCE_ASSERT_EQUAL(copy.get(), 1, countEqual(listDeletedItems(copy.get()), child));
    SOURCE_ASSERT_EQUAL(copy.get(), 0, copy->endSync());
    CPPUNIT_ASSERT_NO_THROW(copy.reset());
#endif
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?