File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / scripts / dev / generate-phpt.phar
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Oct 14 08:02:46 2013 UTC (11 years, 8 months ago) by misho
Branches: php, MAIN
CVS tags: v5_4_29p0, v5_4_29, v5_4_20p0, v5_4_20, HEAD
v 5.4.20

    1: <?php
    2: Phar::mapPhar('generate-phpt.phar');
    3: require 'phar://generate-phpt.phar/generate-phpt.php';
    4: __HALT_COMPILER(); ?>
    5: 
    6: 
:generate-phpt.php5J5;gtFunction.phpJeGh
    7: gtText.phpJYgtClassMap.php	J	Btexts/unknownMethod.txtlJl2_texts/unknownClass.txtiJioptexts/testTypeNotSpecified.txt2J2?texts/help.txt?J?otexts/methodNotSpecified.txtcJc*l&texts/functionOrMethodNotSpecified.txt8J8texts/unknownFunction.txtrJrșgtCodeSnippet.phpqJq>1gtAutoload.php7J7˶setup/gtCommandLineOptions.php)J){)setup/preconditions/gtIsValidFunction.phpJt-setup/preconditions/gtIsSpecifiedTestType.phppJp?Sܶ*setup/preconditions/gtIfClassHasMethod.phpJ5
    8: 	5setup/preconditions/gtIsSpecifiedFunctionOrMethod.phpJ
