Skip to content

Commit

Permalink
tests: add basic tests for annotation function
Browse files Browse the repository at this point in the history
  • Loading branch information
yuja committed Oct 27, 2024
1 parent f6db242 commit b485881
Show file tree
Hide file tree
Showing 2 changed files with 249 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/tests/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ fn test_no_forgotten_test_files() {
testutils::assert_no_forgotten_test_files(&test_dir);
}

mod test_annotate;
mod test_bad_locking;
mod test_commit_builder;
mod test_commit_concurrent;
Expand Down
248 changes: 248 additions & 0 deletions lib/tests/test_annotate.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
// Copyright 2024 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 std::fmt::Write as _;

use jj_lib::annotate::get_annotation_for_file;
use jj_lib::backend::CommitId;
use jj_lib::backend::MergedTreeId;
use jj_lib::backend::MillisSinceEpoch;
use jj_lib::backend::Signature;
use jj_lib::backend::Timestamp;
use jj_lib::commit::Commit;
use jj_lib::repo::MutableRepo;
use jj_lib::repo::Repo;
use jj_lib::repo_path::RepoPath;
use jj_lib::settings::UserSettings;
use testutils::create_tree;
use testutils::TestRepo;

fn create_commit_fn<'a>(
mut_repo: &'a mut MutableRepo,
settings: &'a UserSettings,
) -> impl FnMut(&str, &[&CommitId], MergedTreeId) -> Commit + 'a {
// stabilize commit IDs for ease of debugging
let signature = Signature {
name: "Some One".to_owned(),
email: "[email protected]".to_owned(),
timestamp: Timestamp {
timestamp: MillisSinceEpoch(0),
tz_offset: 0,
},
};
move |description, parent_ids, tree_id| {
let parent_ids = parent_ids.iter().map(|&id| id.clone()).collect();
mut_repo
.new_commit(settings, parent_ids, tree_id)
.set_author(signature.clone())
.set_committer(signature.clone())
.set_description(description)
.write()
.unwrap()
}
}

fn annotate(repo: &dyn Repo, commit: &Commit, file_path: &RepoPath) -> String {
let annotation = get_annotation_for_file(repo, commit, file_path).unwrap();
let mut output = String::new();
for (commit_id, line) in &annotation.file_annotations {
let commit = repo.store().get_commit(commit_id).unwrap();
let desc = commit.description().trim_end();
write!(output, "{desc}: {line}").unwrap();
}
output
}

