container_test::List_test Class Reference

Polymorphic code for testing concrete sub-classes of container::List. More...

#include <list_test.h>

Inheritance diagram for container_test::List_test:

Inheritance graph
[legend]
Collaboration diagram for container_test::List_test:

Collaboration graph
[legend]

List of all members.

Protected Member Functions

void verifyEmptyStateCoherence (List *a)
void verifyEmptyStateCoherence (List &a)
void verifyNonEmptyStateCoherence_tail (List *a, int count)
void verifyNonEmptyStateCoherence_tail (List &a, int count)
void verifyNonEmptyStateCoherence_notTail (List *a, int count)
void verifyNonEmptyStateCoherence_notTail (List &a, int count)
void generateDataAndPopulateList (Entity **&data, List *list, const int listSize, bool print=false)
 Creates a new test data set.
void defaultConstructor (const Object::Info *type)
void cursorControl (const Object::Info *type)
void purgeConents (const Object::Info *type)
void locateEntity (const Object::Info *type)
void entityAt (const Object::Info *type)

Static Protected Attributes

static const int SOME_OTHER_KEY
static const int ZERO_INDEX
static const int NEGATIVE_INDEX
static const int BIG_INDEX
static const int SOME_OTHER_INDEX
static const int INDEX_NOT_FOUND
static const int KEY_4
static const string KEY_4_AS_STRING


Detailed Description

Polymorphic code for testing concrete sub-classes of container::List.

There are no actual unit tests in List_test that the googletest framework will recognize and execute automatically. The googletest framework doesn't provide an elegant solution for testing the compliance of derived classes. This class is sub-classed by OrderedLinkedList_test and SortedLinkedList_test in order to re-use common unit test code.


Member Function Documentation

void container_test::List_test::cursorControl ( const Object::Info type  )  [protected]

