use caesar_cipher_enc_dec::caesar_cipher::{
decrypt, decrypt_safe, encrypt, encrypt_safe, CipherError,
};
use caesar_cipher_enc_dec::config::{ALPHABET_SIZE, DEFAULT_SHIFT};
#[test]
fn test_decrypt_shift_i16_min_does_not_panic() {
let text = "ABC";
let shift = i16::MIN;
let result = decrypt(text, shift);
assert_eq!(result, "IJK");
}
#[test]
fn test_decrypt_shift_i16_min_plus_one() {
let text = "ABC";
let shift = i16::MIN + 1;
let result = decrypt(text, shift);
let expected = encrypt("ABC", 7);
assert_eq!(result, expected);
}
#[test]
fn test_decrypt_shift_i16_max() {
let text = "ABC";
let shift = i16::MAX;
let result = decrypt(text, shift);
let expected = encrypt("ABC", 19);
assert_eq!(result, expected);
}
#[test]
fn test_decrypt_shift_large_negative() {
let text = "Hello";
let shift = -30_000;
let result = decrypt(text, shift);
let expected = encrypt("Hello", 30_000);
assert_eq!(result, expected);
}
#[test]
fn test_decrypt_shift_alphabet_size_equivalence() {
let text = "Hello World";
let result = decrypt(text, ALPHABET_SIZE);
assert_eq!(result, text);
}
#[test]
fn test_decrypt_preserves_encrypt_roundtrip_with_extreme_shift() {
let original = "Hello World";
let shift = 10_000_i16;
let encrypted = encrypt(original, shift);
let decrypted = decrypt(&encrypted, shift);
assert_eq!(decrypted, original);
}
#[test]
fn test_cli_default_shift_matches_constant() {
use caesar_cipher_enc_dec::cli::{Cli, Commands};
use clap::Parser;
let cli = Cli::try_parse_from(["caesar_cipher", "encrypt", "--text", "Hello"])
.expect("parse should succeed");
match cli.command {
Commands::Encrypt(args) => assert_eq!(args.shift, DEFAULT_SHIFT),
_ => panic!("expected Encrypt subcommand"),
}
}
#[test]
fn test_cli_default_shift_applies_to_decrypt() {
use caesar_cipher_enc_dec::cli::{Cli, Commands};
use clap::Parser;
let cli = Cli::try_parse_from(["caesar_cipher", "decrypt", "--text", "Khoor"])
.expect("parse should succeed");
match cli.command {
Commands::Decrypt(args) => assert_eq!(args.shift, DEFAULT_SHIFT),
_ => panic!("expected Decrypt subcommand"),
}
}
#[test]
fn test_cli_explicit_shift_overrides_default() {
use caesar_cipher_enc_dec::cli::{Cli, Commands};
use clap::Parser;
let cli = Cli::try_parse_from(["caesar_cipher", "encrypt", "--text", "Hi", "--shift", "7"])
.expect("parse should succeed");
match cli.command {
Commands::Encrypt(args) => assert_eq!(args.shift, 7),
_ => panic!("expected Encrypt subcommand"),
}
}
#[test]
fn test_encrypt_safe_rejects_empty_string() {
let text = "";
let result = encrypt_safe(text, 3);
assert!(matches!(result, Err(CipherError::EmptyText)));
}
#[test]
fn test_encrypt_safe_rejects_spaces_only() {
let text = " ";
let result = encrypt_safe(text, 3);
assert!(matches!(result, Err(CipherError::EmptyText)));
}
#[test]
fn test_encrypt_safe_rejects_tabs_and_newlines() {
let text = "\t\n\r ";
let result = encrypt_safe(text, 3);
assert!(matches!(result, Err(CipherError::EmptyText)));
}
#[test]
fn test_decrypt_safe_rejects_whitespace_only() {
let text = " \t";
let result = decrypt_safe(text, 3);
assert!(matches!(result, Err(CipherError::EmptyText)));
}
#[test]
fn test_encrypt_safe_accepts_text_with_surrounding_whitespace() {
let text = " Hi ";
let result = encrypt_safe(text, 3);
let encrypted = result.expect("non-empty text should succeed");
assert_eq!(encrypted, " Kl ");
}
#[test]
fn test_empty_text_error_message_mentions_whitespace() {
let err = CipherError::EmptyText;
let msg = format!("{}", err);
assert!(
msg.contains("whitespace"),
"expected message to mention whitespace, got: {}",
msg
);
}