#[test]
fn test_annotate_linear() {
let settings = testutils::user_settings();
let test_repo = TestRepo::init();
let repo = &test_repo.repo;

let root_commit_id = repo.store().root_commit_id();
let file_path = RepoPath::from_internal_string("file");

let mut tx = repo.start_transaction(&settings);
let mut create_commit = create_commit_fn(tx.repo_mut(), &settings);
let content1 = "";
let content2 = "2a\n2b\n";
let content3 = "2b\n3\n";
let tree1 = create_tree(repo, &[(file_path, content1)]);
let tree2 = create_tree(repo, &[(file_path, content2)]);
let tree3 = create_tree(repo, &[(file_path, content3)]);
let commit1 = create_commit("commit1", &[root_commit_id], tree1.id());
let commit2 = create_commit("commit2", &[commit1.id()], tree2.id());
let commit3 = create_commit("commit3", &[commit2.id()], tree3.id());
let commit4 = create_commit("commit4", &[commit3.id()], tree3.id()); // empty commit
drop(create_commit);

insta::assert_snapshot!(annotate(tx.repo(), &commit1, file_path), @"");
insta::assert_snapshot!(annotate(tx.repo(), &commit2, file_path), @r#"
commit2: 2a
commit2: 2b
"#);
insta::assert_snapshot!(annotate(tx.repo(), &commit3, file_path), @r#"
commit2: 2b
commit3: 3
"#);
insta::assert_snapshot!(annotate(tx.repo(), &commit4, file_path), @r#"
commit2: 2b
commit3: 3
"#);
}

#[test]
fn test_annotate_merge_simple() {
let settings = testutils::user_settings();
let test_repo = TestRepo::init();
let repo = &test_repo.repo;

let root_commit_id = repo.store().root_commit_id();
let file_path = RepoPath::from_internal_string("file");

// 4 "2 1 3"
// |\
// | 3 "1 3"
// | |
// 2 | "2 1"
// |/
// 1 "1"
let mut tx = repo.start_transaction(&settings);
let mut create_commit = create_commit_fn(tx.repo_mut(), &settings);
let content1 = "1\n";
let content2 = "2\n1\n";
let content3 = "1\n3\n";
let content4 = "2\n1\n3\n";
let tree1 = create_tree(repo, &[(file_path, content1)]);
let tree2 = create_tree(repo, &[(file_path, content2)]);
let tree3 = create_tree(repo, &[(file_path, content3)]);
let tree4 = create_tree(repo, &[(file_path, content4)]);
let commit1 = create_commit("commit1", &[root_commit_id], tree1.id());
let commit2 = create_commit("commit2", &[commit1.id()], tree2.id());
let commit3 = create_commit("commit3", &[commit1.id()], tree3.id());
let commit4 = create_commit("commit4", &[commit2.id(), commit3.id()], tree4.id());
drop(create_commit);

insta::assert_snapshot!(annotate(tx.repo(), &commit4, file_path), @r#"
commit2: 2
commit1: 1
commit3: 3
"#);
}

#[test]
fn test_annotate_merge_split() {
let settings = testutils::user_settings();
let test_repo = TestRepo::init();
let repo = &test_repo.repo;

let root_commit_id = repo.store().root_commit_id();
let file_path = RepoPath::from_internal_string("file");

// 4 "2 1a 1b 3 4"
// |\
// | 3 "1b 3"
// | |
// 2 | "2 1a"
// |/
// 1 "1a 1b"
let mut tx = repo.start_transaction(&settings);
let mut create_commit = create_commit_fn(tx.repo_mut(), &settings);
let content1 = "1a\n1b\n";
let content2 = "2\n1a\n";
let content3 = "1b\n3\n";
let content4 = "2\n1a\n1b\n3\n4\n";
let tree1 = create_tree(repo, &[(file_path, content1)]);
let tree2 = create_tree(repo, &[(file_path, content2)]);
let tree3 = create_tree(repo, &[(file_path, content3)]);
let tree4 = create_tree(repo, &[(file_path, content4)]);
let commit1 = create_commit("commit1", &[root_commit_id], tree1.id());
let commit2 = create_commit("commit2", &[commit1.id()], tree2.id());
let commit3 = create_commit("commit3", &[commit1.id()], tree3.id());
let commit4 = create_commit("commit4", &[commit2.id(), commit3.id()], tree4.id());
drop(create_commit);

insta::assert_snapshot!(annotate(tx.repo(), &commit4, file_path), @r#"
commit2: 2
commit1: 1a
commit1: 1b
commit3: 3
commit4: 4
"#);
}

#[test]
#[should_panic] // FIXME: shouldn't panic because of duplicated "1"s
fn test_annotate_merge_dup() {
let settings = testutils::user_settings();
let test_repo = TestRepo::init();
let repo = &test_repo.repo;

let root_commit_id = repo.store().root_commit_id();
let file_path = RepoPath::from_internal_string("file");

// 4 "2 1 1 3 4"
// |\
// | 3 "1 3"
// | |
// 2 | "2 1"
// |/
// 1 "1"
let mut tx = repo.start_transaction(&settings);
let mut create_commit = create_commit_fn(tx.repo_mut(), &settings);
let content1 = "1\n";
let content2 = "2\n1\n";
let content3 = "1\n3\n";
let content4 = "2\n1\n1\n3\n4\n";
let tree1 = create_tree(repo, &[(file_path, content1)]);
let tree2 = create_tree(repo, &[(file_path, content2)]);
let tree3 = create_tree(repo, &[(file_path, content3)]);
let tree4 = create_tree(repo, &[(file_path, content4)]);
let commit1 = create_commit("commit1", &[root_commit_id], tree1.id());
let commit2 = create_commit("commit2", &[commit1.id()], tree2.id());
let commit3 = create_commit("commit3", &[commit1.id()], tree3.id());
let commit4 = create_commit("commit4", &[commit2.id(), commit3.id()], tree4.id());
drop(create_commit);

insta::assert_snapshot!(annotate(tx.repo(), &commit4, file_path), @r#"
commit2: 2
commit1: 1
commit1: 1
commit3: 3
commit4: 4
"#);
}

#[test]
fn test_annotate_file_directory_transition() {
let settings = testutils::user_settings();
let test_repo = TestRepo::init();
let repo = &test_repo.repo;

let root_commit_id = repo.store().root_commit_id();
let file_path1 = RepoPath::from_internal_string("file/was_dir");
let file_path2 = RepoPath::from_internal_string("file");

let mut tx = repo.start_transaction(&settings);
let mut create_commit = create_commit_fn(tx.repo_mut(), &settings);
let tree1 = create_tree(repo, &[(file_path1, "1\n")]);
let tree2 = create_tree(repo, &[(file_path2, "2\n")]);
let commit1 = create_commit("commit1", &[root_commit_id], tree1.id());
let commit2 = create_commit("commit2", &[commit1.id()], tree2.id());
drop(create_commit);

insta::assert_snapshot!(annotate(tx.repo(), &commit2, file_path2), @r#"
commit2: 2
"#);
}

0 comments on commit b485881

Please sign in to comment.