text:
<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category  Zend
 * @package   Zend_Uri
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license   http://framework.zend.com/license/new-bsd     New BSD License
 * @version   $Id: Http.php 23970 2011-05-03 15:46:57Z ralph $
 */

/**
 * @see Zend_Uri
 */
require_once 'Zend/Uri.php';

/**
 * @see Zend_Validate_Hostname
 */
require_once 'Zend/Validate/Hostname.php';

/**
 * HTTP(S) URI handler
 *
 * @category  Zend
 * @package   Zend_Uri
 * @uses      Zend_Uri
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license   http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Uri_Http extends Zend_Uri
{
    /**
     * Character classes for validation regular expressions
     */
    const CHAR_ALNUM    = 'A-Za-z0-9';
    const CHAR_MARK     = '-_.!~*\'()\[\]';
    const CHAR_RESERVED = ';\/?:@&=+$,';
    const CHAR_SEGMENT  = ':@&=+$,;';
    const CHAR_UNWISE   = '{}|\\\\^`';

    /**
     * HTTP username
     *
     * @var string
     */
    protected $_username = '';

    /**
     * HTTP password
     *
     * @var string
     */
    protected $_password = '';

    /**
     * HTTP host
     *
     * @var string
     */
    protected $_host = '';

    /**
     * HTTP post
     *
     * @var string
     */
    protected $_port = '';

    /**
     * HTTP part
     *
     * @var string
     */
    protected $_path = '';

    /**
     * HTTP query
     *
     * @var string
     */
    protected $_query = '';

    /**
     * HTTP fragment
     *
     * @var string
     */
    protected $_fragment = '';

    /**
     * Regular expression grammar rules for validation; values added by constructor
     *
     * @var array
     */
    protected $_regex = array();

    /**
     * Constructor accepts a string $scheme (e.g., http, https) and a scheme-specific part of the URI
     * (e.g., example.com/path/to/resource?query=param#fragment)
     *
     * @param  string $scheme         The scheme of the URI
     * @param  string $schemeSpecific The scheme-specific part of the URI
     * @throws Zend_Uri_Exception When the URI is not valid
     */
    protected function __construct($scheme, $schemeSpecific = '')
    {
        // Set the scheme
        $this->_scheme = $scheme;

        // Set up grammar rules for validation via regular expressions. These
        // are to be used with slash-delimited regular expression strings.

        // Escaped special characters (eg. '%25' for '%')
        $this->_regex['escaped']    = '%[[:xdigit:]]{2}';

        // Unreserved characters
        $this->_regex['unreserved'] = '[' . self::CHAR_ALNUM . self::CHAR_MARK . ']';

        // Segment can use escaped, unreserved or a set of additional chars
        $this->_regex['segment']    = '(?:' . $this->_regex['escaped'] . '|[' .
            self::CHAR_ALNUM . self::CHAR_MARK . self::CHAR_SEGMENT . '])*';

        // Path can be a series of segmets char strings seperated by '/'
        $this->_regex['path']       = '(?:\/(?:' . $this->_regex['segment'] . ')?)+';

        // URI characters can be escaped, alphanumeric, mark or reserved chars
        $this->_regex['uric']       = '(?:' . $this->_regex['escaped'] . '|[' .
            self::CHAR_ALNUM . self::CHAR_MARK . self::CHAR_RESERVED .

        // If unwise chars are allowed, add them to the URI chars class
            (self::$_config['allow_unwise'] ? self::CHAR_UNWISE : '') . '])';

        // If no scheme-specific part was supplied, the user intends to create
        // a new URI with this object.  No further parsing is required.
        if (strlen($schemeSpecific) === 0) {
            return;
        }

        // Parse the scheme-specific URI parts into the instance variables.
        $this->_parseUri($schemeSpecific);

        // Validate the URI
        if ($this->valid() === false) {
            require_once 'Zend/Uri/Exception.php';
            throw new Zend_Uri_Exception('Invalid URI supplied');
        }
    }

    /**
     * Creates a Zend_Uri_Http from the given string
     *
     * @param  string $uri String to create URI from, must start with
     *                     'http://' or 'https://'
     * @throws InvalidArgumentException  When the given $uri is not a string or
     *                                   does not start with http:// or https://
     * @throws Zend_Uri_Exception        When the given $uri is invalid
     * @return Zend_Uri_Http
     */
    public static function fromString($uri)
    {
        if (is_string($uri) === false) {
            require_once 'Zend/Uri/Exception.php';
            throw new Zend_Uri_Exception('$uri is not a string');
        }

        $uri            = explode(':', $uri, 2);
        $scheme         = strtolower($uri[0]);
        $schemeSpecific = isset($uri[1]) === true ? $uri[1] : '';

        if (in_array($scheme, array('http', 'https')) === false) {
            require_once 'Zend/Uri/Exception.php';
            throw new Zend_Uri_Exception("Invalid scheme: '$scheme'");
        }

        $schemeHandler = new Zend_Uri_Http($scheme, $schemeSpecific);
        return $schemeHandler;
    }

    /**
     * Parse the scheme-specific portion of the URI and place its parts into instance variables.
     *
     * @param  string $schemeSpecific The scheme-specific portion to parse
     * @throws Zend_Uri_Exception When scheme-specific decoposition fails
     * @throws Zend_Uri_Exception When authority decomposition fails
     * @return void
     */
    protected function _parseUri($schemeSpecific)
    {
        // High-level decomposition parser
        $pattern = '~^((//)([^/?#]*))([^?#]*)(\?([^#]*))?(#(.*))?$~';
        $status  = @preg_match($pattern, $schemeSpecific, $matches);
        if ($status === false) {
            require_once 'Zend/Uri/Exception.php';
            throw new Zend_Uri_Exception('Internal error: scheme-specific decomposition failed');
        }

        // Failed decomposition; no further processing needed
        if ($status === false) {
            return;
        }

        // Save URI components that need no further decomposition
        $this->_path     = isset($matches[4]) === true ? $matches[4] : '';
        $this->_query    = isset($matches[6]) === true ? $matches[6] : '';
        $this->_fragment = isset($matches[8]) === true ? $matches[8] : '';

        // Additional decomposition to get username, password, host, and port
        $combo   = isset($matches[3]) === true ? $matches[3] : '';
        $pattern = '~^(([^:@]*)(:([^@]*))?@)?((?(?=[[])[[][^]]+[]]|[^:]+))(:(.*))?$~';
        $status  = @preg_match($pattern, $combo, $matches);
        if ($status === false) {
            require_once 'Zend/Uri/Exception.php';
            throw new Zend_Uri_Exception('Internal error: authority decomposition failed');
        }

        // Save remaining URI components
        $this->_username = isset($matches[2]) === true ? $matches[2] : '';
        $this->_password = isset($matches[4]) === true ? $matches[4] : '';
        $this->_host     = isset($matches[5]) === true
                         ? preg_replace('~^\[([^]]+)\]$~', '\1', $matches[5])  // Strip wrapper [] from IPv6 literal
                         : '';
        $this->_port     = isset($matches[7]) === true ? $matches[7] : '';
    }

    /**
     * Returns a URI based on current values of the instance variables. If any
     * part of the URI does not pass validation, then an exception is thrown.
     *
     * @throws Zend_Uri_Exception When one or more parts of the URI are invalid
     * @return string
     */
    public function getUri()
    {
        if ($this->valid() === false) {
            require_once 'Zend/Uri/Exception.php';
            throw new Zend_Uri_Exception('One or more parts of the URI are invalid');
        }

        $password = strlen($this->_password) > 0 ? ":$this->_password" : '';
        $auth     = strlen($this->_username) > 0 ? "$this->_username$password@" : '';
        $port     = strlen($this->_port) > 0 ? ":$this->_port" : '';
        $query    = strlen($this->_query) > 0 ? "?$this->_query" : '';
        $fragment = strlen($this->_fragment) > 0 ? "#$this->_fragment" : '';

        return $this->_scheme
             . '://'
             . $auth
             . $this->_host
             . $port
             . $this->_path
             . $query
             . $fragment;
    }

    /**
     * Validate the current URI from the instance variables. Returns true if and only if all
     * parts pass validation.
     *
     * @return boolean
     */
    public function valid()
    {
        // Return true if and only if all parts of the URI have passed validation
        return $this->validateUsername()
           and $this->validatePassword()
           and $this->validateHost()
           and $this->validatePort()
           and $this->validatePath()
           and $this->validateQuery()
           and $this->validateFragment();
    }

    /**
     * Returns the username portion of the URL, or FALSE if none.
     *
     * @return string
     */
    public function getUsername()
    {
        return strlen($this->_username) > 0 ? $this->_username : false;
    }

    /**
     * Returns true if and only if the username passes validation. If no username is passed,
     * then the username contained in the instance variable is used.
     *
     * @param  string $username The HTTP username
     * @throws Zend_Uri_Exception When username validation fails
     * @return boolean
     * @link   http://www.faqs.org/rfcs/rfc2396.html
     */
    public function validateUsername($username = null)
    {
        if ($username === null) {
            $username = $this->_username;
        }

        // If the username is empty, then it is considered valid
        if (strlen($username) === 0) {
            return true;
        }

        // Check the username against the allowed values
        $status = @preg_match('/^(?:' . $this->_regex['escaped'] . '|[' .
            self::CHAR_ALNUM . self::CHAR_MARK . ';:&=+$,' . '])+$/', $username);

        if ($status === false) {
            require_once 'Zend/Uri/Exception.php';
            throw new Zend_Uri_Exception('Internal error: username validation failed');
        }

        return $status === 1;
    }

    /**
     * Sets the username for the current URI, and returns the old username
     *
     * @param  string $username The HTTP username
     * @throws Zend_Uri_Exception When $username is not a valid HTTP username
     * @return string
     */
    public function setUsername($username)
    {
        if ($this->validateUsername($username) === false) {
            require_once 'Zend/Uri/Exception.php';
            throw new Zend_Uri_Exception("Username \"$username\" is not a valid HTTP username");
        }

        $oldUsername     = $this->_username;
        $this->_username = $username;

        return $oldUsername;
    }

    /**
     * Returns the password portion of the URL, or FALSE if none.
     *
     * @return string
     */
    public function getPassword()
    {
        return strlen($this->_password) > 0 ? $this->_password : false;
    }

    /**
     * Returns true if and only if the password passes validation. If no password is passed,
     * then the password contained in the instance variable is used.
     *
     * @param  string $password The HTTP password
     * @throws Zend_Uri_Exception When password validation fails
     * @return boolean
     * @link   http://www.faqs.org/rfcs/rfc2396.html
     */
    public function validatePassword($password = null)
    {
        if ($password === null) {
            $password = $this->_password;
        }

        // If the password is empty, then it is considered valid
        if (strlen($password) === 0) {
            return true;
        }

        // If the password is nonempty, but there is no username, then it is considered invalid
        if (strlen($password) > 0 and strlen($this->_username) === 0) {
            return false;
        }

        // Check the password against the allowed values
        $status = @preg_match('/^(?:' . $this->_regex['escaped'] . '|[' .
            self::CHAR_ALNUM . self::CHAR_MARK . ';:&=+$,' . '])+$/', $password);

        if ($status === false) {
            require_once 'Zend/Uri/Exception.php';
            throw new Zend_Uri_Exception('Internal error: password validation failed.');
        }

        return $status == 1;
    }

    /**
     * Sets the password for the current URI, and returns the old password
     *
     * @param  string $password The HTTP password
     * @throws Zend_Uri_Exception When $password is not a valid HTTP password
     * @return string
     */
    public function setPassword($password)
    {
        if ($this->validatePassword($password) === false) {
            require_once 'Zend/Uri/Exception.php';
            throw new Zend_Uri_Exception("Password \"$password\" is not a valid HTTP password.");
        }

        $oldPassword     = $this->_password;
        $this->_password = $password;

        return $oldPassword;
    }

    /**
     * Returns the domain or host IP portion of the URL, or FALSE if none.
     *
     * @return string
     */
    public function getHost()
    {
        return strlen($this->_host) > 0 ? $this->_host : false;
    }

    /**
     * Returns true if and only if the host string passes validation. If no host is passed,
     * then the host contained in the instance variable is used.
     *
     * @param  string $host The HTTP host
     * @return boolean
     * @uses   Zend_Filter
     */
    public function validateHost($host = null)
    {
        if ($host === null) {
            $host = $this->_host;
        }

        // If the host is empty, then it is considered invalid
        if (strlen($host) === 0) {
            return false;
        }

        // Check the host against the allowed values; delegated to Zend_Filter.
        $validate = new Zend_Validate_Hostname(Zend_Validate_Hostname::ALLOW_ALL);

        return $validate->isValid($host);
    }

    /**
     * Sets the host for the current URI, and returns the old host
     *
     * @param  string $host The HTTP host
     * @throws Zend_Uri_Exception When $host is nota valid HTTP host
     * @return string
     */
    public function setHost($host)
    {
        if ($this->validateHost($host) === false) {
            require_once 'Zend/Uri/Exception.php';
            throw new Zend_Uri_Exception("Host \"$host\" is not a valid HTTP host");
        }

        $oldHost     = $this->_host;
        $this->_host = $host;

        return $oldHost;
    }

    /**
     * Returns the TCP port, or FALSE if none.
     *
     * @return string
     */
    public function getPort()
    {
        return strlen($this->_port) > 0 ? $this->_port : false;
    }

    /**
     * Returns true if and only if the TCP port string passes validation. If no port is passed,
     * then the port contained in the instance variable is used.
     *
     * @param  string $port The HTTP port
     * @return boolean
     */
    public function validatePort($port = null)
    {
        if ($port === null) {
            $port = $this->_port;
        }

        // If the port is empty, then it is considered valid
        if (strlen($port) === 0) {
            return true;
        }

        // Check the port against the allowed values
        return ctype_digit((string) $port) and 1 <= $port and $port <= 65535;
    }

    /**
     * Sets the port for the current URI, and returns the old port
     *
     * @param  string $port The HTTP port
     * @throws Zend_Uri_Exception When $port is not a valid HTTP port
     * @return string
     */
    public function setPort($port)
    {
        if ($this->validatePort($port) === false) {
            require_once 'Zend/Uri/Exception.php';
            throw new Zend_Uri_Exception("Port \"$port\" is not a valid HTTP port.");
        }

        $oldPort     = $this->_port;
        $this->_port = $port;

        return $oldPort;
    }

    /**
     * Returns the path and filename portion of the URL.
     *
     * @return string
     */
    public function getPath()
    {
        return strlen($this->_path) > 0 ? $this->_path : '/';
    }

    /**
     * Returns true if and only if the path string passes validation. If no path is passed,
     * then the path contained in the instance variable is used.
     *
     * @param  string $path The HTTP path
     * @throws Zend_Uri_Exception When path validation fails
     * @return boolean
     */
    public function validatePath($path = null)
    {
        if ($path === null) {
            $path = $this->_path;
        }

        // If the path is empty, then it is considered valid
        if (strlen($path) === 0) {
            return true;
        }

        // Determine whether the path is well-formed
        $pattern = '/^' . $this->_regex['path'] . '$/';
        $status  = @preg_match($pattern, $path);
        if ($status === false) {
            require_once 'Zend/Uri/Exception.php';
            throw new Zend_Uri_Exception('Internal error: path validation failed');
        }

        return (boolean) $status;
    }

    /**
     * Sets the path for the current URI, and returns the old path
     *
     * @param  string $path The HTTP path
     * @throws Zend_Uri_Exception When $path is not a valid HTTP path
     * @return string
     */
    public function setPath($path)
    {
        if ($this->validatePath($path) === false) {
            require_once 'Zend/Uri/Exception.php';
            throw new Zend_Uri_Exception("Path \"$path\" is not a valid HTTP path");
        }

        $oldPath     = $this->_path;
        $this->_path = $path;

        return $oldPath;
    }

    /**
     * Returns the query portion of the URL (after ?), or FALSE if none.
     *
     * @return string
     */
    public function getQuery()
    {
        return strlen($this->_query) > 0 ? $this->_query : false;
    }

    /**
     * Returns the query portion of the URL (after ?) as a
     * key-value-array. If the query is empty an empty array
     * is returned
     *
     * @return array
     */
    public function getQueryAsArray()
    {
        $query = $this->getQuery();
        $querryArray = array();
        if ($query !== false) {
            parse_str($query, $querryArray);
        }
        return $querryArray;
    }

    /**
     * Returns true if and only if the query string passes validation. If no query is passed,
     * then the query string contained in the instance variable is used.
     *
     * @param  string $query The query to validate
     * @throws Zend_Uri_Exception When query validation fails
     * @return boolean
     * @link   http://www.faqs.org/rfcs/rfc2396.html
     */
    public function validateQuery($query = null)
    {
        if ($query === null) {
            $query = $this->_query;
        }

        // If query is empty, it is considered to be valid
        if (strlen($query) === 0) {
            return true;
        }

        // Determine whether the query is well-formed
        $pattern = '/^' . $this->_regex['uric'] . '*$/';
        $status  = @preg_match($pattern, $query);
        if ($status === false) {
            require_once 'Zend/Uri/Exception.php';
            throw new Zend_Uri_Exception('Internal error: query validation failed');
        }

        return $status == 1;
    }

    /**
     * Add or replace params in the query string for the current URI, and
     * return the old query.
     *
     * @param  array $queryParams
     * @return string Old query string
     */
    public function addReplaceQueryParameters(array $queryParams)
    {
        $queryParams = array_merge($this->getQueryAsArray(), $queryParams);
        return $this->setQuery($queryParams);
    }

    /**
     * Remove params in the query string for the current URI, and
     * return the old query.
     *
     * @param  array $queryParamKeys
     * @return string Old query string
     */
    public function removeQueryParameters(array $queryParamKeys)
    {
        $queryParams = array_diff_key($this->getQueryAsArray(), array_fill_keys($queryParamKeys, 0));
        return $this->setQuery($queryParams);
    }

    /**
     * Set the query string for the current URI, and return the old query
     * string This method accepts both strings and arrays.
     *
     * @param  string|array $query The query string or array
     * @throws Zend_Uri_Exception When $query is not a valid query string
     * @return string              Old query string
     */
    public function setQuery($query)
    {
        $oldQuery = $this->_query;

        // If query is empty, set an empty string
        if (empty($query) === true) {
            $this->_query = '';
            return $oldQuery;
        }

        // If query is an array, make a string out of it
        if (is_array($query) === true) {
            $query = http_build_query($query, '', '&');
        } else {
            // If it is a string, make sure it is valid. If not parse and encode it
            $query = (string) $query;
            if ($this->validateQuery($query) === false) {
                parse_str($query, $queryArray);
                $query = http_build_query($queryArray, '', '&');
            }
        }

        // Make sure the query is valid, and set it
        if ($this->validateQuery($query) === false) {
            require_once 'Zend/Uri/Exception.php';
            throw new Zend_Uri_Exception("'$query' is not a valid query string");
        }

        $this->_query = $query;

        return $oldQuery;
    }

    /**
     * Returns the fragment portion of the URL (after #), or FALSE if none.
     *
     * @return string|false
     */
    public function getFragment()
    {
        return strlen($this->_fragment) > 0 ? $this->_fragment : false;
    }

    /**
     * Returns true if and only if the fragment passes validation. If no fragment is passed,
     * then the fragment contained in the instance variable is used.
     *
     * @param  string $fragment Fragment of an URI
     * @throws Zend_Uri_Exception When fragment validation fails
     * @return boolean
     * @link   http://www.faqs.org/rfcs/rfc2396.html
     */
    public function validateFragment($fragment = null)
    {
        if ($fragment === null) {
            $fragment = $this->_fragment;
        }

        // If fragment is empty, it is considered to be valid
        if (strlen($fragment) === 0) {
            return true;
        }

        // Determine whether the fragment is well-formed
        $pattern = '/^' . $this->_regex['uric'] . '*$/';
        $status  = @preg_match($pattern, $fragment);
        if ($status === false) {
            require_once 'Zend/Uri/Exception.php';
            throw new Zend_Uri_Exception('Internal error: fragment validation failed');
        }

        return (boolean) $status;
    }

    /**
     * Sets the fragment for the current URI, and returns the old fragment
     *
     * @param  string $fragment Fragment of the current URI
     * @throws Zend_Uri_Exception When $fragment is not a valid HTTP fragment
     * @return string
     */
    public function setFragment($fragment)
    {
        if ($this->validateFragment($fragment) === false) {
            require_once 'Zend/Uri/Exception.php';
            throw new Zend_Uri_Exception("Fragment \"$fragment\" is not a valid HTTP fragment");
        }

        $oldFragment     = $this->_fragment;
        $this->_fragment = $fragment;

        return $oldFragment;
    }
}


