Trent Apted | 7246835 | 2023-07-11 16:15:57 +1000 | [diff] [blame] | 1 | # Copyright 2023 The ChromiumOS Authors |
| 2 | # Use of this source code is governed by a BSD-style license that can be |
| 3 | # found in the LICENSE file. |
| 4 | |
| 5 | """Tests for the analyzers module.""" |
| 6 | |
Trent Apted | 4d4f1bd | 2023-06-26 12:24:54 +1000 | [diff] [blame] | 7 | from typing import List |
Trent Apted | ed02b39 | 2023-06-26 12:47:11 +1000 | [diff] [blame] | 8 | from unittest import mock |
Trent Apted | 4d4f1bd | 2023-06-26 12:24:54 +1000 | [diff] [blame] | 9 | |
Trent Apted | 7246835 | 2023-07-11 16:15:57 +1000 | [diff] [blame] | 10 | from chromite.cli import analyzers |
Trent Apted | 4d4f1bd | 2023-06-26 12:24:54 +1000 | [diff] [blame] | 11 | from chromite.lib import commandline |
| 12 | |
| 13 | |
| 14 | def process_args(args: List[str]) -> commandline.ArgumentNamespace: |
| 15 | """Feeds an ArgumentParser with the provided `args` to AnalyzerCommand.""" |
| 16 | parser = commandline.ArgumentParser() |
| 17 | analyzers.AnalyzerCommand.AddParser(parser) |
| 18 | parser_namespace = parser.parse_args(args) |
| 19 | analyzers.AnalyzerCommand.ProcessOptions(parser, parser_namespace) |
| 20 | return parser_namespace |
Trent Apted | 7246835 | 2023-07-11 16:15:57 +1000 | [diff] [blame] | 21 | |
| 22 | |
Trent Apted | ed02b39 | 2023-06-26 12:47:11 +1000 | [diff] [blame] | 23 | # Patch can_modify_files to return True for additional coverage. |
| 24 | @mock.patch( |
| 25 | "chromite.cli.analyzers.AnalyzerCommand.can_modify_files", return_value=True |
| 26 | ) |
| 27 | def test_get_files_from_commit(_, run_mock) -> None: |
Trent Apted | 4d4f1bd | 2023-06-26 12:24:54 +1000 | [diff] [blame] | 28 | """Test files from commit are correctly reconstructed as absolute paths.""" |
Trent Apted | 7246835 | 2023-07-11 16:15:57 +1000 | [diff] [blame] | 29 | run_mock.AddCmdResult( |
| 30 | ["git", "rev-parse", "--show-toplevel"], stdout="/path/to/root\n" |
| 31 | ) |
Trent Apted | 4d4f1bd | 2023-06-26 12:24:54 +1000 | [diff] [blame] | 32 | run_mock.AddCmdResult( |
| 33 | ["git", "diff-tree", "--no-commit-id", "--name-only", "-r", "ignored"], |
| 34 | stdout="file1\nsub/file2\n", |
| 35 | ) |
| 36 | # There is a third, more verbose call to `git` to check for uncommitted |
| 37 | # changes. Use no output to indicate that there are none. |
| 38 | run_mock.SetDefaultCmdResult(stdout="") |
| 39 | parser_namespace = process_args(["--commit", "ignored"]) |
| 40 | assert run_mock.call_count == 3 |
| 41 | assert parser_namespace.files == [ |
Trent Apted | 7246835 | 2023-07-11 16:15:57 +1000 | [diff] [blame] | 42 | "/path/to/root/file1", |
| 43 | "/path/to/root/sub/file2", |
| 44 | ] |
| 45 | |
| 46 | |
Trent Apted | 4d4f1bd | 2023-06-26 12:24:54 +1000 | [diff] [blame] | 47 | def test_commit_is_pre_submit(run_mock) -> None: |
| 48 | """Test the special "pre-submit" commit id used by pre-upload.py.""" |
| 49 | parser_namespace = process_args(["--commit", "pre-submit"]) |
| 50 | assert not run_mock.called, "Should not call out to git." |
| 51 | assert not parser_namespace.files, "Files should remain empty." |
| 52 | |
| 53 | |
Trent Apted | 488c893 | 2023-07-27 13:44:16 +1000 | [diff] [blame^] | 54 | @mock.patch.multiple( |
| 55 | analyzers.AnalyzerCommand, can_modify_files=True, use_dryrun_options=True |
| 56 | ) |
| 57 | def test_dry_run_never_inplace() -> None: |
| 58 | """Ensure --check ignores --inplace (sets it to False).""" |
| 59 | assert process_args(["--inplace"]).inplace |
| 60 | assert not process_args(["--check"]).inplace |
| 61 | assert not process_args(["--check", "--inplace"]).inplace |
| 62 | |
| 63 | |
Trent Apted | 7246835 | 2023-07-11 16:15:57 +1000 | [diff] [blame] | 64 | def test_has_uncommitted_changes(run_mock) -> None: |
Trent Apted | 4d4f1bd | 2023-06-26 12:24:54 +1000 | [diff] [blame] | 65 | """Test handling of porcelain output for uncommitted change.""" |
Trent Apted | 7246835 | 2023-07-11 16:15:57 +1000 | [diff] [blame] | 66 | run_mock.SetDefaultCmdResult(stdout="M file\n") |
| 67 | assert analyzers.HasUncommittedChanges(["/path/to/file"]) is True |
| 68 | |
| 69 | |
| 70 | def test_has_no_uncommitted_changes(run_mock) -> None: |
Trent Apted | 4d4f1bd | 2023-06-26 12:24:54 +1000 | [diff] [blame] | 71 | """Test handling of porcelain output when no uncommitted changes.""" |
Trent Apted | 7246835 | 2023-07-11 16:15:57 +1000 | [diff] [blame] | 72 | run_mock.SetDefaultCmdResult(stdout="") |
| 73 | assert analyzers.HasUncommittedChanges(["/path/to/file"]) is False |