/////////////////////////////////////////////////////////////// // // // utstr3.cpp - unit test operators and their support // // // // Source: strs.hpp, strs.cpp v4.4 // // Author: Jim Fawcett, x2654, jfawcett@neptune // // // /////////////////////////////////////////////////////////////// // // // Files needed: // // utstr3.cpp, strs.hpp, strs.cpp // // // // Build command: // // bc utstr3.cpp // // - sets up test driver for debugger walkthrough // // inside integrated development environment // // - single step through tests, tracing into each // // invoked function // // // // Note: utstr3.cpp includes the other files so // // no project file is needed // // // /////////////////////////////////////////////////////////////// // // // Maintenance History: // // v1.0 - 16 Oct 94 // // . tests created // // // /////////////////////////////////////////////////////////////// // // // Signature indicates tests were all run and verified // // all expected results. // // // // // // Signature: Date: // // -------------------------- ----------- // // // /////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////// // // // utstr3.cpp - unit test #3a // // buffResize() expands input buffer used // // with operator>>() // // // // Source: strs.hpp, strs.cpp v4.4 // // Author: Jim Fawcett, x2654, jfawcett@neptune // // // /////////////////////////////////////////////////////////////// // // // Preconditions: // // - str::INBUFFSIZE set to eight by inserting identifier // // TEST_BUFFSIZE in dialog box obtained from menu select // // Options/Compiler/Code generation/Defines // // Derived requirements: // // - expand buffer to make room for input // // - if INBUFFSIZE = 0 then set to 8, else double existing // // value // // // /////////////////////////////////////////////////////////////// // // // Test Procedure - test by debugger walkthrough // // - use TEST_BUFFSIZE in defines dialog box and single // // step through operator>>() and into bufResize() // // - watch INBUFFSIZE // // // // Expected test results: Results verified // // - INBUFFSIZE increases from eight - // // to sixteen // // // /////////////////////////////////////////////////////////////// // // // Signature: Date: // // -------------------------- ----------- // // // /////////////////////////////////////////////////////////////// #include #include #include "strs.hpp" #include "strs.cpp" void main() { ifstream instrm("tststr.dat"); if(!instrm.good()) { cout << "can't open test file tststr1.dat\n"; exit(1); } str tst3a1; instrm >> tst3a1; instrm.close(); // /////////////////////////////////////////////////////////////// // // // utstr3.cpp - unit test #3b // // str& operator=(const str& s) assignment // // // // Source: strs.hpp, strs.cpp v4.4 // // Author: Jim Fawcett, x2654, jfawcett@neptune // // // /////////////////////////////////////////////////////////////// // // // Preconditions: // // - existing objects to assign from and to // // Derived requirements: // // - assign values from one string object to another // // . check to insure not assigning to self (causes // // memory allocation problems) // // . old heap allocation is deleted if it exists // // . new allocation is created for left hand side // // equal to right hand side // // . physical size is set to allocated size // // . smax is set to size of allocation minus one // // . slen is set to length of existing str object // // // /////////////////////////////////////////////////////////////// // // // Test Procedure - test by debugger walkthrough // // - use null str, filled str, and partially filled str, // // and assignment to self as inputs // // - watch slen, s.slen, smax, s.smax, (char*)shead, // // (char*)s.shead, bytes_alloc // // // /////////////////////////////////////////////////////////////// // // // Expected test results: Results verified // // - smax set to s.slen - // // - slen set to s.slen - // // - shead[i] == s.shead[i], i=0..slen - // // - bytes_alloc decremented by old size - // // (incremented by new size in strAlloc) // // // /////////////////////////////////////////////////////////////// // // // Signature: Date: // // -------------------------- ----------- // // // /////////////////////////////////////////////////////////////// // // test assignment of null string to null string // exercises first if block str tst3b1; str tst3b2; tst3b2 = tst3b1; // test assignment of larger string to smaller string // exercises else of second if block tst3b2 = "this is a string"; str tst3b3; tst3b3 = tst3b2; // test assignment of partially filled str to filled string // exercises else if of second if block str tst3b4('x',20); tst3b4 = "another"; str tst3b5 = "another string"; tst3b5 = tst3b4; // test assignment of filled string to partially filled string // exercises second if block tst3b4 = "this is a longer string"; tst3b4 = tst3b2; // test four different kinds of assignment to self tst3b4 = tst3b4; str* ptr = &tst3b4; tst3b4 = *ptr; ptr->operator=(tst3b4); // /////////////////////////////////////////////////////////////// // // // utstr3.cpp - unit test #3c // // str& operator+=(const str& s) assignment // // // // Source: strs.hpp, strs.cpp v4.4 // // Author: Jim Fawcett, x2654, jfawcett@neptune // // // /////////////////////////////////////////////////////////////// // // // Preconditions: // // - existing objects to assign from and to // // Derived requirements: // // - concatenate values from right string object onto // // left string object // // . return if right hand side has zero length // // . allocate smallest possible memory for concatenation // // . copy left side into head of allocated buffer // // . copy right side into tail of allocated buffer // // delete allocation of left hand side // // . make new allocation the left side's buffer // // . set slen and smax to the size of the allocation // // . slen is set to length of existing str object // // // /////////////////////////////////////////////////////////////// // // // Test Procedure - test by debugger walkthrough // // - use null str, filled str, and partially filled str, // // for left and right sides // // - watch slen, s.slen, smax, s.smax, (char*)shead, // // (char*)s.shead, bytes_alloc // // // /////////////////////////////////////////////////////////////// // // // Expected test results: Results verified // // - smax set to slen + s.slen - // // - slen set to new smax - // // - shead[i+slen] == s.shead[i], i=0..slen - // // - bytes_alloc decremented by old size - // // (incremented by new size in strAlloc) // // // /////////////////////////////////////////////////////////////// // // // Signature: Date: // // -------------------------- ----------- // // // /////////////////////////////////////////////////////////////// // additive assignment of one null to another str tst3c1, tst3c2; tst3c1 += tst3c2; // additive assignment of filled string with another tst3c1 = "this is "; tst3c2 = "a concatenated string"; tst3c1 += tst3c2; // additive assignment of partially filled string with another str tst3c3('x',20), tst3c4('y',25); tst3c3 = "xxxxx"; tst3c4 = "yyyyyyyyyyyyyyy"; tst3c3 += tst3c4; // /////////////////////////////////////////////////////////////// // // // utstr3.cpp - unit test #3d // // str& operator+(const str& s) concatenation // // // // Source: strs.hpp, strs.cpp v4.4 // // Author: Jim Fawcett, x2654, jfawcett@neptune // // // /////////////////////////////////////////////////////////////// // // // Preconditions: // // - existing objects to concatenate // // Derived requirements: // // - concatenate values from right string object onto // // left string object, return concatenated str // // . create temporary object to hold sum // // . copy left side into head of allocated buffer // // . copy right side into tail of allocated buffer // // . return temporary by value // // // /////////////////////////////////////////////////////////////// // // // Test Procedure - test by debugger walkthrough // // - use null str, filled str, and partially filled str, // // for left and right sides // // - watch temp.slen, temp.smax, (char*)temp.shead, // // return str // // // /////////////////////////////////////////////////////////////// // // // Expected test results: Results verified // // - temp.smax set to slen + s.slen - // // - temp.slen set to new smax - // // - temp.shead[i] = shead[i], i=0..slen - // // - temp.shead[i+slen] = s.shead[i], - // // i=0..slen+2 // // - return is identical to temp // // // /////////////////////////////////////////////////////////////// // // // Signature: Date: // // -------------------------- ----------- // // // /////////////////////////////////////////////////////////////// // concatenation of one null onto another str tst3d1, tst3d2; str tst3d3 = tst3d1 + tst3d2; // concatenation of filled string onto another tst3d1 = "this is "; tst3d2 = "a concatenated string"; tst3d3 = tst3d1 + tst3d2; // additive assignment of partially filled string with another str tst3d4('x',20), tst3d5('y',25); tst3d4 = "xxxxx"; tst3d5 = "yyyyyyyyyyyyyyy"; str tst3d6 = tst3d4 + tst3d5; // /////////////////////////////////////////////////////////////// // // // utstr3.cpp - unit test #3e // // istream& operator>>(istream& istrm, str& s) // // insert(char ch, int i) // // // // Source: strs.hpp, strs.cpp v4.4 // // Author: Jim Fawcett, x2654, jfawcett@neptune // // // /////////////////////////////////////////////////////////////// // // // Preconditions: // // - existing object to insert from input stream // // - uses TSTSTR.DAT dated 10-3-93 10::44p // // Derived requirements: // // - fill str buffer from input stream using insert(ch,n) // // - discard leading whitespace // // - stop after encountering a trailing newline if // // str::lextype == str::getlines // // - stop at trailing whitespace if // // str::lextype == str::gettokens // // - use expandable buffer to accept object of unknown // // size, expand by doubling when object grows too big // // - resize input str's buffer if too small to hold new // // object, otherwise leave alone // // // /////////////////////////////////////////////////////////////// // // // Test Procedure - test by debugger walkthrough // // - use null str, filled str, and partially filled str, // // for inserted object // // - use getlines, gettokes, and (lextype)2 to test all // // lexing alternatives // // // /////////////////////////////////////////////////////////////// // // // Expected test results: Results verified // // - error message sent if inappropriate - // // lextype // // - s buffer expanded if too small, other- - // // wise left alone // // - s.smax, s.slen set to new allocation - // // if buffer expanded, otherwise left alone // // - (char*)s.shead filled with input chars - // // up to first newline then returns when // // lextype == getlines // // - (char*)s.shead filled with input chars - // // up to first trailing whitespace char // // when lextype == getlines // // // /////////////////////////////////////////////////////////////// // // // Signature: Date: // // -------------------------- ----------- // // // /////////////////////////////////////////////////////////////// // // read lines ifstream in("tststr.dat"); if(!in.good()) { cout << "can't open test file tststr1.dat\n"; exit(1); } str::setLex(str::getlines); str tst3e1; // first read tests if(!visited) block // and if(str::lextype == str::getlines) block // also walks through private helper function insert(ch,int) in >> tst3e1; // next read shows that s buffer is expanded // if not large enough in >> tst3e1; // next read shows that s buffer is left alone // if bigger than input in >> tst3e1; // next read tests eof break in >> tst3e1; // read tokens in.close(); in.open("tststr.dat"); str::setLex(str::gettokens); str tst3e2; // next read tests if(str::lextype == str::gettokens) block // and extract next token sub-block in >> tst3e2; // demonstrates that s buffer is expanded if too small in >> tst3e2; // tests extraction of quoted str sub-block in >> tst3e2; // demonstrates that s buffer is left alone // if bigger than input object in >> tst3e2; // test eof sub-block in gettokens area while(in.good()) in >> tst3e2; // get lexing error message by casting to unknow lexType str::setLex((str::lexType)2); // next statement causes abort due to lexical error // remove comments to test // in >> tst3e2; // /////////////////////////////////////////////////////////////// // // // utstr3.cpp - unit test #3f // // char& operator[](const int n) indexing // // // // Source: strs.hpp, strs.cpp v4.4 // // Author: Jim Fawcett, x2654, jfawcett@neptune // // // /////////////////////////////////////////////////////////////// // // // Preconditions: // // - existing object to index // // Derived requirements: // // - read from, and write to, nth char in allocated buffer // // - if index out of bounds send error message and return // // save value // // . if n < 0 or n >slen send message and return safe // // . otherwise return reference to nth buffer element // // // /////////////////////////////////////////////////////////////// // // // Test Procedure - test by debugger walkthrough // // - use null str, filled str, and partially filled str, // // for right side // // - use negative, in-range, and too large index // // - watch n and return character // // // /////////////////////////////////////////////////////////////// // // // Expected test results: Results verified // // - error message sent and safe returned - // // when n < 0 and when slen < n // // - value of nth char returned when read - // // - value of nth char changed when written - // // // /////////////////////////////////////////////////////////////// // // // Signature: Date: // // -------------------------- ----------- // // // /////////////////////////////////////////////////////////////// str tst3f1 = "this is a string"; // indexing out of bounds char ch = tst3f1[-2]; tst3f1[50] = 'z'; // reading in bounds ch = tst3f1[5]; // writing in bounds tst3f1[5] = '@'; // dummy statement to keep debugger active str temp; }