[Avida-SVN] r1131 - in extras: . source/targets/TestAvida source/testsuites source/testsuites/nAnalyze_dir source/testsuites/nAnalyze_dir/Brainstorm

avidaedward at myxo.css.msu.edu avidaedward at myxo.css.msu.edu
Mon Dec 11 19:36:01 PST 2006


Author: avidaedward
Date: 2006-12-11 22:36:01 -0500 (Mon, 11 Dec 2006)
New Revision: 1131

Added:
   extras/source/testsuites/nAGenotype.cpp
   extras/source/testsuites/nAnalyzeGenotype.cpp
   extras/source/testsuites/nAnalyze_dir/
   extras/source/testsuites/nAnalyze_dir/Brainstorm/
   extras/source/testsuites/nAnalyze_dir/Brainstorm/RunningAnalyze/
Modified:
   extras/
   extras/SConscript
   extras/source/targets/TestAvida/TestAvida.cpp
   extras/source/testsuites/nBlah.cpp
Log:
 r1122 at Kaben-Nanlohys-MacBook-Pro-15:  kaben | 2006-12-08 21:45:59 -0500
 Addition of tests for nAnalyzeGenotypeLink and nAnalyzeGenotype.



Property changes on: extras
___________________________________________________________________
Name: svk:merge
   - 079b078a-dbed-46b9-b3da-37668d4295ca:/avida/local/extras:1120
   + 079b078a-dbed-46b9-b3da-37668d4295ca:/avida/local/extras:1122

