55import pytest
66import yaml
77
8- from openapi_python_client import Config , GeneratorError
8+ from openapi_python_client import Config , ErrorLevel , GeneratorError , Project
99
1010
1111def test__get_project_for_url_or_path (mocker ):
@@ -241,6 +241,17 @@ def make_project(**kwargs):
241241 return Project (** kwargs )
242242
243243
244+ @pytest .fixture
245+ def project_with_dir () -> Project :
246+ """Return a Project with the project dir pre-made (needed for cwd of commands). Unlinks after the test completes"""
247+ project = make_project ()
248+ project .project_dir .mkdir ()
249+
250+ yield project
251+
252+ project .project_dir .rmdir ()
253+
254+
244255class TestProject :
245256 def test___init__ (self , mocker ):
246257 openapi = mocker .MagicMock (title = "My Test API" )
@@ -303,7 +314,7 @@ def test_build(self, mocker):
303314 project ._build_models = mocker .MagicMock ()
304315 project ._build_api = mocker .MagicMock ()
305316 project ._create_package = mocker .MagicMock ()
306- project ._reformat = mocker .MagicMock ()
317+ project ._run_post_hooks = mocker .MagicMock ()
307318 project ._get_errors = mocker .MagicMock ()
308319
309320 result = project .build ()
@@ -313,7 +324,7 @@ def test_build(self, mocker):
313324 project ._build_metadata .assert_called_once ()
314325 project ._build_models .assert_called_once ()
315326 project ._build_api .assert_called_once ()
316- project ._reformat .assert_called_once ()
327+ project ._run_post_hooks .assert_called_once ()
317328 project ._get_errors .assert_called_once ()
318329 assert result == project ._get_errors .return_value
319330
@@ -327,7 +338,7 @@ def test_build_no_meta(self, mocker):
327338 project ._build_models = mocker .MagicMock ()
328339 project ._build_api = mocker .MagicMock ()
329340 project ._create_package = mocker .MagicMock ()
330- project ._reformat = mocker .MagicMock ()
341+ project ._run_post_hooks = mocker .MagicMock ()
331342 project ._get_errors = mocker .MagicMock ()
332343
333344 project .build ()
@@ -354,7 +365,7 @@ def test_update(self, mocker):
354365 project ._build_models = mocker .MagicMock ()
355366 project ._build_api = mocker .MagicMock ()
356367 project ._create_package = mocker .MagicMock ()
357- project ._reformat = mocker .MagicMock ()
368+ project ._run_post_hooks = mocker .MagicMock ()
358369 project ._get_errors = mocker .MagicMock ()
359370
360371 result = project .update ()
@@ -363,7 +374,7 @@ def test_update(self, mocker):
363374 project ._create_package .assert_called_once ()
364375 project ._build_models .assert_called_once ()
365376 project ._build_api .assert_called_once ()
366- project ._reformat .assert_called_once ()
377+ project ._run_post_hooks .assert_called_once ()
367378 project ._get_errors .assert_called_once ()
368379 assert result == project ._get_errors .return_value
369380
@@ -501,44 +512,42 @@ def test__build_setup_py(self, mocker):
501512 setup_template .render .assert_called_once_with ()
502513 setup_path .write_text .assert_called_once_with (setup_template .render (), encoding = "utf-8" )
503514
515+ def test__run_post_hooks_reports_missing_commands (self , project_with_dir ):
516+ fake_command_name = "blahblahdoesntexist"
517+ project_with_dir .config .post_hooks = [fake_command_name ]
518+ need_to_make_cwd = not project_with_dir .project_dir .exists ()
519+ if need_to_make_cwd :
520+ project_with_dir .project_dir .mkdir ()
504521
505- def test__reformat (mocker ):
506- import subprocess
522+ project_with_dir ._run_post_hooks ()
507523
508- sub_run = mocker .patch ("subprocess.run" )
509- project = make_project ()
510- project .project_dir = mocker .MagicMock (autospec = pathlib .Path )
511-
512- project ._reformat ()
513-
514- sub_run .assert_has_calls (
515- [
516- mocker .call (
517- "autoflake -i -r --remove-all-unused-imports --remove-unused-variables --ignore-init-module-imports ." ,
518- cwd = project .package_dir ,
519- shell = True ,
520- stdout = subprocess .PIPE ,
521- stderr = subprocess .PIPE ,
522- check = True ,
523- ),
524- mocker .call (
525- "isort ." ,
526- cwd = project .project_dir ,
527- shell = True ,
528- stdout = subprocess .PIPE ,
529- stderr = subprocess .PIPE ,
530- check = True ,
531- ),
532- mocker .call (
533- "black ." ,
534- cwd = project .project_dir ,
535- shell = True ,
536- stdout = subprocess .PIPE ,
537- stderr = subprocess .PIPE ,
538- check = True ,
539- ),
540- ]
541- )
524+ assert len (project_with_dir .errors ) == 1
525+ error = project_with_dir .errors [0 ]
526+ assert error .level == ErrorLevel .WARNING
527+ assert error .header == "Skipping Integration"
528+ assert fake_command_name in error .detail
529+
530+ def test__run_post_hooks_reports_stdout_of_commands_that_error_with_no_stderr (self , project_with_dir ):
531+ failing_command = "python -c \" print('a message'); exit(1)\" "
532+ project_with_dir .config .post_hooks = [failing_command ]
533+ project_with_dir ._run_post_hooks ()
534+
535+ assert len (project_with_dir .errors ) == 1
536+ error = project_with_dir .errors [0 ]
537+ assert error .level == ErrorLevel .ERROR
538+ assert error .header == "python failed"
539+ assert "a message" in error .detail
540+
541+ def test__run_post_hooks_reports_stderr_of_commands_that_error (self , project_with_dir ):
542+ failing_command = "python -c \" print('a message'); raise Exception('some exception')\" "
543+ project_with_dir .config .post_hooks = [failing_command ]
544+ project_with_dir ._run_post_hooks ()
545+
546+ assert len (project_with_dir .errors ) == 1
547+ error = project_with_dir .errors [0 ]
548+ assert error .level == ErrorLevel .ERROR
549+ assert error .header == "python failed"
550+ assert "some exception" in error .detail
542551
543552
544553def test__get_errors (mocker ):
@@ -559,7 +568,7 @@ def test__get_errors(mocker):
559568 assert project ._get_errors () == [1 , 2 , 3 ]
560569
561570
562- def test__custom_templates (mocker ):
571+ def test_custom_templates (mocker ):
563572 from openapi_python_client import GeneratorData , MetaType , Project
564573
565574 openapi = mocker .MagicMock (
0 commit comments