Bläddra i källkod

Set up directory structure for CodeDweller unit tests.


git-svn-id: https://svn.microneil.com/svn/CodeDweller-Tests/trunk@13 b3372362-9eaa-4a85-aa2b-6faa1ab7c995
master
adeniz 10 år sedan
förälder
incheckning
bb46e541a5
4 ändrade filer med 2872 tillägg och 0 borttagningar
  1. 2401
    0
      TestChild/Doxyfile
  2. 14
    0
      TestChild/buildAndRun
  3. 46
    0
      TestChild/childProgram.cpp
  4. 411
    0
      TestChild/testChild.cpp

+ 2401
- 0
TestChild/Doxyfile
Filskillnaden har hållits tillbaka eftersom den är för stor
Visa fil


+ 14
- 0
TestChild/buildAndRun Visa fil

@@ -0,0 +1,14 @@
CFLAGS='-ICodeDweller -std=c++0x -g -O0'
g++ $CFLAGS childProgram.cpp -o childProgram
if [ $? -ne 0 ]
then
exit -1
fi

g++ $CFLAGS testChild.cpp CodeDweller/child.cpp -o testChild
if [ $? -ne 0 ]
then
exit -1
fi

./testChild

+ 46
- 0
TestChild/childProgram.cpp Visa fil

@@ -0,0 +1,46 @@
#include <iostream>
#include <string>
#include <thread>
#include <chrono>
int
main(int argc, char *argv[]) {
// std::this_thread::sleep_for(std::chrono::milliseconds(150));
// Output for read test.
if (argc == 2) {
// Write a single line and exit.
if (std::string(argv[1]) == "write") {
std::cout << "This is a test";
std::cout.flush();
return 25;
}
// Exit without writing anything.
if (std::string(argv[1]) == "quit") {
return 25;
}
}
char ch;
while (std::cin >> ch) {
// Exit?
if ('q' == ch) {
break;
}
std::cout << (char) std::toupper(ch);
std::cout.flush();
}
return 25;
}

+ 411
- 0
TestChild/testChild.cpp Visa fil