text:
<?php
/**
 * phpRack: Integration Testing Framework
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt. It is also available
 * through the world-wide-web at this URL: http://www.phprack.com/LICENSE.txt
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@phprack.com so we can send you a copy immediately.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * @copyright Copyright (c) phpRack.com
 * @version $Id: Test.php 599 2010-07-06 13:50:14Z yegor256@yahoo.com $
 * @category phpRack
 */

/**
 * @see phpRack_Runner
 */
require_once PHPRACK_PATH . '/Runner.php';

/**
 * @see phpRack_Assertion
 */
require_once PHPRACK_PATH . '/Assertion.php';

/**
 * Parent class of all integration tests
 *
 * @package Tests
 */
abstract class phpRack_Test
{

    const OK = 'OK';
    const FAILURE = 'FAILURE';

    /**
     * This timezone will be used in there is NO timezone
     * set on the server
     *
     * @see setUp()
     */
    const DEFAULT_TIMEZONE = 'EST';

    /**
     * ID of the test (unique in the system)
     *
     * @var string
     */
    protected $_fileName;

    /**
     * Runner of tests
     *
     * @var phpRack_Runner
     */
    protected $_runner;

    /**
     * Assertion to use
     *
     * @var phpRack_Assertion
     * @see __get()
     */
    protected $_assertion = null;

