Skip to content

Commit

Permalink
Merge pull request #213 from mcasper/more_cli_integration_tests
Browse files Browse the repository at this point in the history
Add more CLI integration tests
  • Loading branch information
mcasper committed Feb 18, 2016
2 parents 775f0e5 + 0f4fa1e commit 9f0142c
Show file tree
Hide file tree
Showing 13 changed files with 401 additions and 13 deletions.
18 changes: 18 additions & 0 deletions diesel_cli/tests/database_drop.rs
@@ -0,0 +1,18 @@
use support::{database, project};

#[test]
fn database_drop_drops_database() {
let p = project("database_drop").build();
let db = database(&p.database_url()).create();

assert!(db.exists());

let result = p.command("database")
.arg("drop")
.run();

assert!(result.is_success(), "Result was unsuccessful {:?}", result);
assert!(result.stdout().contains("Dropping database:"),
"Unexpected stdout {}", result.stdout());
assert!(!db.exists());
}
45 changes: 45 additions & 0 deletions diesel_cli/tests/database_reset.rs
@@ -0,0 +1,45 @@
use support::{database, project};

#[test]
fn reset_drops_the_database() {
let p = project("reset_drops_the_database")
.folder("migrations")
.build();
let db = database(&p.database_url()).create();
db.execute("CREATE TABLE posts ( id INTEGER )");

assert!(db.table_exists("posts"));

let result = p.command("database")
.arg("reset")
.run();

assert!(result.is_success(), "Result was unsuccessful {:?}", result);
assert!(!db.table_exists("posts"));
}

#[test]
fn reset_runs_database_setup() {
let p = project("reset_runs_database_setup")
.folder("migrations")
.build();
let db = database(&p.database_url()).create();

db.execute("CREATE TABLE posts ( id INTEGER )");
db.execute("CREATE TABLE users ( id INTEGER )");
p.create_migration("12345_create_users_table",
"CREATE TABLE users ( id INTEGER )",
"DROP TABLE users");

assert!(db.table_exists("posts"));
assert!(db.table_exists("users"));

let result = p.command("database")
.arg("reset")
.run();

assert!(result.is_success(), "Result was unsuccessful {:?}", result);
assert!(!db.table_exists("posts"));
assert!(db.table_exists("users"));
assert!(db.table_exists("__diesel_schema_migrations"));
}
65 changes: 65 additions & 0 deletions diesel_cli/tests/database_setup.rs
@@ -0,0 +1,65 @@
use support::{database, project};

#[test]
fn database_setup_creates_database() {
let p = project("database_setup_creates_database")
.folder("migrations")
.build();

let db = database(&p.database_url());

// sanity check
assert!(!db.exists());

let result = p.command("database")
.arg("setup")
.run();

assert!(result.is_success(), "Result was unsuccessful {:?}", result);
assert!(result.stdout().contains("Creating database:"),
"Unexpected stdout {}", result.stdout());
assert!(db.exists());
}

#[test]
fn database_setup_creates_schema_table () {
let p = project("database_setup_creates_schema_table")
.folder("migrations")
.build();

let db = database(&p.database_url());

// sanity check
assert!(!db.exists());

let result = p.command("database")
.arg("setup")
.run();

assert!(result.is_success(), "Result was unsuccessful {:?}", result);
assert!(db.table_exists("__diesel_schema_migrations"));
}

#[test]
fn database_setup_runs_migrations_if_no_schema_table() {
let p = project("database_setup_runs_migrations_if_no_schema_table")
.folder("migrations")
.build();
let db = database(&p.database_url());

p.create_migration("12345_create_users_table",
"CREATE TABLE users ( id INTEGER )",
"DROP TABLE users");

// sanity check
assert!(!db.exists());

let result = p.command("database")
.arg("setup")
.run();

assert!(result.is_success(), "Result was unsuccessful {:?}", result);
assert!(result.stdout().contains("Running migration 12345"),
"Unexpected stdout {}", result.stdout());
assert!(db.table_exists("users"));
}
File renamed without changes.
27 changes: 27 additions & 0 deletions diesel_cli/tests/migration_redo.rs
@@ -0,0 +1,27 @@
use support::project;

