Skip to content

Commit 1135ead

Browse files
author
Test User
committed
test(commands): expand test coverage for worktree operations
- Add 16 new test functions across create, list, and rename modules - Test path determination, validation, and edge cases - Improve coverage of worktree display formatting and filtering - Enhance testability of rename analysis and validation logic - Fix format string style to comply with clippy::uninlined_format_args
1 parent 76b9b0f commit 1135ead

3 files changed

Lines changed: 356 additions & 127 deletions

File tree

src/commands/create.rs

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -818,4 +818,89 @@ mod tests {
818818
validate_worktree_creation("new-worktree", &existing_path, &existing_worktrees);
819819
assert!(result.is_ok()); // Temporary assertion until struct is fixed
820820
}
821+
822+
// Add 6 new tests for better coverage
823+
#[test]
824+
fn test_determine_worktree_path_custom_missing_path() {
825+
let temp_dir = tempfile::TempDir::new().unwrap();
826+
let git_dir = temp_dir.path().join("project");
827+
std::fs::create_dir_all(&git_dir).unwrap();
828+
829+
let result = determine_worktree_path(&git_dir, "test-worktree", "custom", None);
830+
assert!(result.is_err());
831+
}
832+
833+
#[test]
834+
fn test_determine_worktree_path_invalid_location() {
835+
let temp_dir = tempfile::TempDir::new().unwrap();
836+
let git_dir = temp_dir.path().join("project");
837+
std::fs::create_dir_all(&git_dir).unwrap();
838+
839+
let invalid_location = "invalid-location";
840+
let result = determine_worktree_path(&git_dir, "test-worktree", invalid_location, None);
841+
assert!(result.is_err());
842+
}
843+
844+
#[test]
845+
fn test_validate_worktree_location_all_valid() {
846+
let valid_locations = vec!["same-level", "subdirectory", "custom"];
847+
for location in valid_locations {
848+
assert!(validate_worktree_location(location).is_ok());
849+
}
850+
}
851+
852+
#[test]
853+
fn test_determine_worktree_path_legacy_custom_missing_path() {
854+
let repo_name = "repo";
855+
let result =
856+
determine_worktree_path_legacy("test", WORKTREE_LOCATION_CUSTOM_PATH, None, repo_name);
857+
assert!(result.is_err());
858+
}
859+
860+
#[test]
861+
fn test_determine_worktree_path_subdirectory_repo_name() {
862+
let temp_dir = tempfile::TempDir::new().unwrap();
863+
let git_dir = temp_dir.path().join("my-project");
864+
std::fs::create_dir_all(&git_dir).unwrap();
865+
866+
let result = determine_worktree_path(&git_dir, "feature", "subdirectory", None);
867+
assert!(result.is_ok());
868+
869+
let (path, pattern) = result.unwrap();
870+
assert_eq!(pattern, "subdirectory");
871+
assert!(path.to_string_lossy().contains("my-project"));
872+
assert!(path.to_string_lossy().contains("worktrees"));
873+
assert!(path.to_string_lossy().contains("feature"));
874+
}
875+
876+
#[test]
877+
fn test_branch_source_enum_variants() {
878+
let test_branch = "main";
879+
let test_tag = "v1.0.0";
880+
let test_new_branch = "feature";
881+
let test_base = "develop";
882+
883+
let sources = vec![
884+
BranchSource::Head,
885+
BranchSource::Branch(test_branch.to_string()),
886+
BranchSource::Tag(test_tag.to_string()),
887+
BranchSource::NewBranch {
888+
name: test_new_branch.to_string(),
889+
base: test_base.to_string(),
890+
},
891+
];
892+
893+
// Test that all enum variants can be created and matched
894+
for source in sources {
895+
match source {
896+
BranchSource::Head => {}
897+
BranchSource::Branch(ref branch) => assert_eq!(branch, test_branch),
898+
BranchSource::Tag(ref tag) => assert_eq!(tag, test_tag),
899+
BranchSource::NewBranch { ref name, ref base } => {
900+
assert_eq!(name, test_new_branch);
901+
assert_eq!(base, test_base);
902+
}
903+
}
904+
}
905+
}
821906
}

src/commands/list.rs

Lines changed: 128 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -133,28 +133,22 @@ pub fn list_worktrees_with_ui(manager: &GitWorktreeManager, _ui: &dyn UserInterf
133133
Ok(())
134134
}
135135