m'setup/preconditions/gtIsValidMethod.php2J2&setup/preconditions/gtIsValidClass.phpJۧqsetup/gtPreConditionList.phprJrIsetup/gtOptionalSections.phpJa?ж/setup/exceptions/gtMissingArgumentException.phpOJO´k.setup/exceptions/gtUnknownSectionException.phpJJJ-setup/exceptions/gtUnknownOptionException.phpMJMy˶.setup/exceptions/gtMissingOptionsException.phpLJL9osetup/gtPreCondition.phpJAygtTestCaseWriter.phpJËhSgtMethod.phpJgcodeSnippets/commentEnd.txtJUcodeSnippets/skipifwin.txtWJW?codeSnippets/commentStart.txtJn@codeSnippets/float.txtJC0codeSnippets/string.txtJ1codeSnippets/loopStart.txt&J&ʕcodeSnippets/skipifnotwin.txtXJX5YncodeSnippets/array.txtJGJcodeSnippets/loopClose.txtJcodeSnippets/boolean.txtJ?codeSnippets/skipifnot64b.txtJJJpŶcodeSnippets/skipif64btxtJJJ|"˶$codeSnippets/emptyUnsetUndefNull.txtJ!codeSnippets/object.txtYJY|codeSnippets/int.txtzJzBgtTestSubject.phpJPe'testcase/gtVariationContainerMethod.php3J3x"testcase/gtBasicTestCaseMethod.phpJOtestcase/gtErrorTestCase.phpJtestcase/gtTestCase.phpJ"@$testcase/gtBasicTestCaseFunction.phpHJHx%$testcase/gtErrorTestCaseFunction.phpJ1(testcase/gtVariationTestCaseFunction.phpJ5_)testcase/gtVariationContainerFunction.php;J;a"testcase/gtErrorTestCaseMethod.phpJ"testcase/gtBasicTestCase.phpuJuUK%!testcase/gtVariationContainer.phpJ(=; testcase/gtVariationTestCase.phpJC&testcase/gtVariationTestCaseMethod.php&J&j\<?php
    9: /**
   10:  * Main code for test case generation
   11:  */
   12: 
   13: require_once dirname(__FILE__) . '/gtAutoload.php';
   14: 
   15: //Version check. Will not run on less than PHP53;
   16: 
   17: list($major, $minor, $bug) = explode(".", phpversion(), 3);
   18:  if($major == 5) {
   19:        if($minor < 3) { die("Sorry, you need PHP version 5.3 or greater to run this.\n"); }
   20:    }
   21:    if ($major < 5) { die ("Seriously, you need to upgrade you PHP level\n"); }
   22: 
   23: 
   24: $options = new gtCommandLineOptions();
   25: $optionalSections = new gtOptionalSections();
   26: 
   27: try{
   28:   $options->parse($argv);
   29: } catch (exception $e) {
   30:   echo $e->getMessage()."\n";
   31:   die();
   32: }
   33: 
   34: if($options->hasOption('h')) {
   35:   die(gtText::get('help'));
   36: }
   37: 
   38: try {
   39:   $preConditions = new gtPreConditionList();
   40:   $preConditions->check($options);
   41: } catch (exception $e) {
   42:   echo $e->getMessage()."\n";
   43:   die();
   44: }
   45: 
   46: if($options->hasOption('s')) {
   47:   $optionalSections->setOptions($options);
   48: }
   49:   
   50: 
   51: 
   52: if($options->hasOption('c')) {
   53:   $name = $options->getOption('c')."_".$options->getOption('m');
   54:   $method = new gtMethod($options->getOption('c'), $options->getOption('m'));
   55:   
   56:   $method->setArgumentNames();
   57:   $method->setArgumentLists();
   58:   $method->setInitialisationStatements();
   59:   
   60:   $method->setConstructorArgumentNames();
   61:   $method->setConstructorInitStatements();
   62:   $method->setConstructorArgumentList();
   63: }
   64: 
   65: if($options->hasOption('f')) {
   66:   $name = $options->getOption('f');
   67:   $function = new gtFunction($name);
   68:   $function->setArgumentNames();
   69:   $function->setArgumentLists();
   70:   $function->setInitialisationStatements();
   71: }
   72: 
   73: 
   74: if($options->hasOption('b')) {
   75:   if($options->hasOption('c')) {
   76:     $testCase = gtBasicTestCase::getInstance($optionalSections, 'method');
   77:     $testCase->setMethod($method);
   78:   } else {
   79:     $testCase = gtBasicTestCase::getInstance($optionalSections);
   80:     $testCase->setFunction($function);
   81:   }
   82: 
   83:   $testCase->constructTestCase();
   84:   gtTestCaseWriter::write($name, $testCase->toString(), 'b');
   85: }
   86: 
   87: if($options->hasOption('e')) {
   88:   if($options->hasOption('c')) {
   89:     $testCase = gtErrorTestCase::getInstance($optionalSections, 'method');
   90:     $testCase->setMethod($method);
   91:   } else {
   92:     $testCase = gtErrorTestCase::getInstance($optionalSections);
   93:     $testCase->setFunction($function);
   94:   }
   95: 
   96:   $testCase->constructTestCase();
   97:   gtTestCaseWriter::write($name, $testCase->toString(), 'e');
   98: }
   99: 
  100: 
  101: 
  102: if($options->hasOption('v')) {
  103:   if($options->hasOption('c')) {
  104:     $testCaseContainer = gtVariationContainer::getInstance($optionalSections, 'method');
  105:     $testCaseContainer->setMethod($method);
  106:   } else {
  107:     $testCaseContainer = gtVariationContainer::getInstance ($optionalSections);
  108:     $testCaseContainer->setFunction($function);
  109:   }
  110: 
  111:   $testCaseContainer->constructAll();
  112: 
  113:   $tests = $testCaseContainer->getVariationTests();
  114: 
  115:   $count = 1;
  116:   foreach($tests as $test) {
  117:     gtTestCaseWriter::write($name, $test, 'v', $count);
  118:     $count++;
  119:   }
  120: 
  121: }
  122: ?>
  123: <?php
  124: 
  125: /**
  126:  * Class reperesents a single PHP function.
  127:  *
  128:  */
  129: class gtFunction extends gtTestSubject {
  130: 
  131:   private $functionName;
  132:   
  133:   /**
  134:    * Set the name of the name of the function
  135:    *
  136:    * @param string $functionName
  137:    */
  138:   public function __construct($functionName)  {
  139:     $this->functionName = $functionName;
  140:   }
  141: 
  142: 
  143:   /**
  144:    * Get the names of function arguments and initialise mandatory and optional argument arrays
  145:    *
  146:    */
  147:   public function setArgumentNames() {
  148:     $function= new ReflectionFunction($this->functionName);
  149: 
  150:     foreach ($function->getParameters() as $i => $param) {
  151:       if($param->isOptional()) {
  152:         $this->optionalArgumentNames[] = $param->getName();
  153:       } else {
  154:         $this->mandatoryArgumentNames[] = $param->getName();
  155:       }
  156:     }
  157:   }
  158: 
  159: 
  160:   /**
  161:    * Return the name of the function
  162:    *
  163:    * @return string
  164:    */
  165:   public function getName() {
  166:     return $this->functionName;
  167:   }
  168: 
  169: }
  170: ?><?php
  171: 
  172: /**
  173:  * Get a text message
  174:  *
  175:  */
  176: class gtText
  177: {
  178: 
  179:   /**
  180:    * Get the text message and return it
  181:    *
  182:    * @param string $name
  183:    * @return string
  184:    */
  185:   public static function get($name) {
  186:     $filename = dirname(__FILE__) . '/texts/' . $name . '.txt';
  187: 
  188:     if (!file_exists($filename)) {
  189:       throw new LogicException('The text ' . $name . ' does not exist');
  190:     }
  191: 
  192:     return file_get_contents($filename);
  193:   }
  194: }
  195: 
  196: ?><?php
  197: 
  198:  $gtClassMap = array(
  199:  
  200:     'gtCodeSnippet'                 => 'gtCodeSnippet.php',
  201:     'gtTestSubject'                 => 'gtTestSubject.php',
  202:     'gtFunction'                    => 'gtFunction.php',
  203:     'gtMethod'                      => 'gtMethod.php',
  204:     'gtTestCaseWriter'              => 'gtTestCaseWriter.php',
  205:     'gtText'                        => 'gtText.php',
  206:  
  207:  
  208:  
  209:     'gtCommandLineOptions'          => 'setup/gtCommandLineOptions.php',
  210:     'gtOptionalSections'            => 'setup/gtOptionalSections.php',
  211:     'gtMissingArgumentException'    => 'setup/exceptions/gtMissingArgumentException.php',
  212:     'gtUnknownOptionException'      => 'setup/exceptions/gtUnknownOptionException.php',
  213:     'gtUnknownSectionException'      => 'setup/exceptions/gtUnknownSectionException.php',
  214:     'gtMissingOptionsException'     => 'setup/exceptions/gtMissingOptionsException.php',
  215:  
  216:     'gtPreCondition'                => 'setup/gtPreCondition.php',
  217:     'gtPreConditionList'            => 'setup/gtPreConditionList.php',
  218:     'gtIsSpecifiedTestType'         => 'setup/preconditions/gtIsSpecifiedTestType.php',
  219:     'gtIfClassHasMethod'            => 'setup/preconditions/gtIfClassHasMethod.php',
  220:     'gtIsSpecifiedFunctionOrMethod' => 'setup/preconditions/gtIsSpecifiedFunctionOrMethod.php',
  221:     'gtIsValidClass'                => 'setup/preconditions/gtIsValidClass.php',
  222:     'gtIsValidMethod'               => 'setup/preconditions/gtIsValidMethod.php',
  223:     'gtIsValidFunction'             => 'setup/preconditions/gtIsValidFunction.php',
  224:  
  225:  
  226:      'gtTestCase'                   => 'testcase/gtTestCase.php',
  227:      'gtVariationTestCase'          => 'testcase/gtVariationTestCase.php',
  228:      'gtVariationTestCaseFunction'  => 'testcase/gtVariationTestCaseFunction.php',
  229:      'gtVariationTestCaseMethod'    => 'testcase/gtVariationTestCaseMethod.php',
  230:  
  231:      'gtBasicTestCase'              => 'testcase/gtBasicTestCase.php',
  232:      'gtBasicTestCaseFunction'      => 'testcase/gtBasicTestCaseFunction.php',
  233:      'gtBasicTestCaseMethod'        => 'testcase/gtBasicTestCaseMethod.php',
  234:  
  235:      'gtErrorTestCase'              => 'testcase/gtErrorTestCase.php',
  236:      'gtErrorTestCaseFunction'      => 'testcase/gtErrorTestCaseFunction.php',
  237:      'gtErrorTestCaseMethod'        => 'testcase/gtErrorTestCaseMethod.php',
  238:  
  239:      'gtVariationContainer'         => 'testcase/gtVariationContainer.php',
  240:      'gtVariationContainerMethod'   => 'testcase/gtVariationContainerMethod.php',
  241:      'gtVariationContainerFunction' => 'testcase/gtVariationContainerFunction.php',
  242:  );
  243: ?>
  244: The method name is not a valid PHP method name.
  245: Check that the extension containing the method is loaded.
  246: 
  247: 
  248: The class name is not a valid PHP class name.
  249: Check that the extension containing the class is loaded.
  250: 
  251: 
  252: Please specify basic, error or variation tests.
  253: 
  254: Usage:
  255: php generate-phpt.php  -f <function_name> |-c <class_name> -m <method_name> -b|e|v [-s skipif:ini:clean:done] [-k win|notwin|64b|not64b] [-x ext]
  256: 
  257: Where:
  258: -f function_name ................. Name of PHP function, eg cos
  259: -c class name .....................Name of class, eg DOMDocument
  260: -m method name ....................Name of method, eg createAttribute
  261: -b ............................... Generate basic tests
  262: -e ............................... Generate error tests
  263: -v ............................... Generate variation tests
  264: -s sections....................... Create optional sections, colon separated list
  265: -k skipif key..................... Skipif option, only used if -s skipif is used.
  266: -x extension.......................Skipif option, specify extension to check for
  267: -h ............................... Print this message
  268: 
  269: You have given a class name but not supplied a method name to test.
  270: The method name is required.
  271: 
  272: 
  273: Please supply a function or method name to be tested.
  274: 
  275: 
  276: The function name is not a valid PHP function name.
  277: Check that the extension containing the function is loaded.
  278: 
  279: <?php
  280: 
  281: /**
  282:  * Retrieves code snippets for adding to test cases
  283:  * 
  284:  */
  285: class gtCodeSnippet
  286: {
  287: 
  288:   /**
  289:    * get the code snippet and initialise an array with it
  290:    *
  291:    * @param string $name
  292:    * @return array
  293:    */
  294:   public static function get($name) {
  295:     
  296:     $filename = dirname(__FILE__) . '/codeSnippets/' . $name . '.txt';
  297: 
  298:     if (!file_exists($filename)) {
  299:       throw new LogicException('The code snippet ' . $name . ' does not exist');
  300:     }
  301:     
  302:     $lines = file($filename);
  303:     foreach($lines as $l) {
  304:       $array[] = rtrim($l);
  305:     }
  306:     return $array;
  307:   }
  308:   
  309:   
  310:   /**
  311:    * Append the code snippet on to an existing array
  312:    *
  313:    * @param string $name
  314:    * @param array $array
  315:    * @return array
  316:    */
  317:   public static function append($name, $array) {
  318:     $filename = dirname(__FILE__) . '/codeSnippets/' . $name . '.txt';
  319: 
  320:     if (!file_exists($filename)) {
  321:       throw new LogicException('The code snippet ' . $name . ' does not exist');
  322:     }
  323: 
  324:     $text =  file($filename);
  325:     foreach ($text as $t) {
  326:       $array[] = rtrim($t);
  327:     }
  328:     
  329:     return $array;
  330:   }
  331:   
  332:   
  333:   /**
  334:    * Appends blank entries on to an array
  335:    *
  336:    * @param int $numberOfLines
  337:    * @param array $array
  338:    * @return array
  339:    */
  340:   public static function appendBlankLines($numberOfLines, $array) {
  341: 
  342:     for ($i=0; $i< $numberOfLines; $i++) {
  343:       $array[] = "";
  344:     }
  345:     
  346:     return $array;
  347:   }
  348:   
  349: }
  350: ?><?php
  351: 
  352: 
  353: gtAutoload::init();
  354: 
  355: /**
  356:  * Autoloader using a map file (gtClassMap.php)
  357:  * defining the file to load each class from.
  358:  */
  359: class gtAutoload
  360: {
  361:   /**
  362:    * @var array
  363:    */
  364:   protected static $classMap;
  365: 
  366:   /**
  367:    * @var string
  368:    */
  369:   protected static $classPath;
  370: 
  371: 
  372:   /**
  373:    * Initialize the autoloader
  374:    *
  375:    * @return null
  376:    */
  377:   public static function init()
  378:   {
  379:     self::$classPath = dirname(__FILE__);
  380: 
  381:     if (substr(self::$classPath, -1) != '/') {
  382:       self::$classPath .= '/';
  383:     }
  384: 
  385:     if (file_exists(self::$classPath . 'gtClassMap.php')) {
  386:       include self::$classPath . 'gtClassMap.php';
  387:       self::$classMap = $gtClassMap;
  388:     }
  389: 
  390:     if (function_exists('__autoload')) {
  391:       spl_autoload_register('__autoload');
  392:     }
  393: 
  394:     spl_autoload_register(array('gtAutoload', 'autoload'));
  395:   }
  396: 
  397: 
  398:   /**
  399:    * Autoload method
  400:    *
  401:    * @param string $class Class name to autoload
  402:    * @return null
  403:    */
  404:   public static function autoload($class)
  405:   {
  406:     if (isset(self::$classMap[$class])) {
  407:       include self::$classPath . self::$classMap[$class];
  408:     }
  409:   }
  410: }
  411: 
  412: ?><?php
  413: 
  414: /**
  415:  * Parse command line options
  416:  *
  417:  */
  418: class gtCommandLineOptions {
  419: 
  420:   protected $shortOptions = array(
  421:     'b',
  422:     'e',
  423:     'v',
  424:     'h',
  425:   );
  426: 
  427:   protected $shortOptionsWithArgs = array(
  428:     'c',
  429:     'm',
  430:     'f',
  431:     'i',
  432:     's',
  433:     'x',
  434:     'k',
  435:   );
  436:   
  437:   protected $options;
  438: 
  439:   protected function isShortOption($arg)
  440:   {
  441:     return (substr($arg, 0, 1) == '-') && (substr($arg, 1, 1) != '-');
  442:   }
  443: 
  444:   public function isValidOptionArg($array, $index) {
  445:     if (!isset($array[$index]))
  446:     {
  447:       return false;
  448:     }
  449:     return substr($array[$index], 0, 1) != '-';
  450:   }
  451: 
  452: 
  453:   public function parse($argv)
  454:   {
  455:     if(count($argv) < 2) {
  456:       throw new gtMissingOptionsException('Command line options are required');
  457:     }
  458:     
  459:     for ($i=1; $i<count($argv); $i++) {
  460: 
  461:       if ($this->isShortOption($argv[$i])) {
  462:         $option = substr($argv[$i], 1);
  463:       } else {
  464:         throw new gtUnknownOptionException('Unrecognised command line option ' . $argv[$i]);
  465:       }
  466: 
  467:       if (!in_array($option, array_merge($this->shortOptions, $this->shortOptionsWithArgs)))
  468:       {
  469:         throw new gtUnknownOptionException('Unknown option ' . $argv[$i]);
  470:       }
  471: 
  472:       if (in_array($option, $this->shortOptions)) {
  473:         $this->options[$option] = true;
  474:         continue;
  475:       }
  476: 
  477:       if (!$this->isValidOptionArg($argv, $i + 1))
  478:       {
  479:         throw new gtMissingArgumentException('Missing argument for command line option ' . $argv[$i]);
  480:       }
  481: 
  482:       $i++;
  483:       $this->options[$option] = $argv[$i];
  484:     }
  485:   }
  486:   
  487:  /**
  488:    *
  489:    */
  490:   public function getOption($option)
  491:   {
  492:     if (!isset($this->options[$option])) {
  493:       return false;
  494:     }
  495:     return $this->options[$option];
  496:   }
  497: 
  498: 
  499:   /**
  500:    * Check whether an option exists
  501:    */
  502:   public function hasOption($option)
  503:   {
  504:     return isset($this->options[$option]);
  505:   }
  506: 
  507: 
  508: }
  509: ?><?php
  510: 
  511: /**
  512:  * Check that the function name is valid
  513:  *
  514:  */
  515: class gtIsValidFunction extends gtPreCondition {
  516: 
  517:   public function check( $clo) {
  518:     if($clo->hasOption('f') ) {
  519:       $function = $clo->getOption('f');
  520:       $functions = get_defined_functions();
  521:       if( in_array( $function, $functions['internal'] ) ) {
  522:         return true;
  523:       }
  524:       return false;
  525:     }
  526:     return true;
  527:   }
  528: 
  529:   public function getMessage() {
  530:     return gtText::get('unknownFunction');
  531:   }
  532: }
  533: ?><?php
  534: 
  535: /**
  536:  * Check that b|c|v is specified
  537:  *
  538:  */
  539: class gtIsSpecifiedTestType extends gtPreCondition {
  540:   
  541:   public function check( $clo) {
  542:     if($clo->hasOption('b') || $clo->hasOption('e') || $clo->hasOption('v') ) {
  543:     
  544:         return true;
  545:       }
  546:     return false;
  547:   }
  548:   
  549:   public function getMessage() {
  550:     return gtText::get('testTypeNotSpecified');
  551:   }
  552: }
  553: ?><?php
  554: 
  555: /**
  556:  * If use has requested a class check that method is specified
  557:  *
  558:  */
  559: class gtIfClassHasMethod extends gtPreCondition {
  560:   
  561:   public function check( $clo) {
  562:     if($clo->hasOption('c')) {
  563:       if(!$clo->hasOption('m')) {
  564:         return false;
  565:       }
  566:       return  true;
  567:     }
  568:     return true;
  569:   }
  570:   
  571:   public function getMessage() {
  572:     return gtText::get('methodNotSpecified');
  573:   }
  574: 
  575: }
  576: ?><?php
  577: 
  578: /**
  579:  * Check that either a method or a function is specified
  580:  *
  581:  */
  582: class gtIsSpecifiedFunctionOrMethod extends gtPreCondition {
  583:   
  584:   public function check( $clo) {
  585:     if($clo->hasOption('f') || $clo->hasOption('m')) {
  586:     
  587:         return true;
  588:       }
  589:     return false;
  590:   }
  591:   
  592:   public function getMessage() {
  593:     return gtText::get('functionOrMethodNotSpecified');
  594:   }
  595: }
  596: ?><?php
  597: 
  598: /**
  599:  * Check that teh method name is valid
  600:  *
  601:  */
  602: class gtIsValidMethod extends gtPreCondition {
  603: 
  604:  public function check( $clo) {
  605:     if($clo->hasOption('m') ) {
  606:       $className = $clo->getOption('c');
  607:       $class = new ReflectionClass($className);
  608:       $methods = $class->getMethods();
  609:       foreach($methods as $method) {
  610:         if($clo->getOption('m') == $method->getName()) {
  611:           return true;
  612:         }
  613:       }
  614:       return false;
  615:     }
  616:     return true;
  617:   }
  618: 
  619:   public function getMessage() {
  620:     return gtText::get('unknownMethod');
  621:   }
  622: }
  623: ?><?php
  624: 
  625: /**
  626:  * Check that the class name is valid
  627:  *
  628:  */
  629: class gtIsValidClass extends gtPreCondition {
  630: 
  631:   public function check( $clo) {
  632:     if($clo->hasOption('c') ) {
  633:       $className = $clo->getOption('c');
  634:       if( in_array( $className, get_declared_classes() ) ) {
  635:         return true;
  636:       }
  637:       return false;
  638:     }
  639:     return true;
  640:   }
  641: 
  642:   public function getMessage() {
  643:     return gtText::get('unknownClass');
  644:   }
  645: }
  646: ?><?php
  647: 
  648: /**
  649:  * List of preconditions.
  650:  *
  651:  */
  652: class gtPreConditionList {
  653:   
  654:   private $preConditions = array(
  655:       'gtIsSpecifiedTestType',
  656:       'gtIsSpecifiedFunctionOrMethod',  
  657:       'gtIfClassHasMethod',
  658:       'gtIsValidClass',
  659:       'gtIsValidFunction',
  660:       'gtIsValidMethod',
  661:   );
  662: 
  663: 
  664:   /**
  665:    * Create an instance of each pre-condition and run their check methods
  666:    *
  667:    */
  668:   public function check($clo) {
  669:     foreach ($this->preConditions as $preCon) {
  670:       $checkThis = new $preCon;
  671:       if(!$checkThis->check($clo)) {
  672:         echo $checkThis->getMessage();
  673:         die(gtText::get('help'));
  674:       }
  675:     }
  676:   }
  677: }
  678: ?><?php
  679: class gtOptionalSections {
  680: 
  681:   private $optSections = array(
  682:     'skipif' => false,
  683:     'ini'    => false,
  684:     'clean'  => false,
  685:     'done'   => false,
  686:   );
  687: 
  688:   private $skipifKey = '';
  689:   private $skipifExt = '';
  690: 
  691: 
  692:   public function setOptions($commandLineOptions) {
  693:     if($commandLineOptions->hasOption('s')) {
  694:       $options = explode(':', $commandLineOptions->getOption('s'));
  695: 
  696:       foreach($options as $option) {
  697: 
  698:         if(array_key_exists($option, $this->optSections )) {
  699:           $this->optSections[$option] = true;
  700:         } else {
  701:           throw new gtUnknownSectionException('Unrecognised optional section');
  702:         }
  703:       }
  704: 
  705:       if($commandLineOptions->hasOption('k')) {
  706:         $this->skipifKey = $commandLineOptions->getOption('k');
  707:       }
  708:       
  709:       if($commandLineOptions->hasOption('x')) {
  710:         $this->skipifExt = $commandLineOptions->getOption('x');
  711:       }
  712:       
  713:     }
  714:   }
  715: 
  716: 
  717: 
  718:   public function getOptions() {
  719:     return $this->optSections;
  720:   }
  721: 
  722: 
  723:   public function getSkipifKey() {
  724:     return $this->skipifKey;
  725:   }
  726:   
  727:   public function getSkipifExt() {
  728:     return $this->skipifExt;
  729:   }
  730: 
  731:   public function hasSkipif() {
  732:     return $this->optSections['skipif'];
  733:   }
  734: 
  735:   public function hasSkipifKey() {
  736:     if($this->skipifKey != '') {
  737:       return true;
  738:     }
  739:     return false;
  740:   }
  741:   
  742:   public function hasSkipifExt() {
  743:     if($this->skipifExt != '') {
  744:       return true;
  745:     }
  746:     return false;
  747:   }
  748:   public function hasIni() {
  749:     return $this->optSections['ini'];
  750:   }
  751: 
  752:   public function hasClean() {
  753:     return $this->optSections['clean'];
  754:   }
  755:   
  756:   public function hasDone() {
  757:     return $this->optSections['done'];
  758:   }
  759: 
  760: 
  761: }
  762: ?><?php
  763: 
  764:   class gtMissingArgumentException extends RuntimeException
  765:   {
  766:   }
  767: 
  768: ?>
  769: <?php
  770: 
  771: class gtUnknownSectionException extends RuntimeException
  772:   {
  773:   }
  774: ?><?php
  775: 
  776:   class gtUnknownOptionException extends RuntimeException
  777:   {
  778:   }
  779: 
  780: ?>
  781: <?php
  782: 
  783:  class gtMissingOptionsException extends RuntimeException
  784:   {
  785:   }
  786: 
  787: ?><?php
  788: 
  789: /**
  790:  * parent class for preconditions
  791:  *
  792:  */
  793: abstract class gtPreCondition {
  794:   
  795:   abstract public function check($clo); 
  796:   
  797:   abstract public function getMessage(); 
  798:   
  799: }
  800: ?><?php
  801: 
  802: /**
  803:  * Writes a single test case to a file
  804:  *
  805:  */
  806: class gtTestCaseWriter {
  807:   
  808:   public static function write($name, $string, $type, $count = 0) {
  809:     if ($type  == 'b') {
  810:     $fileName = $name."_basic.phpt";
  811:     }
  812:     
  813:     if ($type  == 'e') {
  814:      $fileName = $name."_error.phpt";
  815:     }
  816:     
  817:     if ($type  == 'v') {
  818:       $fileName = $name."_variation".$count.".phpt";
  819:     }
  820:     
  821:     $fh = fopen($fileName, 'w');
  822:     fwrite ($fh, $string);
  823:     fclose($fh);
  824:   }
  825: }
  826: ?><?php
  827: 
  828: /**
  829:  * Class for method under test (see gtFunction for non-OO tests)
  830:  */
  831: class gtMethod  extends gtTestSubject {
  832: 
  833:   private $className;
  834:   private $methodName;
  835:   private $constructorArgumentNames;
  836:   private $constructorArgumentList = '';
  837:   private $constructorInitialisationStatements;
  838: 
  839: 
  840: 
  841:   /**
  842:    * Construct gtMethod object from the class and method names
  843:    *
  844:    * @param string $className
  845:    * @param string $methodName
  846:    */
  847:   public function __construct($className, $methodName) {
  848:     $this->className = $className;
  849:     $this->methodName = $methodName;
  850:   }
  851: 
  852: 
  853:   /**
  854:    * Set the names of the class constructor arguments. Take only mandatory argument names.
  855:    *
  856:    */
  857:   public function setConstructorArgumentNames() {
  858:     $reflectionClass = new ReflectionClass($this->className);
  859:     $constructor = $reflectionClass->getConstructor();
  860:     foreach($constructor->getParameters() as $i => $param) {
  861:       //if(!$param->isOptional()) {
  862:         $this->constructorArgumentNames[] = $param->getName();
  863:       //}
  864:     }
  865:   }
  866: 
  867:   
  868:   /**
  869:    * Set the names of the mandatory and optional arguments to the method
  870:    *
  871:    */
  872:   public function setArgumentNames() {
  873: 
  874:     $methodClass  = new reflectionMethod($this->className, $this->methodName);
  875:     $parameters = $methodClass->getParameters();
  876: 
  877:     foreach ($methodClass->getParameters() as $i => $param) {
  878:       if($param->isOptional()) {
  879:         $this->optionalArgumentNames[] = $param->getName();
  880:       } else {
  881:         $this->mandatoryArgumentNames[] = $param->getName();
  882:       }
  883: 
  884:     }
  885:   }
  886: 
  887: 
  888:   /**
  889:    * Return the list of constructor argument names
  890:    *
  891:    * @return array
  892:    */
  893:   public function getConstructorArgumentNames() {
  894:     return $this->constructorArgumentNames;
  895:   }
  896: 
  897:   /**
  898:    * Return the name of the method
  899:    *
  900:    * @return string
  901:    */
  902:   public function getName() {
  903:     return $this->methodName;
  904:   }
  905: 
  906: 
  907:   /**
  908:    * Return the name of the class
  909:    *
  910:    * @return string
  911:    */
  912:   public function getClassName() {
  913:     return $this->className;
  914:   }
  915:   
  916:   /**
  917:    * Set the list of arguments to be passed to the constructor
  918:    *
  919:    */
  920:   public function setConstructorArgumentList() {
  921:     if(count ($this->constructorArgumentNames) > 0) {
  922:       
  923:       for( $i = 0; $i < count( $this->constructorArgumentNames ); $i++) {
  924:         $this->constructorArgumentList .= "\$".$this->constructorArgumentNames[$i].", ";
  925:       }
  926:       $this->constructorArgumentList = substr($this->constructorArgumentList, 0, -2);
  927:     }
  928:   }
  929: 
  930: 
  931:   /**
  932:    * Return the list of the arguments to be passed to the constructor
  933:    *
  934:    * @return string
  935:    */
  936:   public function getConstructorArgumentList() {
  937:     return $this->constructorArgumentList;
  938:   }
  939: 
  940:   
  941:   /**
  942:    * Set up the source statements that initialise constructor arguments;
  943:    *
  944:    */
  945:   public function setConstructorInitStatements() {
  946:     if(count ($this->constructorArgumentNames) > 0) {
  947:       foreach( $this->constructorArgumentNames as $name) {
  948:         $this->constructorInitialisationStatements[] = "\$".$name." = ";
  949:       }
  950:     }
  951: 
  952:   }
  953: 
  954:   
  955:   /**
  956:    * Return the constructor initialisation statements
  957:    *
  958:    * @return array
  959:    */
  960:   public function getConstructorInitStatements() {
  961:     return $this->constructorInitialisationStatements;
  962:   }
  963: }
  964: ?> *
  965:  */if (substr(PHP_OS, 0, 3) == 'WIN') die("skip this test is not for Windows platforms");
  966: /**
  967:  *$variation_array = array(
  968:   'float 10.5' => 10.5,
  969:   'float -10.5' => -10.5,
  970:   'float 12.3456789000e10' => 12.3456789000e10,
  971:   'float -12.3456789000e10' => -12.3456789000e10,
  972:   'float .5' => .5,
  973:   );$heredoc = <<<EOT
  974: hello world
  975: EOT;
  976: 
  977: $variation_array = array(
  978:   'string DQ' => "string",
  979:   'string SQ' => 'string',
  980:   'mixed case string' => "sTrInG",
  981:   'heredoc' => $heredoc,
  982:   );foreach ( $variation_array as $var ) {if (substr(PHP_OS, 0, 3) != 'WIN') die("skip this test is for Windows platforms only");
  983: $index_array = array(1, 2, 3);
  984: $assoc_array = array(1 => 'one', 2 => 'two');
  985: 
  986: $variation_array = array(
  987:   'empty array' => array(),
  988:   'int indexed array' => $index_array,
  989:   'associative array' => $assoc_array,
  990:   'nested arrays' => array('foo', $index_array, $assoc_array),
  991:   );}$variation_array = array(
  992:   'lowercase true' => true,
  993:   'lowercase false' =>false,
  994:   'uppercase TRUE' =>TRUE,
  995:   'uppercase FALSE' =>FALSE,
  996:   );if (PHP_INT_SIZE != 8) die("skip this test is for 64bit platforms only");
  997: if (PHP_INT_SIZE != 4) die("skip this test is for 32bit platforms only");
  998: $unset_var = 10;
  999: unset($unset_var);
 1000: 
 1001: $variation_array = array(
 1002:   'unset var' => @$unset_var,
 1003:   'undefined var' => @$undefined_var,	
 1004:   'empty string DQ' => "",
 1005:   'empty string SQ' => '',
 1006:   'uppercase NULL' => NULL,
 1007:   'lowercase null' => null,
 1008:   );function test_error_handler($err_no, $err_msg, $filename, $linenum, $vars) {
 1009:         if (error_reporting() != 0) {
 1010:                 // report non-silenced errors
 1011:                 echo "Error: $err_no - $err_msg, $filename($linenum)\n";
 1012:         }
 1013: }
 1014: set_error_handler('test_error_handler');
 1015: 
 1016: 
 1017: 
 1018: class classWithToString
 1019: {
 1020:         public function __toString() {
 1021:                 return "Class A object";
 1022:         }
 1023: }
 1024: 
 1025: class classWithoutToString
 1026: {
 1027: }
 1028: 
 1029: $variation_array = array(
 1030:   'instance of classWithToString' => new classWithToString(),
 1031:   'instance of classWithoutToString' => new classWithoutToString(),
 1032:   );$variation_array = array (
 1033:     'int 0' => 0,
 1034:     'int 1' => 1,
 1035:     'int 12345' => 12345,
 1036:     'int -12345' => -2345,
 1037:     );<?php
 1038: abstract class gtTestSubject {
 1039: 
 1040:   protected $optionalArgumentNames;
 1041:   protected $mandatoryArgumentNames;
 1042: 
 1043:   protected $extraArgumentList = '';
 1044:   protected $shortArgumentList = '';
 1045: 
 1046:   protected $allowedArgumentLists;
 1047: 
 1048:   protected $maximumArgumentList;
 1049:   
 1050:   protected $initialisationStatements;
 1051: 
 1052: 
 1053:   /** Return the list of all mandatory argument names
 1054:    *
 1055:    * @return array
 1056:    */
 1057:   public function getMandatoryArgumentNames() {
 1058:     return $this->mandatoryArgumentNames;
 1059:   }
 1060: 
 1061: 
 1062:   /**
 1063:    * Return the list of all optional argument names
 1064:    *
 1065:    * @return array
 1066:    */
 1067:   public function getOptionalArgumentNames() {
 1068:     return $this->optionalArgumentNames;
 1069:   }
 1070:   
 1071:   public function setArgumentLists() {
 1072:     $this->setValidArgumentLists();
 1073:     $this->setExtraArgumentList();
 1074:     $this->setShortArgumentList();
 1075:   }
 1076: 
 1077:   /**
 1078:    * Set the argument list to call the subject with. Adds one extra argument.
 1079:    *
 1080:    */
 1081:   public function setExtraArgumentList() {
 1082:     if(count ($this->mandatoryArgumentNames) > 0) {
 1083:       for( $i = 0; $i < count( $this->mandatoryArgumentNames ); $i++) {
 1084:         $this->extraArgumentList .= "\$".$this->mandatoryArgumentNames[$i].", ";
 1085:       }
 1086:     }
 1087:      
 1088:     if(count ($this->optionalArgumentNames) > 0) {
 1089:       for( $i = 0; $i < count( $this->optionalArgumentNames ); $i++) {
 1090:         $this->extraArgumentList .=  "\$".$this->optionalArgumentNames[$i].", ";
 1091:       }
 1092:     }
 1093: 
 1094:     $this->extraArgumentList= $this->extraArgumentList. "\$extra_arg";
 1095:   }
 1096:    
 1097: 
 1098:   /**
 1099:    * Return the list of arguments as it appears in the function call
 1100:    *
 1101:    * @return string - list of arguments
 1102:    */
 1103:   public function getExtraArgumentList() {
 1104:     return $this->extraArgumentList;
 1105:   }
 1106: 
 1107: 
 1108:   /**
 1109:    * Set the list of function arguments to be one less that the number of mandatory arguments
 1110:    *
 1111:    */
 1112:   public function setShortArgumentList() {
 1113: 
 1114:     if(count ($this->mandatoryArgumentNames) > 0) {
 1115:       for( $i = 0; $i < count( $this->mandatoryArgumentNames ) - 1; $i++) {
 1116:         $this->shortArgumentList .= "\$".$this->mandatoryArgumentNames[$i].", ";
 1117:       }
 1118:       $this->shortArgumentList = substr($this->shortArgumentList, 0, -2);
 1119:     }
 1120:   }
 1121: 
 1122: 
 1123:   /**
 1124:    * Return the short list of arguments
 1125:    *
 1126:    * @return string - list of arguments
 1127:    */
 1128:   public function getShortArgumentList() {
 1129:     return $this->shortArgumentList;
 1130:   }
 1131: 
 1132: 
 1133:   /**
 1134:    * Construct the list of all possible ways to call the subject (function or method)
 1135:    *
 1136:    */
 1137:   public function setValidArgumentLists() {
 1138:     $this->allowedArgumentLists[0] = '';
 1139:     if(count ($this->mandatoryArgumentNames) > 0) {
 1140:       for( $i = 0; $i < count( $this->mandatoryArgumentNames ); $i++) {
 1141:         $this->allowedArgumentLists[0] .= "\$".$this->mandatoryArgumentNames[$i].", ";
 1142:       }
 1143:     }
 1144:      
 1145:     if(count ($this->optionalArgumentNames) > 0) {
 1146:       for( $i = 0; $i < count( $this->optionalArgumentNames ); $i++) {
 1147:         $this->allowedArgumentLists[] = $this->allowedArgumentLists[$i]."\$".$this->optionalArgumentNames[$i].", ";
 1148:         $this->allowedArgumentLists[$i] = substr ($this->allowedArgumentLists[$i], 0, -2);
 1149:       }
 1150:     }
 1151: 
 1152:     $this->allowedArgumentLists[count($this->allowedArgumentLists) -1 ] = substr($this->allowedArgumentLists[count($this->allowedArgumentLists) -1 ], 0, -2);
 1153:   }
 1154: 
 1155: 
 1156:   /**
 1157:    * Return the array of all possible sets of method/function arguments
 1158:    *
 1159:    * @return unknown
 1160:    */
 1161:   public function getValidArgumentLists() {
 1162:     return $this->allowedArgumentLists;
 1163:   }
 1164: 
 1165: 
 1166:   /**
 1167:    * Returns the argument list with teh greatest possible number of arguments.
 1168:    *
 1169:    * @return string
 1170:    */
 1171:   public function getMaximumArgumentList() {
 1172:     return end($this->allowedArgumentLists);
 1173:   }
 1174: 
 1175: 
 1176:   /**
 1177:    * Write initialisation statemenst for all the variables that might be used
 1178:    *
 1179:    */
 1180:   public function setInitialisationStatements() {
 1181:     if(count ($this->mandatoryArgumentNames) > 0) {
 1182:       foreach( $this->mandatoryArgumentNames as $name) {
 1183:         $this->initialisationStatements[] = "\$".$name." = ";
 1184:       }
 1185:     }
 1186:     if(count ($this->optionalArgumentNames) > 0) {
 1187:       foreach( $this->optionalArgumentNames as $name) {
 1188:         $this->initialisationStatements[] = "\$".$name." = ";
 1189:       }
 1190:     }
 1191:   }
 1192:   
 1193:   /**
 1194:    * Return the initialisation statements
 1195:    *
 1196:    * @return unknown
 1197:    */
 1198:   public function getInitialisationStatements() {
 1199:     return $this->initialisationStatements;
 1200:   }
 1201: }
 1202: ?><?php
 1203: /**
 1204:  * Container for all possible variation test cases for a method
 1205:  */
 1206: class gtVariationContainerMethod extends gtVariationContainer {
 1207:   
 1208:   protected $method;
 1209:   protected $optionalSections;
 1210:   
 1211:   public function __construct($osl) {
 1212:     $this->optionalSections = $osl;
 1213:   }
 1214:   
 1215:   
 1216:   /**
 1217:    * Sets the method to be tested
 1218:    *
 1219:    * @param gtMethod $method
 1220:    */
 1221:   public function setMethod(gtMethod $method) {
 1222:     $this->method = $method;
 1223:   }
 1224:   
 1225:   
 1226:   /**
 1227:    * Constructs all variation tests in $this_variationTests
 1228:    *
 1229:    */
 1230:   public function constructAll() {
 1231:     
 1232:     $numberOfArguments = count($this->method->getMandatoryArgumentNames()) + count($this->method->getOptionalArgumentNames());
 1233:     
 1234:     for($i = 1; $i <= $numberOfArguments; $i++) {
 1235:       
 1236:       foreach ($this->dataTypes as $d) {
 1237:         
 1238:         $testCase = gtVariationTestCase::getInstance($this->optionalSections, 'method');
 1239:         $testCase->setUp($this->method, $i, $d);
 1240:         $testCase->constructTestCase();
 1241:         $this->variationTests[] = $testCase->toString();
 1242:         
 1243:       }
 1244:     }
 1245:   }  
 1246: }
 1247: ?><?php
 1248: 
 1249: /**
 1250:  * Class for basic test case construction for class methods
 1251:  */
 1252: class gtBasicTestCaseMethod extends gtBasicTestCase {
 1253: 
 1254:   public function __construct($opt) {
 1255:     $this->optionalSections = $opt;
 1256:   }
 1257: 
 1258:   /**
 1259:    * Set the method 
 1260:    *
 1261:    * @param gtMethod $method
 1262:    */
 1263:   public function setMethod($method) {
 1264:     $this->subject = $method;
 1265:   }
 1266:   
 1267: public function constructTestCase() {
 1268:     $this->constructCommonHeaders();
 1269: 
 1270:     $this->addBasicEcho();
 1271:     
 1272:     $this->constructorArgInit();
 1273:     $this->constructorCreateInstance();
 1274:     
 1275:     $this->constructSubjectCalls();
 1276:     
 1277:     $this->constructCommonClosing();
 1278:     
 1279:   }
 1280: 
 1281:   public function testHeader() {
 1282:     $this->testCase[] = "--TEST--";
 1283:     $this->testCase[] = "Test class ".$this->subject->getClassName()." method  ".$this->subject->getName()."() by calling it with its expected arguments";
 1284:     
 1285:   }
 1286:   
 1287:   public function subjectCalls() {
 1288:     $lists = $this->subject->getValidArgumentLists();
 1289: 
 1290:     foreach($lists as $list){
 1291:       $this->testCase[] = "var_dump( \$class->".$this->subject->getName()."( ".$list." ) );";
 1292:       $this->testCase = gtCodeSnippet::appendBlankLines(1, $this->testCase );
 1293:     }
 1294:     $this->testCase = gtCodeSnippet::appendBlankLines(2, $this->testCase );    
 1295:   }
 1296: 
 1297: }
 1298: ?><?php
 1299: 
 1300: /**
 1301:  * Class for simple errors - one too many args and one too few
 1302:  */
 1303: 
 1304: abstract class gtErrorTestCase extends gtTestCase {
 1305: 
 1306:   protected $shortArgumentList = '';
 1307:   protected $longArgumentList = '';
 1308: 
 1309: 
 1310:   /**
 1311:    * Return instance of either method or function error test case
 1312:    *
 1313:    * @param string $type
 1314:    * @return test case object
 1315:    */
 1316:   public static function getInstance($optionalSections, $type = 'function') {
 1317:      
 1318:     if($type == 'function') {
 1319:       return new gtErrorTestCaseFunction($optionalSections);
 1320:     }
 1321:     if($type =='method') {
 1322:       return new gtErrorTestCaseMethod($optionalSections);
 1323:     }
 1324: 
 1325:   }
 1326: 
 1327:   public function getShortArgumentList() {
 1328:     return $this->shortArgumentList;
 1329:   }
 1330: 
 1331:   public function getLongArgumentList() {
 1332:     return $this->longArgumentList;
 1333:   }
 1334:   
 1335:   public function constructSubjectCalls() {
 1336:     $this->argInit();
 1337:     
 1338:     //Initialise the additional argument
 1339:     $this->testCase[] = "\$extra_arg = ";
 1340:     
 1341:     $this->subjectCalls();
 1342:   }
 1343:   
 1344:  public function addErrorEcho() {
 1345:     $this->testCase[] = "echo \"*** Test by calling method or function with incorrect numbers of arguments ***\\n\"";
 1346:     $this->testCase = gtCodeSnippet::appendBlankLines(1, $this->testCase );
 1347:   }
 1348: }
 1349: 
 1350: ?><?php
 1351: 
 1352: /**
 1353:  * Class for all test cases
 1354:  */
 1355: abstract class gtTestCase {
 1356: 
 1357: 
 1358:   /**
 1359:    * The subject of the test, may be either a function (gtFunction) or a method (gtMethod)
 1360:    *
 1361:    * @var gtMethod or gtFunction
 1362:    */
 1363:   protected $subject;
 1364: 
 1365: 
 1366:   /**
 1367:    * Arry of strings containing the test case
 1368:    *
 1369:    * @var array
 1370:    */
 1371:   protected $testCase;
 1372: 
 1373: 
 1374:   /**
 1375:    * Object containing teh ooptional sections that may be added to the test case
 1376:    *
 1377:    * @var gtOptionalSections
 1378:    */
 1379:   protected $optionalSections;
 1380: 
 1381: 
 1382:   /**
 1383:    * Convert test case from array to string
 1384:    *
 1385:    * @return string
 1386:    */
 1387:   public function toString() {
 1388:     $testCaseString = "";
 1389:     foreach($this->testCase as $line) {
 1390:       $testCaseString .= $line."\n";
 1391:     }
 1392:     return $testCaseString;
 1393:   }
 1394: 
 1395: 
 1396: 
 1397:   /**
 1398:    * Returns test case as a array
 1399:    *
 1400:    * @return array
 1401:    */
 1402:   public function getTestCase() {
 1403:     return $this->testCase;
 1404:   }
 1405: 
 1406: 
 1407:   /**
 1408:    * Construct the common headers (title, file section..) of the test case
 1409:    *
 1410:    */
 1411:   public function ConstructCommonHeaders() {
 1412:     $this->testHeader();
 1413: 
 1414:     if($this->optionalSections->hasSkipif()) {
 1415:       $this->addSkipif();
 1416:     }
 1417: 
 1418:     if($this->optionalSections->hasIni()) {
 1419:       $this->addIni();
 1420:     }
 1421: 
 1422:     $this->fileOpening();
 1423:   }
 1424: 
 1425: 
 1426:   /**
 1427:    * Construct the common closing statements (clean, done, EXPECTF...)
 1428:    *
 1429:    */
 1430:   public function ConstructCommonClosing() {
 1431:     $this->fileClosing();
 1432:      
 1433:     if ($this->optionalSections->hasDone()) {
 1434:       $this->addDone();
 1435:     }
 1436:      
 1437:     if ($this->optionalSections->hasClean()) {
 1438:       $this->addClean();
 1439:     }
 1440: 
 1441:     $this->addExpectf();
 1442:   }
 1443: 
 1444:   /**
 1445:    * Start the FILE section of the test
 1446:    *
 1447:    */
 1448:   public function fileOpening() {
 1449:     $this->testCase[] = "--FILE--";
 1450:     $this->testCase[] = "<?php";
 1451:     $this->testCase = gtCodeSnippet::appendBlankLines(2, $this->testCase );
 1452:   }
 1453: 
 1454: 
 1455:   /**
 1456:    * Add constructor argument initialisation to test case
 1457:    *
 1458:    */
 1459:   public function constructorArgInit() {
 1460:     $conStatements = $this->subject->getConstructorInitStatements();
 1461:     foreach($conStatements as $statement) {
 1462:       $this->testCase[] = $statement;
 1463:     }
 1464:   }
 1465: 
 1466: 
 1467:   /**
 1468:    * Create instance of class in the test case
 1469:    *
 1470:    */
 1471:   public function constructorCreateInstance() {
 1472:     $constructorList = $this->subject->getConstructorArgumentList();
 1473:     $this->testCase[] = "\$class = new ".$this->subject->getClassName()."( ".$constructorList." );";
 1474:     $this->testCase = gtCodeSnippet::appendBlankLines(2, $this->testCase );
 1475:   }
 1476: 
 1477: 
 1478:   /**
 1479:    * Add function or method initilaisation statements to the test case
 1480:    *
 1481:    */
 1482:   public function argInit() {
 1483:     $statements = $this->subject->getInitialisationStatements();
 1484:     foreach($statements as $statement) {
 1485:       $this->testCase[] = $statement;
 1486:     }
 1487:     $this->testCase = gtCodeSnippet::appendBlankLines(2, $this->testCase );
 1488:   }
 1489: 
 1490: 
 1491:   /**
 1492:    * Add FILE section closing tag to teh test case
 1493:    *
 1494:    */
 1495:   public function fileClosing() {
 1496:     $this->testCase[] = "?>";
 1497:   }
 1498: 
 1499: 
 1500:   /**
 1501:    * Add a skipif section to the test case
 1502:    *
 1503:    */
 1504:   public function addSkipif() {
 1505:     $this->testCase[] = "--SKIPIF--";
 1506:     $this->testCase[] = "<?php";
 1507:     if($this->optionalSections->hasSkipifKey()) {
 1508:       $key = $this->optionalSections->getSkipifKey();
 1509:       //test standard skipif sections
 1510:       if($key == 'win') {
 1511:         $this->testCase = gtCodeSnippet::append('skipifwin', $this->testCase);
 1512:       }
 1513:       if($key == 'notwin' ) {
 1514:         $this->testCase = gtCodeSnippet::append('skipifnotwin', $this->testCase);
 1515:       }
 1516: 
 1517:       if($key == '64b' ) {
 1518:         $this->testCase = gtCodeSnippet::append('skipif64b', $this->testCase);
 1519:       }
 1520: 
 1521:       if($key == 'not64b' ) {
 1522:         $this->testCase = gtCodeSnippet::append('skipifnot64b', $this->testCase);
 1523:       }
 1524:     }
 1525: 
 1526:     if($this->optionalSections->hasSkipifExt()) {
 1527:       $ext = $this->optionalSections->getSkipifExt();
 1528:       $this->testCase[] = "if (!extension_loaded('$ext')) die ('skip $ext extension not available in this build');";
 1529:     }
 1530:     $this->testCase[] = "?>";
 1531:   }
 1532: 
 1533: 
 1534:   /**
 1535:    * Add an INI section to the test case
 1536:    *
 1537:    */
 1538:   public function addIni() {
 1539:     $this->testCase[] = "--INI--";
 1540:     $this->testCase[] = "";
 1541:   }
 1542: 
 1543: 
 1544:   /**
 1545:    * Add a clean section to the test case
 1546:    *
 1547:    */
 1548:   public function addClean() {
 1549:     $this->testCase[] = "--CLEAN--";
 1550:     $this->testCase[] = "<?php";
 1551:     $this->testCase[] = "?>";
 1552:   }
 1553: 
 1554: 
 1555:   /**
 1556:    * Add a ===DONE=== statement to the test case
 1557:    *
 1558:    */
 1559:   public function addDone() {
 1560:     $this->testCase[] = "===DONE===";
 1561:   }
 1562: 
 1563: 
 1564:   /**
 1565:    * Add an EXPECTF section
 1566:    *
 1567:    */
 1568:   public function addExpectf() {
 1569:     $this->testCase[] = "--EXPECTF--";
 1570:     if ($this->optionalSections->hasDone() ){
 1571:       $this->testCase[] = '===DONE===';
 1572:     }
 1573:   }
 1574: 
 1575:   public function getOpt() {
 1576:     return $this->optionalSections;
 1577:   }
 1578: }
 1579: ?><?php
 1580: 
 1581: /**
 1582:  * Basic test case for a PHP function
 1583:  *
 1584:  */
 1585: class gtBasicTestCaseFunction extends gtBasicTestCase {
 1586: 
 1587: 
 1588:   public function __construct($opt) {
 1589:     $this->optionalSections = $opt;
 1590:   }
 1591: 
 1592:   /**
 1593:    * Set the function name
 1594:    *
 1595:    * @param gtFunction $function
 1596:    */
 1597:   public function setFunction($function) {
 1598:     $this->subject = $function;
 1599:   }
 1600: 
 1601:   public function constructTestCase() {
 1602:     $this->constructCommonHeaders();
 1603:     
 1604:     $this->addBasicEcho();
 1605:     
 1606:     $this->constructSubjectCalls();
 1607:     
 1608:     $this->constructCommonClosing();
 1609:    
 1610:   }
 1611: 
 1612: 
 1613:   /**
 1614:    * Construct test case header
 1615:    *
 1616:    */
 1617:   public function testHeader() {
 1618:     //Opening section and start of test case array.
 1619:     $this->testCase[] = "--TEST--";
 1620:     $this->testCase[] = "Test function ".$this->subject->getName()."() by calling it with its expected arguments";
 1621:   }
 1622: 
 1623:   /**
 1624:    * Add the test section to call the function
 1625:    *
 1626:    */
 1627:   public function subjectCalls() {
 1628:     // Construct the argument list to pass to the function being tested
 1629:     $lists = $this->subject->getValidArgumentLists();
 1630: 
 1631:     foreach($lists as $list){
 1632: 
 1633:       $this->testCase = gtCodeSnippet::appendBlankLines(1, $this->testCase );
 1634:       $this->testCase[] = "var_dump(".$this->subject->getName()."( ".$list." ) );";
 1635:     }
 1636:     $this->testCase = gtCodeSnippet::appendBlankLines(2, $this->testCase );
 1637:   }
 1638: 
 1639: }
 1640: ?><?php
 1641: 
 1642: /**
 1643:  * Error test case for a PHP function
 1644:  *
 1645:  */
 1646: class gtErrorTestCaseFunction extends gtErrorTestCase {
 1647: 
 1648:   public function __construct($opt) {
 1649:     $this->optionalSections = $opt;
 1650:   }
 1651: 
 1652:   /**
 1653:    * Set the function name
 1654:    *
 1655:    * @param string $function
 1656:    */
 1657:   public function setFunction($function) {
 1658:     $this->subject = $function;
 1659:   }
 1660: 
 1661: 
 1662:   /**
 1663:    * Construct the test case as an array of strings
 1664:    *
 1665:    */
 1666:   public function constructTestCase() {
 1667:     $this->constructCommonHeaders();
 1668:     
 1669:     $this->addErrorEcho();
 1670:       
 1671:     $this->constructSubjectCalls();
 1672:     
 1673:     $this->constructCommonClosing();
 1674:     
 1675:   }
 1676: 
 1677: 
 1678:   public function testHeader() {
 1679:     $this->testCase[] = "--TEST--";
 1680:     $this->testCase[] = "Test function ".$this->subject->getName()."() by calling it more than or less than its expected arguments";
 1681:   }
 1682: 
 1683:   public function subjectCalls() {
 1684:     // Construct the argument lists to pass to the function being tested
 1685:     $list = $this->subject->getExtraArgumentList();
 1686:     $this->testCase = gtCodeSnippet::appendBlankLines(1, $this->testCase );
 1687:     $this->testCase[] = "var_dump(".$this->subject->getName()."( ".$list." ) );";
 1688: 
 1689:     $list = $this->subject->getShortArgumentList();
 1690:     $this->testCase = gtCodeSnippet::appendBlankLines(1, $this->testCase );
 1691:     $this->testCase[] = "var_dump(".$this->subject->getName()."( ".$list." ) );";
 1692:     $this->testCase = gtCodeSnippet::appendBlankLines(2, $this->testCase );
 1693:   }
 1694: 
 1695: }
 1696: ?><?php
 1697: 
 1698: /**
 1699:  * Class for variation tests for a PHP function
 1700:  */
 1701: class gtVariationTestCaseFunction extends gtVariationTestCase {
 1702: 
 1703:   protected $argumentNumber;
 1704:   protected $variationData;
 1705:   protected $testCase;
 1706: 
 1707:   public function __construct($opt) {
 1708:     $this->optionalSections = $opt;
 1709:   }
 1710:   /**
 1711:    * Set data neede to construct variation tests
 1712:    *
 1713:    * @param gtfunction $function
 1714:    * @param string $argumentNumber
 1715:    * @param string $variationData
 1716:    */
 1717:   public function setUp(gtfunction $function, $argumentNumber, $variationData) {
 1718:     $this->subject = $function;
 1719:     $this->argumentNumber = $argumentNumber;
 1720:     $this->variationData = $variationData;
 1721: 
 1722:   }
 1723: 
 1724: 
 1725:   /**
 1726:    * Constructs  the test case as a array of strings
 1727:    *
 1728:    */
 1729:   public function constructTestCase() {
 1730:     $this->constructCommonHeaders(); 
 1731:       
 1732:     $this->addVariationEcho();
 1733:     
 1734:     $this->constructSubjectCalls();
 1735:     
 1736:     $this->constructCommonClosing();
 1737:     
 1738:   }
 1739:   public function testHeader() {
 1740:     $this->testCase[] = "--TEST--";
 1741:     $this->testCase[] = "Test function ".$this->subject->getName()."() by substituting argument ".$this->argumentNumber." with ".$this->variationData." values.";
 1742:   }
 1743: 
 1744:   
 1745:   public function subjectCalls() { 
 1746:     $this->testCase = gtCodeSnippet::append('loopStart', $this->testCase);
 1747: 
 1748:     // Construct the argument list to pass to the function being tested
 1749:     $argumentList = explode(",", $this->subject->getMaximumArgumentList());
 1750:     $argumentList[$this->argumentNumber -1 ] = "\$var ";
 1751:     $list = implode(", ", $argumentList);
 1752: 
 1753: 
 1754:     $this->testCase[] = "  var_dump(".$this->subject->getName()."( ".$list." ) );";
 1755:     $this->testCase = gtCodeSnippet::append('loopClose', $this->testCase);
 1756:   }
 1757:    
 1758: }
 1759: ?><?php
 1760: 
 1761: /**
 1762:  * Container for all possible variation test cases of functions
 1763:  */
 1764: class gtVariationContainerFunction extends gtVariationContainer {
 1765:   
 1766:   protected $function;
 1767:   protected $optionalSections;
 1768:   
 1769:   public function __construct($osl) {
 1770:     $this->optionalSections = $osl;
 1771:   }
 1772:   
 1773:   /**
 1774:    * Sets function being tested
 1775:    *
 1776:    * @param gtFunction $function
 1777:    */
 1778:   public function setFunction(gtFunction $function) {
 1779:     $this->function = $function;
 1780:   }
 1781:   
 1782:   
 1783:   /**
 1784:    * constructs all possible variation testcases in array $this->variationTests
 1785:    *
 1786:    */
 1787:   public function constructAll() {
 1788:     
 1789:         
 1790:     $numberOfArguments = count($this->function->getMandatoryArgumentNames()) + count($this->function->getOptionalArgumentNames());
 1791:     for($i = 1; $i <= $numberOfArguments; $i++) {
 1792:       foreach ($this->dataTypes as $d) {
 1793:         $testCase = gtVariationTestCase::getInstance($this->optionalSections);
 1794:         $testCase->setUp($this->function, $i, $d);
 1795:         $testCase->constructTestCase();
 1796:         $this->variationTests[] = $testCase->toString();
 1797:       }
 1798:     }
 1799:   }  
 1800: }
 1801: ?><?php
 1802: 
 1803: /**
 1804:  * Error test case for a PHP method
 1805:  *
 1806:  */
 1807: class gtErrorTestCaseMethod extends gtErrorTestCase {
 1808: 
 1809:   public function __construct($opt) {
 1810:     $this->optionalSections = $opt;
 1811:   }
 1812:   private $method;
 1813: 
 1814:   /**
 1815:    * Set the method name
 1816:    *
 1817:    * @param string $method
 1818:    */
 1819:   public function setMethod($method) {
 1820:     $this->subject = $method;
 1821:   }
 1822: 
 1823: 
 1824:   /**
 1825:    * Construct the test case as an array of strings
 1826:    *
 1827:    */
 1828:   public function constructTestCase() {
 1829:     $this->constructCommonHeaders();
 1830:     
 1831:     $this->addErrorEcho();
 1832:     
 1833:     $this->constructorArgInit();
 1834:     $this->constructorCreateInstance();
 1835:     
 1836:     $this->constructSubjectCalls();
 1837:     
 1838:     $this->constructCommonClosing();
 1839:   }
 1840:  
 1841:   public function testHeader() {
 1842:     $this->testCase[] = "--TEST--";
 1843:     $this->testCase[] = "Test class ".$this->subject->getClassName()." method ".$this->subject->getName()."() by calling it more than or less than its expected arguments";
 1844:   }
 1845:  
 1846:   public function subjectCalls() {
 1847: 
 1848:     // Construct the argument list to pass to the method being tested
 1849:     $list = $this->subject->getExtraArgumentList();
 1850:     $this->testCase = gtCodeSnippet::appendBlankLines(1, $this->testCase );
 1851:     $this->testCase[] = "var_dump(".$this->subject->getName()."( ".$list." ) );";
 1852:     
 1853:     $list = $this->subject->getShortArgumentList();
 1854:     $this->testCase = gtCodeSnippet::appendBlankLines(1, $this->testCase );
 1855:     $this->testCase[] = "var_dump(".$this->subject->getName()."( ".$list." ) );";
 1856:   
 1857:   }
 1858: }
 1859: ?><?php
 1860: 
 1861: /**
 1862:  * Class for basic test case construction
 1863:  */
 1864: 
 1865: abstract class gtBasicTestCase extends gtTestCase {
 1866: 
 1867:   protected $subject;
 1868: 
 1869: 
 1870:   /**
 1871:    * Returns an instance of a test case for a method or a function
 1872:    *
 1873:    * @param string $type
 1874:    * @return test case object
 1875:    */
 1876:   public static function getInstance($optionalSections, $type = 'function') {
 1877:     if($type == 'function') {
 1878:       return new gtBasicTestCaseFunction($optionalSections);
 1879:     }
 1880:     if($type =='method') {
 1881:       return new gtBasicTestCaseMethod($optionalSections);
 1882:     }
 1883:   }
 1884:   
 1885:   public function constructSubjectCalls() {
 1886:         $this->argInit();
 1887:         $this->subjectCalls();
 1888:   }
 1889:   
 1890:   public function addBasicEcho() {
 1891:     $this->testCase[] = "echo \"*** Test by calling method or function with its expected arguments ***\\n\"";
 1892:     $this->testCase = gtCodeSnippet::appendBlankLines(1, $this->testCase );
 1893:   }
 1894: }
 1895: ?><?php
 1896: 
 1897: /**
 1898:  * Container for all possible variation test cases
 1899:  */
 1900: abstract class gtVariationContainer {
 1901:   
 1902:   protected $variationTests;
 1903:   
 1904:   protected $dataTypes = array (
 1905:                          'array',
 1906:                          'boolean',
 1907:                          'emptyUnsetUndefNull',
 1908:                          'float',
 1909:                          'int',
 1910:                          'object',
 1911:                          'string',
 1912:                          );
 1913:   
 1914:   
 1915:                      
 1916:   /**
 1917:    * Return an instance of a containers for either function or method tests
 1918:    *
 1919:    * @param string $type
 1920:    * @return variation test container
 1921:    */
 1922:    public static function getInstance ($optionalSections, $type = 'function') {
 1923:     
 1924:     if($type == 'function') {
 1925:       return new gtVariationContainerFunction($optionalSections);
 1926:     }
 1927:     if($type =='method') {
 1928:       return new gtVariationContainerMethod($optionalSections);
 1929:     }
 1930:     
 1931:   }
 1932:   
 1933:   
 1934:   public function constructAll() {
 1935:   }
 1936:   
 1937:   
 1938:   /**
 1939:    * Returns all varaition tests as an array of arrays
 1940:    *
 1941:    * @return string
 1942:    */
 1943:   public function getVariationTests() {
 1944:     return $this->variationTests;
 1945:   }
 1946:   
 1947: }
 1948: ?>
 1949: <?php
 1950: 
 1951: /**
 1952:  * Class for extended variations. Needs 'data type' and argument to vary
 1953:  */
 1954: 
 1955: abstract class gtVariationTestCase extends gtTestCase {
 1956: 
 1957: 
 1958:   /**
 1959:    * Returns an instance of a test case for a method or a function
 1960:    *
 1961:    * @param string $type
 1962:    * @return test case object
 1963:    */
 1964:   public static function getInstance($optionalSections, $type = 'function') {
 1965:      
 1966:     if($type == 'function') {
 1967:       return new gtVariationTestCaseFunction($optionalSections);
 1968:     }
 1969:     if($type =='method') {
 1970:       return new gtVariationTestCaseMethod($optionalSections);
 1971:     }
 1972: 
 1973:   }
 1974: 
 1975:   public function argInitVariation() {
 1976:     $statements = $this->subject->getInitialisationStatements();
 1977:     for($i=0; $i<count($statements); $i++) {
 1978:       if($i != ( $this->argumentNumber -1) ) {
 1979:         $this->testCase[] = $statements[$i];
 1980:       }
 1981:     }
 1982:     $this->testCase = gtCodeSnippet::appendBlankLines(2, $this->testCase );
 1983:   }
 1984: 
 1985:   public function addVariationCode() {
 1986:     $this->testCase = gtCodeSnippet::append($this->variationData, $this->testCase);
 1987:     $this->testCase = gtCodeSnippet::appendBlankLines(2, $this->testCase );
 1988:   }
 1989: 
 1990:   public function constructSubjectCalls() {
 1991:     $this->argInitVariation();
 1992:     $this->addVariationCode();
 1993:     $this->subjectCalls();
 1994:   }
 1995: 
 1996:   public function addVariationEcho() {
 1997:     $this->testCase[] = "echo \"*** Test substituting argument ".$this->argumentNumber." with ".$this->variationData." values ***\\n\";";
 1998:     $this->testCase = gtCodeSnippet::appendBlankLines(1, $this->testCase );
 1999:   }
 2000: 
 2001: }
 2002: ?><?php
 2003: 
 2004: /**
 2005:  * Class for variation tests for a PHP method
 2006:  */
 2007: class gtVariationTestCaseMethod extends gtVariationTestCase {
 2008: 
 2009:   protected $subject;
 2010:   protected $argumentNumber;
 2011:   protected $variationData;
 2012:   protected $testCase;
 2013: 
 2014:   public function __construct($opt) {
 2015:     $this->optionalSections = $opt;
 2016:   }
 2017: 
 2018:   /**
 2019:    * Set data neede to construct variation tests
 2020:    *
 2021:    * @param gtMethod $method
 2022:    * @param string $argumentNumber
 2023:    * @param string $variationData
 2024:    */
 2025:   public function setUp(gtMethod $method, $argumentNumber, $variationData) {
 2026:     $this->subject = $method;
 2027:     $this->argumentNumber = $argumentNumber;
 2028:     $this->variationData = $variationData;
 2029:   }
 2030: 
 2031: 
 2032:   /**
 2033:    * Constructs the test case as a array of strings
 2034:    *
 2035:    */
 2036:   public function constructTestCase() {
 2037:     $this->constructCommonHeaders();
 2038:     
 2039:     $this->addVariationEcho();
 2040:     
 2041:     $this->constructorArgInit();
 2042:     $this->constructorCreateInstance();
 2043:     
 2044:     $this->constructSubjectcalls();
 2045:     $this->constructCommonClosing();
 2046:     
 2047:   }
 2048: 
 2049:   public function testHeader() {
 2050:     $this->testCase[] = "--TEST--";
 2051:     $this->testCase[] = "Test class ".$this->subject->getClassName()." method ".$this->subject->getName()."() by substituting argument ".$this->argumentNumber." with ".$this->variationData." values.";
 2052:   }
 2053: 
 2054:   public function subjectCalls() {
 2055:     $this->testCase = gtCodeSnippet::append('loopStart', $this->testCase);
 2056:     // Construct the argument list to pass to the method being tested
 2057:     $argumentList = explode(",", $this->subject->getMaximumArgumentList());
 2058:     $argumentList[$this->argumentNumber -1 ] = "\$var ";
 2059:     $list = implode(", ", $argumentList);
 2060: 
 2061: 
 2062:     $this->testCase[] = "  var_dump(\$class->".$this->subject->getName()."( ".$list." ) );";
 2063:     $this->testCase = gtCodeSnippet::append('loopClose', $this->testCase);
 2064: 
 2065:   }
 2066: 
 2067: }
 2068: 
 2069: ?>:yD7`_gDUGBMB

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>