[ Index ]

PHP Cross Reference of Akelos Framework

title

Body

[close]

/ -> AkUnitTest.php (source)

   1  <?php
   2  /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
   3  
   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  // +----------------------------------------------------------------------+
  10  
  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>
  17   */
  18  
  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');
  24  
  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');
  28  
  29  class AkUnitTest extends UnitTestCase
  30  {
  31      var $module = '';
  32      var $insert_models_data = false;
  33      var $instantiate_models = false;
  34      
  35      function AkUnitTest($label = false) {
  36          parent::UnitTestCase($label);
  37          $this->_configure();
  38      }
  39      
  40      /**
  41       *    Gets a list of test names. Normally that will
  42       *    be all internal methods that start with the
  43       *    name "test". This method should be overridden
  44       *    if you want a different rule.
  45       *    @return array        List of test names.
  46       *    @access public
  47       */
  48      function getTests() {
  49          $methods = array();
  50          if (isset($this->skip) && $this->skip == true) {
  51              return $methods;
  52          }
  53          foreach (get_class_methods(get_class($this)) as $method) {
  54              if ($this->_isTest($method)) {
  55                  $methods[] = $method;
  56              }
  57          }
  58          return $methods;
  59      }
  60      
  61      function _configure()
  62      {
  63          $this->skip = !$this->_checkIfEnabled();
  64          $this->_loadFixtures();
  65      }
  66      
  67      function _checkIfEnabled($file = null)
  68      {
  69          if ($file == null) {
  70              $file = isset($this->check_file)?$this->check_file:null;
  71          }
  72          if ($file!=null && file_exists($file)) {
  73              $val = file_get_contents($file);
  74              if ($val == '0') {
  75                  return false;
  76              }
  77          }
  78          return true;
  79      }
  80      
  81      
  82      function _loadFixtures($loadFixture = null)
  83      {
  84          if (isset($this->fixtures)) {
  85              $this->fixtures = is_array($this->fixtures)?$this->fixtures:Ak::toArray($this->fixtures);
  86          } else {
  87              $this->fixtures = array();
  88          }
  89          
  90          foreach ($this->fixtures as $fixture) {
  91              $file = AK_TEST_DIR.DS.'fixtures'.DS.'data'.DS.$fixture.'.yaml';
  92              if(!file_exists($file)){
  93                  continue;
  94              }
  95              if ($loadFixture!=null && $fixture!=$loadFixture) {
  96                  continue;
  97              }
  98              $setAlias=false;
  99              if (!isset($this->$fixture)) {
 100                  $this->$fixture = array();
 101                  $setAlias=true;
 102                  $this->{$fixture.'_set'}=true;
 103              } else if ($this->{$fixture.'_set'}) {
 104                  $setAlias = true;
 105              }
 106              $class_name = AkInflector::classify($fixture);
 107              if($this->instantiateModel($class_name)){
 108                  $contents = &Ak::getStaticVar('yaml_fixture_'.$file);
 109                  if (!$contents) {
 110                      ob_start();
 111                      require_once($file);
 112                      $contents = ob_get_clean();
 113                      Ak::setStaticVar('yaml_fixture_'.$file, $contents);
 114                  }
 115                  $items = Ak::convert('yaml','array',$contents);
 116                  foreach ($items as $alias=>$item){
 117                      $obj=&$this->{$class_name}->create($item);
 118                      if (isset($item['created_at'])) {
 119                          $obj->updateAttribute('created_at',$item['created_at']);
 120                      } else if (isset($item['created_on'])) {
 121                          $obj->updateAttribute('created_on',$item['created_on']);
 122                      }
 123                      if ($setAlias) {
 124                          $array=&$this->$fixture;
 125                          $array[$alias] = &$obj;
 126                          $this->$fixture = &$array;
 127                      }
 128                  }
 129              }
 130          }
 131      }
 132      
 133      function resetFrameworkDatabaseTables()
 134      {
 135          require_once(AK_APP_DIR.DS.'installers'.DS.'framework_installer.php');
 136          $installer = new FrameworkInstaller();
 137          $installer->uninstall();
 138          $installer->install();
 139          AkDbSchemaCache::clearAll();
 140      }
 141  
 142      /**
 143       * Re-installs the table for a given Modelname and includes or even instantiates the Model.
 144       * Looks in test/fixtures/app/models for the models and in test/fixtures/app/installers for the appropriate installers.
 145       * If no class-file for Model is found, it generates a dumb one temporarily.
 146       * For quick and dirty guys, the table can be generated on the fly. see below.
 147       *  
 148       * examples:
 149       * installAndIncludeModels('Article');
 150       * installAndIncludeModels(array('Article','Comment'=>'id,body'));
 151       *
 152       * @param mixed $models
 153       */
 154      function installAndIncludeModels($models = array())
 155      {
 156          $args = func_get_args();
 157          $last_arg = count($args)-1;
 158  
 159          if (isset($args[$last_arg]) && is_array($args[$last_arg]) && (isset($args[$last_arg]['instantiate']) || isset($args[$last_arg]['populate']))){
 160              $options = array_pop($args);
 161          } else $options = array();
 162          $default_options = array('instantiate' => true);
 163          $options = array_merge($default_options, $options);
 164  
 165          $models = !empty($args) ? (is_array($args[0]) ? array_shift($args) : (count($args) > 1 ? $args : Ak::toArray($args[0]))) : array();
 166  
 167          foreach ($models as $key=>$value){                               // handle array('Tag','Article')   <= array
 168              $model = is_numeric($key) ? $value : $key;                   //  or    array('Tag'=>'id,name'); <= a hash!
 169              $table_definition = is_numeric($key) ? '' : $value;
 170              $this->_reinstallModel($model, $table_definition);
 171              $this->_includeOrGenerateModel($model);
 172              if($this->insert_models_data || !empty($options['populate'])){
 173                  $this->populateTables(AkInflector::tableize($model));
 174              }
 175              if($this->instantiate_models || !empty($options['instantiate'])){
 176                  $this->instantiateModel($model);
 177              }
 178          }
 179      }
 180  
 181      function _reinstallModel($model, $table_definition = '')
 182      {
 183          if (!$this->uninstallAndInstallMigration($model)){
 184              $table_name = AkInflector::tableize($model);
 185              if (empty($table_definition)) {
 186                  trigger_error(Ak::t('Could not install the table %tablename for the model %modelname',array('%tablename'=>$table_name, '%modelname'=>$model)),E_USER_ERROR);
 187                  return false;
 188              }
 189              $installer =& new AkInstaller();
 190              $installer->dropTable($table_name,array('sequence'=>true));
 191              $installer->createTable($table_name,$table_definition,array('timestamp'=>false));
 192              
 193          } else {
 194              $table_name = AkInflector::tableize($model);
 195          }
 196          if (isset($this->fixtures) && is_array($this->fixtures) && in_array($table_name,$this->fixtures)) {
 197              $this->_loadFixtures($table_name);
 198          }
 199      }
 200  
 201      function uninstallAndInstallMigration($installer_name)
 202      {
 203          if (file_exists(AK_APP_DIR.DS.'installers'.DS.AkInflector::underscore($installer_name).'_installer.php')){
 204              require_once(AK_APP_DIR.DS.'installers'.DS.AkInflector::underscore($installer_name).'_installer.php');
 205              $installer_class_name = $installer_name.'Installer';
 206              $Installer =& new $installer_class_name();
 207              $Installer->uninstall();
 208              $Installer->install();
 209              return true;
 210          }
 211          return false;
 212      }
 213  
 214      function _includeOrGenerateModel($model_name)
 215      {
 216          if (file_exists(AK_MODELS_DIR.DS.AkInflector::underscore($model_name).'.php')){
 217              require_once(AK_MODELS_DIR.DS.AkInflector::underscore($model_name).'.php');
 218          } else {
 219              if (class_exists($model_name)){
 220                  return true;
 221              }
 222              $model_source_code = "class ".$model_name." extends ActiveRecord { ";
 223              if (!AK_PHP5) $model_source_code .= $this->__fix_for_PHP4($model_name);
 224              $model_source_code .= "}";
 225              $has_errors = @eval($model_source_code) === false;
 226              if ($has_errors) trigger_error(Ak::t('Could not declare the model %modelname.',array('%modelname'=>$model_name)),E_USER_ERROR);
 227          }
 228      }
 229  
 230      function __fix_for_PHP4($model_name)
 231      {
 232          $table_name = AkInflector::tableize($model_name);
 233          return "function $model_name()
 234      {
 235          \$this->setModelName('$model_name');
 236          \$attributes = (array)func_get_args();
 237          \$this->setTableName('$table_name');
 238          \$this->init(\$attributes);
 239      }";
 240  
 241      }
 242  
 243      function populateTables()
 244      {
 245          
 246          $args = func_get_args();
 247          $tables = !empty($args) ? (is_array($args[0]) ? $args[0] : (count($args) > 1 ? $args : Ak::toArray($args))) : array();
 248          foreach ($tables as $table){
 249              $file = AK_TEST_DIR.DS.'fixtures'.DS.'data'.DS.(empty($this->module)?'':$this->module.DS).Ak::sanitize_include($table).'.yaml';
 250              if(!file_exists($file)){
 251                  continue;
 252              }
 253              $class_name = AkInflector::classify($table);
 254              if($this->instantiateModel($class_name)){
 255                  $contents = &Ak::getStaticVar('yaml_fixture_'.$file);
 256                  if (!$contents) {
 257                      ob_start();
 258                      require_once($file);
 259                      $contents = ob_get_clean();
 260                      Ak::setStaticVar('yaml_fixture_'.$file, $contents);
 261                  }
 262                  $items = Ak::convert('yaml','array',$contents);
 263                  foreach ($items as $item){
 264                      
 265                      $obj=&$this->{$class_name}->create($item);
 266                      if (isset($item['created_at'])) {
 267                          $obj->updateAttribute('created_at',$item['created_at']);
 268                      } else if (isset($item['created_on'])) {
 269                          $obj->updateAttribute('created_on',$item['created_on']);
 270                      }
 271                  }
 272              }
 273          }
 274      }
 275  
 276      function instantiateModel($model_name)
 277      {
 278          if(class_exists($model_name) || Ak::import($model_name)){
 279              $this->$model_name =& new $model_name();
 280          } else {
 281              trigger_error(Ak::t('Could not instantiate %modelname',array('%modelname'=>$model_name)),E_USER_ERROR);
 282          }
 283          return !empty($this->$model_name) && is_object($this->$model_name) && strtolower(get_class($this->$model_name)) == strtolower($model_name);
 284      }
 285  
 286      /**
 287       * Includes and instantiates given models
 288       */
 289      function includeAndInstatiateModels()
 290      {
 291          $args = func_get_args();
 292          $models = isset($args[1]) ? (array)$args : Ak::toArray($args[0]);
 293          foreach ($models as $model){
 294              $this->_includeOrGenerateModel($model);
 295              $this->instantiateModel($model);
 296          }
 297      }
 298  }
 299  
 300  /**
 301  * Unit tester for your mailers.
 302  *
 303  * This tester will copy your application views from the app/views to test/fixtures/app/views 
 304  * unless you implicitly set AkMailerTest::avoid_copying_views to true.
 305  */
 306  class AkMailerTest extends AkUnitTest 
 307  {
 308      function __construct()
 309      {
 310          empty($this->avoid_copying_views) && Ak::copy(AK_BASE_DIR.DS.'app'.DS.'views',AK_VIEWS_DIR);
 311      }
 312  }
 313  
 314  class AkWebTestCase extends WebTestCase
 315  {
 316      function assertWantedText($text, $message = '%s')
 317      {
 318          $this->assertWantedPattern('/'.preg_quote($text).'/', $message);
 319      }
 320  
 321      /**
 322       * Asserts only if the whole response matches $text
 323       */
 324      function assertTextMatch($text, $message = '%s')
 325      {
 326          $this->assertWantedPattern('/^'.preg_quote($text).'$/', $message);
 327      }
 328  }
 329  
 330  ?>


Generated: Mon Oct 27 12:43:49 2008 Cross-referenced by PHPXref 0.6