136-
#[cfg(false)] // Temporarily disabled due to WorktreeInfo struct field changes
136+
#[cfg(test)]
137137
mod tests {
138138
use super::*;
139139
use std::path::PathBuf;
140140

141141
#[test]
142-
#[ignore = "WorktreeInfo struct fields need to be updated"]
143142
fn test_format_worktree_display_basic() {
144143
let worktree = WorktreeInfo {
145144
name: "feature".to_string(),
146145
path: PathBuf::from("/tmp/feature"),
147-
branch: Some("feature".to_string()),
148-
commit_info: None,
149-
head: "HEAD".to_string(),
150-
is_bare: false,
151-
is_detached: false,
152-
is_locked: false,
153-
lock_reason: None,
146+
branch: "feature".to_string(),
154147
is_current: false,
155148
has_changes: false,
156149
last_commit: None,
157150
ahead_behind: None,
151+
is_locked: false,
158152
};
159153

160154
let display = format_worktree_display(&worktree, false);
@@ -166,17 +160,12 @@ mod tests {
166160
let worktree = WorktreeInfo {
167161
name: "main".to_string(),
168162
path: PathBuf::from("/tmp/main"),
169-
branch: Some("main".to_string()),
170-
commit_info: None,
171-
head: "HEAD".to_string(),
172-
is_bare: false,
173-
is_detached: false,
174-
is_locked: false,
175-
lock_reason: None,
163+
branch: "main".to_string(),
176164
is_current: true,
177165
has_changes: false,
178166
last_commit: None,
179167
ahead_behind: None,
168+
is_locked: false,
180169
};
181170

182171
let display = format_worktree_display(&worktree, false);
@@ -188,17 +177,12 @@ mod tests {
188177
let worktree = WorktreeInfo {
189178
name: "locked".to_string(),
190179
path: PathBuf::from("/tmp/locked"),
191-
branch: Some("locked".to_string()),
192-
commit_info: None,
193-
head: "HEAD".to_string(),
194-
is_bare: false,
195-
is_detached: false,
196-
is_locked: true,
197-
lock_reason: Some("maintenance".to_string()),
180+
branch: "locked".to_string(),
198181
is_current: false,
199182
has_changes: true,
200183
last_commit: None,
201184
ahead_behind: None,
185+
is_locked: true,
202186
};
203187

204188
let display = format_worktree_display(&worktree, false);
@@ -210,17 +194,12 @@ mod tests {
210194
let worktree = WorktreeInfo {
211195
name: "feature".to_string(),
212196
path: PathBuf::from("/tmp/feature"),
213-
branch: Some("feature".to_string()),
214-
commit_info: None,
215-
head: "HEAD".to_string(),
216-
is_bare: false,
217-
is_detached: false,
218-
is_locked: false,
219-
lock_reason: None,
197+
branch: "feature".to_string(),
220198
is_current: false,
221199
has_changes: false,
222200
last_commit: None,
223201
ahead_behind: None,
202+
is_locked: false,
224203
};
225204

226205
let display = format_worktree_display(&worktree, true);
@@ -232,17 +211,12 @@ mod tests {
232211
let worktree = WorktreeInfo {
233212
name: "feature-auth".to_string(),
234213
path: PathBuf::from("/tmp/feature"),
235-
branch: Some("feature".to_string()),
236-
commit_info: None,
237-
head: "HEAD".to_string(),
238-
is_bare: false,
239-
is_detached: false,
240-
is_locked: false,
241-
lock_reason: None,
214+
branch: "feature".to_string(),
242215
is_current: false,
243216
has_changes: false,
244217
last_commit: None,
245218
ahead_behind: None,
219+
is_locked: false,
246220
};
247221

248222
assert!(should_show_worktree(&worktree, false, Some("auth")));
@@ -253,17 +227,12 @@ mod tests {
253227
let worktree = WorktreeInfo {
254228
name: "feature-ui".to_string(),
255229
path: PathBuf::from("/tmp/feature"),
256-
branch: Some("feature".to_string()),
257-
commit_info: None,
258-
head: "HEAD".to_string(),
259-
is_bare: false,
260-
is_detached: false,
261-
is_locked: false,
262-
lock_reason: None,
230+
branch: "feature".to_string(),
263231
is_current: false,
264232
has_changes: false,
265233
last_commit: None,
266234
ahead_behind: None,
235+
is_locked: false,
267236
};
268237

269238
assert!(!should_show_worktree(&worktree, false, Some("auth")));
@@ -274,17 +243,12 @@ mod tests {
274243
let worktree = WorktreeInfo {
275244
name: "clean".to_string(),
276245
path: PathBuf::from("/tmp/clean"),
277-
branch: Some("clean".to_string()),
278-
commit_info: None,
279-
head: "HEAD".to_string(),
280-
is_bare: false,
281-
is_detached: false,
282-
is_locked: false,
283-
lock_reason: None,
246+
branch: "clean".to_string(),
284247
is_current: false,
285248
has_changes: false,
286249
last_commit: None,
287250
ahead_behind: None,
251+
is_locked: false,
288252
};
289253

290254
assert!(should_show_worktree(&worktree, true, None));
@@ -295,36 +259,135 @@ mod tests {
295259
let clean_worktree = WorktreeInfo {
296260
name: "clean".to_string(),
297261
path: PathBuf::from("/tmp/clean"),
298-
branch: Some("clean".to_string()),
299-
commit_info: None,
300-
head: "HEAD".to_string(),
301-
is_bare: false,
302-
is_detached: false,
303-
is_locked: false,
304-
lock_reason: None,
262+
branch: "clean".to_string(),
305263
is_current: false,
306264
has_changes: false,
307265
last_commit: None,
308266
ahead_behind: None,
267+
is_locked: false,
309268
};
310269

311270
let dirty_worktree = WorktreeInfo {
312271
name: "dirty".to_string(),
313272
path: PathBuf::from("/tmp/dirty"),
314-
branch: Some("dirty".to_string()),
315-
commit_info: None,
316-
head: "HEAD".to_string(),
317-
is_bare: false,
318-
is_detached: false,
319-
is_locked: false,
320-
lock_reason: None,
273+
branch: "dirty".to_string(),
321274
is_current: false,
322275
has_changes: true,
323276
last_commit: None,
324277
ahead_behind: None,
278+
is_locked: false,
325279
};
326280

327281
assert!(!should_show_worktree(&clean_worktree, false, None));
328282
assert!(should_show_worktree(&dirty_worktree, false, None));
329283
}
284+
285+
// Add 5 new tests for better coverage
286+
#[test]
287+
fn test_format_worktree_display_verbose_with_commit() {
288+
let test_commit_id = "abc123def";
289+
let test_path = "/tmp/feature";
290+
let worktree = WorktreeInfo {
291+
name: "feature".to_string(),
292+
path: PathBuf::from(test_path),
293+
branch: "feature".to_string(),
294+
is_current: false,
295+
has_changes: false,
296+
last_commit: Some(crate::infrastructure::git::CommitInfo {
297+
id: test_commit_id.to_string(),
298+
message: "Add feature".to_string(),
299+
author: "test@example.com".to_string(),
300+
time: "2023-01-01".to_string(),
301+
}),
302+
ahead_behind: None,
303+
is_locked: false,
304+
};
305+
306+
let display = format_worktree_display(&worktree, true);
307+
assert!(display.contains(&format!("[{test_commit_id}]")));
308+
assert!(display.contains(&format!("- {test_path}")));
309+
}
310+
311+
#[test]
312+
fn test_format_worktree_display_verbose_with_ahead_behind() {
313+
let ahead_count = 2;
314+
let behind_count = 3;
315+
let worktree = WorktreeInfo {
316+
name: "feature".to_string(),
317+
path: PathBuf::from("/tmp/feature"),
318+
branch: "feature".to_string(),
319+
is_current: false,
320+
has_changes: false,
321+
last_commit: None,
322+
ahead_behind: Some((ahead_count, behind_count)),
323+
is_locked: false,
324+
};
325+
326+
let display = format_worktree_display(&worktree, true);
327+
assert!(display.contains(&format!("↑{ahead_count} ↓{behind_count}")));
328+
}
329+
330+
#[test]
331+
fn test_format_worktree_display_all_flags() {
332+
let worktree_name = "complex";
333+
let worktree = WorktreeInfo {
334+
name: worktree_name.to_string(),
335+
path: PathBuf::from("/tmp/complex"),
336+
branch: "complex".to_string(),
337+
is_current: true,
338+
has_changes: true,
339+
last_commit: None,
340+
ahead_behind: None,
341+
is_locked: true,
342+
};
343+
344+
let display = format_worktree_display(&worktree, false);
345+
assert_eq!(
346+
display,
347+
format!("{worktree_name} (current) (locked) (changes)")
348+
);
349+
}
350+
351+
#[test]
352+
fn test_should_show_worktree_empty_filter() {
353+
let worktree = WorktreeInfo {
354+
name: "any".to_string(),
355+
path: PathBuf::from("/tmp/any"),
356+
branch: "any".to_string(),
357+
is_current: false,
358+
has_changes: false,
359+
last_commit: None,
360+
ahead_behind: None,
361+
is_locked: false,
362+
};
363+
364+
// Empty string filter should match anything
365+
assert!(should_show_worktree(&worktree, false, Some("")));
366+
}
367+
368+
#[test]
369+
fn test_should_show_worktree_partial_filter() {
370+
let test_filters = vec!["auth", "feature", "login"];
371+
let no_match_filter = "ui";
372+
let worktree = WorktreeInfo {
373+
name: "feature-auth-login".to_string(),
374+
path: PathBuf::from("/tmp/feature"),
375+
branch: "feature".to_string(),
376+
is_current: false,
377+
has_changes: false,
378+
last_commit: None,
379+
ahead_behind: None,
380+
is_locked: false,
381+
};
382+
383+
// Partial matches should work
384+
for filter in test_filters {
385+
assert!(should_show_worktree(&worktree, false, Some(filter)));
386+
}
387+
assert!(!should_show_worktree(
388+
&worktree,
389+
false,
390+
Some(no_match_filter)
391+
));
392+
}
330393
}

0 commit comments

Comments
 (0)