int main(){ // A main program that will mostly automatically test the Image and Photo_set // classes and compute a preliminary grade based on their functionality int total = 0; // Points for each method in the image class const int image_get_name = 1; const int image_get_tags = 1; const int image_set_name = 1; const int image_set_tags = 1; const int image_get_next = 6; const int image_set_next = 6; const int image_image_null = 1; const int image_image_strings = 1; // Points for each method in the photo_set class const int pset_get_name = 2; const int pset_change_set_name = 2; const int pset_add_image = 7; const int pset_display_images = 6; const int pset_number_of_images = 5; const int pset_extract_image = 7; const int pset_save_set = 14; const int pset_load_set = 14; const int pset_load_clear_penalty = 3; // First, test the image class. // Create a new image Image test_image("D1","Line with spaces"); // make sure the observors work if ( test_image.get_name() == "D1"){ total += image_get_name; cerr << setw(40) << "Image::get_name" << setw(10) << "Passed" << endl; } else cerr << setw(40) << "Image::get_name" << setw(10) << "FAIL" << endl; if (test_image.get_tags() == "Line with spaces"){ total += image_get_tags; cerr << setw(40) << "Image::get_tags" << setw(10) << "Passed" << endl; } else cerr << setw(40) << "Image::get_tags" << setw(10) << "FAIL" << endl; // make sure the accesors work test_image.set_name("D2"); test_image.set_tags("Other stuff"); if ( test_image.get_name() == "D2"){ total += image_set_name; cerr << setw(40) << "Image::set_name" << setw(10) << "Passed" << endl; } else cerr << setw(40) << "Image::set_name" << setw(10) << "FAIL" << endl; if (test_image.get_tags() == "Other stuff"){ total += image_set_tags; cerr << setw(40) << "Image::set_tags" << setw(10) << "Passed" << endl; } else cerr << setw(40) << "Image::set_tags" << setw(10) << "FAIL" << endl; // check the pointer part out // Find out what it was to start, then see if we can change it Image * start = test_image.get_next_image(); Image * another = new Image; test_image.set_next_image(another); Image * result = test_image.get_next_image(); if (result == another){ // both set and read worked total += image_get_next; total += image_set_next; cerr << setw(40) << "Image::get_next_image" << setw(10) << "Passed" << endl; cerr << setw(40) << "Image::set_next_image" << setw(10) << "Passed" << endl; } else if (result == start){ // get worked, but set didn't total += image_get_next; cerr << setw(40) << "Image::get_next_image" << setw(10) << "Passed" << endl; cerr << setw(40) << "Image::set_next_image" << setw(10) << "FAIL" << endl; } else { // Bad things hapenned cerr << setw(40) << "Image::get_next_image" << setw(10) << "FAIL" << endl; cerr << setw(40) << "Image::set_next_image" << setw(10) << "FAIL" << endl; } // Now that the above things worked, we can test the constructors Image blank; if ((blank.get_name() == "") && (blank.get_tags() == "") && (blank.get_next_image() == NULL)){ total += image_image_null; cerr << setw(40) << "Image::Image()" << setw(10) << "Passed" << endl; } else cerr << setw(40) << "Image::Image()" << setw(10) << "FAIL" << endl; Image strings("D3","String fest"); if ((strings.get_name() == "D3") && (strings.get_tags() == "String fest") && (strings.get_next_image() == NULL)){ total += image_image_strings; cerr << setw(40) << "Image::Image(string,string)" << setw(10) << "Passed" << endl; } else { // Not much detail to see what failed here because I would be surprised if anyone // missed it cerr << setw(40) << "Image::Image(string,string)" << setw(10) << "FAIL" << endl; } cerr << endl << endl; // Ok, time to test the photo_set class // First, test the name setting and reading Photo_set some_set; some_set.change_set_name("Please work"); if (some_set.get_name() == "Please work"){ total += pset_change_set_name; total += pset_get_name; cerr << setw(40) << "Photo_set::change_set_name" << setw(10) << "Passed" << endl; cerr << setw(40) << "Photo_set::get_name" << setw(10) << "Passed" << endl; } else { } // In order to test this, we need to cheat and make cout go to a file that we // can read to test it, instead of it going to the screen. The code below makes // cout go to a file instead of the screen. It is magic. ofstream ofile("picco-out.txt"); // save output buffer of the stream streambuf* strm_buffer = cout.rdbuf(); // redirect ouput into the file cout.rdbuf (ofile.rdbuf()); // test that we can add an image and display it Photo_set test_set; Image a_test_image ("D3","Tasty cows"); test_set.add_image(a_test_image); test_set.display_images(); // This fixes cout and closes the file cout.rdbuf (strm_buffer); ofile.close(); ifstream ifile("picco-out.txt"); int test_num; string test_name, test_tags_start, test_tags_rest, test_tags; ifile >> test_num >> test_name; // Do some trickery to get rid of spaces ahead of the tags ifile >> test_tags_start; getline (ifile, test_tags_rest); test_tags = test_tags_start + test_tags_rest; ifile.close(); // Now we created the file, see if the output was right if ((test_num == 1) && (test_name == "D3") && (test_tags == "Tasty cows")) { total += pset_add_image; cerr << setw(40) << "Photo_set::add_image" << setw(10) << "Passed" << endl; } else { if (test_num != 1) { cerr << "Test_num was not read properly. It should have been 1 and it was:" << test_num << endl; } if (test_name != "D3") { cerr << "Test_name was not read properly. It should have been D3 and it was: " << test_name << endl; } if (test_tags != "Tasty cows"){ cerr << "Test_tags was not read properly. It hould have been Tasty cows and it was: " << test_tags << endl; } cerr << "Test results after this may be incorrect" << endl; } // Ok, so maybe add_images and display_images are probably working now // Check display_images a bit more // Now add some more images to better test the adding method and the printing // since adding can go wrong Image image1; image1.set_name("D4"); image1.set_tags("Brown cows"); test_set.add_image(image1); Image image2; image2.set_name("D5"); image2.set_tags("White cows"); test_set.add_image(image2); Image image3; image3.set_name("D6"); image3.set_tags("Spotted cows"); test_set.add_image(image3); // Do the magic to send things to a file ofile.open("picco-out.txt"); // save output buffer of the stream strm_buffer = cout.rdbuf(); // redirect ouput into the file cout.rdbuf (ofile.rdbuf()); test_set.display_images(); // This fixes cout and closes the file cout.rdbuf (strm_buffer); ofile.close(); ifile.open("picco-out.txt"); int test_num1, test_num2, test_num3, test_num4; string test_name1, test_name2, test_name3, test_name4; string test_tags1, test_tags2, test_tags3, test_tags4; ifile >> test_num1 >> test_name1; ifile >> test_tags_start; getline (ifile, test_tags_rest); test_tags1 = test_tags_start + test_tags_rest; ifile >> test_num2 >> test_name2; ifile >> test_tags_start; getline (ifile, test_tags_rest); test_tags2 = test_tags_start + test_tags_rest; ifile >> test_num3 >> test_name3; ifile >> test_tags_start; getline (ifile, test_tags_rest); test_tags3 = test_tags_start + test_tags_rest; ifile >> test_num4 >> test_name4; ifile >> test_tags_start; getline (ifile, test_tags_rest); test_tags4 = test_tags_start + test_tags_rest; ifile.close(); bool line1=false, line2=false,line3=false,line4=false; // Now we created the file, see if the output was right // Line 1 if ((test_num1 == 1) && (test_name1 == "D3") && (test_tags1 == "Tasty cows")) { line1 = true; } else { if (test_num1 != 1) { cerr << "Test_num1 was not read properly. It should have been 1 and it was:" << test_num1 << endl; } if (test_name1 != "D3") { cerr << "Test_name1 was not read properly. It should have been D3 and it was: " << test_name1 << endl; } if (test_tags1 != "Tasty cows"){ cerr << "Test_tags1 was not read properly. It hould have been Tasty cows and it was: " << test_tags1 << endl; } } // Line 2 if ((test_num2 == 2) && (test_name2 == "D4") && (test_tags2 == "Brown cows")) { line2 = true; } else { if (test_num2 != 2) { cerr << "Test_num2 was not read properly. It should have been 2 and it was:" << test_num2 << endl; } if (test_name2 != "D4") { cerr << "Test_name2 was not read properly. It should have been D4 and it was: " << test_name2 << endl; } if (test_tags2 != "Brown cows"){ cerr << "Test_tags2 was not read properly. It hould have been Brown cows and it was: " << test_tags2 << endl; } } // Line 3 if ((test_num3 == 3) && (test_name3 == "D5") && (test_tags3 == "White cows")) { line3 = true; } else { if (test_num3 != 3) { cerr << "Test_num3 was not read properly. It should have been 3 and it was:" << test_num3 << endl; } if (test_name3 != "D5") { cerr << "Test_name3 was not read properly. It should have been D5 and it was: " << test_name3 << endl; } if (test_tags3 != "White cows"){ cerr << "Test_tags3 was not read properly. It hould have been White cows and it was: " << test_tags3 << endl; } } // Line 4 if ((test_num4 == 4) && (test_name4 == "D6") && (test_tags4 == "Spotted cows")) { line4 = true; } else { if (test_num4 != 4) { cerr << "Test_num4 was not read properly. It should have been 4 and it was:" << test_num4 << endl; } if (test_name4 != "D6") { cerr << "Test_name4 was not read properly. It should have been D6 and it was: " << test_name4 << endl; } if (test_tags4 != "Spotted cows"){ cerr << "Test_tags4 was not read properly. It hould have been Spotted cows and it was: " << test_tags4 << endl; } } if (line1 && line2 && line3 && line4){ total += pset_display_images; cerr << setw(40) << "Photo_set::display_images" << setw(10) << "Passed" << endl; } else{ cerr << line1 << line2 << line3 << line4 << endl; cerr << setw(40) << "Photo_set::display_images" << setw(10) << "Passed" << endl; } // test the number of images if (test_set.number_of_images() == 4){ Photo_set this_set; if (this_set.number_of_images() == 0){ total += pset_number_of_images; cerr << setw(40) << "Photo_set::number_of_images" << setw(10) << "Passed" << endl; } else { cerr << setw(40) << "Photo_set::number_of_images" << setw(10) << "FAIL on empty" << endl; } } else { cerr << setw(40) << "Photo_set::number_of_images" << setw(10) << "FAIL" << endl; cerr << setw(40) << "EXTRACT AND LOAD SET TESTS BELOW MAY BE INVALID" << endl; } // test the extract image method // and the display again, to make sure it isn't removed Image extract; int size_before = test_set.number_of_images(); extract = test_set.extract_image(2); int size_after = test_set.number_of_images(); int difference = size_before - size_after; if ((extract.get_name() == "D4") && (extract.get_tags() == "Brown cows") && (extract.get_next_image() == NULL) && (difference == 0)) { cerr << setw(40) << "Photo_set::extract_image" << setw(10) << "Passed" << endl; total += pset_extract_image; } else { cerr << setw(40) << "Photo_set::extract_image" << setw(10) << "FAIL" << endl; if (extract.get_name() != "D4") { cerr << "Extract fail in get name" << endl; } if (extract.get_tags() != "Brown cows") { cerr << "Extract fail in get tags" << endl; } if (extract.get_next_image() != NULL) { cerr << "Extract fail in get next image - probably forgot to set it to NULL" << endl; } if (difference != 0 ) { cerr << "Extract image messed up the list somehow, so it is a different size" << endl; } } // test the save_set test_set.change_set_name("Cow collection"); test_set.save_set("test_output"); // Ouput was easy, testing to make sure it was right is a little harder, // but we can use the code from above ifile.open("test_output"); string read_tags; getline(ifile, read_tags); ifile >> test_name1; ifile >> test_tags_start; getline (ifile, test_tags_rest); test_tags1 = test_tags_start + test_tags_rest; ifile >> test_name2; ifile >> test_tags_start; getline (ifile, test_tags_rest); test_tags2 = test_tags_start + test_tags_rest; ifile.close(); line1=false, line2=false; // Now we created the file, see if the output was right // Line 1 if ((test_name1 == "D3") && (test_tags1 == "Tasty cows")) { line1 = true; } else { if (test_name1 != "D3") { cerr << "Test_name1 was not read properly. It should have been D3 and it was: " << test_name1 << endl; } if (test_tags1 != "Tasty cows"){ cerr << "Test_tags1 was not read properly. It hould have been Tasty cows and it was: " << test_tags1 << endl; } } // Line 2 if ((test_name2 == "D4") && (test_tags2 == "Brown cows")) { line2 = true; } else { if (test_name2 != "D4") { cerr << "Test_name2 was not read properly. It should have been D4 and it was: " << test_name2 << endl; } if (test_tags2 != "Brown cows"){ cerr << "Test_tags2 was not read properly. It hould have been Brown cows and it was: " << test_tags2 << endl; } } if (line1 && line2 && (read_tags == "Cow collection")) { total += pset_save_set; cerr << setw(40) << "Photo_set::save_set" << setw(10) << "Passed" << endl; } else{ cerr << setw(40) << "Photo_set::save_set" << setw(10) << "FAIL" << endl; } // Test the load_set // We should be able to load the set we just saved Photo_set another_set; another_set.load_set("test_output"); // Now test that all of the elements are the same bool same = true; if (test_set.get_name() != another_set.get_name()) same = false; if (test_set.number_of_images() == another_set.number_of_images()){ for (int i = 1; i <= test_set.number_of_images(); i++){ string test_set_tags = test_set.extract_image(i).get_tags(); string another_set_tags = another_set.extract_image(i).get_tags(); // Remove leading spaces from both tags while (test_set_tags.at(0) == ' '){ test_set_tags.erase(0,1); } while (another_set_tags.at(0) == ' '){ another_set_tags.erase(0,1); } // Now there should be no leading spaces if (test_set_tags != another_set_tags){ same = false; cerr << "Tag mismatch"<< endl; } else { // match after removing spaces } } } else { cerr << "Mismatch in number of images" << endl; same = false; } // Load again to make sure the list is cleared bool cleared = true; int before = another_set.number_of_images(); another_set.load_set("test_output"); if (another_set.number_of_images() != before){ cleared = false; cerr << "Before: " << before << endl; cerr << "After: " << another_set.number_of_images() << endl; } if (same && cleared){ cerr << setw(40) << "Photo_set::load_set" << setw(10) << "Passed" << endl; total += pset_load_set; } else { if (same && !cleared){ cerr << setw(40) << "Photo_set::load_set" << setw(10) << "FAIL;!clear" << endl; total += pset_load_set - pset_load_clear_penalty; } else { cerr << setw(40) << "Photo_set::load_set" << setw(10) << "FAIL" << endl; } } cerr << endl << setw(40) << "Total points: " << setw(10) << total << endl; }