From 7e4bb5300a4e8149b0b3803d5089e2d03002d20a Mon Sep 17 00:00:00 2001 From: Vendan Date: Tue, 28 May 2013 22:55:51 -0400 Subject: [PATCH] Clean merge of fixed mysql datetime handling --- .gitignore | 2 ++ .travis.yml | 5 ++- ActiveRecord.php | 4 +-- README.md | 2 +- composer.json | 5 +++ lib/Cache.php | 3 +- lib/CallBack.php | 3 +- lib/Column.php | 66 +++++++++++++++++++++++++++++++---- lib/Config.php | 31 ++++++++++++++-- lib/Connection.php | 19 +++++----- lib/ConnectionManager.php | 4 +-- lib/DateTime.php | 3 +- lib/Exceptions.php | 23 ++++++------ lib/Expressions.php | 15 +++++--- lib/Inflector.php | 3 +- lib/Model.php | 17 ++++----- lib/Reflections.php | 3 +- lib/Relationship.php | 11 +++--- lib/SQLBuilder.php | 3 +- lib/Serialization.php | 3 +- lib/Singleton.php | 5 ++- lib/Table.php | 3 +- lib/Utils.php | 8 +++-- lib/Validations.php | 3 +- lib/adapters/MysqlAdapter.php | 9 +++++ test/ActiveRecordFindTest.php | 14 +++++--- test/ColumnTest.php | 9 +++++ test/DateTimeTest.php | 15 ++++---- test/ExpressionsTest.php | 7 ++++ test/MysqlAdapterTest.php | 7 ++++ test/SqliteAdapterTest.php | 9 ++++- test/helpers/DatabaseTest.php | 6 ++-- test/helpers/config.php | 3 ++ 33 files changed, 229 insertions(+), 94 deletions(-) diff --git a/.gitignore b/.gitignore index 71debdbaa..c5370fc0d 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ *.log test/*.db *.swp +vendor/* +composer.lock \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 64da582da..29f25a3a8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,5 @@ +install: composer install --prefer-source --dev + before_script: - echo 'extension = "memcache.so"' >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini - mysql -e 'CREATE DATABASE phpar_test;' @@ -12,5 +14,6 @@ language: php php: - 5.3 - 5.4 + - 5.5 -script: phpunit -c phpunit.xml test/ +script: vendor/bin/phpunit -c phpunit.xml test/ diff --git a/ActiveRecord.php b/ActiveRecord.php index dda0ff632..17b325703 100644 --- a/ActiveRecord.php +++ b/ActiveRecord.php @@ -15,6 +15,7 @@ require __DIR__.'/lib/Table.php'; require __DIR__.'/lib/ConnectionManager.php'; require __DIR__.'/lib/Connection.php'; +require __DIR__.'/lib/Serialization.php'; require __DIR__.'/lib/SQLBuilder.php'; require __DIR__.'/lib/Reflections.php'; require __DIR__.'/lib/Inflector.php'; @@ -45,5 +46,4 @@ function activerecord_autoload($class_name) if (file_exists($file)) require_once $file; -} -?> +} \ No newline at end of file diff --git a/README.md b/README.md index 4355e4749..3d0680914 100755 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # PHP ActiveRecord - Version 1.0 # -[![Build Status](https://travis-ci.org/kla/php-activerecord.png?branch=master)](https://travis-ci.org/kla/php-activerecord) +[![Build Status](https://travis-ci.org/jpfuentes2/php-activerecord.png?branch=master)](https://travis-ci.org/jpfuentes2/php-activerecord) by diff --git a/composer.json b/composer.json index 40a14c8f1..a4eed119c 100644 --- a/composer.json +++ b/composer.json @@ -8,6 +8,11 @@ "require": { "php": ">=5.3.0" }, + "require-dev": { + "phpunit/phpunit": "3.7.*", + "pear/pear_exception": "1.0.*@dev", + "pear/Log": "dev-master" + }, "autoload": { "files": [ "ActiveRecord.php" ] } diff --git a/lib/Cache.php b/lib/Cache.php index e5f95f294..090a2468b 100644 --- a/lib/Cache.php +++ b/lib/Cache.php @@ -76,5 +76,4 @@ private static function get_namespace() { return (isset(static::$options['namespace']) && strlen(static::$options['namespace']) > 0) ? (static::$options['namespace'] . "::") : ""; } -} -?> +} \ No newline at end of file diff --git a/lib/CallBack.php b/lib/CallBack.php index c184384c4..3aaf50f9f 100644 --- a/lib/CallBack.php +++ b/lib/CallBack.php @@ -248,5 +248,4 @@ public function register($name, $closure_or_method_name=null, $options=array()) else $this->registry[$name][] = $closure_or_method_name; } -} -?> +} \ No newline at end of file diff --git a/lib/Column.php b/lib/Column.php index d73bd1b75..33c4790f3 100644 --- a/lib/Column.php +++ b/lib/Column.php @@ -30,10 +30,10 @@ class Column 'date' => self::DATE, 'time' => self::TIME, - 'int' => self::INTEGER, 'tinyint' => self::INTEGER, 'smallint' => self::INTEGER, 'mediumint' => self::INTEGER, + 'int' => self::INTEGER, 'bigint' => self::INTEGER, 'float' => self::DECIMAL, @@ -102,14 +102,56 @@ class Column */ public $sequence; + /** + * Cast a value to an integer type safely + * + * This will attempt to cast a value to an integer, + * unless its detected that the casting will cause + * the number to overflow or lose precision, in which + * case the number will be returned as a string, so + * that large integers (BIGINTS, unsigned INTS, etc) + * can still be stored without error + * + * This would ideally be done with bcmath or gmp, but + * requiring a new PHP extension for a bug-fix is a + * little ridiculous + * + * @param mixed $value The value to cast + * @return int|string type-casted value + */ + public static function castIntegerSafely($value) + { + if (is_int($value)) + return $value; + + // Its just a decimal number + elseif (is_numeric($value) && floor($value) != $value) + return (int) $value; + + // If adding 0 to a string causes a float conversion, + // we have a number over PHP_INT_MAX + elseif (is_string($value) && is_float($value + 0)) + return (string) $value; + + // If a float was passed and its greater than PHP_INT_MAX + // (which could be wrong due to floating point precision) + // We'll also check for equal to (>=) in case the precision + // loss creates an overflow on casting + elseif (is_float($value) && $value >= PHP_INT_MAX) + return number_format($value, 0, '', ''); + + return (int) $value; + } + /** * Casts a value to the column's type. * * @param mixed $value The value to cast * @param Connection $connection The Connection this column belongs to + * @param boolean $db_format Flag of whether to cast value from the database format * @return mixed type-casted value */ - public function cast($value, $connection) + public function cast($value, $connection, $db_format = false) { if ($value === null) return null; @@ -117,7 +159,7 @@ public function cast($value, $connection) switch ($this->type) { case self::STRING: return (string)$value; - case self::INTEGER: return (int)$value; + case self::INTEGER: return static::castIntegerSafely($value); case self::DECIMAL: return (double)$value; case self::DATETIME: case self::DATE: @@ -129,8 +171,21 @@ public function cast($value, $connection) if ($value instanceof \DateTime) return new DateTime($value->format('Y-m-d H:i:s T')); - - return $connection->string_to_datetime($value); + if($db_format) + { + return $connection->string_to_datetime($value); + } + else + { + try + { + return new DateTime($value); + } + catch(\Exception $e) + { + return null; + } + } } return $value; } @@ -152,4 +207,3 @@ public function map_raw_type() return $this->type; } } -?> \ No newline at end of file diff --git a/lib/Config.php b/lib/Config.php index eeee4f7b7..46f1c64e4 100644 --- a/lib/Config.php +++ b/lib/Config.php @@ -79,6 +79,14 @@ class Config extends Singleton */ private $date_format = \DateTime::ISO8601; + /** + * The current timezone to use by default in databases. + * Used for databases that can't store timezone info.(MySQL) + * + * @var DateTimeZone + */ + private $default_timezone; + /** * Allows config initialization using a closure. * @@ -280,6 +288,26 @@ public function set_date_format($format) Serialization::$DATETIME_FORMAT = $format; } + public function get_default_timezone() + { + if(!isset($this->default_timezone)) + { + $this->default_timezone = new \DateTimeZone(date_default_timezone_get()); + } + return $this->default_timezone; + } + + public function set_default_timezone($timezone) + { + if($timezone instanceof \DateTimeZone) + { + $this->default_timezone = $timezone; + } + else + { + $this->default_timezone = new \DateTimeZone($timezone); + } + } /** * Sets the url for the cache server to enable query caching. * @@ -300,5 +328,4 @@ public function set_cache($url, $options=array()) { Cache::initialize($url,$options); } -}; -?> +} diff --git a/lib/Connection.php b/lib/Connection.php index a083e9671..3f7670426 100644 --- a/lib/Connection.php +++ b/lib/Connection.php @@ -473,13 +473,15 @@ public function datetime_to_string($datetime) */ public function string_to_datetime($string) { - $date = date_create($string); - $errors = \DateTime::getLastErrors(); - - if ($errors['warning_count'] > 0 || $errors['error_count'] > 0) - return null; - - return new DateTime($date->format(static::$datetime_format)); + try + { + $datetime = new DateTime($string); + } + catch(\Exception $e) + { + $datetime = null; + } + return $datetime; } /** @@ -531,6 +533,3 @@ public function accepts_limit_and_order_for_update_and_delete() } } - -; -?> diff --git a/lib/ConnectionManager.php b/lib/ConnectionManager.php index 3f0b8db15..fb16d167f 100644 --- a/lib/ConnectionManager.php +++ b/lib/ConnectionManager.php @@ -46,6 +46,4 @@ public static function drop_connection($name=null) if (isset(self::$connections[$name])) unset(self::$connections[$name]); } -} - -?> +} \ No newline at end of file diff --git a/lib/DateTime.php b/lib/DateTime.php index b701efdff..9b488236b 100644 --- a/lib/DateTime.php +++ b/lib/DateTime.php @@ -147,5 +147,4 @@ public function setTimestamp($unixtimestamp) $this->flag_dirty(); call_user_func_array(array($this,'parent::setTimestamp'),func_get_args()); } -} -?> +} \ No newline at end of file diff --git a/lib/Exceptions.php b/lib/Exceptions.php index ee66d40d6..3e2e05173 100644 --- a/lib/Exceptions.php +++ b/lib/Exceptions.php @@ -9,14 +9,14 @@ * * @package ActiveRecord */ -class ActiveRecordException extends \Exception {}; +class ActiveRecordException extends \Exception {} /** * Thrown when a record cannot be found. * * @package ActiveRecord */ -class RecordNotFound extends ActiveRecordException {}; +class RecordNotFound extends ActiveRecordException {} /** * Thrown when there was an error performing a database operation. @@ -44,28 +44,28 @@ public function __construct($adapter_or_string_or_mystery) else parent::__construct($adapter_or_string_or_mystery); } -}; +} /** * Thrown by {@link Model}. * * @package ActiveRecord */ -class ModelException extends ActiveRecordException {}; +class ModelException extends ActiveRecordException {} /** * Thrown by {@link Expressions}. * * @package ActiveRecord */ -class ExpressionsException extends ActiveRecordException {}; +class ExpressionsException extends ActiveRecordException {} /** * Thrown for configuration problems. * * @package ActiveRecord */ -class ConfigException extends ActiveRecordException {}; +class ConfigException extends ActiveRecordException {} /** * Thrown when attempting to access an invalid property on a {@link Model}. @@ -91,7 +91,7 @@ public function __construct($class_name, $property_name) $this->message = "Undefined property: {$class_name}->{$property_name} in {$this->file} on line {$this->line}"; parent::__construct(); } -}; +} /** * Thrown when attempting to perform a write operation on a {@link Model} that is in read-only mode. @@ -112,26 +112,25 @@ public function __construct($class_name, $method_name) $this->message = "{$class_name}::{$method_name}() cannot be invoked because this model is set to read only"; parent::__construct(); } -}; +} /** * Thrown for validations exceptions. * * @package ActiveRecord */ -class ValidationsArgumentError extends ActiveRecordException {}; +class ValidationsArgumentError extends ActiveRecordException {} /** * Thrown for relationship exceptions. * * @package ActiveRecord */ -class RelationshipException extends ActiveRecordException {}; +class RelationshipException extends ActiveRecordException {} /** * Thrown for has many thru exceptions. * * @package ActiveRecord */ -class HasManyThroughAssociationException extends RelationshipException {}; -?> \ No newline at end of file +class HasManyThroughAssociationException extends RelationshipException {} \ No newline at end of file diff --git a/lib/Expressions.php b/lib/Expressions.php index f023d5aba..3fa2962fa 100644 --- a/lib/Expressions.php +++ b/lib/Expressions.php @@ -148,16 +148,24 @@ private function substitute(&$values, $substitute, $pos, $parameter_index) if (is_array($value)) { + $value_count = count($value); + + if ($value_count === 0) + if ($substitute) + return 'NULL'; + else + return self::ParameterMarker; + if ($substitute) { $ret = ''; - for ($i=0,$n=count($value); $i<$n; ++$i) + for ($i=0, $n=$value_count; $i<$n; ++$i) $ret .= ($i > 0 ? ',' : '') . $this->stringify_value($value[$i]); return $ret; } - return join(',',array_fill(0,count($value),self::ParameterMarker)); + return join(',',array_fill(0,$value_count,self::ParameterMarker)); } if ($substitute) @@ -181,5 +189,4 @@ private function quote_string($value) return "'" . str_replace("'","''",$value) . "'"; } -} -?> +} \ No newline at end of file diff --git a/lib/Inflector.php b/lib/Inflector.php index 56f990601..732fb3422 100644 --- a/lib/Inflector.php +++ b/lib/Inflector.php @@ -116,5 +116,4 @@ class StandardInflector extends Inflector { public function tableize($s) { return Utils::pluralize(strtolower($this->underscorify($s))); } public function variablize($s) { return str_replace(array('-',' '),array('_','_'),strtolower(trim($s))); } -} -?> +} \ No newline at end of file diff --git a/lib/Model.php b/lib/Model.php index 2c9bdb4ea..ca0b14b9e 100644 --- a/lib/Model.php +++ b/lib/Model.php @@ -258,7 +258,7 @@ public function __construct(array $attributes=array(), $guard_attributes=true, $ $this->attributes[$meta->inflected_name] = $meta->default; } - $this->set_attributes_via_mass_assignment($attributes, $guard_attributes); + $this->set_attributes_via_mass_assignment($attributes, $guard_attributes, true); // since all attribute assignment now goes thru assign_attributes() we want to reset // dirty if instantiating via find since nothing is really dirty when doing that @@ -431,18 +431,19 @@ public function __wakeup() * * @param string $name Name of the attribute * @param mixed &$value Value of the attribute + * @param boolean $db_format If it needs to be casted as a "from database" value * @return mixed the attribute value */ - public function assign_attribute($name, $value) + public function assign_attribute($name, $value, $db_format = false) { $table = static::table(); if (!is_object($value)) { if (array_key_exists($name, $table->columns)) { - $value = $table->columns[$name]->cast($value, static::connection()); + $value = $table->columns[$name]->cast($value, static::connection(), $db_format); } else { $col = $table->get_column_by_inflected_name($name); if (!is_null($col)){ - $value = $col->cast($value, static::connection()); + $value = $col->cast($value, static::connection(), $db_format); } } } @@ -1155,8 +1156,9 @@ public function set_attributes(array $attributes) * @throws ActiveRecord\UndefinedPropertyException * @param array $attributes An array in the form array(name => value, ...) * @param boolean $guard_attributes Flag of whether or not protected/non-accessible attributes should be guarded + * @param boolean $db_format Flag of whether to cast value from the database type */ - private function set_attributes_via_mass_assignment(array &$attributes, $guard_attributes) + private function set_attributes_via_mass_assignment(array &$attributes, $guard_attributes, $db_format = false) { //access uninflected columns since that is what we would have in result set $table = static::table(); @@ -1170,7 +1172,7 @@ private function set_attributes_via_mass_assignment(array &$attributes, $guard_a // is a normal field on the table if (array_key_exists($name,$table->columns)) { - $value = $table->columns[$name]->cast($value,$connection); + $value = $table->columns[$name]->cast($value,$connection, $db_format); $name = $table->columns[$name]->inflected_name; } @@ -1858,5 +1860,4 @@ public static function transaction($closure) } return true; } -}; -?> +} diff --git a/lib/Reflections.php b/lib/Reflections.php index f41a9b2ff..2a03627e8 100644 --- a/lib/Reflections.php +++ b/lib/Reflections.php @@ -82,5 +82,4 @@ private function get_class($mixed=null) return $this->get_called_class(); } -} -?> \ No newline at end of file +} \ No newline at end of file diff --git a/lib/Relationship.php b/lib/Relationship.php index dd1519cd1..297d89438 100644 --- a/lib/Relationship.php +++ b/lib/Relationship.php @@ -380,7 +380,7 @@ public function construct_inner_join_sql(Table $from_table, $using_through=false * @param Model $model The model this relationship belongs to */ abstract function load(Model $model); -}; +} /** * One-to-many relationship. @@ -604,7 +604,7 @@ public function load_eagerly($models=array(), $attributes=array(), $includes, Ta $this->set_keys($table->class->name); $this->query_and_attach_related_models_eagerly($table,$models,$attributes,$includes,$this->foreign_key, $table->pk); } -}; +} /** * One-to-one relationship. @@ -626,7 +626,7 @@ public function load_eagerly($models=array(), $attributes=array(), $includes, Ta */ class HasOne extends HasMany { -}; +} /** * @todo implement me @@ -650,7 +650,7 @@ public function load(Model $model) { } -}; +} /** * Belongs to relationship. @@ -725,5 +725,4 @@ public function load_eagerly($models=array(), $attributes, $includes, Table $tab { $this->query_and_attach_related_models_eagerly($table,$models,$attributes,$includes, $this->primary_key,$this->foreign_key); } -}; -?> +} \ No newline at end of file diff --git a/lib/SQLBuilder.php b/lib/SQLBuilder.php index 58a3c8a40..ef239ed87 100644 --- a/lib/SQLBuilder.php +++ b/lib/SQLBuilder.php @@ -419,5 +419,4 @@ private function quoted_key_names() return $keys; } -} -?> +} \ No newline at end of file diff --git a/lib/Serialization.php b/lib/Serialization.php index fd3e179c2..db0208808 100644 --- a/lib/Serialization.php +++ b/lib/Serialization.php @@ -368,5 +368,4 @@ private function to_csv($arr) fclose($outstream); return $buffer; } -} -?> +} \ No newline at end of file diff --git a/lib/Singleton.php b/lib/Singleton.php index 429164a4a..fe370c2fc 100644 --- a/lib/Singleton.php +++ b/lib/Singleton.php @@ -51,7 +51,6 @@ final private function __clone() {} final protected function get_called_class() { $backtrace = debug_backtrace(); - return get_class($backtrace[2]['object']); + return get_class($backtrace[2]['object']); } -} -?> \ No newline at end of file +} \ No newline at end of file diff --git a/lib/Table.php b/lib/Table.php index e1ac5541f..ac39ee336 100644 --- a/lib/Table.php +++ b/lib/Table.php @@ -551,5 +551,4 @@ private function set_setters_and_getters() trigger_error('static::$getters and static::$setters are deprecated. Please define your setters and getters by declaring methods in your model prefixed with get_ or set_. See http://www.phpactiverecord.org/projects/main/wiki/Utilities#attribute-setters and http://www.phpactiverecord.org/projects/main/wiki/Utilities#attribute-getters on how to make use of this option.', E_USER_DEPRECATED); } -}; -?> +} \ No newline at end of file diff --git a/lib/Utils.php b/lib/Utils.php index 6218807de..af5840cd6 100644 --- a/lib/Utils.php +++ b/lib/Utils.php @@ -362,5 +362,9 @@ public static function squeeze($char, $string) { return preg_replace("/$char+/",$char,$string); } -}; -?> + + public static function add_irregular($singular, $plural) + { + self::$irregular[$singular] = $plural; + } +} \ No newline at end of file diff --git a/lib/Validations.php b/lib/Validations.php index e503653ce..39ea6cfb8 100644 --- a/lib/Validations.php +++ b/lib/Validations.php @@ -908,5 +908,4 @@ public function getIterator() { return new ArrayIterator($this->full_messages()); } -}; -?> +} \ No newline at end of file diff --git a/lib/adapters/MysqlAdapter.php b/lib/adapters/MysqlAdapter.php index 12a50db63..ec27abce3 100644 --- a/lib/adapters/MysqlAdapter.php +++ b/lib/adapters/MysqlAdapter.php @@ -13,6 +13,8 @@ class MysqlAdapter extends Connection { static $DEFAULT_PORT = 3306; + static $datetime_format = 'Y-m-d H:i:s'; + public function limit($sql, $offset, $limit) { $offset = is_null($offset) ? '' : intval($offset) . ','; @@ -76,6 +78,13 @@ public function set_encoding($charset) $this->query('SET NAMES ?',$params); } + public function datetime_to_string($datetime) + { + $newDatetime = clone $datetime; + $newDatetime->setTimezone(Config::instance()->get_default_timezone()); + return parent::datetime_to_string($newDatetime); + } + public function accepts_limit_and_order_for_update_and_delete() { return true; } public function native_database_types() diff --git a/test/ActiveRecordFindTest.php b/test/ActiveRecordFindTest.php index aa513fe41..f8289978c 100644 --- a/test/ActiveRecordFindTest.php +++ b/test/ActiveRecordFindTest.php @@ -79,6 +79,15 @@ public function test_find_all_with_no_bind_values() $this->assert_equals(1,$authors[0]->author_id); } + /** + * @expectedException ActiveRecord\DatabaseException + */ + public function test_find_all_with_empty_array_bind_value_throws_exception() + { + $authors = Author::find('all',array('conditions' => array('author_id IN(?)', array()))); + $this->assertCount(0,$authors); + } + public function test_find_hash_using_alias() { $venues = Venue::all(array('conditions' => array('marquee' => 'Warner Theatre', 'city' => array('Washington','New York')))); @@ -451,11 +460,6 @@ public function test_find_by_pk_should_not_use_limit() public function test_find_by_datetime() { - if ( getenv('TRAVIS') ) $this->markTestSkipped( - 'The Travis CI environment seems to screw this up for unknonwn reasons; ' . - 'see Github #298 (https://github.com/kla/php-activerecord/issues/298)' - ); - $now = new DateTime(); $arnow = new ActiveRecord\DateTime(); $arnow->setTimestamp($now->getTimestamp()); diff --git a/test/ColumnTest.php b/test/ColumnTest.php index c9a8a9187..f5769bc68 100644 --- a/test/ColumnTest.php +++ b/test/ColumnTest.php @@ -86,6 +86,15 @@ public function test_cast() $this->assert_cast(Column::DATE,$datetime,'2001-01-01'); $this->assert_cast(Column::DATE,$datetime,$datetime); $this->assert_cast(Column::STRING,'bubble tea','bubble tea'); + $this->assert_cast(Column::INTEGER,4294967295,'4294967295'); + $this->assert_cast(Column::INTEGER,'18446744073709551615','18446744073709551615'); + + // 32 bit + if (PHP_INT_SIZE === 4) + $this->assert_cast(Column::INTEGER,'2147483648',(((float) PHP_INT_MAX) + 1)); + // 64 bit + elseif (PHP_INT_SIZE === 8) + $this->assert_cast(Column::INTEGER,'9223372036854775808',(((float) PHP_INT_MAX) + 1)); } public function test_cast_leave_null_alone() diff --git a/test/DateTimeTest.php b/test/DateTimeTest.php index 285ca0ea8..5bb098755 100644 --- a/test/DateTimeTest.php +++ b/test/DateTimeTest.php @@ -7,6 +7,7 @@ class DateTimeTest extends SnakeCase_PHPUnit_Framework_TestCase public function set_up() { $this->date = new DateTime(); + $this->time = time(); $this->original_format = DateTime::$DEFAULT_FORMAT; } @@ -85,43 +86,43 @@ public function test_format() public function test_format_by_friendly_name() { - $d = date(DateTime::get_format('db')); + $d = date(DateTime::get_format('db'), $this->time); $this->assert_equals($d, $this->date->format('db')); } public function test_format_by_custom_format() { $format = 'Y/m/d'; - $this->assert_equals(date($format), $this->date->format($format)); + $this->assert_equals(date($format, $this->time), $this->date->format($format)); } public function test_format_uses_default() { - $d = date(DateTime::$FORMATS[DateTime::$DEFAULT_FORMAT]); + $d = date(DateTime::$FORMATS[DateTime::$DEFAULT_FORMAT], $this->time); $this->assert_equals($d, $this->date->format()); } public function test_all_formats() { foreach (DateTime::$FORMATS as $name => $format) - $this->assert_equals(date($format), $this->date->format($name)); + $this->assert_equals(date($format, $this->time), $this->date->format($name)); } public function test_change_default_format_to_format_string() { DateTime::$DEFAULT_FORMAT = 'H:i:s'; - $this->assert_equals(date(DateTime::$DEFAULT_FORMAT), $this->date->format()); + $this->assert_equals(date(DateTime::$DEFAULT_FORMAT, $this->time), $this->date->format()); } public function test_change_default_format_to_friently() { DateTime::$DEFAULT_FORMAT = 'short'; - $this->assert_equals(date(DateTime::$FORMATS['short']), $this->date->format()); + $this->assert_equals(date(DateTime::$FORMATS['short'], $this->time), $this->date->format()); } public function test_to_string() { - $this->assert_equals(date(DateTime::get_format()), "" . $this->date); + $this->assert_equals(date(DateTime::get_format(), $this->time), "" . $this->date); } } ?> diff --git a/test/ExpressionsTest.php b/test/ExpressionsTest.php index e2e8ac6b5..fdddb57ea 100644 --- a/test/ExpressionsTest.php +++ b/test/ExpressionsTest.php @@ -82,6 +82,13 @@ public function test_zero_variable() $this->assert_equals(array(0),$a->values()); } + public function test_empty_array_variable() + { + $a = new Expressions(null,'id IN(?)',array()); + $this->assert_equals('id IN(?)',$a->to_s()); + $this->assert_equals(array(array()),$a->values()); + } + public function test_ignore_invalid_parameter_marker() { $a = new Expressions(null,"question='Do you love backslashes?' and id in(?)",array(1,2)); diff --git a/test/MysqlAdapterTest.php b/test/MysqlAdapterTest.php index 2a93570e6..9fb1fd184 100644 --- a/test/MysqlAdapterTest.php +++ b/test/MysqlAdapterTest.php @@ -33,5 +33,12 @@ public function test_limit_with_null_offset_does_not_contain_offset() $this->assert_true(strpos($this->conn->last_query, 'LIMIT 1') !== false); } + + public function test_datetime_to_string() + { + $datetime = new DateTime('2009-01-01 01:01:01 EST'); + $roundtrip = $this->conn->string_to_datetime($this->conn->datetime_to_string($datetime)); + $this->assert_equals($datetime->getTimestamp(), $roundtrip->getTimestamp()); + } } ?> diff --git a/test/SqliteAdapterTest.php b/test/SqliteAdapterTest.php index b3c3f1cf1..48b8c1b5b 100644 --- a/test/SqliteAdapterTest.php +++ b/test/SqliteAdapterTest.php @@ -12,10 +12,17 @@ public function tearDown() { parent::tearDown(); - @unlink($this->db); @unlink(self::InvalidDb); } + + public static function _tearDownAfterClass() + { + parent::tearDownAfterClass(); + + @unlink($this->db); + } + public function testConnectToInvalidDatabaseShouldNotCreateDbFile() { try diff --git a/test/helpers/DatabaseTest.php b/test/helpers/DatabaseTest.php index 22209447e..45ebc4069 100644 --- a/test/helpers/DatabaseTest.php +++ b/test/helpers/DatabaseTest.php @@ -55,7 +55,7 @@ public function assert_exception_message_contains($contains, $closure) $message = $e->getMessage(); } - $this->assert_true(strpos($message,$contains) !== false); + $this->assertContains($contains, $message); } /** @@ -68,14 +68,14 @@ public function assert_sql_has($needle, $haystack) { $needle = str_replace(array('"','`'),'',$needle); $haystack = str_replace(array('"','`'),'',$haystack); - return $this->assert_true(strpos($haystack,$needle) !== false); + return $this->assertContains($needle, $haystack); } public function assert_sql_doesnt_has($needle, $haystack) { $needle = str_replace(array('"','`'),'',$needle); $haystack = str_replace(array('"','`'),'',$haystack); - return $this->assert_false(strpos($haystack,$needle) !== false); + return $this->assertNotContains($needle, $haystack); } } ?> diff --git a/test/helpers/config.php b/test/helpers/config.php index 159e17136..7a64233ae 100644 --- a/test/helpers/config.php +++ b/test/helpers/config.php @@ -9,6 +9,9 @@ * To run a specific test : phpunit ????Test.php */ +set_include_path(get_include_path() . PATH_SEPARATOR . './vendor/phpunit/PHPUnit' + . PATH_SEPARATOR . './vendor/pear/log'); + @include_once 'Log.php'; @include_once 'Log/file.php'; require_once 'PHPUnit/Framework/TestCase.php';