Merge remote-tracking branch 'upstream/develop' into unit-tests
diff --git a/.travis.yml b/.travis.yml
index 29111bc..c6a4b5e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,10 +4,18 @@
   - 5.3
   - 5.4
 
+env:
+  - DB=mysql
+  - DB=pgsql
+  - DB=sqlite
+
 before_script:
   - pyrus channel-discover pear.php-tools.net
   - pyrus install http://pear.php-tools.net/get/vfsStream-0.11.2.tgz
   - phpenv rehash
+  - sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'DROP DATABASE IF EXISTS ci_test;' -U postgres; fi"
+  - sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'create database ci_test;' -U postgres; fi"
+  - sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'create database IF NOT EXISTS ci_test;'; fi"
 
 script: phpunit --configuration tests/phpunit.xml 
 
diff --git a/system/database/DB.php b/system/database/DB.php
index 96e4955..e943423 100755
--- a/system/database/DB.php
+++ b/system/database/DB.php
@@ -138,7 +138,12 @@
 		class CI_DB extends CI_DB_driver { }
 	}
 
-	require_once(BASEPATH.'database/drivers/'.$params['dbdriver'].'/'.$params['dbdriver'].'_driver.php');
+	// Load the DB driver
+	$driver_file = BASEPATH.'database/drivers/'.$params['dbdriver'].'/'.$params['dbdriver'].'_driver.php';
+
+	if ( ! file_exists($driver_file)) show_error('Invalid DB driver');
+
+	require_once($driver_file);
 
 	// Instantiate the DB adapter
 	$driver = 'CI_DB_'.$params['dbdriver'].'_driver';
diff --git a/tests/codeigniter/database/DB_test.php b/tests/codeigniter/database/DB_test.php
new file mode 100644
index 0000000..10e8dec
--- /dev/null
+++ b/tests/codeigniter/database/DB_test.php
@@ -0,0 +1,47 @@
+<?php
+
+class DB_test extends CI_TestCase {
+
+	// ------------------------------------------------------------------------
+
+	public function test_db_invalid()
+	{
+		$db_config = new Mock_Database_DB(array(
+			'undefined' => array(
+				'dsn' => '',
+				'hostname' => 'undefined',
+				'username' => 'undefined',
+				'password' => 'undefined',
+				'database' => 'undefined',
+				'dbdriver' => 'undefined',
+			),
+		));
+
+		$this->setExpectedException('InvalidArgumentException', 'CI Error: Invalid DB driver');
+
+		Mock_Database_DB::DB($db_config->set_dsn('undefined'), TRUE);
+	}
+
+	// ------------------------------------------------------------------------
+
+	public function test_db_valid()
+	{
+		$db_config = new Mock_Database_DB(array(
+			'mysql' => array(
+				'dsn' => '',
+				'hostname' => 'localhost',
+				'username' => 'travis',
+				'password' => '',
+				'database' => 'ci_test',
+				'dbdriver' => 'mysql',
+			),
+		));
+
+		$db = Mock_Database_DB::DB($db_config->set_dsn('mysql'), TRUE);
+
+		$this->assertTrue($db instanceof CI_DB);
+		$this->assertTrue($db instanceof CI_DB_Driver);
+		$this->assertTrue($db instanceof CI_DB_mysql_driver);
+	}
+	
+}
\ No newline at end of file
diff --git a/tests/codeigniter/database/.gitkeep b/tests/codeigniter/database/query_builder/.gitkeep
similarity index 100%
rename from tests/codeigniter/database/.gitkeep
rename to tests/codeigniter/database/query_builder/.gitkeep
diff --git a/tests/mocks/database/db.php b/tests/mocks/database/db.php
new file mode 100644
index 0000000..11e4a93
--- /dev/null
+++ b/tests/mocks/database/db.php
@@ -0,0 +1,72 @@
+<?php
+
+class Mock_Database_DB {
+
+	private $config = array();
+	
+	/**
+	 * Prepare database configuration skeleton
+	 *
+	 * @param  array 	DB configuration to set
+	 * @return void
+	 */
+	public function __construct($config = array())
+	{
+		$this->config = $config;
+	}
+
+	public function set_dsn($group = 'default')
+	{
+		if ( ! isset($this->config[$group]))
+		{
+			throw new InvalidArgumentException('Group '.$group.' not exists');
+		}
+
+		$params = array(
+			'dbprefix' => '',
+			'pconnect' => FALSE,
+			'db_debug' => TRUE,
+			'cache_on' => FALSE,
+			'cachedir' => '',
+			'char_set' => 'utf8',
+			'dbcollat' => 'utf8_general_ci',
+			'swap_pre' => '',
+			'autoinit' => TRUE,
+			'stricton' => FALSE,
+			'failover' => array()
+		);
+
+		$config = array_merge($this->config[$group], $params);
+
+		if ( ! empty($config['dsn']))
+		{
+			$dsn = $config['dsn'];
+		}
+		else
+		{
+			$dsn = $config['dbdriver'].'://'.$config['username'].':'.$config['password']
+			       .'@'.$config['hostname'].'/'.$config['database'];
+
+		}
+
+		$other_params = array_slice($config, 6);
+
+		return $dsn.http_build_query($other_params);
+	}
+
+	public static function DB($group, $query_builder = FALSE)
+	{
+		include_once(BASEPATH.'database/DB.php');
+
+		try 
+		{
+			$db = DB($group, $query_builder);
+		}
+		catch (Exception $e)
+		{
+			throw new InvalidArgumentException($e->getMessage());
+		}
+
+		return $db;
+	}
+}
\ No newline at end of file
diff --git a/tests/mocks/database/.gitkeep b/tests/mocks/database/models/.gitkeep
similarity index 100%
rename from tests/mocks/database/.gitkeep
rename to tests/mocks/database/models/.gitkeep
diff --git a/tests/phpunit.xml b/tests/phpunit.xml
index dfeecd1..ffd2a1f 100644
--- a/tests/phpunit.xml
+++ b/tests/phpunit.xml
@@ -15,10 +15,7 @@
 			<directory suffix="test.php">codeigniter/core</directory>
 			<directory suffix="test.php">codeigniter/helpers</directory>
 			<directory suffix="test.php">codeigniter/libraries</directory>
-			<!-- We'll worry about these later ...
-			<directory suffix="test.php">codeigniter/libraries</directory>
-			<directory suffix="test.php">codeigniter/helpers</directory>
-			-->
+			<directory suffix="test.php">codeigniter/database</directory>
 		</testsuite>
 	</testsuites>
 	<filters>