/*

* ------

* These functions are designed to help you test your MyString objects,

* as well as show the client usage of the class.

*

* The BasicTest function builds an array of strings using various

* constructor options and prints them out. It also uses the String

* stream operations to read some strings from a data file.

*

* The RelationTest function checks out the basic relational operations

* (==, !=, <, etc) on Strings and char *s.

*

* The ConcatTest functions checks the overloaded + and += operators that

* do string concatenation.

*

* The CopyTest tries out the copy constructor and assignment operators

* to make sure they do a true deep copy.

*

* Although not exhaustive, these tests will help you to exercise the basic

* functionality of the class and show you how a client might use it.

*

* While you are developing your MyString class, you might find it

* easier to comment out functions you are ready for, so that you don't

* get lots of compile/link complaints.

*/

#include "mystring.h"

#include <fstream>

#include <cctype> // for toupper()

#include <string>

#include <cassert>

#include <iostream>

using namespace std;

using namespace cs_mystring;

void BasicTest();

void RelationTest();

void ConcatTest();

void CopyTest();

MyString AppendTest(const MyString& ref, MyString val);

string boolString(bool convertMe);

int main()

{

BasicTest();

RelationTest();

ConcatTest();

CopyTest();

}

string boolString(bool convertMe) {

if (convertMe) {

return "true";

} else {

return "false";

}

}

void BasicTest()

{

MyString s;

int stringLength;

cout < "----- Testing basic String creation & printing" < endl;

const MyString strs[] =

{MyString("Wow"), MyString("C++ is neat!"),

MyString(""), MyString("a-z")};

for (int i = 0; i < 4; i++){

cout < "string [" < i <"] = " < strs[i] < endl;

}

cout < endl < "----- Now reading MyStrings from file" < endl;

cout < endl < "----- first, word by word" < endl;

ifstream in("mystring.txt");

assert(in);

while (in.peek() == '#'){

in.ignore(128, '\n');

}

in > s;

while (in) {

cout < "Read string = " < s < endl;

in > s;

}

in.close();

cout < endl < "----- now, line by line" < endl;

ifstream in2("mystring.txt");

assert(in2);

while (in2.peek() == '#'){

in2.ignore(128, '\n');

}

s.read(in2, '\n');

while (in2) {

cout < "Read string = " < s < endl;

s.read(in2, '\n');

}

cout < endl < "----- Testing access to characters (using const)" < endl;

const MyString s1("abcdefghijklmnopqsrtuvwxyz");

cout < "Whole string is " < s1 < endl;

cout < "now char by char: ";

stringLength = s1.length();

for (int i = 0; i < stringLength; i++){

cout < s1[i];

}

cout < endl < "----- Testing access to characters (using non-const)" < endl;

MyString s2("abcdefghijklmnopqsrtuvwxyz");

cout < "Start with " < s2;

stringLength = s2.length();

for (int i = 0; i < stringLength; i++){

s2[i] = toupper(s2[i]);

}

cout < " and convert to " < s2 < endl;

}

void RelationTest()

{

cout < "\n----- Testing relational operators between MyStrings\n";

const MyString strs[] =

{MyString("app"), MyString("apple"), MyString(""),

MyString("Banana"), MyString("Banana")};

for (int i = 0; i < 4; i++) {

cout < "Comparing " < strs[i] < " to " < strs[i+1] < endl;

cout < "\tIs left < right? " < boolString(strs[i] < strs[i+1]) < endl;

cout < "\tIs left <= right? " < boolString(strs[i] <= strs[i+1]) < endl;

cout < "\tIs left > right? " < boolString(strs[i] > strs[i+1]) < endl;

cout < "\tIs left >= right? " < boolString(strs[i] >= strs[i+1]) < endl;

cout < "\tDoes left == right? " < boolString(strs[i] == strs[i+1]) < endl;

cout < "\tDoes left != right ? " < boolString(strs[i] != strs[i+1]) < endl;

}

cout < "\n----- Testing relations between MyStrings and char *\n";

MyString s("he");

const char *t = "hello";

cout < "Comparing " < s < " to " < t < endl;

cout < "\tIs left < right? " < boolString(s < t) < endl;

cout < "\tIs left <= right? " < boolString(s <= t) < endl;

cout < "\tIs left > right? " < boolString(s > t) < endl;

cout < "\tIs left >= right? " < boolString(s >= t) < endl;

cout < "\tDoes left == right? " < boolString(s == t) < endl;

cout < "\tDoes left != right ? " < boolString(s != t) < endl;

MyString u("wackity");

const char *v = "why";

cout < "Comparing " < v < " to " < u < endl;

cout < "\tIs left < right? " < boolString(v < u) < endl;

cout < "\tIs left <= right? " < boolString(v <= u) < endl;

cout < "\tIs left > right? " < boolString(v > u) < endl;

cout < "\tIs left >= right? " < boolString(v >= u) < endl;

cout < "\tDoes left == right? " < boolString(v == u) < endl;

cout < "\tDoes left != right ? " < boolString(v != u) < endl;

}

void ConcatTest()

{

cout < "\n----- Testing concatentation on MyStrings\n";

const MyString s[] =

{MyString("outrageous"), MyString("milk"), MyString(""),

MyString("cow"), MyString("bell")};

for (int i = 0; i < 4; i++) {

cout < s[i] < " + " < s[i+1] < " = " < s[i] + s[i+1] < endl;

}

cout < "\n----- Testing concatentation between MyString and char *\n";

const MyString a("abcde");

const char *b = "XYZ";

cout < a < " + " < b < " = " < a + b < endl;

cout < b < " + " < a < " = " < b + a < endl;

cout < "\n----- Testing shorthand concat/assign on MyStrings\n";

MyString s2[] =

{MyString("who"), MyString("what"), MyString("WHEN"),

MyString("Where"), MyString("why")};

for (int i = 0; i < 4; i++) {

cout < s2[i] < " += " < s2[i+1] < " = ";

cout < (s2[i] += s2[i+1]) < "and";

cout < s2[i] < endl;

}

cout < "\n----- Testing shorthand concat/assign using char *\n";

MyString u("I love ");

const char *v = "programming";

cout < u < " += " < v < " = ";

cout < (u += v) < endl;

}

MyString AppendTest(const MyString& ref, MyString val)

{

val[0] = 'B';

return val + ref;

}

void CopyTest()

{

cout < "\n----- Testing copy constructor and operator= on MyStrings\n";

MyString orig("cake");

MyString copy(orig); // invoke copy constructor

copy[0] = 'f'; // change first letter of the *copy*

cout < "original is " < orig < ", copy is " < copy < endl;

MyString copy2; // makes an empty string

copy2 = orig; // invoke operator=

copy2[0] = 'f'; // change first letter of the *copy*

cout < "original is " < orig < ", copy is " < copy2 < endl;

copy2 = "Copy Cat";

copy2 = copy2; // copy onto self and see what happens

cout < "after self assignment, copy is " < copy2 < endl;

cout < "Testing pass & return MyStrings by value and ref" < endl;

MyString val = "winky";

MyString sum = AppendTest("Boo", val);

cout < "after calling Append, sum is " < sum < endl;

cout < "val is " < val < endl;

val = sum;

cout < "after assign, val is " < val < endl;

}