00164                                                     {
00165 
00166    List* a = listFactory(type);
00167 
00168    // Cursor manipulation with a empty list
00169    cout << "List a is empty" << endl;
00170    cout << "  " << a << endl;
00171    verifyEmptyStateCoherence(a);
00172    EXPECT_EQ(false, a->toFirst());
00173    verifyEmptyStateCoherence(a);
00174    EXPECT_EQ(false, a->toLast());
00175    verifyEmptyStateCoherence(a);
00176    EXPECT_EQ(false, a->toNext());
00177    verifyEmptyStateCoherence(a);
00178    EXPECT_EQ(false, a->toPrev());
00179    verifyEmptyStateCoherence(a);
00180    a->toTail();
00181    verifyEmptyStateCoherence(a);
00182 
00183    // Cursor manipulation with a list containing a single node
00184    Entity* e1 = new Entity();
00185    a->add(e1);
00186    cout << "List a has one item" << endl;
00187    cout << "  " << a << endl;
00188    EXPECT_EQ(true, a->toPrev());
00189    cout << "After toPrev()" << endl;
00190    cout << "  " << a << endl;
00191    verifyNonEmptyStateCoherence_notTail(a, 1);
00192    cout << "Current node contains: " << a->currentEntity() << endl;
00193    EXPECT_EQ(e1, a->currentEntity());
00194    EXPECT_FALSE(a->toPrev());
00195    verifyNonEmptyStateCoherence_notTail(a, 1);
00196    EXPECT_FALSE(a->toNext());
00197    cout << "After toNext()" << endl;
00198    cout << "  " << a << endl;
00199    verifyNonEmptyStateCoherence_tail(a, 1);
00200    EXPECT_TRUE(a->toFirst());
00201    cout << "After toFirst()" << endl;
00202    cout << "  " << a << endl;
00203    verifyNonEmptyStateCoherence_notTail(a, 1);
00204    a->toTail();
00205    cout << "After toTail()" << endl;
00206    cout << "  " << a << endl;
00207    verifyNonEmptyStateCoherence_tail(a, 1);
00208    EXPECT_TRUE(a->toLast());
00209    cout << "After toLast()" << endl;
00210    cout << "  " << a << endl;
00211    verifyNonEmptyStateCoherence_notTail(a, 1);
00212 
00213    //Cursor manipulation with a list containing 2 nodes
00214    EXPECT_TRUE(a->toFirst());
00215    cout << "After toFirst(), (cursor shouldn't have moved)" << endl;
00216    cout << "  " << a << endl;
00217    EXPECT_TRUE(a->isLast());
00218    cout << "Adding a 2nd item using default add method" << endl;
00219    Entity* e2 = new Entity();
00220    a->add(e2);
00221    cout << "After add(e2), cursor should still point to e1." << endl;
00222    cout << "  " << a << endl;
00223    EXPECT_EQ(e1, a->currentEntity());
00224    EXPECT_TRUE(e1->compareKeyTo(*a->currentEntity()) == 0);
00225 
00226    int indexResult;
00227    Entity key = *e1;
00228    Entity* entityResult;
00229    a->locateEntity(key, indexResult, entityResult);
00230    EXPECT_EQ(e1, entityResult);
00231    EXPECT_NE(INDEX_NOT_FOUND, indexResult);
00232 
00233    // Where method add(Entity*) puts the new items is up to the implementing
00234    // class. Therefore, this generic test cannot know, at compile time,
00235    // whether the second entity was added first or last.
00236    if (indexResult == 0) {
00237       EXPECT_FALSE(a->isLast());
00238       EXPECT_TRUE(a->isFirst());
00239    } else {
00240       EXPECT_TRUE(a->isLast());
00241       EXPECT_FALSE(a->isFirst());
00242    }
00243 
00244    List_test::verifyNonEmptyStateCoherence_notTail(a, 2);
00245    if (indexResult == 0) {
00246       EXPECT_TRUE(a->toNext());
00247       cout << "After toNext()" << endl;
00248       cout << "  " << a << endl;
00249       verifyNonEmptyStateCoherence_notTail(a, 2);
00250       EXPECT_FALSE(a->toNext());
00251       cout << "After 2nd call toNext()" << endl;
00252       cout << "  " << a << endl;
00253       verifyNonEmptyStateCoherence_tail(a, 2);
00254       EXPECT_TRUE(a->toPrev());
00255       cout << "Last node contains: " << a->currentEntity() << endl;
00256       EXPECT_EQ(e2, a->currentEntity());
00257       EXPECT_TRUE(a->toPrev());
00258       EXPECT_TRUE(a->isFirst());
00259       cout << "After toPrev()" << endl;
00260       cout << "  " << a << endl;
00261       verifyNonEmptyStateCoherence_notTail(a, 2);
00262       cout << "First node contains: " << a->currentEntity() << endl;
00263       EXPECT_EQ(e1, a->currentEntity());
00264       EXPECT_FALSE(a->toPrev());
00265       cout << "After toPrev()" << endl;
00266       cout << "  " << a << endl;
00267       verifyNonEmptyStateCoherence_notTail(a, 2);
00268    } else {
00269       EXPECT_TRUE(a->toPrev());
00270       cout << "After toPrev()" << endl;
00271       cout << "  " << a << endl;
00272       EXPECT_FALSE(a->toPrev());
00273       cout << "After 2nd call toPrev(), (cursor shouldn't have moved)" << endl;
00274       cout << "  " << a << endl;
00275       EXPECT_TRUE(a->isFirst());
00276       verifyNonEmptyStateCoherence_notTail(a, 2);
00277       cout << "First node contains: " << a->currentEntity() << endl;
00278       EXPECT_EQ(e2, a->currentEntity());
00279       EXPECT_TRUE(a->toNext());
00280       EXPECT_TRUE(a->isLast());
00281       cout << "After toNext()" << endl;
00282       cout << "  " << a << endl;
00283       verifyNonEmptyStateCoherence_notTail(a, 2);
00284       cout << "Last node contains: " << a->currentEntity() << endl;
00285       EXPECT_EQ(e1, a->currentEntity());
00286       EXPECT_FALSE(a->toNext());
00287       cout << "After toNext()" << endl;
00288       cout << "  " << a << endl;
00289       verifyNonEmptyStateCoherence_tail(a, 2);
00290    }
00291 
00292    delete a;
00293 }

Here is the call graph for this function:

void container_test::List_test::defaultConstructor ( const Object::Info type  )  [protected]

