#![allow(non_upper_case_globals)]
use waddling_errors_hash::{HashConfig, compute_hash_with_config};
use waddling_errors_macros::{diag, setup};
pub mod components {
use waddling_errors_macros::component;
component! {
Auth {
docs: "Authentication component",
tags: ["test"],
},
Database {
docs: "Database component",
tags: ["test"],
},
}
}
pub mod primaries {
use waddling_errors_macros::primary;
primary! {
Token {
docs: "Token category",
},
Connection {
docs: "Connection category",
},
}
}
pub mod sequences {
use waddling_errors_macros::sequence;
sequence! {
TEST001(1) {
description: "Test sequence 001",
typical_severity: "Error",
},
TEST002(2) {
description: "Test sequence 002",
typical_severity: "Error",
},
TEST003(3) {
description: "Test sequence 003",
typical_severity: "Error",
},
TEST010(10) {
description: "Test sequence 010",
typical_severity: "Error",
},
TEST020(20) {
description: "Test sequence 020",
typical_severity: "Error",
},
TEST030(30) {
description: "Test sequence 030",
typical_severity: "Error",
},
}
}
setup! {
components = crate::components,
primaries = crate::primaries,
sequences = crate::sequences,
}
diag! {
E.AUTH.TOKEN.TEST001: {
message: "Test error with default hash",
fields: [],
'R role: "Public",
},
}
#[test]
fn test_default_hash_is_reproducible() {
let macro_hash = E_AUTH_TOKEN_TEST001_HASH;
let hash_bytes = waddling_errors_hash::const_wdp_hash_from_parts(
b'E', b"AUTH", b"TOKEN", 1, );
let manual_hash = std::str::from_utf8(&hash_bytes).unwrap();
println!("Macro hash: {}", macro_hash);
println!("Manual hash: {}", manual_hash);
assert_eq!(
macro_hash, manual_hash,
"WDP hash mismatch! Macro generated '{}' but manual computation gave '{}'",
macro_hash, manual_hash
);
}
#[test]
fn test_default_hash_explicit_config() {
let macro_hash = E_AUTH_TOKEN_TEST001_HASH;
let hash_bytes = waddling_errors_hash::const_wdp_hash_from_parts(
b'E', b"AUTH", b"TOKEN", 1, );
let manual_hash = std::str::from_utf8(&hash_bytes).unwrap();
println!("Macro hash: {}", macro_hash);
println!("Expected hash: {}", manual_hash);
assert_eq!(
macro_hash, manual_hash,
"Hash should match WDP-conformant computation"
);
}
#[test]
fn test_default_hash_format() {
let hash = E_AUTH_TOKEN_TEST001_HASH;
assert_eq!(
hash.len(),
5,
"Hash should be 5 characters, got {}",
hash.len()
);
assert!(
hash.chars().all(|c| c.is_ascii_alphanumeric()),
"Hash should be base62 alphanumeric, got '{}'",
hash
);
println!(
"Hash format valid: {} (length={}, base62=yes)",
hash,
hash.len()
);
}
diag! {
E.AUTH.TOKEN.TEST002: {
message: "Second test error",
fields: [],
'R role: "Public",
},
E.AUTH.TOKEN.TEST003: {
message: "Third test error",
fields: [],
'R role: "Developer",
},
}
#[test]
fn test_different_errors_different_hashes() {
let hash001 = E_AUTH_TOKEN_TEST001_HASH;
let hash002 = E_AUTH_TOKEN_TEST002_HASH;
let hash003 = E_AUTH_TOKEN_TEST003_HASH;
println!("E.AUTH.TOKEN.001: {}", hash001);
println!("E.AUTH.TOKEN.002: {}", hash002);
println!("E.AUTH.TOKEN.003: {}", hash003);
assert_ne!(
hash001, hash002,
"Different errors should have different hashes"
);
assert_ne!(
hash002, hash003,
"Different errors should have different hashes"
);
assert_ne!(
hash001, hash003,
"Different errors should have different hashes"
);
}
#[test]
fn test_different_errors_match_manual_computation() {
let hash001 = E_AUTH_TOKEN_TEST001_HASH;
let hash002 = E_AUTH_TOKEN_TEST002_HASH;
let hash003 = E_AUTH_TOKEN_TEST003_HASH;
let bytes001 = waddling_errors_hash::const_wdp_hash_from_parts(b'E', b"AUTH", b"TOKEN", 1);
let bytes002 = waddling_errors_hash::const_wdp_hash_from_parts(b'E', b"AUTH", b"TOKEN", 2);
let bytes003 = waddling_errors_hash::const_wdp_hash_from_parts(b'E', b"AUTH", b"TOKEN", 3);
let expected001 = std::str::from_utf8(&bytes001).unwrap();
let expected002 = std::str::from_utf8(&bytes002).unwrap();
let expected003 = std::str::from_utf8(&bytes003).unwrap();
assert_eq!(hash001, expected001, "Hash 001 mismatch");
assert_eq!(hash002, expected002, "Hash 002 mismatch");
assert_eq!(hash003, expected003, "Hash 003 mismatch");
}
diag! {
E.AUTH.TOKEN.TEST010: {
message: "Error severity test",
fields: [],
'R role: "Public",
},
}
diag! {
W.AUTH.TOKEN.TEST010: {
message: "Warning severity test",
fields: [],
'R role: "Public",
},
}
diag! {
C.AUTH.TOKEN.TEST010: {
message: "Critical severity test",
fields: [],
'R role: "Public",
},
}
#[test]
fn test_different_severities_different_hashes() {
let error_hash = E_AUTH_TOKEN_TEST010_HASH;
let warning_hash = W_AUTH_TOKEN_TEST010_HASH;
let critical_hash = C_AUTH_TOKEN_TEST010_HASH;
println!("Error hash: {}", error_hash);
println!("Warning hash: {}", warning_hash);
println!("Critical hash: {}", critical_hash);
assert_ne!(error_hash, warning_hash, "E vs W should differ");
assert_ne!(error_hash, critical_hash, "E vs C should differ");
assert_ne!(warning_hash, critical_hash, "W vs C should differ");
}
#[test]
fn test_severity_hashes_reproducible() {
let error_hash = E_AUTH_TOKEN_TEST010_HASH;
let warning_hash = W_AUTH_TOKEN_TEST010_HASH;
let bytes_error = waddling_errors_hash::const_wdp_hash_from_parts(b'E', b"AUTH", b"TOKEN", 10);
let bytes_warning =
waddling_errors_hash::const_wdp_hash_from_parts(b'W', b"AUTH", b"TOKEN", 10);
let expected_error = std::str::from_utf8(&bytes_error).unwrap();
let expected_warning = std::str::from_utf8(&bytes_warning).unwrap();
assert_eq!(
error_hash, expected_error,
"Error hash should be reproducible"
);
assert_eq!(
warning_hash, expected_warning,
"Warning hash should be reproducible"
);
}
diag! {
E.AUTH.TOKEN.TEST020: {
message: "Auth component test",
fields: [],
'R role: "Public",
},
}
diag! {
E.DATABASE.TOKEN.TEST020: {
message: "Database component test",
fields: [],
'R role: "Public",
},
}
#[test]
fn test_different_components_different_hashes() {
let auth_hash = E_AUTH_TOKEN_TEST020_HASH;
let db_hash = E_DATABASE_TOKEN_TEST020_HASH;
println!("AUTH component: {}", auth_hash);
println!("DATABASE component: {}", db_hash);
assert_ne!(
auth_hash, db_hash,
"Different components should have different hashes"
);
let bytes_auth = waddling_errors_hash::const_wdp_hash_from_parts(b'E', b"AUTH", b"TOKEN", 20);
let bytes_db = waddling_errors_hash::const_wdp_hash_from_parts(b'E', b"DATABASE", b"TOKEN", 20);
let expected_auth = std::str::from_utf8(&bytes_auth).unwrap();
let expected_db = std::str::from_utf8(&bytes_db).unwrap();
assert_eq!(auth_hash, expected_auth);
assert_eq!(db_hash, expected_db);
}
diag! {
E.AUTH.TOKEN.TEST030: {
message: "Token primary test",
fields: [],
'R role: "Public",
},
}
diag! {
E.AUTH.CONNECTION.TEST030: {
message: "Connection primary test",
fields: [],
'R role: "Public",
},
}
#[test]
fn test_different_primaries_different_hashes() {
let token_hash = E_AUTH_TOKEN_TEST030_HASH;
let conn_hash = E_AUTH_CONNECTION_TEST030_HASH;
println!("TOKEN primary: {}", token_hash);
println!("CONNECTION primary: {}", conn_hash);
assert_ne!(
token_hash, conn_hash,
"Different primaries should have different hashes"
);
let bytes_token = waddling_errors_hash::const_wdp_hash_from_parts(b'E', b"AUTH", b"TOKEN", 30);
let bytes_conn =
waddling_errors_hash::const_wdp_hash_from_parts(b'E', b"AUTH", b"CONNECTION", 30);
let expected_token = std::str::from_utf8(&bytes_token).unwrap();
let expected_conn = std::str::from_utf8(&bytes_conn).unwrap();
assert_eq!(token_hash, expected_token);
assert_eq!(conn_hash, expected_conn);
}
#[test]
fn test_xxhash3_produces_valid_hashes() {
let code = "E.AUTH.TOKEN.999";
let config = HashConfig::wdp_compliant();
let hash = compute_hash_with_config(code, &config);
println!("\nxxHash3 (WDP-mandated) produces valid 5-char base62 hash:");
assert_eq!(hash.len(), 5, "xxHash3 hash should be 5 chars");
assert!(
hash.chars().all(|c| c.is_ascii_alphanumeric()),
"xxHash3 hash should be base62"
);
println!(" xxHash3 → {}", hash);
}
#[test]
fn test_hash_determinism() {
let code = "E.AUTH.TOKEN.999";
let config = HashConfig::wdp_compliant();
let hash1 = compute_hash_with_config(code, &config);
let hash2 = compute_hash_with_config(code, &config);
let hash3 = compute_hash_with_config(code, &config);
println!("Hash 1: {}", hash1);
println!("Hash 2: {}", hash2);
println!("Hash 3: {}", hash3);
assert_eq!(hash1, hash2, "Hash should be deterministic");
assert_eq!(hash2, hash3, "Hash should be deterministic");
}
#[test]
fn test_different_seeds_different_hashes() {
let code = "E.AUTH.TOKEN.999";
let hash_seed1 = compute_hash_with_config(code, &HashConfig::new(1));
let hash_seed2 = compute_hash_with_config(code, &HashConfig::new(2));
let hash_seed3 = compute_hash_with_config(code, &HashConfig::new(3));
println!("Seed 1: {}", hash_seed1);
println!("Seed 2: {}", hash_seed2);
println!("Seed 3: {}", hash_seed3);
assert_ne!(hash_seed1, hash_seed2);
assert_ne!(hash_seed2, hash_seed3);
assert_ne!(hash_seed1, hash_seed3);
}
#[test]
fn summary_all_macro_hashes() {
println!("\n╔════════════════════════════════════════════════════════╗");
println!("║ Hash Verification Summary (Macro-Generated) ║");
println!("╚════════════════════════════════════════════════════════╝\n");
println!("WDP-conformant configuration (xxHash3 + WDP seed + normalization):");
println!(" E.AUTH.TOKEN.001: {}", E_AUTH_TOKEN_TEST001_HASH);
println!(" E.AUTH.TOKEN.002: {}", E_AUTH_TOKEN_TEST002_HASH);
println!(" E.AUTH.TOKEN.003: {}", E_AUTH_TOKEN_TEST003_HASH);
println!("\nDifferent severities (same component/primary/sequence):");
println!(" E.AUTH.TOKEN.010: {}", E_AUTH_TOKEN_TEST010_HASH);
println!(" W.AUTH.TOKEN.010: {}", W_AUTH_TOKEN_TEST010_HASH);
println!(" C.AUTH.TOKEN.010: {}", C_AUTH_TOKEN_TEST010_HASH);
println!("\nDifferent components:");
println!(" E.AUTH.TOKEN.020: {}", E_AUTH_TOKEN_TEST020_HASH);
println!(" E.DATABASE.TOKEN.020: {}", E_DATABASE_TOKEN_TEST020_HASH);
println!("\nDifferent primaries:");
println!(" E.AUTH.TOKEN.030: {}", E_AUTH_TOKEN_TEST030_HASH);
println!(
" E.AUTH.CONNECTION.030: {}",
E_AUTH_CONNECTION_TEST030_HASH
);
println!("\n✅ All hashes are 5-character base62 strings");
println!("✅ All hashes are deterministic and reproducible");
println!("✅ Manual computation matches macro-generated hashes\n");
}