3 * Ethna_UnitTestManager.php
5 * @author Takuya Ookubo <sfio@sakura.ai.to>
6 * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
11 require_once('simpletest/unit_tester.php');
12 require_once('Ethna_UnitTestCase.php');
13 require_once('Ethna_UnitTestReporter.php');
16 * Ethnaユニットテストマネージャクラス
18 * @author Takuya Ookubo <sfio@sakura.ai.to>
22 class Ethna_UnitTestManager extends Ethna_AppManager
24 /** @var object Ethna_Controller コントローラオブジェクト */
27 /** @var array 一般テストケース定義 */
28 var $testcase = array();
31 * Ethna_UnitTestManagerのコンストラクタ
34 * @param object Ethna_Backend &$backend Ethna_Backendオブジェクト
36 function Ethna_UnitTestManager(&$backend)
38 parent::Ethna_AppManager($backend);
39 $this->ctl =& Ethna_Controller::getInstance();
40 $this->class_factory =& $this->ctl->getClassFactory();
47 * @return array アクション一覧
49 function _getActionList()
51 $im =& new Ethna_InfoManager($this->backend);
52 return $im->getActionList();
59 * @param string $class_name ビュークラス名
60 * @return string アクション名
62 function viewClassToName($class_name)
64 $prefix = sprintf("%s_View_", $this->ctl->getAppId());
65 if (preg_match("/$prefix(.*)/", $class_name, $match) == 0) {
71 $action_name = substr(preg_replace('/([A-Z])/e', "'_' . strtolower('\$1')", $target), 1);
77 * 指定されたクラス名を継承しているかどうかを返す
80 * @param string $class_name チェック対象のクラス名
81 * @param string $parent_name 親クラス名
82 * @return bool true:継承している false:いない
84 function _isSubclassOf($class_name, $parent_name)
86 while ($tmp = get_parent_class($class_name)) {
87 if (strcasecmp($tmp, $parent_name) == 0) {
99 * @param string $script ファイル名
100 * @return array ビュークラス定義一覧
102 function __analyzeViewScript($script)
104 $class_list = array();
107 $fp = fopen($script, 'r');
111 while (feof($fp) == false) {
112 $source .= fgets($fp, 8192);
116 // トークンに分割してクラス定義情報を取得
117 $token_list = token_get_all($source);
118 for ($i = 0; $i < count($token_list); $i++) {
119 $token = $token_list[$i];
121 if ($token[0] == T_CLASS) {
124 $class_name = $token_list[$i][1]; // should be T_STRING
125 if ($this->_isSubclassOf($class_name, 'Ethna_ViewClass')) {
126 $view_name = $this->viewClassToName($class_name);
127 $class_list[$view_name] = array(
128 'template_file' => $this->ctl->_getForwardPath($view_name),
129 'view_class' => $class_name,
130 'view_class_file' => $this->ctl->getDefaultViewPath($view_name),
136 if (count($class_list) == 0) {
143 * ディレクトリ以下のビュースクリプトを解析する
146 * @param string $action_dir 解析対象のディレクトリ
147 * @return array ビュークラス定義一覧
149 function __analyzeViewList($view_dir = null)
153 if (is_null($view_dir)) {
154 $view_dir = $this->ctl->getViewdir();
156 $prefix_len = strlen($this->ctl->getViewdir());
158 $ext = '.' . $this->ctl->getExt('php');
159 $ext_len = strlen($ext);
161 $dh = opendir($view_dir);
163 while (($file = readdir($dh)) !== false) {
164 $path = "$view_dir/$file";
165 if ($file != '.' && $file != '..' && is_dir($path)) {
166 $tmp = $this->__analyzeViewList($path);
167 $r = array_merge($r, $tmp);
170 if (substr($file, -$ext_len, $ext_len) != $ext) {
175 $class_list = $this->__analyzeViewScript($path);
176 if (is_null($class_list) == false) {
177 $r = array_merge($r, $class_list);
190 * @return array ビュー一覧
192 function _getViewList()
194 $im =& new Ethna_InfoManager($this->backend);
195 // $view_class_list = array_keys($im->getForwardList());
199 // テンプレート/ビュースクリプトを解析する
200 $forward_list = $im->_analyzeForwardList();
201 $view_list = $this->__analyzeViewList();
204 $manifest_forward_list = $im->_getForwardList_Manifest($forward_list);
207 $implicit_forward_list = $im->_getForwardList_Implicit($forward_list, $manifest_forward_list);
209 $r = array_merge($view_list, $manifest_forward_list, $implicit_forward_list);
221 function _getTestAction()
223 $action_class_list = array_keys($this->_getActionList());
226 foreach ($action_class_list as $key => $action_name) {
227 $action_class = $this->ctl->getDefaultActionClass($action_name, false).'_TestCase';
228 if (!class_exists($action_class)) {
229 unset($action_class_list[$key]);
233 return $action_class_list;
242 function _getTestView()
244 $view_class_list = array_keys($this->_getViewList());
247 foreach ($view_class_list as $key => $view_name) {
248 $view_class = $this->ctl->getDefaultViewClass($view_name, false).'_TestCase';
249 if (!class_exists($view_class)) {
250 unset($view_class_list[$key]);
254 return $view_class_list;
261 * @return mixed 0:正常終了 Ethna_Error:エラー
265 $action_class_list = $this->_getTestAction();
266 $view_class_list = $this->_getTestView();
268 $test =& new GroupTest("Ethna UnitTest");
271 foreach ($action_class_list as $action_name) {
272 $action_class = $this->ctl->getDefaultActionClass($action_name, false).'_TestCase';
273 $action_form = $this->ctl->getDefaultFormClass($action_name, false).'_TestCase';
275 $test->addTestCase(new $action_class($this->ctl));
276 $test->addTestCase(new $action_form($this->ctl));
280 foreach ($view_class_list as $view_name) {
281 $view_class = $this->ctl->getDefaultViewClass($view_name, false).'_TestCase';
283 $test->addTestCase(new $view_class($this->ctl));
287 foreach ($this->testcase as $class_name => $file_name) {
288 $dir = $this->ctl->getBasedir().'/';
289 include_once $dir . $file_name;
290 $testcase_name = $class_name.'_TestCase';
291 $test->addTestCase(new $testcase_name($this->ctl));
295 $af =& $this->ctl->getActionForm();
298 $reporter = new Ethna_UnitTestReporter();
299 $test->run($reporter);
302 $this->ctl->action_form =& $af;
303 $this->backend->action_form =& $af;
304 $this->backend->af =& $af;
306 return array($reporter->report, $reporter->result);