|
1 | 1 | import dataclasses |
2 | 2 | import decimal |
3 | 3 | import sys |
4 | | -from typing import Any, Optional |
| 4 | +from typing import Any, Optional, Union |
5 | 5 | from unittest import TestCase |
6 | 6 | from unittest.mock import MagicMock, patch |
7 | 7 |
|
@@ -206,64 +206,89 @@ def test_command(arg1: bool = False): |
206 | 206 | @patch("targ.CLI._get_cleaned_args") |
207 | 207 | def test_optional_bool_arg(self, _get_cleaned_args: MagicMock): |
208 | 208 | """ |
209 | | - Test command arguments which are of type Optional[bool]. |
| 209 | + Test command arguments which are optional booleans. |
210 | 210 | """ |
211 | 211 |
|
212 | | - def test_command(arg1: Optional[bool] = None): |
213 | | - """ |
214 | | - A command for testing optional boolean arguments. |
215 | | - """ |
216 | | - if arg1 is None: |
| 212 | + def print_arg(arg): |
| 213 | + if arg is None: |
217 | 214 | print("arg1 is None") |
218 | | - elif arg1 is True: |
| 215 | + elif arg is True: |
219 | 216 | print("arg1 is True") |
220 | | - elif arg1 is False: |
| 217 | + elif arg is False: |
221 | 218 | print("arg1 is False") |
222 | 219 | else: |
223 | 220 | raise ValueError("arg1 is the wrong type") |
224 | 221 |
|
225 | | - cli = CLI() |
226 | | - cli.register(test_command) |
| 222 | + def test_optional(arg1: Optional[bool] = None): |
| 223 | + """ |
| 224 | + A command for testing `Optional[bool]` arguments. |
| 225 | + """ |
| 226 | + print_arg(arg1) |
227 | 227 |
|
228 | | - with patch("builtins.print", side_effect=print_) as print_mock: |
| 228 | + def test_union(arg1: Union[bool, None] = None): |
| 229 | + """ |
| 230 | + A command for testing `Union[bool, None]` arguments. |
| 231 | + """ |
| 232 | + print_arg(arg1) |
229 | 233 |
|
230 | | - configs: list[Config] = [ |
231 | | - Config( |
232 | | - params=["test_command", "--arg1"], |
233 | | - output="arg1 is True", |
234 | | - ), |
235 | | - Config( |
236 | | - params=["test_command", "--arg1=True"], |
237 | | - output="arg1 is True", |
238 | | - ), |
239 | | - Config( |
240 | | - params=["test_command", "--arg1=true"], |
241 | | - output="arg1 is True", |
242 | | - ), |
243 | | - Config( |
244 | | - params=["test_command", "--arg1=t"], |
245 | | - output="arg1 is True", |
246 | | - ), |
247 | | - Config( |
248 | | - params=["test_command", "--arg1=False"], |
249 | | - output="arg1 is False", |
250 | | - ), |
251 | | - Config( |
252 | | - params=["test_command", "--arg1=false"], |
253 | | - output="arg1 is False", |
254 | | - ), |
255 | | - Config( |
256 | | - params=["test_command", "--arg1=f"], |
257 | | - output="arg1 is False", |
258 | | - ), |
259 | | - Config(params=["test_command"], output="arg1 is None"), |
260 | | - ] |
| 234 | + commands = [test_optional, test_union] |
261 | 235 |
|
262 | | - for config in configs: |
263 | | - _get_cleaned_args.return_value = config.params |
264 | | - cli.run() |
265 | | - print_mock.assert_called_with(config.output) |
266 | | - print_mock.reset_mock() |
| 236 | + if sys.version_info.major == 3 and sys.version_info.minor >= 10: |
| 237 | + |
| 238 | + def test_union_syntax(arg1: bool | None = None): # type: ignore |
| 239 | + """ |
| 240 | + A command for testing `bool | None` arguments. |
| 241 | + """ |
| 242 | + print_arg(arg1) |
| 243 | + |
| 244 | + commands.append(test_union_syntax) |
| 245 | + |
| 246 | + cli = CLI() |
| 247 | + |
| 248 | + for command in commands: |
| 249 | + cli.register(command) |
| 250 | + |
| 251 | + with patch("builtins.print", side_effect=print_) as print_mock: |
| 252 | + for command in commands: |
| 253 | + command_name = command.__name__ |
| 254 | + |
| 255 | + configs: list[Config] = [ |
| 256 | + Config( |
| 257 | + params=[command_name, "--arg1"], |
| 258 | + output="arg1 is True", |
| 259 | + ), |
| 260 | + Config( |
| 261 | + params=[command_name, "--arg1=True"], |
| 262 | + output="arg1 is True", |
| 263 | + ), |
| 264 | + Config( |
| 265 | + params=[command_name, "--arg1=true"], |
| 266 | + output="arg1 is True", |
| 267 | + ), |
| 268 | + Config( |
| 269 | + params=[command_name, "--arg1=t"], |
| 270 | + output="arg1 is True", |
| 271 | + ), |
| 272 | + Config( |
| 273 | + params=[command_name, "--arg1=False"], |
| 274 | + output="arg1 is False", |
| 275 | + ), |
| 276 | + Config( |
| 277 | + params=[command_name, "--arg1=false"], |
| 278 | + output="arg1 is False", |
| 279 | + ), |
| 280 | + Config( |
| 281 | + params=[command_name, "--arg1=f"], |
| 282 | + output="arg1 is False", |
| 283 | + ), |
| 284 | + Config(params=[command_name], output="arg1 is None"), |
| 285 | + ] |
| 286 | + |
| 287 | + for config in configs: |
| 288 | + _get_cleaned_args.return_value = config.params |
| 289 | + cli.run() |
| 290 | + print_mock.assert_called_with(config.output) |
| 291 | + print_mock.reset_mock() |
267 | 292 |
|
268 | 293 | @patch("targ.CLI._get_cleaned_args") |
269 | 294 | def test_int_arg(self, _get_cleaned_args: MagicMock): |
@@ -302,6 +327,67 @@ def test_command(arg1: decimal.Decimal): |
302 | 327 | print_mock.assert_called_with(config.output) |
303 | 328 | print_mock.reset_mock() |
304 | 329 |
|
| 330 | + @patch("targ.CLI._get_cleaned_args") |
| 331 | + def test_optional_int_arg(self, _get_cleaned_args: MagicMock): |
| 332 | + """ |
| 333 | + Test command arguments which are optional int. |
| 334 | + """ |
| 335 | + |
| 336 | + def print_arg(arg): |
| 337 | + if arg is None: |
| 338 | + print("arg1 is None") |
| 339 | + elif isinstance(arg, int): |
| 340 | + print("arg1 is an int") |
| 341 | + else: |
| 342 | + raise ValueError("arg1 is the wrong type") |
| 343 | + |
| 344 | + def test_optional(arg1: Optional[int] = None): |
| 345 | + """ |
| 346 | + A command for testing `Optional[int]` arguments. |
| 347 | + """ |
| 348 | + print_arg(arg1) |
| 349 | + |
| 350 | + def test_union(arg1: Union[int, None] = None): |
| 351 | + """ |
| 352 | + A command for testing `Union[int, None]` arguments. |
| 353 | + """ |
| 354 | + print_arg(arg1) |
| 355 | + |
| 356 | + commands = [test_optional, test_union] |
| 357 | + |
| 358 | + if sys.version_info.major == 3 and sys.version_info.minor >= 10: |
| 359 | + |
| 360 | + def test_union_syntax(arg1: int | None = None): # type: ignore |
| 361 | + """ |
| 362 | + A command for testing `int | None` arguments. |
| 363 | + """ |
| 364 | + print_arg(arg1) |
| 365 | + |
| 366 | + commands.append(test_union_syntax) |
| 367 | + |
| 368 | + cli = CLI() |
| 369 | + |
| 370 | + for command in commands: |
| 371 | + cli.register(command) |
| 372 | + |
| 373 | + with patch("builtins.print", side_effect=print_) as print_mock: |
| 374 | + for command in commands: |
| 375 | + command_name = command.__name__ |
| 376 | + |
| 377 | + configs: list[Config] = [ |
| 378 | + Config( |
| 379 | + params=[command_name, "--arg1=1"], |
| 380 | + output="arg1 is an int", |
| 381 | + ), |
| 382 | + Config(params=[command_name], output="arg1 is None"), |
| 383 | + ] |
| 384 | + |
| 385 | + for config in configs: |
| 386 | + _get_cleaned_args.return_value = config.params |
| 387 | + cli.run() |
| 388 | + print_mock.assert_called_with(config.output) |
| 389 | + print_mock.reset_mock() |
| 390 | + |
305 | 391 | @patch("targ.CLI._get_cleaned_args") |
306 | 392 | def test_decimal_arg(self, _get_cleaned_args: MagicMock): |
307 | 393 | """ |
|
0 commit comments