Skip to content

Commit 7b123be

Browse files
committed
refactor
- deduplicate - remove unhappy tests in favor of unit-testing the respective function.
1 parent 67acbae commit 7b123be

File tree

2 files changed

+84
-112
lines changed

2 files changed

+84
-112
lines changed

crates/but/src/command/legacy/describe.rs

Lines changed: 54 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use anyhow::{Result, bail};
22
use but_ctx::Context;
3-
use but_oxidize::{ObjectIdExt, OidExt};
3+
use but_oxidize::{ObjectIdExt as _, OidExt};
44
use gitbutler_project::Project;
5+
use gix::prelude::ObjectIdExt;
56

67
use crate::{legacy::id::CliId, tui, utils::OutputChannel};
78

@@ -64,17 +65,8 @@ fn edit_branch_name(
6465
}
6566

6667
if let Some(sid) = stack_entry.id {
67-
let new_name = if let Some(msg) = message {
68-
// Use provided message, trim and validate
69-
let trimmed = msg.trim();
70-
if trimmed.is_empty() {
71-
bail!("Aborting due to empty branch name");
72-
}
73-
trimmed.to_string()
74-
} else {
75-
// Fall back to editor
76-
get_branch_name_from_editor(branch_name)?
77-
};
68+
let new_name = prepare_provided_message(message, "branch name")
69+
.unwrap_or_else(|| get_branch_name_from_editor(branch_name))?;
7870
but_api::legacy::stack::update_branch_name(
7971
project.id,
8072
sid,
@@ -91,6 +83,16 @@ fn edit_branch_name(
9183
bail!("Branch '{}' not found in any stack", branch_name)
9284
}
9385

86+
fn prepare_provided_message(msg: Option<&str>, entity: &str) -> Option<Result<String>> {
87+
msg.map(|msg| {
88+
let trimmed = msg.trim();
89+
if trimmed.is_empty() {
90+
bail!("Aborting due to empty {entity}");
91+
}
92+
Ok(trimmed.to_string())
93+
})
94+
}
95+
9496
fn edit_commit_message_by_id(
9597
ctx: &Context,
9698
project: &Project,
@@ -149,24 +151,19 @@ fn edit_commit_message_by_id(
149151
let current_message = commit_message.to_string();
150152

151153
// Get new message from provided argument or editor
152-
let new_message = if let Some(msg) = message {
153-
// Use provided message, trim and validate
154-
let trimmed = msg.trim();
155-
if trimmed.is_empty() {
156-
bail!("Aborting due to empty commit message");
157-
}
158-
trimmed.to_string()
159-
} else {
160-
// Get the files changed in this commit using but_api
154+
let new_message = prepare_provided_message(message, "commit message").unwrap_or_else(|| {
161155
let commit_details = but_api::legacy::diff::commit_details(project.id, commit_oid.into())?;
162156
let changed_files = get_changed_files_from_commit_details(&commit_details);
163157

164158
// Open editor with current message and file list
165-
get_commit_message_from_editor(&current_message, &changed_files)?
166-
};
159+
get_commit_message_from_editor(&current_message, &changed_files)
160+
})?;
167161

168162
if new_message.trim() == current_message.trim() {
169-
bail!("No changes to commit message.");
163+
if let Some(out) = out.for_human() {
164+
writeln!(out, "No changes to commit message - nothing to be done")?;
165+
}
166+
return Ok(());
170167
}
171168

172169
// Use gitbutler_branch_actions::update_commit_message instead of low-level primitives
@@ -179,11 +176,12 @@ fn edit_commit_message_by_id(
179176
)?;
180177

181178
if let Some(out) = out.for_human() {
179+
let repo = ctx.repo.get()?;
182180
writeln!(
183181
out,
184182
"Updated commit message for {} (now {})",
185-
commit_oid.to_hex_with_len(7),
186-
new_commit_oid.to_gix().to_hex_with_len(7)
183+
commit_oid.attach(&repo).shorten_or_id(),
184+
new_commit_oid.to_gix().attach(&repo).shorten_or_id()
187185
)?;
188186
}
189187

@@ -259,3 +257,33 @@ fn get_branch_name_from_editor(current_name: &str) -> Result<String> {
259257

260258
Ok(branch_name)
261259
}
260+
261+
#[cfg(test)]
262+
mod tests {
263+
264+
mod prepare_provided_message {
265+
use super::super::*;
266+
267+
#[test]
268+
fn empty_is_fails() {
269+
assert_eq!(
270+
prepare_provided_message(Some(""), "message")
271+
.unwrap()
272+
.unwrap_err()
273+
.to_string(),
274+
"Aborting due to empty message"
275+
);
276+
}
277+
278+
#[test]
279+
fn empty_is_after_trimming_fails() {
280+
assert_eq!(
281+
prepare_provided_message(Some(" "), "message")
282+
.unwrap()
283+
.unwrap_err()
284+
.to_string(),
285+
"Aborting due to empty message"
286+
);
287+
}
288+
}
289+
}
Lines changed: 30 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
use snapbox::str;
2-
31
use crate::utils::{Sandbox, setup_metadata};
2+
use gitbutler_commit::commit_ext::CommitExt;
3+
use snapbox::str;
44

55
#[test]
66
fn describe_commit_with_message_flag() -> anyhow::Result<()> {
@@ -22,43 +22,17 @@ Updated commit message for [..] (now [..])
2222
2323
"#]]);
2424

25-
// Verify the commit message was updated
26-
let log = env.git_log()?;
27-
assert!(log.contains("Updated commit message"));
28-
assert!(!log.contains("add A"));
29-
30-
Ok(())
31-
}
32-
33-
// Note: Branch rename test is omitted because the test scenario uses single-character
34-
// branch names ("A") which don't meet the 2-character minimum requirement for CLI IDs.
35-
// The branch rename functionality with -m flag is tested manually and works correctly.
36-
37-
#[test]
38-
fn describe_with_empty_message_fails() -> anyhow::Result<()> {
39-
let env = Sandbox::init_scenario_with_target_and_default_settings("one-stack")?;
4025
insta::assert_snapshot!(env.git_log()?, @r"
41-
* edd3eb7 (HEAD -> gitbutler/workspace) GitButler Workspace Commit
42-
* 9477ae7 (A) add A
43-
* 0dc3733 (origin/main, origin/HEAD, main) add M
26+
* d84f3c4 (HEAD -> gitbutler/workspace) GitButler Workspace Commit
27+
* 2f7c570 (A) Updated commit message
28+
* 0dc3733 (origin/main, origin/HEAD, main, gitbutler/target) add M
4429
");
4530

46-
setup_metadata(&env, &["A"])?;
47-
48-
// Try to describe commit with empty message
49-
env.but("describe 9477ae7 -m ''")
50-
.assert()
51-
.failure()
52-
.stderr_eq(str![[r#"
53-
Error: Aborting due to empty commit message
54-
55-
"#]]);
56-
5731
Ok(())
5832
}
5933

6034
#[test]
61-
fn describe_with_whitespace_only_message_fails() -> anyhow::Result<()> {
35+
fn describe_commit_with_multiline_message() -> anyhow::Result<()> {
6236
let env = Sandbox::init_scenario_with_target_and_default_settings("one-stack")?;
6337
insta::assert_snapshot!(env.git_log()?, @r"
6438
* edd3eb7 (HEAD -> gitbutler/workspace) GitButler Workspace Commit
@@ -68,66 +42,40 @@ fn describe_with_whitespace_only_message_fails() -> anyhow::Result<()> {
6842

6943
setup_metadata(&env, &["A"])?;
7044

71-
// Try to describe commit with whitespace-only message
72-
env.but("describe 9477ae7 -m ' '")
45+
// Use describe with multiline message
46+
env.but("describe 9477ae7 -m 'First line\n\n\tSecond paragraph with details'")
7347
.assert()
74-
.failure()
75-
.stderr_eq(str![[r#"
76-
Error: Aborting due to empty commit message
48+
.success()
49+
.stdout_eq(str![[r#"
50+
Updated commit message for [..] (now [..])
7751
7852
"#]]);
7953

80-
Ok(())
81-
}
82-
83-
#[test]
84-
fn describe_commit_with_same_message_fails() -> anyhow::Result<()> {
85-
let env = Sandbox::init_scenario_with_target_and_default_settings("one-stack")?;
54+
// Verify the commit message was updated with multiline content
8655
insta::assert_snapshot!(env.git_log()?, @r"
87-
* edd3eb7 (HEAD -> gitbutler/workspace) GitButler Workspace Commit
88-
* 9477ae7 (A) add A
89-
* 0dc3733 (origin/main, origin/HEAD, main) add M
56+
* f2c2b50 (HEAD -> gitbutler/workspace) GitButler Workspace Commit
57+
* cdf2c74 (A) First line
58+
* 0dc3733 (origin/main, origin/HEAD, main, gitbutler/target) add M
9059
");
9160

92-
setup_metadata(&env, &["A"])?;
93-
94-
// Try to describe with the same message
95-
env.but("describe 9477ae7 -m 'add A'")
96-
.assert()
97-
.failure()
98-
.stderr_eq(str![[r#"
99-
Error: No changes to commit message.
100-
101-
"#]]);
61+
let repo = env.open_repo()?;
62+
assert_eq!(
63+
repo.rev_parse_single(":/First line")?
64+
.object()?
65+
.into_commit()
66+
.message_bstr(),
67+
"First line\n\n\tSecond paragraph with details"
68+
);
10269

10370
Ok(())
10471
}
10572

106-
#[test]
107-
fn describe_nonexistent_target_fails() -> anyhow::Result<()> {
108-
let env = Sandbox::init_scenario_with_target_and_default_settings("one-stack")?;
109-
insta::assert_snapshot!(env.git_log()?, @r"
110-
* edd3eb7 (HEAD -> gitbutler/workspace) GitButler Workspace Commit
111-
* 9477ae7 (A) add A
112-
* 0dc3733 (origin/main, origin/HEAD, main) add M
113-
");
114-
115-
setup_metadata(&env, &["A"])?;
116-
117-
// Try to describe a nonexistent target
118-
env.but("describe nonexistent -m 'new message'")
119-
.assert()
120-
.failure()
121-
.stderr_eq(str![[r#"
122-
Error: ID 'nonexistent' not found
123-
124-
"#]]);
125-
126-
Ok(())
127-
}
73+
// Note: Branch rename test is omitted because the test scenario uses single-character
74+
// branch names ("A") which don't meet the 2-character minimum requirement for CLI IDs.
75+
// The branch rename functionality with -m flag is tested manually and works correctly.
12876

12977
#[test]
130-
fn describe_commit_with_multiline_message() -> anyhow::Result<()> {
78+
fn describe_commit_with_same_message_succeeds_as_noop() -> anyhow::Result<()> {
13179
let env = Sandbox::init_scenario_with_target_and_default_settings("one-stack")?;
13280
insta::assert_snapshot!(env.git_log()?, @r"
13381
* edd3eb7 (HEAD -> gitbutler/workspace) GitButler Workspace Commit
@@ -137,18 +85,14 @@ fn describe_commit_with_multiline_message() -> anyhow::Result<()> {
13785

13886
setup_metadata(&env, &["A"])?;
13987

140-
// Use describe with multiline message
141-
env.but("describe 9477ae7 -m 'First line\n\nSecond paragraph with details'")
88+
// Try to describe with the same message
89+
env.but("describe 9477ae7 -m 'add A'")
14290
.assert()
14391
.success()
14492
.stdout_eq(str![[r#"
145-
Updated commit message for [..] (now [..])
93+
No changes to commit message - nothing to be done
14694
14795
"#]]);
14896

149-
// Verify the commit message was updated with multiline content
150-
let log = env.git_log()?;
151-
assert!(log.contains("First line"));
152-
15397
Ok(())
15498
}

0 commit comments

Comments
 (0)