// Revision: 14 1.10.1.4 source/core/testfw/itestcol.hpp, testfw, ioc.v400, 980918 
#ifndef _ITESTCOL_
#define _ITESTCOL_
/**
 * Class ITestCollection: An abstract base class that represents a protocol for classes of tests that contain other subtests.
 *
 * ITestCollection, an abstract base class of ITest, contains a collection of ITest instances.
 * The tests in the collection run sequentially to determine the success
 * or failure of the entire group.
 *
 * @package Test Framework
 * @category Testing
 *
 * @author Alan Liu
 * @task Initial Test Framework
 * @author Esther Tong
 * @task TestFrameworkLite
 * @author David McCusker, Christoper Miller, Carol Widra, and Kwansook Nam
 * @task Many of the other Contributors to TestFramework
 *
 * @copyright
 *      IBM Open Class Library
 *      (C) Copyright International Business Machines Corporation 1997
 *      Licensed Material - Program-Property of IBM - All Rights Reserved.
 *
 */

#include <itest.hpp>
#include <iset2.h>

#if __IBMCPP__ >= 400
#pragma namemangling(compat)
#endif

#pragma enum(4)
#pragma pack(push,4)

//-----------------------------------------------------------------------------
// ITestCollection paragraph
//-----------------------------------------------------------------------------

/**
 * ITestCollection is a subclass of ITest which tests a sequence of subtests.
 *
 * This allows the test authors to group related ITest subclasses together within
 * a single test.  The tests in the collection are run sequentially to determine
 * the success or failure of the entire group.  The resulting test passes if all
 * of its subtests pass, and fails otherwise.  The subtests are always executed
 * in a fixed order (the order in which you add subtests).  The subtests can be
 * run in random order ifyou call "randomlyReorder" method after adding subtests.
 * ITestCollection doesn't halt on subtest failure.  It runs all the subtests by
 * default.  To change this default behavior, you need to call "setHaltOnFail(true)"
 * in your setupSubtests.
 *
 * @subclassing Clients should derive a subclass and override setupSubtests method.
 * In setupSubtests, clients should call "adoptTest" for each subtest.
 *
 */
class ITestCollection : public ITest {
public:

//-------------------------------------------------------------------------
// Canonical methods
//-------------------------------------------------------------------------

/** @group Construction and  Destruction */


/**
 * Default Constructor
 */
ITestCollection();

/**
 * Copy Constructor
 */
ITestCollection(const ITestCollection&);


/**
 * Standard Assignment Operator
 */
ITestCollection& operator=(const ITestCollection&);


/**
 * Destructor
 *
 * ITestCollection destructor does NOT delete the subtests of this
 * collection.  Subclasses are responsible for doing this.
 *
 */
virtual ~ITestCollection();


//------------------------------------------------------------------------
/**
 * Framework method that derived classes can override to provide metainformation about themselves.
 */
virtual void copyInfo() ;

//-------------------------------------------------------------------------
/**
 * adoptTest adds the Subtest to this test's collection of subtests.
 *
 * The caller must not delete the subTest after calling adopt.
 * ITestCollection takes ownership of the subTest will manage storage.
 */
virtual void adoptTest(ITest* subTest);


//-------------------------------------------------------------------------
/**
 * Method used to stop running the test collection when any subtest fails.
 *
 * If client calls this function with "true", ITestCollection will halt
 * when any of its subtests fails.  If the client calls this function with
 * "false", ITestCollection will continue running all tests, even if one or
 * more of the subtests fail.  The default behavior is running all tests.
 */
void setHaltOnFail(bool);

//-------------------------------------------------------------------------
/**
 * Returns the current value that indicates whether or not to halt on failure.
 *
 * @return  bool     Current setting of setHaltOnFail.
 */
bool haltOnFail() const;

//-------------------------------------------------------------------------
/**
 * Randomly reordered test execution order.
 *
 * Randomly rearranges the order in which tests will be
 * executed by the test method.
 */
virtual void randomlyReorder(long initialSeed = 0);

protected:

//-------------------------------------------------------------------------
/**
 * ITestCollection overrides the ITest::reset method.
 *
 * ITestCollection overrides the ITest::reset method to reset all of its
 * subtests as well as itself.
 *
 * Subclasses should NOT need to override reset.
 */
virtual void reset();


//-------------------------------------------------------------------------
/**
 * ITestCollection overrides the ITest::setup method.
 *
 * ITestCollection calls setupSubtests to create all the subtests.
 * setupSubtests is called only once when setup is called for the
 * first time.  Next, it calls propagateInputs for all subtests.  It
 * then calls ITest::setup.
 *
 * Subclasses should NOT need to override setup.
 *
 */
virtual void setup();

//-------------------------------------------------------------------------
/**
 * ITestCollection overrides the ITest::test method.
 *
 * ITestCollection overrides the ITest::test method to call the run
 * method for each of its subtests.  If all subtests pass, the the
 * ITestCollection passes.  If any subtest fails, the the ITestCollection
 * fails.  If haltOnFail returns true then no further subtests will be run
 * once any subtest fails.  Otherwise, all subtests are always run.
 *
 * Subclasses should NOT override test.
 *
 */
virtual void test();

//-------------------------------------------------------------------------
/**
 * Customized operator<<(ITieredTextBuffer) implementation.
 *
 * First calls ITest::print(out), and the prints the number of
 * subtests and the current setting of haltOnFail().
 */
virtual void print(ITieredTextBuffer&);

//-------------------------------------------------------------------------
// Subtest methods
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
/**
 * Controls how input parameters to the test are sent to subtests.
 *
 * propagateInputs is a framework method which controls how input parameters
 * to the test are sent to subtests.  The ITestCollection implementation copies
 * all input arguments unchanged to all subtests.  Called by setup.
 *
 * Subclasses may wish to override this method to alter this behavior.  For
 * example, subclasses may wish to parse or process the inputs before
 * passing them to subtests, or generate inputs for the subtests.
 */
virtual void propagateInputs(ITest& subtest);

//-------------------------------------------------------------------------
/**
 * setupSubtests is called by setup to create the subtests.
 *
 * setupSubtests is called by setup to create the subtests.  Subclasses should
 * override setupSubtests in instantiate all subtests and call adoptTest for
 * each subtest.  Do NOT delete your subtests after calling adoptTest.
 *
 * @override always
 *
 */
virtual void setupSubtests(); // Called by setup

private:
        IVPtrSequence<ITest*>   fSubtests;
        bool                    fHaltOnFail;
        bool                    fSubtestsSetup;
};

#pragma pack(pop)
#pragma enum(pop)

#if __IBMCPP__ >= 400
#pragma namemangling()
#endif

#endif // _ITESTCOL_
