Coverage for tests / unit / tools / shfmt / test_error_handling.py: 100%
47 statements
« prev ^ index » next coverage.py v7.13.0, created at 2026-04-03 18:53 +0000
« prev ^ index » next coverage.py v7.13.0, created at 2026-04-03 18:53 +0000
1"""Unit tests for shfmt plugin error handling."""
3from __future__ import annotations
5import subprocess
6from pathlib import Path
7from typing import TYPE_CHECKING
8from unittest.mock import patch
10from assertpy import assert_that
12from lintro.parsers.shfmt.shfmt_parser import parse_shfmt_output
13from lintro.tools.definitions.shfmt import ShfmtPlugin
15if TYPE_CHECKING:
16 pass
19# =============================================================================
20# Tests for timeout handling
21# =============================================================================
24def test_check_with_timeout(
25 shfmt_plugin: ShfmtPlugin,
26 tmp_path: Path,
27) -> None:
28 """Check handles timeout correctly.
30 Args:
31 shfmt_plugin: The ShfmtPlugin instance to test.
32 tmp_path: Temporary directory path for test files.
33 """
34 test_file = tmp_path / "test_script.sh"
35 test_file.write_text('#!/bin/bash\necho "hello"\n')
37 with patch(
38 "lintro.plugins.execution_preparation.verify_tool_version",
39 return_value=None,
40 ):
41 with patch.object(
42 shfmt_plugin,
43 "_run_subprocess",
44 side_effect=subprocess.TimeoutExpired(cmd=["shfmt"], timeout=30),
45 ):
46 result = shfmt_plugin.check([str(test_file)], {})
48 assert_that(result.success).is_false()
51def test_fix_with_timeout(
52 shfmt_plugin: ShfmtPlugin,
53 tmp_path: Path,
54) -> None:
55 """Fix handles timeout correctly.
57 Args:
58 shfmt_plugin: The ShfmtPlugin instance to test.
59 tmp_path: Temporary directory path for test files.
60 """
61 test_file = tmp_path / "test_script.sh"
62 test_file.write_text('#!/bin/bash\necho "hello"\n')
64 with patch(
65 "lintro.plugins.execution_preparation.verify_tool_version",
66 return_value=None,
67 ):
68 with patch.object(
69 shfmt_plugin,
70 "_run_subprocess",
71 side_effect=subprocess.TimeoutExpired(cmd=["shfmt"], timeout=30),
72 ):
73 result = shfmt_plugin.fix([str(test_file)], {})
75 assert_that(result.success).is_false()
78# =============================================================================
79# Tests for output parsing
80# =============================================================================
83def test_parse_shfmt_output_single_file() -> None:
84 """Parse single file diff from shfmt output."""
85 output = """--- script.sh
86+++ script.sh
87@@ -1,3 +1,3 @@
88-if [ "$foo" = "bar" ]; then
89+if [ "$foo" = "bar" ]; then
90 echo "match"
91 fi"""
92 issues = parse_shfmt_output(output)
94 assert_that(issues).is_length(1)
95 assert_that(issues[0].file).is_equal_to("script.sh")
96 assert_that(issues[0].line).is_equal_to(1)
97 assert_that(issues[0].message).contains("Needs formatting")
98 assert_that(issues[0].fixable).is_true()
101def test_parse_shfmt_output_multiple_files() -> None:
102 """Parse multiple files diff from shfmt output."""
103 output = """--- script1.sh
104+++ script1.sh
105@@ -1,2 +1,2 @@
106-echo "hello"
107+echo "hello"
108--- script2.sh
109+++ script2.sh
110@@ -1,2 +1,2 @@
111-if [ 1 ]; then
112+if [ 1 ]; then"""
113 issues = parse_shfmt_output(output)
115 assert_that(issues).is_length(2)
116 assert_that(issues[0].file).is_equal_to("script1.sh")
117 assert_that(issues[1].file).is_equal_to("script2.sh")
120def test_parse_shfmt_output_empty() -> None:
121 """Parse empty output returns empty list."""
122 issues = parse_shfmt_output("")
124 assert_that(issues).is_empty()
127def test_parse_shfmt_output_none() -> None:
128 """Parse None output returns empty list."""
129 issues = parse_shfmt_output(None)
131 assert_that(issues).is_empty()
134def test_parse_shfmt_output_with_orig_suffix() -> None:
135 """Parse diff with .orig suffix in header."""
136 output = """--- script.sh.orig
137+++ script.sh
138@@ -1,2 +1,2 @@
139-echo "hello"
140+echo "hello" """
141 issues = parse_shfmt_output(output)
143 assert_that(issues).is_length(1)
144 assert_that(issues[0].file).is_equal_to("script.sh")