#[test]
fn migration_redo_runs_the_last_migration_down_and_up() {
let p = project("migration_redo")
.folder("migrations")
.build();
p.create_migration("12345_create_users_table",
"CREATE TABLE users ( id INTEGER )",
"DROP TABLE users");

// Make sure the project is setup
p.command("setup").run();

let result = p.command("migration")
.arg("redo")
.run();

let expected_stdout = "\
Rolling back migration 12345
Running migration 12345
";

assert!(result.is_success(), "Result was unsuccessful {:?}", result);
assert!(result.stdout().contains(expected_stdout),
"Unexpected stdout {}", result.stdout());
}
27 changes: 27 additions & 0 deletions diesel_cli/tests/migration_revert.rs
@@ -0,0 +1,27 @@
use support::{database, project};

#[test]
fn migration_revert_runs_the_last_migration_down() {
let p = project("migration_revert")
.folder("migrations")
.build();
let db = database(&p.database_url());

p.create_migration("12345_create_users_table",
"CREATE TABLE users ( id INTEGER )",
"DROP TABLE users");

// Make sure the project is setup
p.command("setup").run();

assert!(db.table_exists("users"));

let result = p.command("migration")
.arg("revert")
.run();

assert!(result.is_success(), "Result was unsuccessful {:?}", result);
assert!(result.stdout().contains("Rolling back migration 12345"),
"Unexpected stdout {}", result.stdout());
assert!(!db.table_exists("users"));
}
27 changes: 27 additions & 0 deletions diesel_cli/tests/migration_run.rs
@@ -0,0 +1,27 @@
use support::{database, project};

#[test]
fn migration_run_runs_pending_migrations() {
let p = project("migration_run")
.folder("migrations")
.build();
let db = database(&p.database_url());

// Make sure the project is setup
p.command("setup").run();

p.create_migration("12345_create_users_table",
"CREATE TABLE users ( id INTEGER )",
"DROP TABLE users");

assert!(!db.table_exists("users"));

let result = p.command("migration")
.arg("run")
.run();

assert!(result.is_success(), "Result was unsuccessful {:?}", result);
assert!(result.stdout().contains("Running migration 12345"),
"Unexpected stdout {}", result.stdout());
assert!(db.table_exists("users"));
}
57 changes: 45 additions & 12 deletions diesel_cli/tests/setup.rs
@@ -1,29 +1,62 @@
use support::project;
use support::{database, project};

#[test]
fn setup_creates_database() {
let p = project("setup_creates_database").build();
let db = database(&p.database_url());

// sanity check
assert!(!database_exists(&p.database_url()));
assert!(!db.exists());

let result = p.command("setup").run();

assert!(result.is_success(), "Result was unsuccessful {:?}", result);
assert!(result.stdout().contains("Creating database:"),
"Unexpected stdout {}", result.stdout());
assert!(database_exists(&p.database_url()));
assert!(db.exists());
}

