/** @file

    $Id$

    $Date$
    $Author$

    @copy &copy; Marc W&auml;ckerlin
    @license LGPL, see file <a href="license.html">COPYING</a>

    $Log$
    Revision 1.9  2005/04/19 18:48:00  marc
    new feature PartialExec

    Revision 1.8  2005/04/07 20:55:21  marc
    Oops, there's a make distcheck...? Now it works.

    Revision 1.7  2004/12/20 13:21:21  marc
    exception tests: each exception must be in an own test case

    Revision 1.6  2004/12/14 20:30:10  marc
    added possibility to pass string to stdin of child process

    Revision 1.5  2004/10/13 10:43:11  marc
    test for bad exception specification

    Revision 1.4  2004/08/28 16:21:25  marc
    mrw-c++-0.92 (mrw)
    - new file: version.cpp
    - new file header for all sources
    - work around warning in mrw::auto<T>
    - possibility to compile without log4cxx
    - work around bugs in demangle.h and libiberty.h
    - corrections in documentation
    - added simple tracing mechanism
    - more warnings
    - small corrections in Auto<>::Free and a new test for it
    - possibility to compile without stack trace

*/
#include <mrw/exec.hpp>
#include <mrw/stacktrace.hpp>
#include <mrw/stdext.hpp>
#include <cppunit/TestFixture.h>
#include <cppunit/ui/text/TestRunner.h>
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <string>
#include <stdlib.h>

class ExecTest: public CppUnit::TestFixture {
public:
  void lsTest() {
    std::string res = (mrw::Cmd("/bin/ls"), "-l",
                       std::string(getenv("srcdir"))+"/..").execute();
    CPPUNIT_ASSERT(res.find("COPYING")<res.size());
  }
  void catTest() {
    std::string res = mrw::Cmd("/bin/cat").execute("This is a test");
    CPPUNIT_ASSERT(res=="This is a test");
  }
  void excTest1() {
    std::string res = (mrw::Cmd("/bin/false")).execute().result();
  }
  void excTest2() {
    std::string res = (mrw::Cmd("/bin/false")).execute("").result();
  }
  void unexpectedExc() throw(std::bad_exception) {
    std::string res = (mrw::Cmd("/bin/false")).execute().result();
  }
  void lsTest2() {
    std::string res;
    mrw::PartialExec exec = (mrw::Cmd("/bin/ls"), "-l",
                             std::string(getenv("srcdir"))+"/..").start();
    while (!exec.finished()) res+=exec.read().first;
    CPPUNIT_ASSERT(res.find("COPYING")<res.size());
  }
  void catTest2() {
    mrw::PartialExec exec = mrw::Cmd("/bin/cat").start(true);
    std::string res = exec.read("This is a test\n").first;
    res += exec.read("More to come...\n").first;
    exec.finish();
    while (!exec.finished()) res+=exec.read().first;
    CPPUNIT_ASSERT(res=="This is a test\nMore to come...\n");
  }
  void excTest12() {
    mrw::PartialExec exec = (mrw::Cmd("/bin/false")).start();
    while (!exec.finished()) exec.read();
  }
  void excTest22() {
    mrw::PartialExec exec = (mrw::Cmd("/bin/false")).start(true);
    while (!exec.finished()) exec.read("xxx");
  }
  void unexpectedExc2() throw(std::bad_exception) {
    mrw::PartialExec exec = (mrw::Cmd("/bin/false")).start();
    while (!exec.finished()) exec.read();
  }
  CPPUNIT_TEST_SUITE(ExecTest);
  CPPUNIT_TEST(lsTest);
  CPPUNIT_TEST(catTest);
  CPPUNIT_TEST_EXCEPTION(excTest1, mrw::ExecutionFailedExc);
  CPPUNIT_TEST_EXCEPTION(excTest2, mrw::ExecutionFailedExc);
  CPPUNIT_TEST_EXCEPTION(unexpectedExc, std::bad_exception);
  CPPUNIT_TEST(lsTest2);
  CPPUNIT_TEST(catTest2);
  CPPUNIT_TEST_EXCEPTION(excTest12, mrw::ExecutionFailedExc);
  CPPUNIT_TEST_EXCEPTION(excTest22, mrw::ExecutionFailedExc);
  CPPUNIT_TEST_EXCEPTION(unexpectedExc2, std::bad_exception);
  CPPUNIT_TEST_SUITE_END();
};
CPPUNIT_TEST_SUITE_REGISTRATION(ExecTest);

int main() {
  CppUnit::TextUi::TestRunner runner;
  runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
  return runner.run() ? 0 : 1;
}
