@@ -120,6 +120,8 @@ def test_lifecycle_passes_name_to_cmd_up(monkeypatch):
120120 """`project up <name>` の name は project_name として up に伝播する。"""
121121 from devbase .commands import container
122122 captured = {}
123+ # name 解決 (chdir) は別テストで検証するためここでは no-op 化し、伝播のみ見る。
124+ monkeypatch .setattr (container , '_resolve_project_name' , lambda name : True )
123125 monkeypatch .setattr (container , 'cmd_up' ,
124126 lambda project_name = None , scale = None :
125127 captured .update (project_name = project_name ) or 0 )
@@ -141,42 +143,49 @@ def test_lifecycle_container_path_has_no_name(monkeypatch):
141143
142144
143145# ---------------------------------------------------------------------------
144- # _dispatch_lifecycle: name 未実装 warning
145- # (PR1 では up/scale も含め全サブコマンドが CWD の compose に作用するため、
146- # name 指定時はサブコマンドに関わらず警告する)
146+ # _dispatch_lifecycle: name 解決 (PR2 で wrapper cd の Python フォールバックを実装)
147+ # name 指定時は handler 呼び出し前に _resolve_project_name で chdir する。
148+ # 解決失敗時は handler を呼ばずに 1 を返す。詳細な解決ロジックは
149+ # test_project_name_resolution.py を参照。
147150# ---------------------------------------------------------------------------
148151
149- def test_lifecycle_warns_for_up_with_name (monkeypatch , caplog ):
150- """`project up < name>` は name 指定時に未実装 warning を出す 。"""
152+ def test_lifecycle_resolves_name_before_handler (monkeypatch ):
153+ """name 指定時は handler 前に _resolve_project_name を呼ぶ 。"""
151154 from devbase .commands import container
152- monkeypatch .setattr (container , 'cmd_up' , lambda project_name = None , scale = None : 0 )
155+ order = []
156+ monkeypatch .setattr (container , '_resolve_project_name' ,
157+ lambda name : order .append (('resolve' , name )) or True )
158+ monkeypatch .setattr (container , 'cmd_up' ,
159+ lambda project_name = None , scale = None :
160+ order .append (('up' , project_name )) or 0 )
153161 args = _args (subcommand = 'up' , name = 'carmo' , scale = None )
154- with caplog .at_level (logging .WARNING , logger = 'devbase.commands.container' ):
155- assert container ._dispatch_lifecycle (args ) == 0
156- assert any ('未実装' in r .message for r in caplog .records ), \
157- 'up でも name 指定時は警告しなければならない'
162+ assert container ._dispatch_lifecycle (args ) == 0
163+ assert order == [('resolve' , 'carmo' ), ('up' , 'carmo' )]
158164
159165
160- def test_lifecycle_warns_for_scale_with_name (monkeypatch , caplog ):
161- """`project scale < name> N` も name 指定時に未実装 warning を出す 。"""
166+ def test_lifecycle_aborts_when_name_unresolved (monkeypatch ):
167+ """name 解決に失敗したら handler を呼ばず 1 を返す 。"""
162168 from devbase .commands import container
163- monkeypatch .setattr (container , 'cmd_scale' ,
164- lambda new_scale = None , project_name = None : 0 )
165- args = _args (subcommand = 'scale' , name = 'carmo' , new_scale = 3 )
166- with caplog .at_level (logging .WARNING , logger = 'devbase.commands.container' ):
167- assert container ._dispatch_lifecycle (args ) == 0
168- assert any ('未実装' in r .message for r in caplog .records ), \
169- 'scale でも name 指定時は警告しなければならない'
169+ called = []
170+ monkeypatch .setattr (container , '_resolve_project_name' , lambda name : False )
171+ monkeypatch .setattr (container , 'cmd_up' ,
172+ lambda project_name = None , scale = None :
173+ called .append ('up' ) or 0 )
174+ args = _args (subcommand = 'up' , name = 'bogus' , scale = None )
175+ assert container ._dispatch_lifecycle (args ) == 1
176+ assert called == [], '解決失敗時は handler を呼んではならない'
170177
171178
172- def test_lifecycle_no_warning_without_name (monkeypatch , caplog ):
173- """name 未指定なら警告を出さない 。"""
179+ def test_lifecycle_no_resolution_without_name (monkeypatch ):
180+ """name 未指定なら _resolve_project_name を呼ばない 。"""
174181 from devbase .commands import container
182+ resolved = []
183+ monkeypatch .setattr (container , '_resolve_project_name' ,
184+ lambda name : resolved .append (name ) or True )
175185 monkeypatch .setattr (container , 'cmd_up' , lambda project_name = None , scale = None : 0 )
176186 args = _args (subcommand = 'up' , scale = None ) # name 属性なし
177- with caplog .at_level (logging .WARNING , logger = 'devbase.commands.container' ):
178- assert container ._dispatch_lifecycle (args ) == 0
179- assert not any ('未実装' in r .message for r in caplog .records )
187+ assert container ._dispatch_lifecycle (args ) == 0
188+ assert resolved == []
180189
181190
182191# ---------------------------------------------------------------------------
@@ -293,6 +302,7 @@ def test_shortcut_up_propagates_name_through_dispatch(monkeypatch):
293302 """`devbase up <name>` の name がショートカット経由で cmd_up まで伝播する。"""
294303 from devbase .commands import container
295304 captured = {}
305+ monkeypatch .setattr (container , '_resolve_project_name' , lambda name : True )
296306 monkeypatch .setattr (container , 'cmd_up' ,
297307 lambda project_name = None , scale = None :
298308 captured .update (project_name = project_name ) or 0 )
@@ -306,6 +316,7 @@ def test_shortcut_scale_propagates_name_through_dispatch(monkeypatch):
306316 """`devbase scale <name> N` の name がショートカット経由で cmd_scale まで伝播する。"""
307317 from devbase .commands import container
308318 captured = {}
319+ monkeypatch .setattr (container , '_resolve_project_name' , lambda name : True )
309320 monkeypatch .setattr (container , 'cmd_scale' ,
310321 lambda new_scale = None , project_name = None :
311322 captured .update (project_name = project_name , new_scale = new_scale ) or 0 )
0 commit comments