Source for file Ethna_UnitTestManager.php

Documentation is available at Ethna_UnitTestManager.php

  1. <?php
  2. /**
  3.  *  Ethna_UnitTestManager.php
  4.  *
  5.  *  @author     Takuya Ookubo <sfio@sakura.ai.to>
  6.  *  @license    http://www.opensource.org/licenses/bsd-license.php The BSD License
  7.  *  @package    Ethna
  8.  *  @version    $Id: Ethna_UnitTestManager.php 515 2008-04-30 10:53:42Z mumumu-org $
  9.  */
  10.  
  11. require_once('simpletest/unit_tester.php');
  12. require_once('Ethna_UnitTestCase.php');
  13. require_once('Ethna_UnitTestReporter.php');
  14.  
  15. /**
  16.  *  Ethnaユニットテストマネージャクラス
  17.  *
  18.  *  @author     Takuya Ookubo <sfio@sakura.ai.to>
  19.  *  @access     public
  20.  *  @package    Ethna
  21.  */
  22. {
  23.     /** @var    object  Ethna_Controller    コントローラオブジェクト */
  24.     var $ctl;
  25.  
  26.     /** @var    array                       一般テストケース定義 */
  27.     var $testcase = array();
  28.  
  29.     /**
  30.      *  Ethna_UnitTestManagerのコンストラクタ
  31.      *
  32.      *  @access public
  33.      *  @param  object  Ethna_Backend   &$backend   Ethna_Backendオブジェクト
  34.      */
  35.     function Ethna_UnitTestManager(&$backend)
  36.     {
  37.         parent::Ethna_AppManager($backend);
  38.         $this->ctl =Ethna_Controller::getInstance();
  39.         $this->class_factory =$this->ctl->getClassFactory();
  40.         $this->testcase = array_merge($this->testcase$this->_getTestCaseList())
  41.     }
  42.  
  43.     /**
  44.      *  action, view 以外のテストケースの一覧を取得する
  45.      *
  46.      *  @access private
  47.      *  @param  テストケースが含まれているディレクトリ名 
  48.      */
  49.     function _getTestCaseList($test_dir NULL)
  50.     {
  51.         $r array();
  52.  
  53.         if (is_null($test_dir)) {
  54.             $test_dir $this->ctl->getTestdir();
  55.         }
  56.         $base $this->ctl->getBasedir();
  57.  
  58.         $child_dir_list array();
  59.  
  60.         $dh opendir($test_dir);
  61.         if ($dh == false{
  62.             return;
  63.         }
  64.  
  65.         $ext $this->ctl->getExt('php');
  66.         while (($file readdir($dh)) !== false{
  67.             if ($file == "." || $file == ".."{
  68.                 continue;
  69.             }
  70.             $file $test_dir $file;
  71.  
  72.             if (is_dir($file)) {
  73.                 $child_dir_list[$file;
  74.                 continue;
  75.             }
  76.  
  77.             if (preg_match("/\.$ext\$/"$file== 0{
  78.                 continue;
  79.             }
  80.  
  81.             $file str_replace($this->ctl->getTestdir()''$file);
  82.  
  83.             $key ereg_replace("^(.*)Test\.$ext"'\1'$file);
  84.             $key str_replace('/'''$key);
  85.  
  86.             $r[$keystr_replace($base '/'''$this->ctl->getTestdir($file);
  87.         }
  88.  
  89.         closedir($dh);
  90.  
  91.         foreach ($child_dir_list as $child_dir{
  92.             $tmp $this->_getTestCaseList($child_dir "/");
  93.             $r array_merge($r$tmp);
  94.         }
  95.  
  96.         return $r;
  97.     }
  98.  
  99.     /**
  100.      *  定義済みアクション一覧を取得する
  101.      *
  102.      *  @access public
  103.      *  @return array   アクション一覧
  104.      */
  105.     function _getActionList()
  106.     {
  107.         $im =new Ethna_InfoManager($this->backend);
  108.         return $im->getActionList();
  109.     }
  110.  
  111.     /**
  112.      *  クラス名からビュー名を取得する
  113.      *
  114.      *  @access public
  115.      *  @param  string  $class_name     ビュークラス名
  116.      *  @return string  アクション名
  117.      */
  118.     function viewClassToName($class_name)
  119.     {
  120.         $prefix sprintf("%s_View_"$this->ctl->getAppId());
  121.         if (preg_match("/$prefix(.*)/"$class_name$match== 0{
  122.             // 不明なクラス名
  123.             return null;
  124.         }
  125.         $target $match[1];
  126.  
  127.         $action_name substr(preg_replace('/([A-Z])/e'"'_' . strtolower('\$1')"$target)1);
  128.  
  129.         return $action_name;
  130.     }
  131.  
  132.     /**
  133.      *  指定されたクラス名を継承しているかどうかを返す
  134.      *
  135.      *  @access private
  136.      *  @param  string  $class_name     チェック対象のクラス名
  137.      *  @param  string  $parent_name    親クラス名
  138.      *  @return bool    true:継承している false:いない
  139.      */
  140.     function _isSubclassOf($class_name$parent_name)
  141.     {
  142.         while ($tmp get_parent_class($class_name)) {
  143.             if (strcasecmp($tmp$parent_name== 0{
  144.                 return true;
  145.             }
  146.             $class_name $tmp;
  147.         }
  148.         return false;
  149.     }
  150.  
  151.     /**
  152.      *  ビュースクリプトを解析する
  153.      *
  154.      *  @access private
  155.      *  @param  string  $script ファイル名
  156.      *  @return array   ビュークラス定義一覧
  157.      */
  158.     function __analyzeViewScript($script)
  159.     {
  160.         $class_list array();
  161.  
  162.         $source "";
  163.         $fp fopen($script'r');
  164.         if ($fp == false{
  165.             return null;
  166.         }
  167.         while (feof($fp== false{
  168.             $source .= fgets($fp8192);
  169.         }
  170.         fclose($fp);
  171.  
  172.         // トークンに分割してクラス定義情報を取得
  173.         $token_list token_get_all($source);
  174.         for ($i 0$i count($token_list)$i++{
  175.             $token $token_list[$i];
  176.  
  177.             if ($token[0== T_CLASS{
  178.                 // クラス定義開始
  179.                 $i += 2;
  180.                 $class_name $token_list[$i][1];       // should be T_STRING
  181.                 if ($this->_isSubclassOf($class_name'Ethna_ViewClass')) {
  182.                     $view_name $this->viewClassToName($class_name);
  183.                     $class_list[$view_namearray(
  184.                         'template_file' => $this->ctl->_getForwardPath($view_name),
  185.                         'view_class' => $class_name,
  186.                         'view_class_file' => $this->ctl->getDefaultViewPath($view_name),
  187.                     );
  188.                 }
  189.             }
  190.         }
  191.  
  192.         if (count($class_list== 0{
  193.             return null;
  194.         }
  195.         return $class_list;
  196.     }
  197.  
  198.     /**
  199.      *  ディレクトリ以下のビュースクリプトを解析する
  200.      *
  201.      *  @access private
  202.      *  @param  string  $action_dir     解析対象のディレクトリ
  203.      *  @return array   ビュークラス定義一覧
  204.      */
  205.     function __analyzeViewList($view_dir null)
  206.     {
  207.         $r array();
  208.  
  209.         if (is_null($view_dir)) {
  210.             $view_dir $this->ctl->getViewdir();
  211.         }
  212.         $prefix_len strlen($this->ctl->getViewdir());
  213.  
  214.         $ext '.' $this->ctl->getExt('php');
  215.         $ext_len strlen($ext);
  216.  
  217.         $dh opendir($view_dir);
  218.         if ($dh{
  219.             while (($file readdir($dh)) !== false{
  220.                 $path "$view_dir/$file";
  221.                 if ($file != '.' && $file != '..' && is_dir($path)) {
  222.                     $tmp $this->__analyzeViewList($path);
  223.                     $r array_merge($r$tmp);
  224.                     continue;
  225.                 }
  226.                 if (substr($file-$ext_len$ext_len!= $ext{
  227.                     continue;
  228.                 }
  229.  
  230.                 include_once($path);
  231.                 $class_list $this->__analyzeViewScript($path);
  232.                 if (is_null($class_list== false{
  233.                     $r array_merge($r$class_list);
  234.                 }
  235.             }
  236.         }
  237.         closedir($dh);
  238.  
  239.         return $r;
  240.     }
  241.  
  242.     /**
  243.      *  定義済みビュー一覧を取得する
  244.      *
  245.      *  @access public
  246.      *  @return array   ビュー一覧
  247.      */
  248.     function _getViewList()
  249.     {
  250.         $im =new Ethna_InfoManager($this->backend);
  251. //        $view_class_list = array_keys($im->getForwardList());
  252.  
  253.         $r array();
  254.  
  255.         // テンプレート/ビュースクリプトを解析する
  256.         $forward_list $im->_analyzeForwardList();
  257.         $view_list $this->__analyzeViewList();
  258.  
  259.         // ビュー定義エントリ一覧
  260.         $manifest_forward_list $im->_getForwardList_Manifest($forward_list);
  261.  
  262.         // ビュー定義省略エントリ一覧
  263.         $implicit_forward_list $im->_getForwardList_Implicit($forward_list$manifest_forward_list);
  264.  
  265.         $r array_merge($view_list$manifest_forward_list$implicit_forward_list);
  266.         ksort($r);
  267.  
  268.         return $r;
  269.     }
  270.  
  271.     /**
  272.      *  アクションテストクラスを取得する
  273.      *
  274.      *  @access private
  275.      *  @return array 
  276.      */
  277.     function _getTestAction()
  278.     {
  279.         $action_class_list array_keys($this->_getActionList());
  280.  
  281.         // テストの存在するアクション
  282.         foreach ($action_class_list as $key => $action_name{
  283.             $action_class $this->ctl->getDefaultActionClass($action_namefalse).'_TestCase';
  284.             if (!class_exists($action_class)) {
  285.                 unset($action_class_list[$key]);
  286.             }
  287.         }
  288.  
  289.         return $action_class_list;
  290.     }
  291.  
  292.     /**
  293.      *  ビューテストクラスを取得する
  294.      *
  295.      *  @access private
  296.      *  @return array 
  297.      */
  298.     function _getTestView()
  299.     {
  300.         $view_class_list array_keys($this->_getViewList());
  301.  
  302.         // テストの存在するビュー
  303.         foreach ($view_class_list as $key => $view_name{
  304.             $view_class $this->ctl->getDefaultViewClass($view_namefalse).'_TestCase';
  305.             if (!class_exists($view_class)) {
  306.                 unset($view_class_list[$key]);
  307.             }
  308.         }
  309.  
  310.         return $view_class_list;
  311.     }
  312.  
  313.     /**
  314.      *  ユニットテストを実行する
  315.      *
  316.      *  @access private
  317.      *  @return mixed   0:正常終了 Ethna_Error:エラー
  318.      */
  319.     function run()
  320.     {
  321.         $action_class_list $this->_getTestAction();
  322.         $view_class_list $this->_getTestView();
  323.  
  324.         $test =new GroupTest("Ethna UnitTest");
  325.  
  326.         // アクション
  327.         foreach ($action_class_list as $action_name{
  328.             $action_class $this->ctl->getDefaultActionClass($action_namefalse).'_TestCase';
  329.             $action_form $this->ctl->getDefaultFormClass($action_namefalse).'_TestCase';
  330.  
  331.             $test->addTestCase(new $action_class($this->ctl));
  332.             $test->addTestCase(new $action_form($this->ctl));
  333.         }
  334.  
  335.         // ビュー
  336.         foreach ($view_class_list as $view_name{
  337.             $view_class $this->ctl->getDefaultViewClass($view_namefalse).'_TestCase';
  338.  
  339.             $test->addTestCase(new $view_class($this->ctl));
  340.         }
  341.  
  342.         // 一般
  343.         foreach ($this->testcase as $class_name => $file_name{
  344.             $dir $this->ctl->getBasedir().'/';
  345.             include_once $dir $file_name;
  346.             $testcase_name $class_name.'_TestCase';
  347.             $test->addTestCase(new $testcase_name($this->ctl));
  348.         }
  349.  
  350.         // ActionFormのバックアップ
  351.         $af =$this->ctl->getActionForm();
  352.  
  353.         //出力したい形式にあわせて切り替える
  354.         $reporter new Ethna_UnitTestReporter();
  355.         $test->run($reporter);
  356.  
  357.         // ActionFormのリストア
  358.         $this->ctl->action_form =$af;
  359.         $this->backend->action_form =$af;
  360.         $this->backend->af =$af;
  361.  
  362.         return array($reporter->report$reporter->result);
  363.     }
  364. }
  365. ?>

Documentation generated on Thu, 08 May 2008 00:15:34 +0900 by phpDocumentor 1.4.2