    /**
     * Ajax options to control front page behavior
     *
     * @var array
     * @see setAjaxOptions()
     * @see getAjaxOptions()
     */
    private $_ajaxOptions = array(
        'autoStart'          => true, // start it when front is loaded
        'reload'             => false, // reload every X seconds, in AJAX
        'linesCount'         => null, // how many lines should be displayed on browser side when we use tailf method
        'secVisible'         => null, // how long these lines should be visible (in seconds)
        'attachOutput'       => false, // attach output to previous result log
        'data'               => array(), // used for store data which should be returned in next ajax query
        'fileLastOffset'     => null, // used for control offset to read in phpRack_Package_Disc_File::tailf()
        'logSizeLimit'       => 100, // maximum size of log, in KB
        'pauseWhenFocusLost' => true, // stop ajax requests when window lost focus
        'tags'               => array(), // used for store available options for parametrized test
        'tag'                => null // selected tag param from front end
    );

    /**
     * Construct the class
     *
     * This constructor is going to be used only from factory() method. Making
     * this method "private" leads to problems in PHP 5.2.5 and maybe earlier
     * versions.
     *
     * @param string ID of the test, absolute (!) file name
     * @param phpRack_Runner Instance of test runner
     * @return void
     * @see factory()
     */
    protected final function __construct($fileName, phpRack_Runner $runner)
    {
        $this->_fileName = realpath($fileName);
        $this->_runner = $runner;
        $this->_init();
    }

    /**
     * Create new instance of the class, using PHP absolute file name
     *
     * @param string ID of the test, absolute (!) file name
     * @param phpRack_Runner Instance of test runner
     * @return phpRack_Test
     * @throws Exception
     */
    public static function factory($fileName, phpRack_Runner $runner)
    {
        if (!file_exists($fileName)) {
            throw new Exception("File '{$fileName}' is not found");
        }

        if (!preg_match(phpRack_Runner::TEST_PATTERN, $fileName)) {
            throw new Exception("File '{$fileName}' is not named properly, can't run it");
        }

        $className = pathinfo($fileName, PATHINFO_FILENAME);

        // workaround against ZCA static code analysis
        eval('require_once $fileName;');

        if (!class_exists($className)) {
            throw new Exception("Class '{$className}' is not defined in '{$fileName}'");
        }

        return new $className($fileName, $runner);
    }

    /**
     * Dispatches property-like calls to the class
     *
     * @param string Name of the property to get
     * @return mixed
     * @throws Exception If nothing found
     */
    public final function __get($name)
    {
        if ($name == 'assert') {
            if (!isset($this->_assertion)) {
                $this->_assertion = phpRack_Assertion::factory($this);
            }
            return $this->_assertion;
        }
        throw new Exception("Property '{$name}' not found in " . get_class($this));
    }

    /**
     * Get unique test ID (file name of the test)
     *
     * @return string
     * @see $this->_fileName
     */
    public function getFileName()
    {
        return $this->_fileName;
    }

    /**
     * Get label of the test
     *
     * @return string
     */
    public function getLabel()
    {
        return ltrim(substr($this->_fileName, strlen($this->_runner->getDir())), '/');
    }

    /**
     * Run the test and return result
     *
     * @return phpRack_Result
     * @see phpRack_Runner::run()
     */
    public final function run()
    {
        // clean all previous results, if any
        $this->assert->getResult()->clean();

        // find all methods that start with "test" and call them
        $rc = new ReflectionClass($this);
        foreach ($rc->getMethods() as $method) {
            if (!preg_match('/^test/', $method->getName())) {
                continue;
            }
            try {
                $this->setUp();

                // to avoid test cancelation because time is over
                set_time_limit(0);

                call_user_func(
                    array($this, $method->getName()),
                    $this->_ajaxOptions['tag']
                );
                $this->tearDown();
            } catch (Exception $e) {
                $this->assert->getResult()->addLog(
                    sprintf(
                        '[Exception] %s: %s "%s"',
                        $method->getName(),
                        get_class($e),
                        $e->getMessage()
                    )
                )
                ->fail();
            }
        }

        // add final log line, summarizing the test execution
        $this->assert->getResult()->addLog(
            sprintf(
                'Finished %s, %0.3fsec',
                get_class($this),
                $this->assert->getResult()->getDuration()
            )
        );

        // return instance of phpRack_Result class
        return $this->assert->getResult();
    }

