mirror of
https://github.com/jj-vcs/jj.git
synced 2026-07-03 14:02:54 +08:00
Mostly done with OpenCode and Claude Sonnet 4.6 with the following prompt, and reviewed manually: Replace the Result.unwrap with the ? operator in test functions. While doing that, make sure to: * Add TestResult as return type in the test functions where you replace unwrap by the ? operator, and Ok(()) at the end. * Do the replacement only in method with the `#[test]` decorator. * Don't replace unwraps in closures. * Don't replace Option.unwrap. * Be careful to not change the insta snapshot references. * Run the tests each time you're done with a file. * Keep the unwraps that you can't replace with the ? operator. Note that: * You can identify all the Result.unwrap locations with this command: cargo clippy --tests --message-format=short -- -W clippy::unwrap_used 2>&1 | grep / | grep Result | grep <filename> * Begin with the file with the most Result.unwrap in them as shown by this command: cargo clippy --tests --message-format=short -- -W clippy::unwrap_used 2>&1 | grep Result | cut -d: -f1 | sort | uniq -c | sort -nr * Some non test files have inline tests. Before this PR: ❯ cargo clippy --tests --message-format=short -- -W clippy::unwrap_used 2>&1 | grep Result | wc -l 3973 After this PR: ❯ cargo clippy --tests --message-format=short -- -W clippy::unwrap_used 2>&1 | grep Result | wc -l 1064
383 lines
12 KiB
Rust
383 lines
12 KiB
Rust
// Copyright 2025 The Jujutsu Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// https://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
use testutils::TestResult;
|
|
|
|
use crate::common::CommandOutput;
|
|
use crate::common::TestEnvironment;
|
|
use crate::common::TestWorkDir;
|
|
|
|
#[must_use]
|
|
fn get_colocation_status(work_dir: &TestWorkDir) -> CommandOutput {
|
|
work_dir.run_jj([
|
|
"git",
|
|
"colocation",
|
|
"status",
|
|
"--ignore-working-copy",
|
|
"--quiet", // suppress hint
|
|
])
|
|
}
|
|
|
|
fn read_git_target(workspace_root: &std::path::Path) -> String {
|
|
let mut path = workspace_root.to_path_buf();
|
|
path.extend([".jj", "repo", "store", "git_target"]);
|
|
std::fs::read_to_string(path).unwrap()
|
|
}
|
|
|
|
#[test]
|
|
fn test_git_colocation_enable_success() -> TestResult {
|
|
let test_env = TestEnvironment::default();
|
|
|
|
// Initialize a non-colocated Jujutsu/Git workspace
|
|
test_env
|
|
.run_jj_in(
|
|
test_env.env_root(),
|
|
["git", "init", "--no-colocate", "repo"],
|
|
)
|
|
.success();
|
|
let work_dir = test_env.work_dir("repo");
|
|
let workspace_root = work_dir.root();
|
|
|
|
// Need at least one commit to be able to set git HEAD later
|
|
work_dir.run_jj(["new"]).success();
|
|
|
|
// Verify it's not colocated initially
|
|
assert!(!workspace_root.join(".git").exists());
|
|
assert_eq!(read_git_target(workspace_root), "git");
|
|
|
|
// And that there is no Git HEAD yet
|
|
insta::assert_snapshot!(get_colocation_status(&work_dir), @"
|
|
Workspace is currently not colocated with Git.
|
|
Last imported/exported Git HEAD: (none)
|
|
[EOF]
|
|
");
|
|
|
|
// Run colocate command
|
|
let output = work_dir.run_jj(["git", "colocation", "enable"]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
Workspace successfully converted into a colocated Jujutsu/Git workspace.
|
|
[EOF]
|
|
");
|
|
|
|
// Verify colocate succeeded
|
|
assert!(workspace_root.join(".git").exists());
|
|
assert!(
|
|
!workspace_root
|
|
.join(".jj")
|
|
.join("repo")
|
|
.join("store")
|
|
.join("git")
|
|
.exists()
|
|
);
|
|
assert_eq!(read_git_target(workspace_root), "../../../.git");
|
|
|
|
// Verify .jj/.gitignore was created
|
|
let gitignore_content = std::fs::read_to_string(workspace_root.join(".jj").join(".gitignore"))?;
|
|
assert_eq!(gitignore_content, "/*\n");
|
|
|
|
// Verify that Git HEAD was set correctly
|
|
insta::assert_snapshot!(get_colocation_status(&work_dir), @"
|
|
Workspace is currently colocated with Git.
|
|
Last imported/exported Git HEAD: e8849ae12c709f2321908879bc724fdb2ab8a781
|
|
[EOF]
|
|
");
|
|
|
|
// Verify that the repo changed
|
|
let output = work_dir.run_jj(["op", "show", "-T", "description ++ '\n'"]);
|
|
insta::assert_snapshot!(output, @"
|
|
set git head to working copy parent
|
|
[EOF]
|
|
");
|
|
Ok(())
|
|
}
|
|
|
|
#[test]
|
|
fn test_git_colocation_enable_empty() {
|
|
let test_env = TestEnvironment::default();
|
|
|
|
// Initialize a non-colocated Jujutsu/Git workspace
|
|
test_env
|
|
.run_jj_in(
|
|
test_env.env_root(),
|
|
["git", "init", "--no-colocate", "repo"],
|
|
)
|
|
.success();
|
|
let work_dir = test_env.work_dir("repo");
|
|
let setup_op_id = work_dir.current_operation_id();
|
|
|
|
// Run colocate command
|
|
let output = work_dir.run_jj(["git", "colocation", "enable"]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
Workspace successfully converted into a colocated Jujutsu/Git workspace.
|
|
[EOF]
|
|
");
|
|
|
|
// Verify that Git HEAD was set correctly
|
|
insta::assert_snapshot!(get_colocation_status(&work_dir), @"
|
|
Workspace is currently colocated with Git.
|
|
Last imported/exported Git HEAD: (none)
|
|
[EOF]
|
|
");
|
|
|
|
// No repo change required
|
|
assert_eq!(setup_op_id, work_dir.current_operation_id());
|
|
}
|
|
|
|
#[test]
|
|
fn test_git_colocation_enable_already_colocated() {
|
|
let test_env = TestEnvironment::default();
|
|
|
|
// Initialize a colocated Jujutsu/Git repo
|
|
test_env
|
|
.run_jj_in(test_env.env_root(), ["git", "init", "--colocate", "repo"])
|
|
.success();
|
|
let work_dir = test_env.work_dir("repo");
|
|
|
|
// Try to colocate it again - should fail
|
|
let output = work_dir.run_jj(["git", "colocation", "enable"]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
Workspace is already colocated with Git.
|
|
[EOF]
|
|
");
|
|
}
|
|
|
|
#[test]
|
|
fn test_git_colocation_enable_with_existing_git_dir() -> TestResult {
|
|
let test_env = TestEnvironment::default();
|
|
|
|
// Initialize a non-colocated Jujutsu/Git repo
|
|
test_env
|
|
.run_jj_in(
|
|
test_env.env_root(),
|
|
["git", "init", "--no-colocate", "repo"],
|
|
)
|
|
.success();
|
|
let work_dir = test_env.work_dir("repo");
|
|
let workspace_root = work_dir.root();
|
|
|
|
// Create a .git directory manually
|
|
std::fs::create_dir(workspace_root.join(".git"))?;
|
|
std::fs::write(workspace_root.join(".git").join("dummy"), "dummy")?;
|
|
|
|
// Try to colocate - should fail
|
|
let output = work_dir.run_jj(["git", "colocation", "enable"]);
|
|
insta::assert_snapshot!(output.strip_stderr_last_line(), @"
|
|
------- stderr -------
|
|
Error: A .git directory already exists in the workspace root. Cannot colocate.
|
|
[EOF]
|
|
[exit status: 1]
|
|
");
|
|
Ok(())
|
|
}
|
|
|
|
#[test]
|
|
fn test_git_colocation_disable_success() {
|
|
let test_env = TestEnvironment::default();
|
|
|
|
// Create a colocated Jujutsu/Git repo
|
|
test_env
|
|
.run_jj_in(test_env.env_root(), ["git", "init", "--colocate", "repo"])
|
|
.success();
|
|
let work_dir = test_env.work_dir("repo");
|
|
let workspace_root = work_dir.root();
|
|
|
|
// Need at least one commit to be able to set git HEAD later
|
|
work_dir.run_jj(["new"]).success();
|
|
|
|
// Verify that Git HEAD is set
|
|
insta::assert_snapshot!(get_colocation_status(&work_dir), @"
|
|
Workspace is currently colocated with Git.
|
|
Last imported/exported Git HEAD: e8849ae12c709f2321908879bc724fdb2ab8a781
|
|
[EOF]
|
|
");
|
|
|
|
// Verify it's colocated
|
|
assert!(workspace_root.join(".git").exists());
|
|
assert_eq!(read_git_target(workspace_root), "../../../.git");
|
|
|
|
// Disable colocation
|
|
let output = work_dir.run_jj(["git", "colocation", "disable"]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
Workspace successfully converted into a non-colocated Jujutsu/Git workspace.
|
|
[EOF]
|
|
");
|
|
|
|
// Verify that disable colocation succeeded
|
|
assert!(!workspace_root.join(".git").exists());
|
|
assert!(
|
|
workspace_root
|
|
.join(".jj")
|
|
.join("repo")
|
|
.join("store")
|
|
.join("git")
|
|
.exists()
|
|
);
|
|
assert_eq!(read_git_target(workspace_root), "git");
|
|
assert!(!workspace_root.join(".jj").join(".gitignore").exists());
|
|
|
|
// Verify that Git HEAD was removed correctly
|
|
insta::assert_snapshot!(get_colocation_status(&work_dir), @"
|
|
Workspace is currently not colocated with Git.
|
|
Last imported/exported Git HEAD: (none)
|
|
[EOF]
|
|
");
|
|
|
|
// Verify that the repo changed
|
|
let output = work_dir.run_jj(["op", "show", "-T", "description ++ '\n'"]);
|
|
insta::assert_snapshot!(output, @"
|
|
remove git head reference
|
|
[EOF]
|
|
");
|
|
}
|
|
|
|
#[test]
|
|
fn test_git_colocation_disable_empty() {
|
|
let test_env = TestEnvironment::default();
|
|
|
|
// Create a colocated Jujutsu/Git repo
|
|
test_env
|
|
.run_jj_in(test_env.env_root(), ["git", "init", "--colocate", "repo"])
|
|
.success();
|
|
let work_dir = test_env.work_dir("repo");
|
|
let setup_op_id = work_dir.current_operation_id();
|
|
|
|
// Verify that Git HEAD is unset
|
|
insta::assert_snapshot!(get_colocation_status(&work_dir), @"
|
|
Workspace is currently colocated with Git.
|
|
Last imported/exported Git HEAD: (none)
|
|
[EOF]
|
|
");
|
|
|
|
// Disable colocation
|
|
let output = work_dir.run_jj(["git", "colocation", "disable"]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
Workspace successfully converted into a non-colocated Jujutsu/Git workspace.
|
|
[EOF]
|
|
");
|
|
|
|
// No repo change required
|
|
assert_eq!(setup_op_id, work_dir.current_operation_id());
|
|
}
|
|
|
|
#[test]
|
|
fn test_git_colocation_disable_not_colocated() {
|
|
let test_env = TestEnvironment::default();
|
|
|
|
// Initialize a non-colocated Jujutsu/Git repo
|
|
test_env
|
|
.run_jj_in(
|
|
test_env.env_root(),
|
|
["git", "init", "--no-colocate", "repo"],
|
|
)
|
|
.success();
|
|
let work_dir = test_env.work_dir("repo");
|
|
|
|
// Try to disable colocation when not colocated - should fail
|
|
let output = work_dir.run_jj(["git", "colocation", "disable"]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
Workspace is already not colocated with Git.
|
|
[EOF]
|
|
");
|
|
}
|
|
|
|
#[test]
|
|
fn test_git_colocation_status_non_colocated() {
|
|
let test_env = TestEnvironment::default();
|
|
|
|
// Initialize a non-colocated Jujutsu/Git repo
|
|
test_env
|
|
.run_jj_in(
|
|
test_env.env_root(),
|
|
["git", "init", "--no-colocate", "repo"],
|
|
)
|
|
.success();
|
|
let work_dir = test_env.work_dir("repo");
|
|
|
|
// Check status - should show non-colocated
|
|
let output = work_dir.run_jj(["git", "colocation", "status"]);
|
|
insta::assert_snapshot!(output, @"
|
|
Workspace is currently not colocated with Git.
|
|
Last imported/exported Git HEAD: (none)
|
|
[EOF]
|
|
------- stderr -------
|
|
Hint: To enable colocation, run: `jj git colocation enable`
|
|
[EOF]
|
|
");
|
|
}
|
|
|
|
#[test]
|
|
fn test_git_colocation_status_colocated() {
|
|
let test_env = TestEnvironment::default();
|
|
|
|
// Initialize a colocated jj repo
|
|
test_env
|
|
.run_jj_in(test_env.env_root(), ["git", "init", "--colocate", "repo"])
|
|
.success();
|
|
let work_dir = test_env.work_dir("repo");
|
|
|
|
// Check status - should show colocated
|
|
let output = work_dir.run_jj(["git", "colocation", "status"]);
|
|
insta::assert_snapshot!(output, @"
|
|
Workspace is currently colocated with Git.
|
|
Last imported/exported Git HEAD: (none)
|
|
[EOF]
|
|
------- stderr -------
|
|
Hint: To disable colocation, run: `jj git colocation disable`
|
|
[EOF]
|
|
");
|
|
}
|
|
|
|
#[test]
|
|
fn test_git_colocation_in_secondary_workspace() {
|
|
let test_env = TestEnvironment::default();
|
|
test_env
|
|
.run_jj_in(".", ["git", "init", "--no-colocate", "main"])
|
|
.success();
|
|
let main_dir = test_env.work_dir("main");
|
|
main_dir
|
|
.run_jj(["workspace", "add", "../secondary"])
|
|
.success();
|
|
let secondary_dir = test_env.work_dir("secondary");
|
|
|
|
let output = secondary_dir.run_jj(["git", "colocation", "status"]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
Error: This command cannot be used in a non-main Jujutsu workspace
|
|
[EOF]
|
|
[exit status: 1]
|
|
");
|
|
|
|
let output = secondary_dir.run_jj(["git", "colocation", "enable"]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
Error: This command cannot be used in a non-main Jujutsu workspace
|
|
[EOF]
|
|
[exit status: 1]
|
|
");
|
|
|
|
let output = secondary_dir.run_jj(["git", "colocation", "disable"]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
Error: This command cannot be used in a non-main Jujutsu workspace
|
|
[EOF]
|
|
[exit status: 1]
|
|
");
|
|
}
|