@@ -541,3 +541,91 @@ def test_list_templates_with_fixture_dir(
541541 assert result .exit_code == 0 , text
542542 assert "fixture-only" in text
543543 assert os .environ .get ("CPA_CATALOG_FIXTURE" ) == "1"
544+
545+
546+ def test_non_empty_target_fails_before_scaffold (
547+ tmp_path : Path , monkeypatch : pytest .MonkeyPatch
548+ ) -> None :
549+ """Leftover target dir must fail immediately — not after interactive work."""
550+ target = tmp_path / "existing"
551+ target .mkdir ()
552+ (target / "leftover.txt" ).write_text ("already here" , encoding = "utf-8" )
553+ tpl = tmp_path / "tpl"
554+ tpl .mkdir ()
555+ called : dict [str , bool ] = {"create" : False }
556+
557+ async def fake_check_for_latest_version (_package_name ):
558+ return None
559+
560+ async def fake_create_python_app (* _args , ** _kwargs ):
561+ called ["create" ] = True
562+
563+ monkeypatch .setattr (
564+ "create_awesome_python_app.cli.check_for_latest_version" ,
565+ fake_check_for_latest_version ,
566+ )
567+ monkeypatch .setattr (
568+ "create_awesome_python_app.cli.create_python_app" ,
569+ fake_create_python_app ,
570+ )
571+
572+ result = runner .invoke (
573+ app ,
574+ [
575+ "--template" ,
576+ f"file://{ tpl } " ,
577+ "--no-install" ,
578+ "--no-interactive" ,
579+ str (target ),
580+ ],
581+ )
582+ text = (result .stdout or "" ) + (result .stderr or "" )
583+ assert result .exit_code == 1 , text
584+ assert "not empty" in text .lower ()
585+ assert "--force" in text
586+ assert called ["create" ] is False
587+
588+
589+ def test_non_empty_target_allows_force (
590+ tmp_path : Path , monkeypatch : pytest .MonkeyPatch
591+ ) -> None :
592+ target = tmp_path / "existing"
593+ target .mkdir ()
594+ (target / "leftover.txt" ).write_text ("already here" , encoding = "utf-8" )
595+ tpl = tmp_path / "tpl"
596+ tpl .mkdir ()
597+ captured : dict [str , object ] = {}
598+
599+ async def fake_check_for_latest_version (_package_name ):
600+ return None
601+
602+ async def fake_create_python_app (project_directory , options , * _args , ** _kwargs ):
603+ captured ["project_directory" ] = project_directory
604+ captured ["options" ] = options
605+
606+ monkeypatch .setattr (
607+ "create_awesome_python_app.cli.check_for_latest_version" ,
608+ fake_check_for_latest_version ,
609+ )
610+ monkeypatch .setattr (
611+ "create_awesome_python_app.cli.create_python_app" ,
612+ fake_create_python_app ,
613+ )
614+
615+ result = runner .invoke (
616+ app ,
617+ [
618+ "--template" ,
619+ f"file://{ tpl } " ,
620+ "--force" ,
621+ "--no-install" ,
622+ "--no-interactive" ,
623+ str (target ),
624+ ],
625+ )
626+ text = (result .stdout or "" ) + (result .stderr or "" )
627+ assert result .exit_code == 0 , text
628+ assert captured ["project_directory" ] == str (target )
629+ options = captured ["options" ]
630+ assert isinstance (options , dict )
631+ assert options ["force" ] is True
0 commit comments