    /**
     * Setup test environment, if necessary, before running every test
     *
     * @return void
     * @see run()
     */
    public function setUp()
    {
        // Check the default time zone
        $defaultTimeZone = ini_get('date.timezone');
        if (empty($defaultTimeZone)) {
            ini_set('date.timezone', self::DEFAULT_TIMEZONE);
            $this->_log(
                'INI setting date.timezone is not set. ' .
                self::DEFAULT_TIMEZONE . ' set as the time zone. ' .
                'Please set date.timezone to you current time zone'
            );
        }
    }

    /**
     * Clean environment if necessary
     *
     * @return void
     * @see run()
     */
    public function tearDown()
    {
    }

    /**
     * Set ajax options
     *
     * @param array List of options to set
     * @return void
     * @see phpRack_Package_Disc_File::tail()
     */
    public function setAjaxOptions($options)
    {
        foreach ($options as $name=>$value) {
            if (!array_key_exists($name, $this->_ajaxOptions)) {
                throw new Exception("AJAX option '{$name}' is not valid");
                continue;
            }
            $this->_ajaxOptions[$name] = $value;
        }
    }

    /**
     * Get ajax options
     *
     * @return array
     * @see phpRack_Runner::run()
     * @see index.phtml
     */
    public function getAjaxOptions()
    {
        return $this->_ajaxOptions;
    }

    /**
     * Simple assertion method to compare two values
     *
     * @param mixed What we're expecting to have
     * @param mixed What we actually have
     * @param string Optional message to show
     * @return $this
     */
    public function assertEquals($dest, $src, $message = null)
    {
        if ($dest != $src) {
            if (!is_null($message)) {
                $this->_log($message);
            }
            $this->assert->fail("Comparison failed");
        } else {
            $this->_log("Comparison succeeded");
        }
        return $this;
    }

    /**
     * Allow child class to overwrite test default options, by overwritting this method
     * If you want disable ajax auto start it is proper place for that
     *
     * @return void
     * @see __construct()
     */
    protected function _init()
    {

    }

    /**
     * Log one message
     *
     * @param string The message
     * @return void
     */
    protected function _log($message)
    {
        $this->assert->getResult()->addLog($message);
    }
}

repo_name: michael-romer/zf-boilerplate

repo_language: PHP

mime_type: text/html


text:
<?php
/**
 * phpRack: Integration Testing Framework
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt. It is also available
 * through the world-wide-web at this URL: http://www.phprack.com/LICENSE.txt
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@phprack.com so we can send you a copy immediately.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * @copyright Copyright (c) phpRack.com
 * @version $Id: Assertion.php 545 2010-05-04 09:40:46Z yegor256@yahoo.com $
 * @category phpRack
 */

/**
 * @see phpRack_Package
 */
require_once PHPRACK_PATH . '/Package.php';

/**
 * @see phpRack_Result
 */
require_once PHPRACK_PATH . '/Result.php';

/**
 * @see phpRack_Test
 */
require_once PHPRACK_PATH . '/Test.php';

/**
 * One single test assertion
 *
 * @package Tests
 * @see phpRack_Test::__get()
 */
class phpRack_Assertion
{

    /**
     * Result collector
     *
     * @var phpRack_Result
     * @see __construct()
     */
    protected $_result;

    /**
     * Construct the class
     *
     * @param phpRack_Test Test, which pushes results here
     * @return void
     * @see phpRack_Test::__get()
     */
    private function __construct(phpRack_Test $test)
    {
        $this->_result = new phpRack_Result($test);
    }

    /**
     * Create new assertion
     *
     * There is a combination of static factory() method and a private
     * constructor. However we don't have any static factory here, just an
     * incapsulation of constructor. Some time ago we had a static factory,
     * but then removed it. Maybe in the future we might get back to this
     * design approach.
     *
     * @param phpRack_Test Test that is using this assertion
     * @return phpRack_Assertion
     * @see phpRack_Test::__get()
     */
    public static function factory(phpRack_Test $test)
    {
        return new self($test);
    }

    /**
     * Dispatcher of calls to packages
     *
     * @param string Name of the package to get
     * @return phpRack_Package
     * @see phpRack_Test::_log() and many other methods inside Integration Tests
     */
    public function __get($name)
    {
        return phpRack_Package::factory($name, $this->_result);
    }

    /**
     * Call method, any one
     *
     * This magic method will be called when you're using any assertion and
     * some method inside it, for example:
     *
     * <code>
     * // inside your instance of phpRack_Test:
     * $this->assert->php->extensions->isLoaded('simplexml');
     * </code>
     *
     * The call in the example will lead you to this method, and will call
     * __call('simplexml', array()).
     *
     * @param string Name of the method to call
     * @param array Arguments to pass
     * @return mixed
     * @see PhpConfigurationTest::testPhpExtensionsExist isLoaded() reaches this point
     */
    public function __call($name, array $args)
    {
        return call_user_func_array(
            array(
                phpRack_Package::factory('simple', $this->_result),
                $name
            ),
            $args
        );
    }

    /**
     * Get instance of result collector
     *
     * @return phpRack_Result
     * @see phpRack_Test::_log() and many other methods inside Integration Tests
     */
    public function getResult()
    {
        return $this->_result;
    }

}


text:
<?php
/**
 * phpRack: Integration Testing Framework
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt. It is also available
 * through the world-wide-web at this URL: http://www.phprack.com/LICENSE.txt
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@phprack.com so we can send you a copy immediately.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * @copyright Copyright (c) phpRack.com
 * @version $Id: Runner.php 628 2010-07-25 15:27:29Z yegor256@yahoo.com $
 * @category phpRack
 */

/**
 * @see phpRack_Test
 */
require_once PHPRACK_PATH . '/Test.php';

/**
 * @see phpRack_Suite
 */
require_once PHPRACK_PATH . '/Suite.php';

/**
 * Run all tests together, or one by one
 *
 * First you should create an instance of this class, providing it an array
 * of options. Then you can either run individual test or all tests in a
 * test suite:
 *
 * <code>
 * $runner = new phpRack_Runner(array('dir'=>'/path/to/my-tests'));
 * echo $runner->runSuite();
 * </code>
 *
 * This code will give you a plain-text report of all tests in your collection,
 * executed and logged.
 *
 * @package Tests
 * @see bootstrap.php
 */
class phpRack_Runner
{

    /**
     * This is how you should name your test files, if you want
     * them to be found by the Runner
     *
     * @var string
     * @see getTests()
     */
    const TEST_PATTERN = '/(\w+Test)\.php$/i';

    /**
     * This is how you should name your suite files, if you want
     * them to be found by the Runner
     *
     * @var string
     * @see getTests()
     */
    const SUITE_PATTERN = '/(\w+Suite)\.php$/i';

    /**
     * List of options, which are changeable
     *
     * @var array
     * @see __construct()
     */
    protected $_options = array(
        'dir'      => null,
        'auth'     => null,
        'htpasswd' => null,
        'notify'   => null,
    );

    /**
     * Authentication adapter
     *
     * @var phpRack_Runner_Auth
     */
    protected $_auth;

    /**
     * Construct the class
     *
     * @param array Options to set to the class
     * @return void
     * @throws Exception If an option is invalid
     * @see bootstrap.php
     */
    public function __construct(array $options)
    {
        foreach ($options as $option=>$value) {
            if (!array_key_exists($option, $this->_options)) {
                throw new Exception("Option '{$option}' is not recognized");
            }
            $this->_options[$option] = $value;
        }
        /**
         * @see phpRack_Runner_Auth
         */
        require_once PHPRACK_PATH . '/Runner/Auth.php';
        $this->_auth = new phpRack_Runner_Auth($this, $this->_options);
    }

    /**
     * Return authentication adapter
     *
     * @return phpRack_Runner_Auth
     * @see bootstrap.php
     */
    public function getAuth()
    {
        return $this->_auth;
    }

    /**
     * We're running the tests in CLI environment?
     *
     * @return boolean
     * @see phpRack_Runner_Auth::isAuthenticated()
     */
    public function isCliEnvironment()
    {
        global $_SERVER;
        return empty($_SERVER['DOCUMENT_ROOT']);
    }

    /**
     * Check whether client connection has enough security level?
     *
     * @return boolean
     * @see bootstrap.php
     */
    public function isEnoughSecurityLevel()
    {
        global $_SERVER;
        if (empty($this->_options['auth']['onlySSL'])) {
            return true;
        }
        return !empty($_SERVER['HTTPS']);
    }