Modified: extras/SConscript
===================================================================
--- extras/SConscript	2006-12-12 03:35:59 UTC (rev 1130)
+++ extras/SConscript	2006-12-12 03:36:01 UTC (rev 1131)
@@ -109,6 +109,10 @@
 # Library of test suites.
 testsuites_srcs = [
   'source/testsuites/nAnalyze.cpp',
+  # For unknown reasons, scons is not happy if the following file is
+  # renamed to "nAnalyzeGenotype.cpp". @kgn
+  'source/testsuites/nBlah.cpp',
+  # "nAGenotype.cpp" doesn't work either. @kgn
   'source/testsuites/nChangeList.cpp',
   'source/testsuites/nDataEntry.cpp',
   'source/testsuites/nDataFile.cpp',

Modified: extras/source/targets/TestAvida/TestAvida.cpp
===================================================================
--- extras/source/targets/TestAvida/TestAvida.cpp	2006-12-12 03:35:59 UTC (rev 1130)
+++ extras/source/targets/TestAvida/TestAvida.cpp	2006-12-12 03:36:01 UTC (rev 1131)
@@ -13,6 +13,7 @@
 /* Declare the testsuites collections. */
 /* This is only necessary for loading tests in otherwise dead code. */
 namespace nAnalyze { void PhysicalLink(); }
+namespace nAnalyzeGenotype { void PhysicalLink(); }
 namespace nChangeList { void PhysicalLink(); }
 namespace nDataEntry { void PhysicalLink(); }
 namespace nDataFile { void PhysicalLink(); }
@@ -30,6 +31,7 @@
   /* Load the testsuites collections. */
   /* This is only necessary for loading tests in otherwise dead code. */
   nAnalyze::PhysicalLink();
+  nAnalyzeGenotype::PhysicalLink();
   nChangeList::PhysicalLink();
   nDataEntry::PhysicalLink();
   nDataFile::PhysicalLink();

Added: extras/source/testsuites/nAGenotype.cpp
===================================================================
--- extras/source/testsuites/nAGenotype.cpp	2006-12-12 03:35:59 UTC (rev 1130)
+++ extras/source/testsuites/nAGenotype.cpp	2006-12-12 03:36:01 UTC (rev 1131)
@@ -0,0 +1,53 @@
+#include "cAnalyzeGenotype.h"
+
+#include "cTestLib.h"
+
+#include <iostream>
+
+
+using namespace std;
+
+/* Tests. */
+namespace nAnalyzeGenotype {
+/* Brainstorms. {{{1 */
+  /* cAnalyzeGenotype_Brainstorm_HelloWorld {{{2 */
+  namespace Brainstorm_HelloWorld {
+    void test(const cStringList &attrs){
+      if(!attrs.HasString("HelloWorld")){
+        cout << "XXX Skipping HelloWorld test." << endl;
+        return;
+      }
+      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
+      /* Make sure testing is working with successes and failures. @kgn */
+      TEST(true);
+      TEST(false);
+    }
+    cAddTestSuite t("cAnalyzeGenotype_Brainstorm_HelloWorld", test);
+  }
+
+/* Unit tests. {{{1 */
+  /* cAnalyzeGenotype_UnitTest_HelloWorld {{{2 */
+  namespace UnitTest_HelloWorld {
+    void test(const cStringList &attrs){
+      if(!attrs.HasString("HelloWorld")){
+        cout << "XXX Skipping HelloWorld test." << endl;
+        return;
+      }
+      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
+      /* Make sure testing is working with successes and failures. @kgn */
+      TEST(true);
+      TEST(false);
+    }
+    cAddTestSuite t("cAnalyzeGenotype_UnitTest_HelloWorld", test);
+  }
+
+  // }}}1
+  /*
+  This function does nothing;
+  but if the compiler sees that this function is called, then the
+  compiler will also connect the above tests to the testing library.
+  */
+  void PhysicalLink(){}
+}
+
+

Added: extras/source/testsuites/nAnalyzeGenotype.cpp
===================================================================
--- extras/source/testsuites/nAnalyzeGenotype.cpp	2006-12-12 03:35:59 UTC (rev 1130)
+++ extras/source/testsuites/nAnalyzeGenotype.cpp	2006-12-12 03:36:01 UTC (rev 1131)
@@ -0,0 +1,348 @@
+//
+//#include "cAnalyze.h"
+//
+//#include "cAvidaConfig.h"
+//#include "cDefaultAnalyzeDriver.h"
+//#include "cDefaultRunDriver.h"
+//#include "cDrivermanager.h"
+//#include "cTestLib.h"
+//#include "cXMLArchive.h"
+//#include "cWorld.h"
+//
+//#include <iostream>
+//#include <fstream>
+//
+//using namespace std;
+//
+///* Tests. */
+//namespace nBlah {
+///* Test-helpers. {{{1 */
+//  /* save_stuff {{{2 */
+//  template <class T>
+//  void save_stuff(const T &s, const char * filename){
+//    std::ofstream ofs(filename);
+//    cXMLOArchive oa(ofs);
+//    oa.ArkvObj("cBlah_Archive", s);
+//  }
+//
+//  /* restore_stuff {{{2 */
+//  template <class T>
+//  void restore_stuff(T &s, const char * filename) {
+//    std::ifstream ifs(filename);
+//    cXMLIArchive ia(ifs);
+//    ia.ArkvObj("cBlah_Archive", s);
+//  }
+//
+///* Brainstorms. {{{1 */
+//  /* cBlah_Brainstorm_HelloWorld {{{2 */
+//  namespace Brainstorm_HelloWorld {
+//    void test(const cStringList &attrs){
+//      if(!attrs.HasString("HelloWorld")){
+//        cout << "XXX Skipping HelloWorld test." << endl;
+//        return;
+//      }
+//      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
+//      /* Make sure testing is working with successes and failures. @kgn */
+//      TEST(true);
+//      TEST(false);
+//    }
+//    cAddTestSuite t("cBlah_Brainstorm_HelloWorld", test);
+//  }
+//
+//  /* cBlah_Brainstorm_RunningAnalyze {{{2 */
+//  namespace Brainstorm_RunningAnalyze {
+//    void test(){
+//      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
+//      
+//      char * argv[] = {
+//        "cBlah_Brainstorm_RunningAnalyze",
+//      };
+//      int argc = sizeof(argv)/sizeof(char *);
+//
+//      cDriverManager::Initialize();
+//      cWorld *world = new cWorld(
+//        cAvidaConfig::LoadWithCmdLineArgs(argc, argv)
+//      );
+//      cAvidaDriver* driver = new cDefaultAnalyzeDriver(
+//        world,
+//        (world->GetConfig().ANALYZE_MODE.Get() == 2)
+//      );
+//
+//      driver->Run();
+//
+//      delete driver;
+//      delete world;
+//    }
+//    cAddTestSuite t("cBlah_Brainstorm_RunningAnalyze", test);
+//  }
+//
+//  /* cBlah_Brainstorm_CumulativeStemminess {{{2 */
+//  namespace Brainstorm_CumulativeStemminess {
+//    void test(){
+//      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
+//
+//      /*
+//      Initialize
+//      */
+//      cWorld world();
+//
+//      
+//      //cAnalyzeGenotype * genotype = NULL;
+//      //tListIterator<cAnalyzeGenotype> batch_it(batch[cur_batch].List());
+//      //const int num_gens = batch[cur_batch].List().GetSize();
+//      //
+//      //// Put all of the genotypes in an array for easy reference and collect
+//      //// other information on them as we process them.
+//      //tArray<cAnalyzeGenotype *> gen_array(num_gens);
+//      //tHashTable<int, int> id_hash;  // Store array pos for each id.
+//      //tArray<int> id_array(num_gens), pid_array(num_gens);
+//      //tArray<int> depth_array(num_gens), birth_array(num_gens);
+//      //int array_pos = 0;
+//      //while ((genotype = batch_it.Next()) != NULL) {
+//      //  // Put the genotype in an array.
+//      //  gen_array[array_pos] = genotype;
+//      //  id_hash.Add(genotype->GetID(), array_pos);
+//      //  id_array[array_pos] = genotype->GetID();
+//      //  pid_array[array_pos] = genotype->GetParentID();
+//      //  depth_array[array_pos] = genotype->GetDepth();
+//      //  birth_array[array_pos] = genotype->GetUpdateBorn();
+//      //  array_pos++;
+//      //}
+//
+//      //// Now collect information about the offspring of each individual.
+//      //tArray<int> ppos_array(num_gens), offspring_count(num_gens);
+//      //offspring_count.SetAll(0);
+//      //for (int pos = 0; pos < num_gens; pos++) {
+//      //  int parent_id = gen_array[pos]->GetParentID();
+//      //  if (parent_id == -1) {  // Organism has no parent (i.e., ancestor)
+//      //    ppos_array[pos] = -1;
+//      //    continue;
+//      //  }
+//      //  int parent_pos = -1;
+//      //  id_hash.Find(parent_id, parent_pos);
+//      //  ppos_array[pos] = parent_pos;
+//      //  offspring_count[parent_pos]++;
+//      //}
+//
+//      //// For each genotype, figure out how far back you need to go to get to a
+//      //// branch point.
+//      //tArray<int> branch_dist_array(num_gens);
+//      //tArray<int> branch_pos_array(num_gens);
+//      //branch_dist_array.SetAll(-1);
+//      //branch_pos_array.SetAll(-1);
+//      //bool found = true;
+//      //int loop_count = 0;
+//      //while (found == true) {
+//      //  found = false;
+//      //  for (int pos = 0; pos < num_gens; pos++) {
+//      //    if (branch_dist_array[pos] > -1) continue; // continue if its set.
+//      //    found = true;
+//      //    int parent_pos = ppos_array[pos];
+//      //    if (parent_pos == -1) branch_dist_array[pos] = 0;  // Org is root.
+//      //    else if (offspring_count[parent_pos] > 1) {        // Parent is branch.
+//	    //branch_dist_array[pos] = 1;
+//	    //branch_pos_array[pos] = parent_pos;
+//      //    }
+//      //    else if (branch_dist_array[parent_pos] > -1) {     // Parent calculated.
+//	    //branch_dist_array[pos] = branch_dist_array[parent_pos]+1;
+//	    //branch_pos_array[pos] = branch_pos_array[parent_pos];
+//      //    }
+//      //    // Otherwise, we are not yet ready to calculate this entry.
+//      //  }
+//      //  loop_count++;
+//      //}
+//
+//      //
+//      //// Cumulative Stemminess
+//      //for (int pos = 0; pos < num_gens; pos++) {
+//      //  // We're only interested in internal n-furcating nodes.
+//      //  if (pid_array[pos] == -1) continue;  // Don't want root.
+//      //  if (offspring_count[pos] <= 1) continue; // No leaves or nonfurcating nodes
+//
+//      //  // @CAO Find distance to all children.
+//      //  // @CAO Find distance to parent branch.
+//      //  // @CAO DO math.
+//      //}
+//
+//
+//      //cout << "LOOP COUNT:" << loop_count << endl;
+//      //for (int i = 0; i < num_gens; i++) {
+//      //  int branch_pos = branch_pos_array[i];
+//      //  int branch_id = (branch_pos == -1) ? -1 : id_array[branch_pos];
+//      //  cout << i << " "
+//	    // << id_array[i] << " "
+//	    // << offspring_count[i] << " "
+//	    // << branch_dist_array[i] << " "
+//	    // << branch_id << " "
+//	    // << endl;
+//      //}
+//
+//      /* Make sure testing is working with successes and failures. @kgn */
+//      TEST(true);
+//      TEST(false);
+//    }
+//    cAddTestSuite t("cBlah_Brainstorm_CumulativeStemminess", test);
+//  }
+//
+///* Unit tests. {{{1 */
+//  /* cBlah_UnitTest_HelloWorld {{{2 */
+//  namespace UnitTest_HelloWorld {
+//    void test(const cStringList &attrs){
+//      if(!attrs.HasString("HelloWorld")){
+//        cout << "XXX Skipping HelloWorld test." << endl;
+//        return;
+//      }
+//      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
+//      /* Make sure testing is working with successes and failures. @kgn */
+//      TEST(true);
+//      TEST(false);
+//    }
+//    cAddTestSuite t("cBlah_UnitTest_HelloWorld", test);
+//  }
+//
+//  /* cBlah_UnitTest_cAvidaConfigDestruction {{{2 */
+//  namespace UnitTest_cAvidaConfigDestruction {
+//    void test(const cStringList &attrs){
+//      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
+//      /* Make sure testing is working with successes and failures. @kgn */
+//
+//      cAvidaConfig* cfg = new cAvidaConfig();
+//      delete cfg;
+//    }
+//    cAddTestSuite t("cBlah_UnitTest_cAvidaConfigDestruction", test);
+//  }
+//
+//  /* cBlah_UnitTest_Destructor {{{2 */
+//  namespace UnitTest_Destructor {
+//    void test(){
+//      cout << "FIXME : interim test. I'm trying to track-down" << endl;
+//      cout << "bad destruction of cWorld. When I figure out" << endl;
+//      cout << "what's wrong, move this test to reflect the" << endl;
+//      cout << "source of the bug. @kgn" << endl;
+//      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
+//
+//      char * argv[] = {
+//        "cBlah_Brainstorm_RunningAnalyze",
+//        "-c", "gcs_avida.cfg",
+//      };
+//      int argc = sizeof(argv)/sizeof(char *);
+//
+//      cout << "argc : " << argc << endl;
+//
+//      cDriverManager::Initialize();
+//      cWorld *world = new cWorld(
+//        cAvidaConfig::LoadWithCmdLineArgs(argc, argv)
+//      );
+//      cAvidaDriver* driver = NULL;
+//
+//      if (world->GetConfig().ANALYZE_MODE.Get() > 0) {
+//        driver = new cDefaultAnalyzeDriver(world, (world->GetConfig().ANALYZE_MODE.Get() == 2));
+//      } else {
+//        driver = new cDefaultRunDriver(world);
+//      }
+//  
+//      driver->Run();
+//
+//      delete driver;
+//      delete world;
+//    }
+//    cAddTestSuite t("cBlah_UnitTest_Destructor", test);
+//  }
+//
+//  /* cBlah_UnitTest_Archiving {{{2 */
+//  namespace UnitTest_Archiving {
+//    void test(const cStringList &attrs){
+//      if(!attrs.HasString("Template")){
+//        cout << "XXX Skipping Template test." << endl;
+//        return;
+//      }
+//#   if !ENABLE_SERIALIZATION
+//      cout << "XXX : Test skipped because serialization is disabled." << endl;
+//#   else // ENABLE_SERIALIZATION
+//      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
+//      //std::string filename("./cBlah_basic_serialization.xml");
+//
+//      //{
+//      //  cAnalyze o();
+//      //  save_stuff<>(o, filename.c_str());
+//      //}
+//
+//      //{
+//      //  cAnalyze o;
+//
+//      //  restore_stuff<>(o, filename.c_str());
+//      //  TEST(true);
+//      //}
+//
+//      //std::remove(filename.c_str());
+//#   endif // ENABLE_SERIALIZATION
+//    }
+//    cAddTestSuite t("cBlah_UnitTest_Archiving", test);
+//  }
+//
+//  // }}}1
+//  /*
+//  This function does nothing;
+//  but if the compiler sees that this function is called, then the
+//  compiler will also connect the above tests to the testing library.
+//  */
+//  void PhysicalLink(){}
+//}
+//
+//
+
+//static int icky;
+
+#include "cAnalyzeGenotype.h"
+
+#include "cTestLib.h"
+
+#include <iostream>
+
+
+using namespace std;
+
+/* Tests. */
+namespace nAnalyzeGenotype {
+/* Brainstorms. {{{1 */
+  /* cAnalyzeGenotype_Brainstorm_HelloWorld {{{2 */
+  namespace Brainstorm_HelloWorld {
+    void test(const cStringList &attrs){
+      if(!attrs.HasString("HelloWorld")){
+        cout << "XXX Skipping HelloWorld test." << endl;
+        return;
+      }
+      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
+      /* Make sure testing is working with successes and failures. @kgn */
+      TEST(true);
+      TEST(false);
+    }
+    cAddTestSuite t("cAnalyzeGenotype_Brainstorm_HelloWorld", test);
+  }
+
+/* Unit tests. {{{1 */
+  /* cAnalyzeGenotype_UnitTest_HelloWorld {{{2 */
+  namespace UnitTest_HelloWorld {
+    void test(const cStringList &attrs){
+      if(!attrs.HasString("HelloWorld")){
+        cout << "XXX Skipping HelloWorld test." << endl;
+        return;
+      }
+      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
+      /* Make sure testing is working with successes and failures. @kgn */
+      TEST(true);
+      TEST(false);
+    }
+    cAddTestSuite t("cAnalyzeGenotype_UnitTest_HelloWorld", test);
+  }
+
+  // }}}1
+  /*
+  This function does nothing;
+  but if the compiler sees that this function is called, then the
+  compiler will also connect the above tests to the testing library.
+  */
+  void PhysicalLink(){}
+}
+
+


Property changes on: extras/source/testsuites/nAnalyzeGenotype.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/cpp

Modified: extras/source/testsuites/nBlah.cpp
===================================================================
--- extras/source/testsuites/nBlah.cpp	2006-12-12 03:35:59 UTC (rev 1130)
+++ extras/source/testsuites/nBlah.cpp	2006-12-12 03:36:01 UTC (rev 1131)
@@ -1,39 +1,20 @@
-#include "cAnalyze.h"
+#include "cAnalyzeGenotype.h"
 
-#include "cAvidaConfig.h"
-#include "cDefaultAnalyzeDriver.h"
-#include "cDefaultRunDriver.h"
 #include "cDrivermanager.h"
+#include "cHardwareManager.h"
 #include "cTestLib.h"
-#include "cXMLArchive.h"
 #include "cWorld.h"
 
 #include <iostream>
-#include <fstream>
+#include <assert.h>
 
+
 using namespace std;
 
 /* Tests. */
-namespace nAnalyze {
-/* Test-helpers. {{{1 */
-  /* save_stuff {{{2 */
-  template <class T>
-  void save_stuff(const T &s, const char * filename){
-    std::ofstream ofs(filename);
-    cXMLOArchive oa(ofs);
-    oa.ArkvObj("cAnalyze_Archive", s);
-  }
-
-  /* restore_stuff {{{2 */
-  template <class T>
-  void restore_stuff(T &s, const char * filename) {
-    std::ifstream ifs(filename);
-    cXMLIArchive ia(ifs);
-    ia.ArkvObj("cAnalyze_Archive", s);
-  }
-
+namespace nAnalyzeGenotype {
 /* Brainstorms. {{{1 */
-  /* cAnalyze_Brainstorm_HelloWorld {{{2 */
+  /* cAnalyzeGenotype_Brainstorm_HelloWorld {{{2 */
   namespace Brainstorm_HelloWorld {
     void test(const cStringList &attrs){
       if(!attrs.HasString("HelloWorld")){
@@ -45,238 +26,985 @@
       TEST(true);
       TEST(false);
     }
-    cAddTestSuite t("cAnalyze_Brainstorm_HelloWorld", test);
+    cAddTestSuite t("cAnalyzeGenotype_Brainstorm_HelloWorld", test);
   }
+  /* cAnalyzeGenotype_Brainstorm_cAnalyzeGenotypeLink {{{2 */
 
-  /* cAnalyze_Brainstorm_RunningAnalyze {{{2 */
-  namespace Brainstorm_RunningAnalyze {
+  /*
+  XXX Questions:
+  - Should I add Verify() or Okay() functions?
+
+  - We have copy constructor semantics in cAnalyzeGenotype. What does
+    this mean for semantics of cAnalyzeGenotypeLink operations?
+    - I think it means we have possible automatic inconsistency:
+
+      we can have two distinct cAnalyzeGenotype instances representing
+      the same genotype (i.e., same ID). In that case we'll have
+      inconsistency in a lineage tree containing both instances.
+
+    - If we assume that no batch contains multiple instances of the same
+      genotype, we have no inconsistency.
+
+      Do we have any batch operations which could produce multiple
+      instances of the same genotype?
+  */
+
+  /*
+  XXX Done:
+  - Verify cAnalyzeGenotype destructor properly destroys
+    cAnalyzeGenotypeLink.
+  - Verify cAnalyzeGenotype constructor properly initializes
+    cAnalyzeGenotypeLink.
+  - Verify cAnalyzeGenotype::LinkParent(0).
+  - Verify that adding same child twice does not create two entries in
+    child list.
+  - Write / verify cAnalyzeGenotypeLink constructor.
+  - Write / verify cAnalyzeGenotypeLink::SetParent().
+  - Write / verify cAnalyzeGenotypeLink::GetParent().
+  - Write / verify cAnalyzeGenotypeLink::GetChildList().
+  - Write / verify cAnalyzeGenotypeLink::ClearChildren().
+  - Write / verify cAnalyzeGenotypeLink::FindChild().
+  - Write / verify cAnalyzeGenotypeLink::RemoveChild().
+  - Write / verify cAnalyzeGenotypeLink::AddChild().
+  - Write / verify cAnalyzeGenotype::GetLink().
+  - Write / verify cAnalyzeGenotype::LinkParent().
+  - Write / verify cAnalyzeGenotype::LinkChild().
+  - Write / verify cAnalyzeGenotype::UnlinkParent().
+  - Write / verify cAnalyzeGenotype::UnlinkChildren().
+  - Write / verify cAnalyzeGenotype::Unlink().
+  - Write / verify cAnalyzeGenotype::GetParent().
+  - Write / verify cAnalyzeGenotype::HasChild().
+  - Write / verify cAnalyzeGenotype::UnlinkChild().
+  - Write / verify cAnalyzeGenotype::GetChildList().
+  */
+
+  namespace Brainstorm_cAnalyzeGenotypeLink {
+    /*
+    This is a convenience function to instantiate cAnalyzeGenotype
+    instances.
+    */
+    cAnalyzeGenotype AGFactory(cWorld &world, cString symbol_string){
+      return cAnalyzeGenotype(&world, symbol_string, world.GetHardwareManager().GetInstSet());
+    }
     void test(){
-      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
-      
-      char * argv[] = {
-        "cAnalyze_Brainstorm_RunningAnalyze",
-      };
+      /* Common test setup. {{{3 */
+      /*
+      cWorld instance to give us a working context.
+      */
+      char * argv[] = { "cAnalyzeGenotype_Brainstorm_cAnalyzeGenotypeLink", };
       int argc = sizeof(argv)/sizeof(char *);
 
       cDriverManager::Initialize();
-      cWorld *world = new cWorld(
-        cAvidaConfig::LoadWithCmdLineArgs(argc, argv)
-      );
-      cAvidaDriver* driver = new cDefaultAnalyzeDriver(
-        world,
-        (world->GetConfig().ANALYZE_MODE.Get() == 2)
-      );
+      cWorld *world = new cWorld( cAvidaConfig::LoadWithCmdLineArgs(argc, argv));
 
-      driver->Run();
+      /* Test very basic cAnalyzeGenotypeLink functions GetChildList(), SetParent(), FindChild(), RemoveChild(), ClearChildren(). {{{3 */
+      if(true){
+        cAnalyzeGenotype
+          p(AGFactory(*world, "ccc")),
+          f1a(AGFactory(*world, "ccc")),
+          f1b(AGFactory(*world, "ccc")),
+          f2a(AGFactory(*world, "ccc")),
+          f2b(AGFactory(*world, "ccc"));
 
-      delete driver;
-      delete world;
-    }
-    cAddTestSuite t("cAnalyze_Brainstorm_RunningAnalyze", test);
-  }
+        cAnalyzeGenotypeLink pl, f1al, f1bl, f2al, f2bl;
 
-  /* cAnalyze_Brainstorm_CumulativeStemminess {{{2 */
-  namespace Brainstorm_CumulativeStemminess {
-    void test(){
-      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
+        pl.SetParent(0);
 
-      /*
-      Initialize
-      */
-      cWorld world();
+        pl.GetChildList().PushRear(&f1a);
+        f1al.SetParent(&p);
 
-      
-      //cAnalyzeGenotype * genotype = NULL;
-      //tListIterator<cAnalyzeGenotype> batch_it(batch[cur_batch].List());
-      //const int num_gens = batch[cur_batch].List().GetSize();
-      //
-      //// Put all of the genotypes in an array for easy reference and collect
-      //// other information on them as we process them.
-      //tArray<cAnalyzeGenotype *> gen_array(num_gens);
-      //tHashTable<int, int> id_hash;  // Store array pos for each id.
-      //tArray<int> id_array(num_gens), pid_array(num_gens);
-      //tArray<int> depth_array(num_gens), birth_array(num_gens);
-      //int array_pos = 0;
-      //while ((genotype = batch_it.Next()) != NULL) {
-      //  // Put the genotype in an array.
-      //  gen_array[array_pos] = genotype;
-      //  id_hash.Add(genotype->GetID(), array_pos);
-      //  id_array[array_pos] = genotype->GetID();
-      //  pid_array[array_pos] = genotype->GetParentID();
-      //  depth_array[array_pos] = genotype->GetDepth();
-      //  birth_array[array_pos] = genotype->GetUpdateBorn();
-      //  array_pos++;
-      //}
+        pl.GetChildList().PushRear(&f1b);
+        f1bl.SetParent(&p);
 
-      //// Now collect information about the offspring of each individual.
-      //tArray<int> ppos_array(num_gens), offspring_count(num_gens);
-      //offspring_count.SetAll(0);
-      //for (int pos = 0; pos < num_gens; pos++) {
-      //  int parent_id = gen_array[pos]->GetParentID();
-      //  if (parent_id == -1) {  // Organism has no parent (i.e., ancestor)
-      //    ppos_array[pos] = -1;
-      //    continue;
-      //  }
-      //  int parent_pos = -1;
-      //  id_hash.Find(parent_id, parent_pos);
-      //  ppos_array[pos] = parent_pos;
-      //  offspring_count[parent_pos]++;
-      //}
+        f1al.GetChildList().PushRear(&f2a);
+        f2al.SetParent(&f1a);
 
-      //// For each genotype, figure out how far back you need to go to get to a
-      //// branch point.
-      //tArray<int> branch_dist_array(num_gens);
-      //tArray<int> branch_pos_array(num_gens);
-      //branch_dist_array.SetAll(-1);
-      //branch_pos_array.SetAll(-1);
-      //bool found = true;
-      //int loop_count = 0;
-      //while (found == true) {
-      //  found = false;
-      //  for (int pos = 0; pos < num_gens; pos++) {
-      //    if (branch_dist_array[pos] > -1) continue; // continue if its set.
-      //    found = true;
-      //    int parent_pos = ppos_array[pos];
-      //    if (parent_pos == -1) branch_dist_array[pos] = 0;  // Org is root.
-      //    else if (offspring_count[parent_pos] > 1) {        // Parent is branch.
-	    //branch_dist_array[pos] = 1;
-	    //branch_pos_array[pos] = parent_pos;
-      //    }
-      //    else if (branch_dist_array[parent_pos] > -1) {     // Parent calculated.
-	    //branch_dist_array[pos] = branch_dist_array[parent_pos]+1;
-	    //branch_pos_array[pos] = branch_pos_array[parent_pos];
-      //    }
-      //    // Otherwise, we are not yet ready to calculate this entry.
-      //  }
-      //  loop_count++;
-      //}
+        f1al.GetChildList().PushRear(&f2b);
+        f2bl.SetParent(&f1a);
 
-      //
-      //// Cumulative Stemminess
-      //for (int pos = 0; pos < num_gens; pos++) {
-      //  // We're only interested in internal n-furcating nodes.
-      //  if (pid_array[pos] == -1) continue;  // Don't want root.
-      //  if (offspring_count[pos] <= 1) continue; // No leaves or nonfurcating nodes
+        /* 
+        pl should have no parent
+        pl should have children f1a and f1b
+        f1al should have parent p
+        f1al should have children f2a and f2b
+        f1bl should have parent p
+        f1bl should have no children
+        f2al should have parent f1a
+        f2al should have no children
+        f2bl should have parent f1a
+        f2bl should have no children
+        */
+        if(true){
+          TEST(pl.GetParent() == 0);
+          TEST(pl.GetChildList().FindPtr(&p) == 0);
+          TEST(pl.GetChildList().FindPtr(&f1a) == &f1a);
+          TEST(pl.GetChildList().FindPtr(&f1b) == &f1b);
+          TEST(pl.GetChildList().FindPtr(&f2a) == 0);
+          TEST(pl.GetChildList().FindPtr(&f2b) == 0);
 
-      //  // @CAO Find distance to all children.
-      //  // @CAO Find distance to parent branch.
-      //  // @CAO DO math.
-      //}
+          TEST(f1al.GetParent() == &p);
+          TEST(f1al.GetChildList().FindPtr(&p) == 0);
+          TEST(f1al.GetChildList().FindPtr(&f1a) == 0);
+          TEST(f1al.GetChildList().FindPtr(&f1b) == 0);
+          TEST(f1al.GetChildList().FindPtr(&f2a) == &f2a);
+          TEST(f1al.GetChildList().FindPtr(&f2b) == &f2b);
 
+          TEST(f1bl.GetParent() == &p);
+          TEST(f1bl.GetChildList().FindPtr(&p) == 0);
+          TEST(f1bl.GetChildList().FindPtr(&f1a) == 0);
+          TEST(f1bl.GetChildList().FindPtr(&f1b) == 0);
+          TEST(f1bl.GetChildList().FindPtr(&f2a) == 0);
+          TEST(f1bl.GetChildList().FindPtr(&f2b) == 0);
 
-      //cout << "LOOP COUNT:" << loop_count << endl;
-      //for (int i = 0; i < num_gens; i++) {
-      //  int branch_pos = branch_pos_array[i];
-      //  int branch_id = (branch_pos == -1) ? -1 : id_array[branch_pos];
-      //  cout << i << " "
-	    // << id_array[i] << " "
-	    // << offspring_count[i] << " "
-	    // << branch_dist_array[i] << " "
-	    // << branch_id << " "
-	    // << endl;
-      //}
+          TEST(f2al.GetParent() == &f1a);
+          TEST(f2al.GetChildList().FindPtr(&p) == 0);
+          TEST(f2al.GetChildList().FindPtr(&f1a) == 0);
+          TEST(f2al.GetChildList().FindPtr(&f1b) == 0);
+          TEST(f2al.GetChildList().FindPtr(&f2a) == 0);
+          TEST(f2al.GetChildList().FindPtr(&f2b) == 0);
 
-      /* Make sure testing is working with successes and failures. @kgn */
-      TEST(true);
-      TEST(false);
-    }
-    cAddTestSuite t("cAnalyze_Brainstorm_CumulativeStemminess", test);
-  }
+          TEST(f2bl.GetParent() == &f1a);
+          TEST(f2bl.GetChildList().FindPtr(&p) == 0);
+          TEST(f2bl.GetChildList().FindPtr(&f1a) == 0);
+          TEST(f2bl.GetChildList().FindPtr(&f1b) == 0);
+          TEST(f2bl.GetChildList().FindPtr(&f2a) == 0);
+          TEST(f2bl.GetChildList().FindPtr(&f2b) == 0);
+        }
 
-/* Unit tests. {{{1 */
-  /* cAnalyze_UnitTest_HelloWorld {{{2 */
-  namespace UnitTest_HelloWorld {
-    void test(const cStringList &attrs){
-      if(!attrs.HasString("HelloWorld")){
-        cout << "XXX Skipping HelloWorld test." << endl;
-        return;
+        /* 
+        pl should have no parent
+        pl should have children f1a and f1b
+        f1al should have parent p
+        f1al should have children f2a and f2b
+        f1bl should have parent p
+        f1bl should have no children
+        f2al should have parent f1a
+        f2al should have no children
+        f2bl should have parent f1a
+        f2bl should have no children
+        */
+        {
+          TEST(pl.GetParent() == 0);
+          TEST(pl.FindChild(&p) == 0);
+          TEST(pl.FindChild(&f1a) == &f1a);
+          TEST(pl.FindChild(&f1b) == &f1b);
+          TEST(pl.FindChild(&f2a) == 0);
+          TEST(pl.FindChild(&f2b) == 0);
+
+          TEST(f1al.GetParent() == &p);
+          TEST(f1al.FindChild(&p) == 0);
+          TEST(f1al.FindChild(&f1a) == 0);
+          TEST(f1al.FindChild(&f1b) == 0);
+          TEST(f1al.FindChild(&f2a) == &f2a);
+          TEST(f1al.FindChild(&f2b) == &f2b);
+
+          TEST(f1bl.GetParent() == &p);
+          TEST(f1bl.FindChild(&p) == 0);
+          TEST(f1bl.FindChild(&f1a) == 0);
+          TEST(f1bl.FindChild(&f1b) == 0);
+          TEST(f1bl.FindChild(&f2a) == 0);
+          TEST(f1bl.FindChild(&f2b) == 0);
+
+          TEST(f2al.GetParent() == &f1a);
+          TEST(f2al.FindChild(&p) == 0);
+          TEST(f2al.FindChild(&f1a) == 0);
+          TEST(f2al.FindChild(&f1b) == 0);
+          TEST(f2al.FindChild(&f2a) == 0);
+          TEST(f2al.FindChild(&f2b) == 0);
+
+          TEST(f2bl.GetParent() == &f1a);
+          TEST(f2bl.FindChild(&p) == 0);
+          TEST(f2bl.FindChild(&f1a) == 0);
+          TEST(f2bl.FindChild(&f1b) == 0);
+          TEST(f2bl.FindChild(&f2a) == 0);
+          TEST(f2bl.FindChild(&f2b) == 0);
+        }
+
+        pl.ClearChildren();
+        /* 
+        pl should have no parent
+        pl should have no children
+        f1al should still have parent p
+        f1al should have children f2a and f2b
+        f1bl should still have parent p
+        f1bl should have no children
+        f2al should have parent f1a
+        f2al should have no children
+        f2bl should have parent f1a
+        f2bl should have no children
+        */
+        {
+          TEST(pl.GetParent() == 0);
+          TEST(pl.FindChild(&p) == 0);
+          TEST(pl.FindChild(&f1a) == 0);
+          TEST(pl.FindChild(&f1b) == 0);
+          TEST(pl.FindChild(&f2a) == 0);
+          TEST(pl.FindChild(&f2b) == 0);
+
+          TEST(f1al.GetParent() == &p);
+          TEST(f1al.FindChild(&p) == 0);
+          TEST(f1al.FindChild(&f1a) == 0);
+          TEST(f1al.FindChild(&f1b) == 0);
+          TEST(f1al.FindChild(&f2a) == &f2a);
+          TEST(f1al.FindChild(&f2b) == &f2b);
+
+          TEST(f1bl.GetParent() == &p);
+          TEST(f1bl.FindChild(&p) == 0);
+          TEST(f1bl.FindChild(&f1a) == 0);
+          TEST(f1bl.FindChild(&f1b) == 0);
+          TEST(f1bl.FindChild(&f2a) == 0);
+          TEST(f1bl.FindChild(&f2b) == 0);
+
+          TEST(f2al.GetParent() == &f1a);
+          TEST(f2al.FindChild(&p) == 0);
+          TEST(f2al.FindChild(&f1a) == 0);
+          TEST(f2al.FindChild(&f1b) == 0);
+          TEST(f2al.FindChild(&f2a) == 0);
+          TEST(f2al.FindChild(&f2b) == 0);
+
+          TEST(f2bl.GetParent() == &f1a);
+          TEST(f2bl.FindChild(&p) == 0);
+          TEST(f2bl.FindChild(&f1a) == 0);
+          TEST(f2bl.FindChild(&f1b) == 0);
+          TEST(f2bl.FindChild(&f2a) == 0);
+          TEST(f2bl.FindChild(&f2b) == 0);
+        }
+
+        /*
+        pl doesn't have f1a as a child,
+        but f1al has f2a as a child.
+        */
+        TEST(0 == pl.RemoveChild(&f1a));
+        TEST(&f2a == f1al.RemoveChild(&f2a));
+        /* 
+        pl should have no parent
+        pl should have no children
+        f1al should still have parent p
+        f1al should still have child f2b
+        f1bl should still have parent p
+        f1bl should have no children
+        f2al should have parent f1a
+        f2al should have no children
+        f2bl should have parent f1a
+        f2bl should have no children
+        */
+        {
+          TEST(pl.GetParent() == 0);
+          TEST(pl.FindChild(&p) == 0);
+          TEST(pl.FindChild(&f1a) == 0);
+          TEST(pl.FindChild(&f1b) == 0);
+          TEST(pl.FindChild(&f2a) == 0);
+          TEST(pl.FindChild(&f2b) == 0);
+
+          TEST(f1al.GetParent() == &p);
+          TEST(f1al.FindChild(&p) == 0);
+          TEST(f1al.FindChild(&f1a) == 0);
+          TEST(f1al.FindChild(&f1b) == 0);
+          TEST(f1al.FindChild(&f2a) == 0);
+          TEST(f1al.FindChild(&f2b) == &f2b);
+
+          TEST(f1bl.GetParent() == &p);
+          TEST(f1bl.FindChild(&p) == 0);
+          TEST(f1bl.FindChild(&f1a) == 0);
+          TEST(f1bl.FindChild(&f1b) == 0);
+          TEST(f1bl.FindChild(&f2a) == 0);
+          TEST(f1bl.FindChild(&f2b) == 0);
+
+          TEST(f2al.GetParent() == &f1a);
+          TEST(f2al.FindChild(&p) == 0);
+          TEST(f2al.FindChild(&f1a) == 0);
+          TEST(f2al.FindChild(&f1b) == 0);
+          TEST(f2al.FindChild(&f2a) == 0);
+          TEST(f2al.FindChild(&f2b) == 0);
+
+          TEST(f2bl.GetParent() == &f1a);
+          TEST(f2bl.FindChild(&p) == 0);
+          TEST(f2bl.FindChild(&f1a) == 0);
+          TEST(f2bl.FindChild(&f1b) == 0);
+          TEST(f2bl.FindChild(&f2a) == 0);
+          TEST(f2bl.FindChild(&f2b) == 0);
+        }
+
+        /* 
+        pl should have no parent
+        pl should have no children
+        f1al should still have parent p
+        f1al should still have child f2b
+        f1bl should still have parent p
+        f1bl should have no children
+        f2al should have parent f1a
+        f2al should have no children
+        f2bl should now have no parent
+        f2bl should have no children
+        */
+        f2bl.SetParent(0);
+        {
+          TEST(pl.GetParent() == 0);
+          TEST(pl.FindChild(&p) == 0);
+          TEST(pl.FindChild(&f1a) == 0);
+          TEST(pl.FindChild(&f1b) == 0);
+          TEST(pl.FindChild(&f2a) == 0);
+          TEST(pl.FindChild(&f2b) == 0);
+
+          TEST(f1al.GetParent() == &p);
+          TEST(f1al.FindChild(&p) == 0);
+          TEST(f1al.FindChild(&f1a) == 0);
+          TEST(f1al.FindChild(&f1b) == 0);
+          TEST(f1al.FindChild(&f2a) == 0);
+          TEST(f1al.FindChild(&f2b) == &f2b);
+
+          TEST(f1bl.GetParent() == &p);
+          TEST(f1bl.FindChild(&p) == 0);
+          TEST(f1bl.FindChild(&f1a) == 0);
+          TEST(f1bl.FindChild(&f1b) == 0);
+          TEST(f1bl.FindChild(&f2a) == 0);
+          TEST(f1bl.FindChild(&f2b) == 0);
+
+          TEST(f2al.GetParent() == &f1a);
+          TEST(f2al.FindChild(&p) == 0);
+          TEST(f2al.FindChild(&f1a) == 0);
+          TEST(f2al.FindChild(&f1b) == 0);
+          TEST(f2al.FindChild(&f2a) == 0);
+          TEST(f2al.FindChild(&f2b) == 0);
+
+          TEST(f2bl.GetParent() == 0);
+          TEST(f2bl.FindChild(&p) == 0);
+          TEST(f2bl.FindChild(&f1a) == 0);
+          TEST(f2bl.FindChild(&f1b) == 0);
+          TEST(f2bl.FindChild(&f2a) == 0);
+          TEST(f2bl.FindChild(&f2b) == 0);
+        }
+
       }
-      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
-      /* Make sure testing is working with successes and failures. @kgn */
-      TEST(true);
-      TEST(false);
-    }
-    cAddTestSuite t("cAnalyze_UnitTest_HelloWorld", test);
-  }
 
-  /* cAnalyze_UnitTest_cAvidaConfigDestruction {{{2 */
-  namespace UnitTest_cAvidaConfigDestruction {
-    void test(const cStringList &attrs){
-      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
-      /* Make sure testing is working with successes and failures. @kgn */
+      /* Test cAnalyzeGenotypeLink function AddChild(). {{{3 */
+      if(true){
+        cAnalyzeGenotype
+          p(AGFactory(*world, "ccc")),
+          f1a(AGFactory(*world, "ccc")),
+          f1b(AGFactory(*world, "ccc")),
+          f2a(AGFactory(*world, "ccc")),
+          f2b(AGFactory(*world, "ccc"));
+        cAnalyzeGenotypeLink pl, f1al, f1bl, f2al, f2bl;
 
-      cAvidaConfig* cfg = new cAvidaConfig();
-      delete cfg;
-    }
-    cAddTestSuite t("cAnalyze_UnitTest_cAvidaConfigDestruction", test);
-  }
+        pl.SetParent(0);
 
-  /* cAnalyze_UnitTest_Destructor {{{2 */
-  namespace UnitTest_Destructor {
-    void test(){
-      cout << "FIXME : interim test. I'm trying to track-down" << endl;
-      cout << "bad destruction of cWorld. When I figure out" << endl;
-      cout << "what's wrong, move this test to reflect the" << endl;
-      cout << "source of the bug. @kgn" << endl;
-      cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
+        pl.AddChild(&f1a);
+        f1al.SetParent(&p);
 
-      char * argv[] = {
-        "cAnalyze_Brainstorm_RunningAnalyze",
-        "-c", "gcs_avida.cfg",
-      };
-      int argc = sizeof(argv)/sizeof(char *);
+        pl.AddChild(&f1b);
+        f1bl.SetParent(&p);
 
-      cout << "argc : " << argc << endl;
+        f1al.AddChild(&f2a);
+        f2al.SetParent(&f1a);
 
-      cDriverManager::Initialize();
-      cWorld *world = new cWorld(
-        cAvidaConfig::LoadWithCmdLineArgs(argc, argv)
-      );
-      cAvidaDriver* driver = NULL;
+        f1al.AddChild(&f2b);
+        f2bl.SetParent(&f1a);
 
-      if (world->GetConfig().ANALYZE_MODE.Get() > 0) {
-        driver = new cDefaultAnalyzeDriver(world, (world->GetConfig().ANALYZE_MODE.Get() == 2));
-      } else {
-        driver = new cDefaultRunDriver(world);
+        /* 
+        pl should have no parent
+        pl should have children f1a and f1b
+        f1al should have parent p
+        f1al should have children f2a and f2b
+        f1bl should have parent p
+        f1bl should have no children
+        f2al should have parent f1a
+        f2al should have no children
+        f2bl should have parent f1a
+        f2bl should have no children
+        */
+        {
+          TEST(pl.GetParent() == 0);
+          TEST(pl.FindChild(&p) == 0);
+          TEST(pl.FindChild(&f1a) == &f1a);
+          TEST(pl.FindChild(&f1b) == &f1b);
+          TEST(pl.FindChild(&f2a) == 0);
+          TEST(pl.FindChild(&f2b) == 0);
+
+          TEST(f1al.GetParent() == &p);
+          TEST(f1al.FindChild(&p) == 0);
+          TEST(f1al.FindChild(&f1a) == 0);
+          TEST(f1al.FindChild(&f1b) == 0);
+          TEST(f1al.FindChild(&f2a) == &f2a);
+          TEST(f1al.FindChild(&f2b) == &f2b);
+
+          TEST(f1bl.GetParent() == &p);
+          TEST(f1bl.FindChild(&p) == 0);
+          TEST(f1bl.FindChild(&f1a) == 0);
+          TEST(f1bl.FindChild(&f1b) == 0);
+          TEST(f1bl.FindChild(&f2a) == 0);
+          TEST(f1bl.FindChild(&f2b) == 0);
+
+          TEST(f2al.GetParent() == &f1a);
+          TEST(f2al.FindChild(&p) == 0);
+          TEST(f2al.FindChild(&f1a) == 0);
+          TEST(f2al.FindChild(&f1b) == 0);
+          TEST(f2al.FindChild(&f2a) == 0);
+          TEST(f2al.FindChild(&f2b) == 0);
+
+          TEST(f2bl.GetParent() == &f1a);
+          TEST(f2bl.FindChild(&p) == 0);
+          TEST(f2bl.FindChild(&f1a) == 0);
+          TEST(f2bl.FindChild(&f1b) == 0);
+          TEST(f2bl.FindChild(&f2a) == 0);
+          TEST(f2bl.FindChild(&f2b) == 0);
+        }
       }
-  
-      driver->Run();
 
-      delete driver;
+      /* Test cAnalyzeGenotype functions UnlinkParent(), LinkChild(), GetLink(). {{{3 */
+      {
+        cAnalyzeGenotype
+          p(AGFactory(*world, "ccc")),
+          f1a(AGFactory(*world, "ccc")),
+          f1b(AGFactory(*world, "ccc")),
+          f2a(AGFactory(*world, "ccc")),
+          f2b(AGFactory(*world, "ccc"));
+
+        p.UnlinkParent();
+        // or p.LinkParent(0)...
+        p.LinkChild(f1a);
+        p.LinkChild(f1b);
+        f1a.LinkChild(f2a);
+        f1a.LinkChild(f2b);
+
+        /* 
+        p should have no parent
+        p should have children f1a and f1b
+        f1a should have parent p
+        f1a should have children f2a and f2b
+        f1b should have parent p
+        f1b should have no children
+        f2a should have parent f1a
+        f2a should have no children
+        f2b should have parent f1a
+        f2b should have no children
+        */
+        {
+          TEST(p.GetLink().GetParent() == 0);
+          TEST(p.GetLink().FindChild(&p) == 0);
+          TEST(p.GetLink().FindChild(&f1a) == &f1a);
+          TEST(p.GetLink().FindChild(&f1b) == &f1b);
+          TEST(p.GetLink().FindChild(&f2a) == 0);
+          TEST(p.GetLink().FindChild(&f2b) == 0);
+
+          TEST(f1a.GetLink().GetParent() == &p);
+          TEST(f1a.GetLink().FindChild(&p) == 0);
+          TEST(f1a.GetLink().FindChild(&f1a) == 0);
+          TEST(f1a.GetLink().FindChild(&f1b) == 0);
+          TEST(f1a.GetLink().FindChild(&f2a) == &f2a);
+          TEST(f1a.GetLink().FindChild(&f2b) == &f2b);
+
+          TEST(f1b.GetLink().GetParent() == &p);
+          TEST(f1b.GetLink().FindChild(&p) == 0);
+          TEST(f1b.GetLink().FindChild(&f1a) == 0);
+          TEST(f1b.GetLink().FindChild(&f1b) == 0);
+          TEST(f1b.GetLink().FindChild(&f2a) == 0);
+          TEST(f1b.GetLink().FindChild(&f2b) == 0);
+
+          TEST(f2a.GetLink().GetParent() == &f1a);
+          TEST(f2a.GetLink().FindChild(&p) == 0);
+          TEST(f2a.GetLink().FindChild(&f1a) == 0);
+          TEST(f2a.GetLink().FindChild(&f1b) == 0);
+          TEST(f2a.GetLink().FindChild(&f2a) == 0);
+          TEST(f2a.GetLink().FindChild(&f2b) == 0);
+
+          TEST(f2b.GetLink().GetParent() == &f1a);
+          TEST(f2b.GetLink().FindChild(&p) == 0);
+          TEST(f2b.GetLink().FindChild(&f1a) == 0);
+          TEST(f2b.GetLink().FindChild(&f1b) == 0);
+          TEST(f2b.GetLink().FindChild(&f2a) == 0);
+          TEST(f2b.GetLink().FindChild(&f2b) == 0);
+        }
+      }
+
+      /* Test cAnalyzeGenotype function LinkParent(). {{{3 */
+      {
+        cAnalyzeGenotype
+          p(AGFactory(*world, "ccc")),
+          f1a(AGFactory(*world, "ccc")),
+          f1b(AGFactory(*world, "ccc")),
+          f2a(AGFactory(*world, "ccc")),
+          f2b(AGFactory(*world, "ccc"));
+
+
+        p.UnlinkParent();
+        // or p.LinkParent(0)... ?
+        f1a.LinkParent(&p);
+        f1b.LinkParent(&p);
+        f2a.LinkParent(&f1a);
+        f2b.LinkParent(&f1a);
+
+        /* 
+        p should have no parent
+        p should have children f1a and f1b
+        f1a should have parent p
+        f1a should have children f2a and f2b
+        f1b should have parent p
+        f1b should have no children
+        f2a should have parent f1a
+        f2a should have no children
+        f2b should have parent f1a
+        f2b should have no children
+        */
+        {
+          TEST(p.GetLink().GetParent() == 0);
+          TEST(p.GetLink().FindChild(&p) == 0);
+          TEST(p.GetLink().FindChild(&f1a) == &f1a);
+          TEST(p.GetLink().FindChild(&f1b) == &f1b);
+          TEST(p.GetLink().FindChild(&f2a) == 0);
+          TEST(p.GetLink().FindChild(&f2b) == 0);
+
+          TEST(f1a.GetLink().GetParent() == &p);
+          TEST(f1a.GetLink().FindChild(&p) == 0);
+          TEST(f1a.GetLink().FindChild(&f1a) == 0);
+          TEST(f1a.GetLink().FindChild(&f1b) == 0);
+          TEST(f1a.GetLink().FindChild(&f2a) == &f2a);
+          TEST(f1a.GetLink().FindChild(&f2b) == &f2b);
+
+          TEST(f1b.GetLink().GetParent() == &p);
+          TEST(f1b.GetLink().FindChild(&p) == 0);
+          TEST(f1b.GetLink().FindChild(&f1a) == 0);
+          TEST(f1b.GetLink().FindChild(&f1b) == 0);
+          TEST(f1b.GetLink().FindChild(&f2a) == 0);
+          TEST(f1b.GetLink().FindChild(&f2b) == 0);
+
+          TEST(f2a.GetLink().GetParent() == &f1a);
+          TEST(f2a.GetLink().FindChild(&p) == 0);
+          TEST(f2a.GetLink().FindChild(&f1a) == 0);
+          TEST(f2a.GetLink().FindChild(&f1b) == 0);
+          TEST(f2a.GetLink().FindChild(&f2a) == 0);
+          TEST(f2a.GetLink().FindChild(&f2b) == 0);
+
+          TEST(f2b.GetLink().GetParent() == &f1a);
+          TEST(f2b.GetLink().FindChild(&p) == 0);
+          TEST(f2b.GetLink().FindChild(&f1a) == 0);
+          TEST(f2b.GetLink().FindChild(&f1b) == 0);
+          TEST(f2b.GetLink().FindChild(&f2a) == 0);
+          TEST(f2b.GetLink().FindChild(&f2b) == 0);
+        }
+      }
+
+      /* Test cAnalyzeGenotype function UnlinkChildren(), LinkParent(0). {{{3 */
+      {
+        cAnalyzeGenotype
+          p(AGFactory(*world, "ccc")),
+          f1a(AGFactory(*world, "ccc")),
+          f1b(AGFactory(*world, "ccc")),
+          f2a(AGFactory(*world, "ccc")),
+          f2b(AGFactory(*world, "ccc"));
+
+
+        p.UnlinkParent();
+        // or p.LinkParent(0)... ?
+        f1a.LinkParent(&p);
+        f1b.LinkParent(&p);
+        f2a.LinkParent(&f1a);
+        f2b.LinkParent(&f1a);
+
+        p.UnlinkChildren();
+        f2a.LinkParent(0);
+
+        /* 
+        p should have no parent
+        p should have no children
+        f1a should have no parent
+        f1a should have child f2b
+        f1b should have no parent
+        f1b should have no children
+        f2a should have no parent
+        f2a should have no children
+        f2b should have parent f1a
+        f2b should have no children
+        */
+        {
+          TEST(p.GetLink().GetParent() == 0);
+          TEST(p.GetLink().FindChild(&p) == 0);
+          TEST(p.GetLink().FindChild(&f1a) == 0);
+          TEST(p.GetLink().FindChild(&f1b) == 0);
+          TEST(p.GetLink().FindChild(&f2a) == 0);
+          TEST(p.GetLink().FindChild(&f2b) == 0);
+
+          TEST(f1a.GetLink().GetParent() == 0);
+          TEST(f1a.GetLink().FindChild(&p) == 0);
+          TEST(f1a.GetLink().FindChild(&f1a) == 0);
+          TEST(f1a.GetLink().FindChild(&f1b) == 0);
+          TEST(f1a.GetLink().FindChild(&f2a) == 0);
+          TEST(f1a.GetLink().FindChild(&f2b) == &f2b);
+
+          TEST(f1b.GetLink().GetParent() == 0);
+          TEST(f1b.GetLink().FindChild(&p) == 0);
+          TEST(f1b.GetLink().FindChild(&f1a) == 0);
+          TEST(f1b.GetLink().FindChild(&f1b) == 0);
+          TEST(f1b.GetLink().FindChild(&f2a) == 0);
+          TEST(f1b.GetLink().FindChild(&f2b) == 0);
+
+          TEST(f2a.GetLink().GetParent() == 0);
+          TEST(f2a.GetLink().FindChild(&p) == 0);
+          TEST(f2a.GetLink().FindChild(&f1a) == 0);
+          TEST(f2a.GetLink().FindChild(&f1b) == 0);
+          TEST(f2a.GetLink().FindChild(&f2a) == 0);
+          TEST(f2a.GetLink().FindChild(&f2b) == 0);
+
+          TEST(f2b.GetLink().GetParent() == &f1a);
+          TEST(f2b.GetLink().FindChild(&p) == 0);
+          TEST(f2b.GetLink().FindChild(&f1a) == 0);
+          TEST(f2b.GetLink().FindChild(&f1b) == 0);
+          TEST(f2b.GetLink().FindChild(&f2a) == 0);
+          TEST(f2b.GetLink().FindChild(&f2b) == 0);
+        }
+      }
+
+      /* Test cAnalyzeGenotype function Unlink(). {{{3 */
+      {
+        cAnalyzeGenotype
+          p(AGFactory(*world, "ccc")),
+          f1a(AGFactory(*world, "ccc")),
+          f1b(AGFactory(*world, "ccc")),
+          f2a(AGFactory(*world, "ccc")),
+          f2b(AGFactory(*world, "ccc"));
+
+
+        p.UnlinkParent();
+        // or p.LinkParent(0)... ?
+        f1a.LinkParent(&p);
+        f1b.LinkParent(&p);
+        f2a.LinkParent(&f1a);
+        f2b.LinkParent(&f1a);
+
+        f1a.Unlink();
+        /* 
+        p should have no parent
+        p should have child f1b
+        f1a should have no parent
+        f1a should have no children
+        f1b should have parent p
+        f1b should have no children
+        f2a should have no parent
+        f2a should have no children
+        f2b should have no parent
+        f2b should have no children
+        */
+        {
+          TEST(p.GetLink().GetParent() == 0);
+          TEST(p.GetLink().FindChild(&p) == 0);
+          TEST(p.GetLink().FindChild(&f1a) == 0);
+          TEST(p.GetLink().FindChild(&f1b) == &f1b);
+          TEST(p.GetLink().FindChild(&f2a) == 0);
+          TEST(p.GetLink().FindChild(&f2b) == 0);
+
+          TEST(f1a.GetLink().GetParent() == 0);
+          TEST(f1a.GetLink().FindChild(&p) == 0);
+          TEST(f1a.GetLink().FindChild(&f1a) == 0);
+          TEST(f1a.GetLink().FindChild(&f1b) == 0);
+          TEST(f1a.GetLink().FindChild(&f2a) == 0);
+          TEST(f1a.GetLink().FindChild(&f2b) == 0);
+
+          TEST(f1b.GetLink().GetParent() == &p);
+          TEST(f1b.GetLink().FindChild(&p) == 0);
+          TEST(f1b.GetLink().FindChild(&f1a) == 0);
+          TEST(f1b.GetLink().FindChild(&f1b) == 0);
+          TEST(f1b.GetLink().FindChild(&f2a) == 0);
+          TEST(f1b.GetLink().FindChild(&f2b) == 0);
+
+          TEST(f2a.GetLink().GetParent() == 0);
+          TEST(f2a.GetLink().FindChild(&p) == 0);
+          TEST(f2a.GetLink().FindChild(&f1a) == 0);
+          TEST(f2a.GetLink().FindChild(&f1b) == 0);
+          TEST(f2a.GetLink().FindChild(&f2a) == 0);
+          TEST(f2a.GetLink().FindChild(&f2b) == 0);
+
+          TEST(f2b.GetLink().GetParent() == 0);
+          TEST(f2b.GetLink().FindChild(&p) == 0);
+          TEST(f2b.GetLink().FindChild(&f1a) == 0);
+          TEST(f2b.GetLink().FindChild(&f1b) == 0);
+          TEST(f2b.GetLink().FindChild(&f2a) == 0);
+          TEST(f2b.GetLink().FindChild(&f2b) == 0);
+        }
+      }
+
+      /* Verify cAnalyzeGenotypeLink constructor. It shouldn't do much beyond initialize its child_list to empty and its parent to null. {{{3 */
+      {
+        cAnalyzeGenotypeLink pl;
+
+        TEST(0 == pl.GetParent());
+        TEST(0 == pl.GetChildList().GetSize());
+      }
+
+      /* Verify that adding same child twice does not create two entries in child list. {{{3 */
+      {
+        cAnalyzeGenotype
+          f1a(AGFactory(*world, "ccc")),
+          f1b(AGFactory(*world, "ccc"));
+        cAnalyzeGenotypeLink pl;
+
+        TEST(0 == pl.GetParent());
+        TEST(0 == pl.GetChildList().GetSize());
+
+        /* First add of f1a. */
+        pl.AddChild(&f1a);
+        TEST(1 == pl.GetChildList().GetSize());
+        /* Second add of f1a. */
+        pl.AddChild(&f1a);
+        TEST(1 == pl.GetChildList().GetSize());
+
+        /* First add of f1b. */
+        pl.AddChild(&f1b);
+        TEST(2 == pl.GetChildList().GetSize());
+      }
+
+      /* Verify cAnalyzeGenotype constructor handling of cAnalyzeGenotypeLink. {{{3 */
+      {
+        cAnalyzeGenotype p(AGFactory(*world, "ccc"));
+
+        TEST(0 == p.GetLink().GetParent());
+        TEST(0 == p.GetLink().GetChildList().GetSize());
+      }
+
+      /* XXX To-Do: Verify cAnalyzeGenotype destructor properly destroys cAnalyzeGenotypeLink. {{{3 */
+      {
+        cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
+        cAnalyzeGenotype *p, *f1a, *f1b, *f2a, *f2b, *orphan;
+
+        p = new cAnalyzeGenotype(AGFactory(*world, "ccc"));
+        f1a = new cAnalyzeGenotype(AGFactory(*world, "ccc"));
+        f1b = new cAnalyzeGenotype(AGFactory(*world, "ccc"));
+        f2a = new cAnalyzeGenotype(AGFactory(*world, "ccc"));
+        f2b = new cAnalyzeGenotype(AGFactory(*world, "ccc"));
+
+        orphan = new cAnalyzeGenotype(AGFactory(*world, "ccc"));
+
+        p->LinkChild(*f1a);
+        p->LinkChild(*f1b);
+        f1a->LinkChild(*f2a);
+        f1a->LinkChild(*f2b);
+
+        /* 
+        p should have no parent
+        p should have children f1a and f1b
+        f1a should have parent p
+        f1a should have children f2a and f2b
+        f1b should have parent p
+        f1b should have no children
+        f2a should have parent f1a
+        f2a should have no children
+        f2b should have parent f1a
+        f2b should have no children
+        orphan should have no parent
+        orphan should have no children
+        */
+        {
+          TEST(p->GetLink().GetParent() == 0);
+          TEST(2 == p->GetLink().GetChildList().GetSize());
+          TEST(f1a->GetLink().GetParent() == p);
+          TEST(2 == f1a->GetLink().GetChildList().GetSize());
+          TEST(f1b->GetLink().GetParent() == p);
+          TEST(0 == f1b->GetLink().GetChildList().GetSize());
+          TEST(f2a->GetLink().GetParent() == f1a);
+          TEST(0 == f2a->GetLink().GetChildList().GetSize());
+          TEST(f2b->GetLink().GetParent() == f1a);
+          TEST(0 == f2b->GetLink().GetChildList().GetSize());
+          TEST(orphan->GetLink().GetParent() == 0);
+          TEST(0 == orphan->GetLink().GetChildList().GetSize());
+        }
+
+        assert(f2b); delete f2b; f2b=0;
+        /*
+        XXX:
+        When f2b is not set zero after delete, a second delete causes
+        cString.h:124: failed assertion `refs > 0'! I've been looking
+        for things that trigger this symptom. Yay.
+        @kgn
+        */
+        /* 
+        p should have no parent
+        p should have children f1a and f1b
+        f1a should have parent p
+        f1a should have child f2a
+        f1b should have parent p
+        f1b should have no children
+        f2a should have parent f1a
+        f2a should have no children
+        orphan should have no parent
+        orphan should have no children
+        */
+        {
+          TEST(p->GetLink().GetParent() == 0);
+          TEST(2 == p->GetLink().GetChildList().GetSize());
+          TEST(f1a->GetLink().GetParent() == p);
+          TEST(1 == f1a->GetLink().GetChildList().GetSize());
+          TEST(f1b->GetLink().GetParent() == p);
+          TEST(0 == f1b->GetLink().GetChildList().GetSize());
+          TEST(f2a->GetLink().GetParent() == f1a);
+          TEST(0 == f2a->GetLink().GetChildList().GetSize());
+          TEST(orphan->GetLink().GetParent() == 0);
+          TEST(0 == orphan->GetLink().GetChildList().GetSize());
+        }
+
+        assert(f1a); delete f1a; f1a=0;
+        /*
+        XXX:
+        When f2b is not set zero after delete, a second delete causes
+        cString.h:124: failed assertion `refs > 0'! I've been looking
+        for things that trigger this symptom. Yay.
+        @kgn
+        */
+        /* 
+        p should have no parent
+        p should have child f1b
+        f1b should have parent p
+        f1b should have no children
+        f2a should have no parent
+        f2a should have no children
+        orphan should have no parent
+        orphan should have no children
+        */
+        {
+          TEST(p->GetLink().GetParent() == 0);
+          TEST(1 == p->GetLink().GetChildList().GetSize());
+          TEST(f1b->GetLink().GetParent() == p);
+          TEST(0 == f1b->GetLink().GetChildList().GetSize());
+          TEST(f2a->GetLink().GetParent() == 0);
+          TEST(0 == f2a->GetLink().GetChildList().GetSize());
+          TEST(orphan->GetLink().GetParent() == 0);
+          TEST(0 == orphan->GetLink().GetChildList().GetSize());
+        }
+
+        delete orphan;
+        delete f2a;
+        delete f1b;
+        delete p;
+      }
+
+      /* Test cAnalyzeGenotype functions GetParent, HasChild(), UnlinkChild(), GetChildList(). {{{3 */
+      if(true){
+        cAnalyzeGenotype
+          p(AGFactory(*world, "ccc")),
+          f1a(AGFactory(*world, "ccc")),
+          f1b(AGFactory(*world, "ccc")),
+          f2a(AGFactory(*world, "ccc")),
+          f2b(AGFactory(*world, "ccc"));
+
+        cAnalyzeGenotypeLink pl, f1al, f1bl, f2al, f2bl;
+
+        f1a.LinkParent(&p);
+        f1b.LinkParent(&p);
+        f2a.LinkParent(&f1a);
+        f2b.LinkParent(&f1a);
+
+        /* Test GetParent(). */
+        {
+          TEST(p.GetParent() == 0);
+          TEST(f1a.GetParent() == &p);
+          TEST(f1b.GetParent() == &p);
+          TEST(f2a.GetParent() == &f1a);
+          TEST(f2b.GetParent() == &f1a);
+        }
+
+        /* Test HasChild(). */
+        {
+          TEST(!p.HasChild(p));
+          TEST(p.HasChild(f1a));
+          TEST(p.HasChild(f1b));
+          TEST(!p.HasChild(f2a));
+          TEST(!p.HasChild(f2b));
+
+          TEST(!f1a.HasChild(p));
+          TEST(!f1a.HasChild(f1a));
+          TEST(!f1a.HasChild(f1b));
+          TEST(f1a.HasChild(f2a));
+          TEST(f1a.HasChild(f2b));
+
+          TEST(!f1b.HasChild(p));
+          TEST(!f1b.HasChild(f1a));
+          TEST(!f1b.HasChild(f1b));
+          TEST(!f1b.HasChild(f2a));
+          TEST(!f1b.HasChild(f2b));
+
+          TEST(!f2a.HasChild(p));
+          TEST(!f2a.HasChild(f1a));
+          TEST(!f2a.HasChild(f1b));
+          TEST(!f2a.HasChild(f2a));
+          TEST(!f2a.HasChild(f2b));
+
+          TEST(!f2b.HasChild(p));
+          TEST(!f2b.HasChild(f1a));
+          TEST(!f2b.HasChild(f1b));
+          TEST(!f2b.HasChild(f2a));
+          TEST(!f2b.HasChild(f2b));
+        }
+
+        /* Test UnlinkChild() and GetChildList(). */
+        {
+          TEST(2 == p.GetChildList().GetSize());
+          TEST(!p.UnlinkChild(p));
+          TEST(2 == p.GetChildList().GetSize());
+          TEST(p.UnlinkChild(f1a));
+          TEST(1 == p.GetChildList().GetSize());
+          TEST(p.UnlinkChild(f1b));
+          TEST(0 == p.GetChildList().GetSize());
+          TEST(!p.UnlinkChild(f2a));
+          TEST(!p.UnlinkChild(f2b));
+          TEST(0 == p.GetChildList().GetSize());
+
+          TEST(2 == f1a.GetChildList().GetSize());
+          TEST(!f1a.UnlinkChild(p));
+          TEST(!f1a.UnlinkChild(f1a));
+          TEST(!f1a.UnlinkChild(f1b));
+          TEST(2 == f1a.GetChildList().GetSize());
+          TEST(f1a.UnlinkChild(f2a));
+          TEST(1 == f1a.GetChildList().GetSize());
+          TEST(f1a.UnlinkChild(f2b));
+          TEST(0 == f1a.GetChildList().GetSize());
+
+          TEST(0 == f1b.GetChildList().GetSize());
+          TEST(!f1b.UnlinkChild(p));
+          TEST(!f1b.UnlinkChild(f1a));
+          TEST(!f1b.UnlinkChild(f1b));
+          TEST(!f1b.UnlinkChild(f2a));
+          TEST(!f1b.UnlinkChild(f2b));
+          TEST(0 == f1b.GetChildList().GetSize());
+
+          TEST(0 == f2a.GetChildList().GetSize());
+          TEST(!f2a.UnlinkChild(p));
+          TEST(!f2a.UnlinkChild(f1a));
+          TEST(!f2a.UnlinkChild(f1b));
+          TEST(!f2a.UnlinkChild(f2a));
+          TEST(!f2a.UnlinkChild(f2b));
+          TEST(0 == f2a.GetChildList().GetSize());
+
+          TEST(0 == f2b.GetChildList().GetSize());
+          TEST(!f2b.UnlinkChild(p));
+          TEST(!f2b.UnlinkChild(f1a));
+          TEST(!f2b.UnlinkChild(f1b));
+          TEST(!f2b.UnlinkChild(f2a));
+          TEST(!f2b.UnlinkChild(f2b));
+          TEST(0 == f2b.GetChildList().GetSize());
+        }
+      }
+
+
+      /* Common test teardown. {{{3 */
       delete world;
+      /* }}}3 */
     }
-    cAddTestSuite t("cAnalyze_UnitTest_Destructor", test);
+    cAddTestSuite t("cAnalyzeGenotype_Brainstorm_cAnalyzeGenotypeLink", test);
   }
 
-  /* cAnalyze_UnitTest_Archiving {{{2 */
-  namespace UnitTest_Archiving {
+
+/* Unit tests. {{{1 */
+  /* cAnalyzeGenotype_UnitTest_HelloWorld {{{2 */
+  namespace UnitTest_HelloWorld {
     void test(const cStringList &attrs){
-      if(!attrs.HasString("Template")){
-        cout << "XXX Skipping Template test." << endl;
+      if(!attrs.HasString("HelloWorld")){
+        cout << "XXX Skipping HelloWorld test." << endl;
         return;
       }
-#   if !ENABLE_SERIALIZATION
-      cout << "XXX : Test skipped because serialization is disabled." << endl;
-#   else // ENABLE_SERIALIZATION
       cout << "XXX This is a test stub. It needs filling-in. @kgn" << endl;
-      //std::string filename("./cAnalyze_basic_serialization.xml");
-
-      //{
-      //  cAnalyze o();
-      //  save_stuff<>(o, filename.c_str());
-      //}
-
-      //{
-      //  cAnalyze o;
-
-      //  restore_stuff<>(o, filename.c_str());
-      //  TEST(true);
-      //}
-
-      //std::remove(filename.c_str());
-#   endif // ENABLE_SERIALIZATION
+      /* Make sure testing is working with successes and failures. @kgn */
+      TEST(true);
+      TEST(false);
     }
-    cAddTestSuite t("cAnalyze_UnitTest_Archiving", test);
+    cAddTestSuite t("cAnalyzeGenotype_UnitTest_HelloWorld", test);
   }
 
   // }}}1




More information about the Avida-cvs mailing list