#include "salist.h" // this is the file that i have written that is supposed to be able to run though this successfully
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;
const int NUMELEM=100;
struct Book{
int id_;
char author_[31];
char title_[41];
Book(){
id_=100;
strcpy(author_,"someone");
strcpy(title_,"ABC");
}
};
ostream& operator<<(ostream& os,const Book& b);
template <class T>
void adjust(int idx,T arr[]);
template <class T>
void remove(int idx,T arr[],int sz);
bool checkInts(const int correctlist[],const int checklist[],int sz);
bool checkBooks(const Book correctlist[],const Book checklist[],int sz);
bool sameBook(const Book& b1,const Book& b2);
bool checkID(const Book& idptr,const Book& B);
bool checkTitle(const Book& ptr,const Book& B);
bool checkInt(const int& numptr,const int& val);
int main(void){
int numbooks;
Book* bookrecs;
Book* bookcheck;
Book* bookorig;
Node<Book>* booknode;
Node<int>* intnode;
int intrecs[NUMELEM],intcheck[NUMELEM],intorig[NUMELEM];
FILE* fs=fopen("a1q2data.txt","r");
bool passtest=true;
int pick;
Book Nomatch;
int ipassback;
if(fs){
SAList<int> ilist;
SAList<Book> blist;
fscanf(fs,"%d\n",&numbooks);
bookrecs=new Book[numbooks];
bookcheck=new Book[numbooks];
bookorig=new Book[numbooks];
for(int i=0;i<numbooks;i++){
fscanf(fs,"%d;%[^;];%[^\n]\n",&(bookrecs[i].id_),
bookrecs[i].author_,bookrecs[i].title_);
}
for(int i=0;i<numbooks;i++){
blist.insert(bookrecs[numbooks-1-i]);
bookorig[i]=bookrecs[i];
}
for(int i=0;i<NUMELEM;i++){
ilist.insert(i);
intrecs[NUMELEM-1-i]=i;
}
for(int i=0;i<NUMELEM;i++){
intorig[i]=intrecs[i];
}
if(blist.get(bookcheck,numbooks) && !checkBooks(bookcheck,bookrecs,numbooks)){
passtest=false;
cout << "Error 1: Bug in either constructor, insert() or get()"<< endl;
}
if (passtest){
ilist.get(intcheck,NUMELEM);
if(!checkInts(intcheck,intrecs,NUMELEM)){
passtest=false;
cout << "Error 2: Bug in either constructor, insert() or get()" << endl;
}
}
SAList<Book> bcopy=blist;
SAList<int> icopy=ilist;
if(passtest){
if(bcopy.get(bookcheck,numbooks) && !checkBooks(bookcheck,bookrecs,numbooks)){
passtest=false;
cout << "Error 3: Error in your copy constructor"<< endl;
}
if (passtest){
icopy.get(intcheck,NUMELEM);
if(!checkInts(intcheck,intrecs,NUMELEM)){
passtest=false;
cout << "Error 4: Error in your copy constructor"<< endl;
}
}
}
if(passtest){
if(blist.search(Nomatch,checkTitle)){
passtest=false;
cout << "Error 5: Failed search() test." << endl;
cout << "search() function return a non-NULL value"<< endl;
cout << "It should have returned a NULL value" << endl;
}
if(passtest){
blist.get(bookcheck,numbooks);
if(!checkBooks(bookcheck,bookrecs,numbooks)){
passtest=false;
cout << "Error 6: List was modified even when search() failed"<< endl;
}
}
}
if(passtest){
if(blist.search(Nomatch,checkID)){
passtest=false;
cout << "Error 7: Failed search() test." << endl;
cout << "search() function return a non-NULL value"<< endl;
cout << "It should have returned a NULL value" << endl;
}
if(passtest){
blist.get(bookcheck,numbooks);
if(!checkBooks(bookcheck,bookrecs,numbooks)){
passtest=false;
cout << "Error 8: Test failed. List was modified even when search failed"<< endl;
}
}
}
if(passtest){
for(int i=0;i<200 && passtest;i++){
if(i==0)
pick=0;
else
pick=rand()%numbooks;
booknode=blist.search(bookrecs[pick],checkTitle);
if(!booknode){
passtest=false;
cout << "Error 9: Failed search() test." << endl;
cout << "search() function returned a NULL" << endl;
cout << "It should have returned the address of the Node found" << endl;
}
if(passtest && !sameBook(booknode->data(),bookrecs[pick])){
passtest=false;
cout << "Error 10: Failed search() test." << endl;
cout << "search() function return value was correct but the node returned" << endl;
cout << "was not the correct node" << endl;
}
if(passtest){
blist.get(bookcheck,numbooks);
adjust(pick,bookrecs);
blist.get(bookcheck,numbooks);
if(!checkBooks(bookcheck,bookrecs,numbooks)){
passtest=false;
cout << "Error 11: Test failed List was not properly adjusted after search"<< endl;
}
}
}//for
for(int i=0;i<200 && passtest;i++){
if(i==100)
pick=0;
else
pick=rand()%numbooks;
booknode=blist.search(bookrecs[pick],checkID);
if(!booknode){
passtest=false;
cout << "Error 12: Failed search() test." << endl;
cout << "search() function returned a NULL pointer, when it should have returned" << endl;
cout << "a node in the list" << endl;
}
if(passtest && !sameBook(booknode->data(),bookrecs[pick])){
passtest=false;
cout << "Error 13: Failed search() test." << endl;
cout << "search() function return value was correct but node returned did not have" << endl;
cout << "the correct book searched for" << endl;
}
if(passtest){
adjust(pick,bookrecs);
blist.get(bookcheck,numbooks);
if(!checkBooks(bookcheck,bookrecs,numbooks)){
passtest=false;
cout << "Error 14: Test failed List was not properly adjusted after search"<< endl;
}
}
}//for
for(int i=0;i<500 && passtest;i++){
if(i==100)
pick=0;
else
pick=rand()%NUMELEM;
intnode=ilist.search(intrecs[pick],checkInt);
if(!intnode){
passtest=false;
cout << "Error 15: Failed search() test." << endl;
cout << "search() function returned a NULL pointer, when it should have returned" << endl;
cout << "a node in the list" << endl;
}
if(passtest && intnode->data()!=intrecs[pick]){
passtest=false;
cout << "Error 16: Failed search() test." << endl;
cout << "search() function return value was correct but node returned did not have" << endl;
cout << "the correct integer searched for" << endl;
}
if(passtest){
adjust(pick,intrecs);
ilist.get(intcheck,NUMELEM);
if(!checkInts(intcheck,intrecs,NUMELEM)){
passtest=false;
cout << "Error 17: Test failed List was not properly adjusted after search"<< endl;
}
}
}//for
}
//test copy constructor
if(passtest){
bcopy.get(bookcheck,numbooks);
if(!checkBooks(bookcheck,bookorig,numbooks)){
passtest=false;
cout << "Error 18: Error in your copy constructor"<< endl;
}
}
if (passtest){
icopy.get(intcheck,NUMELEM);
if(!checkInts(intcheck,intorig,NUMELEM)){
passtest=false;
cout << "Error 19: Error in your copy constructor"<< endl;
}
}
if(passtest){
bcopy=blist;
for(int i=0;i<numbooks;i++){
bookorig[i]=bookrecs[i];
}
bcopy.get(bookcheck,numbooks);
if(!checkBooks(bookcheck,bookrecs,numbooks)){
passtest=false;
cout << "Error 20: Error in your assignment operator"<< endl;
}
}
if(passtest){
icopy=ilist;
for(int i=0;i<NUMELEM;i++){
intorig[i]=intrecs[i];
}
icopy.get(intcheck,NUMELEM);
if(!checkInts(intcheck,intrecs,NUMELEM)){
passtest=false;
cout << "Error 21: Error in your assignment operator"<< endl;
}
}
//test the remove function
if(passtest){
SAList<Book> bempty; //empty list
//remove a node that isn't there
if(blist.remove(Nomatch,checkID)){
passtest=false;
cout << "Error 22: remove() function returned true when called with"<< endl;
cout << "id of book that is not in list" << endl;
}
//remove a node from an empty list
if(passtest && bempty.remove(Nomatch,checkID)){
passtest=false;
cout << "Error 23: remove() function returned true when clist is empty"<< endl;
}
//remove the last node in the list
if(passtest && !blist.remove(bookrecs[numbooks-1],checkID)){
passtest=false;
cout << "Error 24: remove() function returned false when trying to"<< endl;
cout << "remove last book in the list" << endl;
}
if(passtest){
remove(numbooks-1,bookrecs,numbooks);
blist.get(bookcheck,numbooks-1);
if(!checkBooks(bookcheck,bookrecs,numbooks-1)){
passtest=false;
cout << "Error 25: remove() function did not properly remove the node"<< endl;
}
}
//remove the first node in the list
if(passtest && !blist.remove(bookrecs[0],checkID)){
passtest=false;
cout << "Error 26: remove() function returned false when trying to"<< endl;
cout << "remove first book in the list" << endl;
}
if(passtest){
remove(0,bookrecs,numbooks-1);
blist.get(bookcheck,numbooks-2);
if(!checkBooks(bookcheck,bookrecs,numbooks-2)){
passtest=false;
cout << "Error 27: remove() function did not properly remove the node"<< endl;
}
}
//removes some node in middle of list
if(passtest && !blist.remove(bookrecs[5],checkID)){
passtest=false;
cout << "Error 28: remove() function returned false when trying to"<< endl;
cout << "remove book in the middle of the list" << endl;
}
if(passtest){
remove(5,bookrecs,numbooks-2);
blist.get(bookcheck,numbooks-3);
if(!checkBooks(bookcheck,bookrecs,numbooks-3)){
passtest=false;
cout << "Error 29: remove() function did not properly remove the node"<< endl;
}
}
}
//test for deep copy in = operator
if(passtest){
bcopy.get(bookcheck,numbooks);
if(!checkBooks(bookcheck,bookorig,numbooks)){
passtest=false;
cout << "Error 30: Error in your assignment operator"<< endl;
}
}
//test the remove function
if(passtest){
SAList<int> iempty;
//remove a node from an empty list
if(iempty.remove(intrecs[0],checkInt)){
passtest=false;
cout << "Error 31: remove() function returned true when clist is empty"<< endl;
}
//remove the last node in the list
if(passtest && !ilist.remove(intrecs[NUMELEM-1],checkInt)){
passtest=false;
cout << "Error 32: remove() function returned false when trying to"<< endl;
cout << "remove last node in the list" << endl;
}
if(passtest){
remove(NUMELEM-1,intrecs,NUMELEM);
ilist.get(intcheck,NUMELEM-1);
if(!checkInts(intcheck,intrecs,NUMELEM-1)){
passtest=false;
cout << "Error 33: remove() function did not properly remove the node"<< endl;
}
}
//remove the first node in the list
if(passtest && !ilist.remove(intrecs[0],checkInt)){
passtest=false;
cout << "Error 34: remove() function returned false when trying to"<< endl;
cout << "remove first book in the list" << endl;
}
if(passtest){
remove(0,intrecs,NUMELEM-1);
ilist.get(intcheck,NUMELEM-2);
if(!checkInts(intcheck,intrecs,NUMELEM-2)){
passtest=false;
cout << "Error 35: remove() function did not properly remove the node"<< endl;
}
}
//removes some node in middle of list
if(passtest && !ilist.remove(intrecs[10],checkInt)){
passtest=false;
cout << "Error 36: remove() function returned false when trying to"<< endl;
cout << "remove an item from middle of the list" << endl;
}
if(passtest){
remove(10,intrecs,NUMELEM-2);
ilist.get(intcheck,NUMELEM-3);
if(!checkInts(intcheck,intrecs,NUMELEM-3)){
passtest=false;
cout << "Error 37: remove() function did not properly remove the node"<< endl;
}
}
}
if(passtest){
bcopy.get(bookcheck,numbooks);
if(!checkBooks(bookcheck,bookorig,numbooks)){
passtest=false;
cout << "Error 38: Error in your assignment operator"<< endl;
}
}
if(passtest){
cout << "Testing for Q2 completed. All tests passed" << endl;
}
delete bookrecs;
delete bookcheck;
}
else{
cout << "Error: You need to have the file a1q2data.txt to run this main" << endl;
}
}
template <class T>
void adjust(int idx,T arr[]){
T temp=arr[idx];
for (int i=idx;i>0 ;i--){
arr[i]=arr[i-1];
}/*for*/
arr[0]=temp;
}
template <class T>
void remove(int idx,T arr[],int sz){
for(int i=idx;i<sz-1;i++){
arr[i]=arr[i+1];
}
}
bool checkInts(const int checklist[],const int correctlist[],int sz){
bool rc=true;
for(int i=0;i<sz && rc;i++){
if(correctlist[i]!=checklist[i])
rc=false;
}
return rc;
}
bool checkBooks(const Book correctlist[],const Book checklist[],int sz){
bool rc=true;
for(int i=0;i<sz && rc;i++){
if(!sameBook(correctlist[i],checklist[i]))
rc=false;
}
return rc;
}
bool sameBook(const Book& b1,const Book& b2){
bool rc=true;
if((b1.id_!=b2.id_) ||
strcmp(b1.author_,b2.author_)!=0 ||
strcmp(b1.title_,b2.title_)!=0 ){
rc=false;
}
return rc;
}
bool checkID(const Book& b1,const Book& b2){
bool rc=false;
if(b1.id_==b2.id_){
rc=true;
}
return rc;
}
bool checkTitle(const Book& b1,const Book& b2){
bool rc=false;
if(strcmp(b1.title_,b2.title_)==0){
rc=true;
}
return rc;
}
bool checkInt(const int& n1,const int& val){
bool rc=false;
if(n1==val){
rc=true;
}
return rc;
}
ostream& operator<<(ostream& os,const Book& b){
os << "ID: " << b.id_ << endl;
os << "Author: " << b.author_ << endl;
os << "Title: " << b.title_ << endl;
return os;
}