- 移除 config 命令中未使用的 List 子命令及相关显示字段 - 统一 ChangelogCommand 和 CommitCommand 的 ContentGenerator 初始化方式
418 lines
11 KiB
Rust
418 lines
11 KiB
Rust
use assert_cmd::cargo::cargo_bin_cmd;
|
|
use predicates::prelude::*;
|
|
use std::fs;
|
|
use std::path::PathBuf;
|
|
use tempfile::TempDir;
|
|
|
|
fn init_quicommit(config_path: &PathBuf) {
|
|
let mut cmd = cargo_bin_cmd!("quicommit");
|
|
cmd.args(&["init", "--yes", "--config", config_path.to_str().unwrap()]);
|
|
cmd.assert().success();
|
|
}
|
|
|
|
mod config_export {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_export_to_stdout() {
|
|
let temp_dir = TempDir::new().unwrap();
|
|
let config_path = temp_dir.path().join("config.toml");
|
|
init_quicommit(&config_path);
|
|
|
|
let mut cmd = cargo_bin_cmd!("quicommit");
|
|
cmd.args(&[
|
|
"config",
|
|
"export",
|
|
"--config",
|
|
config_path.to_str().unwrap(),
|
|
]);
|
|
|
|
cmd.assert()
|
|
.success()
|
|
.stdout(predicate::str::contains("version"))
|
|
.stdout(predicate::str::contains("[llm]"));
|
|
}
|
|
|
|
#[test]
|
|
fn test_export_to_file() {
|
|
let temp_dir = TempDir::new().unwrap();
|
|
let config_path = temp_dir.path().join("config.toml");
|
|
let export_path = temp_dir.path().join("exported.toml");
|
|
init_quicommit(&config_path);
|
|
|
|
let mut cmd = cargo_bin_cmd!("quicommit");
|
|
cmd.args(&[
|
|
"config",
|
|
"export",
|
|
"--config",
|
|
config_path.to_str().unwrap(),
|
|
"--output",
|
|
export_path.to_str().unwrap(),
|
|
"--password",
|
|
"",
|
|
]);
|
|
|
|
cmd.assert()
|
|
.success()
|
|
.stdout(predicate::str::contains("Configuration exported"));
|
|
|
|
assert!(export_path.exists(), "Export file should be created");
|
|
|
|
let content = fs::read_to_string(&export_path).unwrap();
|
|
assert!(content.contains("version"), "Export should contain version");
|
|
assert!(
|
|
content.contains("[llm]"),
|
|
"Export should contain LLM config"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_export_encrypted() {
|
|
let temp_dir = TempDir::new().unwrap();
|
|
let config_path = temp_dir.path().join("config.toml");
|
|
let export_path = temp_dir.path().join("encrypted.toml");
|
|
init_quicommit(&config_path);
|
|
|
|
let mut cmd = cargo_bin_cmd!("quicommit");
|
|
cmd.args(&[
|
|
"config",
|
|
"export",
|
|
"--config",
|
|
config_path.to_str().unwrap(),
|
|
"--output",
|
|
export_path.to_str().unwrap(),
|
|
"--password",
|
|
"test_password_123",
|
|
]);
|
|
|
|
cmd.assert()
|
|
.success()
|
|
.stdout(predicate::str::contains("encrypted and exported"));
|
|
|
|
assert!(export_path.exists(), "Export file should be created");
|
|
|
|
let content = fs::read_to_string(&export_path).unwrap();
|
|
assert!(
|
|
content.starts_with("ENCRYPTED:"),
|
|
"Encrypted file should start with ENCRYPTED:"
|
|
);
|
|
assert!(
|
|
!content.contains("[llm]"),
|
|
"Encrypted content should not be readable"
|
|
);
|
|
}
|
|
}
|
|
|
|
mod config_import {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_import_plain_config() {
|
|
let temp_dir = TempDir::new().unwrap();
|
|
let config_path = temp_dir.path().join("config.toml");
|
|
let import_path = temp_dir.path().join("import.toml");
|
|
|
|
let plain_config = r#"
|
|
version = "1"
|
|
|
|
[llm]
|
|
provider = "openai"
|
|
model = "gpt-4"
|
|
max_tokens = 1000
|
|
temperature = 0.7
|
|
timeout = 60
|
|
api_key_storage = "keyring"
|
|
|
|
[commit]
|
|
format = "conventional"
|
|
auto_generate = true
|
|
|
|
[tag]
|
|
version_prefix = "v"
|
|
auto_generate = true
|
|
|
|
[changelog]
|
|
path = "CHANGELOG.md"
|
|
auto_generate = true
|
|
|
|
[language]
|
|
output_language = "en"
|
|
keep_types_english = true
|
|
keep_changelog_types_english = true
|
|
"#;
|
|
fs::write(&import_path, plain_config).unwrap();
|
|
|
|
let mut cmd = cargo_bin_cmd!("quicommit");
|
|
cmd.args(&[
|
|
"config",
|
|
"import",
|
|
"--config",
|
|
config_path.to_str().unwrap(),
|
|
"--file",
|
|
import_path.to_str().unwrap(),
|
|
]);
|
|
|
|
cmd.assert()
|
|
.success()
|
|
.stdout(predicate::str::contains("Configuration imported"));
|
|
|
|
let mut cmd = cargo_bin_cmd!("quicommit");
|
|
cmd.args(&[
|
|
"config",
|
|
"get",
|
|
"llm.provider",
|
|
"--config",
|
|
config_path.to_str().unwrap(),
|
|
]);
|
|
cmd.assert()
|
|
.success()
|
|
.stdout(predicate::str::contains("openai"));
|
|
}
|
|
|
|
#[test]
|
|
fn test_import_encrypted_config() {
|
|
let temp_dir = TempDir::new().unwrap();
|
|
let config_path1 = temp_dir.path().join("config1.toml");
|
|
let config_path2 = temp_dir.path().join("config2.toml");
|
|
let export_path = temp_dir.path().join("encrypted.toml");
|
|
|
|
init_quicommit(&config_path1);
|
|
|
|
let mut cmd = cargo_bin_cmd!("quicommit");
|
|
cmd.args(&[
|
|
"config",
|
|
"set",
|
|
"llm.provider",
|
|
"anthropic",
|
|
"--config",
|
|
config_path1.to_str().unwrap(),
|
|
]);
|
|
cmd.assert().success();
|
|
|
|
let mut cmd = cargo_bin_cmd!("quicommit");
|
|
cmd.args(&[
|
|
"config",
|
|
"export",
|
|
"--config",
|
|
config_path1.to_str().unwrap(),
|
|
"--output",
|
|
export_path.to_str().unwrap(),
|
|
"--password",
|
|
"secure_password",
|
|
]);
|
|
cmd.assert().success();
|
|
|
|
let mut cmd = cargo_bin_cmd!("quicommit");
|
|
cmd.args(&[
|
|
"config",
|
|
"import",
|
|
"--config",
|
|
config_path2.to_str().unwrap(),
|
|
"--file",
|
|
export_path.to_str().unwrap(),
|
|
"--password",
|
|
"secure_password",
|
|
]);
|
|
cmd.assert()
|
|
.success()
|
|
.stdout(predicate::str::contains("Configuration imported"));
|
|
|
|
let mut cmd = cargo_bin_cmd!("quicommit");
|
|
cmd.args(&[
|
|
"config",
|
|
"get",
|
|
"llm.provider",
|
|
"--config",
|
|
config_path2.to_str().unwrap(),
|
|
]);
|
|
cmd.assert()
|
|
.success()
|
|
.stdout(predicate::str::contains("anthropic"));
|
|
}
|
|
|
|
#[test]
|
|
fn test_import_encrypted_wrong_password() {
|
|
let temp_dir = TempDir::new().unwrap();
|
|
let config_path = temp_dir.path().join("config.toml");
|
|
let export_path = temp_dir.path().join("encrypted.toml");
|
|
|
|
init_quicommit(&config_path);
|
|
|
|
let mut cmd = cargo_bin_cmd!("quicommit");
|
|
cmd.args(&[
|
|
"config",
|
|
"export",
|
|
"--config",
|
|
config_path.to_str().unwrap(),
|
|
"--output",
|
|
export_path.to_str().unwrap(),
|
|
"--password",
|
|
"correct_password",
|
|
]);
|
|
cmd.assert().success();
|
|
|
|
let mut cmd = cargo_bin_cmd!("quicommit");
|
|
cmd.args(&[
|
|
"config",
|
|
"import",
|
|
"--config",
|
|
config_path.to_str().unwrap(),
|
|
"--file",
|
|
export_path.to_str().unwrap(),
|
|
"--password",
|
|
"wrong_password",
|
|
]);
|
|
cmd.assert()
|
|
.failure()
|
|
.stderr(predicate::str::contains("Failed to decrypt"));
|
|
}
|
|
}
|
|
|
|
mod config_export_import_roundtrip {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_roundtrip_plain() {
|
|
let temp_dir = TempDir::new().unwrap();
|
|
let config_path1 = temp_dir.path().join("config1.toml");
|
|
let config_path2 = temp_dir.path().join("config2.toml");
|
|
let export_path = temp_dir.path().join("export.toml");
|
|
|
|
init_quicommit(&config_path1);
|
|
|
|
let mut cmd = cargo_bin_cmd!("quicommit");
|
|
cmd.args(&[
|
|
"config",
|
|
"set",
|
|
"llm.model",
|
|
"gpt-4-turbo",
|
|
"--config",
|
|
config_path1.to_str().unwrap(),
|
|
]);
|
|
cmd.assert().success();
|
|
|
|
let mut cmd = cargo_bin_cmd!("quicommit");
|
|
cmd.args(&[
|
|
"config",
|
|
"export",
|
|
"--config",
|
|
config_path1.to_str().unwrap(),
|
|
"--output",
|
|
export_path.to_str().unwrap(),
|
|
"--password",
|
|
"",
|
|
]);
|
|
cmd.assert().success();
|
|
|
|
let mut cmd = cargo_bin_cmd!("quicommit");
|
|
cmd.args(&[
|
|
"config",
|
|
"import",
|
|
"--config",
|
|
config_path2.to_str().unwrap(),
|
|
"--file",
|
|
export_path.to_str().unwrap(),
|
|
]);
|
|
cmd.assert().success();
|
|
|
|
let mut cmd = cargo_bin_cmd!("quicommit");
|
|
cmd.args(&[
|
|
"config",
|
|
"get",
|
|
"llm.model",
|
|
"--config",
|
|
config_path2.to_str().unwrap(),
|
|
]);
|
|
cmd.assert()
|
|
.success()
|
|
.stdout(predicate::str::contains("gpt-4-turbo"));
|
|
}
|
|
|
|
#[test]
|
|
fn test_roundtrip_encrypted() {
|
|
let temp_dir = TempDir::new().unwrap();
|
|
let config_path1 = temp_dir.path().join("config1.toml");
|
|
let config_path2 = temp_dir.path().join("config2.toml");
|
|
let export_path = temp_dir.path().join("encrypted.toml");
|
|
let password = "my_secure_password_123";
|
|
|
|
init_quicommit(&config_path1);
|
|
|
|
let mut cmd = cargo_bin_cmd!("quicommit");
|
|
cmd.args(&[
|
|
"config",
|
|
"set",
|
|
"llm.provider",
|
|
"deepseek",
|
|
"--config",
|
|
config_path1.to_str().unwrap(),
|
|
]);
|
|
cmd.assert().success();
|
|
|
|
let mut cmd = cargo_bin_cmd!("quicommit");
|
|
cmd.args(&[
|
|
"config",
|
|
"set",
|
|
"llm.model",
|
|
"deepseek-chat",
|
|
"--config",
|
|
config_path1.to_str().unwrap(),
|
|
]);
|
|
cmd.assert().success();
|
|
|
|
let mut cmd = cargo_bin_cmd!("quicommit");
|
|
cmd.args(&[
|
|
"config",
|
|
"export",
|
|
"--config",
|
|
config_path1.to_str().unwrap(),
|
|
"--output",
|
|
export_path.to_str().unwrap(),
|
|
"--password",
|
|
password,
|
|
]);
|
|
cmd.assert().success();
|
|
|
|
let exported_content = fs::read_to_string(&export_path).unwrap();
|
|
assert!(exported_content.starts_with("ENCRYPTED:"));
|
|
assert!(!exported_content.contains("deepseek"));
|
|
|
|
let mut cmd = cargo_bin_cmd!("quicommit");
|
|
cmd.args(&[
|
|
"config",
|
|
"import",
|
|
"--config",
|
|
config_path2.to_str().unwrap(),
|
|
"--file",
|
|
export_path.to_str().unwrap(),
|
|
"--password",
|
|
password,
|
|
]);
|
|
cmd.assert().success();
|
|
|
|
let mut cmd = cargo_bin_cmd!("quicommit");
|
|
cmd.args(&[
|
|
"config",
|
|
"get",
|
|
"llm.provider",
|
|
"--config",
|
|
config_path2.to_str().unwrap(),
|
|
]);
|
|
cmd.assert()
|
|
.success()
|
|
.stdout(predicate::str::contains("deepseek"));
|
|
|
|
let mut cmd = cargo_bin_cmd!("quicommit");
|
|
cmd.args(&[
|
|
"config",
|
|
"get",
|
|
"llm.model",
|
|
"--config",
|
|
config_path2.to_str().unwrap(),
|
|
]);
|
|
cmd.assert()
|
|
.success()
|
|
.stdout(predicate::str::contains("deepseek-chat"));
|
|
}
|
|
}
|