Coverage for tests / integration / tools / tsc / test_check.py: 100%

59 statements  

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

1"""Integration tests for TypeScript Compiler (tsc) tool definition. 

2 

3These tests require tsc (typescript) to be installed and available in PATH. 

4They verify the TscPlugin definition, check command, and set_options method. 

5""" 

6 

7from __future__ import annotations 

8 

9from collections.abc import Callable 

10from pathlib import Path 

11from typing import TYPE_CHECKING 

12 

13import pytest 

14from assertpy import assert_that 

15 

16from tests.integration.tools.tsc.conftest import tsc_is_available 

17 

18if TYPE_CHECKING: 

19 from lintro.plugins.base import BaseToolPlugin 

20 

21# Skip all tests if tsc is not installed or not working 

22pytestmark = pytest.mark.skipif( 

23 not tsc_is_available(), 

24 reason="tsc not installed or not working", 

25) 

26 

27 

28# --- Tests for TscPlugin definition --- 

29 

30 

31@pytest.mark.parametrize( 

32 ("attr", "expected"), 

33 [ 

34 ("name", "tsc"), 

35 ("can_fix", False), 

36 ], 

37 ids=["name", "can_fix"], 

38) 

39def test_definition_attributes( 

40 get_plugin: Callable[[str], BaseToolPlugin], 

41 attr: str, 

42 expected: object, 

43) -> None: 

44 """Verify TscPlugin definition has correct attribute values. 

45 

46 Tests that the plugin definition exposes the expected values for 

47 name and can_fix attributes. 

48 

49 Args: 

50 get_plugin: Fixture factory to get plugin instances. 

51 attr: The attribute name to check on the definition. 

52 expected: The expected value of the attribute. 

53 """ 

54 tsc_plugin = get_plugin("tsc") 

55 assert_that(getattr(tsc_plugin.definition, attr)).is_equal_to(expected) 

56 

57 

58def test_definition_file_patterns(get_plugin: Callable[[str], BaseToolPlugin]) -> None: 

59 """Verify TscPlugin definition includes TypeScript file patterns. 

60 

61 Tests that the plugin is configured to handle TypeScript files (*.ts, *.tsx). 

62 

63 Args: 

64 get_plugin: Fixture factory to get plugin instances. 

65 """ 

66 tsc_plugin = get_plugin("tsc") 

67 assert_that(tsc_plugin.definition.file_patterns).contains("*.ts") 

68 assert_that(tsc_plugin.definition.file_patterns).contains("*.tsx") 

69 

70 

71# --- Integration tests for tsc check command --- 

72 

73 

74def test_check_file_with_type_errors( 

75 get_plugin: Callable[[str], BaseToolPlugin], 

76 tsc_violation_file: str, 

77) -> None: 

78 """Verify tsc check detects type errors in problematic files. 

79 

80 Runs tsc on a file containing deliberate type violations and verifies 

81 that issues are found. 

82 

83 Args: 

84 get_plugin: Fixture factory to get plugin instances. 

85 tsc_violation_file: Path to file with type errors from test_samples. 

86 """ 

87 tsc_plugin = get_plugin("tsc") 

88 result = tsc_plugin.check([tsc_violation_file], {}) 

89 

90 assert_that(result).is_not_none() 

91 assert_that(result.name).is_equal_to("tsc") 

92 assert_that(result.issues_count).is_greater_than(0) 

93 

94 

95def test_check_type_correct_file( 

96 get_plugin: Callable[[str], BaseToolPlugin], 

97 tsc_clean_file: str, 

98) -> None: 

99 """Verify tsc check passes on type-correct files. 

100 

101 Runs tsc on a properly typed file and verifies no issues are found. 

102 

103 Args: 

104 get_plugin: Fixture factory to get plugin instances. 

105 tsc_clean_file: Path to file with correct types from test_samples. 

106 """ 

107 tsc_plugin = get_plugin("tsc") 

108 result = tsc_plugin.check([tsc_clean_file], {}) 

109 

110 assert_that(result).is_not_none() 

111 assert_that(result.name).is_equal_to("tsc") 

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

113 

114 

115def test_check_empty_directory( 

116 get_plugin: Callable[[str], BaseToolPlugin], 

117 tmp_path: Path, 

118) -> None: 

119 """Verify tsc check handles empty directories gracefully. 

120 

121 Runs tsc on an empty directory and verifies a result is returned 

122 without errors. 

123 

124 Args: 

125 get_plugin: Fixture factory to get plugin instances. 

126 tmp_path: Pytest fixture providing a temporary directory. 

127 """ 

