Program Listing for File BacteriumPhageUnitTest.test.cc¶
↰ Return to documentation for file (source/test/lysis_mode_test/BacteriumPhageUnitTest.test.cc
)
#include "../../lysis_mode/Phage.h"
#include "../../lysis_mode/Bacterium.h"
TEST_CASE("Phage Process", "[lysis]") {
GIVEN("A world and some phage") {
emp::Ptr<emp::Random> random;
random.New(5);
SymConfigBase config;
LysisWorld w(*random, &config);
LysisWorld * world = &w;
config.LYSIS(1);
double int_val = -1;
WHEN("Lysis is enabled and the Phage's burst timer >= the burst time") {
emp::Ptr<Phage> phage;
phage.New(random, world, &config, int_val);
emp::Ptr<Phage> phage1;
phage1.New(random, world, &config, int_val);
emp::Ptr<Phage> phage2;
phage2.New(random, world, &config, int_val);
emp::Ptr<Bacterium> bacterium;
bacterium.New(random, world, &config);
phage->SetHost(bacterium);
int time = 15;
phage->SetBurstTimer(time);
bacterium->AddReproSym(phage1);
bacterium->AddReproSym(phage2);
THEN("Lysis occurs, the host dies") {
size_t location = 2;
// double resources_per_host_per_update = 40;
phage->Process(location);
bool host_dead = true;
std::vector<emp::Ptr<Organism>> empty_syms = {};
REQUIRE(bacterium->GetDead() == host_dead);
REQUIRE(bacterium->GetReproSymbionts() == empty_syms);
}
phage.Delete();
bacterium.Delete();
}
WHEN("Lysis is enabled and the Phage's burst timer < the burst time") {
emp::Ptr<Bacterium> bacterium;
bacterium.New(random, world, &config);
double phage_points = 10;
emp::Ptr<Phage> phage3;
phage3.New(random, world, &config, int_val);
emp::Ptr<Phage> phage4;
phage4.New(random, world, &config, int_val);
emp::Ptr<Phage> phage5;
phage5.New(random, world, &config, int_val);
phage3->SetPoints(phage_points);
bacterium->AddReproSym(phage4);
bacterium->AddReproSym(phage5);
int num_host_orig_syms = 2;
phage3->SetHost(bacterium);
THEN("Phage reproduces, Host gains repro symbionts, Phage loses points") {
size_t location = 2;
// bool host_dead = false;
phage3->Process(location);
REQUIRE(bacterium->GetDead() == false);
std::vector<emp::Ptr<Organism>> updated_repro_syms = bacterium->GetReproSymbionts();
REQUIRE( (int) updated_repro_syms.size() > num_host_orig_syms); // host gained repro syms
REQUIRE(phage3->GetPoints() < phage_points); // phage lost points
}
phage3.Delete();
bacterium.Delete();
}
random.Delete();
}
}
TEST_CASE("Phage Vertical Transmission", "[lysis]"){
emp::Ptr<emp::Random> random = new emp::Random(-1);
SymConfigBase config;
LysisWorld w(*random, &config);
LysisWorld * world = &w;
config.LYSIS(1);
WHEN("phage is lytic"){
config.LYSIS_CHANCE(1);
WHEN("Vertical Transmission is enabled"){
config.VERTICAL_TRANSMISSION(1);
double host_int_val = .5;
double sym_int_val = -.5;
emp::Ptr<Bacterium> bacterium = emp::NewPtr<Bacterium>(random, world, &config, host_int_val);
emp::Ptr<Phage> phage = emp::NewPtr<Phage>(random, world, &config, sym_int_val);
bacterium->AddSymbiont(phage);
emp::Ptr<Bacterium> host_baby = emp::NewPtr<Bacterium>(random, world, &config, bacterium->GetIntVal());
long unsigned int expected_sym_size = host_baby->GetSymbionts().size();
phage->VerticalTransmission(host_baby);
THEN ("Phage does not vertically transmit") {
REQUIRE(host_baby->GetSymbionts().size() == expected_sym_size);
}
bacterium.Delete();
host_baby.Delete();
}
WHEN("Vertical Transmission is disabled"){
config.VERTICAL_TRANSMISSION(0);
double host_int_val = .5;
double sym_int_val = -.5;
emp::Ptr<Bacterium> bacterium = emp::NewPtr<Bacterium>(random, world, &config, host_int_val);
emp::Ptr<Phage> phage = emp::NewPtr<Phage>(random, world, &config, sym_int_val);
bacterium->AddSymbiont(phage);
emp::Ptr<Bacterium> host_baby = emp::NewPtr<Bacterium>(random, world, &config, bacterium->GetIntVal());
long unsigned int expected_sym_size = host_baby->GetSymbionts().size();
phage->VerticalTransmission(host_baby);
THEN ("Phage does not vertically transmit") {
REQUIRE(host_baby->GetSymbionts().size() == expected_sym_size);
}
bacterium.Delete();
host_baby.Delete();
}
}
WHEN("phage is lysogenic"){
config.LYSIS_CHANCE(0);
WHEN("Vertical Transmission is enabled"){
config.VERTICAL_TRANSMISSION(1);
double host_int_val = .5;
double sym_int_val = -.5;
emp::Ptr<Bacterium> bacterium = emp::NewPtr<Bacterium>(random, world, &config, host_int_val);
emp::Ptr<Phage> phage = emp::NewPtr<Phage>(random, world, &config, sym_int_val);
bacterium->AddSymbiont(phage);
emp::Ptr<Bacterium> host_baby = emp::NewPtr<Bacterium>(random, world, &config, bacterium->GetIntVal());
long unsigned int expected_sym_size = host_baby->GetSymbionts().size() +1;
phage->VerticalTransmission(host_baby);
THEN ("Phage does vertically transmit") {
REQUIRE(host_baby->GetSymbionts().size() == expected_sym_size);
}
bacterium.Delete();
host_baby.Delete();
}
WHEN("Vertical Transmission is disabled"){
config.VERTICAL_TRANSMISSION(0);
double host_int_val = .5;
double sym_int_val = -.5;
emp::Ptr<Bacterium> bacterium = emp::NewPtr<Bacterium>(random, world, &config, host_int_val);
emp::Ptr<Phage> phage = emp::NewPtr<Phage>(random, world, &config, sym_int_val);
bacterium->AddSymbiont(phage);
emp::Ptr<Bacterium> host_baby = emp::NewPtr<Bacterium>(random, world, &config, bacterium->GetIntVal());
long unsigned int expected_sym_size = host_baby->GetSymbionts().size()+1;
phage->VerticalTransmission(host_baby);
THEN ("Phage does vertically transmit") {
REQUIRE(host_baby->GetSymbionts().size() == expected_sym_size);
}
bacterium.Delete();
host_baby.Delete();
}
}
}
TEST_CASE("Host phage death and removal from syms list", "[lysis]"){
emp::Ptr<emp::Random> random = new emp::Random(6);
SymConfigBase config;
LysisWorld w(*random, &config);
LysisWorld *world = &w;
config.SYM_LIMIT(2);
WHEN("there is a single lysogenic phage and it is dead"){
config.LYSIS_CHANCE(0);
double host_int_val = .5;
double sym_int_val = -.5;
emp::Ptr<Bacterium> bacterium = emp::NewPtr<Bacterium>(random, world, &config, host_int_val);
emp::Ptr<Phage> phage = emp::NewPtr<Phage>(random, world, &config, sym_int_val);
bacterium->AddSymbiont(phage);
phage->SetDead();
long unsigned int expected_sym_size = 0;
bacterium->Process(0);
THEN("phage is removed from syms list"){
REQUIRE(bacterium->GetSymbionts().size() == expected_sym_size);
}
bacterium.Delete();
}
WHEN("There are multiple lysogenic phage and only one dies"){
config.LYSIS_CHANCE(0);
double host_int_val = .5;
double sym_int_val = -.5;
emp::Ptr<Bacterium> bacterium = emp::NewPtr<Bacterium>(random, world, &config, host_int_val);
emp::Ptr<Organism> phage1 = emp::NewPtr<Phage>(random, world, &config, sym_int_val);
emp::Ptr<Organism> phage2 = emp::NewPtr<Phage>(random, world, &config, 0.0);
bacterium->AddSymbiont(phage1);
bacterium->AddSymbiont(phage2);
phage1->SetDead();
long unsigned int expected_sym_size = 1;
bacterium->Process(0);
THEN("Only the dead phage is removed from the syms list"){
REQUIRE(bacterium->GetSymbionts().size() == expected_sym_size);
emp::Ptr<Organism> curSym = bacterium->GetSymbionts()[0];
REQUIRE(curSym->GetIntVal() == phage2->GetIntVal());
REQUIRE(curSym == phage2);
}
bacterium.Delete();
}
}
TEST_CASE("Phage LysisBurst", "[lysis]"){
emp::Ptr<emp::Random> random = new emp::Random(6);
SymConfigBase config;
LysisWorld w(*random, &config);
LysisWorld * world = &w;
config.LYSIS(1);
config.GRID_X(2);
config.GRID_Y(1);
config.SYM_LIMIT(10);
int location = 0;
double int_val = 0;
emp::Ptr<Phage> phage = emp::NewPtr<Phage>(random, world, &config, int_val);
GIVEN("create two hosts and add both to world as neighbors, add phage offspring to the original host's repro syms"){
emp::Ptr<Bacterium> orig_bacterium = emp::NewPtr<Bacterium>(random, world, &config, int_val);
emp::Ptr<Bacterium> new_bacterium = emp::NewPtr<Bacterium>(random, world, &config, int_val);
orig_bacterium->AddSymbiont(phage);
world->AddOrgAt(orig_bacterium, 0);
world->AddOrgAt(new_bacterium, 1);
emp::Ptr<Organism> p_baby1 = phage->Reproduce();
emp::Ptr<Organism> p_baby2 = phage->Reproduce();
orig_bacterium->AddReproSym(p_baby1);
orig_bacterium->AddReproSym(p_baby2);
WHEN("call the burst method so we can check injection") {
int original_sym_num = new_bacterium->GetSymbionts().size() + orig_bacterium->GetSymbionts().size();
phage->LysisBurst(location);
THEN("the repro syms go into the other host as symbionts and the original host dies"){
int new_sym_num = new_bacterium->GetSymbionts().size() + orig_bacterium->GetSymbionts().size();
REQUIRE(new_sym_num == original_sym_num+2);
REQUIRE(size(orig_bacterium->GetReproSymbionts()) == 0);
REQUIRE(orig_bacterium->GetDead() == true);
}
}
}
}
TEST_CASE("Phage LysisStep", "[lysis]"){
emp::Ptr<emp::Random> random = new emp::Random(9);
SymConfigBase config;
LysisWorld w(*random, &config);
LysisWorld * world = &w;
double sym_repro_points = 5.0;
config.LYSIS(1);
config.SYM_LYSIS_RES(sym_repro_points);
double int_val = 0;
emp::Ptr<Phage> phage = emp::NewPtr<Phage>(random, world, &config, int_val);
emp::Ptr<Bacterium> bacterium = emp::NewPtr<Bacterium>(random, world, &config, int_val);
bacterium->AddSymbiont(phage);
WHEN("The phage doesn't have enough resources to reproduce"){
double repro_syms_size_pre_process = size(bacterium->GetReproSymbionts());
double orig_points = 3.0;
double expected_points = 3.0;
phage->SetPoints(orig_points);
double orig_burst_time = 0.0;
phage->SetBurstTimer(orig_burst_time);
phage->LysisStep();
THEN("The burst timer is incremented but no offspring are created"){
REQUIRE(phage->GetBurstTimer() > orig_burst_time);
REQUIRE(size(bacterium->GetReproSymbionts()) == repro_syms_size_pre_process);
REQUIRE(phage->GetPoints() == expected_points);
}
}
WHEN("The phage does have enough resources to reproduce"){
double expected_repro_syms_size_post_process = size(bacterium->GetReproSymbionts()) + 1; //one offspring created
double orig_points = sym_repro_points;//symbiont given enough resources to produce one offspring
double expected_points = 0.0;
phage->SetPoints(orig_points);
double orig_burst_time = 0.0;
phage->SetBurstTimer(orig_burst_time);
phage->LysisStep();
THEN("The burst timer is incremented and offspring are created"){
REQUIRE(phage->GetBurstTimer() > orig_burst_time);
REQUIRE(size(bacterium->GetReproSymbionts()) == expected_repro_syms_size_post_process);
REQUIRE(phage->GetPoints() == expected_points);
}
}
bacterium.Delete();
}
TEST_CASE("Phage overwrites Symbiont ProcessResources", "[lysis]"){
emp::Ptr<emp::Random> random = new emp::Random(9);
SymConfigBase config;
LysisWorld w(*random, &config);
LysisWorld * world = &w;
double int_val = 0.2;
config.LYSIS(1);
config.LYSIS_CHANCE(0);
config.BENEFIT_TO_HOST(0);
config.SYNERGY(5);
emp::Ptr<Phage> phage = emp::NewPtr<Phage>(random, world, &config, int_val);
emp::Ptr<Bacterium> bacterium = emp::NewPtr<Bacterium>(random, world, &config, int_val);
phage->UponInjection();
double sym_piece = 20;
bacterium->DistribResToSym(phage, sym_piece);
// host would get 20 points if it did this with a symbiont
/* bacterium gets 16; int val is 0.2, sym piece is 20, so:
host donation = host int val * sym piece = 4
res in process = sym piece - host donation = 16
DistribResToSym then calls ProcessResources with host donation (4).
since the phage is lysogenic (lysis_chance = 0) and benefit to host is off (0),
phage ProcessResources returns 0.
ergo, bacterium only adds res in process (16) to its point total.*/
// phage gets 0 points; it doesn't process the 4 resources that bacterium donated
double expected_bacterium_points = 16;
double expected_phage_points = 0;
REQUIRE(bacterium->GetPoints() == expected_bacterium_points);
REQUIRE(phage->GetPoints() == expected_phage_points);
phage.Delete();
bacterium.Delete();
}