    /**
     * Get tests location directory
     *
     * @return string
     * @throws Exception If directory is absent
     * @see getTests()
     */
    public function getDir()
    {
        $dir = $this->_options['dir'];
        if (!file_exists($dir)) {
            throw new Exception("Test directory '{$dir}' is not found");
        }
        return realpath($dir);
    }

    /**
     * Get full list of tests, in array
     *
     * This method builds a list of phpRack_Test class instances, collecting
     * them from integration 1) tests and 2) suites. They both are located in
     * the same directory (pre-configured in $phpRackConfig), but differ only
     * in file name suffix. Integration test ends with "...Test.php" and integration
     * suite ends with "...Suite.php".
     *
     * Suite is an integration of tests, that allows you to use library tests
     * and suites. The majority of testing tasks are similar from server to server.
     * If you want to avoid manual development of tests for every application, just
     * use our library suites, and taylor them for your application needs.
     *
     * @return phpRack_Test[]
     * @see index.phtml
     */
    public function getTests()
    {
        $tests = array();
        foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->getDir())) as $file) {
            switch (true) {
                case preg_match(self::TEST_PATTERN, $file->getFilename()):
                    $tests[] = phpRack_Test::factory(strval($file), $this);
                    break;

                case preg_match(self::SUITE_PATTERN, $file->getFilename()):
                    $suite = phpRack_Suite::factory(strval($file), $this);
                    foreach ($suite->getTests() as $test) {
                        $tests[] = $test;
                    }
                    break;
            }
        }
        return $tests;
    }

    /**
     * Run all tests and return a text report about their execution
     *
     * @return string
     * @see boostrap.php
     */
    public function runSuite()
    {
        $tests = $this->getTests();
        $report = sprintf(
            "\nphpRack v%s\nSuite report, on %s\nPHPRACK_PATH: %s\n\n",
            PHPRACK_VERSION,
            date('d-M-y H:i:s'),
            PHPRACK_PATH
        );
        $success = true;
        $duration = 0;
        foreach ($tests as $test) {
            $result = $test->run();
            $report .= sprintf(
                "%s\n%s: %s, %0.3fsec\n\n",
                $result->getPureLog(),
                $test->getLabel(),
                $result->wasSuccessful() ? phpRack_Test::OK : phpRack_Test::FAILURE,
                $result->getDuration()
            );
            $success &= $result->wasSuccessful();
            $duration += $result->getDuration();
        }
        $report .= sprintf(
            "PHPRACK SUITE: %s, %0.2fmin\n",
            $success ? phpRack_Test::OK : phpRack_Test::FAILURE,
            $duration / 60
        );

        // notify about suite failure
        if (!$success) {
            try {
                $this->_notifyAboutFailure($report);
            } catch (Exception $e) {
                $report .= sprintf(
                    "Failed to notify admin (%s): '%s'\n",
                    get_class($e),
                    $e->getMessage()
                );
            }
        }

        return $report;
    }

    /**
     * Run one test and return JSON result
     *
     * @param string Test file name (absolute name of PHP file)
     * @param string Unique token to return back, if required
     * @param array Associative array of options to be used for setAjaxOptions()
     * @return string JSON
     * @throws Exception
     * @see bootstrap.php
     */
    public function run($fileName, $token = 'token', $options = array())
    {
        if (!$this->getAuth()->isAuthenticated()) {
            //TODO: handle situation when login screen should appear
            throw new Exception("Authentication failed, please login first");
        }
        $test = phpRack_Test::factory($fileName, $this);
        $test->setAjaxOptions($options);

        $result = $test->run();
        $options = $test->getAjaxOptions();

        /**
         * @see phpRack_Runner_Logger
         */
        require_once PHPRACK_PATH . '/Runner/Logger.php';
        return json_encode(
            array(
                'success' => $result->wasSuccessful(),
                'options' => $options,
                'log' => phpRack_Runner_Logger::utf8Encode(
                    phpRack_Runner_Logger::cutLog(
                        $result->getLog(),
                        intval($options['logSizeLimit'])
                    )
                ),
                PHPRACK_AJAX_TOKEN => $token
            )
        );
    }

    /**
     * Notify admin about suite failure
     *
     * @param string Full suite text report
     * @return void
     * @see runSuite()
     * @throws Exception
     * @todo Now we work only with one notifier, which is in class phpRack_Mail. Later
     *      we should add other notifiers, like SMS, IRC, ICQ, etc. When we add them we
     *      should move our phpRack_Mail class to phpRack_Notifier_Mail and create other
     *      notifiers there.
     */
    protected function _notifyAboutFailure($report)
    {
        // no notification required
        if (empty($this->_options['notify'])) {
            return;
        }

        if (!is_array($this->_options['notify'])) {
            throw new Exception("Parameter 'notify' should be an array, '{$this->_options['notify']}' given");
        }

        if (array_key_exists('email', $this->_options['notify'])) {
            /**
             * @see phpRack_Adapters_Notifier_Mail
             */
            require_once PHPRACK_PATH . '/Adapters/Notifier/Mail.php';

            if (array_key_exists('transport', $this->_options['notify']['email'])) {
                $transport = $this->_options['notify']['email']['transport'];
            } else {
                $transport = array();
            }
            if (!empty($transport['class'])) {
                $class = $transport['class'];
                unset($transport['class']);
            } else {
                $class = 'sendmail';
            }
            $mail = phpRack_Adapters_Notifier_Mail::factory($class, $transport);
            $mail->setSubject('phpRack Suite Failure');
            $mail->setBody($report);
            /**
             * @todo Only one recipient is supported now
             */
            $mail->setTo($this->_options['notify']['email']['recipients']);
            $mail->send();
        }
    }

}


text:
<?php
/**
 * phpRack: Integration Testing Framework
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt. It is also available
 * through the world-wide-web at this URL: http://www.phprack.com/LICENSE.txt
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@phprack.com so we can send you a copy immediately.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * @copyright Copyright (c) phpRack.com
 * @version $Id: Package.php 590 2010-06-05 07:49:09Z yegor256@yahoo.com $
 * @category phpRack
 */

/**
 * @see phpRack_Result
 */
require_once PHPRACK_PATH . '/Result.php';

/**
 * @see phpRack_Test
 */
require_once PHPRACK_PATH . '/Test.php';

/**
 * One test assertion package
 *
 * The package is used from your custom integration test, through the instance
 * of {@link phpRack_Assertion} class, which is available like this:
 *
 *
 * class MyTest extends phpRack_Test {
 *   public function testPhpVersion() {
 *     $this->assert->php->version->atLeast('5.2');
 *   }
 * }
 *
 *
 * In this example package {@link phpRack_Package_Php_Version} will be instantiated
 * and returned. Later, method atLeast() will be called in this package.
 *
 * @package Tests
 * @see phpRack_Assertion::__call()
 */
class phpRack_Package
{

    /**
     * Result collector
     *
     * @var phpRack_Result
     * @see __construct()
     * @see __get()
     */
    protected $_result;

    /**
     * Result of the latest call
     *
     * @var boolean TRUE means that the latest call was successful
     * @see _failure()
     * @see _success()
     */
    protected $_latestCallSuccess = false;

    /**
     * Construct the class
     *
     * The method is PROTECTED in order to avoid direct instantiation of
     * packages outside our factory method {@link factory()}. Some packages
     * may override the method, that's why it is protected, not private. For
     * example {@link phpRack_Package_Db_Mysql}.
     *
     * phpRack_Result passed here as parameter is used as a holder of test
     * results. This package will ADD new results to this holder, instead of
     * creating new one. This holder is passed from {@link phpRack_Test}, normally.
     *
     * @param phpRack_Result Result to use
     * @return void
     * @see factory()
     */
    protected function __construct(phpRack_Result $result)
    {
        $this->_result = $result;
    }

    /**
     * Call to unknown function
     *
     * @param string Name of the method
     * @param array List of arguments
     * @return void
     * @throws Exception
     */
    public final function __call($name, array $args)
    {
        throw new Exception(
            sprintf(
                "Method '%s' is absent in '%s' package, %d args passed",
                $name,
                $this->getName(),
                count($args)
            )
        );
    }

    /**
     * Create new package
     *
     * The method is called factory, but this is not really a static factory. This method
     * just simplifies the instantiation of phpRack_Package and encapsulates private
     * constructor. Some time ago we had a static factory here, but then removed it. The
     * organization of methods stay like before (factory + private constructor). Maybe in
     * the future we might decide to introduce static factory again.
     *
     * @param string Name of the package, like "php/version"
     * @param phpRack_Result Collector of log lines
     * @return phpRack_Package
     * @throws Exception
     * @see phpRack_Assertion::__call()
     */
    public static function factory($name, phpRack_Result $result)
    {
        $sectors = array_map('ucfirst', explode('/', $name));
        $className = 'phpRack_Package_' . implode('_', $sectors);

        $packageFile = PHPRACK_PATH . '/Package/' . implode('/', $sectors) . '.php';
        if (!file_exists($packageFile)) {
            throw new Exception("Package '$name' is absent in phpRack: '{$packageFile}'");
        }

        // workaround against ZCA static code analysis
        eval('require_once $packageFile;');

        return new $className($result);
    }