00118                                                          {
00119 
00120    // Null check, probably not necessary, but I'm just trying to figure
00121    // out this new framework.
00122    List* a = listFactory(type);
00123    List* n = NULL;
00124    EXPECT_NE(n, a);
00125 
00126    // I'm relearning the language. Just making sure I understand what's
00127    // going on. a and b should be pointing to two different places.
00128    List* b = listFactory(type);
00129    EXPECT_NE(a, b);
00130 
00131    cout << a->typeInfo()->typeName <<
00132          " default constructor should create empty lists." << endl;
00133    cout << " a " << *a << endl;
00134    EXPECT_TRUE(a->isEmpty());
00135    EXPECT_EQ(0, a->getCount());
00136    cout << " b " << *b << endl;
00137    EXPECT_TRUE(b->isEmpty());
00138    EXPECT_EQ(0, b->getCount());
00139 
00140    cout << "Adding node to " << a->typeInfo()->typeName << " b" << endl;
00141    b->add(new Entity());
00142    cout << " b " << *b << endl;
00143    EXPECT_FALSE(b->isEmpty());
00144    EXPECT_EQ(1, b->getCount());
00145    // isFirst is always false when empty
00146    EXPECT_FALSE(a->isFirst());
00147    // adding a node should not have changed the cursor possition
00148    EXPECT_FALSE(b->isFirst());
00149 
00150    // isLast is always false when empty
00151    EXPECT_FALSE(a->isLast());
00152    // adding a node should not have changed the cursor possition
00153    EXPECT_FALSE(b->isFirst());
00154 
00155    // isLast is always false when empty
00156    EXPECT_TRUE(a->isTail());
00157    // adding a node should not have changed the cursor possition
00158    EXPECT_TRUE(b->isTail());
00159 
00160    delete a;
00161    delete b;
00162 }

Here is the call graph for this function:

void container_test::List_test::entityAt ( const Object::Info type  )  [protected]

00396                                                {
00397    List* emptyList = listFactory(type);
00398    cout << "Calling entityAt(" << ZERO_INDEX << ") on an empty " <<
00399          emptyList->typeInfo()->typeName << '.' << endl;
00400    Entity *entity = new Entity();
00401    Entity *entity2 = entity;
00402    EXPECT_EQ(entity, entity2);
00403    entity = emptyList->entityAt(ZERO_INDEX);
00404    verifyEmptyStateCoherence(emptyList);
00405    EXPECT_TRUE(NULL == entity);
00406    EXPECT_NE(entity2, entity);
00407    cout << "  returned entity(" << entity << ")" << endl;
00408 
00409    List *list = listFactory(type);
00410    Entity *entity3 = new Entity();
00411    list->add(entity3);
00412    EXPECT_TRUE(list->toFirst());
00413    cout << "Calling entityAt(" << ZERO_INDEX << ") on a  " <<
00414          list->typeInfo()->typeName << " with one item." << endl;
00415    cout << "  " << *list << endl;
00416    entity = NULL;
00417    verifyNonEmptyStateCoherence_notTail(*list, 1);
00418    entity = list->entityAt(ZERO_INDEX);
00419    verifyNonEmptyStateCoherence_notTail(*list, 1);
00420    EXPECT_EQ(entity3, entity);
00421    EXPECT_FALSE(entity3 == NULL);
00422    cout << "  returned entity(" << *entity << ")" << endl;
00423 
00424    cout << "Calling entityAt(" << NEGATIVE_INDEX << ") on the same " <<
00425          list->typeInfo()->typeName << '.' << endl;
00426    cout << "  " << *list << endl;
00427    entity = entity2;
00428    verifyNonEmptyStateCoherence_notTail(*list, 1);
00429    entity = list->entityAt(NEGATIVE_INDEX);
00430    verifyNonEmptyStateCoherence_notTail(*list, 1);
00431    EXPECT_TRUE(NULL == entity);
00432    EXPECT_NE(entity2, entity);
00433    cout << "  returned entity(" << entity << ")" << endl;
00434 
00435    cout << "Calling entityAt(" << BIG_INDEX << ") on the same " <<
00436          list->typeInfo()->typeName << '.' << endl;
00437    cout << "  " << *list << endl;
00438    entity = entity2;
00439    verifyNonEmptyStateCoherence_notTail(*list, 1);
00440    entity = list->entityAt(BIG_INDEX);
00441    verifyNonEmptyStateCoherence_notTail(*list, 1);
00442    EXPECT_TRUE(NULL == entity);
00443    EXPECT_NE(entity2, entity);
00444    cout << "  returned entity(" << entity << ")" << endl;
00445 
00446    cout << "Calling entityAt(" << list->getCount() << ") on the same " <<
00447          list->typeInfo()->typeName << '.' << endl;
00448    cout << "  " << *list << endl;
00449    entity = entity2;
00450    verifyNonEmptyStateCoherence_notTail(*list, 1);
00451    entity = list->entityAt(list->getCount());
00452    verifyNonEmptyStateCoherence_notTail(*list, 1);
00453    EXPECT_TRUE(NULL == entity);
00454    EXPECT_NE(entity2, entity);
00455    cout << "  returned entity(" << entity << ")" << endl;
00456 
00457    delete emptyList;
00458    delete list;
00459 }

Here is the call graph for this function:

void container_test::List_test::generateDataAndPopulateList ( Entity **&  data,
List list,
const int  listSize,
bool  print = false 
) [protected]

