diff --git a/src/cli.rs b/src/cli.rs index 99b622a..4115b29 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,5 +1,5 @@ -use clap::{ArgGroup, Parser, Subcommand}; use super::commands as cmd; +use clap::{ArgGroup, Parser, Subcommand}; /// Rust实现的简易版本的Git,用于学习Rust语言 #[derive(Parser)] #[command(author, version, about, long_about = None)] @@ -14,7 +14,6 @@ enum Command { /// 初始化仓库 Init, /// 添加文件到暂存区 - /// @see git add .,git add -A,git add -u,git add * 的区别与联系 Add { /// 要添加的文件 files: Vec, diff --git a/src/commands/add.rs b/src/commands/add.rs index d3aeea6..b12fd21 100644 --- a/src/commands/add.rs +++ b/src/commands/add.rs @@ -8,6 +8,7 @@ use crate::models::*; use crate::utils::util; /// add是对index的操作,不会对工作区产生影响 +/// @see git add .,git add -A,git add -u,git add * 的区别与联系 pub fn add(raw_paths: Vec, all: bool, mut update: bool) { util::check_repo_exist(); diff --git a/src/commands/branch.rs b/src/commands/branch.rs index 50f02f1..889454e 100644 --- a/src/commands/branch.rs +++ b/src/commands/branch.rs @@ -2,7 +2,7 @@ use colored::Colorize; use crate::{ models::*, - utils::{head, store, util}, + utils::{store, util}, }; // branch error @@ -126,10 +126,10 @@ pub fn branch( #[cfg(test)] mod test { use super::*; - use crate::{commands, utils::test_util}; + use crate::{commands, utils::test}; #[test] fn test_create_branch() { - test_util::setup_test_with_clean_mit(); + test::setup_with_clean_mit(); // no commit: invalid object let result = create_branch("test_branch".to_string(), head::current_head_commit()); @@ -170,7 +170,7 @@ mod test { #[test] fn test_delete_branch() { - test_util::setup_test_with_clean_mit(); + test::setup_with_clean_mit(); // no commit: invalid object let result = delete_branch("test_branch".to_string()); diff --git a/src/commands/commit.rs b/src/commands/commit.rs index 24b46b8..3354a0e 100644 --- a/src/commands/commit.rs +++ b/src/commands/commit.rs @@ -1,4 +1,4 @@ -use crate::{models::*, utils::head}; +use crate::models::*; use super::status; @@ -38,33 +38,30 @@ pub fn commit(message: String, allow_empty: bool) { mod test { use std::path::Path; - use crate::{ - commands as cmd, models, - utils::{head, test_util}, - }; + use crate::{commands as cmd, models::*, utils::test}; #[test] #[should_panic] fn test_commit_empty() { - test_util::setup_test_with_empty_workdir(); + test::setup_with_empty_workdir(); super::commit("".to_string(), false); } #[test] fn test_commit() { - test_util::setup_test_with_clean_mit(); + test::setup_with_clean_mit(); let test_file = "a.txt"; let head_one = head::current_head_commit(); assert!(head_one.is_empty()); - test_util::ensure_test_file(&Path::new(test_file), "test content".into()); + test::ensure_file(&Path::new(test_file), "test content".into()); cmd::add(vec![], true, false); cmd::commit("test commit 1".to_string(), true); let head_two = head::current_head_commit(); assert!(head_two.len() > 0); - let commit = models::commit::Commit::load(&head_two); - assert!(commit.get_parent_hash().len() == 0); - assert!(commit.get_message() == "test commit 1"); + let commit = Commit::load(&head_two); + assert_eq!(commit.get_parent_hash().len(), 0); + assert_eq!(commit.get_message(), "test commit 1"); } } diff --git a/src/commands/log.rs b/src/commands/log.rs index e2ea6b6..f60a43c 100644 --- a/src/commands/log.rs +++ b/src/commands/log.rs @@ -1,4 +1,4 @@ -use crate::{models::Commit, utils::head}; +use crate::models::{head, Commit}; use colored::Colorize; const DEFAULT_LOG_NUMBER: usize = 10; @@ -70,10 +70,10 @@ fn __log(all: bool, number: Option) -> usize { #[cfg(test)] mod test { use super::super::super::commands; - use crate::utils::test_util; + use crate::utils::test; #[test] fn test_log() { - test_util::setup_test_with_clean_mit(); + test::setup_with_clean_mit(); assert_eq!(super::__log(false, None), 0); commands::commit::commit("test commit 2".into(), true); assert_eq!(super::__log(false, Some(1)), 1); diff --git a/src/commands/merge.rs b/src/commands/merge.rs index 3c7cf01..0b338c0 100644 --- a/src/commands/merge.rs +++ b/src/commands/merge.rs @@ -1,7 +1,7 @@ use crate::{ commands::{self, status::*}, - models::{Commit, Hash}, - utils::{head, store, util}, + models::{head, Commit, Hash}, + utils::{store, util}, }; enum MergeErr { @@ -83,12 +83,12 @@ mod test { use super::*; use crate::{ commands::{commit, switch::switch}, - utils::test_util, + utils::test, }; #[test] fn test_check_ff() { - test_util::setup_test_with_empty_workdir(); + test::setup_with_empty_workdir(); commit::commit("init".to_string(), true); let commit1 = head::current_head_commit(); let origin_branch = match head::current_head() { diff --git a/src/commands/restore.rs b/src/commands/restore.rs index 14cb5dd..5c98e5b 100644 --- a/src/commands/restore.rs +++ b/src/commands/restore.rs @@ -6,7 +6,7 @@ use std::{ use crate::{ models::*, - utils::{head, store, util}, + utils::{store, util}, }; /// 统计[工作区]中相对于target_blobs已删除的文件(根据filters进行过滤) @@ -216,14 +216,14 @@ pub fn restore(paths: Vec, source: Option, worktree: bool, stage mod test { use std::fs; //TODO 写测试! - use crate::{commands as cmd, commands::status, models::Index, utils::test_util}; + use crate::{commands as cmd, commands::status, models::Index, utils::test}; use std::path::PathBuf; #[test] fn test_restore_stage() { - test_util::setup_test_with_empty_workdir(); + test::setup_with_empty_workdir(); let path = PathBuf::from("a.txt"); - test_util::ensure_no_file(&path); + test::ensure_no_file(&path); cmd::add(vec![], true, false); //add -A cmd::restore(vec![".".to_string()], Some("HEAD".to_string()), false, true); let index = Index::get_instance(); @@ -232,9 +232,9 @@ mod test { #[test] fn test_restore_worktree() { - test_util::setup_test_with_empty_workdir(); + test::setup_with_empty_workdir(); let files = vec!["a.txt", "b.txt", "c.txt", "test/in.txt"]; - test_util::ensure_test_files(&files); + test::ensure_files(&files); cmd::add(vec![], true, false); assert_eq!(status::changes_to_be_committed().new.iter().count(), 4); diff --git a/src/commands/status.rs b/src/commands/status.rs index 21a73ee..9dc844d 100644 --- a/src/commands/status.rs +++ b/src/commands/status.rs @@ -1,6 +1,5 @@ use crate::{ - utils::head, - models::{Commit, Index}, + models::{head, Commit, Index}, utils::util, }; use colored::Colorize; @@ -196,14 +195,14 @@ pub fn status() { #[cfg(test)] mod tests { use super::*; - use crate::{commands as cmd, utils::test_util}; + use crate::{commands as cmd, utils::test}; use std::path::Path; #[test] fn test_changes_to_be_committed() { - test_util::setup_test_with_empty_workdir(); + test::setup_with_empty_workdir(); let test_file = "a.txt"; - test_util::ensure_test_file(Path::new(test_file), None); + test::ensure_file(Path::new(test_file), None); cmd::commit("test commit".to_string(), true); cmd::add(vec![test_file.to_string()], false, false); @@ -215,7 +214,7 @@ mod tests { println!("{:?}", change.to_absolute()); cmd::commit("test commit".to_string(), true); - test_util::ensure_test_file(Path::new(test_file), Some("new content")); + test::ensure_file(Path::new(test_file), Some("new content")); cmd::add(vec![test_file.to_string()], false, false); let change = changes_to_be_committed(); assert_eq!(change.new.len(), 0); diff --git a/src/commands/switch.rs b/src/commands/switch.rs index 90053a1..d46ad93 100644 --- a/src/commands/switch.rs +++ b/src/commands/switch.rs @@ -1,8 +1,8 @@ use colored::Colorize; use crate::{ - models::{Commit, Hash}, - utils::{head, store, util}, + models::{head, Commit, Hash}, + utils::{store, util}, }; use super::{ @@ -88,12 +88,12 @@ mod test { use super::*; use crate::{ commands::{self as cmd}, - utils::test_util, + utils::test, }; use std::path::PathBuf; #[test] fn test_switch() { - test_util::setup_test_with_empty_workdir(); + test::setup_with_empty_workdir(); cmd::commit("init".to_string(), true); let test_branch_1 = "test_branch_1".to_string(); @@ -101,7 +101,7 @@ mod test { /* test 1: NoClean */ let test_file_1 = PathBuf::from("test_file_1"); - test_util::ensure_test_file(&test_file_1, None); + test::ensure_file(&test_file_1, None); let result = switch_to(test_branch_1.clone(), false); assert!(result.is_err()); assert!(matches!(result.unwrap_err(), SwitchErr::NoClean)); @@ -122,12 +122,12 @@ mod test { assert!(matches!(result.unwrap_err(), SwitchErr::InvalidObject)); let tees_file_2 = PathBuf::from("test_file_2"); - test_util::ensure_test_file(&tees_file_2, None); + test::ensure_file(&tees_file_2, None); cmd::add(vec![], true, false); // add all cmd::commit("add file 2".to_string(), false); let history_commit = head::current_head_commit(); // commit: test_file_1 exists, test_file_2 exists - test_util::ensure_no_file(&test_file_1); + test::ensure_no_file(&test_file_1); cmd::add(vec![], true, false); // add all assert!(!test_file_1.exists()); cmd::commit("delete file 1".to_string(), false); diff --git a/src/models/commit.rs b/src/models/commit.rs index 23442f2..5710f80 100644 --- a/src/models/commit.rs +++ b/src/models/commit.rs @@ -82,11 +82,11 @@ impl Commit { #[cfg(test)] mod test { - use crate::utils::test_util; + use crate::utils::test; #[test] fn test_commit() { - test_util::setup_test_with_clean_mit(); + test::setup_with_clean_mit(); let index = super::Index::get_instance(); let mut commit = super::Commit::new(&index, vec!["123".to_string(), "456".to_string()], "test".to_string()); diff --git a/src/utils/head.rs b/src/models/head.rs similarity index 93% rename from src/utils/head.rs rename to src/models/head.rs index 984a65d..ad530ee 100644 --- a/src/utils/head.rs +++ b/src/models/head.rs @@ -113,12 +113,12 @@ pub fn change_head_to_commit(commit_hash: &String) { #[cfg(test)] mod test { - use crate::utils::test_util; - use crate::utils::head; + use crate::models::head; + use crate::utils::test; #[test] fn test_edit_branch() { - test_util::setup_test_with_clean_mit(); + test::setup_with_clean_mit(); let branch_name = "test_branch".to_string() + &rand::random::().to_string(); let branch_head = super::get_branch_head(&branch_name); assert!(branch_head.is_empty()); @@ -127,12 +127,12 @@ mod test { super::update_branch(&branch_name, &commit_hash); let branch_head = super::get_branch_head(&branch_name); assert!(!branch_head.is_empty()); - assert!(branch_head == commit_hash); + assert_eq!(branch_head, commit_hash); } #[test] fn test_list_local_branches() { - test_util::setup_test_with_clean_mit(); + test::setup_with_clean_mit(); let branch_one = "test_branch".to_string() + &rand::random::().to_string(); let branch_two = "test_branch".to_string() + &rand::random::().to_string(); head::update_branch(&branch_one, &"1234567890".to_string()); @@ -145,7 +145,7 @@ mod test { #[test] fn test_change_head_to_branch() { - test_util::setup_test_with_clean_mit(); + test::setup_with_clean_mit(); let branch_name = "test_branch".to_string() + &rand::random::().to_string(); head::update_branch(&branch_name, &"1234567890".to_string()); super::change_head_to_branch(&branch_name); @@ -160,7 +160,7 @@ mod test { #[test] fn test_change_head_to_commit() { - test_util::setup_test_with_clean_mit(); + test::setup_with_clean_mit(); let commit_hash = "1234567890".to_string(); super::change_head_to_commit(&commit_hash); assert!( @@ -174,12 +174,12 @@ mod test { #[test] fn test_update_branch_head() { - test_util::setup_test_with_clean_mit(); + test::setup_with_clean_mit(); let branch_name = "test_branch".to_string() + &rand::random::().to_string(); let commit_hash = "1234567890".to_string(); super::update_branch(&branch_name, &commit_hash); let branch_head = super::get_branch_head(&branch_name); assert!(!branch_head.is_empty()); - assert!(branch_head == commit_hash); + assert_eq!(branch_head, commit_hash); } } diff --git a/src/models/index.rs b/src/models/index.rs index b6afb98..964b7d3 100644 --- a/src/models/index.rs +++ b/src/models/index.rs @@ -209,12 +209,12 @@ impl Index { #[cfg(test)] mod tests { use super::*; - use crate::utils::test_util; + use crate::utils::test; use std::fs; #[test] fn test_meta_get() { - test_util::setup_test_with_clean_mit(); + test::setup_with_clean_mit(); let metadata = fs::metadata(".mit/HEAD").unwrap(); println!("{:?}", util::format_time(&metadata.created().unwrap())); println!("{:?}", util::format_time(&metadata.modified().unwrap())); @@ -223,20 +223,20 @@ mod tests { #[test] fn test_load() { - test_util::setup_test_with_clean_mit(); + test::setup_with_clean_mit(); let index = Index::get_instance(); println!("{:?}", index); } #[test] fn test_save() { - test_util::setup_test_with_clean_mit(); + test::setup_with_clean_mit(); let index = Index::get_instance(); let path = PathBuf::from("../mit_test_storage/.mit/HEAD"); //测试../相对路径的处理 index.add(path.clone(), FileMetaData::new(&Blob::new(&path), &path)); let 中文路径 = "中文路径.txt"; - test_util::ensure_test_file(Path::new(中文路径), None); + test::ensure_file(Path::new(中文路径), None); let path = PathBuf::from(中文路径); index.add(path.clone(), FileMetaData::new(&Blob::new(&path), &path)); index.save(); @@ -245,7 +245,7 @@ mod tests { #[test] fn test_save_load() { - test_util::setup_test_with_empty_workdir(); + test::setup_with_empty_workdir(); let index = Index::get_instance(); let path = PathBuf::from(".mit/HEAD"); index.add(path.clone(), FileMetaData::new(&Blob::new(&path), &path)); diff --git a/src/models/mod.rs b/src/models/mod.rs index 7245fad..0faaeed 100644 --- a/src/models/mod.rs +++ b/src/models/mod.rs @@ -7,5 +7,7 @@ pub use index::FileMetaData; pub use index::Index; pub mod object; pub use object::Hash; +pub mod head; pub mod tree; + pub use tree::Tree; diff --git a/src/models/tree.rs b/src/models/tree.rs index c8d7721..76dabb1 100644 --- a/src/models/tree.rs +++ b/src/models/tree.rs @@ -159,16 +159,16 @@ mod test { use crate::{ models::*, - utils::{util, test_util}, + utils::{test, util}, }; #[test] fn test_new() { - test_util::setup_test_with_clean_mit(); + test::setup_with_clean_mit(); let index = Index::get_instance(); for test_file in vec!["b.txt", "mit_src/a.txt", "test/test.txt"] { let test_file = PathBuf::from(test_file); - test_util::ensure_test_file(&test_file, None); + test::ensure_file(&test_file, None); index.add(test_file.clone(), FileMetaData::new(&Blob::new(&test_file), &test_file)); index.add(test_file.clone(), FileMetaData::new(&Blob::new(&test_file), &test_file)); } @@ -180,12 +180,12 @@ mod test { #[test] fn test_load() { - test_util::setup_test_with_clean_mit(); + test::setup_with_clean_mit(); let index = Index::get_instance(); let test_files = vec!["b.txt", "mit_src/a.txt"]; for test_file in test_files.clone() { let test_file = PathBuf::from(test_file); - test_util::ensure_test_file(&test_file, None); + test::ensure_file(&test_file, None); index.add(test_file.clone(), FileMetaData::new(&Blob::new(&test_file), &test_file)); } @@ -200,11 +200,11 @@ mod test { #[test] fn test_get_recursive_file_entries() { - test_util::setup_test_with_clean_mit(); + test::setup_with_clean_mit(); let index = Index::get_instance(); let mut test_files = vec![PathBuf::from("b.txt"), PathBuf::from("mit_src/a.txt")]; for test_file in test_files.clone() { - test_util::ensure_test_file(&test_file, None); + test::ensure_file(&test_file, None); index.add(test_file.clone(), FileMetaData::new(&Blob::new(&test_file), &test_file)); } @@ -228,13 +228,13 @@ mod test { #[test] fn test_get_recursive_blobs() { - test_util::setup_test_with_clean_mit(); + test::setup_with_clean_mit(); let index = Index::get_instance(); let test_files = vec!["b.txt", "mit_src/a.txt"]; let mut test_blobs = vec![]; for test_file in test_files.clone() { let test_file = PathBuf::from(test_file); - test_util::ensure_test_file(&test_file, None); + test::ensure_file(&test_file, None); let blob = Blob::new(&test_file); test_blobs.push(blob.clone()); index.add(test_file.clone(), FileMetaData::new(&Blob::new(&test_file), &test_file)); diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 36e49f6..381e0a1 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1,4 +1,3 @@ -pub mod util; -pub mod head; pub mod store; -pub mod test_util; \ No newline at end of file +pub mod test; +pub mod util; diff --git a/src/utils/store.rs b/src/utils/store.rs index f0441da..5299172 100644 --- a/src/utils/store.rs +++ b/src/utils/store.rs @@ -87,24 +87,24 @@ mod tests { use std::fs; use super::*; - use crate::utils::test_util; + use crate::utils::test; #[test] fn test_new_success() { - test_util::setup_test_with_clean_mit(); + test::setup_with_clean_mit(); let _ = Store::new(); } #[test] #[should_panic] fn test_new_fail() { - test_util::setup_test_without_mit(); + test::setup_without_mit(); let _ = Store::new(); } #[test] fn test_save_and_load() { - let _ = test_util::setup_test_with_clean_mit(); + let _ = test::setup_with_clean_mit(); let store = Store::new(); let content = "hello world".to_string(); let hash = store.save(&content); @@ -114,7 +114,7 @@ mod tests { #[test] fn test_search() { - test_util::setup_test_with_clean_mit(); + test::setup_with_clean_mit(); let hashs = vec!["1234567890".to_string(), "1235467891".to_string(), "4567892".to_string()]; for hash in hashs.iter() { let mut path = util::get_storage_path().unwrap(); diff --git a/src/utils/test_util.rs b/src/utils/test.rs similarity index 85% rename from src/utils/test_util.rs rename to src/utils/test.rs index 27d849b..039b0d8 100644 --- a/src/utils/test_util.rs +++ b/src/utils/test.rs @@ -1,17 +1,15 @@ #![cfg(test)] - -pub const TEST_DIR: &str = "mit_test_storage"; +/** tools for test */ +use crate::models::Index; use std::{ fs, io::{self, Write}, path::{Path, PathBuf}, }; -use crate::models::Index; - -// 执行测试的储存库 use super::util; -/* tools for test */ + +pub const TEST_DIR: &str = "mit_test_storage"; fn find_cargo_dir() -> PathBuf { let cargo_path = std::env::var("CARGO_MANIFEST_DIR"); if cargo_path.is_err() { @@ -34,7 +32,7 @@ fn find_cargo_dir() -> PathBuf { } /// 准备测试环境,切换到测试目录 -fn setup_test_env() { +fn setup_env() { color_backtrace::install(); // colorize backtrace let mut path = find_cargo_dir(); @@ -51,14 +49,14 @@ pub fn init_mit() { } /// with 初始化的干净的mit -pub fn setup_test_with_clean_mit() { - setup_test_without_mit(); +pub fn setup_with_clean_mit() { + setup_without_mit(); init_mit(); } -pub fn setup_test_without_mit() { +pub fn setup_without_mit() { // 将执行目录切换到测试目录,并清除测试目录下的.mit目录 - setup_test_env(); + setup_env(); let mut path = util::cur_dir(); path.push(util::ROOT_DIR); if path.exists() { @@ -66,9 +64,9 @@ pub fn setup_test_without_mit() { } } -pub fn ensure_test_files>(paths: &Vec) { +pub fn ensure_files>(paths: &Vec) { for path in paths { - ensure_test_file(path.as_ref().as_ref(), None); + ensure_file(path.as_ref().as_ref(), None); } } @@ -85,13 +83,13 @@ pub fn ensure_empty_dir>(path: P) -> io::Result<()> { Ok(()) } -pub fn setup_test_with_empty_workdir() { +pub fn setup_with_empty_workdir() { let test_dir = find_cargo_dir().join(TEST_DIR); ensure_empty_dir(&test_dir).unwrap(); - setup_test_with_clean_mit(); + setup_with_clean_mit(); } -pub fn ensure_test_file(path: &Path, content: Option<&str>) { +pub fn ensure_file(path: &Path, content: Option<&str>) { // 以测试目录为根目录,创建文件 fs::create_dir_all(path.parent().unwrap()).unwrap(); // ensure父目录 let mut file = fs::File::create(util::get_working_dir().unwrap().join(path)) diff --git a/src/utils/util.rs b/src/utils/util.rs index 1520b7d..eb2618e 100644 --- a/src/utils/util.rs +++ b/src/utils/util.rs @@ -431,7 +431,7 @@ pub fn is_typeof_commit(hash: Hash) -> bool { mod tests { use crate::{ models::{blob::Blob, index::Index}, - utils::{test_util, util::*}, + utils::{test, util::*}, }; #[test] @@ -474,7 +474,7 @@ mod tests { #[test] fn test_get_relative_path() { - test_util::setup_test_with_clean_mit(); + test::setup_with_clean_mit(); let path = Path::new("../../src\\main.rs"); let rel_path = get_relative_path(&path, &cur_dir()); println!("{:?}", rel_path); @@ -484,7 +484,7 @@ mod tests { #[test] fn test_to_workdir_absolute_path() { - test_util::setup_test_with_clean_mit(); + test::setup_with_clean_mit(); let path = Path::new("./src/../main.rs"); let abs_path = to_workdir_absolute_path(path); println!("{:?}", abs_path); @@ -496,7 +496,7 @@ mod tests { #[test] fn test_is_inside_repo() { - test_util::setup_test_with_clean_mit(); + test::setup_with_clean_mit(); let path = Path::new("../Cargo.toml"); assert_eq!(is_inside_workdir(path), false); @@ -514,10 +514,10 @@ mod tests { #[test] fn test_list_files() { - test_util::setup_test_with_clean_mit(); - test_util::ensure_test_file(Path::new("test/test.txt"), None); - test_util::ensure_test_file(Path::new("a.txt"), None); - test_util::ensure_test_file(Path::new("b.txt"), None); + test::setup_with_clean_mit(); + test::ensure_file(Path::new("test/test.txt"), None); + test::ensure_file(Path::new("a.txt"), None); + test::ensure_file(Path::new("b.txt"), None); let files = list_files(Path::new("./")); match files { Ok(files) => { @@ -533,9 +533,9 @@ mod tests { #[test] fn test_check_object_type() { - test_util::setup_test_with_clean_mit(); + test::setup_with_clean_mit(); assert_eq!(check_object_type("123".into()), ObjectType::Invalid); - test_util::ensure_test_file(Path::new("test.txt"), Some("test")); + test::ensure_file(Path::new("test.txt"), Some("test")); let hash = Blob::new(get_working_dir().unwrap().join("test.txt").as_path()).get_hash(); assert_eq!(check_object_type(hash), ObjectType::Blob); let mut commit = Commit::new(&Index::get_instance(), vec![], "test".to_string()); @@ -546,7 +546,7 @@ mod tests { #[test] fn test_check_root_dir() { - test_util::setup_test_with_clean_mit(); + test::setup_with_clean_mit(); list_workdir_files().iter().for_each(|f| { fs::remove_file(f).unwrap(); });