Coverage for tests / unit / tools / prettier / test_fix_method.py: 100%

42 statements  

« prev     ^ index     » next       coverage.py v7.13.0, created at 2026-04-03 18:53 +0000

1"""Tests for PrettierPlugin.fix method.""" 

2 

3from __future__ import annotations 

4 

5import subprocess 

6from typing import TYPE_CHECKING, Any 

7from unittest.mock import MagicMock, patch 

8 

9from assertpy import assert_that 

10 

11if TYPE_CHECKING: 

12 from lintro.tools.definitions.prettier import PrettierPlugin 

13 

14 

15def test_fix_success_no_issues( 

16 prettier_plugin: PrettierPlugin, 

17 mock_execution_context_for_tool: Any, 

18) -> None: 

19 """Fix returns success when no issues to fix. 

20 

21 Args: 

22 prettier_plugin: The PrettierPlugin instance to test. 

23 mock_execution_context_for_tool: Mock execution context factory. 

24 """ 

25 with ( 

26 patch.object(prettier_plugin, "_prepare_execution") as mock_prepare, 

27 patch.object(prettier_plugin, "_run_subprocess") as mock_run, 

28 patch.object(prettier_plugin, "_get_executable_command") as mock_exec, 

29 patch.object(prettier_plugin, "_build_config_args") as mock_config, 

30 ): 

31 mock_prepare.return_value = mock_execution_context_for_tool( 

32 files=["test.js"], 

33 rel_files=["test.js"], 

34 cwd="/tmp", 

35 ) 

36 

37 mock_exec.return_value = ["npx", "prettier"] 

38 mock_config.return_value = [] 

39 mock_run.return_value = (True, "All matched files use Prettier code style!") 

40 

41 result = prettier_plugin.fix(["/tmp/test.js"], {}) 

42 

43 assert_that(result.success).is_true() 

44 assert_that(result.remaining_issues_count).is_equal_to(0) 

45 

46 

47def test_fix_success_with_fixes_applied( 

48 prettier_plugin: PrettierPlugin, 

49 mock_execution_context_for_tool: Any, 

50) -> None: 

51 """Fix returns success when fixes applied. 

52 

53 Args: 

54 prettier_plugin: The PrettierPlugin instance to test. 

55 mock_execution_context_for_tool: Mock execution context factory. 

56 """ 

57 with ( 

58 patch.object(prettier_plugin, "_prepare_execution") as mock_prepare, 

59 patch.object(prettier_plugin, "_run_subprocess") as mock_run, 

60 patch.object(prettier_plugin, "_get_executable_command") as mock_exec, 

61 patch.object(prettier_plugin, "_build_config_args") as mock_config, 

62 ): 

63 mock_prepare.return_value = mock_execution_context_for_tool( 

64 files=["test.js"], 

65 rel_files=["test.js"], 

66 cwd="/tmp", 

67 ) 

68 

69 mock_exec.return_value = ["npx", "prettier"] 

70 mock_config.return_value = [] 

71 mock_run.side_effect = [ 

72 (False, "[warn] test.js\n[warn] Code style issues found."), 

73 (True, "test.js"), 

74 (True, "All matched files use Prettier code style!"), 

75 ] 

76 

77 result = prettier_plugin.fix(["/tmp/test.js"], {}) 

78 

79 assert_that(result.success).is_true() 

80 assert_that(result.fixed_issues_count).is_greater_than_or_equal_to(1) 

81 

82 

83def test_fix_timeout_during_check( 

84 prettier_plugin: PrettierPlugin, 

85 mock_execution_context_for_tool: Any, 

86) -> None: 

87 """Fix handles timeout during initial check. 

88 

89 Args: 

90 prettier_plugin: The PrettierPlugin instance to test. 

91 mock_execution_context_for_tool: Mock execution context factory. 

92 """ 

93 from lintro.models.core.tool_result import ToolResult 

94 from lintro.parsers.prettier.prettier_issue import PrettierIssue 

95 

96 timeout_result = ToolResult( 

97 name="prettier", 

98 success=False, 

99 output="Prettier execution timed out (30s limit exceeded).", 

100 issues_count=1, 

101 issues=[ 

102 PrettierIssue( 

103 file="execution", 

104 line=1, 

105 column=1, 

106 code="TIMEOUT", 

107 message="Prettier execution timed out", 

108 ), 

109 ], 

110 initial_issues_count=1, 

111 fixed_issues_count=0, 

112 remaining_issues_count=1, 

113 ) 

114 

115 with ( 

116 patch.object(prettier_plugin, "_prepare_execution") as mock_prepare, 

117 patch.object(prettier_plugin, "_run_subprocess") as mock_run, 

118 patch.object(prettier_plugin, "_get_executable_command") as mock_exec, 

119 patch.object(prettier_plugin, "_build_config_args") as mock_config, 

120 patch.object( 

121 prettier_plugin, 

122 "_create_timeout_result", 

123 return_value=timeout_result, 

124 ), 

125 ): 

126 mock_prepare.return_value = mock_execution_context_for_tool( 

127 files=["test.js"], 

128 rel_files=["test.js"], 

129 cwd="/tmp", 

130 ) 

131 

132 mock_exec.return_value = ["npx", "prettier"] 

133 mock_config.return_value = [] 

134 mock_run.side_effect = subprocess.TimeoutExpired(cmd="prettier", timeout=30) 

135 

136 result = prettier_plugin.fix(["/tmp/test.js"], {}) 

137 

138 assert_that(result.success).is_false() 

139 assert_that(result.output).contains("timed out") 

140 

141 

142def test_fix_early_return_when_should_skip( 

143 prettier_plugin: PrettierPlugin, 

144 mock_execution_context_for_tool: Any, 

145) -> None: 

146 """Fix returns early result when should_skip is True. 

147 

148 Args: 

149 prettier_plugin: The PrettierPlugin instance to test. 

150 mock_execution_context_for_tool: Mock execution context factory. 

151 """ 

152 with patch.object(prettier_plugin, "_prepare_execution") as mock_prepare: 

153 ctx = mock_execution_context_for_tool(should_skip=True) 

154 ctx.early_result = MagicMock(success=True, issues_count=0) 

155 mock_prepare.return_value = ctx 

156 

157 result = prettier_plugin.fix(["/tmp"], {}) 

158 

159 assert_that(result.success).is_true()