Coverage for tests / unit / tools / ruff / fix / test_edge_cases.py: 100%

31 statements  

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

1"""Tests for execute_ruff_fix - Edge cases.""" 

2 

3from __future__ import annotations 

4 

5from unittest.mock import MagicMock, patch 

6 

7from assertpy import assert_that 

8 

9from lintro.tools.implementations.ruff.fix import execute_ruff_fix 

10 

11 

12def test_execute_ruff_fix_handles_malformed_json( 

13 mock_ruff_tool: MagicMock, 

14) -> None: 

15 """Handle malformed JSON output gracefully. 

16 

17 Args: 

18 mock_ruff_tool: Mock RuffTool instance for testing. 

19 """ 

20 with patch( 

21 "lintro.tools.implementations.ruff.fix.walk_files_with_excludes", 

22 ) as mock_walk: 

23 mock_walk.return_value = ["test.py"] 

24 

25 mock_ruff_tool._run_subprocess.side_effect = [ 

26 (True, "not valid json"), # Initial check with bad output 

27 (True, "[]"), # Fix succeeds 

28 ] 

29 

30 result = execute_ruff_fix(mock_ruff_tool, ["test.py"]) 

31 

32 # Should not crash, parser handles malformed JSON 

33 assert_that(result).is_not_none() 

34 assert_that(result.name).is_equal_to("ruff") 

35 

36 

37def test_execute_ruff_fix_handles_empty_output( 

38 mock_ruff_tool: MagicMock, 

39) -> None: 

40 """Handle empty output from subprocess. 

41 

42 Args: 

43 mock_ruff_tool: Mock RuffTool instance for testing. 

44 """ 

45 with patch( 

46 "lintro.tools.implementations.ruff.fix.walk_files_with_excludes", 

47 ) as mock_walk: 

48 mock_walk.return_value = ["test.py"] 

49 

50 mock_ruff_tool._run_subprocess.side_effect = [ 

51 (True, ""), # Empty output 

52 (True, ""), 

53 ] 

54 

55 result = execute_ruff_fix(mock_ruff_tool, ["test.py"]) 

56 

57 assert_that(result.success).is_true() 

58 assert_that(result.issues_count).is_equal_to(0) 

59 

60 

61def test_execute_ruff_fix_format_exit_code_handling( 

62 mock_ruff_tool: MagicMock, 

63 sample_ruff_json_empty_output: str, 

64 sample_ruff_format_check_output: str, 

65) -> None: 

66 """Handle ruff format exit code 1 as success when files are formatted. 

67 

68 Args: 

69 mock_ruff_tool: Mock RuffTool instance for testing. 

70 sample_ruff_json_empty_output: Sample empty JSON output from ruff. 

71 sample_ruff_format_check_output: Sample format check output from ruff. 

72 """ 

73 mock_ruff_tool.options["format"] = True 

74 

75 with patch( 

76 "lintro.tools.implementations.ruff.fix.walk_files_with_excludes", 

77 ) as mock_walk: 

78 mock_walk.return_value = ["test.py"] 

79 

80 mock_ruff_tool._run_subprocess.side_effect = [ 

81 (True, sample_ruff_json_empty_output), # Lint check 

82 (False, sample_ruff_format_check_output), # Format check (exit 1) 

83 (True, sample_ruff_json_empty_output), # Lint fix 

84 (False, ""), # Format fix (exit 1 means files were formatted) 

85 ] 

86 

87 result = execute_ruff_fix(mock_ruff_tool, ["test.py"]) 

88 

89 # Format with exit code 1 and initial format issues should still be success 

90 assert_that(result.success).is_true() 

91 

92 

93def test_execute_ruff_fix_multiple_files( 

94 mock_ruff_tool: MagicMock, 

95 temp_python_files: list[str], 

96 sample_ruff_json_empty_output: str, 

97) -> None: 

98 """Handle multiple files correctly. 

99 

100 Args: 

101 mock_ruff_tool: Mock RuffTool instance for testing. 

102 temp_python_files: List of temporary Python files for testing. 

103 sample_ruff_json_empty_output: Sample empty JSON output from ruff. 

104 """ 

105 with patch( 

106 "lintro.tools.implementations.ruff.fix.walk_files_with_excludes", 

107 ) as mock_walk: 

108 mock_walk.return_value = temp_python_files 

109 

110 mock_ruff_tool._run_subprocess.side_effect = [ 

111 (True, sample_ruff_json_empty_output), 

112 (True, sample_ruff_json_empty_output), 

113 ] 

114 

115 result = execute_ruff_fix(mock_ruff_tool, temp_python_files) 

116 

117 assert_that(result.success).is_true()