summaryrefslogtreecommitdiff
path: root/tests/cli.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/cli.rs')
-rw-r--r--tests/cli.rs356
1 files changed, 356 insertions, 0 deletions
diff --git a/tests/cli.rs b/tests/cli.rs
new file mode 100644
index 0000000..0b99f8b
--- /dev/null
+++ b/tests/cli.rs
@@ -0,0 +1,356 @@
+//! Command-line interface integration test.
+
+use std::{
+ process::{Child, Stdio},
+ time::Duration,
+};
+
+use assert_cmd::{Command, prelude::*};
+use assert_fs::TempDir;
+use predicates::prelude::*;
+use testresult::TestResult;
+
+#[test]
+fn short_help() -> TestResult {
+ Command::cargo_bin("temp-postgres")?
+ .arg("-h")
+ .assert()
+ .success()
+ .stdout(predicate::str::contains("Usage"))
+ .stderr(predicate::str::is_empty());
+ Ok(())
+}
+
+#[test]
+fn long_help() -> TestResult {
+ Command::cargo_bin("temp-postgres")?
+ .arg("--help")
+ .assert()
+ .success()
+ .stdout(predicate::str::contains("Usage"))
+ .stderr(predicate::str::is_empty());
+ Ok(())
+}
+
+#[test]
+fn short_version() -> TestResult {
+ Command::cargo_bin("temp-postgres")?
+ .arg("-V")
+ .assert()
+ .success()
+ .stdout(predicate::str::is_match(
+ r#"^temp-postgres [0-9]+\.[0-9]+\.[0-9]+\n$"#,
+ )?)
+ .stderr(predicate::str::is_empty());
+ Ok(())
+}
+
+#[test]
+fn long_version() -> TestResult {
+ Command::cargo_bin("temp-postgres")?
+ .arg("--version")
+ .assert()
+ .success()
+ .stdout(predicate::str::is_match(
+ r#"^temp-postgres [0-9]+\.[0-9]+\.[0-9]+-[0-9a-f]{7}(-dirty)?\n$"#,
+ )?)
+ .stderr(predicate::str::is_empty());
+ Ok(())
+}
+
+#[test]
+fn wrapped_true() -> TestResult {
+ Command::cargo_bin("temp-postgres")?
+ .arg("--")
+ .arg("true")
+ .assert()
+ .success()
+ .stdout(predicate::str::is_empty())
+ .stderr(predicate::str::contains("PGHOST"));
+ Ok(())
+}
+
+#[test]
+fn wrapped_false() -> TestResult {
+ Command::cargo_bin("temp-postgres")?
+ .arg("--")
+ .arg("false")
+ .assert()
+ .failure()
+ .stdout(predicate::str::is_empty())
+ .stderr(predicate::str::contains("Wrapped command exited error"));
+ Ok(())
+}
+
+#[test]
+fn log_level_off() -> TestResult {
+ Command::cargo_bin("temp-postgres")?
+ .arg("--log-level")
+ .arg("off")
+ .arg("--")
+ .arg("true")
+ .assert()
+ .success()
+ .stdout(predicate::str::is_empty())
+ .stderr(predicate::str::is_empty());
+ Ok(())
+}
+
+#[test]
+fn no_such_flag() -> TestResult {
+ Command::cargo_bin("temp-postgres")?
+ .arg("--foo")
+ .assert()
+ .code(2)
+ .stdout(predicate::str::is_empty())
+ .stderr(predicate::str::contains("unexpected argument"));
+ Ok(())
+}
+
+#[test]
+fn unexpected_argument() -> TestResult {
+ Command::cargo_bin("temp-postgres")?
+ .arg("foo")
+ .assert()
+ .code(2)
+ .stdout(predicate::str::is_empty())
+ .stderr(predicate::str::contains("unexpected argument"));
+ Ok(())
+}
+
+#[test]
+fn missing_username_argument() -> TestResult {
+ Command::cargo_bin("temp-postgres")?
+ .arg("--username")
+ .assert()
+ .code(2)
+ .stdout(predicate::str::is_empty())
+ .stderr(predicate::str::contains("--username"));
+ Ok(())
+}
+
+#[test]
+fn empty_username_argument() -> TestResult {
+ Command::cargo_bin("temp-postgres")?
+ .arg("--username")
+ .arg("")
+ .assert()
+ .code(2)
+ .stdout(predicate::str::is_empty())
+ .stderr(predicate::str::contains("--username"));
+ Ok(())
+}
+
+#[test]
+fn symlink() -> TestResult {
+ let tmp_dir = TempDir::new()?;
+ let symlink = tmp_dir.join("db");
+ let child = std::process::Command::cargo_bin("temp-postgres")?
+ .arg("--username")
+ .arg("alex")
+ .arg("--dbname")
+ .arg("myproject")
+ .arg("--symlink")
+ .arg(&symlink)
+ .stdin(Stdio::null())
+ .stdout(Stdio::null())
+ .stderr(Stdio::null())
+ .spawn()?;
+ for i in (0..100).rev() {
+ std::thread::sleep(Duration::from_millis(200));
+ if symlink.exists() {
+ break;
+ } else if i > 0 {
+ continue;
+ } else {
+ panic!("symlink not created in time");
+ }
+ }
+ Command::new("psql")
+ .arg("--no-psqlrc")
+ .arg("--no-align")
+ .arg("--tuples-only")
+ .arg("--host")
+ .arg(&symlink)
+ .arg("--dbname")
+ .arg("myproject")
+ .arg("--username")
+ .arg("alex")
+ .write_stdin("SELECT current_database(), usename FROM pg_user;")
+ .assert()
+ .success()
+ .stdout(predicate::str::is_match(r#"^myproject|alex\n$"#)?)
+ .stderr(predicate::str::is_empty());
+ interrupt(&child);
+ child.wait_with_output()?.assert().code(130);
+ Ok(())
+}
+
+#[test]
+fn interrupted() -> TestResult {
+ let tmp_dir = TempDir::new()?;
+ let symlink = tmp_dir.join("db");
+ let child = std::process::Command::cargo_bin("temp-postgres")?
+ .arg("--symlink")
+ .arg(&symlink)
+ .stdin(Stdio::null())
+ .stdout(Stdio::null())
+ .stderr(Stdio::null())
+ .spawn()?;
+ for i in (0..100).rev() {
+ std::thread::sleep(Duration::from_millis(200));
+ if symlink.exists() {
+ break;
+ } else if i > 0 {
+ continue;
+ } else {
+ panic!("symlink not created in time");
+ }
+ }
+ interrupt(&child);
+ child.wait_with_output()?.assert().code(130);
+ Ok(())
+}
+
+#[test]
+fn interrupted_empty_command() -> TestResult {
+ let tmp_dir = TempDir::new()?;
+ let symlink = tmp_dir.join("db");
+ let child = std::process::Command::cargo_bin("temp-postgres")?
+ .arg("--symlink")
+ .arg(&symlink)
+ .arg("--")
+ .stdin(Stdio::null())
+ .stdout(Stdio::null())
+ .stderr(Stdio::null())
+ .spawn()?;
+ for i in (0..100).rev() {
+ std::thread::sleep(Duration::from_millis(200));
+ if symlink.exists() {
+ break;
+ } else if i > 0 {
+ continue;
+ } else {
+ panic!("symlink not created in time");
+ }
+ }
+ interrupt(&child);
+ child.wait_with_output()?.assert().code(130);
+ Ok(())
+}
+
+#[test]
+fn interrupted_sleep_command() -> TestResult {
+ let tmp_dir = TempDir::new()?;
+ let symlink = tmp_dir.join("db");
+ let child = std::process::Command::cargo_bin("temp-postgres")?
+ .arg("--symlink")
+ .arg(&symlink)
+ .arg("--")
+ .arg("sleep")
+ .arg("30")
+ .stdin(Stdio::null())
+ .stdout(Stdio::null())
+ .stderr(Stdio::null())
+ .spawn()?;
+ for i in (0..100).rev() {
+ std::thread::sleep(Duration::from_millis(200));
+ if symlink.exists() {
+ break;
+ } else if i > 0 {
+ continue;
+ } else {
+ panic!("symlink not created in time");
+ }
+ }
+ interrupt(&child);
+ child.wait_with_output()?.assert().code(130);
+ Ok(())
+}
+
+#[test]
+fn wrapped_cat() -> TestResult {
+ assert_cmd::Command::cargo_bin("temp-postgres")?
+ .arg("--")
+ .arg("cat")
+ .write_stdin("foo")
+ .assert()
+ .success()
+ .stdout(predicate::str::is_match(r#"^foo$"#)?)
+ .stderr(predicate::str::contains("PGHOST"));
+ Ok(())
+}
+
+#[test]
+fn wrapped_psql_with_username() -> TestResult {
+ assert_cmd::Command::cargo_bin("temp-postgres")?
+ .arg("--username")
+ .arg("alex")
+ .arg("--")
+ .arg("psql")
+ .arg("--no-psqlrc")
+ .arg("--no-align")
+ .arg("--tuples-only")
+ .write_stdin("SELECT current_database(), usename FROM pg_user;")
+ .assert()
+ .success()
+ .stdout(predicate::str::is_match(r#"^alex|alex\n$"#)?)
+ .stderr(predicate::str::contains("PGHOST"));
+ Ok(())
+}
+
+#[test]
+fn wrapped_psql_with_username_and_dbname() -> TestResult {
+ assert_cmd::Command::cargo_bin("temp-postgres")?
+ .arg("--username")
+ .arg("alex")
+ .arg("--dbname")
+ .arg("myproject")
+ .arg("--")
+ .arg("psql")
+ .arg("--no-psqlrc")
+ .arg("--no-align")
+ .arg("--tuples-only")
+ .write_stdin("SELECT current_database(), usename FROM pg_user;")
+ .assert()
+ .success()
+ .stdout(predicate::str::is_match(r#"^myproject|alex\n$"#)?)
+ .stderr(predicate::str::contains("PGHOST"));
+ Ok(())
+}
+
+#[test]
+fn wrapped_psql_with_database_url() -> TestResult {
+ assert_cmd::Command::cargo_bin("temp-postgres")?
+ .arg("--username")
+ .arg("alex")
+ .arg("--dbname")
+ .arg("myproject")
+ .arg("--")
+ .arg("env")
+ .arg("--unset")
+ .arg("PGHOST")
+ .arg("--unset")
+ .arg("PGDATABASE")
+ .arg("--unset")
+ .arg("PGUSER")
+ .arg("--")
+ .arg("bash")
+ .arg("-c")
+ .arg("psql --no-psqlrc --no-align --tuples-only \"$DATABASE_URL\"")
+ .write_stdin("SELECT current_database(), usename FROM pg_user;")
+ .assert()
+ .success()
+ .stdout(predicate::str::is_match(r#"^myproject|alex\n$"#)?)
+ .stderr(predicate::str::contains("PGHOST"));
+ Ok(())
+}
+
+fn interrupt(child: &Child) {
+ // std::os::unix::process::ChildExt::send_signal is nightly-only experimental
+ nix::sys::signal::kill(
+ nix::unistd::Pid::from_raw(child.id() as i32),
+ nix::sys::signal::Signal::SIGINT,
+ )
+ .unwrap();
+}
Generated by cgit. See skreutz.com for my tech blog and contact information.