--- /dev/null
+<?php
+/**
+ * Ethna_Action_UnitTest.php
+ *
+ * @author Takuya Ookubo <sfio@sakura.ai.to>
+ * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
+ * @package Ethna
+ * @version $Id$
+ */
+
+/**
+ * __ethna_unittest__¥Õ¥©¡¼¥à¤Î¼ÂÁõ
+ *
+ * @author Takuya Ookubo <sfio@sakura.ai.to>
+ * @access public
+ * @package Ethna
+ */
+class Ethna_Form_UnitTest extends Ethna_ActionForm
+{
+ /**
+ * @access private
+ * @var array ¥Õ¥©¡¼¥àÃÍÄêµÁ
+ */
+ var $form = array(
+ );
+}
+
+/**
+ * __ethna_unittest__¥¢¥¯¥·¥ç¥ó¤Î¼ÂÁõ
+ *
+ * @author Takuya Ookubo <sfio@sakura.ai.to>
+ * @access public
+ * @package Ethna
+ */
+class Ethna_Action_UnitTest extends Ethna_ActionClass
+{
+ /**
+ * __ethna_unittest__¥¢¥¯¥·¥ç¥ó¤ÎÁ°½èÍý
+ *
+ * @access public
+ * @return string ForwardÀè(Àµ¾ï½ªÎ»¤Ê¤énull)
+ */
+ function prepare()
+ {
+ return null;
+ }
+
+ /**
+ * __ethna_unittest__¥¢¥¯¥·¥ç¥ó¤Î¼ÂÁõ
+ *
+ * @access public
+ * @return string Á«°Ü̾
+ */
+ function perform()
+ {
+ return '__ethna_unittest__';
+ }
+}
+?>
$this->logger->log(LOG_DEBUG, 'form_action_name[%s]', $form_action_name);
// Ethna¥Þ¥Í¡¼¥¸¥ã¤Ø¤Î¥Õ¥©¡¼¥à¤«¤é¤Î¥ê¥¯¥¨¥¹¥È¤ÏµñÈÝ
- if ($form_action_name == "__ethna_info__") {
+ if ($form_action_name == "__ethna_info__" ||
+ $form_action_name == "__ethna_unittest__") {
$form_action_name = "";
}
}
include_once(ETHNA_BASE . '/class/Ethna_InfoManager.php');
+ include_once(ETHNA_BASE . '/class/Ethna_UnitTestManager.php');
// actionÀßÄê
$this->action['__ethna_info__'] = array(
'view_name' => 'Ethna_View_Info',
'view_path' => sprintf('%s/class/View/Ethna_View_Info.php', ETHNA_BASE),
);
+
+
+ // actionÀßÄê
+ $this->action['__ethna_unittest__'] = array(
+ 'form_name' => 'Ethna_Form_UnitTest',
+ 'form_path' => sprintf('%s/class/Action/Ethna_Action_UnitTest.php', ETHNA_BASE),
+ 'class_name' => 'Ethna_Action_UnitTest',
+ 'class_path' => sprintf('%s/class/Action/Ethna_Action_UnitTest.php', ETHNA_BASE),
+ );
+
+ // forwardÀßÄê
+ $this->forward['__ethna_unittest__'] = array(
+ 'forward_path' => sprintf('%s/tpl/unittest.tpl', ETHNA_BASE),
+ 'view_name' => 'Ethna_View_UnitTest',
+ 'view_path' => sprintf('%s/class/View/Ethna_View_UnitTest.php', ETHNA_BASE),
+ );
+
}
/**
*/
function restore()
{
- if (!empty($_COOKIE[$this->session_name]) || session_id() != null) {
+ if (!empty($_COOKIE[$this->session_name]) || session_id() != "") {
session_start();
$this->session_start = true;
$this->_generateFile("skel.app_object.php", sprintf("$basedir/skel/skel.app_object.php"), $macro) == false ||
$this->_generateFile("skel.view.php", sprintf("$basedir/skel/skel.view.php"), $macro) == false ||
$this->_generateFile("skel.template.tpl", sprintf("$basedir/skel/skel.template.tpl"), $macro) == false ||
+ $this->_generateFile("app.unittest.php", sprintf("$basedir/app/%s_UnitTestManager.php", $macro['project_id']), $macro) == false ||
+ $this->_generateFile("www.unittest.php", "$basedir/www/unittest.php", $macro) == false ||
+ $this->_generateFile("skel.action_test.php", sprintf("$basedir/skel/skel.action_test.php"), $macro) == false ||
+ $this->_generateFile("skel.view_test.php", sprintf("$basedir/skel/skel.view_test.php"), $macro) == false ||
$this->_generateFile("template.index.tpl", sprintf("$basedir/template/ja/index.tpl"), $macro) == false) {
return Ethna::raiseError('generating files failed');
}
}
/**
+ * ¥¢¥¯¥·¥ç¥óÍѥƥ¹¥È¤Î¥¹¥±¥ë¥È¥ó¤òÀ¸À®¤¹¤ë
+ *
+ * @access public
+ * @param string $action_name ¥¢¥¯¥·¥ç¥ó̾
+ * @param string $app_dir ¥×¥í¥¸¥§¥¯¥È¥Ç¥£¥ì¥¯¥È¥ê
+ * @return bool true:À®¸ù false:¼ºÇÔ
+ */
+ function generateActionTestSkelton($action_name, $app_dir)
+ {
+ // discover controller
+ $controller_class = $this->_discoverController($app_dir);
+ if (Ethna::isError($controller_class)) {
+ return $controller_class;
+ }
+
+ $c =& new $controller_class;
+ $c->setGateway(GATEWAY_CLI);
+
+ $action_dir = $c->getActiondir();
+ $action_class = $c->getDefaultActionClass($action_name, false);
+ $action_form = $c->getDefaultFormClass($action_name, false);
+ $action_path = $c->getDefaultActionPath($action_name . "Test", false);
+
+ $macro = array();
+ $macro['project_id'] = $c->getAppId();
+ $macro['action_name'] = $action_name;
+ $macro['action_class'] = $action_class;
+ $macro['action_form'] = $action_form;
+ $macro['action_path'] = $action_path;
+
+ $user_macro = $this->_getUserMacro();
+ $macro = array_merge($macro, $user_macro);
+
+ $this->_mkdir(dirname("$action_dir$action_path"), 0755);
+
+ if (file_exists("$action_dir$action_path")) {
+ printf("file [%s] aleady exists -> skip\n", "$action_dir$action_path");
+ } else if ($this->_generateFile("skel.action_test.php", "$action_dir$action_path", $macro) == false) {
+ printf("[warning] file creation failed [%s]\n", "$action_dir$action_path");
+ } else {
+ printf("action test(s) successfully created [%s]\n", "$action_dir$action_path");
+ }
+ }
+
+ /**
+ * ¥Ó¥å¡¼Íѥƥ¹¥È¤Î¥¹¥±¥ë¥È¥ó¤òÀ¸À®¤¹¤ë
+ *
+ * @access public
+ * @param string $forward_name ¥¢¥¯¥·¥ç¥ó̾
+ * @return bool true:À®¸ù false:¼ºÇÔ
+ */
+ function generateViewTestSkelton($forward_name, $app_dir)
+ {
+ // discover controller
+ $controller_class = $this->_discoverController($app_dir);
+ if (Ethna::isError($controller_class)) {
+ return $controller_class;
+ }
+
+ $c =& new $controller_class;
+ $c->setGateway(GATEWAY_CLI);
+
+ $view_dir = $c->getViewdir();
+ $view_class = $c->getDefaultViewClass($forward_name, false);
+ $view_path = $c->getDefaultViewPath($forward_name . "Test", false);
+
+ $macro = array();
+ $macro['project_id'] = $c->getAppId();
+ $macro['forward_name'] = $forward_name;
+ $macro['view_class'] = $view_class;
+ $macro['view_path'] = $view_path;
+
+ $user_macro = $this->_getUserMacro();
+ $macro = array_merge($macro, $user_macro);
+
+ $this->_mkdir(dirname("$view_dir/$view_path"), 0755);
+
+ if (file_exists("$view_dir$view_path")) {
+ printf("file [%s] aleady exists -> skip\n", "$view_dir$view_path");
+ } else if ($this->_generateFile("skel.view_test.php", "$view_dir$view_path", $macro) == false) {
+ printf("[warning] file creation failed [%s]\n", "$view_dir$view_path");
+ } else {
+ printf("view test(s) successfully created [%s]\n", "$view_dir$view_path");
+ }
+ }
+
+ /**
* mkdir -p
*
* @access private
--- /dev/null
+<?php
+/**
+ * Ethna_UnitTestCase.php
+ *
+ * @author Takuya Ookubo <sfio@sakura.ai.to>
+ * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
+ * @package Ethna
+ * @version $Id$
+ */
+
+/**
+ * UnitTestCase¼Â¹Ô¥¯¥é¥¹
+ *
+ * @author Takuya Ookubo <sfio@sakura.ai.to>
+ * @access public
+ * @package Ethna
+ */
+class Ethna_UnitTestCase extends UnitTestCase
+{
+ /** @var object Ethna_Backend backend¥ª¥Ö¥¸¥§¥¯¥È */
+ var $backend;
+
+ /** @var object Ethna_Controller controller¥ª¥Ö¥¸¥§¥¯¥È */
+ var $controller;
+
+ /** @var object Ethna_Controller controller¥ª¥Ö¥¸¥§¥¯¥È($controller¤Î¾Êά·Á) */
+ var $ctl;
+
+ /** @var object Ethna_Session ¥»¥Ã¥·¥ç¥ó¥ª¥Ö¥¸¥§¥¯¥È */
+ var $session;
+
+ /** @var string ¥¢¥¯¥·¥ç¥ó̾ */
+ var $action_name;
+
+ /** @var object Ethna_ActionForm ¥¢¥¯¥·¥ç¥ó¥Õ¥©¡¼¥à¥ª¥Ö¥¸¥§¥¯¥È */
+ var $action_form;
+
+ /** @var object Ethna_ActionForm ¥¢¥¯¥·¥ç¥ó¥Õ¥©¡¼¥à¥ª¥Ö¥¸¥§¥¯¥È($action_form¤Î¾Êά·Á) */
+ var $af;
+
+ /** @var object Ethna_ActionClass ¥¢¥¯¥·¥ç¥ó¥¯¥é¥¹¥ª¥Ö¥¸¥§¥¯¥È */
+ var $action_class;
+
+ /** @var object Ethna_ActionClass ¥¢¥¯¥·¥ç¥ó¥¯¥é¥¹¥ª¥Ö¥¸¥§¥¯¥È($action_class¤Î¾Êά·Á) */
+ var $ac;
+
+ /** @var string ¥Ó¥å¡¼Ì¾ */
+ var $forward_name;
+
+ /** @var object Ethna_ViewClass view¥¯¥é¥¹¥ª¥Ö¥¸¥§¥¯¥È */
+ var $view_class;
+
+ /** @var object Ethna_ViewClass view¥¯¥é¥¹¥ª¥Ö¥¸¥§¥¯¥È($view_class¤Î¾Êά·Á) */
+ var $vc;
+
+ /**
+ * Ethna_UnitTestCase¤Î¥³¥ó¥¹¥È¥é¥¯¥¿
+ *
+ * @access public
+ * @param object Ethna_Controller &$controller ¥³¥ó¥È¥í¡¼¥é¥ª¥Ö¥¸¥§¥¯¥È
+ */
+ function Ethna_UnitTestCase(&$controller)
+ {
+ parent::UnitTestCase();
+
+ // ¥ª¥Ö¥¸¥§¥¯¥È¤ÎÀßÄê
+ $this->controller =& $controller;
+ $this->ctl =& $this->controller;
+ $this->backend =& $this->ctl->getBackend();
+ $this->session =& $this->backend->getSession();
+
+ // ÊÑ¿ô¤Î½é´ü²½
+ $this->action_form = $this->af = null;
+ $this->action_class = $this->ac = null;
+ $this->view_class = $this->vc = null;
+ }
+
+ /**
+ * ¥¢¥¯¥·¥ç¥ó¥Õ¥©¡¼¥à¤ÎºîÀ®¤È´ØÏ¢ÉÕ¤±
+ *
+ * @access public
+ */
+ function _createActionForm($form_name)
+ {
+ $this->action_form =& new $form_name($this->ctl);
+ $this->af =& $this->action_form;
+
+ // controler&backend¤Ëaf¤ò´ØÏ¢ÉÕ¤±
+ $this->ctl->action_name = $this->action_name;
+ $this->ctl->action_form =& $this->af;
+ $this->backend->action_form =& $this->af;
+ $this->backend->af =& $this->af;
+ }
+
+ /**
+ * ¥¢¥¯¥·¥ç¥ó¥Õ¥©¡¼¥à¤ÎºîÀ®
+ *
+ * @access public
+ */
+ function createActionForm()
+ {
+ $form_name = $this->ctl->getActionFormName($this->action_name);
+ $this->_createActionForm($form_name);
+ }
+
+ /**
+ * ñ½ã¤Ê¥¢¥¯¥·¥ç¥ó¥Õ¥©¡¼¥à¤ÎºîÀ®
+ *
+ * @access public
+ */
+ function createPlainActionForm()
+ {
+ $form_name = 'Ethna_ActionForm';
+ $this->_createActionForm($form_name);
+ }
+
+ /**
+ * ¥¢¥¯¥·¥ç¥ó¤ÎºîÀ®
+ *
+ * @access public
+ */
+ function createActionClass()
+ {
+ if ($this->af == null) {
+ $this->createActionForm();
+ }
+
+ // ¥ª¥Ö¥¸¥§¥¯¥ÈÀ¸À®
+ $action_class_name = $this->ctl->getActionClassName($this->action_name);
+ $this->action_class =& new $action_class_name($this->backend);
+ $this->ac =& $this->action_class;
+
+ // backend¤Ëac¤ò´ØÏ¢ÉÕ¤±
+ $this->backend->action_class =& $this->ac;
+ $this->backend->ac =& $this->ac;
+ }
+
+ /**
+ * ¥Ó¥å¡¼¤ÎºîÀ®
+ *
+ * @access public
+ */
+ function createViewClass()
+ {
+ if ($this->af == null) {
+ $this->createPlainActionForm();
+ }
+
+ // ¥ª¥Ö¥¸¥§¥¯¥ÈÀ¸À®
+ $view_class_name = $this->ctl->getViewClassName($this->forward_name);
+ $this->view_class =& new $view_class_name($this->backend, $this->forward_name, $this->ctl->_getForwardPath($this->forward_name));
+ $this->vc =& $this->view_class;
+ }
+}
+?>
--- /dev/null
+<?php
+/**
+ * Ethna_UnitTestManager.php
+ *
+ * @author Takuya Ookubo <sfio@sakura.ai.to>
+ * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
+ * @package Ethna
+ * @version $Id$
+ */
+
+require_once 'simpletest/unit_tester.php';
+require_once 'Ethna_UnitTestCase.php';
+require_once 'Ethna_UnitTestReporter.php';
+
+/**
+ * Ethna¥æ¥Ë¥Ã¥È¥Æ¥¹¥È¥Þ¥Í¡¼¥¸¥ã¥¯¥é¥¹
+ *
+ * @author Takuya Ookubo <sfio@sakura.ai.to>
+ * @access public
+ * @package Ethna
+ */
+class Ethna_UnitTestManager extends Ethna_AppManager
+{
+ /** @var object Ethna_Controller ¥³¥ó¥È¥í¡¼¥é¥ª¥Ö¥¸¥§¥¯¥È */
+ var $ctl;
+
+ /** @var array °ìÈ̥ƥ¹¥È¥±¡¼¥¹ÄêµÁ */
+ var $testcase = array();
+
+ /**
+ * Ethna_UnitTestManager¤Î¥³¥ó¥¹¥È¥é¥¯¥¿
+ *
+ * @access public
+ * @param object Ethna_Backend &$backend Ethna_Backend¥ª¥Ö¥¸¥§¥¯¥È
+ */
+ function Ethna_UnitTestManager(&$backend)
+ {
+ parent::Ethna_AppManager($backend);
+ $this->ctl =& Ethna_Controller::getInstance();
+ $this->class_factory =& $this->ctl->getClassFactory();
+ }
+
+ /**
+ * ¥¢¥¯¥·¥ç¥ó¥Æ¥¹¥È¥¯¥é¥¹¤ò¼èÆÀ¤¹¤ë
+ *
+ * @access private
+ * @return array
+ */
+ function _getTestAction()
+ {
+ $em =& new Ethna_InfoManager($this->backend);
+ $action_class_list = array_keys($em->getActionList());
+
+ // ¥Æ¥¹¥È¤Î¸ºß¤¹¤ë¥¢¥¯¥·¥ç¥ó
+ $action_dir = $this->ctl->getActiondir();
+ foreach ($action_class_list as $key => $action_name) {
+
+ $action_path = $this->ctl->getDefaultActionPath($action_name, false);
+ if (!file_exists("$action_dir$action_path")) {
+ unset($action_class_list[$key]);
+ continue;
+ }
+ @include_once "$action_dir$action_path";
+ $action_class = $this->ctl->getDefaultActionClass($action_name, false).'_TestCase';
+ if (!class_exists($action_class)) {
+ unset($action_class_list[$key]);
+ }
+ }
+
+ return $action_class_list;
+ }
+
+ /**
+ * ¥Ó¥å¡¼¥Æ¥¹¥È¥¯¥é¥¹¤ò¼èÆÀ¤¹¤ë
+ *
+ * @access private
+ * @return array
+ */
+ function _getTestView()
+ {
+ $em =& new Ethna_InfoManager($this->backend);
+ $view_class_list = array_keys($em->getForwardList());
+
+ // ¥Æ¥¹¥È¤Î¸ºß¤¹¤ë¥Ó¥å¡¼
+ $view_dir = $this->ctl->getViewdir();
+ foreach ($view_class_list as $key => $view_name) {
+
+ $view_path = $this->ctl->getDefaultViewPath($view_name, false);
+ if (!file_exists("$view_dir$view_path")) {
+ unset($view_class_list[$key]);
+ continue;
+ }
+ @include_once "$view_dir$view_path";
+ $view_class = $this->ctl->getDefaultViewClass($view_name, false).'_TestCase';
+ if (!class_exists($view_class)) {
+ unset($view_class_list[$key]);
+ }
+ }
+
+ return $view_class_list;
+ }
+
+ /**
+ * ¥æ¥Ë¥Ã¥È¥Æ¥¹¥È¤ò¼Â¹Ô¤¹¤ë
+ *
+ * @access private
+ * @return mixed 0:Àµ¾ï½ªÎ» Ethna_Error:¥¨¥é¡¼
+ */
+ function run()
+ {
+ $action_class_list = $this->_getTestAction();
+ $view_class_list = $this->_getTestView();
+
+ $test =& new GroupTest("Ethna UnitTest");
+
+ // ¥¢¥¯¥·¥ç¥ó
+ foreach ($action_class_list as $action_name) {
+ $action_class = $this->ctl->getDefaultActionClass($action_name, false).'_TestCase';
+ $action_form = $this->ctl->getDefaultFormClass($action_name, false).'_TestCase';
+
+ $test->addTestCase(new $action_class($this->ctl));
+ $test->addTestCase(new $action_form($this->ctl));
+ }
+
+ // ¥Ó¥å¡¼
+ foreach ($view_class_list as $view_name) {
+ $view_class = $this->ctl->getDefaultViewClass($view_name, false).'_TestCase';
+
+ $test->addTestCase(new $view_class($this->ctl));
+ }
+
+ // °ìÈÌ
+ foreach ($this->testcase as $class_name => $file_name) {
+ $dir = $this->ctl->getBasedir().'/';
+ require_once "$dir$file_name";
+ $testcase_name = $class_name.'_TestCase';
+ $test->addTestCase(new $testcase_name($this->ctl));
+ }
+
+ // ActionForm¤Î¥Ð¥Ã¥¯¥¢¥Ã¥×
+ $af =& $this->ctl->getActionForm();
+
+ //½ÐÎϤ·¤¿¤¤·Á¼°¤Ë¤¢¤ï¤»¤ÆÀÚ¤êÂؤ¨¤ë
+ $reporter = new Ethna_UnitTestReporter();
+ $test->run($reporter);
+
+ // ActionForm¤Î¥ê¥¹¥È¥¢
+ $this->ctl->action_form =& $af;
+ $this->backend->action_form =& $af;
+ $this->backend->af =& $af;
+
+ return array($reporter->report, $reporter->result);
+ }
+}
+?>
--- /dev/null
+<?php
+/**
+ * Ethna_UnitTestReporter.php
+ *
+ * @author Takuya Ookubo <sfio@sakura.ai.to>
+ * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
+ * @package Ethna
+ * @version $Id$
+ */
+
+require_once ('simpletest/scorer.php');
+
+/**
+ * Ethna¥Þ¥Í¡¼¥¸¥ã¥¯¥é¥¹
+ *
+ * @author Takuya Ookubo <sfio@sakura.ai.to>
+ * @access public
+ * @package Ethna
+ */
+class Ethna_UnitTestReporter extends SimpleReporter {
+
+ var $_character_set;
+
+ var $report;
+ var $result;
+
+ /**
+ * Ethna_UnitTestReporter¤Î¥³¥ó¥¹¥È¥é¥¯¥¿
+ *
+ * @access public
+ * @param string $character_set ¥¥ã¥é¥¯¥¿¥»¥Ã¥È
+ */
+ function Ethna_UnitTestReporter($character_set = 'EUC-JP') {
+ $this->SimpleReporter();
+ $this->_character_set = $character_set;
+ $this->report= array();
+ $this->result= array();
+ }
+
+ /**
+ * ·ë²Ì
+ *
+ * @access public
+ * @param string $test_name ¥Æ¥¹¥È̾¾Î
+ */
+ function paintFooter($test_name) {
+ $colour = ($this->getFailCount() + $this->getExceptionCount() > 0 ? "red" : "green");
+ $this->result = array(
+ 'TestCaseProgress' => $this->getTestCaseProgress(),
+ 'TestCaseCount' => $this->getTestCaseCount(),
+ 'PassCount' => $this->getPassCount(),
+ 'FailCount' => $this->getFailCount(),
+ 'ExceptionCount' => $this->getExceptionCount(),
+ );
+ }
+
+ /**
+ * ¥Ñ¥¹
+ *
+ * @access public
+ *¡¡@param string $message ¥á¥Ã¥»¡¼¥¸
+ */
+ function paintPass($message)
+ {
+ parent::paintPass($message);
+
+ $test_list = $this->getTestList();
+ $this->report[] = array(
+ 'type' => 'Pass',
+ 'test' => $test_list[2],
+ 'message' => $message,
+ );
+ }
+
+ /**
+ * ¼ºÇÔ
+ *
+ * @access public
+ *¡¡@param string $message ¥á¥Ã¥»¡¼¥¸
+ */
+ function paintFail($message) {
+ parent::paintFail($message);
+
+ $test_list = $this->getTestList();
+ $this->report[] = array(
+ 'type' => 'Fail',
+ 'test' => $test_list[2],
+ 'message' => $message,
+ );
+ }
+
+ /**
+ * Îã³°
+ *
+ * @access public
+ *¡¡@param string $message ¥á¥Ã¥»¡¼¥¸
+ */
+ function paintException($message) {
+ parent::paintException($message);
+
+ $breadcrumb = $this->getTestList();
+ $test = $breadcrumb[2];
+ array_shift($breadcrumb);
+ $this->report[] = array(
+ 'type' => 'Exception',
+ 'test' => $test,
+ 'breadcrumb' => $breadcrumb,
+ 'message' => $message,
+ );
+ }
+
+ /**
+ * ¥Æ¥¹¥È¥±¡¼¥¹³«»Ï
+ *
+ * @access public
+ * @param string $test_name ¥Æ¥¹¥È̾¾Î
+ */
+ function paintCaseStart($test_name)
+ {
+ parent::paintCaseStart($test_name);
+
+ $this->report[] = array(
+ 'type' => 'CaseStart',
+ 'test_name' => $test_name,
+ );
+ }
+
+ /**
+ * ¥Æ¥¹¥È¥±¡¼¥¹½ªÎ»
+ *
+ * @access public
+ * @param string $test_name ¥Æ¥¹¥È̾¾Î
+ */
+ function paintCaseEnd($test_name)
+ {
+ parent::paintCaseEnd($test_name);
+
+ $this->report[] = array(
+ 'type' => 'CaseEnd',
+ );
+ }
+
+ /**
+ * ¥Õ¥©¡¼¥Þ¥Ã¥ÈºÑ¤ß¥á¥Ã¥»¡¼¥¸
+ *
+ * @access public
+ *¡¡@param string $message ¥á¥Ã¥»¡¼¥¸
+ */
+ function paintFormattedMessage($message) {
+ $this->report[] = array(
+ 'type' => 'FormattedMessage',
+ 'message' => $this->_htmlEntities($message),
+ );
+ }
+
+ /**
+ * HTML¥¨¥ó¥Æ¥£¥Æ¥£ÊÑ´¹
+ *
+ *¡¡@access protected
+ *¡¡@param string $message ¥×¥ì¡¼¥ó¥Æ¥¥¹¥È
+ *¡¡@return string HTML¥¨¥ó¥Æ¥£¥Æ¥£ÊÑ´¹ºÑ¤ß¥á¥Ã¥»¡¼¥¸
+ */
+ function _htmlEntities($message) {
+ return htmlentities($message, ENT_COMPAT, $this->_character_set);
+ }
+}
+?>
--- /dev/null
+<?php
+/**
+ * Ethna_Handle_AddActionTest.php
+ *
+ * @author halt feits <halt.feits@gmail.com>
+ * @package Ethna
+ * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
+ * @version $Id$
+ */
+
+/**
+ * add-action-test handler
+ *
+ * @author halt feits <halt.feits@gmail.com>
+ * @access public
+ * @package Ethna
+ */
+class Ethna_Handle_AddActionTest extends Ethna_Handle
+{
+
+ /**
+ * get handler's description
+ *
+ * @access public
+ */
+ function getDescription()
+ {
+ return "add new action test to project:\n {$this->id} [action] ([project-base-dir])\n";
+ }
+
+ /**
+ * add action test
+ *
+ * @access public
+ */
+ function perform()
+ {
+ $r = $this->_validateArgList();
+ if (Ethna::isError($r)) {
+ return $r;
+ }
+ list($action_name, $app_dir) = $r;
+
+ $sg =& new Ethna_SkeltonGenerator();
+ $r = $sg->generateActionTestSkelton($action_name, $app_dir);
+ if (Ethna::isError($r)) {
+ printf("error occurred while generating skelton. please see also following error message(s)\n\n");
+ return $r;
+ }
+
+ return true;
+ }
+
+ /**
+ * show usage
+ *
+ * @access public
+ */
+ function usage()
+ {
+ printf("usage:\nethna %s [action] ([project-base-dir])\n\n", $this->id);
+ }
+
+ /**
+ * check arguments
+ *
+ * @access private
+ */
+ function _validateArgList()
+ {
+ $arg_list = array();
+ if (count($this->arg_list) < 1) {
+ return Ethna::raiseError('too few argments', 'usage');
+ } else if (count($this->arg_list) > 2) {
+ return Ethna::raiseError('too many argments', 'usage');
+ } else if (count($this->arg_list) == 1) {
+ $arg_list[] = $this->arg_list[0];
+ $arg_list[] = getcwd();
+ } else {
+ $arg_list = $this->arg_list;
+ }
+
+ // TODO: check action name(?) - how it would be easy and pluggable
+ if (is_dir($arg_list[1]) == false) {
+ return Ethna::raiseError("no such directory [{$arg_list[1]}]");
+ }
+
+ return $arg_list;
+ }
+
+}
+?>
--- /dev/null
+<?php
+/**
+ * Ethna_Handle_AddViewTest.php
+ *
+ * @author halt feits <halt.feits@gmail.com>
+ * @package Ethna
+ * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
+ * @version $Id$
+ */
+
+/**
+ * add-view-test handler
+ *
+ * @author halt feits <halt.feits@gmail.com>
+ * @access public
+ * @package Ethna
+ */
+class Ethna_Handle_AddViewTest extends Ethna_Handle
+{
+
+ /**
+ * get handler's description
+ *
+ * @access public
+ */
+ function getDescription()
+ {
+ return "add new view test to project:\n {$this->id} [view] ([project-base-dir])\n";
+ }
+
+ /**
+ * add view test
+ *
+ * @access public
+ */
+ function perform()
+ {
+ $r = $this->_validateArgList();
+ if (Ethna::isError($r)) {
+ return $r;
+ }
+ list($view_name, $app_dir) = $r;
+
+ $sg =& new Ethna_SkeltonGenerator();
+ $r = $sg->generateViewTestSkelton($view_name, $app_dir);
+ if (Ethna::isError($r)) {
+ printf("error occurred while generating skelton. please see also following error message(s)\n\n");
+ return $r;
+ }
+
+ return true;
+ }
+
+ /**
+ * show usage
+ *
+ * @access public
+ */
+ function usage()
+ {
+ printf("usage:\nethna %s [view] ([project-base-dir])\n\n", $this->id);
+ }
+
+ /**
+ * check arguments
+ *
+ * @access private
+ */
+ function _validateArgList()
+ {
+ $arg_list = array();
+ if (count($this->arg_list) < 1) {
+ return Ethna::raiseError('too few argments', 'usage');
+ } else if (count($this->arg_list) > 2) {
+ return Ethna::raiseError('too many argments', 'usage');
+ } else if (count($this->arg_list) == 1) {
+ $arg_list[] = $this->arg_list[0];
+ $arg_list[] = getcwd();
+ } else {
+ $arg_list = $this->arg_list;
+ }
+
+ // TODO: check view name(?) - how it would be easy and pluggable
+ if (is_dir($arg_list[1]) == false) {
+ return Ethna::raiseError("no such directory [{$arg_list[1]}]");
+ }
+
+ return $arg_list;
+ }
+
+}
+
+?>
--- /dev/null
+<?php
+/**
+ * Ethna_View_UnitTest.php
+ *
+ * @author Takuya Ookubo <sfio@sakura.ai.to>
+ * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
+ * @package Ethna
+ * @version $Id$
+ */
+
+/**
+ * __ethna_unittest__¥Ó¥å¡¼¤Î¼ÂÁõ
+ *
+ * @author Takuya Ookubo <sfio@sakura.ai.to>
+ * @access public
+ * @package Ethna
+ */
+class Ethna_View_UnitTest extends Ethna_ViewClass
+{
+ /**
+ * Á«°ÜÁ°½èÍý
+ *
+ * @access public
+ */
+ function preforward()
+ {
+ // ¥¿¥¤¥à¥¢¥¦¥È¤·¤Ê¤¤¤è¤¦¤ËÊѹ¹
+ $max_execution_time = ini_get('max_execution_time');
+ set_time_limit(0);
+
+ if (!headers_sent()) {
+ // ¥¥ã¥Ã¥·¥å¤·¤Ê¤¤
+ header("Expires: Thu, 01 Jan 1970 00:00:00 GMT");
+ header("Last-Modified: " . gmdate("D, d M Y H:i:s \G\M\T"));
+ header("Cache-Control: no-store, no-cache, must-revalidate");
+ header("Cache-Control: post-check=0, pre-check=0", false);
+ header("Pragma: no-cache");
+ }
+
+ $ctl =& Ethna_Controller::getInstance();
+
+ // cores
+ $this->af->setApp('app_id', $ctl->getAppId());
+ $this->af->setApp('ethna_version', ETHNA_VERSION);
+
+ // unittest
+ $r = sprintf("%s_UnitTestManager", $ctl->getAppId());
+ $ut =& new $r($this->backend);
+ list($report, $result) = $ut->run();
+ $this->af->setApp('report', $report);
+ $this->af->setApp('result', $result);
+
+ // ¥¿¥¤¥à¥¢¥¦¥È¤ò¸µ¤ËÌ᤹
+ set_time_limit($max_execution_time);
+ }
+}
+?>
--- /dev/null
+<?php
+/**
+ * {$project_id}_UnitTestManager.php
+ *
+ * @author your name
+ * @package {$project_id}
+ * @version $Id$
+ */
+
+/**
+ * {$project_id}¥æ¥Ë¥Ã¥È¥Æ¥¹¥È¥Þ¥Í¡¼¥¸¥ã¥¯¥é¥¹
+ *
+ * @author your name
+ * @access public
+ * @package {$project_id}
+ */
+class {$project_id}_UnitTestManager extends Ethna_UnitTestManager
+{
+ /**
+ * @var array °ìÈ̥ƥ¹¥È¥±¡¼¥¹ÄêµÁ
+ */
+ var $testcase = array(
+ /*
+ * TODO: ¤³¤³¤Ë°ìÈ̥ƥ¹¥È¥±¡¼¥¹ÄêµÁ¤òµ½Ò¤·¤Æ¤¯¤À¤µ¤¤
+ *
+ * µ½ÒÎ㡧
+ *
+ * 'util' => 'app/UtilTest.php',
+ */
+ );
+}
+?>
--- /dev/null
+<?php
+/**
+ * {$action_path}
+ *
+ * @author your name
+ * @package {$project_id}
+ * @version $Id$
+ */
+
+/**
+ * {$action_name}¥Õ¥©¡¼¥à¤Î¥Æ¥¹¥È¥±¡¼¥¹
+ *
+ * @author your name
+ * @access public
+ * @package {$project_id}
+ */
+class {$action_form}_TestCase extends Ethna_UnitTestCase
+{
+ /**
+ * @access private
+ * @var string ¥¢¥¯¥·¥ç¥ó̾
+ */
+ var $action_name = '{$action_name}';
+
+ /**
+ * ¥Æ¥¹¥È¤Î½é´ü²½
+ *
+ * @access public
+ */
+ function setUp()
+ {
+ $this->createActionForm(); // ¥¢¥¯¥·¥ç¥ó¥Õ¥©¡¼¥à¤ÎºîÀ®
+ }
+
+ /**
+ * ¥Æ¥¹¥È¤Î¸å»ÏËö
+ *
+ * @access public
+ */
+ function tearDown()
+ {
+ }
+
+ /**
+ * {$action_name}¥¢¥¯¥·¥ç¥ó¥Õ¥©¡¼¥à¤Î¥µ¥ó¥×¥ë¥Æ¥¹¥È¥±¡¼¥¹
+ *
+ * @access public
+ */
+ /*
+ function test_formSample()
+ {
+ // ¥Õ¥©¡¼¥à¤ÎÀßÄê
+ $this->af->set('id', 1);
+
+ // {$action_name}¥¢¥¯¥·¥ç¥ó¥Õ¥©¡¼¥àÃ͸¡¾Ú
+ $this->assertEqual($this->af->validate(), 0);
+ }
+ */
+}
+
+/**
+ * {$action_name}¥¢¥¯¥·¥ç¥ó¤Î¥Æ¥¹¥È¥±¡¼¥¹
+ *
+ * @author your name
+ * @access public
+ * @package {$project_id}
+ */
+class {$action_class}_TestCase extends Ethna_UnitTestCase
+{
+ /**
+ * @access private
+ * @var string ¥¢¥¯¥·¥ç¥ó̾
+ */
+ var $action_name = '{$action_name}';
+
+ /**
+ * ¥Æ¥¹¥È¤Î½é´ü²½
+ *
+ * @access public
+ */
+ function setUp()
+ {
+ $this->createActionForm(); // ¥¢¥¯¥·¥ç¥ó¥Õ¥©¡¼¥à¤ÎºîÀ®
+ $this->createActionClass(); // ¥¢¥¯¥·¥ç¥ó¥¯¥é¥¹¤ÎºîÀ®
+
+ $this->session->start(); // ¥»¥Ã¥·¥ç¥ó¤Î³«»Ï
+ }
+
+ /**
+ * ¥Æ¥¹¥È¤Î¸å»ÏËö
+ *
+ * @access public
+ */
+ function tearDown()
+ {
+ $this->session->destroy(); // ¥»¥Ã¥·¥ç¥ó¤ÎÇË´þ
+ }
+
+ /**
+ * {$action_name}¥¢¥¯¥·¥ç¥ó¥¯¥é¥¹¤Î¥µ¥ó¥×¥ë¥Æ¥¹¥È¥±¡¼¥¹
+ *
+ * @access public
+ */
+ /*
+ function test_actionSample()
+ {
+ // ¥Õ¥©¡¼¥à¤ÎÀßÄê
+ $this->af->set('id', 1);
+
+ // {$action_name}¥¢¥¯¥·¥ç¥ó¼Â¹ÔÁ°¤Îǧ¾Ú½èÍý
+ $forward_name = $this->ac->authenticate();
+ $this->assertNull($forward_name);
+
+ // {$action_name}¥¢¥¯¥·¥ç¥ó¤ÎÁ°½èÍý
+ $forward_name = $this->ac->prepare();
+ $this->assertNull($forward_name);
+
+ // {$action_name}¥¢¥¯¥·¥ç¥ó¤Î¼ÂÁõ
+ $forward_name = $this->ac->perform();
+ $this->assertEqual($forward_name, '{$action_name}');
+ }
+ */
+}
+?>
--- /dev/null
+<?php
+/**
+ * {$view_path}
+ *
+ * @author your name
+ * @package {$project_id}
+ * @version $Id$
+ */
+
+/**
+ * {$forward_name}¥Ó¥å¡¼¤Î¼ÂÁõ
+ *
+ * @author your name
+ * @access public
+ * @package {$project_id}
+ */
+class {$view_class}_TestCase extends Ethna_UnitTestCase
+{
+ /**
+ * @access private
+ * @var string ¥Ó¥å¡¼Ì¾
+ */
+ var $forward_name = '{$forward_name}';
+
+ /**
+ * ¥Æ¥¹¥È¤Î½é´ü²½
+ *
+ * @access public
+ */
+ function setUp()
+ {
+ $this->createPlainActionForm(); // ¥¢¥¯¥·¥ç¥ó¥Õ¥©¡¼¥à¤ÎºîÀ®
+ $this->createViewClass(); // ¥Ó¥å¡¼¤ÎºîÀ®
+ }
+
+ /**
+ * ¥Æ¥¹¥È¤Î¸å»ÏËö
+ *
+ * @access public
+ */
+ function tearDown()
+ {
+ }
+
+ /**
+ * {$forward_name}Á«°ÜÁ°½èÍý¤Î¥µ¥ó¥×¥ë¥Æ¥¹¥È¥±¡¼¥¹
+ *
+ * @access public
+ */
+ /*
+ function test_viewSample()
+ {
+ // ¥Õ¥©¡¼¥à¤ÎÀßÄê
+ $this->af->set('id', 1);
+
+ // {$forward_name}Á«°ÜÁ°½èÍý
+ $this->vc->preforward();
+ $this->assertNull($this->af->get('data'));
+ }
+ */
+}
+?>
--- /dev/null
+<?php
+error_reporting(E_ALL);
+include_once(dirname(__FILE__) . '/../app/{$project_id}_Controller.php');
+
+{$project_id}_Controller::main('{$project_id}_Controller', array(
+ '__ethna_unittest__',
+ )
+);
+?>
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html lang="ja">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=EUC-JP">
+ <meta http-equiv="Content-Style-Type" content="text/css">
+ <title>{$app.app_id} - Ethna UnitTest</title>
+ <style type="text/css">
+ <!--
+ {literal}
+ body {
+ margin: auto;
+ background-color: #ffffff;
+ color: #000000;
+ }
+ body, td, th, h1, h2 {font-family: sans-serif;}
+ pre {margin: 0px; font-family: monospace;}
+ a:link {color: #000099; text-decoration: none; background-color: #ffffff;}
+ a:hover {text-decoration: underline;}
+ table { margin: auto; border-collapse: collapse;}
+ .center {text-align: center;}
+ .center table { text-align: left;}
+ .center th { text-align: center !important; }
+ td, th { border: 1px solid #000000; font-size: 75%; vertical-align: top;}
+ h1 {font-size: 150%;}
+ h2 {font-size: 125%;}
+ .p {text-align: left;}
+ .e {background-color: #ccccff; font-weight: bold; color: #000000;}
+ .h {background-color: #9999cc; font-weight: bold; color: #000000;}
+ .v {background-color: #cccccc; color: #000000;}
+ .vf {background-color: #cccccc; color: red;}
+ i {color: #666666; background-color: #cccccc;}
+ img {float: right; border: 0px;}
+ hr {width: 600px; background-color: #cccccc; border: 0px; height: 1px; color: #000000;}
+ .header {
+ margin: auto;
+ width:600px;
+ background-color: #9999cc;
+ padding:0.2em;
+ border:solid 1px black;
+ }
+ {/literal}
+ //-->
+ </style>
+</head>
+ <body>
+ <div class="center">
+ <div class="header"><h1>{$app.app_id}</h1></div>
+ <h2>Report</h2>
+ <table border="0" cellpadding="2" width="600">
+ {foreach from=$app.report key="key" item="item"}
+ {if $item.type=='Pass'}
+ <tr>
+ <th class="e">{$item.test}</th>
+ <td class="v">{$item.message}</td>
+ </tr>
+ {elseif $item.type=='CaseEnd'}
+ {elseif $item.type=='CaseStart'}
+ <tr class="h">
+ <th colspan="2">{$item.test_name}</th>
+ </tr>
+ {elseif $item.type=='Exception'}
+ <tr>
+ <th class="e">{$item.test}</th>
+ <td class="vf">Exception
+ <ul>{foreach from=$item.breadcrumb item="crumb"}<li>{$crumb}</li>{/foreach}</ul><strong>{$message|escape:"html"}</strong><br />
+ </td>
+ </tr>
+ {elseif $item.type=='Fail'}
+ <tr>
+ <th class="e">{$item.test}</th>
+ <td class="vf"><strong>Fail</strong> {$item.message}</td>
+ </tr>
+ {else}
+ <tr class="v">
+ <td colspan="2">{$item.message}</td>
+ </tr>
+ {/if}
+ {/foreach}
+ </table>
+ <h2>Result</h2>
+ <p>
+ {$app.result.TestCaseProgress}/{$app.result.TestCaseCount} test cases complete:
+ <strong>{$app.result.PassCount}</strong> passes,
+ <strong>{$app.result.FailCount}</strong> fails and
+ <strong>{$app.result.ExceptionCount}</strong> exceptions.
+ </p>
+ <br />
+ <hr />
+ powered by <a href="http://ethna.jp/">Ethna {$app.ethna_version}</a> (experimental)
+ <hr />
+ </div>
+ </body>
+</html>