com.github.cchacin.cucumber.steps.DatabaseSteps.java Source code

Java tutorial

Introduction

Here is the source code for com.github.cchacin.cucumber.steps.DatabaseSteps.java

Source

/**
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package com.github.cchacin.cucumber.steps;

import static com.ninja_squad.dbsetup.Operations.deleteAllFrom;
import static com.ninja_squad.dbsetup.operation.CompositeOperation.sequenceOf;
import static org.assertj.core.api.Assertions.assertThat;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.jdbc.ScriptRunner;

import com.ninja_squad.dbsetup.DbSetup;
import com.ninja_squad.dbsetup.destination.Destination;
import com.ninja_squad.dbsetup.destination.DriverManagerDestination;
import com.ninja_squad.dbsetup.operation.Insert;
import com.ninja_squad.dbsetup.operation.Operation;

import cucumber.api.DataTable;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import gherkin.formatter.model.DataTableRow;

public class DatabaseSteps {

    private static final Properties properties = new Properties();

    static {
        try (InputStream resource = Thread.currentThread().getContextClassLoader()
                .getResourceAsStream("test-db.properties")) {
            properties.load(resource);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private final Destination destination = new DriverManagerDestination(properties.getProperty("database.url"),
            properties.getProperty("database.user"), properties.getProperty("database.password"));

    @Given("^I have the following rows in the \"(.*?)\" table:$")
    public void i_have_the_following_rows_in_the_table(final String tableName, final DataTable data)
            throws Throwable {
        this.insert(tableName, data);
    }

    @Given("^I have only the following rows in the \"([^\"]*)\" table:$")
    public void I_have_only_the_following_rows_in_the_table(final String tableName, final DataTable data)
            throws Throwable {
        this.deleteAll(tableName);
        this.insert(tableName, data);
    }

    void insert(final String tableName, final DataTable data) {
        final List<DataTableRow> rows = data.getGherkinRows();
        final List<String> columns = rows.get(0).getCells();

        final List<Operation> operations = new ArrayList<>();

        for (DataTableRow row : rows.subList(1, rows.size())) {
            final Insert.Builder builder = Insert.into(tableName);
            builder.columns(columns.toArray(new String[columns.size()]));
            builder.values(row.getCells().toArray(new String[row.getCells().size()]));
            operations.add(builder.build());
        }

        this.apply(sequenceOf(operations));
    }

    void deleteAll(final String tableName) {
        this.apply(deleteAllFrom(tableName));
    }

    void apply(final Operation operation) {
        new DbSetup(destination, operation).launch();
    }

    @Given("^I have the following sql script \"([^\"]*)\"$")
    public void I_have_the_following_sql_script(final String script) throws Throwable {
        new ScriptRunner(this.destination.getConnection()).runScript(new BufferedReader(
                new FileReader(Thread.currentThread().getContextClassLoader().getResource(script).getPath())));
    }

    @Then("^I should have the following rows in the \"([^\"]*)\" table:$")
    public void I_should_have_the_following_rows_in_the_table(final String tableName, final DataTable data)
            throws SQLException, ClassNotFoundException {
        exists(tableName, data);
    }

    void exists(final String tableName, final DataTable data) throws SQLException, ClassNotFoundException {
        final List<DataTableRow> rows = data.getGherkinRows();
        final List<String> columns = rows.get(0).getCells();
        final StringBuilder queryBuilder = new StringBuilder();
        queryBuilder.append(String.format("SELECT %s FROM %s WHERE ", StringUtils.join(columns, ","), tableName));
        queryBuilder.append(StringUtils.join(columns, " = ? AND "));
        queryBuilder.append(" = ?;");
        try (Connection conn = getConnection()) {
            PreparedStatement stmt = conn.prepareStatement(queryBuilder.toString());
            for (DataTableRow row : rows.subList(1, rows.size())) {
                List<String> rowValues = row.getCells();
                for (int i = 0; i < columns.size(); i++) {
                    stmt.setString(i + 1, rowValues.get(i));
                }
                final ResultSet rs = stmt.executeQuery();
                assertThat(rs.next()).isTrue();
            }
        }
    }

    private Connection getConnection() throws ClassNotFoundException, SQLException {
        Class.forName(properties.getProperty("database.driver"));
        return DriverManager.getConnection(properties.getProperty("database.url"),
                properties.getProperty("database.user"), properties.getProperty("database.password"));
    }
}