Repository: jorisroovers/gitlint (language: python)

Issue:
Integration tests don't run on Windows
The integration tests don't run on windows since they depend on `sh`.

To run the tests (without `./run_tests.sh` which is a bash script):
```sh
pytest -rw -s qa/
```

To fix this, we should implement the same sh mock library that in the integration tests that we did for the main gitlint codebase. 



Discussion / hints:
c889121 partially solves the dependency on sh, but I still need to implement a solution for the std I/O interaction functions that are used in various places of the integration tests. Example: https://github.com/jorisroovers/gitlint/blob/6cf5cc60fb53ac5a9e9ec8493d929859befe3844/qa/test_hooks.py#L43-L49

`sh` allows you to pass these via the `out` argument which is useful and intuitive.

Also, when running the integration tests on Windows 10 (Python 3.7), I'm encountering  `UnicodeDecodeError`s, so there will be more work related to that as well.

We'll get there - just might take a while :-)
Fixed a bunch of tests in #392.

Still failing:
- The hook tests, but that's expected since they still depend on the `sh` library. These tests also still fail when running the integration tests on linux without `sh`. I intent to look into fixing this soonish (as part of 0.19.0 release iteration).
- About a half dozen other tests. What's interesting is that some of these seem to pass on GHA but fail locally on windows. More investigation needed for these
```sh
qa/test_commits.py::CommitsTests::test_lint_staged_stdin FAILED 
qa/test_gitlint.py::IntegrationTests::test_git_empty_repo_staged FAILED # passes on CI?
qa/test_stdin.py::StdInTests::test_stdin_file FAILED
qa/test_stdin.py::StdInTests::test_stdin_pipe FAILED # passes on CI
qa/test_stdin.py::StdInTests::test_stdin_pipe_empty FAILED
``` 

Regardless, this is good progress since we can now run integration tests on windows on part of CI, something we've never done before.

Fix patch:
diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml
index 86b5d940..d710273c 100644
--- a/.github/workflows/checks.yml
+++ b/.github/workflows/checks.yml
@@ -52,7 +52,7 @@ jobs:
 
       - name: Integration tests (GITLINT_QA_USE_SH_LIB=0)
         run: |
-          hatch run qa:integration-tests --ignore qa/test_hooks.py qa
+          hatch run qa:integration-tests -k "not(test_commit_hook_continue or test_commit_hook_abort or test_commit_hook_edit)" qa
         env:
           GITLINT_QA_USE_SH_LIB: 0
 
@@ -134,7 +134,7 @@ jobs:
       - name: Integration tests
         run: |
           hatch run qa:install-local
-          hatch run qa:integration-tests -k "not (HookTests or test_lint_staged_stdin or test_stdin_file or test_stdin_pipe_empty)" qa
+          hatch run qa:integration-tests -k "not (test_commit_hook_continue or test_commit_hook_abort or test_commit_hook_edit or test_lint_staged_stdin or test_stdin_file or test_stdin_pipe_empty)" qa
 
       - name: Build test (gitlint)
         run: |


Test patch:
diff --git a/qa/test_hooks.py b/qa/test_hooks.py
index 19edeb25..6867a35c 100644
--- a/qa/test_hooks.py
+++ b/qa/test_hooks.py
@@ -30,18 +30,16 @@ def setUp(self):
 
         # install git commit-msg hook and assert output
         output_installed = gitlint("install-hook", _cwd=self.tmp_git_repo)
-        expected_installed = (
-            f"Successfully installed gitlint commit-msg hook in {self.tmp_git_repo}/.git/hooks/commit-msg\n"
-        )
+        commit_msg_hook_path = os.path.join(self.tmp_git_repo, ".git", "hooks", "commit-msg")
+        expected_installed = f"Successfully installed gitlint commit-msg hook in {commit_msg_hook_path}\n"
 
         self.assertEqualStdout(output_installed, expected_installed)
 
     def tearDown(self):
         # uninstall git commit-msg hook and assert output
         output_uninstalled = gitlint("uninstall-hook", _cwd=self.tmp_git_repo)
-        expected_uninstalled = (
-            f"Successfully uninstalled gitlint commit-msg hook from {self.tmp_git_repo}/.git/hooks/commit-msg\n"
-        )
+        commit_msg_hook_path = os.path.join(self.tmp_git_repo, ".git", "hooks", "commit-msg")
+        expected_uninstalled = f"Successfully uninstalled gitlint commit-msg hook from {commit_msg_hook_path}\n"
 
         self.assertEqualStdout(output_uninstalled, expected_uninstalled)
         super().tearDown()
@@ -171,10 +169,10 @@ def test_commit_hook_worktree(self):
 
         output_installed = gitlint("install-hook", _cwd=worktree_dir)
         expected_hook_path = os.path.join(tmp_git_repo, ".git", "hooks", "commit-msg")
-        expected_msg = f"Successfully installed gitlint commit-msg hook in {expected_hook_path}\r\n"
-        self.assertEqual(output_installed, expected_msg)
+        expected_msg = f"Successfully installed gitlint commit-msg hook in {expected_hook_path}\n"
+        self.assertEqualStdout(output_installed, expected_msg)
 
         output_uninstalled = gitlint("uninstall-hook", _cwd=worktree_dir)
         expected_hook_path = os.path.join(tmp_git_repo, ".git", "hooks", "commit-msg")
-        expected_msg = f"Successfully uninstalled gitlint commit-msg hook from {expected_hook_path}\r\n"
-        self.assertEqual(output_uninstalled, expected_msg)
+        expected_msg = f"Successfully uninstalled gitlint commit-msg hook from {expected_hook_path}\n"
+        self.assertEqualStdout(output_uninstalled, expected_msg)