Creates a new test data set.

A new data array is created and a new List. Both are populated with the same list of Entities. It is the responsibility of the caller to release all objects created: the array of Entity pointers, the List, and all the Entity objects.

Postcondition:
A new array of Entity pointers is created.

A new Linked List is created.

SIZE number if Entity objects are created.

The data array and the List will both be populated with pointers to the newly created Entity objects.

The order will be the same in both the data array and the List.

00102                                                         {
00103    data = new Entity*[listSize];
00104    if (print) cout << "Populating " << list->typeInfo()->typeName <<
00105          " with " << listSize << " entities:" << endl;
00106    if (print) cout << "  " << list << endl;
00107    for (int i = 0; i < listSize; i++) {
00108       data[i] = new Entity();
00109       list->add(data[i]);
00110       if (print) cout << "After add() " << *data[i] << endl;
00111       if (print) cout << "  " << list << endl;
00112       verifyNonEmptyStateCoherence_tail(list, i + 1);
00113    }
00114 }

Here is the call graph for this function:

Here is the caller graph for this function:

void container_test::List_test::locateEntity ( const Object::Info type  )  [protected]

00341                                                    {
00342    List* emptyList = listFactory(type);
00343    cout << "Calling locateEntity on an emtpy " << emptyList->typeInfo()->typeName
00344          << "." << endl;
00345    Entity key(KEY_4);
00346    int index(SOME_OTHER_INDEX);
00347    EXPECT_EQ(SOME_OTHER_INDEX, index);
00348    EXPECT_EQ(KEY_4_AS_STRING, key.getKeyAsString());
00349    Entity *entity = new Entity();
00350    Entity *entity2 = entity;
00351    EXPECT_EQ(entity, entity2);
00352    emptyList->locateEntity(key, index, entity);
00353    verifyEmptyStateCoherence(emptyList);
00354    EXPECT_EQ(INDEX_NOT_FOUND, index);
00355    EXPECT_TRUE(NULL == entity);
00356    EXPECT_NE(entity2, entity);
00357    cout << "  returned index(" << index << ") entity(" << entity << ")" << endl;
00358 
00359    List *list = listFactory(type);
00360    Entity *entity3 = new Entity();
00361    list->add(entity3);
00362    const Entity key2 = *entity3;
00363    cout << "Calling locateEntity on a " << list->typeInfo()->typeName <<
00364          " with a single item." << endl;
00365    cout << "  " << *list << ")" << endl;
00366    cout << "  locating Entity with key(" << key2.getKeyAsString() << ")" << endl;
00367    index = SOME_OTHER_INDEX;
00368    entity = NULL;
00369    verifyNonEmptyStateCoherence_tail(*list, 1);
00370    list->locateEntity(key2, index, entity);
00371    verifyNonEmptyStateCoherence_tail(*list, 1);
00372    EXPECT_EQ(ZERO_INDEX, index);
00373    EXPECT_EQ(entity3, entity);
00374    EXPECT_FALSE(entity3 == NULL);
00375    cout << "  returned index(" << index << ") entity(" << *entity << ")" << endl;
00376 
00377    cout << "Calling locateEntity on the same " << list->typeInfo()->typeName <<
00378          '.' << endl;
00379    cout << "  " << *list << ")" << endl;
00380    cout << "  locating Entity with key(" << SOME_OTHER_KEY << ")" << endl;
00381    const Entity someOtherKey(SOME_OTHER_KEY);
00382    index = SOME_OTHER_INDEX;
00383    entity = entity2;
00384    verifyNonEmptyStateCoherence_tail(*list, 1);
00385    list->locateEntity(someOtherKey, index, entity);
00386    verifyNonEmptyStateCoherence_tail(*list, 1);
00387    EXPECT_EQ(INDEX_NOT_FOUND, index);
00388    EXPECT_TRUE(NULL == entity);
00389    EXPECT_NE(entity2, entity);
00390    cout << "  returned index(" << index << ") entity(" << entity << ")" << endl;
00391 
00392    delete emptyList;
00393    delete list;
00394 }

Here is the call graph for this function:

void container_test::List_test::purgeConents ( const Object::Info type  )  [protected]

