Fixes #149
[akelos.git] / lib / AkUnitTest.php
blob4c0847243e684b8b93f780a652813478217a702f
1 <?php
2 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4 // +----------------------------------------------------------------------+
5 // | Akelos Framework - http://www.akelos.org |
6 // +----------------------------------------------------------------------+
7 // | Copyright (c) 2002-2006, Akelos Media, S.L. & Bermi Ferrer Martinez |
8 // | Released under the GNU Lesser General Public License, see LICENSE.txt|
9 // +----------------------------------------------------------------------+
11 /**
12 * @package ActiveSupport
13 * @subpackage Testing
14 * @author Bermi Ferrer <bermi a.t akelos c.om>
15 * @copyright Copyright (c) 2002-2006, Akelos Media, S.L. http://www.akelos.org
16 * @license GNU Lesser General Public License <http://www.gnu.org/copyleft/lesser.html>
19 require_once(AK_CONTRIB_DIR.DS.'simpletest'.DS.'unit_tester.php');
20 require_once(AK_CONTRIB_DIR.DS.'simpletest'.DS.'mock_objects.php');
21 require_once(AK_CONTRIB_DIR.DS.'simpletest'.DS.'reporter.php');
22 require_once(AK_CONTRIB_DIR.DS.'simpletest'.DS.'web_tester.php');
23 //require_once(AK_CONTRIB_DIR.DS.'simpletest'.DS.'code_coverage.php');
25 require_once(AK_LIB_DIR.DS.'AkActiveRecord.php');
26 require_once(AK_LIB_DIR.DS.'AkInstaller.php');
27 require_once(AK_APP_DIR.DS.'shared_model.php');
29 class AkUnitTest extends UnitTestCase
31 var $module = '';
32 var $insert_models_data = false;
33 var $instantiate_models = false;
35 function resetFrameworkDatabaseTables()
37 require_once(AK_APP_DIR.DS.'installers'.DS.'framework_installer.php');
38 $installer = new FrameworkInstaller();
39 $installer->uninstall();
40 $installer->install();
41 if(isset($_SESSION['__activeRecordColumnsSettingsCache'])){
42 unset($_SESSION['__activeRecordColumnsSettingsCache']);
46 /**
47 * Re-installs the table for a given Modelname and includes or even instantiates the Model.
48 * Looks in test/fixtures/app/models for the models and in test/fixtures/app/installers for the appropriate installers.
49 * If no class-file for Model is found, it generates a dumb one temporarily.
50 * For quick and dirty guys, the table can be generated on the fly. see below.
52 * examples:
53 * installAndIncludeModels('Article');
54 * installAndIncludeModels(array('Article','Comment'=>'id,body'));
56 * @param mixed $models
58 function installAndIncludeModels($models = array())
60 $args = func_get_args();
61 $last_arg = count($args)-1;
63 if (isset($args[$last_arg]) && is_array($args[$last_arg]) && (isset($args[$last_arg]['instantiate']) || isset($args[$last_arg]['populate']))){
64 $options = array_pop($args);
65 } else $options = array();
66 $default_options = array('instantiate' => true);
67 $options = array_merge($default_options, $options);
69 $models = !empty($args) ? (is_array($args[0]) ? array_shift($args) : (count($args) > 1 ? $args : Ak::toArray($args[0]))) : array();
71 foreach ($models as $key=>$value){ // handle array('Tag','Article') <= array
72 $model = is_numeric($key) ? $value : $key; // or array('Tag'=>'id,name'); <= a hash!
73 $table_definition = is_numeric($key) ? '' : $value;
74 $this->_reinstallModel($model, $table_definition);
75 $this->_includeOrGenerateModel($model);
76 if($this->insert_models_data || !empty($options['populate'])){
77 $this->populateTables(AkInflector::tableize($model));
79 if($this->instantiate_models || !empty($options['instantiate'])){
80 $this->instantiateModel($model);
83 if(isset($_SESSION['__activeRecordColumnsSettingsCache'])){
84 unset($_SESSION['__activeRecordColumnsSettingsCache']);
88 function _reinstallModel($model, $table_definition = '')
90 if (!$this->uninstallAndInstallMigration($model)){
91 $table_name = AkInflector::tableize($model);
92 if (empty($table_definition)) {
93 trigger_error(Ak::t('Could not install the table %tablename for the model %modelname',array('%tablename'=>$table_name, '%modelname'=>$model)),E_USER_ERROR);
94 return false;
96 $installer =& new AkInstaller();
97 $installer->dropTable($table_name,array('sequence'=>true));
98 $installer->createTable($table_name,$table_definition,array('timestamp'=>false));
102 function uninstallAndInstallMigration($installer_name)
104 if (file_exists(AK_APP_DIR.DS.'installers'.DS.AkInflector::underscore($installer_name).'_installer.php')){
105 require_once(AK_APP_DIR.DS.'installers'.DS.AkInflector::underscore($installer_name).'_installer.php');
106 $installer_class_name = $installer_name.'Installer';
107 $Installer =& new $installer_class_name();
108 $Installer->uninstall();
109 $Installer->install();
110 return true;
112 return false;
115 function _includeOrGenerateModel($model_name)
117 if (file_exists(AK_MODELS_DIR.DS.AkInflector::underscore($model_name).'.php')){
118 require_once(AK_MODELS_DIR.DS.AkInflector::underscore($model_name).'.php');
119 } else {
120 if (class_exists($model_name)){
121 return true;
123 $model_source_code = "class ".$model_name." extends ActiveRecord { ";
124 if (!AK_PHP5) $model_source_code .= $this->__fix_for_PHP4($model_name);
125 $model_source_code .= "}";
126 $has_errors = @eval($model_source_code) === false;
127 if ($has_errors) trigger_error(Ak::t('Could not declare the model %modelname.',array('%modelname'=>$model_name)),E_USER_ERROR);
131 function __fix_for_PHP4($model_name)
133 $table_name = AkInflector::tableize($model_name);
134 return "function $model_name()
136 \$this->setModelName('$model_name');
137 \$attributes = (array)func_get_args();
138 \$this->setTableName('$table_name');
139 \$this->init(\$attributes);
144 function populateTables()
146 $args = func_get_args();
147 $tables = !empty($args) ? (is_array($args[0]) ? $args[0] : (count($args) > 1 ? $args : Ak::toArray($args))) : array();
148 foreach ($tables as $table){
149 $file = AK_TEST_DIR.DS.'fixtures'.DS.'data'.DS.(empty($this->module)?'':$this->module.DS).Ak::sanitize_include($table).'.yaml';
150 if(!file_exists($file)){
151 continue;
153 $class_name = AkInflector::classify($table);
154 if($this->instantiateModel($class_name)){
155 $items = Ak::convert('yaml','array',file_get_contents($file));
156 foreach ($items as $item){
157 $this->{$class_name}->create($item);
163 function instantiateModel($model_name)
165 if(class_exists($model_name) || Ak::import($model_name)){
166 $this->$model_name =& new $model_name();
167 } else {
168 trigger_error(Ak::t('Could not instantiate %modelname',array('%modelname'=>$model_name)),E_USER_ERROR);
170 return !empty($this->$model_name) && is_object($this->$model_name) && strtolower(get_class($this->$model_name)) == strtolower($model_name);
174 * Includes and instantiates given models
176 function includeAndInstatiateModels()
178 $args = func_get_args();
179 $models = isset($args[1]) ? (array)$args : Ak::toArray($args[0]);
180 foreach ($models as $model){
181 $this->_includeOrGenerateModel($model);
182 $this->instantiateModel($model);
187 class AkWebTestCase extends WebTestCase
189 function assertWantedText($text, $message = '%s')
191 $this->assertWantedPattern('/'.preg_quote($text).'/', $message);
195 * Asserts only if the whole response matches $text
197 function assertTextMatch($text, $message = '%s')
199 $this->assertWantedPattern('/^'.preg_quote($text).'$/', $message);