<?php
/**
* Web Application Component Toolkit
*
* @link http://www.phpwact.org/
*
* @author Wact Development Team
* @link http://www.phpwact.org/team
*
* @copyright Copyright 2006, Jeff Moore
* @license http://opensource.org/licenses/mit-license.php MIT
*/

/**
*/
class Wact_Cli_Command_test extends Wact_Tool_Cli_Command {

    /**
    */
    public $name = 'test';

    /**
    */
    public $description = "Run unit tests.\n";

    /**
    */
    protected $project;

    /**
    */
    public function loadOptions($project) {
        // Add Static options
        $this->options->addOption(new Wact_Tool_Cli_Option(
            'list',
            "Lists test files that would be run.  Does not run tests.",
            'list'
            ));
        $this->options->addOption(new Wact_Tool_Cli_Option(
            'coverage',
            "Generate test coverage report (specify dir).",
            'coverage=='
            ));
    }
    
    /**
    *
    */
    function getTestCaseDirectory() {
        // Needs to be configurable
        return dirname($this->project->projectFile);
    }
    
    /**
    * Execute this command
    */
    public function run($argv = array(), $dispatcher = NULL, $project = NULL) {
        require_once 'simpletest/unit_tester.php';
        require_once 'simpletest/mock_objects.php';

        $this->loadOptions($project);
        
        $this->project = $project;

        $isDryRun = FALSE;
        $runCoverage = FALSE;

        $options = $this->options->parse($argv);

        foreach ($options[0] as $option) {
            $optionName = $option[0];
            switch ($optionName) {
                case 'coverage':
                    $runCoverage = TRUE;
                    break;
                case 'list':
                    $isDryRun = TRUE;
                    break;
                default:
                    echo "invalid option '{$optionName}'\n";
                    exit;
            }
    
        }

        $collector = new Wact_Test_Collector();
        $collector->collect($this->getTestCaseDirectory());
        
        $args = $options[1];
        if (count($args) == 0) {
            // run all tests for the project
            $tests = $collector->getTests($this->getTestCaseDirectory());
            $title = 'All project test cases';
        } else if (count($args) > 1) {
            echo "Too many arguments.\n";
            exit;
        } else {
            $target = $args[0];
            if (is_dir($target)) {
                $tests = $collector->getTests(realpath($target));
                $title = 'Test cases from directory ' . basename(dirname(realpath($target)));
            } else if (is_file($target)) {
                $tests = array(realpath($target));
                $title = 'Test cases from file ' . $target;
            } else if (is_file($target . '.test.php')) {
                $tests = array(realpath($target . '.test.php'));
                $title = 'Test cases from file ' . $target;
            } else {
                echo "Unknown testing target '{$target}'.\n";
                exit;
            }
        }

        if ($isDryRun) {
            foreach($tests as $test) {
                echo $test, "\n";
            }
            exit;
        }
        
        $group = new GroupTest($title);
        foreach($tests as $test) {
            $group->addTestFile($test);
        }
        
        $reporter = new Wact_Test_Reporter_Cli();

        ini_set('log_errors', FALSE);
        error_reporting(E_ALL);
        set_time_limit(0);
        
        $group->run($reporter);

    }

    /**
    * Print detailed help information about this command
    */
    public function printUsage($project) {
        $this->loadOptions($project);
?>

Usage: wact test [options] [file/directory]

Run unit tests. If ALL of the test cases pass a count of total
passes is printed on STDOUT. If ANY of the test cases fail (or raise
errors) details are printed on STDERR and this script returns a non-zero
exit code.

<?php 
        $this->options->printOptions();

    }
    
}

?>