@@ -0,0 +1,411 @@
#include <cstdlib>
#include <iostream>
#include <chrono>
#include <thread>
#include <sstream>
#include "CodeDweller/child.hpp"
////////////////////////////////////////////////////////////////////////////////
// Configuration ///////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// Child program name.
const std::string childName("./childProgram");
////////////////////////////////////////////////////////////////////////////////
// End of configuration ////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
int nTotalTests = 0;
int nPass = 0;
int nFail = 0;
bool result;
#define NO_EXCEPTION_TERM(msg) \
std::cout \
<< msg << " failed to throw exception at line " \
<< __LINE__ << "." << std::endl
#define EXCEPTION_TERM(msg) \
std::cout \
<< msg << " threw unexpected exception at line " \
<< __LINE__ << ": " << e.what() << std::endl
#define RETURN_FALSE(msg) \
std::cout \
<< msg << " at line " << __LINE__ << std::endl; \
return false;
#define RUN_TEST(test) \
std::cout << " " #test ": "; \
std::cout.flush(); \
result = test(); \
std::cout << (result ? "ok" : "fail") << std::endl; \
nTotalTests++; \
if (result) nPass++; else nFail++;
#define SUMMARY \
std::cout \
<< "\nPass: " << nPass \
<< ", Fail: " << nFail \
<< ", Total: " << nTotalTests << std::endl
////////////////////////////////////////////////////////////////////////////////
// Tests ///////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
bool
testIsDone() {
try {
CodeDweller::Child child(childName);
// Test exception if called out-of-order.
try {
child.isDone();
NO_EXCEPTION_TERM("isDone() called without run()");
return false;
} catch (std::exception &e) {
}
child.run();
if (child.isDone()) {
std::cout << "isDone() failure; returned true." << std::endl;
return false;
}
// Command the child to exit.
child.writer << 'q';
child.writer.flush();
// Sleep to let the child exit.
std::this_thread::sleep_for(std::chrono::milliseconds(100));
if (!child.isDone()) {
std::cout << "isDone() failure; returned false." << std::endl;
return false;
}
} catch (std::exception &e) {
EXCEPTION_TERM("isDone()");
return false;
}
return true;
}
bool
testResult() {
try {
std::vector<std::string> cmd;
cmd.push_back(childName);
cmd.push_back("quit");
CodeDweller::Child child(cmd);
// Test exception if called out-of-order.
try {
(void) child.result();
NO_EXCEPTION_TERM(" result() called without run()");
return false;
} catch (std::exception &e) {
}
child.run();
// Test exception if called while child is running.
try {
(void) child.result();
NO_EXCEPTION_TERM(" result() called before child exited");
return false;
} catch (std::exception &e) {
}
// Wait for the child to exit.
std::this_thread::sleep_for(std::chrono::milliseconds(100));
int32_t result = child.result();
if (25 != result) {
std::cout << "result() failure; returned " << result
<< " instead of 25." << std::endl;
return false;
}
} catch (std::exception &e) {
EXCEPTION_TERM("result()");
return false;
}
return true;
}
bool
testTerminate() {
// Test with no waiting.
try {
CodeDweller::Child child(childName);
child.run();
child.terminate();
} catch (std::exception &e) {
EXCEPTION_TERM("terminate() with no waiting");
return false;
}
// Test with waiting.
try {
CodeDweller::Child child(childName);
child.run();
std::this_thread::sleep_for(std::chrono::milliseconds(100));
child.terminate();
} catch (std::exception &e) {
EXCEPTION_TERM("terminate() with 100 ms waiting");
return false;
}
// Test after the child exits.
std::vector<std::string> cmd;
cmd.push_back(childName);
cmd.push_back("quit");
try {
CodeDweller::Child child(cmd);
child.run();
std::this_thread::sleep_for(std::chrono::milliseconds(100));
child.terminate();
} catch (std::exception &e) {
EXCEPTION_TERM("terminate() after child exits");
return false;
}
// Test exception thrown for out-of-order calling.
try {
CodeDweller::Child child(cmd);
child.terminate();
NO_EXCEPTION_TERM("terminate() called without run()");
return false;
} catch (std::exception &e) {
}
return true;
}
bool
testReaderWriter() {
try {
size_t bufSize = 15;
CodeDweller::Child child(childName, bufSize);
std::ostringstream childOutput;
std::vector<std::string> expectedChildOutput;
char readChar;
// Generate input.
char randomLetter[] = "abcdefghijklmnop#rstuvwxyz";
int nChar = bufSize - 1;
int nLines = 2;
for (int iLine = 0; iLine < nLines; iLine++) {
std::string line;
line.erase();
for (int iChar = 0; iChar < nChar; iChar++) {
line.push_back(randomLetter[std::rand() % 26]);
}
expectedChildOutput.push_back(line);
}
// Test exception.
try {
child.writer << bufSize;
child.writer.flush();
NO_EXCEPTION_TERM(" writer called without run()");
return false;
} catch (std::exception &e) {
}
// Clear the writer stream.
try {
child.writer.clear();
} catch (std::exception &e) {
}
child.run();
// Write, read, put back, and reread each character.
for (std::string line : expectedChildOutput) {
// Write one line.
const char *ptr;
ptr = line.data();
for (std::string::size_type i = 0; i < line.length(); i++) {
child.writer << ptr[i];
if (!child.writer) {
RETURN_FALSE(" Failure in testReaderWriter: writer stream is bad");
}
}
child.writer.flush();
if (!child.writer) {
RETURN_FALSE(" Failure in testReaderWriter: writer stream is bad");
}
// Read one line.
std::string readLine;
readLine.erase();
for (std::string::size_type i = 0; i < line.length(); i++) {
child.reader >> readChar;
if (!child.reader) {
RETURN_FALSE(" Failure in testReaderWriter: reader stream is bad");
}
readLine.push_back(readChar);
}
// Convert to upper case.
std::string expectedLine;
expectedLine = line;
for (auto &c : expectedLine) {
c = toupper(c);
}
// Compare.
if (expectedLine != readLine) {
std::cout << " Failure in testReaderWriter." << std::endl;
std::cout << " Expected: '" << expectedLine
<< "'\n Received: '" << readLine << "'" << std::endl;
return false;
}
}
// Send exit message.
child.writer << 'q';
child.writer.flush();
if (!child.writer) {
RETURN_FALSE(" Failure in testReaderWriter: writer stream is bad");
}
// Verify exit.
std::this_thread::sleep_for(std::chrono::milliseconds(100));
if (!child.isDone()) {
std::cout << " Failure in testReaderWriter: "
<< "Child program did not exit." << std::endl;
return false;
}
} catch (std::exception &e) {
EXCEPTION_TERM("reader()/writer()");
return false;
}
return true;
}
bool
testReader() {
try {
std::vector<std::string> cmd;
cmd.push_back(childName);
cmd.push_back("write");
size_t bufSize = 32;
CodeDweller::Child child(cmd, bufSize);
// Test exception.
try {
int temp;
child.reader >> temp;
NO_EXCEPTION_TERM(" reader called without run()");
return false;
} catch (std::exception &e) {
}
child.reader.clear();
child.writer.clear();
std::ostringstream childOutput;
std::string expectedChildOutput("This is a test");
char readChar;
child.run();
child.reader.exceptions(std::istream::badbit);
child.reader >> std::noskipws;
if (!child.reader) {
RETURN_FALSE(" Failure in testReader: reader stream is bad");
}
while (child.reader >> readChar) {
if (!child.reader) {
RETURN_FALSE(" Failure in testReader: reader stream is bad");
}
child.reader.putback(readChar);
if (!child.reader) {
RETURN_FALSE(" Failure in testReader: reader stream is bad");
}
child.reader >> readChar;
if (!child.reader) {
RETURN_FALSE(" Failure in testReader: reader stream is bad");
}
childOutput << readChar;
}
if (!child.reader.eof()) {
RETURN_FALSE(" Failure in testReader: Error occured before "
"EOF was reached while reading");
}
// Check.
if (childOutput.str() != expectedChildOutput) {
std::cout << " reader() failure in testReader." << std::endl;
std::cout << " Expected: '" << expectedChildOutput
<< "'\n Received: '" << childOutput.str() << "'"
<< std::endl;
return false;
}
if (!child.isDone()) {
std::cout << "isDone() failure in testReader." << std::endl;
return false;
}
} catch (std::exception &e) {
EXCEPTION_TERM("reader()");
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
// End of tests ////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
int main()
{
std::cout << "CodeDweller::Child unit tests" << std::endl << std::endl;
CodeDweller::Child child(childName);
RUN_TEST(testIsDone);
RUN_TEST(testResult);
RUN_TEST(testTerminate);
RUN_TEST(testReader);
RUN_TEST(testReaderWriter);
SUMMARY;
return 0;
}

Laddar…
Avbryt
Spara