128 tsc_plugin = get_plugin("tsc") 

129 result = tsc_plugin.check([str(tmp_path)], {}) 

130 

131 assert_that(result).is_not_none() 

132 

133 

134# --- Tests for TscPlugin.set_options method --- 

135 

136 

137@pytest.mark.parametrize( 

138 ("option_name", "option_value", "expected"), 

139 [ 

140 ("project", "tsconfig.json", "tsconfig.json"), 

141 ("strict", True, True), 

142 ("skip_lib_check", True, True), 

143 ("use_project_files", True, True), 

144 ("use_project_files", False, False), 

145 ], 

146 ids=[ 

147 "project", 

148 "strict", 

149 "skip_lib_check", 

150 "use_project_files_true", 

151 "use_project_files_false", 

152 ], 

153) 

154def test_set_options( 

155 get_plugin: Callable[[str], BaseToolPlugin], 

156 option_name: str, 

157 option_value: object, 

158 expected: object, 

159) -> None: 

160 """Verify TscPlugin.set_options correctly sets various options. 

161 

162 Tests that plugin options can be set and retrieved correctly. 

163 

164 Args: 

165 get_plugin: Fixture factory to get plugin instances. 

166 option_name: Name of the option to set. 

167 option_value: Value to set for the option. 

168 expected: Expected value when retrieving the option. 

169 """ 

170 tsc_plugin = get_plugin("tsc") 

171 tsc_plugin.set_options(**{option_name: option_value}) 

172 assert_that(tsc_plugin.options.get(option_name)).is_equal_to(expected) 

173 

174 

175# --- Tests for file targeting with tsconfig.json --- 

176 

177 

178def test_file_targeting_with_tsconfig( 

179 get_plugin: Callable[[str], BaseToolPlugin], 

180 tmp_path: Path, 

181) -> None: 

182 """Verify tsc respects file targeting even when tsconfig.json exists. 

183 

184 Creates a project with tsconfig.json and multiple files, then verifies 

185 that only the specified file is checked (not all files in the project). 

186 

187 Args: 

188 get_plugin: Fixture factory to get plugin instances. 

189 tmp_path: Pytest fixture providing a temporary directory. 

190 """ 

191 # Create tsconfig.json 

192 tsconfig = tmp_path / "tsconfig.json" 

193 tsconfig.write_text('{"compilerOptions": {"strict": true}}') 

194 

195 # Create two TypeScript files - one clean, one with errors 

196 clean_file = tmp_path / "clean.ts" 

197 clean_file.write_text("const x: number = 42;\nexport { x };\n") 

198 

199 error_file = tmp_path / "error.ts" 

200 error_file.write_text("const y: number = 'string';\nexport { y };\n") 

201 

202 tsc_plugin = get_plugin("tsc") 

203 

204 # Check only the clean file - should pass 

205 result = tsc_plugin.check([str(clean_file)], {}) 

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

207 

208 # Check only the error file - should find issues 

209 result = tsc_plugin.check([str(error_file)], {}) 

210 assert_that(result.issues_count).is_greater_than(0) 

211 

212 

213def test_use_project_files_checks_all_files( 

214 get_plugin: Callable[[str], BaseToolPlugin], 

215 tmp_path: Path, 

216) -> None: 

217 """Verify use_project_files=True uses tsconfig.json file selection. 

218 

219 When use_project_files is True, tsc should check all files defined 

220 in tsconfig.json, not just the files passed to check(). 

221 

222 Args: 

223 get_plugin: Fixture factory to get plugin instances. 

224 tmp_path: Pytest fixture providing a temporary directory. 

225 """ 

226 # Create tsconfig.json that includes all .ts files 

227 tsconfig = tmp_path / "tsconfig.json" 

228 tsconfig.write_text( 

229 '{"compilerOptions": {"strict": true}, "include": ["*.ts"]}', 

230 ) 

231 

232 # Create a clean file and an error file 

233 clean_file = tmp_path / "clean.ts" 

234 clean_file.write_text("const x: number = 42;\nexport { x };\n") 

235 

236 error_file = tmp_path / "error.ts" 

237 error_file.write_text("const y: number = 'string';\nexport { y };\n") 

238 

239 tsc_plugin = get_plugin("tsc") 

240 

241 # With use_project_files=True, checking just clean.ts should still find 

242 # errors because tsc checks all files in tsconfig.json 

243 result = tsc_plugin.check( 

244 [str(clean_file)], 

245 {"use_project_files": True}, 

246 ) 

247 

248 # Should find the error in error.ts even though we only passed clean.ts 

249 assert_that(result.issues_count).is_greater_than(0)