00295                                                    {
00296    const int LIST_SIZE = 100;
00297    Entity ** data;
00298    List* a = listFactory(type);
00299    generateDataAndPopulateList(data, a, LIST_SIZE);
00300    verifyNonEmptyStateCoherence_tail(a, LIST_SIZE);
00301 
00302    const int SAMPLE_MOD = 10;
00303    cout << "Created a " << a->typeInfo()->typeName << " with " << LIST_SIZE <<
00304          " items." << endl;
00305    cout << "  count(" << a->getCount() << ")" << endl;
00306    cout << "Vefifying all items. Printing a sample every " <<
00307          SAMPLE_MOD << " items:" << endl;
00308    cout << "      Expected Entity                    Container Entity" << endl;
00309    a->toFirst();
00310    int index = 0;
00311    do {
00312       if ((index % SAMPLE_MOD) == 0) {
00313          cout << "  [" << index << "] " << data[index] << " == " << a->currentEntity() << endl;
00314       }
00315       EXPECT_EQ(data[index], a->currentEntity());
00316       a->toNext();
00317       index++;
00318    } while (!a->isTail());
00319    EXPECT_EQ(LIST_SIZE, index);
00320    EXPECT_EQ(LIST_SIZE, a->purgeContents());
00321    verifyEmptyStateCoherence(a);
00322    cout << "Called purgeContents()" << endl;
00323    cout << "  " << a << endl;
00324 
00325    index = 0;
00326    while (a->toPrev()) index++;
00327    EXPECT_EQ(0, index);
00328 
00329    Entity e;
00330    a->add(&e);
00331    EXPECT_TRUE(a->toPrev());
00332    verifyNonEmptyStateCoherence_notTail(*a, 1);
00333    EXPECT_EQ(&e, a->currentEntity());
00334    EXPECT_TRUE(e.compareKeyTo(*a->extractCurrentEntity()) == 0);
00335    verifyEmptyStateCoherence(a);
00336 
00337    delete a;
00338    delete data;
00339 }

Here is the call graph for this function:

void container_test::List_test::verifyEmptyStateCoherence ( List a  )  [protected]

00062                                                  {
00063    EXPECT_TRUE(a.isEmpty());
00064    EXPECT_EQ(0, a.getCount());
00065    EXPECT_FALSE(a.isFirst());
00066    EXPECT_FALSE(a.isLast());
00067    EXPECT_TRUE(a.isTail());
00068 }

Here is the call graph for this function:

void container_test::List_test::verifyEmptyStateCoherence ( List a  )  [protected]

00058                                                  {
00059    verifyEmptyStateCoherence(*a);
00060 }

Here is the caller graph for this function:

void container_test::List_test::verifyNonEmptyStateCoherence_notTail ( List a,
int  count 
) [protected]

00086                                                                        {
00087    EXPECT_FALSE(a.isEmpty());
00088    EXPECT_EQ(count, a.getCount());
00089    if (count == 1) {
00090       EXPECT_TRUE(a.isFirst());
00091       EXPECT_TRUE(a.isLast());
00092    } else if (count > 1) {
00093       if (a.isFirst()) EXPECT_FALSE(a.isLast());
00094       if (a.isLast()) EXPECT_FALSE(a.isFirst());
00095    }
00096    EXPECT_FALSE(a.isTail());
00097 }

Here is the call graph for this function:

void container_test::List_test::verifyNonEmptyStateCoherence_notTail ( List a,
int  count 
) [protected]

00082                                                                        {
00083    verifyNonEmptyStateCoherence_notTail(*a, count);
00084 }

Here is the caller graph for this function:

void container_test::List_test::verifyNonEmptyStateCoherence_tail ( List a,
int  count 
) [protected]

00074                                                                     {
00075    EXPECT_FALSE(a.isEmpty());
00076    EXPECT_EQ(count, a.getCount());
00077    EXPECT_FALSE(a.isFirst());
00078    EXPECT_FALSE(a.isLast());
00079    EXPECT_TRUE(a.isTail());
00080 }

Here is the call graph for this function:

void container_test::List_test::verifyNonEmptyStateCoherence_tail ( List a,
int  count 
) [protected]

00070                                                                     {
00071    verifyNonEmptyStateCoherence_tail(*a, count);
00072 }

Here is the caller graph for this function:


Member Data Documentation

const int container_test::List_test::BIG_INDEX [static, protected]

const int container_test::List_test::INDEX_NOT_FOUND [static, protected]

const int container_test::List_test::KEY_4 [static, protected]

const string container_test::List_test::KEY_4_AS_STRING [static, protected]

const int container_test::List_test::NEGATIVE_INDEX [static, protected]

const int container_test::List_test::SOME_OTHER_INDEX [static, protected]

const int container_test::List_test::SOME_OTHER_KEY [static, protected]

const int container_test::List_test::ZERO_INDEX [static, protected]


The documentation for this class was generated from the following files:

Generated on Tue Jun 16 23:13:03 2009 by  doxygen 1.5.9