From e53a91fe8c460434e3d5e422bab46559963592c2 Mon Sep 17 00:00:00 2001
From: Robert Sesek
Date: Tue, 14 Aug 2007 01:42:55 +0000
Subject: [PATCH] Adding database unit tests and in the Db module, use a new
DatabaseException class intead of triggering errors
---
Db.php | 70 ++++++-----
DbMySql.php | 1 +
docs/UnitTest/AllTests.php | 3 +
docs/UnitTest/DatabaseMySQLTest.php | 43 +++++++
docs/UnitTest/DatabaseMySQLiTest.php | 43 +++++++
docs/UnitTest/DatabaseTestAbstract.php | 167 +++++++++++++++++++++++++
docs/UnitTest/DatabaseTests.php | 40 ++++++
docs/UnitTest/tests.config.php.new | 12 ++
8 files changed, 351 insertions(+), 28 deletions(-)
create mode 100644 docs/UnitTest/DatabaseMySQLTest.php
create mode 100644 docs/UnitTest/DatabaseMySQLiTest.php
create mode 100644 docs/UnitTest/DatabaseTestAbstract.php
create mode 100644 docs/UnitTest/DatabaseTests.php
diff --git a/Db.php b/Db.php
index e39addd..9450351 100644
--- a/Db.php
+++ b/Db.php
@@ -117,7 +117,7 @@ abstract class BSDb
if ($this->dblink == false)
{
- $this->_error('DB-Link == false, cannot connect');
+ throw new BSDbException('Connect Failed', -1, 'DB-Link == false; connect failed');
return false;
}
@@ -155,7 +155,7 @@ abstract class BSDb
if (!$this->result)
{
- $this->_error('Invalid SQL query');
+ throw new BSDbException($this->_errorString(), $this->_errorNumber(), $string);
}
$this->history[] = $history = array('query' => $string, 'time' => BSFunctions::FetchMicrotimeDiff($time), 'trace' => BSFunctions::FormatBacktrace(debug_backtrace()));
@@ -449,36 +449,50 @@ abstract class BSDb
* should never be reached as it's always overridden
*/
public abstract function transactionCommit();
+}
+
+/**
+ * Database Exception
+ *
+ * Exception handler class for the database classes
+ *
+ * @author Blue Static
+ * @copyright Copyright (c)2002 - [#]year[#], Blue Static
+ * @version $Id$
+ * @package ISSO
+ *
+ */
+class BSDbException extends Exception
+{
+ /**
+ * The query string that caused the error
+ * @var string
+ */
+ private $query;
// ###################################################################
/**
- * Error wrapper for ISSO->message()
- *
- * @param string User defined error message
- */
- protected function _error($message)
+ * Initializes a new database exception
+ *
+ * @param string The error message
+ * @param ineger MySQL error code
+ * @param sring Query string that caused the error
+ */
+ public function __construct($error, $errorNum, $query)
{
- if ($this->showerrors)
- {
- if ($this->dblink)
- {
- $this->errnum = $this->_errorNumber();
- $this->errstr = $this->_errorString();
- }
-
- $style['code'] = 'font-family: \'Courier New\', Courier, mono; font-size: 11px;';
-
- $message_prepped = "\n";
- $message_prepped .= "\n\t» Query:\n
" . htmlspecialchars($this->querystr) ."
\n
";
- $message_prepped .= "\n\t» Error Number: " . $this->errnum . "\n
";
- $message_prepped .= "\n\t» Error Message: " . $this->errstr . "\n
";
- $message_prepped .= "\n\t» Additional Notes: " . $message . "\n
";
- $message_prepped .= "\n\t» File: " . $_SERVER['PHP_SELF'] . "\n";
- $message_prepped .= "\n
\n";
-
- BSRegister::Message('Database Error in `' . BSRegister::GetApplication() . '`', $message_prepped, 3);
- exit;
- }
+ $this->query = $query;
+ parent::__construct($error, $errorNum);
+ }
+
+ // ###################################################################
+ /**
+ * Returns the query that failed
+ *
+ * @return string
+ */
+ public function getQuery()
+ {
+ return $this->query;
}
}
diff --git a/DbMySql.php b/DbMySql.php
index c009152..80c6fb4 100644
--- a/DbMySql.php
+++ b/DbMySql.php
@@ -67,6 +67,7 @@ class BSDbMySql extends BSDb
{
if (!mysql_select_db($database, $link))
{
+ throw new BSDbException($this->_errorString(), $this->_errorNumber(), 'Cannot use the database ' . $database);
$this->_error('Cannot use the database "' . $database . '"');
}
}
diff --git a/docs/UnitTest/AllTests.php b/docs/UnitTest/AllTests.php
index 9444f56..6bb6bb0 100644
--- a/docs/UnitTest/AllTests.php
+++ b/docs/UnitTest/AllTests.php
@@ -37,6 +37,9 @@ class AllTests
require_once 'XmlTest.php';
$suite->addTestSuite('XmlTest');
+ require_once 'DatabaseTests.php';
+ $suite->addTestSuite(DatabaseTests::suite());
+
return $suite;
}
}
diff --git a/docs/UnitTest/DatabaseMySQLTest.php b/docs/UnitTest/DatabaseMySQLTest.php
new file mode 100644
index 0000000..0825de6
--- /dev/null
+++ b/docs/UnitTest/DatabaseMySQLTest.php
@@ -0,0 +1,43 @@
+fixture = BSRegister::LoadModule('DbMySql');
+ $this->fixture->connect(TEST_DB_MYSQL_HOST, TEST_DB_MYSQL_USER, TEST_DB_MYSQL_PASSWORD, TEST_DB_MYSQL_DATABASE);
+ $this->fixture->query("
+ CREATE TABLE test
+ (
+ id int auto_increment,
+ textstuff varchar(255),
+ PRIMARY KEY (id)
+ )
+ ");
+ }
+
+ public function tearDown()
+ {
+ $this->fixture->query("DROP TABLE test");
+ $this->fixture = null;
+ }
+
+ public function testConnect()
+ {
+ try
+ {
+ BSRegister::LoadModule('DbMySql')->connect('localhost', '--invalid user--', '--invalid password--', '--nodatabase--');
+ $this->fail('exception expected');
+ }
+ catch (BSDbException $e)
+ {}
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/docs/UnitTest/DatabaseMySQLiTest.php b/docs/UnitTest/DatabaseMySQLiTest.php
new file mode 100644
index 0000000..86e2513
--- /dev/null
+++ b/docs/UnitTest/DatabaseMySQLiTest.php
@@ -0,0 +1,43 @@
+fixture = BSRegister::LoadModule('DbMySqlI');
+ $this->fixture->connect(TEST_DB_MYSQL_HOST, TEST_DB_MYSQL_USER, TEST_DB_MYSQL_PASSWORD, TEST_DB_MYSQL_DATABASE);
+ $this->fixture->query("
+ CREATE TABLE test
+ (
+ id int auto_increment,
+ textstuff varchar(255),
+ PRIMARY KEY (id)
+ )
+ ");
+ }
+
+ public function tearDown()
+ {
+ $this->fixture->query("DROP TABLE test");
+ $this->fixture = null;
+ }
+
+ public function testConnect()
+ {
+ try
+ {
+ BSRegister::LoadModule('DbMySqlI')->connect('localhost', '--invalid user--', '--invalid password--', '--nodatabase--');
+ $this->fail('exception expected');
+ }
+ catch (BSDbException $e)
+ {}
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/docs/UnitTest/DatabaseTestAbstract.php b/docs/UnitTest/DatabaseTestAbstract.php
new file mode 100644
index 0000000..31f57a9
--- /dev/null
+++ b/docs/UnitTest/DatabaseTestAbstract.php
@@ -0,0 +1,167 @@
+fixture->query("INSERT INTO test (textstuff) VALUES ('moo'), ('foo'), ('hey'), ('foo'), ('boo'), ('poo')");
+ }
+ catch (BSDbException $e)
+ {
+ $this->fail('unexpected exception');
+ }
+
+ try
+ {
+ $res = $this->fixture->query("SELECT * FROM test WHERE textstuff = 'foo'");
+
+ $row = $this->fixture->fetchArray($res);
+ $this->assertNotNull($row['textstuff']);
+
+ $row = $this->fixture->fetchArray($res);
+ $this->assertNotNull($row['textstuff']);
+
+ $row = $this->fixture->fetchArray($res);
+ $this->assertNull($row['textstuff']);
+ }
+ catch (BSDbException $e)
+ {
+ $this->fail('unexpected exception');
+ }
+ }
+
+ public function testEscapeString()
+ {
+ $this->assertEquals("Robert\'s castle", $this->fixture->escapeString("Robert's castle"));
+ }
+
+ public function testFetchObject()
+ {
+ try
+ {
+ $this->fixture->query("INSERT INTO test (textstuff) VALUES ('foo')");
+ }
+ catch (BSDbException $e)
+ {
+ $this->fail('unexpected exception');
+ }
+
+ try
+ {
+ $res = $this->fixture->query("SELECT * FROM test");
+ $obj = $this->fixture->fetchObject($res);
+
+ $this->assertNotNull($obj);
+ $this->assertEquals('foo', $obj->textstuff);
+ }
+ catch (BSDbException $e)
+ {
+ $this->fail('unexpected exception');
+ }
+ }
+
+ public function testQueryFirst()
+ {
+ try
+ {
+ $this->fixture->query("INSERT INTO test (textstuff) VALUES ('abc'), ('123'), ('def')");
+ }
+ catch (BSDbException $e)
+ {
+ $this->fail('unexpected exception');
+ }
+
+ try
+ {
+ $res = $this->fixture->queryFirst("SELECT * FROM test ORDER BY id DESC");
+ $this->assertEquals('def', $res['textstuff']);
+ }
+ catch (BSDbException $e)
+ {
+ $this->fail('unexpected exception');
+ }
+ }
+
+ public function testInsertId()
+ {
+ try
+ {
+ $this->fixture->query("INSERT INTO test (textstuff) VALUES ('abc')");
+ $this->assertEquals(1, $this->fixture->insertId('test', 'textstuff'));
+
+ $this->fixture->query("INSERT INTO test (textstuff) VALUES ('123')");
+ $this->assertEquals(2, $this->fixture->insertId('test', 'textstuff'));
+ }
+ catch (BSDbException $e)
+ {
+ $this->fail('unexpected exception');
+ }
+ }
+
+ public function testNumRows()
+ {
+ try
+ {
+ $this->fixture->query("INSERT INTO test (textstuff) VALUES ('123'), ('456'), ('789')");
+
+ $res = $this->fixture->query("SELECT * FROM test");
+ $this->assertEquals(3, $this->fixture->numRows($res));
+
+ $res = $this->fixture->query("SELECT * FROM test WHERE textstuff = '--invalid value--'");
+ $this->assertEquals(0, $this->fixture->numRows($res));
+ }
+ catch (BSDbException $e)
+ {
+ $this->fail('unexpected exception');
+ }
+ }
+
+ public function testAffectedRows()
+ {
+ try
+ {
+ $this->fixture->query("INSERT INTO test (textstuff) VALUES ('123'), ('456'), ('123')");
+
+ $res = $this->fixture->query("UPDATE test SET textstuff = 'abc' WHERE textstuff = '123'");
+ $this->assertEquals(2, $this->fixture->affectedRows($res));
+
+ $res = $this->fixture->query("SELECT * FROM test WHERE textstuff = 'abc'");
+ $this->assertEquals(2, $this->fixture->numRows($res));
+ }
+ catch (BSDbException $e)
+ {
+ $this->fail('unexpected exception');
+ }
+ }
+
+ public function testInvalidQuery()
+ {
+ try
+ {
+ $this->fixture->query("SELECT * FROM foobar");
+ $this->fail('exception expected');
+ }
+ catch (BSDbException $e)
+ {
+ $this->assertEquals('SELECT * FROM foobar', $e->getQuery());
+ }
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/docs/UnitTest/DatabaseTests.php b/docs/UnitTest/DatabaseTests.php
new file mode 100644
index 0000000..c131e99
--- /dev/null
+++ b/docs/UnitTest/DatabaseTests.php
@@ -0,0 +1,40 @@
+addTestSuite('DatabaseMySQLTest');
+
+ require_once 'DatabaseMySQLiTest.php';
+ $suite->addTestSuite('DatabaseMySQLiTest');
+
+ return $suite;
+ }
+}
+
+if (PHPUnit_MAIN_METHOD == 'DatabaseTests')
+{
+ DatabaseTests::main();
+}
+
+?>
\ No newline at end of file
diff --git a/docs/UnitTest/tests.config.php.new b/docs/UnitTest/tests.config.php.new
index 9bdf099..f542215 100644
--- a/docs/UnitTest/tests.config.php.new
+++ b/docs/UnitTest/tests.config.php.new
@@ -22,6 +22,18 @@
// path to the directory that holds ISSO
define('TEST_PATH_TO_ISSO', '/usr/local/apache2/htdocs');
+// mysql database username
+define('TEST_DB_MYSQL_USER', 'mysql');
+
+// mysql database password
+define('TEST_DB_MYSQL_PASSWORD', 'foo');
+
+// mysql database hostname
+define('TEST_DB_MYSQL_HOST', 'localhost');
+
+// mysql database to use
+define('TEST_DB_MYSQL_DATABASE', 'issotest');
+
/*=====================================================================*
|| ###################################################################
|| # $HeadURL$
--
2.43.5