/**
 * Copyright (C) 2014 Kasper Kronborg Isager.
 */
package dk.itu.donkey;

// General utilities
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

// SQL utilities
import java.sql.Connection;
import java.sql.SQLException;

// JUnit assertions
import static org.junit.Assert.assertEquals;

// JUnit annotations
import org.junit.After;
import org.junit.Test;

/**
 * Database class unit tests.
 *
 * @version 1.0.0
 */
public final class DatabaseTest {
  /**
   * List of databases to test aginst.
   */
  private List<Database> databases = new ArrayList<>();

  /**
   * Run after each test.
   *
   * @throws SQLException In case of a SQL error.
   */
  @After
  public void after() throws SQLException {
    for (Database db: this.databases) {
      db.execute("drop table if exists test");
    }
  }

  /**
   * Test initialization of databases.
   *
   * @throws SQLException In case of a SQL error.
   */
  @Test
  public void testInitialization() throws SQLException {
    // Configure MySQL database.
    Properties mysqlConf = new Properties();
    mysqlConf.put("database", "test");
    mysqlConf.put("user", "travis");

    // Initialize MySQL database.
    this.databases.add(new Database(Driver.MYSQL, mysqlConf));

    // Configure PostgreSQL database.
    Properties postgresqlConf = new Properties();
    postgresqlConf.put("database", "test");
    postgresqlConf.put("user", "postgres");

    // Initialize PostgreSQL database.
    this.databases.add(new Database(Driver.POSTGRESQL, postgresqlConf));

    // Configure SQLite database.
    Properties sqliteConf = new Properties();
    sqliteConf.put("database", "test");

    // Initialize SQLite database.
    this.databases.add(new Database(Driver.SQLITE, sqliteConf));
  }

  /**
   * Test initialization of PostgreSQL database with empty properties.
   *
   * This should throw an exception as a PostgreSQL database cannot be
   * intialized without a database name.
   *
   * @throws SQLException In case of a SQL error.
   */
  @Test(expected = IllegalArgumentException.class)
  public void testPostgresqlWithEmptyProperties() throws SQLException {
    (new Database(Driver.POSTGRESQL, new Properties())).connect();
  }

  /**
   * Test initialization of MySQL database with empty properties.
   *
   * This should throw an exception as a MySQL database cannot be intialized
   * without a database name.
   *
   * @throws SQLException In case of a SQL error.
   */
  @Test(expected = IllegalArgumentException.class)
  public void testMysqlWithEmptyProperties() throws SQLException {
    (new Database(Driver.MYSQL, new Properties())).connect();
  }

  /**
   * Test initialization of SQLite database with empty properties.
   *
   * This should throw an exception as a SQLite database cannot be intialized
   * without a database name.
   *
   * @throws SQLException In case of a SQL error.
   */
  @Test(expected = IllegalArgumentException.class)
  public void testSqliteWithEmptyProperties() throws SQLException {
    (new Database(Driver.SQLITE, new Properties())).connect();
  }

  /**
   * Test the connection of each database.
   *
   * @throws SQLException In case of a SQL error.
   */
  @Test
  public void testConnection() throws SQLException {
    for (Database db: this.databases) {
      Connection connection = db.connect();
    }
  }

  /**
   * Test SQL query execution of each database.
   *
   * @throws SQLException In case of a SQL error.
   */
  @Test
  public void testQueryExecution() throws SQLException {
    for (Database db: this.databases) {
      // Test table creation.
      db.execute("create table test (test varchar(255))");

      List<Object> values1 = new ArrayList<>();
      values1.add("test");

      // Test row insertion.
      db.execute("insert into test (test) values (?)", values1);
      List<Row> res1 = db.execute("select test from test");
      assertEquals(1, res1.size());
      assertEquals("test", res1.get(0).get("test"));

      List<Object> values2 = new ArrayList<>();
      values2.add("tset");
      values2.add("test");

      // Test updating.
      db.execute("update test set test = ? where test = ?");
      List<Row> res2 = db.execute("select test from test", values2);
      assertEquals(1, res2.size());
      assertEquals("tset", res2.get(0).get("test"));

      List<Object> values3 = new ArrayList<>();
      values3.add("tset");

      // Test row deletion.
      db.execute("delete from person where test = ?", values3);
      List<Row> res3 = db.execute("select test from test");
      assertEquals(0, res3.size());

      // Test table deletion.
      db.execute("drop table test");
    }
  }
}

@@ -360,16 +360,41 @@
 .After;%0A
+import org.junit.Before;%0A
 import o
@@ -591,61 +591,66 @@
 ases
- = new ArrayList%3C%3E();%0A%0A  /**%0A   * Run after each t
+;%0A%0A  /**%0A   * Initialize a list of all available databas
 es
-t
 .%0A  
@@ -662,147 +662,104 @@
  * @
-throws SQLException In case of a SQL error.%0A   */%0A  @After%0A  public void after() throws SQLException %7B%0A    for (Database db: this.d
+return A list of initialized databases.%0A   */%0A  public static List%3CDatabase%3E initializeD
 atabases
 ) %7B%0A
@@ -754,24 +754,25 @@
 atabases
+(
 ) %7B%0A    
   db.exe
@@ -767,232 +767,54 @@
     
-  db.execute(%22drop table if exists test%22);%0A    %7D%0A  %7D%0A%0A  /**%0A   * Test initialization of databases.%0A   *%0A   * @throws SQLException In case of a SQL error.%0A   */%0A  @Test%0A  public void testInitialization() throws SQLException %7B
+List%3CDatabase%3E databases = new ArrayList%3C%3E();%0A
 %0A   
@@ -995,37 +995,32 @@
 L database.%0A    
-this.
 databases.add(ne
@@ -1270,37 +1270,32 @@
 L database.%0A    
-this.
 databases.add(ne
@@ -1503,21 +1503,16 @@
 se.%0A    
-this.
 database
@@ -1558,16 +1558,455 @@
 eConf));
+%0A%0A    return databases;%0A  %7D%0A%0A  /**%0A   * Initialize databases before each test.%0A   */%0A  @Before%0A  public void testInitialization() %7B%0A    this.databases = this.initializeDatabases();%0A  %7D%0A%0A  /**%0A   * Clean up databases after each test.%0A   *%0A   * @throws SQLException In case of a SQL error.%0A   */%0A  @After%0A  public void after() throws SQLException %7B%0A    for (Database db: this.databases) %7B%0A      db.execute(%22drop table if exists test%22);%0A    %7D
 %0A  %7D%0A%0A  
@@ -4398,16 +4398,25 @@
 est = ?%22
+, values2
 );%0A     
@@ -4467,25 +4467,16 @@
 om test%22
-, values2
 );%0A     
@@ -4698,14 +4698,12 @@
 rom 
-person
+test
  whe

Fix database tests.