    /**
     * Dispatcher of calls to packages
     *
     * Here we create a sub-package, for example:
     *
     *
     * // inside your instance of phpRack_Test:
     * $this->assert->php->extensions->isLoaded('simplexml');
     *
     *
     * The call in the example will lead you to this method, and will call
     * __get('extensions'). In return we will create an instance of
     * phpRack_Package_Php_Extensions and return it.
     *
     * @param string Name of the property to get
     * @return phpRack_Package
     * @see PhpConfigurationTest::testPhpExtensionsExist ->extensions reaches this point
     */
    public function __get($name)
    {
        return self::factory($this->_getName() . '/' . $name, $this->_result);
    }

    /**
     * What to do on success?
     *
     * @param mixed What to do? STRING will log this string
     * @return $this
     */
    public final function onSuccess($action)
    {
        if ($this->_latestCallSuccess) {
            $this->_log($action);
        }
        return $this;
    }

    /**
     * What to do on failure?
     *
     * @param mixed What to do? STRING will log this string
     * @return $this
     */
    public final function onFailure($action)
    {
        if (!$this->_latestCallSuccess) {
            $this->_log($action);
        }
        return $this;
    }

    /**
     * Get my name, like: "php/version"
     *
     * @return string
     * @see __get()
     */
    protected function _getName()
    {
        $sectors = explode('_', get_class($this)); // e.g. "phpRack_Package_Php_Version"
        return implode(
            '/',
            array_slice(
                array_map(
                    create_function('$a', 'return strtolower($a[0]) . substr($a, 1);'),
                    $sectors
                ),
                2
            )
        );
    }

    /**
     * Call failed
     *
     * @param string String to log
     * @return void
     * @see phpRack_Package_Php::lint() and many other methods
     */
    protected function _failure($log)
    {
        $this->_latestCallSuccess = false;
        $this->_result->fail();
        $this->_log('[' . phpRack_Test::FAILURE . '] ' . $log);
    }

    /**
     * Call was successful
     *
     * @param string String to log
     * @return void
     * @see phpRack_Package_Php::lint() and many other methods
     */
    protected function _success($log)
    {
        $this->_latestCallSuccess = true;
        $this->_log('[' . phpRack_Test::OK . '] ' . $log);
    }

    /**
     * Just log a line
     *
     * @param string String to log
     * @return void
     * @see phpRack_Package_Php::lint() and many other methods
     */
    protected function _log($log)
    {
        $this->_result->addLog($log);
    }

}


text:
<?php
/**
 * phpRack: Integration Testing Framework
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt. It is also available
 * through the world-wide-web at this URL: http://www.phprack.com/LICENSE.txt
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@phprack.com so we can send you a copy immediately.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * @copyright Copyright (c) phpRack.com
 * @version $Id: bootstrap.php 627 2010-07-22 16:59:48Z yegor256@yahoo.com $
 * @category phpRack
 */

/**
 * To make sure that we're reporting ALL errors, and display them
 * all, no matter what are the settings of the server php.ini
 */
error_reporting(E_ALL);
ini_set('display_errors', true);
ini_set('error_prepend_string', '');
ini_set('error_append_string', '');
ini_set('html_errors', false);

/**
 * Here we define a error handler in order to catch all possible
 * PHP errors and show them online, no matter what server settings
 * exist for error handling...
 *
 * Warnings will be IGNORED if statement that caused the error
 * was prepended by the @ error-control operator. This behavior
 * is important for functions like mysql_connect(), fsockopen()
 * to avoid warnings displaying, because when we use them we
 * implement own error detection mechanism.
 */
set_error_handler(
    create_function(
        '$errno, $errstr, $errfile, $errline',
        '
        if (in_array($errno, array(E_WARNING)) && error_reporting() == 0) {
            return;
        }
        echo sprintf(
            "phpRack error (%s): %s, in %s [line:%d]\n",
            $errno,
            $errstr,
            $errfile,
            $errline
        );
        '
    )
);

try {
    /**
     * This variable ($phpRackConfig) shall be declared and filled with
     * values in your phprack.php file, which calls this bootstraper. For
     * complete reference on this variable see:
     * @see http://trac.fazend.com/phpRack/wiki/Bootstrap
     */
    global $phpRackConfig;
    if (!isset($phpRackConfig)) {
        throw new Exception('Invalid configuration: global $phpRackConfig is missed');
    }

    if (!defined('PHPRACK_VERSION')) {
        define('PHPRACK_VERSION', '0.2dev');
    }

    if (!defined('PHPRACK_AJAX_TAG')) {
        define('PHPRACK_AJAX_TAG', 'test');
    }

    if (!defined('PHPRACK_AJAX_TOKEN')) {
        define('PHPRACK_AJAX_TOKEN', 'token');
    }

    if (!defined('PHPRACK_PATH')) {
        define('PHPRACK_PATH', dirname(__FILE__));
    }

    /**
     * @see phpRack_Runner
     */
    require_once PHPRACK_PATH . '/Runner.php';
    $runner = new phpRack_Runner($phpRackConfig);

    /**
     * @see phpRack_View
     */
    require_once PHPRACK_PATH . '/View.php';

    // if it's CLI enviroment - just show a full test report
    if ($runner->isCliEnvironment()) {
        throw new Exception($runner->runSuite());
    }

    // check whether SSL connection is mandatory?
    if (!$runner->isEnoughSecurityLevel()) {
        throw new Exception('You must use SSL protocol to run integration tests');
    }

    /**
     * Using this tag in GET URL we can get a summary report
     * in plain text format.
     */
    if (array_key_exists('suite', $_GET)) {
        header('Content-Type: text/plain');
        if (!$runner->getAuth()->isAuthenticated()) {
            throw new Exception('Access denied');
        }
        throw new Exception($runner->runSuite());
    }

    // Global layout is required, show the front web page of the report
    if (empty($_GET[PHPRACK_AJAX_TAG])) {
        $view = new phpRack_View();
        // show login form, if the user is not authenticated yet
        if (!$runner->getAuth()->isAuthenticated()) {
            $view->assign(array('authResult' => $runner->getAuth()->getAuthResult()));
            throw new Exception($view->render('login.phtml'));
        }
        $view->assign(array('runner' => $runner));
        /**
         * @todo #57 this line leads to the problem explained in the ticket,
         * on some servers, not everywhere. I don't know what is the reason, that's
         * why the line is commented for now.
         */
        // header('Content-Type: application/xhtml+xml');
        throw new Exception($view->render());
    }

    // show error message
    if (!$runner->getAuth()->isAuthenticated()) {
        throw new Exception("Authentication problem. You have to login first.");
    }

    /**
     * Execute one individual test and return its result
     * in JSON format. We reach this point only in AJAX calls from
     * already rendered testing page.
     */
    $options = $_GET;

    /**
     * '_' param is automatically added by jQuery with current time in miliseconds,
     * when we call $.ajax function with cache = false. We unset it to have
     * no exception in phpRack_Test::setAjaxOptions()
     */
    unset($options['_']);

    $fileName = $options[PHPRACK_AJAX_TAG];
    unset($options[PHPRACK_AJAX_TAG]);
    $token = $options[PHPRACK_AJAX_TOKEN];
    unset($options[PHPRACK_AJAX_TOKEN]);

    header('Content-Type: application/json');
    throw new Exception($runner->run($fileName, $token, $options));

} catch (Exception $e) {
    $content = $e->getMessage();
    echo $content;
}


text:
<?php
/**
 * phpRack: Integration Testing Framework
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt. It is also available
 * through the world-wide-web at this URL: http://www.phprack.com/LICENSE.txt
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@phprack.com so we can send you a copy immediately.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * @copyright Copyright (c) phpRack.com
 * @version $Id: Result.php 545 2010-05-04 09:40:46Z yegor256@yahoo.com $
 * @category phpRack
 */

/**
 * @see phpRack_Test
 */
require_once PHPRACK_PATH . '/Test.php';

/**
 * Result of a test execution
 *
 * @package Tests
 * @see phpRack_Assertion::__construct()
 */
class phpRack_Result
{

    /**
     * Log lines
     *
     * @var string
     * @see getLog()
     */
    protected $_lines;

    /**
     * Total result is SUCCESS?
     *
     * @var boolean
     * @see wasSuccessful()
     */
    protected $_success;

    /**
     * When this result was created by test
     *
     * @var float
     * @see clean()
     * @see getDuration()
     */
    protected $_started;

