Explorar o código

Zend_Test works with both PHPUnit 3.4 and 3.7+

I know, it is a little bit hacky solution, but it makes it possible to use controller tests in PHPUnit 3.4 as well as any higher version.
I suppose, that ZF1 is in some maintance mode, where the main goal is to have it running on newer SW versions and if someone wants to have superclean code, he can use ZF2 ;)

Inpired by the patch from http://opensource.hqcodeshop.com/Zend%20Framework/PHPUnit%203.7%20-%201.12.1/
Martin Hujer %!s(int64=12) %!d(string=hai) anos
pai
achega
12a7107be2

+ 6 - 401
library/Zend/Test/PHPUnit/Constraint/DomQuery.php

@@ -20,406 +20,11 @@
  * @version    $Id$
  */
 
-/** @see PHPUnit_Framework_Constraint */
-require_once 'PHPUnit/Framework/Constraint.php';
+/** @see PHPUnit_Runner_Version */
+require_once 'PHPUnit/Runner/Version.php';
 
-/** @see Zend_Dom_Query */
-require_once 'Zend/Dom/Query.php';
-
-/**
- * Zend_Dom_Query-based PHPUnit Constraint
- *
- * @uses       PHPUnit_Framework_Constraint
- * @category   Zend
- * @package    Zend_Test
- * @subpackage PHPUnit
- * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
- * @license    http://framework.zend.com/license/new-bsd     New BSD License
- */
-class Zend_Test_PHPUnit_Constraint_DomQuery extends PHPUnit_Framework_Constraint
-{
-    /**#@+
-     * Assertion type constants
-     */
-    const ASSERT_QUERY            = 'assertQuery';
-    const ASSERT_CONTENT_CONTAINS = 'assertQueryContentContains';
-    const ASSERT_CONTENT_REGEX    = 'assertQueryContentRegex';
-    const ASSERT_CONTENT_COUNT    = 'assertQueryCount';
-    const ASSERT_CONTENT_COUNT_MIN= 'assertQueryCountMin';
-    const ASSERT_CONTENT_COUNT_MAX= 'assertQueryCountMax';
-    /**#@-*/
-
-    /**
-     * Current assertion type
-     * @var string
-     */
-    protected $_assertType        = null;
-
-    /**
-     * Available assertion types
-     * @var array
-     */
-    protected $_assertTypes       = array(
-        self::ASSERT_QUERY,
-        self::ASSERT_CONTENT_CONTAINS,
-        self::ASSERT_CONTENT_REGEX,
-        self::ASSERT_CONTENT_COUNT,
-        self::ASSERT_CONTENT_COUNT_MIN,
-        self::ASSERT_CONTENT_COUNT_MAX,
-    );
-
-    /**
-     * Content being matched
-     * @var string
-     */
-    protected $_content           = null;
-
-    /**
-     * Whether or not assertion is negated
-     * @var bool
-     */
-    protected $_negate            = false;
-
-    /**
-     * CSS selector or XPath path to select against
-     * @var string
-     */
-    protected $_path              = null;
-
-    /**
-     * Whether or not to use XPath when querying
-     * @var bool
-     */
-    protected $_useXpath          = false;
-
-    /**
-     * XPath namespaces
-     * @var array
-     */
-    protected $_xpathNamespaces = array();
-
-    /**
-     * Constructor; setup constraint state
-     *
-     * @param  string $path CSS selector path
-     * @return void
-     */
-    public function __construct($path)
-    {
-        $this->_path = $path;
-    }
-
-    /**
-     * Indicate negative match
-     *
-     * @param  bool $flag
-     * @return void
-     */
-    public function setNegate($flag = true)
-    {
-        $this->_negate = $flag;
-    }
-
-    /**
-     * Whether or not path is a straight XPath expression
-     *
-     * @param  bool $flag
-     * @return Zend_Test_PHPUnit_Constraint_DomQuery
-     */
-    public function setUseXpath($flag = true)
-    {
-        $this->_useXpath = (bool) $flag;
-        return $this;
-    }
-
-    /**
-     * Evaluate an object to see if it fits the constraints
-     *
-     * @param  string $other String to examine
-     * @param  null|string Assertion type
-     * @return bool
-     */
-    public function evaluate($other, $assertType = null)
-    {
-        if (strstr($assertType, 'Not')) {
-            $this->setNegate(true);
-            $assertType = str_replace('Not', '', $assertType);
-        }
-
-        if (strstr($assertType, 'Xpath')) {
-            $this->setUseXpath(true);
-            $assertType = str_replace('Xpath', 'Query', $assertType);
-        }
-
-        if (!in_array($assertType, $this->_assertTypes)) {
-            require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
-            throw new Zend_Test_PHPUnit_Constraint_Exception(sprintf('Invalid assertion type "%s" provided to %s constraint', $assertType, __CLASS__));
-        }
-
-        $this->_assertType = $assertType;
-
-        $method   = $this->_useXpath ? 'queryXpath' : 'query';
-        $domQuery = new Zend_Dom_Query($other);
-        $domQuery->registerXpathNamespaces($this->_xpathNamespaces);
-        $result   = $domQuery->$method($this->_path);
-        $argv     = func_get_args();
-        $argc     = func_num_args();
-
-        switch ($assertType) {
-            case self::ASSERT_CONTENT_CONTAINS:
-                if (3 > $argc) {
-                    require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
-                    throw new Zend_Test_PHPUnit_Constraint_Exception('No content provided against which to match');
-                }
-                $this->_content = $content = $argv[2];
-                return ($this->_negate)
-                    ? $this->_notMatchContent($result, $content)
-                    : $this->_matchContent($result, $content);
-            case self::ASSERT_CONTENT_REGEX:
-                if (3 > $argc) {
-                    require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
-                    throw new Zend_Test_PHPUnit_Constraint_Exception('No pattern provided against which to match');
-                }
-                $this->_content = $content = $argv[2];
-                return ($this->_negate)
-                    ? $this->_notRegexContent($result, $content)
-                    : $this->_regexContent($result, $content);
-            case self::ASSERT_CONTENT_COUNT:
-            case self::ASSERT_CONTENT_COUNT_MIN:
-            case self::ASSERT_CONTENT_COUNT_MAX:
-                if (3 > $argc) {
-                    require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
-                    throw new Zend_Test_PHPUnit_Constraint_Exception('No count provided against which to compare');
-                }
-                $this->_content = $content = $argv[2];
-                return $this->_countContent($result, $content, $assertType);
-            case self::ASSERT_QUERY:
-            default:
-                if ($this->_negate) {
-                    return (0 == count($result));
-                } else {
-                    return (0 != count($result));
-                }
-        }
-    }
-
-    /**
-     * Report Failure
-     *
-     * @see    PHPUnit_Framework_Constraint for implementation details
-     * @param  mixed $other CSS selector path
-     * @param  string $description
-     * @param  bool $not
-     * @return void
-     * @throws PHPUnit_Framework_ExpectationFailedException
-     */
-    public function fail($other, $description, $not = false)
-    {
-        require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
-        switch ($this->_assertType) {
-            case self::ASSERT_CONTENT_CONTAINS:
-                $failure = 'Failed asserting node denoted by %s CONTAINS content "%s"';
-                if ($this->_negate) {
-                    $failure = 'Failed asserting node DENOTED BY %s DOES NOT CONTAIN content "%s"';
-                }
-                $failure = sprintf($failure, $other, $this->_content);
-                break;
-            case self::ASSERT_CONTENT_REGEX:
-                $failure = 'Failed asserting node denoted by %s CONTAINS content MATCHING "%s"';
-                if ($this->_negate) {
-                    $failure = 'Failed asserting node DENOTED BY %s DOES NOT CONTAIN content MATCHING "%s"';
-                }
-                $failure = sprintf($failure, $other, $this->_content);
-                break;
-            case self::ASSERT_CONTENT_COUNT:
-                $failure = 'Failed asserting node DENOTED BY %s OCCURS EXACTLY %d times';
-                if ($this->_negate) {
-                    $failure = 'Failed asserting node DENOTED BY %s DOES NOT OCCUR EXACTLY %d times';
-                }
-                $failure = sprintf($failure, $other, $this->_content);
-                break;
-            case self::ASSERT_CONTENT_COUNT_MIN:
-                $failure = 'Failed asserting node DENOTED BY %s OCCURS AT LEAST %d times';
-                $failure = sprintf($failure, $other, $this->_content);
-                break;
-            case self::ASSERT_CONTENT_COUNT_MAX:
-                $failure = 'Failed asserting node DENOTED BY %s OCCURS AT MOST %d times';
-                $failure = sprintf($failure, $other, $this->_content);
-                break;
-            case self::ASSERT_QUERY:
-            default:
-                $failure = 'Failed asserting node DENOTED BY %s EXISTS';
-                if ($this->_negate) {
-                    $failure = 'Failed asserting node DENOTED BY %s DOES NOT EXIST';
-                }
-                $failure = sprintf($failure, $other);
-                break;
-        }
-
-        if (!empty($description)) {
-            $failure = $description . "\n" . $failure;
-        }
-
-        throw new Zend_Test_PHPUnit_Constraint_Exception($failure);
-    }
-
-    /**
-     * Complete implementation
-     *
-     * @return string
-     */
-    public function toString()
-    {
-        return '';
-    }
-
-    /**
-     * Register XPath namespaces
-     *
-     * @param   array $xpathNamespaces
-     * @return  void
-     */
-    public function registerXpathNamespaces($xpathNamespaces)
-    {
-        $this->_xpathNamespaces = $xpathNamespaces;
-    }
-
-    /**
-     * Check to see if content is matched in selected nodes
-     *
-     * @param  Zend_Dom_Query_Result $result
-     * @param  string $match Content to match
-     * @return bool
-     */
-    protected function _matchContent($result, $match)
-    {
-        $match = (string) $match;
-
-        if (0 == count($result)) {
-            return false;
-        }
-
-        foreach ($result as $node) {
-            $content = $this->_getNodeContent($node);
-            if (strstr($content, $match)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Check to see if content is NOT matched in selected nodes
-     *
-     * @param  Zend_Dom_Query_Result $result
-     * @param  string $match
-     * @return bool
-     */
-    protected function _notMatchContent($result, $match)
-    {
-        if (0 == count($result)) {
-            return true;
-        }
-
-        foreach ($result as $node) {
-            $content = $this->_getNodeContent($node);
-            if (strstr($content, $match)) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Check to see if content is matched by regex in selected nodes
-     *
-     * @param  Zend_Dom_Query_Result $result
-     * @param  string $pattern
-     * @return bool
-     */
-    protected function _regexContent($result, $pattern)
-    {
-        if (0 == count($result)) {
-            return false;
-        }
-
-        foreach ($result as $node) {
-            $content = $this->_getNodeContent($node);
-            if (preg_match($pattern, $content)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Check to see if content is NOT matched by regex in selected nodes
-     *
-     * @param  Zend_Dom_Query_Result $result
-     * @param  string $pattern
-     * @return bool
-     */
-    protected function _notRegexContent($result, $pattern)
-    {
-        if (0 == count($result)) {
-            return true;
-        }
-
-        foreach ($result as $node) {
-            $content = $this->_getNodeContent($node);
-            if (preg_match($pattern, $content)) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Determine if content count matches criteria
-     *
-     * @param  Zend_Dom_Query_Result $result
-     * @param  int $test Value against which to test
-     * @param  string $type assertion type
-     * @return boolean
-     */
-    protected function _countContent($result, $test, $type)
-    {
-        $count = count($result);
-
-        switch ($type) {
-            case self::ASSERT_CONTENT_COUNT:
-                return ($this->_negate)
-                    ? ($test != $count)
-                    : ($test == $count);
-            case self::ASSERT_CONTENT_COUNT_MIN:
-                return ($count >= $test);
-            case self::ASSERT_CONTENT_COUNT_MAX:
-                return ($count <= $test);
-            default:
-                return false;
-        }
-    }
-
-    /**
-     * Get node content, minus node markup tags
-     *
-     * @param  DOMNode $node
-     * @return string
-     */
-    protected function _getNodeContent(DOMNode $node)
-    {
-        if ($node instanceof DOMAttr) {
-            return $node->value;
-        } else {
-            $doc     = $node->ownerDocument;
-            $content = $doc->saveXML($node);
-            $tag     = $node->nodeName;
-            $regex   = '|</?' . $tag . '[^>]*>|';
-            return preg_replace($regex, '', $content);
-        }
-    }
+if (version_compare(PHPUnit_Runner_Version::id(), '3.5', '>=')) {
+    include(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'DomQuery37.php');
+} else {
+    include(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'DomQuery34.php');
 }

+ 425 - 0
library/Zend/Test/PHPUnit/Constraint/DomQuery34.php

@@ -0,0 +1,425 @@
+<?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_Test
+ * @subpackage PHPUnit
+ * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/** @see PHPUnit_Framework_Constraint */
+require_once 'PHPUnit/Framework/Constraint.php';
+
+/** @see Zend_Dom_Query */
+require_once 'Zend/Dom/Query.php';
+
+/**
+ * Zend_Dom_Query-based PHPUnit Constraint
+ *
+ * @uses       PHPUnit_Framework_Constraint
+ * @category   Zend
+ * @package    Zend_Test
+ * @subpackage PHPUnit
+ * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Test_PHPUnit_Constraint_DomQuery extends PHPUnit_Framework_Constraint
+{
+    /**#@+
+     * Assertion type constants
+     */
+    const ASSERT_QUERY            = 'assertQuery';
+    const ASSERT_CONTENT_CONTAINS = 'assertQueryContentContains';
+    const ASSERT_CONTENT_REGEX    = 'assertQueryContentRegex';
+    const ASSERT_CONTENT_COUNT    = 'assertQueryCount';
+    const ASSERT_CONTENT_COUNT_MIN= 'assertQueryCountMin';
+    const ASSERT_CONTENT_COUNT_MAX= 'assertQueryCountMax';
+    /**#@-*/
+
+    /**
+     * Current assertion type
+     * @var string
+     */
+    protected $_assertType        = null;
+
+    /**
+     * Available assertion types
+     * @var array
+     */
+    protected $_assertTypes       = array(
+        self::ASSERT_QUERY,
+        self::ASSERT_CONTENT_CONTAINS,
+        self::ASSERT_CONTENT_REGEX,
+        self::ASSERT_CONTENT_COUNT,
+        self::ASSERT_CONTENT_COUNT_MIN,
+        self::ASSERT_CONTENT_COUNT_MAX,
+    );
+
+    /**
+     * Content being matched
+     * @var string
+     */
+    protected $_content           = null;
+
+    /**
+     * Whether or not assertion is negated
+     * @var bool
+     */
+    protected $_negate            = false;
+
+    /**
+     * CSS selector or XPath path to select against
+     * @var string
+     */
+    protected $_path              = null;
+
+    /**
+     * Whether or not to use XPath when querying
+     * @var bool
+     */
+    protected $_useXpath          = false;
+
+    /**
+     * XPath namespaces
+     * @var array
+     */
+    protected $_xpathNamespaces = array();
+
+    /**
+     * Constructor; setup constraint state
+     *
+     * @param  string $path CSS selector path
+     * @return void
+     */
+    public function __construct($path)
+    {
+        $this->_path = $path;
+    }
+
+    /**
+     * Indicate negative match
+     *
+     * @param  bool $flag
+     * @return void
+     */
+    public function setNegate($flag = true)
+    {
+        $this->_negate = $flag;
+    }
+
+    /**
+     * Whether or not path is a straight XPath expression
+     *
+     * @param  bool $flag
+     * @return Zend_Test_PHPUnit_Constraint_DomQuery
+     */
+    public function setUseXpath($flag = true)
+    {
+        $this->_useXpath = (bool) $flag;
+        return $this;
+    }
+
+    /**
+     * Evaluate an object to see if it fits the constraints
+     *
+     * @param  string $other String to examine
+     * @param  null|string Assertion type
+     * @return bool
+     */
+    public function evaluate($other, $assertType = null)
+    {
+        if (strstr($assertType, 'Not')) {
+            $this->setNegate(true);
+            $assertType = str_replace('Not', '', $assertType);
+        }
+
+        if (strstr($assertType, 'Xpath')) {
+            $this->setUseXpath(true);
+            $assertType = str_replace('Xpath', 'Query', $assertType);
+        }
+
+        if (!in_array($assertType, $this->_assertTypes)) {
+            require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
+            throw new Zend_Test_PHPUnit_Constraint_Exception(sprintf('Invalid assertion type "%s" provided to %s constraint', $assertType, __CLASS__));
+        }
+
+        $this->_assertType = $assertType;
+
+        $method   = $this->_useXpath ? 'queryXpath' : 'query';
+        $domQuery = new Zend_Dom_Query($other);
+        $domQuery->registerXpathNamespaces($this->_xpathNamespaces);
+        $result   = $domQuery->$method($this->_path);
+        $argv     = func_get_args();
+        $argc     = func_num_args();
+
+        switch ($assertType) {
+            case self::ASSERT_CONTENT_CONTAINS:
+                if (3 > $argc) {
+                    require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
+                    throw new Zend_Test_PHPUnit_Constraint_Exception('No content provided against which to match');
+                }
+                $this->_content = $content = $argv[2];
+                return ($this->_negate)
+                    ? $this->_notMatchContent($result, $content)
+                    : $this->_matchContent($result, $content);
+            case self::ASSERT_CONTENT_REGEX:
+                if (3 > $argc) {
+                    require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
+                    throw new Zend_Test_PHPUnit_Constraint_Exception('No pattern provided against which to match');
+                }
+                $this->_content = $content = $argv[2];
+                return ($this->_negate)
+                    ? $this->_notRegexContent($result, $content)
+                    : $this->_regexContent($result, $content);
+            case self::ASSERT_CONTENT_COUNT:
+            case self::ASSERT_CONTENT_COUNT_MIN:
+            case self::ASSERT_CONTENT_COUNT_MAX:
+                if (3 > $argc) {
+                    require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
+                    throw new Zend_Test_PHPUnit_Constraint_Exception('No count provided against which to compare');
+                }
+                $this->_content = $content = $argv[2];
+                return $this->_countContent($result, $content, $assertType);
+            case self::ASSERT_QUERY:
+            default:
+                if ($this->_negate) {
+                    return (0 == count($result));
+                } else {
+                    return (0 != count($result));
+                }
+        }
+    }
+
+    /**
+     * Report Failure
+     *
+     * @see    PHPUnit_Framework_Constraint for implementation details
+     * @param  mixed $other CSS selector path
+     * @param  string $description
+     * @param  bool $not
+     * @return void
+     * @throws PHPUnit_Framework_ExpectationFailedException
+     */
+    public function fail($other, $description, $not = false)
+    {
+        require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
+        switch ($this->_assertType) {
+            case self::ASSERT_CONTENT_CONTAINS:
+                $failure = 'Failed asserting node denoted by %s CONTAINS content "%s"';
+                if ($this->_negate) {
+                    $failure = 'Failed asserting node DENOTED BY %s DOES NOT CONTAIN content "%s"';
+                }
+                $failure = sprintf($failure, $other, $this->_content);
+                break;
+            case self::ASSERT_CONTENT_REGEX:
+                $failure = 'Failed asserting node denoted by %s CONTAINS content MATCHING "%s"';
+                if ($this->_negate) {
+                    $failure = 'Failed asserting node DENOTED BY %s DOES NOT CONTAIN content MATCHING "%s"';
+                }
+                $failure = sprintf($failure, $other, $this->_content);
+                break;
+            case self::ASSERT_CONTENT_COUNT:
+                $failure = 'Failed asserting node DENOTED BY %s OCCURS EXACTLY %d times';
+                if ($this->_negate) {
+                    $failure = 'Failed asserting node DENOTED BY %s DOES NOT OCCUR EXACTLY %d times';
+                }
+                $failure = sprintf($failure, $other, $this->_content);
+                break;
+            case self::ASSERT_CONTENT_COUNT_MIN:
+                $failure = 'Failed asserting node DENOTED BY %s OCCURS AT LEAST %d times';
+                $failure = sprintf($failure, $other, $this->_content);
+                break;
+            case self::ASSERT_CONTENT_COUNT_MAX:
+                $failure = 'Failed asserting node DENOTED BY %s OCCURS AT MOST %d times';
+                $failure = sprintf($failure, $other, $this->_content);
+                break;
+            case self::ASSERT_QUERY:
+            default:
+                $failure = 'Failed asserting node DENOTED BY %s EXISTS';
+                if ($this->_negate) {
+                    $failure = 'Failed asserting node DENOTED BY %s DOES NOT EXIST';
+                }
+                $failure = sprintf($failure, $other);
+                break;
+        }
+
+        if (!empty($description)) {
+            $failure = $description . "\n" . $failure;
+        }
+
+        throw new Zend_Test_PHPUnit_Constraint_Exception($failure);
+    }
+
+    /**
+     * Complete implementation
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return '';
+    }
+
+    /**
+     * Register XPath namespaces
+     *
+     * @param   array $xpathNamespaces
+     * @return  void
+     */
+    public function registerXpathNamespaces($xpathNamespaces)
+    {
+        $this->_xpathNamespaces = $xpathNamespaces;
+    }
+
+    /**
+     * Check to see if content is matched in selected nodes
+     *
+     * @param  Zend_Dom_Query_Result $result
+     * @param  string $match Content to match
+     * @return bool
+     */
+    protected function _matchContent($result, $match)
+    {
+        $match = (string) $match;
+
+        if (0 == count($result)) {
+            return false;
+        }
+
+        foreach ($result as $node) {
+            $content = $this->_getNodeContent($node);
+            if (strstr($content, $match)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Check to see if content is NOT matched in selected nodes
+     *
+     * @param  Zend_Dom_Query_Result $result
+     * @param  string $match
+     * @return bool
+     */
+    protected function _notMatchContent($result, $match)
+    {
+        if (0 == count($result)) {
+            return true;
+        }
+
+        foreach ($result as $node) {
+            $content = $this->_getNodeContent($node);
+            if (strstr($content, $match)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Check to see if content is matched by regex in selected nodes
+     *
+     * @param  Zend_Dom_Query_Result $result
+     * @param  string $pattern
+     * @return bool
+     */
+    protected function _regexContent($result, $pattern)
+    {
+        if (0 == count($result)) {
+            return false;
+        }
+
+        foreach ($result as $node) {
+            $content = $this->_getNodeContent($node);
+            if (preg_match($pattern, $content)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Check to see if content is NOT matched by regex in selected nodes
+     *
+     * @param  Zend_Dom_Query_Result $result
+     * @param  string $pattern
+     * @return bool
+     */
+    protected function _notRegexContent($result, $pattern)
+    {
+        if (0 == count($result)) {
+            return true;
+        }
+
+        foreach ($result as $node) {
+            $content = $this->_getNodeContent($node);
+            if (preg_match($pattern, $content)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Determine if content count matches criteria
+     *
+     * @param  Zend_Dom_Query_Result $result
+     * @param  int $test Value against which to test
+     * @param  string $type assertion type
+     * @return boolean
+     */
+    protected function _countContent($result, $test, $type)
+    {
+        $count = count($result);
+
+        switch ($type) {
+            case self::ASSERT_CONTENT_COUNT:
+                return ($this->_negate)
+                    ? ($test != $count)
+                    : ($test == $count);
+            case self::ASSERT_CONTENT_COUNT_MIN:
+                return ($count >= $test);
+            case self::ASSERT_CONTENT_COUNT_MAX:
+                return ($count <= $test);
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Get node content, minus node markup tags
+     *
+     * @param  DOMNode $node
+     * @return string
+     */
+    protected function _getNodeContent(DOMNode $node)
+    {
+        if ($node instanceof DOMAttr) {
+            return $node->value;
+        } else {
+            $doc     = $node->ownerDocument;
+            $content = $doc->saveXML($node);
+            $tag     = $node->nodeName;
+            $regex   = '|</?' . $tag . '[^>]*>|';
+            return preg_replace($regex, '', $content);
+        }
+    }
+}

+ 437 - 0
library/Zend/Test/PHPUnit/Constraint/DomQuery37.php

@@ -0,0 +1,437 @@
+<?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_Test
+ * @subpackage PHPUnit
+ * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/** @see PHPUnit_Framework_Constraint */
+require_once 'PHPUnit/Framework/Constraint.php';
+
+/** @see Zend_Dom_Query */
+require_once 'Zend/Dom/Query.php';
+
+/**
+ * Zend_Dom_Query-based PHPUnit Constraint
+ *
+ * @uses       PHPUnit_Framework_Constraint
+ * @category   Zend
+ * @package    Zend_Test
+ * @subpackage PHPUnit
+ * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Test_PHPUnit_Constraint_DomQuery extends PHPUnit_Framework_Constraint
+{
+    /**#@+
+     * Assertion type constants
+     */
+    const ASSERT_QUERY            = 'assertQuery';
+    const ASSERT_CONTENT_CONTAINS = 'assertQueryContentContains';
+    const ASSERT_CONTENT_REGEX    = 'assertQueryContentRegex';
+    const ASSERT_CONTENT_COUNT    = 'assertQueryCount';
+    const ASSERT_CONTENT_COUNT_MIN= 'assertQueryCountMin';
+    const ASSERT_CONTENT_COUNT_MAX= 'assertQueryCountMax';
+    /**#@-*/
+
+    /**
+     * Current assertion type
+     * @var string
+     */
+    protected $_assertType        = null;
+
+    /**
+     * Available assertion types
+     * @var array
+     */
+    protected $_assertTypes       = array(
+        self::ASSERT_QUERY,
+        self::ASSERT_CONTENT_CONTAINS,
+        self::ASSERT_CONTENT_REGEX,
+        self::ASSERT_CONTENT_COUNT,
+        self::ASSERT_CONTENT_COUNT_MIN,
+        self::ASSERT_CONTENT_COUNT_MAX,
+    );
+
+    /**
+     * Content being matched
+     * @var string
+     */
+    protected $_content           = null;
+
+    /**
+     * Whether or not assertion is negated
+     * @var bool
+     */
+    protected $_negate            = false;
+
+    /**
+     * CSS selector or XPath path to select against
+     * @var string
+     */
+    protected $_path              = null;
+
+    /**
+     * Whether or not to use XPath when querying
+     * @var bool
+     */
+    protected $_useXpath          = false;
+
+    /**
+     * XPath namespaces
+     * @var array
+     */
+    protected $_xpathNamespaces = array();
+
+    /**
+     * Constructor; setup constraint state
+     *
+     * @param  string $path CSS selector path
+     * @return void
+     */
+    public function __construct($path)
+    {
+        $this->_path = $path;
+    }
+
+    /**
+     * Indicate negative match
+     *
+     * @param  bool $flag
+     * @return void
+     */
+    public function setNegate($flag = true)
+    {
+        $this->_negate = $flag;
+    }
+
+    /**
+     * Whether or not path is a straight XPath expression
+     *
+     * @param  bool $flag
+     * @return Zend_Test_PHPUnit_Constraint_DomQuery
+     */
+    public function setUseXpath($flag = true)
+    {
+        $this->_useXpath = (bool) $flag;
+        return $this;
+    }
+
+    /**
+     * Evaluate an object to see if it fits the constraints
+     *
+     * @param  string       Response content to be matched against (haystack)
+     * @param  null|string  Assertion type
+     * @param  string       (optional) String to match (needle), may be required depending on assertion type
+     * @return bool
+     * 
+     * NOTE:
+     * Drastic changes up to PHPUnit 3.5.15 this was:
+     *     public function evaluate($other, $assertType = null)
+     * In PHPUnit 3.6.0 they changed the interface into this:
+     *     public function evaluate($other, $description = '', $returnResult = FALSE)
+     * We use the new interface for PHP-strict checking, but emulate the old one
+     */
+    public function evaluate($content, $assertType = '', $match = FALSE)
+    {
+        if (strstr($assertType, 'Not')) {
+            $this->setNegate(true);
+            $assertType = str_replace('Not', '', $assertType);
+        }
+
+        if (strstr($assertType, 'Xpath')) {
+            $this->setUseXpath(true);
+            $assertType = str_replace('Xpath', 'Query', $assertType);
+        }
+
+        if (!in_array($assertType, $this->_assertTypes)) {
+            require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
+            throw new Zend_Test_PHPUnit_Constraint_Exception(sprintf('Invalid assertion type "%s" provided to %s constraint', $assertType, __CLASS__));
+        }
+
+        $this->_assertType = $assertType;
+
+        $method   = $this->_useXpath ? 'queryXpath' : 'query';
+        $domQuery = new Zend_Dom_Query($content);
+        $domQuery->registerXpathNamespaces($this->_xpathNamespaces);
+        $result   = $domQuery->$method($this->_path);
+
+        switch ($assertType) {
+            case self::ASSERT_CONTENT_CONTAINS:
+                if (!$match) {
+                    require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
+                    throw new Zend_Test_PHPUnit_Constraint_Exception('No content provided against which to match');
+                }
+                $this->_content = $match;
+                return ($this->_negate)
+                    ? $this->_notMatchContent($result, $match)
+                    : $this->_matchContent($result, $match);
+            case self::ASSERT_CONTENT_REGEX:
+                if (!$match) {
+                    require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
+                    throw new Zend_Test_PHPUnit_Constraint_Exception('No pattern provided against which to match');
+                }
+                $this->_content = $match;
+                return ($this->_negate)
+                    ? $this->_notRegexContent($result, $match)
+                    : $this->_regexContent($result, $match);
+            case self::ASSERT_CONTENT_COUNT:
+            case self::ASSERT_CONTENT_COUNT_MIN:
+            case self::ASSERT_CONTENT_COUNT_MAX:
+                if (!$match) {
+                    require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
+                    throw new Zend_Test_PHPUnit_Constraint_Exception('No count provided against which to compare');
+                }
+                $this->_content = $match;
+                return $this->_countContent($result, $match, $assertType);
+            case self::ASSERT_QUERY:
+            default:
+                if ($this->_negate) {
+                    return (0 == count($result));
+                } else {
+                    return (0 != count($result));
+                }
+        }
+    }
+
+    /**
+     * Report Failure
+     *
+     * @see    PHPUnit_Framework_Constraint for implementation details
+     * @param  mixed    CSS selector path
+     * @param  string   Failure description
+     * @param  object   Cannot be used, null
+     * @return void
+     * @throws PHPUnit_Framework_ExpectationFailedException
+     * NOTE:
+     * Drastic changes up to PHPUnit 3.5.15 this was:
+     *     public function fail($other, $description, $not = false)
+     * In PHPUnit 3.6.0 they changed the interface into this:
+     *     protected function fail($other, $description, PHPUnit_Framework_ComparisonFailure $comparisonFailure = NULL)
+     * We use the new interface for PHP-strict checking
+     */
+    public function fail($other, $description, PHPUnit_Framework_ComparisonFailure $cannot_be_used = NULL)
+    {
+        require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
+        switch ($this->_assertType) {
+            case self::ASSERT_CONTENT_CONTAINS:
+                $failure = 'Failed asserting node denoted by %s CONTAINS content "%s"';
+                if ($this->_negate) {
+                    $failure = 'Failed asserting node DENOTED BY %s DOES NOT CONTAIN content "%s"';
+                }
+                $failure = sprintf($failure, $other, $this->_content);
+                break;
+            case self::ASSERT_CONTENT_REGEX:
+                $failure = 'Failed asserting node denoted by %s CONTAINS content MATCHING "%s"';
+                if ($this->_negate) {
+                    $failure = 'Failed asserting node DENOTED BY %s DOES NOT CONTAIN content MATCHING "%s"';
+                }
+                $failure = sprintf($failure, $other, $this->_content);
+                break;
+            case self::ASSERT_CONTENT_COUNT:
+                $failure = 'Failed asserting node DENOTED BY %s OCCURS EXACTLY %d times';
+                if ($this->_negate) {
+                    $failure = 'Failed asserting node DENOTED BY %s DOES NOT OCCUR EXACTLY %d times';
+                }
+                $failure = sprintf($failure, $other, $this->_content);
+                break;
+            case self::ASSERT_CONTENT_COUNT_MIN:
+                $failure = 'Failed asserting node DENOTED BY %s OCCURS AT LEAST %d times';
+                $failure = sprintf($failure, $other, $this->_content);
+                break;
+            case self::ASSERT_CONTENT_COUNT_MAX:
+                $failure = 'Failed asserting node DENOTED BY %s OCCURS AT MOST %d times';
+                $failure = sprintf($failure, $other, $this->_content);
+                break;
+            case self::ASSERT_QUERY:
+            default:
+                $failure = 'Failed asserting node DENOTED BY %s EXISTS';
+                if ($this->_negate) {
+                    $failure = 'Failed asserting node DENOTED BY %s DOES NOT EXIST';
+                }
+                $failure = sprintf($failure, $other);
+                break;
+        }
+
+        if (!empty($description)) {
+            $failure = $description . "\n" . $failure;
+        }
+
+        throw new Zend_Test_PHPUnit_Constraint_Exception($failure);
+    }
+
+    /**
+     * Complete implementation
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return '';
+    }
+
+    /**
+     * Register XPath namespaces
+     *
+     * @param   array $xpathNamespaces
+     * @return  void
+     */
+    public function registerXpathNamespaces($xpathNamespaces)
+    {
+        $this->_xpathNamespaces = $xpathNamespaces;
+    }
+
+    /**
+     * Check to see if content is matched in selected nodes
+     *
+     * @param  Zend_Dom_Query_Result $result
+     * @param  string $match Content to match
+     * @return bool
+     */
+    protected function _matchContent($result, $match)
+    {
+        $match = (string) $match;
+
+        if (0 == count($result)) {
+            return false;
+        }
+
+        foreach ($result as $node) {
+            $content = $this->_getNodeContent($node);
+            if (strstr($content, $match)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Check to see if content is NOT matched in selected nodes
+     *
+     * @param  Zend_Dom_Query_Result $result
+     * @param  string $match
+     * @return bool
+     */
+    protected function _notMatchContent($result, $match)
+    {
+        if (0 == count($result)) {
+            return true;
+        }
+
+        foreach ($result as $node) {
+            $content = $this->_getNodeContent($node);
+            if (strstr($content, $match)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Check to see if content is matched by regex in selected nodes
+     *
+     * @param  Zend_Dom_Query_Result $result
+     * @param  string $pattern
+     * @return bool
+     */
+    protected function _regexContent($result, $pattern)
+    {
+        if (0 == count($result)) {
+            return false;
+        }
+
+        foreach ($result as $node) {
+            $content = $this->_getNodeContent($node);
+            if (preg_match($pattern, $content)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Check to see if content is NOT matched by regex in selected nodes
+     *
+     * @param  Zend_Dom_Query_Result $result
+     * @param  string $pattern
+     * @return bool
+     */
+    protected function _notRegexContent($result, $pattern)
+    {
+        if (0 == count($result)) {
+            return true;
+        }
+
+        foreach ($result as $node) {
+            $content = $this->_getNodeContent($node);
+            if (preg_match($pattern, $content)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Determine if content count matches criteria
+     *
+     * @param  Zend_Dom_Query_Result $result
+     * @param  int $test Value against which to test
+     * @param  string $type assertion type
+     * @return boolean
+     */
+    protected function _countContent($result, $test, $type)
+    {
+        $count = count($result);
+
+        switch ($type) {
+            case self::ASSERT_CONTENT_COUNT:
+                return ($this->_negate)
+                    ? ($test != $count)
+                    : ($test == $count);
+            case self::ASSERT_CONTENT_COUNT_MIN:
+                return ($count >= $test);
+            case self::ASSERT_CONTENT_COUNT_MAX:
+                return ($count <= $test);
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Get node content, minus node markup tags
+     *
+     * @param  DOMNode $node
+     * @return string
+     */
+    protected function _getNodeContent(DOMNode $node)
+    {
+        if ($node instanceof DOMAttr) {
+            return $node->value;
+        } else {
+            $doc     = $node->ownerDocument;
+            $content = $doc->saveXML($node);
+            $tag     = $node->nodeName;
+            $regex   = '|</?' . $tag . '[^>]*>|';
+            return preg_replace($regex, '', $content);
+        }
+    }
+}

+ 6 - 282
library/Zend/Test/PHPUnit/Constraint/Redirect.php

@@ -20,287 +20,11 @@
  * @version    $Id$
  */
 
-/** @see PHPUnit_Framework_Constraint */
-require_once 'PHPUnit/Framework/Constraint.php';
+/** @see PHPUnit_Runner_Version */
+require_once 'PHPUnit/Runner/Version.php';
 
-/**
- * Redirection constraints
- *
- * @uses       PHPUnit_Framework_Constraint
- * @category   Zend
- * @package    Zend_Test
- * @subpackage PHPUnit
- * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
- * @license    http://framework.zend.com/license/new-bsd     New BSD License
- */
-class Zend_Test_PHPUnit_Constraint_Redirect extends PHPUnit_Framework_Constraint
-{
-    /**#@+
-     * Assertion type constants
-     */
-    const ASSERT_REDIRECT       = 'assertRedirect';
-    const ASSERT_REDIRECT_TO    = 'assertRedirectTo';
-    const ASSERT_REDIRECT_REGEX = 'assertRedirectRegex';
-    /**#@-*/
-
-    /**
-     * Current assertion type
-     * @var string
-     */
-    protected $_assertType      = null;
-
-    /**
-     * Available assertion types
-     * @var array
-     */
-    protected $_assertTypes     = array(
-        self::ASSERT_REDIRECT,
-        self::ASSERT_REDIRECT_TO,
-        self::ASSERT_REDIRECT_REGEX,
-    );
-
-    /**
-     * Pattern to match against
-     * @var string
-     */
-    protected $_match             = null;
-    
-    /**
-     * What is actual redirect
-     */
-    protected $_actual            = null;
-
-    /**
-     * Whether or not assertion is negated
-     * @var bool
-     */
-    protected $_negate            = false;
-
-    /**
-     * Constructor; setup constraint state
-     *
-     * @return void
-     */
-    public function __construct()
-    {
-    }
-
-    /**
-     * Indicate negative match
-     *
-     * @param  bool $flag
-     * @return void
-     */
-    public function setNegate($flag = true)
-    {
-        $this->_negate = $flag;
-    }
-
-    /**
-     * Evaluate an object to see if it fits the constraints
-     *
-     * @param  string $other String to examine
-     * @param  null|string Assertion type
-     * @return bool
-     */
-    public function evaluate($other, $assertType = null)
-    {
-        if (!$other instanceof Zend_Controller_Response_Abstract) {
-            require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
-            throw new Zend_Test_PHPUnit_Constraint_Exception('Redirect constraint assertions require a response object');
-        }
-
-        if (strstr($assertType, 'Not')) {
-            $this->setNegate(true);
-            $assertType = str_replace('Not', '', $assertType);
-        }
-
-        if (!in_array($assertType, $this->_assertTypes)) {
-            require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
-            throw new Zend_Test_PHPUnit_Constraint_Exception(sprintf('Invalid assertion type "%s" provided to %s constraint', $assertType, __CLASS__));
-        }
-
-        $this->_assertType = $assertType;
-
-        $response = $other;
-        $argv     = func_get_args();
-        $argc     = func_num_args();
-
-        switch ($assertType) {
-            case self::ASSERT_REDIRECT_TO:
-                if (3 > $argc) {
-                    require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
-                    throw new Zend_Test_PHPUnit_Constraint_Exception('No redirect URL provided against which to match');
-                }
-                $this->_match = $match = $argv[2];
-                return ($this->_negate)
-                    ? $this->_notMatch($response, $match)
-                    : $this->_match($response, $match);
-            case self::ASSERT_REDIRECT_REGEX:
-                if (3 > $argc) {
-                    require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
-                    throw new Zend_Test_PHPUnit_Constraint_Exception('No pattern provided against which to match redirect');
-                }
-                $this->_match = $match = $argv[2];
-                return ($this->_negate)
-                    ? $this->_notRegex($response, $match)
-                    : $this->_regex($response, $match);
-            case self::ASSERT_REDIRECT:
-            default:
-                $headers  = $response->sendHeaders();
-                if (isset($headers['location'])) {
-                    $redirect = $headers['location'];
-                    $redirect = str_replace('Location: ', '', $redirect);
-                    $this->_actual = $redirect;
-                }
-                return ($this->_negate) ? !$response->isRedirect() : $response->isRedirect();
-        }
-    }
-
-    /**
-     * Report Failure
-     *
-     * @see    PHPUnit_Framework_Constraint for implementation details
-     * @param  mixed $other
-     * @param  string $description Additional message to display
-     * @param  bool $not
-     * @return void
-     * @throws PHPUnit_Framework_ExpectationFailedException
-     */
-    public function fail($other, $description, $not = false)
-    {
-        require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
-        switch ($this->_assertType) {
-            case self::ASSERT_REDIRECT_TO:
-                $failure = 'Failed asserting response redirects to "%s"';
-                if ($this->_negate) {
-                    $failure = 'Failed asserting response DOES NOT redirect to "%s"';
-                }
-                $failure = sprintf($failure, $this->_match);
-                if (!$this->_negate && $this->_actual) {
-                    $failure .= sprintf(PHP_EOL . 'It redirects to "%s".', $this->_actual);
-                }
-                break;
-            case self::ASSERT_REDIRECT_REGEX:
-                $failure = 'Failed asserting response redirects to URL MATCHING "%s"';
-                if ($this->_negate) {
-                    $failure = 'Failed asserting response DOES NOT redirect to URL MATCHING "%s"';
-                }
-                $failure = sprintf($failure, $this->_match);
-                if ($this->_actual) {
-                    $failure .= sprintf(PHP_EOL . 'It redirects to "%s".', $this->_actual);
-                }
-                break;
-            case self::ASSERT_REDIRECT:
-            default:
-                $failure = 'Failed asserting response is a redirect';
-                if ($this->_negate) {
-                    $failure = 'Failed asserting response is NOT a redirect';
-                    if ($this->_actual) {
-                        $failure .= sprintf(PHP_EOL . 'It redirects to "%s"', $this->_actual);
-                    }
-                }
-                break;
-        }
-
-        if (!empty($description)) {
-            $failure = $description . "\n" . $failure;
-        }
-
-        throw new Zend_Test_PHPUnit_Constraint_Exception($failure);
-    }
-
-    /**
-     * Complete implementation
-     *
-     * @return string
-     */
-    public function toString()
-    {
-        return '';
-    }
-
-    /**
-     * Check to see if content is matched in selected nodes
-     *
-     * @param  Zend_Controller_Response_HttpTestCase $response
-     * @param  string $match Content to match
-     * @return bool
-     */
-    protected function _match($response, $match)
-    {
-        if (!$response->isRedirect()) {
-            return false;
-        }
-
-        $headers  = $response->sendHeaders();
-        $redirect = $headers['location'];
-        $redirect = str_replace('Location: ', '', $redirect);
-        $this->_actual = $redirect;
-
-        return ($redirect == $match);
-    }
-
-    /**
-     * Check to see if content is NOT matched in selected nodes
-     *
-     * @param  Zend_Controller_Response_HttpTestCase $response
-     * @param  string $match
-     * @return bool
-     */
-    protected function _notMatch($response, $match)
-    {
-        if (!$response->isRedirect()) {
-            return true;
-        }
-
-        $headers  = $response->sendHeaders();
-        $redirect = $headers['location'];
-        $redirect = str_replace('Location: ', '', $redirect);
-        $this->_actual = $redirect;
-
-        return ($redirect != $match);
-    }
-
-    /**
-     * Check to see if content is matched by regex in selected nodes
-     *
-     * @param  Zend_Controller_Response_HttpTestCase $response
-     * @param  string $pattern
-     * @return bool
-     */
-    protected function _regex($response, $pattern)
-    {
-        if (!$response->isRedirect()) {
-            return false;
-        }
-
-        $headers  = $response->sendHeaders();
-        $redirect = $headers['location'];
-        $redirect = str_replace('Location: ', '', $redirect);
-        $this->_actual = $redirect;
-
-        return preg_match($pattern, $redirect);
-    }
-
-    /**
-     * Check to see if content is NOT matched by regex in selected nodes
-     *
-     * @param  Zend_Controller_Response_HttpTestCase $response
-     * @param  string $pattern
-     * @return bool
-     */
-    protected function _notRegex($response, $pattern)
-    {
-        if (!$response->isRedirect()) {
-            return true;
-        }
-
-        $headers  = $response->sendHeaders();
-        $redirect = $headers['location'];
-        $redirect = str_replace('Location: ', '', $redirect);
-        $this->_actual = $redirect;
-
-        return !preg_match($pattern, $redirect);
-    }
+if (version_compare(PHPUnit_Runner_Version::id(), '3.5', '>=')) {
+    include(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Redirect37.php');
+} else {
+    include(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Redirect34.php');
 }

+ 306 - 0
library/Zend/Test/PHPUnit/Constraint/Redirect34.php

@@ -0,0 +1,306 @@
+<?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_Test
+ * @subpackage PHPUnit
+ * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/** @see PHPUnit_Framework_Constraint */
+require_once 'PHPUnit/Framework/Constraint.php';
+
+/**
+ * Redirection constraints
+ *
+ * @uses       PHPUnit_Framework_Constraint
+ * @category   Zend
+ * @package    Zend_Test
+ * @subpackage PHPUnit
+ * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Test_PHPUnit_Constraint_Redirect extends PHPUnit_Framework_Constraint
+{
+    /**#@+
+     * Assertion type constants
+     */
+    const ASSERT_REDIRECT       = 'assertRedirect';
+    const ASSERT_REDIRECT_TO    = 'assertRedirectTo';
+    const ASSERT_REDIRECT_REGEX = 'assertRedirectRegex';
+    /**#@-*/
+
+    /**
+     * Current assertion type
+     * @var string
+     */
+    protected $_assertType      = null;
+
+    /**
+     * Available assertion types
+     * @var array
+     */
+    protected $_assertTypes     = array(
+        self::ASSERT_REDIRECT,
+        self::ASSERT_REDIRECT_TO,
+        self::ASSERT_REDIRECT_REGEX,
+    );
+
+    /**
+     * Pattern to match against
+     * @var string
+     */
+    protected $_match             = null;
+    
+    /**
+     * What is actual redirect
+     */
+    protected $_actual            = null;
+
+    /**
+     * Whether or not assertion is negated
+     * @var bool
+     */
+    protected $_negate            = false;
+
+    /**
+     * Constructor; setup constraint state
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+    }
+
+    /**
+     * Indicate negative match
+     *
+     * @param  bool $flag
+     * @return void
+     */
+    public function setNegate($flag = true)
+    {
+        $this->_negate = $flag;
+    }
+
+    /**
+     * Evaluate an object to see if it fits the constraints
+     *
+     * @param  string $other String to examine
+     * @param  null|string Assertion type
+     * @return bool
+     */
+    public function evaluate($other, $assertType = null)
+    {
+        if (!$other instanceof Zend_Controller_Response_Abstract) {
+            require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
+            throw new Zend_Test_PHPUnit_Constraint_Exception('Redirect constraint assertions require a response object');
+        }
+
+        if (strstr($assertType, 'Not')) {
+            $this->setNegate(true);
+            $assertType = str_replace('Not', '', $assertType);
+        }
+
+        if (!in_array($assertType, $this->_assertTypes)) {
+            require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
+            throw new Zend_Test_PHPUnit_Constraint_Exception(sprintf('Invalid assertion type "%s" provided to %s constraint', $assertType, __CLASS__));
+        }
+
+        $this->_assertType = $assertType;
+
+        $response = $other;
+        $argv     = func_get_args();
+        $argc     = func_num_args();
+
+        switch ($assertType) {
+            case self::ASSERT_REDIRECT_TO:
+                if (3 > $argc) {
+                    require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
+                    throw new Zend_Test_PHPUnit_Constraint_Exception('No redirect URL provided against which to match');
+                }
+                $this->_match = $match = $argv[2];
+                return ($this->_negate)
+                    ? $this->_notMatch($response, $match)
+                    : $this->_match($response, $match);
+            case self::ASSERT_REDIRECT_REGEX:
+                if (3 > $argc) {
+                    require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
+                    throw new Zend_Test_PHPUnit_Constraint_Exception('No pattern provided against which to match redirect');
+                }
+                $this->_match = $match = $argv[2];
+                return ($this->_negate)
+                    ? $this->_notRegex($response, $match)
+                    : $this->_regex($response, $match);
+            case self::ASSERT_REDIRECT:
+            default:
+                $headers  = $response->sendHeaders();
+                if (isset($headers['location'])) {
+                    $redirect = $headers['location'];
+                    $redirect = str_replace('Location: ', '', $redirect);
+                    $this->_actual = $redirect;
+                }
+                return ($this->_negate) ? !$response->isRedirect() : $response->isRedirect();
+        }
+    }
+
+    /**
+     * Report Failure
+     *
+     * @see    PHPUnit_Framework_Constraint for implementation details
+     * @param  mixed $other
+     * @param  string $description Additional message to display
+     * @param  bool $not
+     * @return void
+     * @throws PHPUnit_Framework_ExpectationFailedException
+     */
+    public function fail($other, $description, $not = false)
+    {
+        require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
+        switch ($this->_assertType) {
+            case self::ASSERT_REDIRECT_TO:
+                $failure = 'Failed asserting response redirects to "%s"';
+                if ($this->_negate) {
+                    $failure = 'Failed asserting response DOES NOT redirect to "%s"';
+                }
+                $failure = sprintf($failure, $this->_match);
+                if (!$this->_negate && $this->_actual) {
+                    $failure .= sprintf(PHP_EOL . 'It redirects to "%s".', $this->_actual);
+                }
+                break;
+            case self::ASSERT_REDIRECT_REGEX:
+                $failure = 'Failed asserting response redirects to URL MATCHING "%s"';
+                if ($this->_negate) {
+                    $failure = 'Failed asserting response DOES NOT redirect to URL MATCHING "%s"';
+                }
+                $failure = sprintf($failure, $this->_match);
+                if ($this->_actual) {
+                    $failure .= sprintf(PHP_EOL . 'It redirects to "%s".', $this->_actual);
+                }
+                break;
+            case self::ASSERT_REDIRECT:
+            default:
+                $failure = 'Failed asserting response is a redirect';
+                if ($this->_negate) {
+                    $failure = 'Failed asserting response is NOT a redirect';
+                    if ($this->_actual) {
+                        $failure .= sprintf(PHP_EOL . 'It redirects to "%s"', $this->_actual);
+                    }
+                }
+                break;
+        }
+
+        if (!empty($description)) {
+            $failure = $description . "\n" . $failure;
+        }
+
+        throw new Zend_Test_PHPUnit_Constraint_Exception($failure);
+    }
+
+    /**
+     * Complete implementation
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return '';
+    }
+
+    /**
+     * Check to see if content is matched in selected nodes
+     *
+     * @param  Zend_Controller_Response_HttpTestCase $response
+     * @param  string $match Content to match
+     * @return bool
+     */
+    protected function _match($response, $match)
+    {
+        if (!$response->isRedirect()) {
+            return false;
+        }
+
+        $headers  = $response->sendHeaders();
+        $redirect = $headers['location'];
+        $redirect = str_replace('Location: ', '', $redirect);
+        $this->_actual = $redirect;
+
+        return ($redirect == $match);
+    }
+
+    /**
+     * Check to see if content is NOT matched in selected nodes
+     *
+     * @param  Zend_Controller_Response_HttpTestCase $response
+     * @param  string $match
+     * @return bool
+     */
+    protected function _notMatch($response, $match)
+    {
+        if (!$response->isRedirect()) {
+            return true;
+        }
+
+        $headers  = $response->sendHeaders();
+        $redirect = $headers['location'];
+        $redirect = str_replace('Location: ', '', $redirect);
+        $this->_actual = $redirect;
+
+        return ($redirect != $match);
+    }
+
+    /**
+     * Check to see if content is matched by regex in selected nodes
+     *
+     * @param  Zend_Controller_Response_HttpTestCase $response
+     * @param  string $pattern
+     * @return bool
+     */
+    protected function _regex($response, $pattern)
+    {
+        if (!$response->isRedirect()) {
+            return false;
+        }
+
+        $headers  = $response->sendHeaders();
+        $redirect = $headers['location'];
+        $redirect = str_replace('Location: ', '', $redirect);
+        $this->_actual = $redirect;
+
+        return preg_match($pattern, $redirect);
+    }
+
+    /**
+     * Check to see if content is NOT matched by regex in selected nodes
+     *
+     * @param  Zend_Controller_Response_HttpTestCase $response
+     * @param  string $pattern
+     * @return bool
+     */
+    protected function _notRegex($response, $pattern)
+    {
+        if (!$response->isRedirect()) {
+            return true;
+        }
+
+        $headers  = $response->sendHeaders();
+        $redirect = $headers['location'];
+        $redirect = str_replace('Location: ', '', $redirect);
+        $this->_actual = $redirect;
+
+        return !preg_match($pattern, $redirect);
+    }
+}

+ 318 - 0
library/Zend/Test/PHPUnit/Constraint/Redirect37.php

@@ -0,0 +1,318 @@
+<?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_Test
+ * @subpackage PHPUnit
+ * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/** @see PHPUnit_Framework_Constraint */
+require_once 'PHPUnit/Framework/Constraint.php';
+
+/**
+ * Redirection constraints
+ *
+ * @uses       PHPUnit_Framework_Constraint
+ * @category   Zend
+ * @package    Zend_Test
+ * @subpackage PHPUnit
+ * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Test_PHPUnit_Constraint_Redirect extends PHPUnit_Framework_Constraint
+{
+    /**#@+
+     * Assertion type constants
+     */
+    const ASSERT_REDIRECT       = 'assertRedirect';
+    const ASSERT_REDIRECT_TO    = 'assertRedirectTo';
+    const ASSERT_REDIRECT_REGEX = 'assertRedirectRegex';
+    /**#@-*/
+
+    /**
+     * Current assertion type
+     * @var string
+     */
+    protected $_assertType      = null;
+
+    /**
+     * Available assertion types
+     * @var array
+     */
+    protected $_assertTypes     = array(
+        self::ASSERT_REDIRECT,
+        self::ASSERT_REDIRECT_TO,
+        self::ASSERT_REDIRECT_REGEX,
+    );
+
+    /**
+     * Pattern to match against
+     * @var string
+     */
+    protected $_match             = null;
+    
+    /**
+     * What is actual redirect
+     */
+    protected $_actual            = null;
+
+    /**
+     * Whether or not assertion is negated
+     * @var bool
+     */
+    protected $_negate            = false;
+
+    /**
+     * Constructor; setup constraint state
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+    }
+
+    /**
+     * Indicate negative match
+     *
+     * @param  bool $flag
+     * @return void
+     */
+    public function setNegate($flag = true)
+    {
+        $this->_negate = $flag;
+    }
+
+    /**
+     * Evaluate an object to see if it fits the constraints
+     *
+     * @param  string $other String to examine
+     * @param  null|string Assertion type
+     * @return bool
+     * NOTE:
+     * Drastic changes up to PHPUnit 3.5.15 this was:
+     *     public function evaluate($other, $assertType = null)
+     * In PHPUnit 3.6.0 they changed the interface into this:
+     *     public function evaluate($other, $description = '', $returnResult = FALSE)
+     * We use the new interface for PHP-strict checking, but emulate the old one
+     */
+    public function evaluate($other, $assertType = null, $variable = FALSE)
+    {
+        if (!$other instanceof Zend_Controller_Response_Abstract) {
+            require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
+            throw new Zend_Test_PHPUnit_Constraint_Exception('Redirect constraint assertions require a response object');
+        }
+
+        if (strstr($assertType, 'Not')) {
+            $this->setNegate(true);
+            $assertType = str_replace('Not', '', $assertType);
+        }
+
+        if (!in_array($assertType, $this->_assertTypes)) {
+            require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
+            throw new Zend_Test_PHPUnit_Constraint_Exception(sprintf('Invalid assertion type "%s" provided to %s constraint', $assertType, __CLASS__));
+        }
+
+        $this->_assertType = $assertType;
+
+        $response = $other;
+        $argv     = func_get_args();
+        $argc     = func_num_args();
+
+        switch ($assertType) {
+            case self::ASSERT_REDIRECT_TO:
+                if (3 > $argc) {
+                    require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
+                    throw new Zend_Test_PHPUnit_Constraint_Exception('No redirect URL provided against which to match');
+                }
+                $this->_match = $match = $argv[2];
+                return ($this->_negate)
+                    ? $this->_notMatch($response, $match)
+                    : $this->_match($response, $match);
+            case self::ASSERT_REDIRECT_REGEX:
+                if (3 > $argc) {
+                    require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
+                    throw new Zend_Test_PHPUnit_Constraint_Exception('No pattern provided against which to match redirect');
+                }
+                $this->_match = $match = $argv[2];
+                return ($this->_negate)
+                    ? $this->_notRegex($response, $match)
+                    : $this->_regex($response, $match);
+            case self::ASSERT_REDIRECT:
+            default:
+                $headers  = $response->sendHeaders();
+                if (isset($headers['location'])) {
+                    $redirect = $headers['location'];
+                    $redirect = str_replace('Location: ', '', $redirect);
+                    $this->_actual = $redirect;
+                }
+                return ($this->_negate) ? !$response->isRedirect() : $response->isRedirect();
+        }
+    }
+
+    /**
+     * Report Failure
+     *
+     * @see    PHPUnit_Framework_Constraint for implementation details
+     * @param  mixed $other
+     * @param  string $description Additional message to display
+     * @param  bool $not
+     * @return void
+     * @throws PHPUnit_Framework_ExpectationFailedException
+     * NOTE:
+     * Drastic changes up to PHPUnit 3.5.15 this was:
+     *     public function fail($other, $description, $not = false)
+     * In PHPUnit 3.6.0 they changed the interface into this:
+     *     protected function fail($other, $description, PHPUnit_Framework_ComparisonFailure $comparisonFailure = NULL)
+     * We use the new interface for PHP-strict checking
+     */
+    public function fail($other, $description, PHPUnit_Framework_ComparisonFailure $cannot_be_used = NULL)
+    {
+        require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
+        switch ($this->_assertType) {
+            case self::ASSERT_REDIRECT_TO:
+                $failure = 'Failed asserting response redirects to "%s"';
+                if ($this->_negate) {
+                    $failure = 'Failed asserting response DOES NOT redirect to "%s"';
+                }
+                $failure = sprintf($failure, $this->_match);
+                if (!$this->_negate && $this->_actual) {
+                    $failure .= sprintf(PHP_EOL . 'It redirects to "%s".', $this->_actual);
+                }
+                break;
+            case self::ASSERT_REDIRECT_REGEX:
+                $failure = 'Failed asserting response redirects to URL MATCHING "%s"';
+                if ($this->_negate) {
+                    $failure = 'Failed asserting response DOES NOT redirect to URL MATCHING "%s"';
+                }
+                $failure = sprintf($failure, $this->_match);
+                if ($this->_actual) {
+                    $failure .= sprintf(PHP_EOL . 'It redirects to "%s".', $this->_actual);
+                }
+                break;
+            case self::ASSERT_REDIRECT:
+            default:
+                $failure = 'Failed asserting response is a redirect';
+                if ($this->_negate) {
+                    $failure = 'Failed asserting response is NOT a redirect';
+                    if ($this->_actual) {
+                        $failure .= sprintf(PHP_EOL . 'It redirects to "%s"', $this->_actual);
+                    }
+                }
+                break;
+        }
+
+        if (!empty($description)) {
+            $failure = $description . "\n" . $failure;
+        }
+
+        throw new Zend_Test_PHPUnit_Constraint_Exception($failure);
+    }
+
+    /**
+     * Complete implementation
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return '';
+    }
+
+    /**
+     * Check to see if content is matched in selected nodes
+     *
+     * @param  Zend_Controller_Response_HttpTestCase $response
+     * @param  string $match Content to match
+     * @return bool
+     */
+    protected function _match($response, $match)
+    {
+        if (!$response->isRedirect()) {
+            return false;
+        }
+
+        $headers  = $response->sendHeaders();
+        $redirect = $headers['location'];
+        $redirect = str_replace('Location: ', '', $redirect);
+        $this->_actual = $redirect;
+
+        return ($redirect == $match);
+    }
+
+    /**
+     * Check to see if content is NOT matched in selected nodes
+     *
+     * @param  Zend_Controller_Response_HttpTestCase $response
+     * @param  string $match
+     * @return bool
+     */
+    protected function _notMatch($response, $match)
+    {
+        if (!$response->isRedirect()) {
+            return true;
+        }
+
+        $headers  = $response->sendHeaders();
+        $redirect = $headers['location'];
+        $redirect = str_replace('Location: ', '', $redirect);
+        $this->_actual = $redirect;
+
+        return ($redirect != $match);
+    }
+
+    /**
+     * Check to see if content is matched by regex in selected nodes
+     *
+     * @param  Zend_Controller_Response_HttpTestCase $response
+     * @param  string $pattern
+     * @return bool
+     */
+    protected function _regex($response, $pattern)
+    {
+        if (!$response->isRedirect()) {
+            return false;
+        }
+
+        $headers  = $response->sendHeaders();
+        $redirect = $headers['location'];
+        $redirect = str_replace('Location: ', '', $redirect);
+        $this->_actual = $redirect;
+
+        return preg_match($pattern, $redirect);
+    }
+
+    /**
+     * Check to see if content is NOT matched by regex in selected nodes
+     *
+     * @param  Zend_Controller_Response_HttpTestCase $response
+     * @param  string $pattern
+     * @return bool
+     */
+    protected function _notRegex($response, $pattern)
+    {
+        if (!$response->isRedirect()) {
+            return true;
+        }
+
+        $headers  = $response->sendHeaders();
+        $redirect = $headers['location'];
+        $redirect = str_replace('Location: ', '', $redirect);
+        $this->_actual = $redirect;
+
+        return !preg_match($pattern, $redirect);
+    }
+}

+ 6 - 385
library/Zend/Test/PHPUnit/Constraint/ResponseHeader.php

@@ -20,390 +20,11 @@
  * @version    $Id$
  */
 
-/** @see PHPUnit_Framework_Constraint */
-require_once 'PHPUnit/Framework/Constraint.php';
+/** @see PHPUnit_Runner_Version */
+require_once 'PHPUnit/Runner/Version.php';
 
-/**
- * Response header PHPUnit Constraint
- *
- * @uses       PHPUnit_Framework_Constraint
- * @category   Zend
- * @package    Zend_Test
- * @subpackage PHPUnit
- * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
- * @license    http://framework.zend.com/license/new-bsd     New BSD License
- */
-class Zend_Test_PHPUnit_Constraint_ResponseHeader extends PHPUnit_Framework_Constraint
-{
-    /**#@+
-     * Assertion type constants
-     */
-    const ASSERT_RESPONSE_CODE   = 'assertResponseCode';
-    const ASSERT_HEADER          = 'assertHeader';
-    const ASSERT_HEADER_CONTAINS = 'assertHeaderContains';
-    const ASSERT_HEADER_REGEX    = 'assertHeaderRegex';
-    /**#@-*/
-
-    /**
-     * Current assertion type
-     * @var string
-     */
-    protected $_assertType      = null;
-
-    /**
-     * Available assertion types
-     * @var array
-     */
-    protected $_assertTypes     = array(
-        self::ASSERT_RESPONSE_CODE,
-        self::ASSERT_HEADER,
-        self::ASSERT_HEADER_CONTAINS,
-        self::ASSERT_HEADER_REGEX,
-    );
-
-    /**
-     * @var int Response code
-     */
-    protected $_code              = 200;
-    
-    /**
-     * @var int Actual response code
-     */
-    protected $_actualCode        = null;
-
-    /**
-     * @var string Header
-     */
-    protected $_header            = null;
-
-    /**
-     * @var string pattern against which to compare header content
-     */
-    protected $_match             = null;
-
-    /**
-     * Whether or not assertion is negated
-     * @var bool
-     */
-    protected $_negate            = false;
-
-    /**
-     * Constructor; setup constraint state
-     *
-     * @return void
-     */
-    public function __construct()
-    {
-    }
-
-    /**
-     * Indicate negative match
-     *
-     * @param  bool $flag
-     * @return void
-     */
-    public function setNegate($flag = true)
-    {
-        $this->_negate = $flag;
-    }
-
-    /**
-     * Evaluate an object to see if it fits the constraints
-     *
-     * @param  Zend_Controller_Response_Abstract $other String to examine
-     * @param  null|string Assertion type
-     * @return bool
-     */
-    public function evaluate($other, $assertType = null)
-    {
-        if (!$other instanceof Zend_Controller_Response_Abstract) {
-            require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
-            throw new Zend_Test_PHPUnit_Constraint_Exception('Header constraint assertions require a response object');
-        }
-
-        if (strstr($assertType, 'Not')) {
-            $this->setNegate(true);
-            $assertType = str_replace('Not', '', $assertType);
-        }
-
-        if (!in_array($assertType, $this->_assertTypes)) {
-            require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
-            throw new Zend_Test_PHPUnit_Constraint_Exception(sprintf('Invalid assertion type "%s" provided to %s constraint', $assertType, __CLASS__));
-        }
-
-        $this->_assertType = $assertType;
-
-        $response = $other;
-        $argv     = func_get_args();
-        $argc     = func_num_args();
-
-        switch ($assertType) {
-            case self::ASSERT_RESPONSE_CODE:
-                if (3 > $argc) {
-                    require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
-                    throw new Zend_Test_PHPUnit_Constraint_Exception('No response code provided against which to match');
-                }
-                $this->_code = $code = $argv[2];
-                return ($this->_negate)
-                    ? $this->_notCode($response, $code)
-                    : $this->_code($response, $code);
-            case self::ASSERT_HEADER:
-                if (3 > $argc) {
-                    require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
-                    throw new Zend_Test_PHPUnit_Constraint_Exception('No header provided against which to match');
-                }
-                $this->_header = $header = $argv[2];
-                return ($this->_negate)
-                    ? $this->_notHeader($response, $header)
-                    : $this->_header($response, $header);
-            case self::ASSERT_HEADER_CONTAINS:
-                if (4 > $argc) {
-                    require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
-                    throw new Zend_Test_PHPUnit_Constraint_Exception('Both a header name and content to match are required for ' . __FUNCTION__);
-                }
-                $this->_header = $header = $argv[2];
-                $this->_match  = $match  = $argv[3];
-                return ($this->_negate)
-                    ? $this->_notHeaderContains($response, $header, $match)
-                    : $this->_headerContains($response, $header, $match);
-            case self::ASSERT_HEADER_REGEX:
-                if (4 > $argc) {
-                    require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
-                    throw new Zend_Test_PHPUnit_Constraint_Exception('Both a header name and content to match are required for ' . __FUNCTION__);
-                }
-                $this->_header = $header = $argv[2];
-                $this->_match  = $match  = $argv[3];
-                return ($this->_negate)
-                    ? $this->_notHeaderRegex($response, $header, $match)
-                    : $this->_headerRegex($response, $header, $match);
-            default:
-                require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
-                throw new Zend_Test_PHPUnit_Constraint_Exception('Invalid assertion type ' . __FUNCTION__);
-        }
-    }
-
-    /**
-     * Report Failure
-     *
-     * @see    PHPUnit_Framework_Constraint for implementation details
-     * @param  mixed $other
-     * @param  string $description Additional message to display
-     * @param  bool $not
-     * @return void
-     * @throws PHPUnit_Framework_ExpectationFailedException
-     */
-    public function fail($other, $description, $not = false)
-    {
-        require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
-        switch ($this->_assertType) {
-            case self::ASSERT_RESPONSE_CODE:
-                $failure = 'Failed asserting response code "%s"';
-                if ($this->_negate) {
-                    $failure = 'Failed asserting response code IS NOT "%s"';
-                }
-                $failure = sprintf($failure, $this->_code);
-                if (!$this->_negate && $this->_actualCode) {
-                    $failure .= sprintf(PHP_EOL . 'Was "%s"', $this->_actualCode);
-                }
-                break;
-            case self::ASSERT_HEADER:
-                $failure = 'Failed asserting response header "%s" found';
-                if ($this->_negate) {
-                    $failure = 'Failed asserting response response header "%s" WAS NOT found';
-                }
-                $failure = sprintf($failure, $this->_header);
-                break;
-            case self::ASSERT_HEADER_CONTAINS:
-                $failure = 'Failed asserting response header "%s" exists and contains "%s"';
-                if ($this->_negate) {
-                    $failure = 'Failed asserting response header "%s" DOES NOT CONTAIN "%s"';
-                }
-                $failure = sprintf($failure, $this->_header, $this->_match);
-                break;
-            case self::ASSERT_HEADER_REGEX:
-                $failure = 'Failed asserting response header "%s" exists and matches regex "%s"';
-                if ($this->_negate) {
-                    $failure = 'Failed asserting response header "%s" DOES NOT MATCH regex "%s"';
-                }
-                $failure = sprintf($failure, $this->_header, $this->_match);
-                break;
-            default:
-                throw new Zend_Test_PHPUnit_Constraint_Exception('Invalid assertion type ' . __FUNCTION__);
-        }
-
-        if (!empty($description)) {
-            $failure = $description . "\n" . $failure;
-        }
-
-        throw new Zend_Test_PHPUnit_Constraint_Exception($failure);
-    }
-
-    /**
-     * Complete implementation
-     *
-     * @return string
-     */
-    public function toString()
-    {
-        return '';
-    }
-
-    /**
-     * Compare response code for positive match
-     *
-     * @param  Zend_Controller_Response_Abstract $response
-     * @param  int $code
-     * @return bool
-     */
-    protected function _code(Zend_Controller_Response_Abstract $response, $code)
-    {
-        $test = $this->_getCode($response);
-        $this->_actualCode = $test;
-        return ($test == $code);
-    }
-
-    /**
-     * Compare response code for negative match
-     *
-     * @param  Zend_Controller_Response_Abstract $response
-     * @param  int $code
-     * @return bool
-     */
-    protected function _notCode(Zend_Controller_Response_Abstract $response, $code)
-    {
-        $test = $this->_getCode($response);
-        return ($test != $code);
-    }
-
-    /**
-     * Retrieve response code
-     *
-     * @param  Zend_Controller_Response_Abstract $response
-     * @return int
-     */
-    protected function _getCode(Zend_Controller_Response_Abstract $response)
-    {
-        $test = $response->getHttpResponseCode();
-        if (null === $test) {
-            $test = 200;
-        }
-        return $test;
-    }
-
-    /**
-     * Positive check for response header presence
-     *
-     * @param  Zend_Controller_Response_Abstract $response
-     * @param  string $header
-     * @return bool
-     */
-    protected function _header(Zend_Controller_Response_Abstract $response, $header)
-    {
-        return (null !== $this->_getHeader($response, $header));
-    }
-
-    /**
-     * Negative check for response header presence
-     *
-     * @param  Zend_Controller_Response_Abstract $response
-     * @param  string $header
-     * @return bool
-     */
-    protected function _notHeader(Zend_Controller_Response_Abstract $response, $header)
-    {
-        return (null === $this->_getHeader($response, $header));
-    }
-
-    /**
-     * Retrieve response header
-     *
-     * @param  Zend_Controller_Response_Abstract $response
-     * @param  string $header
-     * @return string|null
-     */
-    protected function _getHeader(Zend_Controller_Response_Abstract $response, $header)
-    {
-        $headers = $response->sendHeaders();
-        $header  = strtolower($header);
-        if (array_key_exists($header, $headers)) {
-            return $headers[$header];
-        }
-        return null;
-    }
-
-    /**
-     * Positive check for header contents matching pattern
-     *
-     * @param  Zend_Controller_Response_Abstract $response
-     * @param  string $header
-     * @param  string $match
-     * @return bool
-     */
-    protected function _headerContains(Zend_Controller_Response_Abstract $response, $header, $match)
-    {
-        if (null === ($fullHeader = $this->_getHeader($response, $header))) {
-            return false;
-        }
-
-        $contents = str_replace($header . ': ', '', $fullHeader);
-
-        return (strstr($contents, $match) !== false);
-    }
-
-    /**
-     * Negative check for header contents matching pattern
-     *
-     * @param  Zend_Controller_Response_Abstract $response
-     * @param  string $header
-     * @param  string $match
-     * @return bool
-     */
-    protected function _notHeaderContains(Zend_Controller_Response_Abstract $response, $header, $match)
-    {
-        if (null === ($fullHeader = $this->_getHeader($response, $header))) {
-            return true;
-        }
-
-        $contents = str_replace($header . ': ', '', $fullHeader);
-
-        return (strstr($contents, $match) === false);
-    }
-
-    /**
-     * Positive check for header contents matching regex
-     *
-     * @param  Zend_Controller_Response_Abstract $response
-     * @param  string $header
-     * @param  string $pattern
-     * @return bool
-     */
-    protected function _headerRegex(Zend_Controller_Response_Abstract $response, $header, $pattern)
-    {
-        if (null === ($fullHeader = $this->_getHeader($response, $header))) {
-            return false;
-        }
-
-        $contents = str_replace($header . ': ', '', $fullHeader);
-
-        return preg_match($pattern, $contents);
-    }
-
-    /**
-     * Negative check for header contents matching regex
-     *
-     * @param  Zend_Controller_Response_Abstract $response
-     * @param  string $header
-     * @param  string $pattern
-     * @return bool
-     */
-    protected function _notHeaderRegex(Zend_Controller_Response_Abstract $response, $header, $pattern)
-    {
-        if (null === ($fullHeader = $this->_getHeader($response, $header))) {
-            return true;
-        }
-
-        $contents = str_replace($header . ': ', '', $fullHeader);
-
-        return !preg_match($pattern, $contents);
-    }
+if (version_compare(PHPUnit_Runner_Version::id(), '3.5', '>=')) {
+    include(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'ResponseHeader37.php');
+} else {
+    include(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'ResponseHeader34.php');
 }

+ 409 - 0
library/Zend/Test/PHPUnit/Constraint/ResponseHeader34.php

@@ -0,0 +1,409 @@
+<?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_Test
+ * @subpackage PHPUnit
+ * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/** @see PHPUnit_Framework_Constraint */
+require_once 'PHPUnit/Framework/Constraint.php';
+
+/**
+ * Response header PHPUnit Constraint
+ *
+ * @uses       PHPUnit_Framework_Constraint
+ * @category   Zend
+ * @package    Zend_Test
+ * @subpackage PHPUnit
+ * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Test_PHPUnit_Constraint_ResponseHeader extends PHPUnit_Framework_Constraint
+{
+    /**#@+
+     * Assertion type constants
+     */
+    const ASSERT_RESPONSE_CODE   = 'assertResponseCode';
+    const ASSERT_HEADER          = 'assertHeader';
+    const ASSERT_HEADER_CONTAINS = 'assertHeaderContains';
+    const ASSERT_HEADER_REGEX    = 'assertHeaderRegex';
+    /**#@-*/
+
+    /**
+     * Current assertion type
+     * @var string
+     */
+    protected $_assertType      = null;
+
+    /**
+     * Available assertion types
+     * @var array
+     */
+    protected $_assertTypes     = array(
+        self::ASSERT_RESPONSE_CODE,
+        self::ASSERT_HEADER,
+        self::ASSERT_HEADER_CONTAINS,
+        self::ASSERT_HEADER_REGEX,
+    );
+
+    /**
+     * @var int Response code
+     */
+    protected $_code              = 200;
+    
+    /**
+     * @var int Actual response code
+     */
+    protected $_actualCode        = null;
+
+    /**
+     * @var string Header
+     */
+    protected $_header            = null;
+
+    /**
+     * @var string pattern against which to compare header content
+     */
+    protected $_match             = null;
+
+    /**
+     * Whether or not assertion is negated
+     * @var bool
+     */
+    protected $_negate            = false;
+
+    /**
+     * Constructor; setup constraint state
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+    }
+
+    /**
+     * Indicate negative match
+     *
+     * @param  bool $flag
+     * @return void
+     */
+    public function setNegate($flag = true)
+    {
+        $this->_negate = $flag;
+    }
+
+    /**
+     * Evaluate an object to see if it fits the constraints
+     *
+     * @param  Zend_Controller_Response_Abstract $other String to examine
+     * @param  null|string Assertion type
+     * @return bool
+     */
+    public function evaluate($other, $assertType = null)
+    {
+        if (!$other instanceof Zend_Controller_Response_Abstract) {
+            require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
+            throw new Zend_Test_PHPUnit_Constraint_Exception('Header constraint assertions require a response object');
+        }
+
+        if (strstr($assertType, 'Not')) {
+            $this->setNegate(true);
+            $assertType = str_replace('Not', '', $assertType);
+        }
+
+        if (!in_array($assertType, $this->_assertTypes)) {
+            require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
+            throw new Zend_Test_PHPUnit_Constraint_Exception(sprintf('Invalid assertion type "%s" provided to %s constraint', $assertType, __CLASS__));
+        }
+
+        $this->_assertType = $assertType;
+
+        $response = $other;
+        $argv     = func_get_args();
+        $argc     = func_num_args();
+
+        switch ($assertType) {
+            case self::ASSERT_RESPONSE_CODE:
+                if (3 > $argc) {
+                    require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
+                    throw new Zend_Test_PHPUnit_Constraint_Exception('No response code provided against which to match');
+                }
+                $this->_code = $code = $argv[2];
+                return ($this->_negate)
+                    ? $this->_notCode($response, $code)
+                    : $this->_code($response, $code);
+            case self::ASSERT_HEADER:
+                if (3 > $argc) {
+                    require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
+                    throw new Zend_Test_PHPUnit_Constraint_Exception('No header provided against which to match');
+                }
+                $this->_header = $header = $argv[2];
+                return ($this->_negate)
+                    ? $this->_notHeader($response, $header)
+                    : $this->_header($response, $header);
+            case self::ASSERT_HEADER_CONTAINS:
+                if (4 > $argc) {
+                    require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
+                    throw new Zend_Test_PHPUnit_Constraint_Exception('Both a header name and content to match are required for ' . __FUNCTION__);
+                }
+                $this->_header = $header = $argv[2];
+                $this->_match  = $match  = $argv[3];
+                return ($this->_negate)
+                    ? $this->_notHeaderContains($response, $header, $match)
+                    : $this->_headerContains($response, $header, $match);
+            case self::ASSERT_HEADER_REGEX:
+                if (4 > $argc) {
+                    require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
+                    throw new Zend_Test_PHPUnit_Constraint_Exception('Both a header name and content to match are required for ' . __FUNCTION__);
+                }
+                $this->_header = $header = $argv[2];
+                $this->_match  = $match  = $argv[3];
+                return ($this->_negate)
+                    ? $this->_notHeaderRegex($response, $header, $match)
+                    : $this->_headerRegex($response, $header, $match);
+            default:
+                require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
+                throw new Zend_Test_PHPUnit_Constraint_Exception('Invalid assertion type ' . __FUNCTION__);
+        }
+    }
+
+    /**
+     * Report Failure
+     *
+     * @see    PHPUnit_Framework_Constraint for implementation details
+     * @param  mixed $other
+     * @param  string $description Additional message to display
+     * @param  bool $not
+     * @return void
+     * @throws PHPUnit_Framework_ExpectationFailedException
+     */
+    public function fail($other, $description, $not = false)
+    {
+        require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
+        switch ($this->_assertType) {
+            case self::ASSERT_RESPONSE_CODE:
+                $failure = 'Failed asserting response code "%s"';
+                if ($this->_negate) {
+                    $failure = 'Failed asserting response code IS NOT "%s"';
+                }
+                $failure = sprintf($failure, $this->_code);
+                if (!$this->_negate && $this->_actualCode) {
+                    $failure .= sprintf(PHP_EOL . 'Was "%s"', $this->_actualCode);
+                }
+                break;
+            case self::ASSERT_HEADER:
+                $failure = 'Failed asserting response header "%s" found';
+                if ($this->_negate) {
+                    $failure = 'Failed asserting response response header "%s" WAS NOT found';
+                }
+                $failure = sprintf($failure, $this->_header);
+                break;
+            case self::ASSERT_HEADER_CONTAINS:
+                $failure = 'Failed asserting response header "%s" exists and contains "%s"';
+                if ($this->_negate) {
+                    $failure = 'Failed asserting response header "%s" DOES NOT CONTAIN "%s"';
+                }
+                $failure = sprintf($failure, $this->_header, $this->_match);
+                break;
+            case self::ASSERT_HEADER_REGEX:
+                $failure = 'Failed asserting response header "%s" exists and matches regex "%s"';
+                if ($this->_negate) {
+                    $failure = 'Failed asserting response header "%s" DOES NOT MATCH regex "%s"';
+                }
+                $failure = sprintf($failure, $this->_header, $this->_match);
+                break;
+            default:
+                throw new Zend_Test_PHPUnit_Constraint_Exception('Invalid assertion type ' . __FUNCTION__);
+        }
+
+        if (!empty($description)) {
+            $failure = $description . "\n" . $failure;
+        }
+
+        throw new Zend_Test_PHPUnit_Constraint_Exception($failure);
+    }
+
+    /**
+     * Complete implementation
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return '';
+    }
+
+    /**
+     * Compare response code for positive match
+     *
+     * @param  Zend_Controller_Response_Abstract $response
+     * @param  int $code
+     * @return bool
+     */
+    protected function _code(Zend_Controller_Response_Abstract $response, $code)
+    {
+        $test = $this->_getCode($response);
+        $this->_actualCode = $test;
+        return ($test == $code);
+    }
+
+    /**
+     * Compare response code for negative match
+     *
+     * @param  Zend_Controller_Response_Abstract $response
+     * @param  int $code
+     * @return bool
+     */
+    protected function _notCode(Zend_Controller_Response_Abstract $response, $code)
+    {
+        $test = $this->_getCode($response);
+        return ($test != $code);
+    }
+
+    /**
+     * Retrieve response code
+     *
+     * @param  Zend_Controller_Response_Abstract $response
+     * @return int
+     */
+    protected function _getCode(Zend_Controller_Response_Abstract $response)
+    {
+        $test = $response->getHttpResponseCode();
+        if (null === $test) {
+            $test = 200;
+        }
+        return $test;
+    }
+
+    /**
+     * Positive check for response header presence
+     *
+     * @param  Zend_Controller_Response_Abstract $response
+     * @param  string $header
+     * @return bool
+     */
+    protected function _header(Zend_Controller_Response_Abstract $response, $header)
+    {
+        return (null !== $this->_getHeader($response, $header));
+    }
+
+    /**
+     * Negative check for response header presence
+     *
+     * @param  Zend_Controller_Response_Abstract $response
+     * @param  string $header
+     * @return bool
+     */
+    protected function _notHeader(Zend_Controller_Response_Abstract $response, $header)
+    {
+        return (null === $this->_getHeader($response, $header));
+    }
+
+    /**
+     * Retrieve response header
+     *
+     * @param  Zend_Controller_Response_Abstract $response
+     * @param  string $header
+     * @return string|null
+     */
+    protected function _getHeader(Zend_Controller_Response_Abstract $response, $header)
+    {
+        $headers = $response->sendHeaders();
+        $header  = strtolower($header);
+        if (array_key_exists($header, $headers)) {
+            return $headers[$header];
+        }
+        return null;
+    }
+
+    /**
+     * Positive check for header contents matching pattern
+     *
+     * @param  Zend_Controller_Response_Abstract $response
+     * @param  string $header
+     * @param  string $match
+     * @return bool
+     */
+    protected function _headerContains(Zend_Controller_Response_Abstract $response, $header, $match)
+    {
+        if (null === ($fullHeader = $this->_getHeader($response, $header))) {
+            return false;
+        }
+
+        $contents = str_replace($header . ': ', '', $fullHeader);
+
+        return (strstr($contents, $match) !== false);
+    }
+
+    /**
+     * Negative check for header contents matching pattern
+     *
+     * @param  Zend_Controller_Response_Abstract $response
+     * @param  string $header
+     * @param  string $match
+     * @return bool
+     */
+    protected function _notHeaderContains(Zend_Controller_Response_Abstract $response, $header, $match)
+    {
+        if (null === ($fullHeader = $this->_getHeader($response, $header))) {
+            return true;
+        }
+
+        $contents = str_replace($header . ': ', '', $fullHeader);
+
+        return (strstr($contents, $match) === false);
+    }
+
+    /**
+     * Positive check for header contents matching regex
+     *
+     * @param  Zend_Controller_Response_Abstract $response
+     * @param  string $header
+     * @param  string $pattern
+     * @return bool
+     */
+    protected function _headerRegex(Zend_Controller_Response_Abstract $response, $header, $pattern)
+    {
+        if (null === ($fullHeader = $this->_getHeader($response, $header))) {
+            return false;
+        }
+
+        $contents = str_replace($header . ': ', '', $fullHeader);
+
+        return preg_match($pattern, $contents);
+    }
+
+    /**
+     * Negative check for header contents matching regex
+     *
+     * @param  Zend_Controller_Response_Abstract $response
+     * @param  string $header
+     * @param  string $pattern
+     * @return bool
+     */
+    protected function _notHeaderRegex(Zend_Controller_Response_Abstract $response, $header, $pattern)
+    {
+        if (null === ($fullHeader = $this->_getHeader($response, $header))) {
+            return true;
+        }
+
+        $contents = str_replace($header . ': ', '', $fullHeader);
+
+        return !preg_match($pattern, $contents);
+    }
+}

+ 422 - 0
library/Zend/Test/PHPUnit/Constraint/ResponseHeader37.php

@@ -0,0 +1,422 @@
+<?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_Test
+ * @subpackage PHPUnit
+ * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/** @see PHPUnit_Framework_Constraint */
+require_once 'PHPUnit/Framework/Constraint.php';
+
+/**
+ * Response header PHPUnit Constraint
+ *
+ * @uses       PHPUnit_Framework_Constraint
+ * @category   Zend
+ * @package    Zend_Test
+ * @subpackage PHPUnit
+ * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Test_PHPUnit_Constraint_ResponseHeader extends PHPUnit_Framework_Constraint
+{
+    /**#@+
+     * Assertion type constants
+     */
+    const ASSERT_RESPONSE_CODE   = 'assertResponseCode';
+    const ASSERT_HEADER          = 'assertHeader';
+    const ASSERT_HEADER_CONTAINS = 'assertHeaderContains';
+    const ASSERT_HEADER_REGEX    = 'assertHeaderRegex';
+    /**#@-*/
+
+    /**
+     * Current assertion type
+     * @var string
+     */
+    protected $_assertType      = null;
+
+    /**
+     * Available assertion types
+     * @var array
+     */
+    protected $_assertTypes     = array(
+        self::ASSERT_RESPONSE_CODE,
+        self::ASSERT_HEADER,
+        self::ASSERT_HEADER_CONTAINS,
+        self::ASSERT_HEADER_REGEX,
+    );
+
+    /**
+     * @var int Response code
+     */
+    protected $_code              = 200;
+    
+    /**
+     * @var int Actual response code
+     */
+    protected $_actualCode        = null;
+
+    /**
+     * @var string Header
+     */
+    protected $_header            = null;
+
+    /**
+     * @var string pattern against which to compare header content
+     */
+    protected $_match             = null;
+
+    /**
+     * Whether or not assertion is negated
+     * @var bool
+     */
+    protected $_negate            = false;
+
+    /**
+     * Constructor; setup constraint state
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+    }
+
+    /**
+     * Indicate negative match
+     *
+     * @param  bool $flag
+     * @return void
+     */
+    public function setNegate($flag = true)
+    {
+        $this->_negate = $flag;
+    }
+
+    /**
+     * Evaluate an object to see if it fits the constraints
+     *
+     * @param  object       of Zend_Controller_Response_Abstract to be evaluated
+     * @param  null|string  Assertion type
+     * @param  int|string   HTTP response code to evaluate against | header string (haystack)
+     * @param  string       (optional) match (needle), may be required depending on assertion type
+     * @return bool
+     * NOTE:
+     * Drastic changes up to PHPUnit 3.5.15 this was:
+     *     public function evaluate($other, $assertType = null)
+     * In PHPUnit 3.6.0 they changed the interface into this:
+     *     public function evaluate($other, $description = '', $returnResult = FALSE)
+     * We use the new interface for PHP-strict checking, but emulate the old one
+     */
+    public function evaluate($response, $assertType = '', $variable = FALSE)
+    {
+        if (!$response instanceof Zend_Controller_Response_Abstract) {
+            require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
+            throw new Zend_Test_PHPUnit_Constraint_Exception('Header constraint assertions require a response object');
+        }
+
+        if (strstr($assertType, 'Not')) {
+            $this->setNegate(true);
+            $assertType = str_replace('Not', '', $assertType);
+        }
+
+        if (!in_array($assertType, $this->_assertTypes)) {
+            require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
+            throw new Zend_Test_PHPUnit_Constraint_Exception(sprintf('Invalid assertion type "%s" provided to %s constraint', $assertType, __CLASS__));
+        }
+
+        $this->_assertType = $assertType;
+
+        $argv     = func_get_args();
+        $argc     = func_num_args();
+
+        switch ($assertType) {
+            case self::ASSERT_RESPONSE_CODE:
+                if (3 > $argc) {
+                    require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
+                    throw new Zend_Test_PHPUnit_Constraint_Exception('No response code provided against which to match');
+                }
+                $this->_code = $code = $argv[2];
+                return ($this->_negate)
+                    ? $this->_notCode($response, $code)
+                    : $this->_code($response, $code);
+            case self::ASSERT_HEADER:
+                if (3 > $argc) {
+                    require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
+                    throw new Zend_Test_PHPUnit_Constraint_Exception('No header provided against which to match');
+                }
+                $this->_header = $header = $argv[2];
+                return ($this->_negate)
+                    ? $this->_notHeader($response, $header)
+                    : $this->_header($response, $header);
+            case self::ASSERT_HEADER_CONTAINS:
+                if (4 > $argc) {
+                    require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
+                    throw new Zend_Test_PHPUnit_Constraint_Exception('Both a header name and content to match are required for ' . $assertType);
+                }
+                $this->_header = $header = $argv[2];
+                $this->_match  = $match  = $argv[3];
+                return ($this->_negate)
+                    ? $this->_notHeaderContains($response, $header, $match)
+                    : $this->_headerContains($response, $header, $match);
+            case self::ASSERT_HEADER_REGEX:
+                if (4 > $argc) {
+                    require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
+                    throw new Zend_Test_PHPUnit_Constraint_Exception('Both a header name and content to match are required for ' . $assertType);
+                }
+                $this->_header = $header = $argv[2];
+                $this->_match  = $match  = $argv[3];
+                return ($this->_negate)
+                    ? $this->_notHeaderRegex($response, $header, $match)
+                    : $this->_headerRegex($response, $header, $match);
+            default:
+                require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
+                throw new Zend_Test_PHPUnit_Constraint_Exception('Invalid assertion type ' . $assertType);
+        }
+    }
+
+    /**
+     * Report Failure
+     *
+     * @see    PHPUnit_Framework_Constraint for implementation details
+     * @param  mixed    CSS selector path
+     * @param  string   Failure description
+     * @param  object   Cannot be used, null
+     * @return void
+     * @throws PHPUnit_Framework_ExpectationFailedException
+     * NOTE:
+     * Drastic changes up to PHPUnit 3.5.15 this was:
+     *     public function fail($other, $description, $not = false)
+     * In PHPUnit 3.6.0 they changed the interface into this:
+     *     protected function fail($other, $description, PHPUnit_Framework_ComparisonFailure $comparisonFailure = NULL)
+     * We use the new interface for PHP-strict checking
+     */
+    public function fail($other, $description, PHPUnit_Framework_ComparisonFailure $cannot_be_used = NULL)
+    {
+        require_once 'Zend/Test/PHPUnit/Constraint/Exception.php';
+        switch ($this->_assertType) {
+            case self::ASSERT_RESPONSE_CODE:
+                $failure = 'Failed asserting response code "%s"';
+                if ($this->_negate) {
+                    $failure = 'Failed asserting response code IS NOT "%s"';
+                }
+                $failure = sprintf($failure, $this->_code);
+                if (!$this->_negate && $this->_actualCode) {
+                    $failure .= sprintf(PHP_EOL . 'Was "%s"', $this->_actualCode);
+                }
+                break;
+            case self::ASSERT_HEADER:
+                $failure = 'Failed asserting response header "%s" found';
+                if ($this->_negate) {
+                    $failure = 'Failed asserting response response header "%s" WAS NOT found';
+                }
+                $failure = sprintf($failure, $this->_header);
+                break;
+            case self::ASSERT_HEADER_CONTAINS:
+                $failure = 'Failed asserting response header "%s" exists and contains "%s"';
+                if ($this->_negate) {
+                    $failure = 'Failed asserting response header "%s" DOES NOT CONTAIN "%s"';
+                }
+                $failure = sprintf($failure, $this->_header, $this->_match);
+                break;
+            case self::ASSERT_HEADER_REGEX:
+                $failure = 'Failed asserting response header "%s" exists and matches regex "%s"';
+                if ($this->_negate) {
+                    $failure = 'Failed asserting response header "%s" DOES NOT MATCH regex "%s"';
+                }
+                $failure = sprintf($failure, $this->_header, $this->_match);
+                break;
+            default:
+                throw new Zend_Test_PHPUnit_Constraint_Exception('Invalid assertion type ' . __FUNCTION__);
+        }
+
+        if (!empty($description)) {
+            $failure = $description . "\n" . $failure;
+        }
+
+        throw new Zend_Test_PHPUnit_Constraint_Exception($failure);
+    }
+
+    /**
+     * Complete implementation
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return '';
+    }
+
+    /**
+     * Compare response code for positive match
+     *
+     * @param  Zend_Controller_Response_Abstract $response
+     * @param  int $code
+     * @return bool
+     */
+    protected function _code(Zend_Controller_Response_Abstract $response, $code)
+    {
+        $test = $this->_getCode($response);
+        $this->_actualCode = $test;
+        return ($test == $code);
+    }
+
+    /**
+     * Compare response code for negative match
+     *
+     * @param  Zend_Controller_Response_Abstract $response
+     * @param  int $code
+     * @return bool
+     */
+    protected function _notCode(Zend_Controller_Response_Abstract $response, $code)
+    {
+        $test = $this->_getCode($response);
+        return ($test != $code);
+    }
+
+    /**
+     * Retrieve response code
+     *
+     * @param  Zend_Controller_Response_Abstract $response
+     * @return int
+     */
+    protected function _getCode(Zend_Controller_Response_Abstract $response)
+    {
+        $test = $response->getHttpResponseCode();
+        if (null === $test) {
+            $test = 200;
+        }
+        return $test;
+    }
+
+    /**
+     * Positive check for response header presence
+     *
+     * @param  Zend_Controller_Response_Abstract $response
+     * @param  string $header
+     * @return bool
+     */
+    protected function _header(Zend_Controller_Response_Abstract $response, $header)
+    {
+        return (null !== $this->_getHeader($response, $header));
+    }
+
+    /**
+     * Negative check for response header presence
+     *
+     * @param  Zend_Controller_Response_Abstract $response
+     * @param  string $header
+     * @return bool
+     */
+    protected function _notHeader(Zend_Controller_Response_Abstract $response, $header)
+    {
+        return (null === $this->_getHeader($response, $header));
+    }
+
+    /**
+     * Retrieve response header
+     *
+     * @param  Zend_Controller_Response_Abstract $response
+     * @param  string $header
+     * @return string|null
+     */
+    protected function _getHeader(Zend_Controller_Response_Abstract $response, $header)
+    {
+        $headers = $response->sendHeaders();
+        $header  = strtolower($header);
+        if (array_key_exists($header, $headers)) {
+            return $headers[$header];
+        }
+        return null;
+    }
+
+    /**
+     * Positive check for header contents matching pattern
+     *
+     * @param  Zend_Controller_Response_Abstract $response
+     * @param  string $header
+     * @param  string $match
+     * @return bool
+     */
+    protected function _headerContains(Zend_Controller_Response_Abstract $response, $header, $match)
+    {
+        if (null === ($fullHeader = $this->_getHeader($response, $header))) {
+            return false;
+        }
+
+        $contents = str_replace($header . ': ', '', $fullHeader);
+
+        return (strstr($contents, $match) !== false);
+    }
+
+    /**
+     * Negative check for header contents matching pattern
+     *
+     * @param  Zend_Controller_Response_Abstract $response
+     * @param  string $header
+     * @param  string $match
+     * @return bool
+     */
+    protected function _notHeaderContains(Zend_Controller_Response_Abstract $response, $header, $match)
+    {
+        if (null === ($fullHeader = $this->_getHeader($response, $header))) {
+            return true;
+        }
+
+        $contents = str_replace($header . ': ', '', $fullHeader);
+
+        return (strstr($contents, $match) === false);
+    }
+
+    /**
+     * Positive check for header contents matching regex
+     *
+     * @param  Zend_Controller_Response_Abstract $response
+     * @param  string $header
+     * @param  string $pattern
+     * @return bool
+     */
+    protected function _headerRegex(Zend_Controller_Response_Abstract $response, $header, $pattern)
+    {
+        if (null === ($fullHeader = $this->_getHeader($response, $header))) {
+            return false;
+        }
+
+        $contents = str_replace($header . ': ', '', $fullHeader);
+
+        return preg_match($pattern, $contents);
+    }
+
+    /**
+     * Negative check for header contents matching regex
+     *
+     * @param  Zend_Controller_Response_Abstract $response
+     * @param  string $header
+     * @param  string $pattern
+     * @return bool
+     */
+    protected function _notHeaderRegex(Zend_Controller_Response_Abstract $response, $header, $pattern)
+    {
+        if (null === ($fullHeader = $this->_getHeader($response, $header))) {
+            return true;
+        }
+
+        $contents = str_replace($header . ': ', '', $fullHeader);
+
+        return !preg_match($pattern, $contents);
+    }
+}

+ 21 - 1
library/Zend/Test/PHPUnit/Db/Metadata/Generic.php

@@ -164,4 +164,24 @@ class Zend_Test_PHPUnit_Db_Metadata_Generic implements PHPUnit_Extensions_Databa
     {
         return false;
     }
-}
+
+    /**
+     * Disables primary keys if rdbms does not allow setting them otherwise
+     *
+     * @param string $tableName
+     */
+    public function disablePrimaryKeys($tableName)
+    {
+        // Implemented only to match new DBUnit interface
+    }
+
+    /**
+     * Reenables primary keys after they have been disabled
+     *
+     * @param string $tableName
+     */
+    public function enablePrimaryKeys($tableName)
+    {
+        // Implemented only to match new DBUnit interface
+    }
+}