22import os
33import subprocess
44import sys
5+ import textwrap
56from pathlib import Path
6- from typing import Iterator
7+ from types import SimpleNamespace
8+ from typing import Any , Dict , Iterable , Iterator , Tuple
79from unittest .mock import patch
810
911import pytest
1315
1416AUTHOR_NAME = "Ness"
1517AUTHOR_EMAIL = "ness@onett.example"
18+ PROJECT_NAME = "unit-test-1"
1619
1720
1821@pytest .fixture
@@ -34,7 +37,6 @@ def environ() -> Iterator[None]:
3437def new_cookie (
3538 request : pytest .FixtureRequest , environ : None , temp_dir : str
3639) -> Iterator [Path ]:
37- project_name = "unit-test-1"
3840 testargs = [
3941 "new-cookie" ,
4042 "--local" ,
@@ -49,22 +51,51 @@ def new_cookie(
4951 "author_name" : AUTHOR_NAME ,
5052 "github_user" : "ness.unittest.example" ,
5153 "project_description" : "Unit test project" ,
52- "project_name" : project_name ,
54+ "project_name" : PROJECT_NAME ,
5355 }
5456 ),
5557 "-c" ,
5658 request .param ,
5759 ]
5860 with patch .object (sys , "argv" , testargs ):
5961 new_cookie_main ()
60- project_dir = Path (temp_dir ) / project_name
62+ yield Path (temp_dir ) / PROJECT_NAME
63+
64+
65+ @pytest .fixture
66+ def new_cookie_with_lock (new_cookie : Path , temp_dir : str ) -> Iterator [Path ]:
6167 for cmd in (
6268 ["poetry" , "lock" , "--no-update" ],
6369 ["git" , "add" , "poetry.lock" ],
6470 ["git" , "commit" , "-m" , "Create `poetry.lock`" ],
6571 ):
66- subprocess .run (cmd , cwd = project_dir , check = True )
67- yield project_dir
72+ subprocess .run (cmd , cwd = new_cookie , check = True )
73+ yield new_cookie
74+
75+
76+ @pytest .fixture
77+ def run_or_mock () -> Iterator [Dict [Tuple [str , ...], str ]]:
78+ real_run = subprocess .run
79+ mocked_commands : Dict [Tuple [str , ...], str ] = {}
80+
81+ def _run (* args : Any , ** kwargs : Any ) -> Any :
82+ cmd = args [0 ]
83+ cmd_tuple = tuple (cmd )
84+ while cmd_tuple :
85+ if cmd_tuple in mocked_commands :
86+ return SimpleNamespace (
87+ stdout = mocked_commands [cmd_tuple ].encode ()
88+ )
89+ cmd_tuple = cmd_tuple [:- 1 ]
90+ return real_run (* args , ** kwargs )
91+
92+ with patch .object (subprocess , "run" , _run ):
93+ yield mocked_commands
94+
95+
96+ def _manage_cookie (argv : Iterable [str ]) -> None :
97+ with patch .object (sys , "argv" , argv ):
98+ manage_cookie_main ()
6899
69100
70101@pytest .mark .parametrize (
@@ -73,7 +104,30 @@ def new_cookie(
73104 ids = ["no_updates" , "updates" ],
74105 indirect = True ,
75106)
76- def test_manage_cookie_update (new_cookie : str ) -> None :
77- testargs = ["manage-cookie" , "update" , str (new_cookie ), "-p" ]
78- with patch .object (sys , "argv" , testargs ):
79- manage_cookie_main ()
107+ def test_manage_cookie_update (new_cookie_with_lock : str ) -> None :
108+ _manage_cookie (
109+ ["manage-cookie" , "update" , str (new_cookie_with_lock ), "-p" ]
110+ )
111+
112+
113+ @pytest .mark .parametrize ("add_commit" , (True , False ))
114+ def test_manage_cookie_release (
115+ new_cookie : str , run_or_mock : Dict [Tuple [str , ...], str ], add_commit : bool
116+ ) -> None :
117+ run_or_mock [("gh" , "release" , "list" )] = textwrap .dedent (
118+ """
119+ TITLE TYPE TAG NAME PUBLISHED
120+ v1.1.38 Latest v1.1.38 in a galaxy far, far away
121+ v0.21.87 v0.21.87 about a long time ago
122+ v0.0.1 v0.0.1 about never ago
123+ """
124+ ).strip ()
125+ run_or_mock [("gh" ,)] = "" # Prevent any actual gh invocations
126+ subprocess .run (["git" , "tag" , "v1.1.38" , "@" ], cwd = new_cookie , check = True )
127+ if add_commit :
128+ subprocess .run (
129+ ["git" , "commit" , "--allow-empty" , "-m" , "create empty commit" ],
130+ cwd = new_cookie ,
131+ check = True ,
132+ )
133+ _manage_cookie (["manage-cookie" , "release" , str (new_cookie ), "-p" ])
0 commit comments