diff --git a/tests/common/mod.rs b/tests/common/mod.rs index d4be8b4..550f3c4 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -1,11 +1,12 @@ #![allow(dead_code, unreachable_pub)] use std::env; +use std::ffi::OsStr; use std::path::{Path, PathBuf}; use std::process::Command; use assert_cmd::assert::OutputAssertExt; -use assert_fs::fixture::{ChildPath, PathChild}; +use assert_fs::fixture::{ChildPath, FileWriteStr, PathChild}; use etcetera::BaseStrategy; pub struct TestContext { @@ -227,6 +228,24 @@ impl TestContext { .assert() .success(); } + + /// Run `git add` in the temporary directory. + pub fn git_add(&self, path: impl AsRef) { + Command::new("git") + .arg("add") + .arg(path) + .current_dir(&self.temp_dir) + .assert() + .success(); + } + + /// Write a `.pre-commit-config.yaml` file in the temporary directory. + pub fn write_pre_commit_config(&self, content: &str) { + self.temp_dir + .child(".pre-commit-config.yaml") + .write_str(content) + .expect("Failed to write pre-commit config"); + } } #[doc(hidden)] // Macro and test context only, don't use directly. diff --git a/tests/hook_impl.rs b/tests/hook_impl.rs index ef5b924..55783be 100644 --- a/tests/hook_impl.rs +++ b/tests/hook_impl.rs @@ -1,24 +1,19 @@ -use anyhow::Result; -use assert_cmd::assert::OutputAssertExt; -use assert_fs::fixture::{FileWriteStr, PathChild}; +use std::process::Command; + use common::TestContext; use indoc::indoc; -use std::process::Command; use crate::common::cmd_snapshot; mod common; #[test] -fn hook_impl() -> Result<()> { +fn hook_impl() { let context = TestContext::new(); context.init_project(); - context - .workdir() - .child(".pre-commit-config.yaml") - .write_str(indoc! { r" + context.write_pre_commit_config(indoc! { r" repos: - repo: local hooks: @@ -28,14 +23,9 @@ fn hook_impl() -> Result<()> { entry: always fail always_run: true " - })?; + }); - Command::new("git") - .arg("add") - .current_dir(context.workdir()) - .arg(".") - .assert() - .success(); + context.git_add("."); let mut commit = Command::new("git"); commit @@ -66,6 +56,4 @@ fn hook_impl() -> Result<()> { .pre-commit-config.yaml "#); - - Ok(()) } diff --git a/tests/language.rs b/tests/language.rs index dadbc3e..843d2eb 100644 --- a/tests/language.rs +++ b/tests/language.rs @@ -1,8 +1,8 @@ -use crate::common::{cmd_snapshot, TestContext}; use anyhow::Result; -use assert_cmd::Command; use assert_fs::prelude::*; +use crate::common::{cmd_snapshot, TestContext}; + mod common; #[test] @@ -15,8 +15,7 @@ fn fail() -> Result<()> { cwd.child("changelog").create_dir_all()?; cwd.child("changelog/changelog.md").touch()?; - cwd.child(".pre-commit-config.yaml") - .write_str(indoc::indoc! {r" + context.write_pre_commit_config(indoc::indoc! {r" repos: - repo: local hooks: @@ -25,14 +24,9 @@ fn fail() -> Result<()> { entry: changelog filenames must end in .rst language: fail files: 'changelog/.*(? Result<()> { let context = TestContext::new(); + context.init_project(); let cwd = context.workdir(); - cwd.child(".pre-commit-config.yaml") - .write_str(indoc::indoc! {r" + context.write_pre_commit_config(indoc::indoc! {r" repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v5.0.0 @@ -20,24 +20,15 @@ fn run_basic() -> Result<()> { - id: trailing-whitespace - id: end-of-file-fixer - id: check-json - "})?; + "}); // Create a repository with some files. cwd.child("file.txt").write_str("Hello, world!\n")?; cwd.child("valid.json").write_str("{}")?; cwd.child("invalid.json").write_str("{}")?; cwd.child("main.py").write_str(r#"print "abc" "#)?; - Command::new("git") - .current_dir(cwd) - .arg("init") - .assert() - .success(); - Command::new("git") - .current_dir(cwd) - .arg("add") - .arg(".") - .assert() - .success(); + + context.git_add("."); cmd_snapshot!(context.filters(), context.run(), @r#" success: false @@ -84,22 +75,21 @@ fn run_basic() -> Result<()> { } #[test] -fn invalid_hook_id() -> Result<()> { +fn invalid_hook_id() { let context = TestContext::new(); context.init_project(); - context - .workdir() - .child(".pre-commit-config.yaml") - .write_str(indoc::indoc! {r" + context.write_pre_commit_config(indoc::indoc! {r" repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v5.0.0 hooks: - id: trailing-whitespace " - })?; + }); + + context.git_add("."); cmd_snapshot!(context.filters(), context.run().arg("invalid-hook-id"), @r#" success: false @@ -110,8 +100,6 @@ fn invalid_hook_id() -> Result<()> { ----- stderr ----- No hook found for id `invalid-hook-id` "#); - - Ok(()) } /// `.pre-commit-config.yaml` is not staged. @@ -123,24 +111,16 @@ fn config_not_staged() -> Result<()> { context.workdir().child(".pre-commit-config.yaml").touch()?; - Command::new("git") - .arg("add") - .arg(".") - .current_dir(context.workdir()) - .assert() - .success(); - - context - .workdir() - .child(".pre-commit-config.yaml") - .write_str(indoc::indoc! {r" + context.git_add("."); + + context.write_pre_commit_config(indoc::indoc! {r" repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v5.0.0 hooks: - id: trailing-whitespace " - })?; + }); cmd_snapshot!(context.filters(), context.run().arg("invalid-hook-id"), @r#" success: false @@ -157,15 +137,12 @@ fn config_not_staged() -> Result<()> { /// Test the output format for a hook with a CJK name. #[test] -fn cjk_hook_name() -> Result<()> { +fn cjk_hook_name() { let context = TestContext::new(); context.init_project(); - context - .workdir() - .child(".pre-commit-config.yaml") - .write_str(indoc::indoc! {r" + context.write_pre_commit_config(indoc::indoc! {r" repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v5.0.0 @@ -175,7 +152,9 @@ fn cjk_hook_name() -> Result<()> { - id: end-of-file-fixer - id: check-json " - })?; + }); + + context.git_add("."); cmd_snapshot!(context.filters(), context.run(), @r#" success: true @@ -183,27 +162,22 @@ fn cjk_hook_name() -> Result<()> { ----- stdout ----- Cloning https://github.com/pre-commit/pre-commit-hooks@v5.0.0 Installing environment for https://github.com/pre-commit/pre-commit-hooks@v5.0.0 - 去除行尾空格.........................................(no files to check)Skipped - fix end of files.....................................(no files to check)Skipped + 去除行尾空格.............................................................Passed + fix end of files.........................................................Passed check json...........................................(no files to check)Skipped ----- stderr ----- "#); - - Ok(()) } /// Skips hooks based on the `SKIP` environment variable. #[test] -fn skips() -> Result<()> { +fn skips() { let context = TestContext::new(); context.init_project(); - context - .workdir() - .child(".pre-commit-config.yaml") - .write_str(indoc::indoc! {r" + context.write_pre_commit_config(indoc::indoc! {r" repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v5.0.0 @@ -212,7 +186,9 @@ fn skips() -> Result<()> { - id: end-of-file-fixer - id: check-json " - })?; + }); + + context.git_add("."); cmd_snapshot!(context.filters(), context.run().env("SKIP", "end-of-file-fixer"), @r#" success: true @@ -220,7 +196,7 @@ fn skips() -> Result<()> { ----- stdout ----- Cloning https://github.com/pre-commit/pre-commit-hooks@v5.0.0 Installing environment for https://github.com/pre-commit/pre-commit-hooks@v5.0.0 - trim trailing whitespace.............................(no files to check)Skipped + trim trailing whitespace.................................................Passed fix end of files........................................................Skipped check json...........................................(no files to check)Skipped @@ -237,7 +213,6 @@ fn skips() -> Result<()> { ----- stderr ----- "#); - Ok(()) } /// Test global `files`, `exclude`, and hook level `files`, `exclude`. @@ -254,10 +229,7 @@ fn files_and_exclude() -> Result<()> { cwd.child("main.py").write_str(r#"print "abc" "#)?; // Global files and exclude. - context - .workdir() - .child(".pre-commit-config.yaml") - .write_str(indoc::indoc! {r" + context.write_pre_commit_config(indoc::indoc! {r" files: file.txt repos: - repo: https://github.com/pre-commit/pre-commit-hooks @@ -267,14 +239,9 @@ fn files_and_exclude() -> Result<()> { - id: end-of-file-fixer - id: check-json " - })?; + }); - Command::new("git") - .arg("add") - .arg(".") - .current_dir(cwd) - .assert() - .success(); + context.git_add("."); cmd_snapshot!(context.filters(), context.run(), @r#" success: false @@ -295,10 +262,7 @@ fn files_and_exclude() -> Result<()> { // Override hook level files and exclude. // Global files and exclude. - context - .workdir() - .child(".pre-commit-config.yaml") - .write_str(indoc::indoc! {r" + context.write_pre_commit_config(indoc::indoc! {r" repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v5.0.0 @@ -309,14 +273,9 @@ fn files_and_exclude() -> Result<()> { exclude: (valid.json|main.py) - id: check-json " - })?; + }); - Command::new("git") - .arg("add") - .arg(".") - .current_dir(cwd) - .assert() - .success(); + context.git_add("."); cmd_snapshot!(context.filters(), context.run(), @r#" success: false @@ -349,10 +308,7 @@ fn file_types() -> Result<()> { cwd.child("main.py").write_str(r#"print "abc" "#)?; // Global files and exclude. - context - .workdir() - .child(".pre-commit-config.yaml") - .write_str(indoc::indoc! {r#" + context.write_pre_commit_config(indoc::indoc! {r#" repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v5.0.0 @@ -367,14 +323,9 @@ fn file_types() -> Result<()> { types: [ "json" ] exclude_types: [ "json" ] "# - })?; + }); - Command::new("git") - .arg("add") - .arg(".") - .current_dir(cwd) - .assert() - .success(); + context.git_add("."); cmd_snapshot!(context.filters(), context.run(), @r#" success: false @@ -418,10 +369,7 @@ fn fail_fast() -> Result<()> { cwd.child("main.py").write_str(r#"print "abc" "#)?; // Global files and exclude. - context - .workdir() - .child(".pre-commit-config.yaml") - .write_str(indoc::indoc! {r#" + context.write_pre_commit_config(indoc::indoc! {r#" repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v5.0.0 @@ -434,14 +382,9 @@ fn fail_fast() -> Result<()> { - id: trailing-whitespace - id: trailing-whitespace "# - })?; + }); - Command::new("git") - .arg("add") - .arg(".") - .current_dir(cwd) - .assert() - .success(); + context.git_add("."); cmd_snapshot!(context.filters(), context.run(), @r#" success: false @@ -480,24 +423,16 @@ fn subdirectory() -> Result<()> { child.child("file.txt").write_str("Hello, world! ")?; // Global files and exclude. - context - .workdir() - .child(".pre-commit-config.yaml") - .write_str(indoc::indoc! {r" + context.write_pre_commit_config(indoc::indoc! {r" repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v5.0.0 hooks: - id: trailing-whitespace " - })?; + }); - Command::new("git") - .arg("add") - .arg(".") - .current_dir(cwd) - .assert() - .success(); + context.git_add("."); cmd_snapshot!(context.filters(), context.run().current_dir(&child).arg("--files").arg("file.txt"), @r#" success: false @@ -528,10 +463,7 @@ fn log_file() -> Result<()> { cwd.child("file.txt").write_str("Hello, world! ")?; // Global files and exclude. - context - .workdir() - .child(".pre-commit-config.yaml") - .write_str(indoc::indoc! {r" + context.write_pre_commit_config(indoc::indoc! {r" repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v5.0.0 @@ -539,14 +471,9 @@ fn log_file() -> Result<()> { - id: trailing-whitespace log_file: log.txt " - })?; + }); - Command::new("git") - .arg("add") - .arg(".") - .current_dir(cwd) - .assert() - .success(); + context.git_add("."); cmd_snapshot!(context.filters(), context.run(), @r#" success: false @@ -571,15 +498,12 @@ fn log_file() -> Result<()> { /// Pass pre-commit environment variables to the hook. #[cfg(unix)] #[test] -fn pass_env_vars() -> Result<()> { +fn pass_env_vars() { let context = TestContext::new(); context.init_project(); - context - .workdir() - .child(".pre-commit-config.yaml") - .write_str(indoc::indoc! {r#" + context.write_pre_commit_config(indoc::indoc! {r#" repos: - repo: local hooks: @@ -588,7 +512,7 @@ fn pass_env_vars() -> Result<()> { language: system entry: sh -c "echo $PRE_COMMIT > env.txt" always_run: true - "#})?; + "#}); cmd_snapshot!(context.filters(), context.run(), @r#" success: true @@ -601,6 +525,4 @@ fn pass_env_vars() -> Result<()> { let env = context.read("env.txt"); assert_eq!(env, "1\n"); - - Ok(()) } diff --git a/tests/validate.rs b/tests/validate.rs index f9ccf8b..c75e989 100644 --- a/tests/validate.rs +++ b/tests/validate.rs @@ -17,10 +17,7 @@ fn validate_config() -> anyhow::Result<()> { ----- stderr ----- "#); - context - .workdir() - .child(".pre-commit-config.yaml") - .write_str(indoc::indoc! {r" + context.write_pre_commit_config(indoc::indoc! {r" repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v5.0.0 @@ -28,7 +25,7 @@ fn validate_config() -> anyhow::Result<()> { - id: trailing-whitespace - id: end-of-file-fixer - id: check-json - "})?; + "}); // Validate one file. cmd_snapshot!(context.filters(), context.validate_config().arg(".pre-commit-config.yaml"), @r#" success: true