From a4ec9e07e1b2e6f37f7119651ae3bb63b79988b6 Mon Sep 17 00:00:00 2001 From: Fintan Halpenny Date: Fri, 18 Nov 2022 12:52:54 +0000 Subject: [PATCH] radicle-surf: organise tests Reorganise the tests into module files, rather than all being in a single file. No tests were changed in this patch. The `serialize` flag was also not enabled in `test/Cargo.toml`. This is enabled to ensure those tests are run moving forward. Signed-off-by: Fintan Halpenny X-Clacks-Overhead: GNU Terry Pratchett --- radicle-surf/t/src/git.rs | 793 +----------------------- radicle-surf/t/src/git/branch.rs | 25 + radicle-surf/t/src/git/code_browsing.rs | 68 ++ radicle-surf/t/src/git/commit.rs | 33 + radicle-surf/t/src/git/diff.rs | 198 ++++++ radicle-surf/t/src/git/last_commit.rs | 126 ++++ radicle-surf/t/src/git/namespace.rs | 121 ++++ radicle-surf/t/src/git/reference.rs | 46 ++ radicle-surf/t/src/git/rev.rs | 92 +++ radicle-surf/t/src/git/submodule.rs | 10 + radicle-surf/t/src/git/threading.rs | 33 + test/Cargo.toml | 5 +- 12 files changed, 770 insertions(+), 780 deletions(-) create mode 100644 radicle-surf/t/src/git/branch.rs create mode 100644 radicle-surf/t/src/git/code_browsing.rs create mode 100644 radicle-surf/t/src/git/commit.rs create mode 100644 radicle-surf/t/src/git/diff.rs create mode 100644 radicle-surf/t/src/git/last_commit.rs create mode 100644 radicle-surf/t/src/git/namespace.rs create mode 100644 radicle-surf/t/src/git/reference.rs create mode 100644 radicle-surf/t/src/git/rev.rs create mode 100644 radicle-surf/t/src/git/submodule.rs create mode 100644 radicle-surf/t/src/git/threading.rs diff --git a/radicle-surf/t/src/git.rs b/radicle-surf/t/src/git.rs index 534aea0..513583a 100644 --- a/radicle-surf/t/src/git.rs +++ b/radicle-surf/t/src/git.rs @@ -3,786 +3,27 @@ //! Unit tests for radicle_surf::git and its submodules. -#[cfg(feature = "serialize")] -use radicle_surf::git::{Author, Commit}; -use radicle_surf::{ - diff::*, - file_system::directory, - git::{Branch, Error, Glob, Oid, Repository}, -}; - const GIT_PLATINUM: &str = "../data/git-platinum"; -#[cfg(not(feature = "gh-actions"))] -#[test] -// An issue with submodules, see: https://github.com/radicle-dev/radicle-surf/issues/54 -fn test_submodule_failure() { - use git_ref_format::refname; - - let repo = Repository::discover(".").unwrap(); - repo.root_dir(&Branch::local(refname!("main"))).unwrap(); -} - -#[cfg(test)] -mod namespace { - use super::*; - use git_ref_format::{name::component, refname}; - use pretty_assertions::{assert_eq, assert_ne}; - - #[test] - fn switch_to_banana() -> Result<(), Error> { - let repo = Repository::open(GIT_PLATINUM)?; - let history_master = repo.history(&Branch::local(refname!("master")))?; - repo.switch_namespace("golden")?; - let history_banana = repo.history(&Branch::local(refname!("banana")))?; - - assert_ne!(history_master.head(), history_banana.head()); - - Ok(()) - } - - #[test] - fn me_namespace() -> Result<(), Error> { - let repo = Repository::open(GIT_PLATINUM)?; - let history = repo.history(&Branch::local(refname!("master")))?; - - assert_eq!(repo.which_namespace().unwrap(), None); - - repo.switch_namespace("me")?; - assert_eq!(repo.which_namespace().unwrap(), Some("me".parse()?)); - - let history_feature = repo.history(&Branch::local(refname!("feature/#1194")))?; - assert_eq!(history.head(), history_feature.head()); - - let expected_branches: Vec = vec![Branch::local(refname!("feature/#1194"))]; - let mut branches = repo - .branches(&Glob::heads("*")?)? - .collect::, _>>()?; - branches.sort(); - - assert_eq!(expected_branches, branches); - - let expected_branches: Vec = vec![Branch::remote( - component!("fein"), - refname!("heads/feature/#1194"), - )]; - let mut branches = repo - .branches(&Glob::remotes("fein/*")?)? - .collect::, _>>()?; - branches.sort(); - - assert_eq!(expected_branches, branches); - - Ok(()) - } - - #[test] - fn golden_namespace() -> Result<(), Error> { - let repo = Repository::open(GIT_PLATINUM)?; - let history = repo.history(&Branch::local(refname!("master")))?; - - assert_eq!(repo.which_namespace().unwrap(), None); - - repo.switch_namespace("golden")?; - - assert_eq!(repo.which_namespace().unwrap(), Some("golden".parse()?)); - - let golden_history = repo.history(&Branch::local(refname!("master")))?; - assert_eq!(history.head(), golden_history.head()); - - let expected_branches: Vec = vec![ - Branch::local(refname!("banana")), - Branch::local(refname!("master")), - ]; - let mut branches = repo - .branches(&Glob::heads("*")?)? - .collect::, _>>()?; - branches.sort(); - - assert_eq!(expected_branches, branches); - - // NOTE: these tests used to remove the categories, i.e. heads & tags, but that - // was specialised logic based on the radicle-link storage layout. - let remote = component!("kickflip"); - let expected_branches: Vec = vec![ - Branch::remote(remote.clone(), refname!("heads/fakie/bigspin")), - Branch::remote(remote.clone(), refname!("heads/heelflip")), - Branch::remote(remote, refname!("tags/v0.1.0")), - ]; - let mut branches = repo - .branches(&Glob::remotes("kickflip/*")?)? - .collect::, _>>()?; - branches.sort(); - - assert_eq!(expected_branches, branches); - - Ok(()) - } - - #[test] - fn silver_namespace() -> Result<(), Error> { - let repo = Repository::open(GIT_PLATINUM)?; - let history = repo.history(&Branch::local(refname!("master")))?; - - assert_eq!(repo.which_namespace().unwrap(), None); - - repo.switch_namespace("golden/silver")?; - assert_eq!( - repo.which_namespace().unwrap(), - Some("golden/silver".parse()?) - ); - let silver_history = repo.history(&Branch::local(refname!("master")))?; - assert_ne!(history.head(), silver_history.head()); - - let expected_branches: Vec = vec![Branch::local(refname!("master"))]; - let mut branches = repo - .branches(&Glob::heads("*")?.and_remotes("*")?)? - .collect::, _>>()?; - branches.sort(); - - assert_eq!(expected_branches, branches); - - Ok(()) - } -} - -#[cfg(test)] -mod rev { - use git_ref_format::{name::component, refname}; - - use super::*; - use std::str::FromStr; - - // **FIXME**: This seems to break occasionally on - // buildkite. For some reason the commit - // 3873745c8f6ffb45c990eb23b491d4b4b6182f95, which is on master - // (currently HEAD), is not found. It seems to load the history - // with d6880352fc7fda8f521ae9b7357668b17bb5bad5 as the HEAD. - // - // To temporarily fix this, we need to select "New Build" from the build kite - // build page that's failing. - // * Under "Message" put whatever you want. - // * Under "Branch" put in the branch you're working on. - // * Expand "Options" and select "clean checkout". - #[test] - fn _master() -> Result<(), Error> { - let repo = Repository::open(GIT_PLATINUM)?; - let mut history = - repo.history(&Branch::remote(component!("origin"), refname!("master")))?; - - let commit1 = Oid::from_str("3873745c8f6ffb45c990eb23b491d4b4b6182f95")?; - assert!( - history.any(|commit| commit.unwrap().id == commit1), - "commit_id={}, history =\n{:#?}", - commit1, - &history - ); - - let commit2 = Oid::from_str("d6880352fc7fda8f521ae9b7357668b17bb5bad5")?; - assert!( - history.any(|commit| commit.unwrap().id == commit2), - "commit_id={}, history =\n{:#?}", - commit2, - &history - ); - - Ok(()) - } - - #[test] - fn commit() -> Result<(), Error> { - let repo = Repository::open(GIT_PLATINUM)?; - let rev = Oid::from_str("3873745c8f6ffb45c990eb23b491d4b4b6182f95")?; - let mut history = repo.history(rev)?; - - let commit1 = Oid::from_str("3873745c8f6ffb45c990eb23b491d4b4b6182f95")?; - assert!(history.any(|commit| commit.unwrap().id == commit1)); - - Ok(()) - } - - #[test] - fn commit_parents() -> Result<(), Error> { - let repo = Repository::open(GIT_PLATINUM)?; - let rev = Oid::from_str("3873745c8f6ffb45c990eb23b491d4b4b6182f95")?; - let history = repo.history(rev)?; - let commit = history.head(); - - assert_eq!( - commit.parents, - vec![Oid::from_str("d6880352fc7fda8f521ae9b7357668b17bb5bad5")?] - ); - - Ok(()) - } - - #[test] - fn commit_short() -> Result<(), Error> { - let repo = Repository::open(GIT_PLATINUM)?; - let rev = repo.oid("3873745c8")?; - let mut history = repo.history(rev)?; - - let commit1 = Oid::from_str("3873745c8f6ffb45c990eb23b491d4b4b6182f95")?; - assert!(history.any(|commit| commit.unwrap().id == commit1)); - - Ok(()) - } - - #[test] - fn tag() -> Result<(), Error> { - let repo = Repository::open(GIT_PLATINUM)?; - let rev = refname!("refs/tags/v0.2.0"); - let history = repo.history(&rev)?; - - let commit1 = Oid::from_str("2429f097664f9af0c5b7b389ab998b2199ffa977")?; - assert_eq!(history.head().id, commit1); - - Ok(()) - } -} - -#[cfg(test)] -mod last_commit { - use git_ref_format::refname; - - use super::*; - use std::{ - path::{Path, PathBuf}, - str::FromStr, - }; - - #[test] - fn readme_missing_and_memory() { - let repo = Repository::open(GIT_PLATINUM) - .expect("Could not retrieve ./data/git-platinum as git repository"); - let oid = - Oid::from_str("d3464e33d75c75c99bfb90fa2e9d16efc0b7d0e3").expect("Failed to parse SHA"); - - // memory.rs is commited later so it should not exist here. - let memory_last_commit_oid = repo - .last_commit(Path::new("src/memory.rs"), oid) - .expect("Failed to get last commit") - .map(|commit| commit.id); - - assert_eq!(memory_last_commit_oid, None); - - // README.md exists in this commit. - let readme_last_commit = repo - .last_commit(Path::new("README.md"), oid) - .expect("Failed to get last commit") - .map(|commit| commit.id); - - assert_eq!(readme_last_commit, Some(oid)); - } - - #[test] - fn folder_svelte() { - let repo = Repository::open(GIT_PLATINUM) - .expect("Could not retrieve ./data/git-platinum as git repository"); - // Check that last commit is the actual last commit even if head commit differs. - let oid = - Oid::from_str("19bec071db6474af89c866a1bd0e4b1ff76e2b97").expect("Could not parse SHA"); - - let expected_commit_id = Oid::from_str("f3a089488f4cfd1a240a9c01b3fcc4c34a4e97b2").unwrap(); - - let folder_svelte = repo - .last_commit(Path::new("examples/Folder.svelte"), oid) - .expect("Failed to get last commit") - .map(|commit| commit.id); - - assert_eq!(folder_svelte, Some(expected_commit_id)); - } - - #[test] - fn nest_directory() { - let repo = Repository::open(GIT_PLATINUM) - .expect("Could not retrieve ./data/git-platinum as git repository"); - // Check that last commit is the actual last commit even if head commit differs. - let oid = - Oid::from_str("19bec071db6474af89c866a1bd0e4b1ff76e2b97").expect("Failed to parse SHA"); - - let expected_commit_id = Oid::from_str("2429f097664f9af0c5b7b389ab998b2199ffa977").unwrap(); - - let nested_directory_tree_commit_id = repo - .last_commit( - Path::new("this/is/a/really/deeply/nested/directory/tree"), - oid, - ) - .expect("Failed to get last commit") - .map(|commit| commit.id); - - assert_eq!(nested_directory_tree_commit_id, Some(expected_commit_id)); - } - - #[test] - #[cfg(not(windows))] - fn can_get_last_commit_for_special_filenames() { - let repo = Repository::open(GIT_PLATINUM) - .expect("Could not retrieve ./data/git-platinum as git repository"); - - // Check that last commit is the actual last commit even if head commit differs. - let oid = - Oid::from_str("a0dd9122d33dff2a35f564d564db127152c88e02").expect("Failed to parse SHA"); - - let expected_commit_id = Oid::from_str("a0dd9122d33dff2a35f564d564db127152c88e02").unwrap(); - - let backslash_commit_id = repo - .last_commit(Path::new(r"special/faux\\path"), oid) - .expect("Failed to get last commit") - .map(|commit| commit.id); - assert_eq!(backslash_commit_id, Some(expected_commit_id)); - - let ogre_commit_id = repo - .last_commit(Path::new("special/👹👹👹"), oid) - .expect("Failed to get last commit") - .map(|commit| commit.id); - assert_eq!(ogre_commit_id, Some(expected_commit_id)); - } - - #[test] - fn root() { - let repo = Repository::open(GIT_PLATINUM) - .expect("Could not retrieve ./data/git-platinum as git repository"); - let rev = Branch::local(refname!("master")); - let root_last_commit_id = repo - .last_commit(&PathBuf::new(), &rev) - .expect("Failed to get last commit") - .map(|commit| commit.id); - - let expected_oid = repo - .history(&Branch::local(refname!("master"))) - .unwrap() - .head() - .id; - assert_eq!(root_last_commit_id, Some(expected_oid)); - } - - #[test] - fn binary_file() { - let repo = Repository::open(GIT_PLATINUM) - .expect("Could not retrieve ./data/git-platinum as git repository"); - let history = repo.history(&Branch::local(refname!("dev"))).unwrap(); - let file_commit = history.by_path(Path::new("bin/cat")).next(); - assert!(file_commit.is_some()); - println!("file commit: {:?}", &file_commit); - } -} - -#[cfg(test)] -mod diff { - use super::*; - use git_ref_format::refname; - use pretty_assertions::assert_eq; - use std::{path::Path, str::FromStr}; - - #[test] - fn test_initial_diff() -> Result<(), Error> { - let repo = Repository::open(GIT_PLATINUM)?; - let oid = Oid::from_str("d3464e33d75c75c99bfb90fa2e9d16efc0b7d0e3")?; - let commit = repo.commit(oid).unwrap(); - assert!(commit.parents.is_empty()); - - let diff = repo.initial_diff(oid)?; - - let expected_diff = Diff { - created: vec![CreateFile { - path: Path::new("README.md").to_path_buf(), - diff: FileDiff::Plain { - hunks: vec![Hunk { - header: Line::from(b"@@ -0,0 +1 @@\n".to_vec()), - lines: vec![LineDiff::addition( - b"This repository is a data source for the Upstream front-end tests.\n" - .to_vec(), - 1, - )], - }] - .into(), - }, - }], - deleted: vec![], - moved: vec![], - copied: vec![], - modified: vec![], - }; - assert_eq!(expected_diff, diff); - - Ok(()) - } - - #[test] - fn test_diff_of_rev() -> Result<(), Error> { - let repo = Repository::open(GIT_PLATINUM)?; - let diff = repo.diff_from_parent("80bacafba303bf0cdf6142921f430ff265f25095")?; - assert_eq!(diff.created.len(), 0); - assert_eq!(diff.deleted.len(), 0); - assert_eq!(diff.moved.len(), 0); - assert_eq!(diff.modified.len(), 1); - Ok(()) - } - - #[test] - fn test_diff() -> Result<(), Error> { - let repo = Repository::open(GIT_PLATINUM)?; - let oid = "80bacafba303bf0cdf6142921f430ff265f25095"; - let commit = repo.commit(oid).unwrap(); - let parent_oid = commit.parents.get(0).unwrap(); - let diff = repo.diff(*parent_oid, oid)?; - - let expected_diff = Diff { - created: vec![], - deleted: vec![], - moved: vec![], - copied: vec![], - modified: vec![ModifiedFile { - path: Path::new("README.md").to_path_buf(), - diff: FileDiff::Plain { - hunks: vec![Hunk { - header: Line::from(b"@@ -1 +1,2 @@\n".to_vec()), - lines: vec![ - LineDiff::deletion(b"This repository is a data source for the Upstream front-end tests.\n".to_vec(), 1), - LineDiff::addition(b"This repository is a data source for the Upstream front-end tests and the\n".to_vec(), 1), - LineDiff::addition(b"[`radicle-surf`](https://github.com/radicle-dev/git-platinum) unit tests.\n".to_vec(), 2), - ] - }].into() - }, - eof: None, - }] - }; - assert_eq!(expected_diff, diff); - - Ok(()) - } - - #[test] - fn test_branch_diff() -> Result<(), Error> { - let repo = Repository::open(GIT_PLATINUM)?; - let diff = repo.diff( - &Branch::local(refname!("master")), - &Branch::local(refname!("dev")), - )?; - - println!("Diff two branches: master -> dev"); - println!( - "result: created {} deleted {} moved {} modified {}", - diff.created.len(), - diff.deleted.len(), - diff.moved.len(), - diff.modified.len() - ); - assert_eq!(diff.created.len(), 1); - assert_eq!(diff.deleted.len(), 11); - assert_eq!(diff.moved.len(), 1); - assert_eq!(diff.modified.len(), 2); - for c in diff.created.iter() { - println!("created: {:?}", &c.path); - } - for d in diff.deleted.iter() { - println!("deleted: {:?}", &d.path); - } - for m in diff.moved.iter() { - println!("moved: {:?} -> {:?}", &m.old_path, &m.new_path); - } - for m in diff.modified.iter() { - println!("modified: {:?}", &m.path); - } - Ok(()) - } - - #[cfg(feature = "serialize")] - #[test] - fn test_diff_serde() -> Result<(), Error> { - let diff = Diff { - created: vec![CreateFile{path: unsound::path::new("LICENSE"), diff: FileDiff::Plain { hunks: Hunks::default() }}], - deleted: vec![], - moved: vec![ - MoveFile { - old_path: unsound::path::new("CONTRIBUTING"), - new_path: unsound::path::new("CONTRIBUTING.md") - } - ], - copied: vec![], - modified: vec![ModifiedFile { - path: Path::with_root(&[unsound::label::new("README.md")]), - diff: FileDiff::Plain { - hunks: vec![Hunk { - header: Line::from(b"@@ -1 +1,2 @@\n".to_vec()), - lines: vec![ - LineDiff::deletion(b"This repository is a data source for the Upstream front-end tests.\n".to_vec(), 1), - LineDiff::addition(b"This repository is a data source for the Upstream front-end tests and the\n".to_vec(), 1), - LineDiff::addition(b"[`radicle-surf`](https://github.com/radicle-dev/git-platinum) unit tests.\n".to_vec(), 2), - LineDiff::context(b"\n".to_vec(), 3, 4), - ] - }].into() - }, - eof: None, - }] - }; - - let eof: Option = None; - let json = serde_json::json!({ - "created": [{"path": "LICENSE", "diff": { - "type": "plain", - "hunks": [] - }, - }], - "deleted": [], - "moved": [{ "oldPath": "CONTRIBUTING", "newPath": "CONTRIBUTING.md" }], - "copied": [], - "modified": [{ - "path": "README.md", - "diff": { - "type": "plain", - "hunks": [{ - "header": "@@ -1 +1,2 @@\n", - "lines": [ - { "lineNum": 1, - "line": "This repository is a data source for the Upstream front-end tests.\n", - "type": "deletion" - }, - { "lineNum": 1, - "line": "This repository is a data source for the Upstream front-end tests and the\n", - "type": "addition" - }, - { "lineNum": 2, - "line": "[`radicle-surf`](https://github.com/radicle-dev/git-platinum) unit tests.\n", - "type": "addition" - }, - { "lineNumOld": 3, "lineNumNew": 4, - "line": "\n", - "type": "context" - } - ] - }] - }, - "eof" : eof, - }] - }); - assert_eq!(serde_json::to_value(&diff).unwrap(), json); - - Ok(()) - } -} - -#[cfg(test)] -mod threading { - use git_ref_format::{name::component, refname}; - use radicle_surf::git::Glob; - - use super::*; - use std::sync::{Mutex, MutexGuard}; - - #[test] - fn basic_test() -> Result<(), Error> { - let shared_repo = Mutex::new(Repository::open(GIT_PLATINUM)?); - let locked_repo: MutexGuard = shared_repo.lock().unwrap(); - let mut branches = locked_repo - .branches(&Glob::heads("*")?.and_remotes("*")?)? - .collect::, _>>()?; - branches.sort(); - - let origin = component!("origin"); - let banana = component!("banana"); - assert_eq!( - branches, - vec![ - Branch::local(refname!("dev")), - Branch::local(refname!("master")), - Branch::remote(banana.clone(), refname!("orange/pineapple")), - Branch::remote(banana, refname!("pineapple")), - Branch::remote(origin.clone(), refname!("HEAD")), - Branch::remote(origin.clone(), refname!("dev")), - Branch::remote(origin, refname!("master")), - ] - ); - - Ok(()) - } -} - #[cfg(feature = "serialize")] #[cfg(test)] -mod commit { - use super::{Author, Commit}; - use proptest::prelude::*; - use radicle_git_ext::Oid; - use std::str::FromStr; - use test_helpers::roundtrip; - - #[cfg(feature = "serialize")] - proptest! { - #[test] - fn prop_test_commits(commit in commits_strategy()) { - roundtrip::json(commit) - } - } - - fn commits_strategy() -> impl Strategy { - ("[a-fA-F0-9]{40}", any::(), any::()).prop_map(|(id, text, time)| Commit { - id: Oid::from_str(&id).unwrap(), - author: Author { - name: text.clone(), - email: text.clone(), - time: git2::Time::new(time, 0), - }, - committer: Author { - name: text.clone(), - email: text.clone(), - time: git2::Time::new(time, 0), - }, - message: text.clone(), - summary: text, - parents: vec![Oid::from_str(&id).unwrap(), Oid::from_str(&id).unwrap()], - }) - } -} - +mod branch; +#[cfg(test)] +mod code_browsing; #[cfg(feature = "serialize")] #[cfg(test)] -mod branch { - use git_ref_format::{RefStr, RefString}; - use git_ref_format_test::gen; - use proptest::prelude::*; - use test_helpers::roundtrip; - - use super::*; - - proptest! { - #[test] - fn prop_test_branch(branch in gen_branch()) { - roundtrip::json(branch) - } - } - - fn gen_branch() -> impl Strategy { - prop_oneof![ - gen::valid().prop_map(|name| Branch::local(RefString::try_from(name).unwrap())), - (gen::valid(), gen::valid()).prop_map(|(remote, name): (String, String)| { - let remote = - RefStr::try_from_str(&remote).expect("BUG: reference strings should be valid"); - let name = - RefStr::try_from_str(&name).expect("BUG: reference strings should be valid"); - Branch::remote(remote.head(), name) - }) - ] - } -} - +mod commit; #[cfg(test)] -mod reference { - use super::*; - use radicle_surf::git::Glob; - - #[test] - fn test_branches() { - let repo = Repository::open(GIT_PLATINUM).unwrap(); - let branches = repo.branches(&Glob::heads("*").unwrap()).unwrap(); - for b in branches { - println!("{}", b.unwrap().refname()); - } - let branches = repo - .branches(&Glob::heads("*").unwrap().and_remotes("banana/*").unwrap()) - .unwrap(); - for b in branches { - println!("{}", b.unwrap().refname()); - } - } - - #[test] - fn test_tag_snapshot() { - let repo = Repository::open(GIT_PLATINUM).unwrap(); - let tags = repo - .tags(&Glob::tags("*").unwrap()) - .unwrap() - .collect::, _>>() - .unwrap(); - assert_eq!(tags.len(), 6); - let root_dir = repo.root_dir(&tags[0]).unwrap(); - assert_eq!(root_dir.entries(&repo).unwrap().entries().count(), 1); - } - - #[test] - fn test_namespaces() { - let repo = Repository::open(GIT_PLATINUM).unwrap(); - let namespaces = repo.namespaces(&Glob::namespaces("*").unwrap()).unwrap(); - assert_eq!(namespaces.count(), 3); - let namespaces = repo - .namespaces(&Glob::namespaces("golden/*").unwrap()) - .unwrap(); - assert_eq!(namespaces.count(), 2); - let namespaces = repo - .namespaces(&Glob::namespaces("golden/*").unwrap().and("me/*").unwrap()) - .unwrap(); - assert_eq!(namespaces.count(), 3); - } -} - -mod code_browsing { - use std::path::Path; - - use super::*; - - use git_ref_format::refname; - use radicle_surf::{file_system::Directory, git::Repository}; - - #[test] - fn iterate_root_dir_recursive() { - let repo = Repository::open(GIT_PLATINUM).unwrap(); - - let root_dir = repo.root_dir(&Branch::local(refname!("master"))).unwrap(); - let count = println_dir(&root_dir, &repo); - - assert_eq!(count, 36); // Check total file count. - - /// Prints items in `dir` with `indent_level`. - /// For sub-directories, will do Depth-First-Search and print - /// recursively. - /// Returns the number of items visited (i.e. printed) - fn println_dir(dir: &Directory, repo: &Repository) -> i32 { - dir.traverse::( - repo, - (0, 0), - &mut |(count, indent_level), entry| { - println!("> {}{}", " ".repeat(indent_level * 4), entry.name()); - match entry { - directory::Entry::File(_) => Ok((count + 1, indent_level)), - directory::Entry::Directory(_) => Ok((count + 1, indent_level + 1)), - } - }, - ) - .unwrap() - .0 - } - } - - #[test] - fn browse_repo_lazily() { - let repo = Repository::open(GIT_PLATINUM).unwrap(); - let root_dir = repo.root_dir(&Branch::local(refname!("master"))).unwrap(); - let count = root_dir.entries(&repo).unwrap().entries().count(); - assert_eq!(count, 8); - let count = traverse(&root_dir, &repo); - assert_eq!(count, 36); - - fn traverse(dir: &Directory, repo: &Repository) -> i32 { - dir.traverse::( - repo, - 0, - &mut |count, _| Ok(count + 1), - ) - .unwrap() - } - } - - #[test] - fn test_file_history() { - let repo = Repository::open(GIT_PLATINUM).unwrap(); - let history = repo.history(&Branch::local(refname!("dev"))).unwrap(); - let path = Path::new("README.md"); - let mut file_history = history.by_path(path); - let commit = file_history.next().unwrap().unwrap(); - let file = repo - .get_commit_file(&commit.id, &Path::new("README.md")) - .unwrap(); - assert_eq!(file.size(), 67); - } -} +mod diff; +#[cfg(test)] +mod last_commit; +#[cfg(test)] +mod namespace; +#[cfg(test)] +mod reference; +#[cfg(test)] +mod rev; +#[cfg(test)] +mod submodule; +#[cfg(test)] +mod threading; diff --git a/radicle-surf/t/src/git/branch.rs b/radicle-surf/t/src/git/branch.rs new file mode 100644 index 0000000..28dd4f4 --- /dev/null +++ b/radicle-surf/t/src/git/branch.rs @@ -0,0 +1,25 @@ +use git_ref_format::{RefStr, RefString}; +use git_ref_format_test::gen; +use proptest::prelude::*; +use test_helpers::roundtrip; + +use radicle_surf::git::Branch; + +proptest! { + #[test] + fn prop_test_branch(branch in gen_branch()) { + roundtrip::json(branch) + } +} + +fn gen_branch() -> impl Strategy { + prop_oneof![ + gen::valid().prop_map(|name| Branch::local(RefString::try_from(name).unwrap())), + (gen::valid(), gen::valid()).prop_map(|(remote, name): (String, String)| { + let remote = + RefStr::try_from_str(&remote).expect("BUG: reference strings should be valid"); + let name = RefStr::try_from_str(&name).expect("BUG: reference strings should be valid"); + Branch::remote(remote.head(), name) + }) + ] +} diff --git a/radicle-surf/t/src/git/code_browsing.rs b/radicle-surf/t/src/git/code_browsing.rs new file mode 100644 index 0000000..f7108fb --- /dev/null +++ b/radicle-surf/t/src/git/code_browsing.rs @@ -0,0 +1,68 @@ +use std::path::Path; + +use git_ref_format::refname; +use radicle_surf::{ + file_system::{directory, Directory}, + git::{Branch, Repository}, +}; + +use super::GIT_PLATINUM; + +#[test] +fn iterate_root_dir_recursive() { + let repo = Repository::open(GIT_PLATINUM).unwrap(); + + let root_dir = repo.root_dir(&Branch::local(refname!("master"))).unwrap(); + let count = println_dir(&root_dir, &repo); + + assert_eq!(count, 36); // Check total file count. + + /// Prints items in `dir` with `indent_level`. + /// For sub-directories, will do Depth-First-Search and print + /// recursively. + /// Returns the number of items visited (i.e. printed) + fn println_dir(dir: &Directory, repo: &Repository) -> i32 { + dir.traverse::( + repo, + (0, 0), + &mut |(count, indent_level), entry| { + println!("> {}{}", " ".repeat(indent_level * 4), entry.name()); + match entry { + directory::Entry::File(_) => Ok((count + 1, indent_level)), + directory::Entry::Directory(_) => Ok((count + 1, indent_level + 1)), + } + }, + ) + .unwrap() + .0 + } +} + +#[test] +fn browse_repo_lazily() { + let repo = Repository::open(GIT_PLATINUM).unwrap(); + + let root_dir = repo.root_dir(&Branch::local(refname!("master"))).unwrap(); + let count = root_dir.entries(&repo).unwrap().entries().count(); + assert_eq!(count, 8); + let count = traverse(&root_dir, &repo); + assert_eq!(count, 36); + + fn traverse(dir: &Directory, repo: &Repository) -> i32 { + dir.traverse::(repo, 0, &mut |count, _| Ok(count + 1)) + .unwrap() + } +} + +#[test] +fn test_file_history() { + let repo = Repository::open(GIT_PLATINUM).unwrap(); + let history = repo.history(&Branch::local(refname!("dev"))).unwrap(); + let path = Path::new("README.md"); + let mut file_history = history.by_path(path); + let commit = file_history.next().unwrap().unwrap(); + let file = repo + .get_commit_file(&commit.id, &Path::new("README.md")) + .unwrap(); + assert_eq!(file.size(), 67); +} diff --git a/radicle-surf/t/src/git/commit.rs b/radicle-surf/t/src/git/commit.rs new file mode 100644 index 0000000..ef90cf5 --- /dev/null +++ b/radicle-surf/t/src/git/commit.rs @@ -0,0 +1,33 @@ +use std::str::FromStr; + +use proptest::prelude::*; +use radicle_git_ext::Oid; +use radicle_surf::git::{Author, Commit}; +use test_helpers::roundtrip; + +#[cfg(feature = "serialize")] +proptest! { + #[test] + fn prop_test_commits(commit in commits_strategy()) { + roundtrip::json(commit) + } +} + +fn commits_strategy() -> impl Strategy { + ("[a-fA-F0-9]{40}", any::(), any::()).prop_map(|(id, text, time)| Commit { + id: Oid::from_str(&id).unwrap(), + author: Author { + name: text.clone(), + email: text.clone(), + time: git2::Time::new(time, 0), + }, + committer: Author { + name: text.clone(), + email: text.clone(), + time: git2::Time::new(time, 0), + }, + message: text.clone(), + summary: text, + parents: vec![Oid::from_str(&id).unwrap(), Oid::from_str(&id).unwrap()], + }) +} diff --git a/radicle-surf/t/src/git/diff.rs b/radicle-surf/t/src/git/diff.rs new file mode 100644 index 0000000..1b89d5c --- /dev/null +++ b/radicle-surf/t/src/git/diff.rs @@ -0,0 +1,198 @@ +use git_ref_format::refname; +use pretty_assertions::assert_eq; +use radicle_git_ext::Oid; +use radicle_surf::{ + diff::{CreateFile, Diff, FileDiff, Hunk, Line, LineDiff, ModifiedFile}, + git::{Branch, Error, Repository}, +}; +use std::{path::Path, str::FromStr}; + +use super::GIT_PLATINUM; + +#[test] +fn test_initial_diff() -> Result<(), Error> { + let repo = Repository::open(GIT_PLATINUM)?; + let oid = Oid::from_str("d3464e33d75c75c99bfb90fa2e9d16efc0b7d0e3")?; + let commit = repo.commit(oid).unwrap(); + assert!(commit.parents.is_empty()); + + let diff = repo.initial_diff(oid)?; + + let expected_diff = Diff { + created: vec![CreateFile { + path: Path::new("README.md").to_path_buf(), + diff: FileDiff::Plain { + hunks: vec![Hunk { + header: Line::from(b"@@ -0,0 +1 @@\n".to_vec()), + lines: vec![LineDiff::addition( + b"This repository is a data source for the Upstream front-end tests.\n" + .to_vec(), + 1, + )], + }] + .into(), + }, + }], + deleted: vec![], + moved: vec![], + copied: vec![], + modified: vec![], + }; + assert_eq!(expected_diff, diff); + + Ok(()) +} + +#[test] +fn test_diff_of_rev() -> Result<(), Error> { + let repo = Repository::open(GIT_PLATINUM)?; + let diff = repo.diff_from_parent("80bacafba303bf0cdf6142921f430ff265f25095")?; + assert_eq!(diff.created.len(), 0); + assert_eq!(diff.deleted.len(), 0); + assert_eq!(diff.moved.len(), 0); + assert_eq!(diff.modified.len(), 1); + Ok(()) +} + +#[test] +fn test_diff() -> Result<(), Error> { + let repo = Repository::open(GIT_PLATINUM)?; + let oid = "80bacafba303bf0cdf6142921f430ff265f25095"; + let commit = repo.commit(oid).unwrap(); + let parent_oid = commit.parents.get(0).unwrap(); + let diff = repo.diff(*parent_oid, oid)?; + + let expected_diff = Diff { + created: vec![], + deleted: vec![], + moved: vec![], + copied: vec![], + modified: vec![ModifiedFile { + path: Path::new("README.md").to_path_buf(), + diff: FileDiff::Plain { + hunks: vec![Hunk { + header: Line::from(b"@@ -1 +1,2 @@\n".to_vec()), + lines: vec![ + LineDiff::deletion(b"This repository is a data source for the Upstream front-end tests.\n".to_vec(), 1), + LineDiff::addition(b"This repository is a data source for the Upstream front-end tests and the\n".to_vec(), 1), + LineDiff::addition(b"[`radicle-surf`](https://github.com/radicle-dev/git-platinum) unit tests.\n".to_vec(), 2), + ] + }].into() + }, + eof: None, + }] + }; + assert_eq!(expected_diff, diff); + + Ok(()) +} + +#[test] +fn test_branch_diff() -> Result<(), Error> { + let repo = Repository::open(GIT_PLATINUM)?; + let diff = repo.diff( + &Branch::local(refname!("master")), + &Branch::local(refname!("dev")), + )?; + + println!("Diff two branches: master -> dev"); + println!( + "result: created {} deleted {} moved {} modified {}", + diff.created.len(), + diff.deleted.len(), + diff.moved.len(), + diff.modified.len() + ); + assert_eq!(diff.created.len(), 1); + assert_eq!(diff.deleted.len(), 11); + assert_eq!(diff.moved.len(), 1); + assert_eq!(diff.modified.len(), 2); + for c in diff.created.iter() { + println!("created: {:?}", &c.path); + } + for d in diff.deleted.iter() { + println!("deleted: {:?}", &d.path); + } + for m in diff.moved.iter() { + println!("moved: {:?} -> {:?}", &m.old_path, &m.new_path); + } + for m in diff.modified.iter() { + println!("modified: {:?}", &m.path); + } + Ok(()) +} + +#[cfg(feature = "serialize")] +#[test] +fn test_diff_serde() { + use radicle_surf::diff::{Hunks, MoveFile}; + + let diff = Diff { + created: vec![ CreateFile { + path: Path::new("LICENSE").to_path_buf(), + diff: FileDiff::Plain { hunks: Hunks::default() } + }], + deleted: vec![], + moved: vec![ MoveFile { + old_path: Path::new("CONTRIBUTING").to_path_buf(), + new_path: Path::new("CONTRIBUTING.md").to_path_buf(), + }], + copied: vec![], + modified: vec![ ModifiedFile { + path: Path::new("README.md").to_path_buf(), + diff: FileDiff::Plain { + hunks: vec![Hunk { + header: Line::from(b"@@ -1 +1,2 @@\n".to_vec()), + lines: vec![ + LineDiff::deletion(b"This repository is a data source for the Upstream front-end tests.\n".to_vec(), 1), + LineDiff::addition(b"This repository is a data source for the Upstream front-end tests and the\n".to_vec(), 1), + LineDiff::addition(b"[`radicle-surf`](https://github.com/radicle-dev/git-platinum) unit tests.\n".to_vec(), 2), + LineDiff::context(b"\n".to_vec(), 3, 4), + ] + }].into() + }, + eof: None, + }] + }; + + let eof: Option = None; + let json = serde_json::json!({ + "created": [{"path": "LICENSE", "diff": { + "type": "plain", + "hunks": [] + }, + }], + "deleted": [], + "moved": [{ "oldPath": "CONTRIBUTING", "newPath": "CONTRIBUTING.md" }], + "copied": [], + "modified": [{ + "path": "README.md", + "diff": { + "type": "plain", + "hunks": [{ + "header": "@@ -1 +1,2 @@\n", + "lines": [ + { "lineNum": 1, + "line": "This repository is a data source for the Upstream front-end tests.\n", + "type": "deletion" + }, + { "lineNum": 1, + "line": "This repository is a data source for the Upstream front-end tests and the\n", + "type": "addition" + }, + { "lineNum": 2, + "line": "[`radicle-surf`](https://github.com/radicle-dev/git-platinum) unit tests.\n", + "type": "addition" + }, + { "lineNumOld": 3, "lineNumNew": 4, + "line": "\n", + "type": "context" + } + ] + }] + }, + "eof" : eof, + }] + }); + assert_eq!(serde_json::to_value(&diff).unwrap(), json); +} diff --git a/radicle-surf/t/src/git/last_commit.rs b/radicle-surf/t/src/git/last_commit.rs new file mode 100644 index 0000000..d12dd18 --- /dev/null +++ b/radicle-surf/t/src/git/last_commit.rs @@ -0,0 +1,126 @@ +use std::{ + path::{Path, PathBuf}, + str::FromStr, +}; + +use git_ref_format::refname; +use radicle_git_ext::Oid; +use radicle_surf::git::{Branch, Repository}; + +use super::GIT_PLATINUM; + +#[test] +fn readme_missing_and_memory() { + let repo = Repository::open(GIT_PLATINUM) + .expect("Could not retrieve ./data/git-platinum as git repository"); + let oid = + Oid::from_str("d3464e33d75c75c99bfb90fa2e9d16efc0b7d0e3").expect("Failed to parse SHA"); + + // memory.rs is commited later so it should not exist here. + let memory_last_commit_oid = repo + .last_commit(Path::new("src/memory.rs"), oid) + .expect("Failed to get last commit") + .map(|commit| commit.id); + + assert_eq!(memory_last_commit_oid, None); + + // README.md exists in this commit. + let readme_last_commit = repo + .last_commit(Path::new("README.md"), oid) + .expect("Failed to get last commit") + .map(|commit| commit.id); + + assert_eq!(readme_last_commit, Some(oid)); +} + +#[test] +fn folder_svelte() { + let repo = Repository::open(GIT_PLATINUM) + .expect("Could not retrieve ./data/git-platinum as git repository"); + // Check that last commit is the actual last commit even if head commit differs. + let oid = + Oid::from_str("19bec071db6474af89c866a1bd0e4b1ff76e2b97").expect("Could not parse SHA"); + + let expected_commit_id = Oid::from_str("f3a089488f4cfd1a240a9c01b3fcc4c34a4e97b2").unwrap(); + + let folder_svelte = repo + .last_commit(Path::new("examples/Folder.svelte"), oid) + .expect("Failed to get last commit") + .map(|commit| commit.id); + + assert_eq!(folder_svelte, Some(expected_commit_id)); +} + +#[test] +fn nest_directory() { + let repo = Repository::open(GIT_PLATINUM) + .expect("Could not retrieve ./data/git-platinum as git repository"); + // Check that last commit is the actual last commit even if head commit differs. + let oid = + Oid::from_str("19bec071db6474af89c866a1bd0e4b1ff76e2b97").expect("Failed to parse SHA"); + + let expected_commit_id = Oid::from_str("2429f097664f9af0c5b7b389ab998b2199ffa977").unwrap(); + + let nested_directory_tree_commit_id = repo + .last_commit( + Path::new("this/is/a/really/deeply/nested/directory/tree"), + oid, + ) + .expect("Failed to get last commit") + .map(|commit| commit.id); + + assert_eq!(nested_directory_tree_commit_id, Some(expected_commit_id)); +} + +#[test] +#[cfg(not(windows))] +fn can_get_last_commit_for_special_filenames() { + let repo = Repository::open(GIT_PLATINUM) + .expect("Could not retrieve ./data/git-platinum as git repository"); + + // Check that last commit is the actual last commit even if head commit differs. + let oid = + Oid::from_str("a0dd9122d33dff2a35f564d564db127152c88e02").expect("Failed to parse SHA"); + + let expected_commit_id = Oid::from_str("a0dd9122d33dff2a35f564d564db127152c88e02").unwrap(); + + let backslash_commit_id = repo + .last_commit(Path::new(r"special/faux\\path"), oid) + .expect("Failed to get last commit") + .map(|commit| commit.id); + assert_eq!(backslash_commit_id, Some(expected_commit_id)); + + let ogre_commit_id = repo + .last_commit(Path::new("special/👹👹👹"), oid) + .expect("Failed to get last commit") + .map(|commit| commit.id); + assert_eq!(ogre_commit_id, Some(expected_commit_id)); +} + +#[test] +fn root() { + let repo = Repository::open(GIT_PLATINUM) + .expect("Could not retrieve ./data/git-platinum as git repository"); + let rev = Branch::local(refname!("master")); + let root_last_commit_id = repo + .last_commit(&PathBuf::new(), &rev) + .expect("Failed to get last commit") + .map(|commit| commit.id); + + let expected_oid = repo + .history(&Branch::local(refname!("master"))) + .unwrap() + .head() + .id; + assert_eq!(root_last_commit_id, Some(expected_oid)); +} + +#[test] +fn binary_file() { + let repo = Repository::open(GIT_PLATINUM) + .expect("Could not retrieve ./data/git-platinum as git repository"); + let history = repo.history(&Branch::local(refname!("dev"))).unwrap(); + let file_commit = history.by_path(Path::new("bin/cat")).next(); + assert!(file_commit.is_some()); + println!("file commit: {:?}", &file_commit); +} diff --git a/radicle-surf/t/src/git/namespace.rs b/radicle-surf/t/src/git/namespace.rs new file mode 100644 index 0000000..5d34125 --- /dev/null +++ b/radicle-surf/t/src/git/namespace.rs @@ -0,0 +1,121 @@ +use git_ref_format::{name::component, refname}; +use pretty_assertions::{assert_eq, assert_ne}; +use radicle_surf::git::{Branch, Error, Glob, Repository}; + +use super::GIT_PLATINUM; + +#[test] +fn switch_to_banana() -> Result<(), Error> { + let repo = Repository::open(GIT_PLATINUM)?; + let history_master = repo.history(&Branch::local(refname!("master")))?; + repo.switch_namespace("golden")?; + let history_banana = repo.history(&Branch::local(refname!("banana")))?; + + assert_ne!(history_master.head(), history_banana.head()); + + Ok(()) +} + +#[test] +fn me_namespace() -> Result<(), Error> { + let repo = Repository::open(GIT_PLATINUM)?; + let history = repo.history(&Branch::local(refname!("master")))?; + + assert_eq!(repo.which_namespace().unwrap(), None); + + repo.switch_namespace("me")?; + assert_eq!(repo.which_namespace().unwrap(), Some("me".parse()?)); + + let history_feature = repo.history(&Branch::local(refname!("feature/#1194")))?; + assert_eq!(history.head(), history_feature.head()); + + let expected_branches: Vec = vec![Branch::local(refname!("feature/#1194"))]; + let mut branches = repo + .branches(&Glob::heads("*")?)? + .collect::, _>>()?; + branches.sort(); + + assert_eq!(expected_branches, branches); + + let expected_branches: Vec = vec![Branch::remote( + component!("fein"), + refname!("heads/feature/#1194"), + )]; + let mut branches = repo + .branches(&Glob::remotes("fein/*")?)? + .collect::, _>>()?; + branches.sort(); + + assert_eq!(expected_branches, branches); + + Ok(()) +} + +#[test] +fn golden_namespace() -> Result<(), Error> { + let repo = Repository::open(GIT_PLATINUM)?; + let history = repo.history(&Branch::local(refname!("master")))?; + + assert_eq!(repo.which_namespace().unwrap(), None); + + repo.switch_namespace("golden")?; + + assert_eq!(repo.which_namespace().unwrap(), Some("golden".parse()?)); + + let golden_history = repo.history(&Branch::local(refname!("master")))?; + assert_eq!(history.head(), golden_history.head()); + + let expected_branches: Vec = vec![ + Branch::local(refname!("banana")), + Branch::local(refname!("master")), + ]; + let mut branches = repo + .branches(&Glob::heads("*")?)? + .collect::, _>>()?; + branches.sort(); + + assert_eq!(expected_branches, branches); + + // NOTE: these tests used to remove the categories, i.e. heads & tags, but that + // was specialised logic based on the radicle-link storage layout. + let remote = component!("kickflip"); + let expected_branches: Vec = vec![ + Branch::remote(remote.clone(), refname!("heads/fakie/bigspin")), + Branch::remote(remote.clone(), refname!("heads/heelflip")), + Branch::remote(remote, refname!("tags/v0.1.0")), + ]; + let mut branches = repo + .branches(&Glob::remotes("kickflip/*")?)? + .collect::, _>>()?; + branches.sort(); + + assert_eq!(expected_branches, branches); + + Ok(()) +} + +#[test] +fn silver_namespace() -> Result<(), Error> { + let repo = Repository::open(GIT_PLATINUM)?; + let history = repo.history(&Branch::local(refname!("master")))?; + + assert_eq!(repo.which_namespace().unwrap(), None); + + repo.switch_namespace("golden/silver")?; + assert_eq!( + repo.which_namespace().unwrap(), + Some("golden/silver".parse()?) + ); + let silver_history = repo.history(&Branch::local(refname!("master")))?; + assert_ne!(history.head(), silver_history.head()); + + let expected_branches: Vec = vec![Branch::local(refname!("master"))]; + let mut branches = repo + .branches(&Glob::heads("*")?.and_remotes("*")?)? + .collect::, _>>()?; + branches.sort(); + + assert_eq!(expected_branches, branches); + + Ok(()) +} diff --git a/radicle-surf/t/src/git/reference.rs b/radicle-surf/t/src/git/reference.rs new file mode 100644 index 0000000..ac2d4f6 --- /dev/null +++ b/radicle-surf/t/src/git/reference.rs @@ -0,0 +1,46 @@ +use radicle_surf::git::{Glob, Repository}; + +use super::GIT_PLATINUM; + +#[test] +fn test_branches() { + let repo = Repository::open(GIT_PLATINUM).unwrap(); + let branches = repo.branches(&Glob::heads("*").unwrap()).unwrap(); + for b in branches { + println!("{}", b.unwrap().refname()); + } + let branches = repo + .branches(&Glob::heads("*").unwrap().and_remotes("banana/*").unwrap()) + .unwrap(); + for b in branches { + println!("{}", b.unwrap().refname()); + } +} + +#[test] +fn test_tag_snapshot() { + let repo = Repository::open(GIT_PLATINUM).unwrap(); + let tags = repo + .tags(&Glob::tags("*").unwrap()) + .unwrap() + .collect::, _>>() + .unwrap(); + assert_eq!(tags.len(), 6); + let root_dir = repo.root_dir(&tags[0]).unwrap(); + assert_eq!(root_dir.entries(&repo).unwrap().entries().count(), 1); +} + +#[test] +fn test_namespaces() { + let repo = Repository::open(GIT_PLATINUM).unwrap(); + let namespaces = repo.namespaces(&Glob::namespaces("*").unwrap()).unwrap(); + assert_eq!(namespaces.count(), 3); + let namespaces = repo + .namespaces(&Glob::namespaces("golden/*").unwrap()) + .unwrap(); + assert_eq!(namespaces.count(), 2); + let namespaces = repo + .namespaces(&Glob::namespaces("golden/*").unwrap().and("me/*").unwrap()) + .unwrap(); + assert_eq!(namespaces.count(), 3); +} diff --git a/radicle-surf/t/src/git/rev.rs b/radicle-surf/t/src/git/rev.rs new file mode 100644 index 0000000..2b7d1b8 --- /dev/null +++ b/radicle-surf/t/src/git/rev.rs @@ -0,0 +1,92 @@ +use std::str::FromStr; + +use git_ref_format::{name::component, refname}; +use radicle_surf::git::{Branch, Error, Oid, Repository}; + +use super::GIT_PLATINUM; + +// **FIXME**: This seems to break occasionally on +// buildkite. For some reason the commit +// 3873745c8f6ffb45c990eb23b491d4b4b6182f95, which is on master +// (currently HEAD), is not found. It seems to load the history +// with d6880352fc7fda8f521ae9b7357668b17bb5bad5 as the HEAD. +// +// To temporarily fix this, we need to select "New Build" from the build kite +// build page that's failing. +// * Under "Message" put whatever you want. +// * Under "Branch" put in the branch you're working on. +// * Expand "Options" and select "clean checkout". +#[test] +fn _master() -> Result<(), Error> { + let repo = Repository::open(GIT_PLATINUM)?; + let mut history = repo.history(&Branch::remote(component!("origin"), refname!("master")))?; + + let commit1 = Oid::from_str("3873745c8f6ffb45c990eb23b491d4b4b6182f95")?; + assert!( + history.any(|commit| commit.unwrap().id == commit1), + "commit_id={}, history =\n{:#?}", + commit1, + &history + ); + + let commit2 = Oid::from_str("d6880352fc7fda8f521ae9b7357668b17bb5bad5")?; + assert!( + history.any(|commit| commit.unwrap().id == commit2), + "commit_id={}, history =\n{:#?}", + commit2, + &history + ); + + Ok(()) +} + +#[test] +fn commit() -> Result<(), Error> { + let repo = Repository::open(GIT_PLATINUM)?; + let rev = Oid::from_str("3873745c8f6ffb45c990eb23b491d4b4b6182f95")?; + let mut history = repo.history(rev)?; + + let commit1 = Oid::from_str("3873745c8f6ffb45c990eb23b491d4b4b6182f95")?; + assert!(history.any(|commit| commit.unwrap().id == commit1)); + + Ok(()) +} + +#[test] +fn commit_parents() -> Result<(), Error> { + let repo = Repository::open(GIT_PLATINUM)?; + let rev = Oid::from_str("3873745c8f6ffb45c990eb23b491d4b4b6182f95")?; + let history = repo.history(rev)?; + let commit = history.head(); + + assert_eq!( + commit.parents, + vec![Oid::from_str("d6880352fc7fda8f521ae9b7357668b17bb5bad5")?] + ); + + Ok(()) +} + +#[test] +fn commit_short() -> Result<(), Error> { + let repo = Repository::open(GIT_PLATINUM)?; + let rev = repo.oid("3873745c8")?; + let mut history = repo.history(rev)?; + + let commit1 = Oid::from_str("3873745c8f6ffb45c990eb23b491d4b4b6182f95")?; + assert!(history.any(|commit| commit.unwrap().id == commit1)); + + Ok(()) +} + +#[test] +fn tag() -> Result<(), Error> { + let repo = Repository::open(GIT_PLATINUM)?; + let rev = refname!("refs/tags/v0.2.0"); + let history = repo.history(&rev)?; + + let commit1 = Oid::from_str("2429f097664f9af0c5b7b389ab998b2199ffa977")?; + assert_eq!(history.head().id, commit1); + + Ok(()) +} diff --git a/radicle-surf/t/src/git/submodule.rs b/radicle-surf/t/src/git/submodule.rs new file mode 100644 index 0000000..1410e88 --- /dev/null +++ b/radicle-surf/t/src/git/submodule.rs @@ -0,0 +1,10 @@ +#[cfg(not(feature = "gh-actions"))] +#[test] +// An issue with submodules, see: https://github.com/radicle-dev/radicle-surf/issues/54 +fn test_submodule_failure() { + use git_ref_format::refname; + use radicle_surf::git::{Branch, Repository}; + + let repo = Repository::discover(".").unwrap(); + repo.root_dir(&Branch::local(refname!("main"))).unwrap(); +} diff --git a/radicle-surf/t/src/git/threading.rs b/radicle-surf/t/src/git/threading.rs new file mode 100644 index 0000000..7448cf0 --- /dev/null +++ b/radicle-surf/t/src/git/threading.rs @@ -0,0 +1,33 @@ +use std::sync::{Mutex, MutexGuard}; + +use git_ref_format::{name::component, refname}; +use radicle_surf::git::{Branch, Error, Glob, Repository}; + +use super::GIT_PLATINUM; + +#[test] +fn basic_test() -> Result<(), Error> { + let shared_repo = Mutex::new(Repository::open(GIT_PLATINUM)?); + let locked_repo: MutexGuard = shared_repo.lock().unwrap(); + let mut branches = locked_repo + .branches(&Glob::heads("*")?.and_remotes("*")?)? + .collect::, _>>()?; + branches.sort(); + + let origin = component!("origin"); + let banana = component!("banana"); + assert_eq!( + branches, + vec![ + Branch::local(refname!("dev")), + Branch::local(refname!("master")), + Branch::remote(banana.clone(), refname!("orange/pineapple")), + Branch::remote(banana, refname!("pineapple")), + Branch::remote(origin.clone(), refname!("HEAD")), + Branch::remote(origin.clone(), refname!("dev")), + Branch::remote(origin, refname!("master")), + ] + ); + + Ok(()) +} diff --git a/test/Cargo.toml b/test/Cargo.toml index d34790c..5e21e10 100644 --- a/test/Cargo.toml +++ b/test/Cargo.toml @@ -27,16 +27,13 @@ features = ["test"] path = "../git-trailers/t" features = ["test"] -# [dev-dependencies.gitd-lib-test] -# path = "../cli/gitd-lib/t" - [dev-dependencies.link-git-test] path = "../link-git/t" features = ["test"] [dev-dependencies.radicle-surf-test] path = "../radicle-surf/t" -features = ["test"] +features = ["serialize", "test"] [dev-dependencies.git-storage-test] path = "../git-storage/t"