// Copyright 2022 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 insta::assert_snapshot;use regex::Regex; use crate::common::CommandOutput;use crate::common::TestEnvironment; #[test]fn test_debug_fileset() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); let output = work_dir.run_jj(["debug", "fileset", "all()"]); assert_snapshot!(output, @" -- Parsed: All -- Matcher: EverythingMatcher [EOF] "); let output = work_dir.run_jj(["debug", "fileset", "cwd:.."]); assert_snapshot!(output.normalize_backslash(), @r#" ------- stderr ------- Error: Failed to parse fileset: Invalid file pattern Caused by: 1: --> 1:1 | 1 | cwd:.. | ^----^ | = Invalid file pattern 2: Path ".." is not in the repo "." 3: Invalid component ".." in repo-relative path "../" [EOF] [exit status: 1] "#);} #[test]fn test_debug_revset() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); let mut insta_settings = insta::Settings::clone_current(); insta_settings.add_filter(r"(?m)(^ .*\n)+", " ..\n"); let _guard = insta_settings.bind_to_scope(); let output = work_dir.run_jj(["debug", "revset", "root()"]); assert_snapshot!(output, @" -- Parsed: Root -- Resolved: Root -- Optimized: Root -- Backend: Commits( .. ) -- Evaluated: RevsetImpl { .. } -- Commit IDs: 0000000000000000000000000000000000000000 [EOF] "); let output = work_dir.run_jj(["debug", "revset", "--no-optimize", "root() & ~@"]); assert_snapshot!(output, @" -- Parsed: Intersection( .. ) -- Resolved: Intersection( .. ) -- Backend: Intersection( .. ) -- Evaluated: RevsetImpl { .. } -- Commit IDs: 0000000000000000000000000000000000000000 [EOF] "); let output = work_dir.run_jj(["debug", "revset", "--no-resolve", "foo & ~bar"]); assert_snapshot!(output, @" -- Parsed: Intersection( .. ) -- Optimized: Difference( .. ) [EOF] "); let output = work_dir.run_jj([ "debug", "revset", "--no-resolve", "--no-optimize", "foo & ~bar", ]); assert_snapshot!(output, @" -- Parsed: Intersection( .. ) [EOF] ");} #[test]fn test_debug_index() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); let output = work_dir.run_jj(["debug", "index"]); assert_snapshot!(filter_index_stats(output), @" === Commits === Number of commits: 2 Number of merges: 0 Max generation number: 1 Number of heads: 1 Number of changes: 2 Stats per level: Level 0: Number of commits: 2 Name: [hash] === Changed paths === Indexed commits: none Stats per level: [EOF] "); // Enable changed-path index, index one commit let output = work_dir.run_jj(["debug", "index-changed-paths", "-n1"]); assert_snapshot!(output, @" ------- stderr ------- Finished indexing 1..2 commits. [EOF] "); let output = work_dir.run_jj(["debug", "index"]); assert_snapshot!(filter_index_stats(output), @" === Commits === Number of commits: 2 Number of merges: 0 Max generation number: 1 Number of heads: 1 Number of changes: 2 Stats per level: Level 0: Number of commits: 2 Name: [hash] === Changed paths === Indexed commits: 1..2 Stats per level: Level 0: Number of commits: 1 Number of changed paths: 0 Number of paths: 0 Name: [hash] [EOF] ");} #[test]fn test_debug_reindex() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); work_dir.run_jj(["new"]).success(); work_dir.run_jj(["new"]).success(); let output = work_dir.run_jj(["debug", "index"]); assert_snapshot!(filter_index_stats(output), @" === Commits === Number of commits: 4 Number of merges: 0 Max generation number: 3 Number of heads: 1 Number of changes: 4 Stats per level: Level 0: Number of commits: 3 Name: [hash] Level 1: Number of commits: 1 Name: [hash] === Changed paths === Indexed commits: none Stats per level: [EOF] "); let output = work_dir.run_jj(["debug", "reindex"]); insta::assert_snapshot!(output, @" ------- stderr ------- Finished indexing 4 commits. [EOF] "); let output = work_dir.run_jj(["debug", "index"]); assert_snapshot!(filter_index_stats(output), @" === Commits === Number of commits: 4 Number of merges: 0 Max generation number: 3 Number of heads: 1 Number of changes: 4 Stats per level: Level 0: Number of commits: 4 Name: [hash] === Changed paths === Indexed commits: none Stats per level: [EOF] ");} #[test]fn test_debug_stacked_table() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); work_dir.run_jj(["new"]).success(); work_dir.run_jj(["new"]).success(); work_dir.run_jj(["new"]).success(); let output = work_dir.run_jj([ "debug", "stacked-table", ".jj/repo/store/extra", "--key-size=20", // HASH_LENGTH ]); assert_snapshot!(filter_index_stats(output), @" Number of entries: 4 Stats per level: Level 0: Number of entries: 3 Name: [hash] Level 1: Number of entries: 1 Name: [hash] [EOF] ");} #[test]fn test_debug_tree() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); let sub_dir = work_dir.create_dir_all("dir/subdir"); sub_dir.write_file("file1", "contents 1"); work_dir.run_jj(["new"]).success(); sub_dir.write_file("file2", "contents 2"); // Defaults to showing the tree at the current commit let output = work_dir.run_jj(["debug", "tree"]); assert_snapshot!(output.normalize_backslash(), @r#" dir/subdir/file1: Ok(Resolved(Some(File { id: FileId("498e9b01d79cb8d31cdf0df1a663cc1fcefd9de3"), executable: false, copy_id: CopyId("") }))) dir/subdir/file2: Ok(Resolved(Some(File { id: FileId("b2496eaffe394cd50a9db4de5787f45f09fd9722"), executable: false, copy_id: CopyId("") }))) [EOF] "# ); // Can show the tree at another commit let output = work_dir.run_jj(["debug", "tree", "-r@-"]); assert_snapshot!(output.normalize_backslash(), @r#" dir/subdir/file1: Ok(Resolved(Some(File { id: FileId("498e9b01d79cb8d31cdf0df1a663cc1fcefd9de3"), executable: false, copy_id: CopyId("") }))) [EOF] "# ); // Can filter by paths let output = work_dir.run_jj(["debug", "tree", "dir/subdir/file2"]); assert_snapshot!(output.normalize_backslash(), @r#" dir/subdir/file2: Ok(Resolved(Some(File { id: FileId("b2496eaffe394cd50a9db4de5787f45f09fd9722"), executable: false, copy_id: CopyId("") }))) [EOF] "# ); // Can a show the root tree by id let output = work_dir.run_jj([ "debug", "tree", "--id=0958358e3f80e794f032b25ed2be96cf5825da6c", ]); assert_snapshot!(output.normalize_backslash(), @r#" dir/subdir/file1: Ok(Resolved(Some(File { id: FileId("498e9b01d79cb8d31cdf0df1a663cc1fcefd9de3"), executable: false, copy_id: CopyId("") }))) dir/subdir/file2: Ok(Resolved(Some(File { id: FileId("b2496eaffe394cd50a9db4de5787f45f09fd9722"), executable: false, copy_id: CopyId("") }))) [EOF] "# ); // Can a show non-root tree by id let output = work_dir.run_jj([ "debug", "tree", "--dir=dir", "--id=6ac232efa713535ae518a1a898b77e76c0478184", ]); assert_snapshot!(output.normalize_backslash(), @r#" dir/subdir/file1: Ok(Resolved(Some(File { id: FileId("498e9b01d79cb8d31cdf0df1a663cc1fcefd9de3"), executable: false, copy_id: CopyId("") }))) dir/subdir/file2: Ok(Resolved(Some(File { id: FileId("b2496eaffe394cd50a9db4de5787f45f09fd9722"), executable: false, copy_id: CopyId("") }))) [EOF] "# ); // Can filter by paths when showing non-root tree (matcher applies from root) let output = work_dir.run_jj([ "debug", "tree", "--dir=dir", "--id=6ac232efa713535ae518a1a898b77e76c0478184", "dir/subdir/file2", ]); assert_snapshot!(output.normalize_backslash(), @r#" dir/subdir/file2: Ok(Resolved(Some(File { id: FileId("b2496eaffe394cd50a9db4de5787f45f09fd9722"), executable: false, copy_id: CopyId("") }))) [EOF] "# );} fn filter_index_stats(output: CommandOutput) -> CommandOutput { let regex = Regex::new(r" Name: [0-9a-z]+").unwrap(); output.normalize_stdout_with(|text| regex.replace_all(&text, " Name: [hash]").into_owned())}
// Copyright 2022 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 insta::assert_snapshot;
use regex::Regex;
use crate::common::CommandOutput;
use crate::common::TestEnvironment;
#[test]
fn test_debug_fileset() {
let test_env = TestEnvironment::default();
test_env.run_jj_in(".", ["git", "init", "repo"]).success();
let work_dir = test_env.work_dir("repo");
let output = work_dir.run_jj(["debug", "fileset", "all()"]);
assert_snapshot!(output, @"
-- Parsed:
All
-- Matcher:
EverythingMatcher
[EOF]
");
let output = work_dir.run_jj(["debug", "fileset", "cwd:.."]);
assert_snapshot!(output.normalize_backslash(), @r#"
------- stderr -------
Error: Failed to parse fileset: Invalid file pattern
Caused by:
1: --> 1:1
|
1 | cwd:..
| ^----^
|
= Invalid file pattern
2: Path ".." is not in the repo "."
3: Invalid component ".." in repo-relative path "../"
[EOF]
[exit status: 1]
"#);
}
#[test]
fn test_debug_revset() {
let test_env = TestEnvironment::default();
test_env.run_jj_in(".", ["git", "init", "repo"]).success();
let work_dir = test_env.work_dir("repo");
let mut insta_settings = insta::Settings::clone_current();
insta_settings.add_filter(r"(?m)(^ .*\n)+", " ..\n");
let _guard = insta_settings.bind_to_scope();
let output = work_dir.run_jj(["debug", "revset", "root()"]);
assert_snapshot!(output, @"
-- Parsed:
Root
-- Resolved:
Root
-- Optimized:
Root
-- Backend:
Commits(
..
)
-- Evaluated:
RevsetImpl {
..
}
-- Commit IDs:
0000000000000000000000000000000000000000
[EOF]
");
let output = work_dir.run_jj(["debug", "revset", "--no-optimize", "root() & ~@"]);
assert_snapshot!(output, @"
-- Parsed:
Intersection(
..
)
-- Resolved:
Intersection(
..
)
-- Backend:
Intersection(
..
)
-- Evaluated:
RevsetImpl {
..
}
-- Commit IDs:
0000000000000000000000000000000000000000
[EOF]
");
let output = work_dir.run_jj(["debug", "revset", "--no-resolve", "foo & ~bar"]);
assert_snapshot!(output, @"
-- Parsed:
Intersection(
..
)
-- Optimized:
Difference(
..
)
[EOF]
");
let output = work_dir.run_jj([
"debug",
"revset",
"--no-resolve",
"--no-optimize",
"foo & ~bar",
]);
assert_snapshot!(output, @"
-- Parsed:
Intersection(
..
)
[EOF]
");
}
#[test]
fn test_debug_index() {
let test_env = TestEnvironment::default();
test_env.run_jj_in(".", ["git", "init", "repo"]).success();
let work_dir = test_env.work_dir("repo");
let output = work_dir.run_jj(["debug", "index"]);
assert_snapshot!(filter_index_stats(output), @"
=== Commits ===
Number of commits: 2
Number of merges: 0
Max generation number: 1
Number of heads: 1
Number of changes: 2
Stats per level:
Level 0:
Number of commits: 2
Name: [hash]
=== Changed paths ===
Indexed commits: none
Stats per level:
[EOF]
");
// Enable changed-path index, index one commit
let output = work_dir.run_jj(["debug", "index-changed-paths", "-n1"]);
assert_snapshot!(output, @"
------- stderr -------
Finished indexing 1..2 commits.
[EOF]
");
let output = work_dir.run_jj(["debug", "index"]);
assert_snapshot!(filter_index_stats(output), @"
=== Commits ===
Number of commits: 2
Number of merges: 0
Max generation number: 1
Number of heads: 1
Number of changes: 2
Stats per level:
Level 0:
Number of commits: 2
Name: [hash]
=== Changed paths ===
Indexed commits: 1..2
Stats per level:
Level 0:
Number of commits: 1
Number of changed paths: 0
Number of paths: 0
Name: [hash]
[EOF]
");
}
#[test]
fn test_debug_reindex() {
let test_env = TestEnvironment::default();
test_env.run_jj_in(".", ["git", "init", "repo"]).success();
let work_dir = test_env.work_dir("repo");
work_dir.run_jj(["new"]).success();
work_dir.run_jj(["new"]).success();
let output = work_dir.run_jj(["debug", "index"]);
assert_snapshot!(filter_index_stats(output), @"
=== Commits ===
Number of commits: 4
Number of merges: 0
Max generation number: 3
Number of heads: 1
Number of changes: 4
Stats per level:
Level 0:
Number of commits: 3
Name: [hash]
Level 1:
Number of commits: 1
Name: [hash]
=== Changed paths ===
Indexed commits: none
Stats per level:
[EOF]
");
let output = work_dir.run_jj(["debug", "reindex"]);
insta::assert_snapshot!(output, @"
------- stderr -------
Finished indexing 4 commits.
[EOF]
");
let output = work_dir.run_jj(["debug", "index"]);
assert_snapshot!(filter_index_stats(output), @"
=== Commits ===
Number of commits: 4
Number of merges: 0
Max generation number: 3
Number of heads: 1
Number of changes: 4
Stats per level:
Level 0:
Number of commits: 4
Name: [hash]
=== Changed paths ===
Indexed commits: none
Stats per level:
[EOF]
");
}
#[test]
fn test_debug_stacked_table() {
let test_env = TestEnvironment::default();
test_env.run_jj_in(".", ["git", "init", "repo"]).success();
let work_dir = test_env.work_dir("repo");
work_dir.run_jj(["new"]).success();
work_dir.run_jj(["new"]).success();
work_dir.run_jj(["new"]).success();
let output = work_dir.run_jj([
"debug",
"stacked-table",
".jj/repo/store/extra",
"--key-size=20", // HASH_LENGTH
]);
assert_snapshot!(filter_index_stats(output), @"
Number of entries: 4
Stats per level:
Level 0:
Number of entries: 3
Name: [hash]
Level 1:
Number of entries: 1
Name: [hash]
[EOF]
");
}
#[test]
fn test_debug_tree() {
let test_env = TestEnvironment::default();
test_env.run_jj_in(".", ["git", "init", "repo"]).success();
let work_dir = test_env.work_dir("repo");
let sub_dir = work_dir.create_dir_all("dir/subdir");
sub_dir.write_file("file1", "contents 1");
work_dir.run_jj(["new"]).success();
sub_dir.write_file("file2", "contents 2");
// Defaults to showing the tree at the current commit
let output = work_dir.run_jj(["debug", "tree"]);
assert_snapshot!(output.normalize_backslash(), @r#"
dir/subdir/file1: Ok(Resolved(Some(File { id: FileId("498e9b01d79cb8d31cdf0df1a663cc1fcefd9de3"), executable: false, copy_id: CopyId("") })))
dir/subdir/file2: Ok(Resolved(Some(File { id: FileId("b2496eaffe394cd50a9db4de5787f45f09fd9722"), executable: false, copy_id: CopyId("") })))
[EOF]
"#
);
// Can show the tree at another commit
let output = work_dir.run_jj(["debug", "tree", "-r@-"]);
assert_snapshot!(output.normalize_backslash(), @r#"
dir/subdir/file1: Ok(Resolved(Some(File { id: FileId("498e9b01d79cb8d31cdf0df1a663cc1fcefd9de3"), executable: false, copy_id: CopyId("") })))
[EOF]
"#
);
// Can filter by paths
let output = work_dir.run_jj(["debug", "tree", "dir/subdir/file2"]);
assert_snapshot!(output.normalize_backslash(), @r#"
dir/subdir/file2: Ok(Resolved(Some(File { id: FileId("b2496eaffe394cd50a9db4de5787f45f09fd9722"), executable: false, copy_id: CopyId("") })))
[EOF]
"#
);
// Can a show the root tree by id
let output = work_dir.run_jj([
"debug",
"tree",
"--id=0958358e3f80e794f032b25ed2be96cf5825da6c",
]);
assert_snapshot!(output.normalize_backslash(), @r#"
dir/subdir/file1: Ok(Resolved(Some(File { id: FileId("498e9b01d79cb8d31cdf0df1a663cc1fcefd9de3"), executable: false, copy_id: CopyId("") })))
dir/subdir/file2: Ok(Resolved(Some(File { id: FileId("b2496eaffe394cd50a9db4de5787f45f09fd9722"), executable: false, copy_id: CopyId("") })))
[EOF]
"#
);
// Can a show non-root tree by id
let output = work_dir.run_jj([
"debug",
"tree",
"--dir=dir",
"--id=6ac232efa713535ae518a1a898b77e76c0478184",
]);
assert_snapshot!(output.normalize_backslash(), @r#"
dir/subdir/file1: Ok(Resolved(Some(File { id: FileId("498e9b01d79cb8d31cdf0df1a663cc1fcefd9de3"), executable: false, copy_id: CopyId("") })))
dir/subdir/file2: Ok(Resolved(Some(File { id: FileId("b2496eaffe394cd50a9db4de5787f45f09fd9722"), executable: false, copy_id: CopyId("") })))
[EOF]
"#
);
// Can filter by paths when showing non-root tree (matcher applies from root)
let output = work_dir.run_jj([
"debug",
"tree",
"--dir=dir",
"--id=6ac232efa713535ae518a1a898b77e76c0478184",
"dir/subdir/file2",
]);
assert_snapshot!(output.normalize_backslash(), @r#"
dir/subdir/file2: Ok(Resolved(Some(File { id: FileId("b2496eaffe394cd50a9db4de5787f45f09fd9722"), executable: false, copy_id: CopyId("") })))
[EOF]
"#
);
}
fn filter_index_stats(output: CommandOutput) -> CommandOutput {
let regex = Regex::new(r" Name: [0-9a-z]+").unwrap();
output.normalize_stdout_with(|text| regex.replace_all(&text, " Name: [hash]").into_owned())
}