    /**
     * Test object which is owner of this result object,
     * used for give ability to set ajax options from phpRack_Package
     *
     * @var phpRack_Test
     * @see setTest()
     * @see getTest()
     */
    protected $_test;

    /**
     * Construct the class
     *
     * @param phpRack_Test Test, which pushes results here
     * @return void
     * @see phpRack_Assertion::__construct()
     */
    public function __construct(phpRack_Test $test)
    {
        $this->_test = $test;
        $this->clean();
    }

    /**
     * Set total result to FAILURE
     *
     * @return void
     * @see phpRack_Package::_failure()
     */
    public function fail()
    {
        $this->_success = false;
    }

    /**
     * Was the test successful?
     *
     * @return boolean
     * @see phpRack_Runner::runSuite()
     */
    public function wasSuccessful()
    {
        return $this->_success;
    }

    /**
     * Get full log of the result
     *
     * @return string
     * @see phpRack_Runner::run()
     */
    public function getLog()
    {
        return implode("\n", $this->_lines);
    }

    /**
     * Get log of assertions only, without any other messages
     *
     * @return string
     * @see phpRack_Runner::runSuite()
     */
    public function getPureLog()
    {
        return implode("\n", preg_grep('/^\[[A-Z]+\]\s/', $this->_lines));
    }

    /**
     * Get result lifetime, duration in seconds
     *
     * @return void
     * @see phpRack_Runner::runSuite()
     */
    public function getDuration()
    {
        return microtime(true) - $this->_started;
    }

    /**
     * Add new log line
     *
     * @param string Log line to add
     * @return $this
     * @see phpRack_Package::_log()
     */
    public function addLog($line)
    {
        $this->_lines[] = $line;
        return $this;
    }

    /**
     * Clean log
     *
     * @return void
     * @see phpRack_Test::run()
     */
    public function clean()
    {
        $this->_success = true;
        $this->_lines = array();
        $this->_started = microtime(true);
    }

    /**
     * Get test which is owner of this result object
     *
     * @return phpRack_Test
     * @see phpRack_Package_Disc_File::tail()
     */
    public function getTest()
    {
        return $this->_test;
    }
}


text:
<?php
/**
 * phpRack: Integration Testing Framework
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt. It is also available
 * through the world-wide-web at this URL: http://www.phprack.com/LICENSE.txt
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@phprack.com so we can send you a copy immediately.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * @copyright Copyright (c) phpRack.com
 * @version $Id: Suite.php 611 2010-07-12 14:23:40Z yegor256@yahoo.com $
 * @category phpRack
 */

/**
 * Parent class of all test suites
 *
 * Suites are maintained as directories full of tests, inside "phpRack/Suite/library"
 * holder. When we {@link _addSuite()}, this class files all tests in this suite
 * directory and add them all to itself. Also, library contains individual
 * tests, which can be added to the suite by means of {@link _addTest()}.
 *
 * @package Tests
 */
abstract class PhpRack_Suite
{
    /**
     * Runner of tests
     * @todo #48 Will be used when #48 will be merged into trunk
     *
     * @var phpRack_Runner
     * @see __construct()
     * @see _addTest()
     * @see _addSuite()
     */
    //private $_runner;

    /**
     * Suite tests
     *
     * @var array of phpRack_Test
     * @see getTests()
     * @see _addTest()
     */
    private $_tests = array();

    /**
     * Sub-suites
     *
     * @var array of PhpRack_Suite
     * @see getTests()
     * @see _addSuite()
     */
    private $_suites = array();

    /**
     * Create new instance of the class, using PHP absolute file name
     *
     * @param string ID of the suite, absolute (!) file name
     * @param phpRack_Runner Instance of test runner
     * @return phpRack_Suite
     * @throws Exception
     * @see _addSuite()
     * @see phpRack_Runner::getTests()
     */
    public static function factory($fileName, $runner)
    {
        if (!file_exists($fileName)) {
            throw new Exception("File '{$fileName}' is not found");
        }

        if (!preg_match(phpRack_Runner::SUITE_PATTERN, $fileName)) {
            throw new Exception("File '{$fileName}' is not named properly, can't run it");
        }

        $className = pathinfo($fileName, PATHINFO_FILENAME);

        // workaround against ZCA static code analysis
        eval('require_once $fileName;');
        return new $className($fileName, $runner);
    }

    /**
     * Get tests defined in this suite and sub suites
     *
     * @return array of phpRack_Test
     * @see phpRack_Runner::getTests()
     */
    public function getTests()
    {
        $tests = $this->_tests;
        foreach ($this->_suites as $suite) {
            $tests = array_merge($tests, $suite->getTests());
        }
        return $tests;
    }

    /**
     * Allow child class to add tests and sub suites by overwritting this
     * method
     *
     * @return void
     * @see __construct()
     */
    protected function __init()
    {

    }

    /**
     * Add suite
     *
     * Suite is a collection of tests. Name of the suite ($suiteName) is a name
     * of directory in "phpRack/Suite/library".
     *
     * @param string Suite name
     * @param array options
     * @return $this
     * @throws Exception if suite can't be found
     * @see MySuite::_init()
     * @see phpRack_Suite_Test
     */
    protected function _addSuite($suiteName, array $options = array())
    {
        assert(is_string($suiteName)); // for ZCA only
        assert(is_array($options)); // for ZCA only
        // @see #48
        // $suitePath = $suiteName;
        // Exception is possible here
        // $this->_suites[] = self::factory($suitePath, $this->_runner, $options);
        return $this;
    }

    /**
     * Add test
     *
     * Test should be located in our test library, inside "phpRack/Suite/library"
     * directory, and should be inherited from {@link phpRack_Suite_Test} class.
     *
     * @param string Suite name
     * @param array options
     * @return $this
     * @throws Exception if test can't be found
     * @see MySuite::_init()
     * @see phpRack_Suite_Test
     */
    protected function _addTest($testName, array $options = array())
    {
        // @see #48
        // $testPath = $testName;
        // @see #48
        assert(is_array($options)); // for ZCA only
        assert(is_string($testName)); // for ZCA only
        // Exception is possible here
        // $this->_tests[] = phpRack_Test::factory($testPath, $this->_runner);
        return $this;
    }

    /**
     * Test suite constructor
     *
     * @return void
     * @see factory()
     */
    private function __construct()
    {
        $this->_init();
    }
}


text:
<?php
/**
 * phpRack: Integration Testing Framework
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt. It is also available
 * through the world-wide-web at this URL: http://www.phprack.com/LICENSE.txt
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@phprack.com so we can send you a copy immediately.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * @copyright Copyright (c) phpRack.com
 * @version $Id: View.php 594 2010-07-02 05:35:01Z yegor256@yahoo.com $
 * @category phpRack
 */

/**
 * @see phpRack_Test
 */
require_once PHPRACK_PATH . '/Test.php';

/**
 * View in order to render test presentation page
 *
 * This class is used as a view component in our simple MVC pattern, where
 * model is {@link phpRack_Runner}, view is {@link phpRack_View} and controller is a simple
 * script in {@link bootstrap.php}. An instance of this class is accepting
 * variables and a script name in order to render it, for example:
 *
 * <code>
 * $view = new phpRack_View();
 * $view->assign(array('name' => 'My Name To Render'));
 * $html = $view->render('index.phtml');
 * </code>
 *
 * In this example, you can access "name" inside "index.phtml" like this:
 * $this->name.
 *
 * @package Tests
 * @see bootstrap.php
 */
class phpRack_View
{

    /**
     * Injected variables
     *
     * Variables from this array can be used inside view script, just as
     * local class variables. It is implemented by {@link __get()}
     *
     * @var array
     * @see __get()
     */
    protected $_injected = array();

    /**
     * Getter dispatcher, used inside view script
     *
     * @param string Name of the property to get
     * @return mixed
     * @see $this->_injected
     */
    public function __get($name)
    {
        if (array_key_exists($name, $this->_injected)) {
            return $this->_injected[$name];
        }
        throw new Exception("Property '{$name}' is absent in " . get_class($this));
    }

    /**
     * Inject variables into class
     *
     * @param array Associative array of variables to inject, where keys are names
     *      and values are real values to be used later in view script.
     * @return $this
     * @see bootstrap.php
     */
    public function assign(array $injects)
    {
        foreach ($injects as $name=>$value) {
            $this->_injected[$name] = $value;
        }
        return $this;
    }

    /**
     * Render the view and return HTML
     *
     * @param string Name of the script to render, inside "/layout"
     * @return HTML
     * @see bootstrap.php
     */
    public function render($script = 'index.phtml')
    {
        // two-step view, with layout
        $this->assign(array('script' => $script));

        ob_start();
        // workaround against ZCA static code analysis
        eval("include PHPRACK_PATH . '/layout/layout.phtml';");
        return $this->compressedHtml(ob_get_clean());
    }

