#[test]
fn test_model_source_display_hf() {
let source = ModelSource::HuggingFace {
org: "test".to_string(),
repo: "model".to_string(),
file: Some("model.gguf".to_string()),
};
let _debug = format!("{:?}", source);
}
#[test]
fn test_model_source_clone() {
let source = ModelSource::Url("https://example.com/model.apr".to_string());
let cloned = source.clone();
assert_eq!(source, cloned);
}
#[test]
fn test_run_options_custom() {
let options = RunOptions {
max_tokens: 100,
benchmark: true,
verbose: true,
..Default::default()
};
assert_eq!(options.max_tokens, 100);
assert!(options.benchmark);
}
#[test]
fn test_run_result_debug() {
let result = RunResult {
text: "Hello".to_string(),
duration_secs: 0.1,
cached: true,
tokens_generated: Some(5),
tok_per_sec: None,
used_gpu: None,
generated_tokens: None,
};
let _debug = format!("{:?}", result);
assert_eq!(result.tokens_generated, Some(5));
}
#[test]
fn test_extract_shard_files_empty_json() {
let json = "{}";
let files = extract_shard_files(json);
assert!(files.is_empty());
}
#[test]
fn test_extract_shard_files_invalid_json() {
let json = "not valid json";
let files = extract_shard_files(json);
assert!(files.is_empty());
}
#[test]
fn test_cache_path_url_contains_urls_dir() {
let source = ModelSource::Url("https://example.com/model.apr".to_string());
let cache = source.cache_path();
assert!(cache.to_string_lossy().contains("urls"));
}
#[test]
fn test_cache_path_hf_with_file() {
let source = ModelSource::HuggingFace {
org: "test".to_string(),
repo: "model".to_string(),
file: Some("model-q4.gguf".to_string()),
};
let cache = source.cache_path();
assert!(cache.to_string_lossy().contains("test"));
assert!(cache.to_string_lossy().contains("model"));
}
#[test]
fn test_find_model_in_dir_returns_dir_if_no_model() {
let result = find_model_in_dir(Path::new("/nonexistent/directory"));
assert!(result.is_ok());
assert_eq!(result.expect("value"), PathBuf::from("/nonexistent/directory"));
}
#[test]
fn test_glob_first_no_match() {
let result = glob_first(Path::new("/nonexistent/*.gguf"));
assert!(result.is_none());
}
#[test]
fn test_format_prediction_output_single() {
use std::time::Duration;
let options = RunOptions::default();
let result =
format_prediction_output(&[0.9, 0.05, 0.05], Duration::from_millis(100), &options);
assert!(result.is_ok());
}
#[test]
fn test_format_prediction_output_json() {
use std::time::Duration;
let options = RunOptions {
output_format: "json".to_string(),
..Default::default()
};
let result = format_prediction_output(&[0.5, 0.5], Duration::from_millis(50), &options);
assert!(result.is_ok());
let output = result.expect("value");
assert!(output.contains("predictions"));
}
#[test]
fn test_format_prediction_output_empty() {
use std::time::Duration;
let options = RunOptions::default();
let result = format_prediction_output(&[], Duration::from_millis(10), &options);
assert!(result.is_ok());
}
#[test]
fn test_resolve_model_local_returns_path() {
let source = ModelSource::Local(PathBuf::from("/nonexistent/model.apr"));
let result = resolve_model(&source, false, false);
assert!(result.is_ok());
assert_eq!(result.expect("value"), PathBuf::from("/nonexistent/model.apr"));
}
#[test]
fn test_resolve_model_offline_hf() {
let source = ModelSource::HuggingFace {
org: "test".to_string(),
repo: "model".to_string(),
file: None,
};
let result = resolve_model(&source, false, true);
assert!(result.is_err());
}
#[test]
fn test_find_cached_model_not_exists() {
let result = find_cached_model("nonexistent_org", "nonexistent_repo", None);
assert!(result.is_none());
}
#[test]
fn test_run_model_invalid_source() {
let options = RunOptions::default();
let result = run_model("hf://", &options);
assert!(result.is_err());
}
#[test]
fn test_parse_input_features_none() {
let result = parse_input_features(None);
assert!(result.is_ok());
assert!(result.expect("value").is_empty());
}
#[test]
fn test_parse_input_features_file_not_found() {
let path = PathBuf::from("/nonexistent/input.wav");
let result = parse_input_features(Some(&path));
assert!(result.is_err());
}
#[test]
fn test_run_options_with_trace() {
let options = RunOptions {
trace: true,
trace_verbose: true,
trace_steps: Some(vec!["embed".to_string()]),
..Default::default()
};
assert!(options.trace);
assert!(options.trace_verbose);
}
#[test]
fn test_run_result_clone() {
let result = RunResult {
text: "Test".to_string(),
duration_secs: 1.0,
cached: false,
tokens_generated: None,
tok_per_sec: None,
used_gpu: None,
generated_tokens: None,
};
let cloned = result.clone();
assert_eq!(result.text, cloned.text);
}
#[test]
fn clean_model_output_strips_assistant_prefix_with_newline() {
let raw = "<|im_start|>assistant\nThe answer is 42.";
let cleaned = clean_model_output(raw);
assert_eq!(cleaned, "The answer is 42.");
}
#[test]
fn clean_model_output_strips_all_markers_simultaneously() {
let raw = "<|im_start|>assistant\nHello<|im_end|><|endoftext|>";
let cleaned = clean_model_output(raw);
assert_eq!(cleaned, "Hello");
}
#[test]
fn clean_model_output_strips_repeated_markers() {
let raw = "<|im_end|>text<|im_end|>";
let cleaned = clean_model_output(raw);
assert_eq!(cleaned, "text");
}
#[test]
fn clean_model_output_trims_whitespace_after_removal() {
let raw = " <|im_end|> \n Hello \n <|endoftext|> ";
let cleaned = clean_model_output(raw);
assert_eq!(cleaned, "Hello");
}
#[test]
fn clean_model_output_preserves_partial_marker_text() {
let raw = "Use <|tag|> for formatting";
let cleaned = clean_model_output(raw);
assert_eq!(cleaned, "Use <|tag|> for formatting");
}
#[test]
fn clean_model_output_preserves_unicode() {
let raw = "<|im_start|>assistant\n\u{1f600} Hello \u{00e9}\u{00e8}<|im_end|>";
let cleaned = clean_model_output(raw);
assert_eq!(cleaned, "\u{1f600} Hello \u{00e9}\u{00e8}");
}
#[test]
fn parse_hf_file_with_dot_in_third_segment() {
let source = ModelSource::parse("hf://org/repo/model-q4.gguf").expect("should parse");
match source {
ModelSource::HuggingFace { org, repo, file } => {
assert_eq!(org, "org");
assert_eq!(repo, "repo");
assert_eq!(file, Some("model-q4.gguf".to_string()));
}
other => panic!("Expected HuggingFace, got {other:?}"),
}
}
#[test]
fn parse_hf_subdir_without_dot_is_not_file() {
let source = ModelSource::parse("hf://org/repo/subdir/model.gguf").expect("should parse");
match source {
ModelSource::HuggingFace { file, .. } => {
assert_eq!(
file, None,
"Third segment without dot should not trigger file detection"
);
}
other => panic!("Expected HuggingFace, got {other:?}"),
}
}
#[test]
fn parse_hf_three_segments_no_extension() {
let source = ModelSource::parse("hf://org/repo/branch").expect("should parse");
match source {
ModelSource::HuggingFace { file, .. } => {
assert_eq!(
file, None,
"Segment without dot should not be treated as file"
);
}
other => panic!("Expected HuggingFace, got {other:?}"),
}
}
#[test]
fn parse_empty_string_is_local() {
let source = ModelSource::parse("").expect("should parse");
assert_eq!(source, ModelSource::Local(PathBuf::from("")));
}
#[test]
fn parse_dotted_filename_is_local() {
let source = ModelSource::parse("model.v2.safetensors").expect("should parse");
assert_eq!(
source,
ModelSource::Local(PathBuf::from("model.v2.safetensors"))
);
}
#[test]
fn md5_hash_single_byte_difference() {
let h1 = md5_hash(b"aaaa");
let h2 = md5_hash(b"aaab");
assert_ne!(h1, h2, "Single byte change must produce different hash");
let diff_bits = (h1 ^ h2).count_ones();
assert!(
diff_bits >= 8,
"Expected avalanche effect (>=8 bits differ), got {diff_bits}"
);
}
#[test]
fn md5_hash_zero_bytes_nonzero() {
let h = md5_hash(&[0u8; 100]);
assert_ne!(h, 0, "Hash of zero bytes must not be zero");
}
#[test]
fn md5_hash_order_dependent() {
let h1 = md5_hash(b"ab");
let h2 = md5_hash(b"ba");
assert_ne!(h1, h2, "Hash must be order-dependent");
}
#[test]
fn md5_hash_large_input() {
let data = vec![0xFFu8; 10_000];
let h = md5_hash(&data);
let _ = h; }
#[test]
fn extract_shard_files_colon_in_key() {
let json = r#"{
"weight_map": {
"model:layer:0.weight": "shard-00001.safetensors"
}
}"#;
let files = extract_shard_files(json);
assert_eq!(files.len(), 1);
assert!(files.contains("shard-00001.safetensors"));
}
#[test]
fn extract_shard_files_crlf_formatting() {
let json = "{\r\n \"weight_map\": {\r\n \"a\": \"model-00001.safetensors\"\r\n }\r\n}";
let files = extract_shard_files(json);
assert_eq!(files.len(), 1);
}
#[test]
fn parse_token_ids_json_array() {
let result = parse_token_ids("[1, 2, 3]").expect("should parse JSON array");
assert_eq!(result, vec![1, 2, 3]);
}
#[test]
fn parse_token_ids_tab_separated() {
let result = parse_token_ids("10\t20\t30").expect("should parse TSV");
assert_eq!(result, vec![10, 20, 30]);
}
#[test]
fn parse_token_ids_newline_separated() {
let result = parse_token_ids("100\n200\n300").expect("should parse newlines");
assert_eq!(result, vec![100, 200, 300]);
}
#[test]
fn parse_token_ids_with_padding() {
let result = parse_token_ids(" 42 , 43 , 44 ").expect("should handle padding");
assert_eq!(result, vec![42, 43, 44]);
}
#[test]
fn parse_token_ids_max_u32() {
let input = format!("{}", u32::MAX);
let result = parse_token_ids(&input).expect("should parse max u32");
assert_eq!(result, vec![u32::MAX]);
}