#[cfg(feature = "postgres")]
fn database_exists(url: &str) -> bool {
use diesel::pg::PgConnection;
use diesel::prelude::*;
PgConnection::establish(url).is_ok()
#[test]
fn setup_creates_migrations_directory() {
let p = project("setup_creates_migrations_directory").build();

// make sure the project builder doesn't create it for us
assert!(!p.has_file("migrations"));

let result = p.command("setup").run();

assert!(result.is_success(), "Result was unsuccessful {:?}", result);
assert!(p.has_file("migrations"));
}

#[cfg(feature = "sqlite")]
fn database_exists(url: &str) -> bool {
use std::path::Path;
Path::new(url).exists()
#[test]
fn setup_creates_schema_table() {
let p = project("setup_creates_schema_table").build();
let db = database(&p.database_url());
let result = p.command("setup").run();

assert!(result.is_success(), "Result was unsuccessful {:?}", result);
assert!(db.table_exists("__diesel_schema_migrations"));
}

#[test]
fn setup_runs_migrations_if_no_schema_table() {
let p = project("setup_runs_migrations_if_no_schema_table")
.folder("migrations")
.build();
let db = database(&p.database_url());

p.create_migration("12345_create_users_table",
"CREATE TABLE users ( id INTEGER )",
"DROP TABLE users");

// sanity check
assert!(!db.exists());

let result = p.command("setup").run();

assert!(result.is_success(), "Result was unsuccessful {:?}", result);
assert!(result.stdout().contains("Running migration 12345"),
"Unexpected stdout {}", result.stdout());
assert!(db.table_exists("users"));
}
12 changes: 12 additions & 0 deletions diesel_cli/tests/support/mod.rs
@@ -1,4 +1,16 @@
mod command;
mod project_builder;

#[cfg(feature = "sqlite")]
#[path="sqlite_database.rs"]
pub mod database;

#[cfg(feature = "postgres")]
#[path="postgres_database.rs"]
pub mod database;

pub use self::project_builder::project;

pub fn database(url: &str) -> database::Database {
database::Database::new(url)
}
62 changes: 62 additions & 0 deletions diesel_cli/tests/support/postgres_database.rs
@@ -0,0 +1,62 @@
use diesel::expression::sql;
use diesel::pg::PgConnection;
use diesel::types::Bool;
use diesel::{Connection, select, LoadDsl};

pub struct Database {
url: String
}

impl Database {
pub fn new(url: &str) -> Self {
Database {
url: url.into()
}
}

pub fn create(self) -> Self {
let (database, postgres_url) = self.split_url();
let conn = PgConnection::establish(&postgres_url).unwrap();
conn.execute(&format!("CREATE DATABASE {}", database)).unwrap();
self
}

pub fn exists(&self) -> bool {
PgConnection::establish(&self.url).is_ok()
}

pub fn table_exists(&self, table: &str) -> bool {
select(sql::<Bool>(&format!("EXISTS \
(SELECT 1 \
FROM information_schema.tables \
WHERE table_name = '{}')", table)))
.get_result(&self.conn()).unwrap()
}

pub fn conn(&self) -> PgConnection {
PgConnection::establish(&self.url)
.expect(&format!("Failed to open connection to {}", &self.url))
}

pub fn execute(&self, command: &str) {
self.conn().execute(command)
.expect(&format!("Error executing command {}", command));
}

fn split_url(&self) -> (String, String) {
let mut split: Vec<&str> = self.url.split("/").collect();
let database = split.pop().unwrap();
let postgres_url = split.join("/");
(database.into(), postgres_url)
}
}

impl Drop for Database {
fn drop(&mut self) {
let (database, postgres_url) = self.split_url();
let conn = PgConnection::establish(&postgres_url).unwrap();
conn.silence_notices(|| {
conn.execute(&format!("DROP DATABASE IF EXISTS {}", database)).unwrap();
});
}
}
12 changes: 12 additions & 0 deletions diesel_cli/tests/support/project_builder.rs
Expand Up @@ -82,6 +82,18 @@ impl Project {
pub fn has_file(&self, path: &str) -> bool {
self.directory.path().join(path).exists()
}

pub fn create_migration(&self, name: &str, up: &str, down: &str) {
use std::io::Write;
let migration_path = self.directory.path().join("migrations").join(name);
fs::create_dir(&migration_path)
.expect("Migrations folder must exist to create a migration");
let mut up_file = fs::File::create(&migration_path.join("up.sql")).unwrap();
up_file.write_all(up.as_bytes()).unwrap();

let mut down_file = fs::File::create(&migration_path.join("down.sql")).unwrap();
down_file.write_all(down.as_bytes()).unwrap();
}
}

#[cfg(feature = "postgres")]
Expand Down

0 comments on commit 9f0142c

Please sign in to comment.