[ Index ]

PHP Cross Reference of Limb3

title

Body

[close]

/tests_runner/lib/simpletest/ -> web_tester.php (source)

   1  <?php
   2      /**

   3       *    Base include file for SimpleTest.

   4       *    @package    SimpleTest

   5       *    @subpackage    WebTester

   6       *    @version    $Id: web_tester.php 5999 2007-06-18 13:13:08Z pachanga $

   7       */
   8  
   9      /**#@+

  10       *    include other SimpleTest class files

  11       */
  12      require_once(dirname(__FILE__) . '/test_case.php');
  13      require_once(dirname(__FILE__) . '/browser.php');
  14      require_once(dirname(__FILE__) . '/page.php');
  15      require_once(dirname(__FILE__) . '/expectation.php');
  16      /**#@-*/

  17      
  18      /**

  19       *    Test for an HTML widget value match.

  20       *      @package SimpleTest

  21       *      @subpackage WebTester

  22       */
  23      class FieldExpectation extends SimpleExpectation {
  24          var $_value;
  25          
  26          /**

  27           *    Sets the field value to compare against.

  28           *    @param mixed $value     Test value to match. Can be an

  29           *                            expectation for say pattern matching.

  30           *    @param string $message  Optiona message override. Can use %s as

  31           *                            a placeholder for the original message.

  32           *    @access public

  33           */
  34          function FieldExpectation($value, $message = '%s') {
  35              $this->SimpleExpectation($message);
  36              if (is_array($value)) {
  37                  sort($value);
  38              }
  39              $this->_value = $value;
  40          }
  41          
  42          /**

  43           *    Tests the expectation. True if it matches

  44           *    a string value or an array value in any order.

  45           *    @param mixed $compare        Comparison value. False for

  46           *                                 an unset field.

  47           *    @return boolean              True if correct.

  48           *    @access public

  49           */
  50          function test($compare) {
  51              if ($this->_value === false) {
  52                  return ($compare === false);
  53              }
  54              if ($this->_isSingle($this->_value)) {
  55                  return $this->_testSingle($compare);
  56              }
  57              if (is_array($this->_value)) {
  58                  return $this->_testMultiple($compare);
  59              }
  60              return false;
  61          }
  62          
  63          /**

  64           *    Tests for valid field comparisons with a single option.

  65           *    @param mixed $value       Value to type check.

  66           *    @return boolean           True if integer, string or float.

  67           *    @access private

  68           */
  69          function _isSingle($value) {
  70              return is_string($value) || is_integer($value) || is_float($value);
  71          }
  72          
  73          /**

  74           *    String comparison for simple field with a single option.

  75           *    @param mixed $compare    String to test against.

  76           *    @returns boolean         True if matching.

  77           *    @access private

  78           */
  79          function _testSingle($compare) {
  80              if (is_array($compare) && count($compare) == 1) {
  81                  $compare = $compare[0];
  82              }
  83              if (! $this->_isSingle($compare)) {
  84                  return false;
  85              }
  86              return ($this->_value == $compare);
  87          }
  88          
  89          /**

  90           *    List comparison for multivalue field.

  91           *    @param mixed $compare    List in any order to test against.

  92           *    @returns boolean         True if matching.

  93           *    @access private

  94           */
  95          function _testMultiple($compare) {
  96              if (is_string($compare)) {
  97                  $compare = array($compare);
  98              }
  99              if (! is_array($compare)) {
 100                  return false;
 101              }
 102              sort($compare);
 103              return ($this->_value === $compare);
 104          }
 105          
 106          /**

 107           *    Returns a human readable test message.

 108           *    @param mixed $compare      Comparison value.

 109           *    @return string             Description of success

 110           *                               or failure.

 111           *    @access public

 112           */
 113          function testMessage($compare) {
 114              $dumper = &$this->_getDumper();
 115              if (is_array($compare)) {
 116                  sort($compare);
 117              }
 118              if ($this->test($compare)) {
 119                  return "Field expectation [" . $dumper->describeValue($this->_value) . "]";
 120              } else {
 121                  return "Field expectation [" . $dumper->describeValue($this->_value) .
 122                          "] fails with [" .
 123                          $dumper->describeValue($compare) . "] " .
 124                          $dumper->describeDifference($this->_value, $compare);
 125              }
 126          }
 127      }
 128      
 129      /**

 130       *    Test for a specific HTTP header within a header block.

 131       *      @package SimpleTest

 132       *      @subpackage WebTester

 133       */
 134      class HttpHeaderExpectation extends SimpleExpectation {
 135          var $_expected_header;
 136          var $_expected_value;
 137          
 138          /**

 139           *    Sets the field and value to compare against.

 140           *    @param string $header   Case insenstive trimmed header name.

 141           *    @param mixed $value     Optional value to compare. If not

 142           *                            given then any value will match. If

 143           *                            an expectation object then that will

 144           *                            be used instead.

 145           *    @param string $message  Optiona message override. Can use %s as

 146           *                            a placeholder for the original message.

 147           */
 148          function HttpHeaderExpectation($header, $value = false, $message = '%s') {
 149              $this->SimpleExpectation($message);
 150              $this->_expected_header = $this->_normaliseHeader($header);
 151              $this->_expected_value = $value;
 152          }
 153          
 154          /**

 155           *    Accessor for aggregated object.

 156           *    @return mixed        Expectation set in constructor.

 157           *    @access protected

 158           */
 159          function _getExpectation() {
 160              return $this->_expected_value;
 161          }
 162          
 163          /**

 164           *    Removes whitespace at ends and case variations.

 165           *    @param string $header    Name of header.

 166           *    @param string            Trimmed and lowecased header

 167           *                             name.

 168           *    @access private

 169           */
 170          function _normaliseHeader($header) {
 171              return strtolower(trim($header));
 172          }
 173          
 174          /**

 175           *    Tests the expectation. True if it matches

 176           *    a string value or an array value in any order.

 177           *    @param mixed $compare   Raw header block to search.

 178           *    @return boolean         True if header present.

 179           *    @access public

 180           */
 181          function test($compare) {
 182              return is_string($this->_findHeader($compare));
 183          }
 184          
 185          /**

 186           *    Searches the incoming result. Will extract the matching

 187           *    line as text.

 188           *    @param mixed $compare   Raw header block to search.

 189           *    @return string          Matching header line.

 190           *    @access protected

 191           */
 192          function _findHeader($compare) {
 193              $lines = split("\r\n", $compare);
 194              foreach ($lines as $line) {
 195                  if ($this->_testHeaderLine($line)) {
 196                      return $line;
 197                  }
 198              }
 199              return false;
 200          }
 201          
 202          /**

 203           *    Compares a single header line against the expectation.

 204           *    @param string $line      A single line to compare.

 205           *    @return boolean          True if matched.

 206           *    @access private

 207           */
 208          function _testHeaderLine($line) {
 209              if (count($parsed = split(':', $line, 2)) < 2) {
 210                  return false;
 211              }
 212              list($header, $value) = $parsed;
 213              if ($this->_normaliseHeader($header) != $this->_expected_header) {
 214                  return false;
 215              }
 216              return $this->_testHeaderValue($value, $this->_expected_value);
 217          }
 218          
 219          /**

 220           *    Tests the value part of the header.

 221           *    @param string $value        Value to test.

 222           *    @param mixed $expected      Value to test against.

 223           *    @return boolean             True if matched.

 224           *    @access protected

 225           */
 226          function _testHeaderValue($value, $expected) {
 227              if ($expected === false) {
 228                  return true;
 229              }
 230              if (SimpleExpectation::isExpectation($expected)) {
 231                  return $expected->test(trim($value));
 232              }
 233              return (trim($value) == trim($expected));
 234          }
 235          
 236          /**

 237           *    Returns a human readable test message.

 238           *    @param mixed $compare      Raw header block to search.

 239           *    @return string             Description of success

 240           *                               or failure.

 241           *    @access public

 242           */
 243          function testMessage($compare) {
 244              if (SimpleExpectation::isExpectation($this->_expected_value)) {
 245                  $message = $this->_expected_value->overlayMessage($compare, $this->_getDumper());
 246              } else {
 247                  $message = $this->_expected_header .
 248                          ($this->_expected_value ? ': ' . $this->_expected_value : '');
 249              }
 250              if (is_string($line = $this->_findHeader($compare))) {
 251                  return "Searching for header [$message] found [$line]";
 252              } else {
 253                  return "Failed to find header [$message]";
 254              }
 255          }
 256      }
 257        
 258      /**

 259       *    Test for a specific HTTP header within a header block that

 260       *    should not be found.

 261       *      @package SimpleTest

 262       *      @subpackage WebTester

 263       */
 264      class NoHttpHeaderExpectation extends HttpHeaderExpectation {
 265          var $_expected_header;
 266          var $_expected_value;
 267          
 268          /**

 269           *    Sets the field and value to compare against.

 270           *    @param string $unwanted   Case insenstive trimmed header name.

 271           *    @param string $message    Optiona message override. Can use %s as

 272           *                              a placeholder for the original message.

 273           */
 274          function NoHttpHeaderExpectation($unwanted, $message = '%s') {
 275              $this->HttpHeaderExpectation($unwanted, false, $message);
 276          }
 277          
 278          /**

 279           *    Tests that the unwanted header is not found.

 280           *    @param mixed $compare   Raw header block to search.

 281           *    @return boolean         True if header present.

 282           *    @access public

 283           */
 284          function test($compare) {
 285              return ($this->_findHeader($compare) === false);
 286          }
 287          
 288          /**

 289           *    Returns a human readable test message.

 290           *    @param mixed $compare      Raw header block to search.

 291           *    @return string             Description of success

 292           *                               or failure.

 293           *    @access public

 294           */
 295          function testMessage($compare) {
 296              $expectation = $this->_getExpectation();
 297              if (is_string($line = $this->_findHeader($compare))) {
 298                  return "Found unwanted header [$expectation] with [$line]";
 299              } else {
 300                  return "Did not find unwanted header [$expectation]";
 301              }
 302          }
 303      }
 304      
 305      /**

 306       *    Test for a text substring.

 307       *      @package SimpleTest

 308       *      @subpackage UnitTester

 309       */
 310      class TextExpectation extends SimpleExpectation {
 311          var $_substring;
 312          
 313          /**

 314           *    Sets the value to compare against.

 315           *    @param string $substring  Text to search for.

 316           *    @param string $message    Customised message on failure.

 317           *    @access public

 318           */
 319          function TextExpectation($substring, $message = '%s') {
 320              $this->SimpleExpectation($message);
 321              $this->_substring = $substring;
 322          }
 323          
 324          /**

 325           *    Accessor for the substring.

 326           *    @return string       Text to match.

 327           *    @access protected

 328           */
 329          function _getSubstring() {
 330              return $this->_substring;
 331          }
 332          
 333          /**

 334           *    Tests the expectation. True if the text contains the

 335           *    substring.

 336           *    @param string $compare        Comparison value.

 337           *    @return boolean               True if correct.

 338           *    @access public

 339           */
 340          function test($compare) {
 341              return (strpos($compare, $this->_substring) !== false);
 342          }
 343          
 344          /**

 345           *    Returns a human readable test message.

 346           *    @param mixed $compare      Comparison value.

 347           *    @return string             Description of success

 348           *                               or failure.

 349           *    @access public

 350           */
 351          function testMessage($compare) {
 352              if ($this->test($compare)) {
 353                  return $this->_describeTextMatch($this->_getSubstring(), $compare);
 354              } else {
 355                  $dumper = &$this->_getDumper();
 356                  return "Text [" . $this->_getSubstring() .
 357                          "] not detected in [" .
 358                          $dumper->describeValue($compare) . "]";
 359              }
 360          }
 361          
 362          /**

 363           *    Describes a pattern match including the string

 364           *    found and it's position.

 365           *    @param string $substring      Text to search for.

 366           *    @param string $subject        Subject to search.

 367           *    @access protected

 368           */
 369          function _describeTextMatch($substring, $subject) {
 370              $position = strpos($subject, $substring);
 371              $dumper = &$this->_getDumper();
 372              return "Text [$substring] detected at character [$position] in [" .
 373                      $dumper->describeValue($subject) . "] in region [" .
 374                      $dumper->clipString($subject, 100, $position) . "]";
 375          }
 376      }
 377      
 378      /**

 379       *    Fail if a substring is detected within the

 380       *    comparison text.

 381       *      @package SimpleTest

 382       *      @subpackage UnitTester

 383       */
 384      class NoTextExpectation extends TextExpectation {
 385          
 386          /**

 387           *    Sets the reject pattern

 388           *    @param string $substring  Text to search for.

 389           *    @param string $message    Customised message on failure.

 390           *    @access public

 391           */
 392          function NoTextExpectation($substring, $message = '%s') {
 393              $this->TextExpectation($substring, $message);
 394          }
 395          
 396          /**

 397           *    Tests the expectation. False if the substring appears

 398           *    in the text.

 399           *    @param string $compare        Comparison value.

 400           *    @return boolean               True if correct.

 401           *    @access public

 402           */
 403          function test($compare) {
 404              return ! parent::test($compare);
 405          }
 406          
 407          /**

 408           *    Returns a human readable test message.

 409           *    @param string $compare      Comparison value.

 410           *    @return string              Description of success

 411           *                                or failure.

 412           *    @access public

 413           */
 414          function testMessage($compare) {
 415              if ($this->test($compare)) {
 416                  $dumper = &$this->_getDumper();
 417                  return "Text [" . $this->_getSubstring() .
 418                          "] not detected in [" .
 419                          $dumper->describeValue($compare) . "]";
 420              } else {
 421                  return $this->_describeTextMatch($this->_getSubstring(), $compare);
 422              }
 423          }
 424      }
 425      
 426      /**

 427       *    Test case for testing of web pages. Allows

 428       *    fetching of pages, parsing of HTML and

 429       *    submitting forms.

 430       *    @package SimpleTest

 431       *    @subpackage WebTester

 432       */
 433      class WebTestCase extends SimpleTestCase {
 434          var $_browser;
 435          var $_ignore_errors = false;
 436          
 437          /**

 438           *    Creates an empty test case. Should be subclassed

 439           *    with test methods for a functional test case.

 440           *    @param string $label     Name of test case. Will use

 441           *                             the class name if none specified.

 442           *    @access public

 443           */
 444          function WebTestCase($label = false) {
 445              $this->SimpleTestCase($label);
 446          }
 447          
 448          /**

 449           *    Announces the start of the test.

 450           *    @param string $method    Test method just started.

 451           *    @access public

 452           */
 453          function before($method) {
 454              parent::before($method);
 455              $this->setBrowser($this->createBrowser());
 456          }
 457  
 458          /**

 459           *    Announces the end of the test. Includes private clean up.

 460           *    @param string $method    Test method just finished.

 461           *    @access public

 462           */
 463          function after($method) {
 464              $this->unsetBrowser();
 465              parent::after($method);
 466          }
 467          
 468          /**

 469           *    Gets a current browser reference for setting

 470           *    special expectations or for detailed

 471           *    examination of page fetches.

 472           *    @return SimpleBrowser     Current test browser object.

 473           *    @access public

 474           */
 475          function &getBrowser() {
 476              return $this->_browser;
 477          }
 478          
 479          /**

 480           *    Gets a current browser reference for setting

 481           *    special expectations or for detailed

 482           *    examination of page fetches.

 483           *    @param SimpleBrowser $browser    New test browser object.

 484           *    @access public

 485           */
 486          function setBrowser(&$browser) {
 487              return $this->_browser = &$browser;
 488          }
 489            
 490          /**

 491           *    Clears the current browser reference to help the

 492           *    PHP garbage collector.

 493           *    @access public

 494           */
 495          function unsetBrowser() {
 496              unset($this->_browser);
 497          }
 498        
 499          /**

 500           *    Creates a new default web browser object.

 501           *    Will be cleared at the end of the test method.

 502           *    @return TestBrowser           New browser.

 503           *    @access public

 504           */
 505          function &createBrowser() {
 506              $browser = &new SimpleBrowser();
 507              return $browser;
 508          }
 509          
 510          /**

 511           *    Gets the last response error.

 512           *    @return string    Last low level HTTP error.

 513           *    @access public

 514           */
 515          function getTransportError() {
 516              return $this->_browser->getTransportError();
 517          }
 518            
 519          /**

 520           *    Accessor for the currently selected URL.

 521           *    @return string        Current location or false if

 522           *                          no page yet fetched.

 523           *    @access public

 524           */
 525          function getUrl() {
 526              return $this->_browser->getUrl();
 527          }
 528          
 529          /**

 530           *    Dumps the current request for debugging.

 531           *    @access public

 532           */
 533          function showRequest() {
 534              $this->dump($this->_browser->getRequest());
 535          }
 536          
 537          /**

 538           *    Dumps the current HTTP headers for debugging.

 539           *    @access public

 540           */
 541          function showHeaders() {
 542              $this->dump($this->_browser->getHeaders());
 543          }
 544        
 545          /**

 546           *    Dumps the current HTML source for debugging.

 547           *    @access public

 548           */
 549          function showSource() {
 550              $this->dump($this->_browser->getContent());
 551          }
 552        
 553          /**

 554           *    Dumps the visible text only for debugging.

 555           *    @access public

 556           */
 557          function showText() {
 558              $this->dump(wordwrap($this->_browser->getContentAsText(), 80));
 559          }
 560          
 561          /**

 562           *    Simulates the closing and reopening of the browser.

 563           *    Temporary cookies will be discarded and timed

 564           *    cookies will be expired if later than the

 565           *    specified time.

 566           *    @param string/integer $date Time when session restarted.

 567           *                                If ommitted then all persistent

 568           *                                cookies are kept. Time is either

 569           *                                Cookie format string or timestamp.

 570           *    @access public

 571           */
 572          function restart($date = false) {
 573              if ($date === false) {
 574                  $date = time();
 575              }
 576              $this->_browser->restart($date);
 577          }
 578          
 579          /**

 580           *    Moves cookie expiry times back into the past.

 581           *    Useful for testing timeouts and expiries.

 582           *    @param integer $interval    Amount to age in seconds.

 583           *    @access public

 584           */
 585          function ageCookies($interval) {
 586              $this->_browser->ageCookies($interval);
 587          }
 588          
 589          /**

 590           *    Disables frames support. Frames will not be fetched

 591           *    and the frameset page will be used instead.

 592           *    @access public

 593           */
 594          function ignoreFrames() {
 595              $this->_browser->ignoreFrames();
 596          }
 59