Skip to content

Commit 4015815

Browse files
authored
Merge pull request #28 from lookbusy1344/claude/issue-27-20250903-1933
fix: bugs and improvements for issue #27
2 parents bec3ccd + dd687ec commit 4015815

File tree

4 files changed

+394
-27
lines changed

4 files changed

+394
-27
lines changed

src/classes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,5 +126,5 @@ OPTIONS:
126126
127127
Algorithm can be:
128128
CRC32, MD5, SHA1, WHIRLPOOL, BLAKE2S-256, BLAKE2B-512,
129-
SHA2 / SHA2-256 / SHA-256, SHA-224, SHA2-384, SHA2-512,
129+
SHA2 / SHA2-256 / SHA-256, SHA2-224, SHA2-384, SHA2-512,
130130
SHA3 / SHA3-256 (default), SHA3-384, SHA3-512";

src/main.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use std::io;
88
use std::io::BufRead;
99
use std::str::FromStr;
1010

11-
use anyhow::{anyhow, Result};
11+
use anyhow::{Result, anyhow};
1212

1313
//use crate::hasher::hash_file_crc32;
1414
use blake2::{Blake2b512, Blake2s256};
@@ -24,7 +24,7 @@ use classes::OutputEncoding;
2424
use hasher::{file_exists, hash_file_encoded};
2525

2626
use crate::classes::{
27-
BasicHash, ConfigSettings, HashAlgorithm, DEFAULT_HASH, GIT_VERSION_SHORT, HELP, VERSION,
27+
BasicHash, ConfigSettings, DEFAULT_HASH, GIT_VERSION_SHORT, HELP, HashAlgorithm, VERSION,
2828
};
2929

