/************************************************* * Tester * The top-level testing class. Each derived * class inherits the routines: * * int run() * * For a derived class to function, it must * override the void process() member function. * The process function should read in a line from * the input file and tests the routine based on * those instructions. * * The member variables are: * * Class_name *object A pointer to the object * being tested. * * string command The string read in from * the input file indicating * the next command to be * tested. * * int count The number of the current * test being run. * * The member functions are: * * int run() Start a test run testing until * the end of the file, one test * per line. * void process() Process and run an individual * test. * * Author: Douglas Wilhelm Harder * Copyright (c) 2006-9 by Douglas Wilhelm Harder. All rights reserved. * * DO NOT EDIT THIS FILE *************************************************/ #ifndef TESTER_H #define TESTER_H #ifndef nullptr #define nullptr 0 #endif #include #include #include #include "ece250.h" template class Tester { protected: Class_name *object; std::string command; public: Tester( Class_name *obj = nullptr ): object( obj ) { // emtpy constructor } int run(); virtual void process() = 0; }; /**************************************************** * int run() * * Indefinite run of test cases: continue reading console * input until the end of the file. ****************************************************/ template int Tester::run() { // read the flag which indicates the command to be test and // stop if we have reached the end of the file ece250::allocation_table.stop_recording(); const static std::string prompt = " % "; while ( true ) { // terminate if there is an end-of-file or the user types 'exit' if ( std::cin.eof() ) { break; } ++ece250::count; std::cout << ece250::count << prompt; std::cin >> command; // Remove any comments if ( command.substr( 0, 2 ) == "//" ) { char comment[1024]; std::cin.getline( comment, 1024 ); std::cout << command << comment << std::endl; continue; } // terminate if there is an end-of-file or the user types 'exit' if ( std::cin.eof() ) { std::cout << "Exiting..." << std::endl; break; } // If the user enters !!, // set the command to be the last command // If the user enters !n where n is a number, (1 <= n < count) // set the command ot be the nth command if ( command == "!!" ) { if ( ece250::count == 1 ) { std::cout << "Event not found" << std::endl; continue; } command = ece250::history[ece250::count - 1]; } else if ( command[0] == '!' ) { int n; std::istringstream number( command.substr( 1, command.length() - 1 ) ); number >> n; if ( n <= 0 || n >= ece250::count || n >= 1000 ) { std::cout << "Event not found" << std::endl; continue; } command = ece250::history[n]; } // only track the first 1001 commands if ( ece250::count < 1000 ) { ece250::history[ece250::count] = command; } // start tracking any memory allocations made ece250::allocation_table.start_recording(); // There are five key commands if ( command == "exit" ) { std::cout << "Okay" << std::endl; ece250::allocation_table.stop_recording(); break; } else if ( command == "delete" ) { delete object; object = nullptr; std::cout << "delete object; // Okay" << std::endl; } else if ( command == "summary" ) { ece250::allocation_table.summary(); } else if ( command == "details" ) { ece250::allocation_table.details(); } else if ( command == "memory" ) { int n; std::cin >> n; if ( n == ece250::allocation_table.memory_alloc() ) { std::cout << "Okay" << std::endl; } else { std::cout << "Failure in memory allocation: expecting " << n << " bytes to be allocated, but " << ece250::allocation_table.memory_alloc() << " bytes were allocated" << std::endl; } } else if ( command == "memory_store" ) { ece250::allocation_table.memory_store(); std::cout << "Okay" << std::endl; } else if ( command == "memory_change" ) { int n; std::cin >> n; ece250::allocation_table.memory_change( n ); } else { process(); } // stop tracking any memory allocations made ece250::allocation_table.stop_recording(); } return 0; } #endif