Skip to content

Commit 07ac516

Browse files
committed
fixed #125: improved unit tests
1 parent 1dc2941 commit 07ac516

6 files changed

Lines changed: 117 additions & 29 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "tuckr"
3-
version = "0.12.0"
3+
version = "0.13.0-beta"
44
authors = ["RaphGL"]
55
edition = "2024"
66
description = "Super powered GNU Stow replacement"

src/dotfiles.rs

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -184,35 +184,32 @@ pub fn group_without_target(group: &str) -> &str {
184184
}
185185

186186
fn platform_is_under_wsl() -> bool {
187-
if !cfg!(target_os = "linux") {
187+
if cfg!(not(target_os = "linux")) {
188188
return false;
189189
}
190190

191191
for file in &["/proc/sys/kernel/osrelease", "/proc/version"] {
192-
if let Ok(content) = std::fs::read(file) {
193-
let Ok(content) = std::str::from_utf8(&content) else {
194-
return false;
195-
};
192+
let Ok(content) = std::fs::read(file) else {
193+
continue;
194+
};
196195

197-
if content.contains("microsoft") || content.contains("WSL") {
198-
return true;
199-
}
196+
let Ok(content) = std::str::from_utf8(&content) else {
197+
continue;
198+
};
199+
200+
if content.contains("microsoft") || content.contains("WSL") {
201+
return true;
200202
}
201203
}
202204

203-
let Ok(wsl_interop_exists) = std::fs::exists("/proc/sys/fs/binfmt_misc/WSLInterop") else {
204-
return false;
205-
};
206-
207-
wsl_interop_exists
205+
std::fs::exists("/proc/sys/fs/binfmt_misc/WSLInterop").is_ok()
208206
}
209207

210208
/// Returns true if a group with specified name can be used by current platform.
211209
/// Checks if a group should be linked on current platform. For unconditional
212210
/// groups, this function returns true; for conditional groups, this function
213211
/// returns true when group suffix matches current target_os or target_family.
214212
pub fn group_is_valid_target(group: &str, custom_targets: &[impl AsRef<str>]) -> bool {
215-
// Gets the current OS and OS family
216213
let current_target_os = format!("_{}", env::consts::OS);
217214
let current_target_family = format!("_{}", env::consts::FAMILY);
218215

@@ -247,7 +244,7 @@ impl Dotfile {
247244
return false;
248245
};
249246

250-
let home_dir = dirs::home_dir().unwrap();
247+
let home_dir = get_dotfiles_target_dir_path().unwrap();
251248
!target.starts_with(home_dir)
252249
}
253250

@@ -409,9 +406,13 @@ pub fn get_target_basepath(target: &path::Path) -> Option<PathBuf> {
409406
}
410407

411408
pub fn get_dotfiles_target_dir_path() -> Result<PathBuf, String> {
412-
#[cfg(test)]
413-
{
414-
unsafe { std::env::remove_var("TUCKR_TARGET") };
409+
if cfg!(test) {
410+
return Ok(std::env::temp_dir().join(format!(
411+
"tuckr-target-{}",
412+
// this will return a namespace but `::` is invalid on paths in windows
413+
// so we need to change it to prevent panics when interacting with the file system there
414+
std::thread::current().name().unwrap().replace("::", "_")
415+
)));
415416
}
416417

417418
if let Ok(dir) = std::env::var("TUCKR_TARGET")
@@ -554,7 +555,7 @@ mod tests {
554555

555556
assert_eq!(
556557
Dotfile::try_from(group).unwrap().to_target_path().unwrap(),
557-
dirs::home_dir().unwrap().join(".zshrc")
558+
super::get_dotfiles_target_dir_path().unwrap().join(".zshrc")
558559
);
559560
}
560561

src/fileops.rs

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -560,15 +560,18 @@ pub fn groupis_cmd(ctx: &Context, files: &[String]) -> Result<(), ExitCode> {
560560
}
561561
};
562562

563+
let mut found_non_group_file = false;
563564
for file in files {
564565
let file_path = Path::new(file);
565566
if !file_path.exists() {
566567
eprintln!("{}", t!("errors.x_doesnt_exist", x = file).red());
568+
found_non_group_file = true;
567569
continue;
568570
}
569571

570572
let Some(group) = dotfiles::get_dotfile_from_path(file_path) else {
571573
eprintln!("{}", t!("errors.not_a_tuckr_dotfile", file = file).red());
574+
found_non_group_file = true;
572575
continue;
573576
};
574577

@@ -578,7 +581,11 @@ pub fn groupis_cmd(ctx: &Context, files: &[String]) -> Result<(), ExitCode> {
578581
println!("{}", group.group_name);
579582
}
580583

581-
Ok(())
584+
if found_non_group_file {
585+
Err(ExitCode::FAILURE)
586+
} else {
587+
Ok(())
588+
}
582589
}
583590

584591
pub fn get_user_confirmation(msg: &str) -> bool {
@@ -774,10 +781,7 @@ mod tests {
774781
let dotfiles_dir = dotfiles::get_dotfiles_path(None).unwrap();
775782
fs::create_dir_all(dotfiles_dir.join("Configs")).unwrap();
776783

777-
let target_dir = dirs::home_dir().unwrap().join(format!(
778-
"tuckr_test-{}",
779-
std::thread::current().name().unwrap().replace("::", "_")
780-
));
784+
let target_dir = dotfiles::get_dotfiles_target_dir_path().unwrap();
781785
fs::create_dir_all(&target_dir).unwrap();
782786

783787
Self {
@@ -945,4 +949,30 @@ mod tests {
945949
assert!(dotfiles_dir.join("Hooks").exists());
946950
assert!(dotfiles_dir.join("Secrets").exists());
947951
}
952+
953+
#[test]
954+
fn groupis_cmd_detects_groups_properly() {
955+
let ft = FileopsTest::start();
956+
let ctx = Context::default();
957+
958+
let testfile = ft.target_dir.join("Tuckr-GroupIs-UnitTest-File");
959+
960+
assert!(groupis_cmd(&ctx, &[testfile.to_str().unwrap().into()]).is_err());
961+
962+
fs::write(&testfile, "test".as_bytes()).unwrap();
963+
assert!(groupis_cmd(&ctx, &[testfile.to_str().unwrap().into()]).is_err());
964+
965+
push_cmd(
966+
&ctx,
967+
"test".into(),
968+
&[testfile.to_str().unwrap().into()],
969+
true,
970+
false,
971+
true,
972+
).unwrap();
973+
974+
assert!(groupis_cmd(&ctx, &[testfile.to_str().unwrap().into()]).is_ok());
975+
976+
fs::remove_file(testfile).unwrap();
977+
}
948978
}

src/hooks.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ pub fn set_cmd(
254254
}
255255

256256
let run_deploy_steps = |stages: DeployStages, group: String| -> Result<(), ExitCode> {
257-
if !dotfiles::group_is_valid_target(&group, &ctx.custom_targets) || exclude.contains(&group)
257+
if exclude.contains(&group)
258258
{
259259
return Ok(());
260260
}
@@ -377,7 +377,7 @@ pub fn unset_cmd(ctx: &Context, groups: &[String], exclude: &[String]) -> Result
377377
};
378378

379379
for group in groups.iter() {
380-
if !dotfiles::group_is_valid_target(group, &ctx.custom_targets) || exclude.contains(group) {
380+
if exclude.contains(group) {
381381
continue;
382382
}
383383

src/symlinks.rs

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1196,19 +1196,33 @@ mod tests {
11961196

11971197
impl Test {
11981198
fn start() -> Self {
1199+
let target_dir = dotfiles::get_dotfiles_target_dir_path().unwrap();
1200+
fs::create_dir_all(&target_dir).unwrap();
1201+
11991202
crate::fileops::init_cmd(&Context::default()).unwrap();
12001203
let dotfiles_dir = dotfiles::get_dotfiles_path(None).unwrap();
1204+
let configs_dir = dotfiles_dir.join("Configs");
12011205
let group_dir = dotfiles_dir.join("Configs").join("Group1");
12021206
let new_config_dir = group_dir.join(".config");
1203-
12041207
fs::create_dir_all(&new_config_dir).unwrap();
12051208

12061209
let filepaths = [
12071210
new_config_dir.join("group_file"),
12081211
group_dir.join("group_file_0"),
1212+
1213+
configs_dir
1214+
.join("shared_group1")
1215+
.join("shared_dir")
1216+
.join("file1"),
1217+
configs_dir
1218+
.join("shared_group2")
1219+
.join("shared_dir")
1220+
.join("file2"),
12091221
];
12101222

12111223
for filepath in &filepaths {
1224+
fs::create_dir_all(filepath.parent().unwrap()).unwrap();
1225+
12121226
let mut file = File::create(filepath).unwrap();
12131227
_ = file
12141228
.write("Some random content on file".as_bytes())
@@ -1303,4 +1317,47 @@ mod tests {
13031317
test_adding_symlink();
13041318
test_removing_symlink();
13051319
}
1320+
1321+
#[test]
1322+
fn resolve_shared_directories() {
1323+
let ctx = Context::default();
1324+
let target_dir = dotfiles::get_dotfiles_target_dir_path().unwrap();
1325+
let shared_dir_target = target_dir.join("shared_dir");
1326+
_ = fs::remove_dir_all(&shared_dir_target);
1327+
1328+
let test = Test::start();
1329+
1330+
assert!(!shared_dir_target.exists());
1331+
1332+
_ = super::add_cmd(
1333+
&ctx,
1334+
false,
1335+
&["shared_group1".into()],
1336+
&[],
1337+
false,
1338+
false,
1339+
true,
1340+
);
1341+
1342+
let file1_target = shared_dir_target.join("file1");
1343+
let file2_target = shared_dir_target.join("file2");
1344+
1345+
assert!(shared_dir_target.is_symlink());
1346+
assert!(!file1_target.is_symlink() && file1_target.is_file());
1347+
1348+
_ = super::add_cmd(
1349+
&ctx,
1350+
false,
1351+
&["shared_group2".into()],
1352+
&[],
1353+
false,
1354+
false,
1355+
true,
1356+
);
1357+
1358+
assert!(file1_target.is_symlink() && file1_target.is_file());
1359+
assert!(file2_target.is_symlink() && file2_target.is_file());
1360+
1361+
_ = fs::remove_dir_all(shared_dir_target);
1362+
}
13061363
}

0 commit comments

Comments
 (0)