    /**
     * Escapes special chars "\" and "'" in javascript
     *
     * @param string Path of the file to be rendered in JavaScript
     * @return string
     * @see #13
     * @see index.phtml
     */
    public function jsPath($path)
    {
        return addcslashes($path, "\\'");
    }

    /**
     * Compress HTML content
     *
     * @param string HTML content, before compression
     * @return string HTML content, compressed
     */
    public function compressedHtml($html)
    {
        $dom = new DOMDocument();
        $dom->preserveWhiteSpace = false;
        $dom->formatOutput = false;
        $dom->loadXml($html);

        $xpath = new DOMXPath($dom);
        $xpath->registerNamespace('xhtml', 'http://www.w3.org/1999/xhtml');
        $comments = $xpath->query('//comment()');
        foreach ($comments as $comment) {
            $comment->parentNode->removeChild($comment);
        }

        $replacers = array(
            '/\/\*.*?\*\//s'   => '', // remove multi line comments
            '/\/\/.*\r?\n\s*/' => '', // remove single line comments
            '/\s*\r?\n\s*/'    => '', // remove lines end with leading/trailing spaces
            '/\s+/'            => ' ', // convert multiple spaces to single
            '/\s?([\(\)\,\;=\'\"\-\+:\*&])\s?/' => '${1}', // compress unnecessary spaces
        );

        // skip compressing first script, because it is minified version of jQuery
        $scripts = $xpath->query('//xhtml:script[position() > 1]');

        foreach ($scripts as $script) {
            foreach ($script->childNodes as $childNode) {
                if ($childNode->nodeType == XML_CDATA_SECTION_NODE) {
                    $childNode->nodeValue = "\n" . preg_replace(
                        array_keys($replacers),
                        $replacers,
                        $childNode->nodeValue
                    );
                }
            }
        }
        /**
         * fix output due to libxml2 bug described in #53
         */
        return preg_replace('/<!\[CDATA\[\s*(\/\/)?\]\]>/', '//', $dom->saveXml());
    }

    /**
     * Return a compressed version of CSS
     *
     * @param string Relative path of CSS script, inside /layout dir
     * @return string CSS content compressed
     */
    public function compressedCss($css)
    {
        $content = file_get_contents(PHPRACK_PATH . '/layout/' . $css);
        $replacers = array(
            '/[\n\r\t]+/'         => ' ', // remove duplicated white spaces
            '/\s+/'               => ' ', // convert multiple spaces to single
            '/\s+([\,\:\{\}])/'   => '${1}', // compress leading white spaces
            '/([\,\;\:\{\}])\s+/' => '${1}', // compress trailing white spaces
            '/\/\*.*?\*\//'       => '', // kill comments at all
        );
        return preg_replace(
            array_keys($replacers),
            $replacers,
            $content
        );
    }

}


text:
<?php
/**
 * phpRack: Integration Testing Framework
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt. It is also available
 * through the world-wide-web at this URL: http://www.phprack.com/LICENSE.txt
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@phprack.com so we can send you a copy immediately.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * @copyright Copyright (c) phpRack.com
 * @version $Id: Test.php 570 2010-05-07 06:00:24Z yegor256@yahoo.com $
 * @category phpRack
 */

/**
 * @see phpRack_Test
 */
require_once PHPRACK_PATH . '/Test.php';

/**
 * Parent class of all tests in suite library
 *
 * @package Tests
 */
abstract class PhpRack_Suite_Test extends phpRack_Test
{
    /**
     * Configuration options
     *
     * @var array
     * @see setConfig()
     */
    protected $_config = array();

    /**
     * Set configuration params
     *
     * @param array List of configuration options
     * @return void
     * @throws Exception
     */
    public final function setConfig(array $config = array())
    {
        foreach ($config as $name=>$value) {
            if (!array_key_exists($name, $this->_config)) {
                throw new Exception("Option '{$name}' is not allowed for " . get_class($this));
            }
            $this->_config[$name] = $value;
        }
    }
}


text:
<?php
/**
 * phpRack: Integration Testing Framework
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt. It is also available
 * through the world-wide-web at this URL: http://www.phprack.com/LICENSE.txt
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@phprack.com so we can send you a copy immediately.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * @copyright Copyright (c) phpRack.com
 * @version $Id: LogViewerTest.php 570 2010-05-07 06:00:24Z yegor256@yahoo.com $
 * @category phpRack
 */

/**
 * @see phpRack_Suite_Test
 */
require_once PHPRACK_PATH . '/Suite/Test.php';

/**
 * View log file
 *
 * @package Tests
 */
class phpRack_Suite_LogViewerTest extends phpRack_Suite_Test
{
    /**
     * Configuration options
     *
     * @var array
     */
    protected $_config = array(
        'file' => 'php://temp',
    );

    /**
     * View log file in AJAX mode
     *
     * @return void
     */
    public function testShowLogFile()
    {
        $this->assert->disc->file
            ->tailf($this->_config['file']);
    }
}


text:
<?php
/**
 * phpRack: Integration Testing Framework
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt. It is also available
 * through the world-wide-web at this URL: http://www.phprack.com/LICENSE.txt
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@phprack.com so we can send you a copy immediately.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * @copyright Copyright (c) phpRack.com
 * @version $Id: TopProcessesTest.php 570 2010-05-07 06:00:24Z yegor256@yahoo.com $
 * @category phpRack
 */

/**
 * @see phpRack_Suite_Test
 */
require_once PHPRACK_PATH . '/Suite/Test.php';

/**
 * List of processes running on the server
 *
 * @package Tests
 */
class phpRack_Suite_ServerHealth_ProcessesTest extends phpRack_Suite_Test
{
    /**
     * Pre-configuration of the test
     *
     * @return void
     */
    protected function _init()
    {
        $this->setAjaxOptions(
            array(
                'reload' => 5, // every 5 seconds, if possible
            )
        );
    }

    /**
     * Show full list of top-processes and some other supplementary information
     *
     * @return void
     * @todo #48 This test works only on Linux, so we should change it
     *      soon to something more portable
     */
    public function testShowProcesses()
    {
        $this->assert->shell->exec('date 2>&1');
        $this->assert->shell->exec('uptime 2>&1');
        $this->assert->shell->exec(
            'ps o "%cpu %mem nice user time stat command" ax | '
            . 'awk \'NR==1; NR > 1 {print $0 | "sort -k 1 -r"}\' | '
            . 'grep -v "^ 0.0" 2>&1'
        );
        $this->assert->shell->exec('df 2>&1');
    }
}


text:
<?php
/**
 * phpRack: Integration Testing Framework
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt. It is also available
 * through the world-wide-web at this URL: http://www.phprack.com/LICENSE.txt
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@phprack.com so we can send you a copy immediately.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * @copyright Copyright (c) phpRack.com
 * @version $Id: PhpinfoTest.php 570 2010-05-07 06:00:24Z yegor256@yahoo.com $
 * @category phpRack
 */

/**
 * @see phpRack_Suite_Test
 */
require_once PHPRACK_PATH . '/Suite/Test.php';

/**
 * View phpinfo()
 *
 * @package Tests
 */
class phpRack_Suite_Php5_PhpinfoTest extends phpRack_Suite_Test
{
    /**
     * Show phpinfo()
     *
     * @return void
     */
    public function testShowPhpinfo()
    {
        $this->assert->php->phpinfo();
    }
}


text:
<?php echo $this->authResult->getMessage()?>

<form method="post">
    <?php require_once PHPRACK_PATH . '/Runner/Auth.php' ?>

Login:
<input name="<?php echo phpRack_Runner_Auth::POST_LOGIN?>" />

Password:
<input name="<?php echo phpRack_Runner_Auth::POST_PWD?>" type="password" />

<input type="submit" />

</form>


text:
PHPRACK_PATH: <tt><?php echo PHPRACK_PATH?></tt>

<?php $i = 0; ?>
<?php $jsCalls = array(); ?>

    <?php foreach ($this->runner->getTests() as $test):?>
        <?php $ajaxOptions = $test->getAjaxOptions();?>

        <div id="d<?php echo ++$i?>" class="task">
            <?php echo $test->getLabel() ?>:
            <?php
            if (!empty($ajaxOptions['autoStart'])) {
                echo 'waiting...';
            } else {
                echo 'click to start...';
            }
            // No enter before span to avoid slideToogle() problem in IE
            ?>

        <?php
        $jsCalls[$i] = array(
            'divId'              => 'div#d' . $i,
            'fileName'           => $this->jsPath($test->getFileName()),
            'autoStart'          => !empty($ajaxOptions['autoStart']) ? true : false,
            'pauseWhenFocusLost' => !empty($ajaxOptions['pauseWhenFocusLost']) ? true : false,
        );
        ?>
    <?php endforeach; ?>