meli/tests: add test_cli_subcommands.rs

Add test to catch any failure of CLI subcommand.

Signed-off-by: Manos Pitsidianakis <manos@pitsidianak.is>
pull/430/head
Manos Pitsidianakis 2 months ago
parent 8dc4465c58
commit 9daf943758
No known key found for this signature in database
GPG Key ID: 7729C7707F7E09D0

106
Cargo.lock generated

@ -59,6 +59,27 @@ dependencies = [
"libc",
]
[[package]]
name = "anstyle"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b"
[[package]]
name = "assert_cmd"
version = "2.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed72493ac66d5804837f480ab3766c72bdfab91a65e565fc54fa9e42db0073a8"
dependencies = [
"anstyle",
"bstr",
"doc-comment",
"predicates",
"predicates-core",
"predicates-tree",
"wait-timeout",
]
[[package]]
name = "async-channel"
version = "1.9.0"
@ -269,6 +290,17 @@ dependencies = [
"log",
]
[[package]]
name = "bstr"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6798148dccfbff0fae41c7574d2fa8f1ef3492fba0face179de5d8d447d67b05"
dependencies = [
"memchr",
"regex-automata",
"serde",
]
[[package]]
name = "bufstream-fresh"
version = "0.3.1"
@ -516,6 +548,12 @@ version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946"
[[package]]
name = "difflib"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8"
[[package]]
name = "dirs-next"
version = "2.0.0"
@ -537,6 +575,12 @@ dependencies = [
"winapi",
]
[[package]]
name = "doc-comment"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
[[package]]
name = "either"
version = "1.9.0"
@ -698,6 +742,15 @@ dependencies = [
"miniz_oxide",
]
[[package]]
name = "float-cmp"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4"
dependencies = [
"num-traits",
]
[[package]]
name = "fnv"
version = "1.0.7"
@ -1251,6 +1304,7 @@ dependencies = [
name = "meli"
version = "0.8.6"
dependencies = [
"assert_cmd",
"async-task",
"bitflags 2.4.0",
"crossbeam",
@ -1264,6 +1318,7 @@ dependencies = [
"nix",
"notify-rust",
"pcre2",
"predicates",
"proc-macro2",
"quote",
"regex",
@ -1410,6 +1465,12 @@ dependencies = [
"minimal-lexical",
]
[[package]]
name = "normalize-line-endings"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be"
[[package]]
name = "notify"
version = "6.1.1"
@ -1634,6 +1695,36 @@ dependencies = [
"windows-sys 0.48.0",
]
[[package]]
name = "predicates"
version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68b87bfd4605926cdfefc1c3b5f8fe560e3feca9d5552cf68c466d3d8236c7e8"
dependencies = [
"anstyle",
"difflib",
"float-cmp",
"normalize-line-endings",
"predicates-core",
"regex",
]
[[package]]
name = "predicates-core"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b794032607612e7abeb4db69adb4e33590fa6cf1149e95fd7cb00e634b92f174"
[[package]]
name = "predicates-tree"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "368ba315fb8c5052ab692e68a0eefec6ec57b23a36959c14496f0b0df2c0cecf"
dependencies = [
"predicates-core",
"termtree",
]
[[package]]
name = "proc-macro-error"
version = "1.0.4"
@ -2176,6 +2267,12 @@ dependencies = [
"redox_termios",
]
[[package]]
name = "termtree"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76"
[[package]]
name = "ternop"
version = "1.0.1"
@ -2416,6 +2513,15 @@ version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "wait-timeout"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6"
dependencies = [
"libc",
]
[[package]]
name = "waker-fn"
version = "1.1.0"

@ -83,7 +83,9 @@ regex = "1"
syn = { version = "1", features = [] }
[dev-dependencies]
assert_cmd = { version = "2" }
flate2 = { version = "1" }
predicates = { version = "3" }
regex = "1"
tempfile = "3.3"

@ -0,0 +1,188 @@
//
// meli
//
// Copyright 2024 Emmanouil Pitsidianakis <manos@pitsidianak.is>
//
// This file is part of meli.
//
// meli is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// meli is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with meli. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: EUPL-1.2 OR GPL-3.0-or-later
use std::{io::Write, path::Path};
use assert_cmd::{assert::OutputAssertExt, Command};
use predicates::prelude::*;
use tempfile::TempDir;
#[test]
fn test_cli_subcommands() {
for var in [
"PAGER",
"MANPATH",
"EDITOR",
"MELI_CONFIG",
"HOME",
"XDG_CACHE_HOME",
"XDG_STATE_HOME",
"XDG_CONFIG_DIRS",
"XDG_CONFIG_HOME",
"XDG_DATA_DIRS",
"XDG_DATA_HOME",
] {
std::env::remove_var(var);
}
fn version() {
// --version is successful
for arg in ["--version", "-v"] {
let mut cmd = Command::cargo_bin("meli").unwrap();
let output = cmd.arg(arg).output().unwrap().assert();
output.code(0).stdout(predicates::str::starts_with("meli "));
}
}
fn help() {
// --help is successful
for arg in ["--help", "-h"] {
let mut cmd = Command::cargo_bin("meli").unwrap();
let output = cmd.arg(arg).output().unwrap().assert();
output
.code(0)
.stdout(predicates::str::contains("terminal mail client"))
.stdout(predicates::str::contains("USAGE"))
.stdout(predicates::str::contains("FLAGS"))
.stdout(predicates::str::contains("OPTIONS"))
.stdout(predicates::str::contains("SUBCOMMANDS"))
.stdout(predicates::str::contains("create-config"))
.stdout(predicates::str::contains("test-config"))
.stdout(predicates::str::contains("tools"))
.stdout(predicates::str::contains("man"))
.stdout(predicates::str::contains("install-man"))
.stdout(predicates::str::contains("compiled-with"))
.stdout(predicates::str::contains("edit-config"))
.stdout(predicates::str::contains("help"))
.stdout(predicates::str::contains("print-app-directories"))
.stdout(predicates::str::contains("print-config-path"))
.stdout(predicates::str::contains("print-default-theme"))
.stdout(predicates::str::contains("print-loaded-themes"))
.stdout(predicates::str::contains("print-log-path"))
.stdout(predicates::str::contains("view"));
}
}
fn test_subcommand_succeeds(arg: &str) {
let mut cmd = Command::cargo_bin("meli").unwrap();
let output = cmd.arg(arg).output().unwrap().assert();
output.code(0).stdout(predicates::str::is_empty().not());
}
fn test_subcommand_succeeds_empty(arg: &str) {
let mut cmd = Command::cargo_bin("meli").unwrap();
let output = cmd.arg(arg).output().unwrap().assert();
output.code(0).stdout(predicates::str::is_empty());
}
fn test_subcommand_install_man(dir: &Path) {
let mut cmd = Command::cargo_bin("meli").unwrap();
let output = cmd.arg("install-man").arg(dir).output().unwrap().assert();
output.code(0).stdout(predicates::str::is_empty().not());
let mut path = dir.to_path_buf();
for (man, dir) in [
("meli.1", "man1"),
("meli.conf.5", "man5"),
("meli-themes.5", "man5"),
("meli.7", "man7"),
] {
path.push(dir);
assert!(path.is_dir());
path.push(man);
assert!(path.is_file());
path.pop();
path.pop();
}
}
version();
help();
test_subcommand_succeeds("help");
test_subcommand_succeeds("compiled-with");
test_subcommand_succeeds("man");
let tmp_dir = TempDir::new().unwrap();
test_subcommand_install_man(tmp_dir.path());
fn config_not_exists(conf: &Path) {
let mut cmd = Command::cargo_bin("meli").unwrap();
let output = cmd.arg("-c").arg(conf).output().unwrap().assert();
output
.code(1)
.stderr(predicate::eq(
"Edit the sample configuration and relaunch meli.\nKind: Configuration\n",
))
.stdout(
predicate::eq(
format!(
"No configuration found. Would you like to generate one in {path}? [Y/n] \
Written example configuration to {path}",
path = conf.display()
)
.as_str(),
)
.trim()
.normalize(),
);
}
let conf_path = tmp_dir.path().join("conf.toml");
config_not_exists(&conf_path);
assert!(conf_path.exists());
assert!(conf_path.is_file());
{
let mut conf_file = std::fs::OpenOptions::new()
.append(true)
.create(false)
.open(&conf_path)
.unwrap();
conf_file
.write_all(
br#"
[accounts.imap]
root_mailbox = "INBOX"
format = "imap"
identity="username@example.com"
server_username = "null"
server_hostname = "example.com"
server_password_command = "false"
[composing]
send_mail = 'false'
"#,
)
.unwrap();
}
std::env::set_var("MELI_CONFIG", &conf_path);
test_subcommand_succeeds_empty("test-config");
test_subcommand_succeeds("print-app-directories");
test_subcommand_succeeds("print-config-path");
test_subcommand_succeeds("print-default-theme");
test_subcommand_succeeds("print-loaded-themes");
test_subcommand_succeeds("print-log-path");
tmp_dir.close().unwrap();
}
Loading…
Cancel
Save