3030
mod classes;
@@ -228,8 +228,17 @@ fn get_paths_matching_glob(config: &ConfigSettings) -> Result<Vec<String>> {
228228
.collect();
229229

230230
// If the glob matched nothing, check if the pattern itself is a valid file
231-
if glob_matches.is_empty() && file_exists(pattern) {
232-
result.push(pattern.clone());
231+
if glob_matches.is_empty() {
232+
if file_exists(pattern) {
233+
result.push(pattern.clone());
234+
} else {
235+
// Check if this looks like a specific file path (not a glob pattern)
236+
// If it doesn't contain glob metacharacters, treat it as a missing file error
237+
if !pattern.contains(&['*', '?', '[', ']']) {
238+
return Err(anyhow::anyhow!("File not found: {}", pattern));
239+
}
240+
// Otherwise it's a glob pattern that matched nothing, which is acceptable
241+
}
233242
} else {
234243
result.extend(glob_matches);
235244
}
@@ -279,11 +288,11 @@ where
279288
let file_hash = call_hasher(config.algorithm, config.encoding, pathstr);
280289

281290
match file_hash {
282-
Ok(hash) => {
291+
Ok(basic_hash) => {
283292
if config.exclude_fn {
284-
println!("{}", hash.0);
293+
println!("{basic_hash}");
285294
} else {
286-
println!("{} {}", hash.0, pathstr);
295+
println!("{basic_hash} {pathstr}");
287296
}
288297
}
289298

src/unit_tests.rs

Lines changed: 124 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,132 @@
1-
#![allow(unused_imports)]
2-
// #![allow(dead_code)]
3-
// #![allow(unused_variables)]
4-
5-
// unit tests are part of the main crate
6-
71
#[cfg(test)]
82
use super::*;
3+
use std::str::FromStr;
4+
5+
#[test]
6+
fn test_parse_hash_algorithm_valid() {
7+
assert_eq!(
8+
parse_hash_algorithm(Some("SHA3-256")).unwrap(),
9+
HashAlgorithm::SHA3_256
10+
);
11+
assert_eq!(
12+
parse_hash_algorithm(Some("MD5")).unwrap(),
13+
HashAlgorithm::MD5
14+
);
15+
assert_eq!(
16+
parse_hash_algorithm(Some("CRC32")).unwrap(),
17+
HashAlgorithm::CRC32
18+
);
19+
assert_eq!(
20+
parse_hash_algorithm(Some("WHIRLPOOL")).unwrap(),
21+
HashAlgorithm::Whirlpool
22+
);
23+
}
24+
25+
#[test]
26+
fn test_parse_hash_algorithm_default() {
27+
assert_eq!(parse_hash_algorithm(None).unwrap(), DEFAULT_HASH);
28+
assert_eq!(parse_hash_algorithm(Some("")).unwrap(), DEFAULT_HASH);
29+
}
30+
31+
#[test]
32+
fn test_parse_hash_algorithm_invalid() {
33+
assert!(parse_hash_algorithm(Some("INVALID")).is_err());
34+
}
35+
36+
#[test]
37+
fn test_parse_hash_encoding_valid() {
38+
assert_eq!(
39+
parse_hash_encoding(Some("Hex")).unwrap(),
40+
OutputEncoding::Hex
41+
);
42+
assert_eq!(
43+
parse_hash_encoding(Some("Base64")).unwrap(),
44+
OutputEncoding::Base64
45+
);
46+
assert_eq!(
47+
parse_hash_encoding(Some("Base32")).unwrap(),
48+
OutputEncoding::Base32
49+
);
50+
}
51+
52+
#[test]
53+
fn test_parse_hash_encoding_default() {
54+
assert_eq!(
55+
parse_hash_encoding(None).unwrap(),
56+
OutputEncoding::Unspecified
57+
);
58+
assert_eq!(
59+
parse_hash_encoding(Some("")).unwrap(),
60+
OutputEncoding::Unspecified
61+
);
62+
}
63+
64+
#[test]
65+
fn test_hash_algorithm_from_str() {
66+
assert_eq!(
67+
HashAlgorithm::from_str("sha3-256").unwrap(),
68+
HashAlgorithm::SHA3_256
69+
);
70+
assert_eq!(
71+
HashAlgorithm::from_str("SHA2").unwrap(),
72+
HashAlgorithm::SHA2_256
73+
);
74+
assert_eq!(
75+
HashAlgorithm::from_str("sha1").unwrap(),
76+
HashAlgorithm::SHA1
77+
);
78+
}
79+
80+
#[test]
81+
fn test_config_settings_new() {
82+
let config = ConfigSettings::new(
83+
true, // debug_mode
84+
false, // exclude_fn
85+
false, // single_thread
86+
true, // case_sensitive
87+
HashAlgorithm::SHA3_256,
88+
OutputEncoding::Hex,
89+
Some(100),
90+
);
91+
92+
assert!(config.debug_mode);
93+
assert!(!config.exclude_fn);
94+
assert!(config.case_sensitive);
95+
assert_eq!(config.algorithm, HashAlgorithm::SHA3_256);
96+
assert_eq!(config.encoding, OutputEncoding::Hex);
97+
assert_eq!(config.limit_num, Some(100));
98+
assert!(config.supplied_paths.is_empty());
99+
}
100+
101+
#[test]
102+
fn test_config_settings_set_paths() {
103+
let mut config = ConfigSettings::new(
104+
false,
105+
false,
106+
false,
107+
false,
108+
HashAlgorithm::MD5,
109+
OutputEncoding::Base64,
110+
None,
111+
);
112+
113+
let paths = vec!["file1.txt".to_string(), "file2.txt".to_string()];
114+
config.set_supplied_paths(paths.clone());
115+
116+
assert_eq!(config.supplied_paths, paths);
117+
}
9118

10119
#[test]
11-
fn unit_it_works() {
12-
assert_eq!(2 + 2, 4);
120+
fn test_basic_hash_display() {
121+
let hash = BasicHash("abc123".to_string());
122+
assert_eq!(format!("{hash}"), "abc123");
13123
}
14124

15125
#[test]
16-
fn help_length() {
17-
assert!(HELP.len() > 10);
126+
fn test_help_content() {
127+
assert!(HELP.contains("USAGE:"));
128+
assert!(HELP.contains("FLAGS:"));
129+
assert!(HELP.contains("OPTIONS:"));
130+
assert!(HELP.contains("Algorithm can be:"));
131+
assert!(HELP.len() > 100);
18132
}

0 commit comments

Comments
 (0)