@@ -159,6 +159,59 @@ fn status_report_marks_subscription_spend_with_tilde() {
159159 assert ! ( out. contains( "~$0.000000" ) , "{out}" ) ;
160160}
161161
162+ #[ test]
163+ fn status_latest_uses_same_kv_layout_for_completed_failed_running ( ) {
164+ let cases = [
165+ ( RunStatus :: Completed , "completed ->" ) ,
166+ ( RunStatus :: Failed , "failed ->" ) ,
167+ ( RunStatus :: Executing , "running ->" ) ,
168+ ] ;
169+ let mut layouts = Vec :: new ( ) ;
170+
171+ for ( status, expected_state) in cases {
172+ let temp = repo_tempdir ( ) ;
173+ let ( paths, mut state) = state ( & temp, expected_state) ;
174+ state. status = status;
175+ state. failure_reason = ( status == RunStatus :: Failed ) . then ( || "acceptance failed" . into ( ) ) ;
176+ save_state ( & state) . expect ( "save state" ) ;
177+
178+ let output = deadreckon ( & paths)
179+ . current_dir ( & state. cwd )
180+ . args ( [ "status" , "latest" , "--plain" ] )
181+ . output ( )
182+ . expect ( "status latest" ) ;
183+
184+ assert_success ( & output) ;
185+ let out = stdout ( & output) ;
186+ assert ! ( out. contains( "deadreckon status" ) , "{out}" ) ;
187+ assert ! ( out. contains( expected_state) , "{out}" ) ;
188+ assert ! ( !out. contains( "executing" ) , "{out}" ) ;
189+ layouts. push ( status_layout_keys ( & out) ) ;
190+ }
191+
192+ assert_eq ! ( layouts[ 0 ] , layouts[ 1 ] ) ;
193+ assert_eq ! ( layouts[ 0 ] , layouts[ 2 ] ) ;
194+ assert_eq ! (
195+ layouts[ 0 ] ,
196+ [
197+ "run" ,
198+ "state" ,
199+ "phase" ,
200+ "scope" ,
201+ "updated" ,
202+ "provider" ,
203+ "sandbox" ,
204+ "spend" ,
205+ "wall" ,
206+ "goal" ,
207+ "state" ,
208+ "launch-dir" ,
209+ "working" ,
210+ "mode" ,
211+ ]
212+ ) ;
213+ }
214+
162215fn state ( temp : & TempDir , goal : & str ) -> ( DeadreckonPaths , deadreckon_core:: PipelineState ) {
163216 let paths = DeadreckonPaths :: from_home ( temp. path ( ) . join ( "home" ) ) ;
164217 let cwd = temp. path ( ) . join ( "repo" ) ;
@@ -183,6 +236,15 @@ fn state(temp: &TempDir, goal: &str) -> (DeadreckonPaths, deadreckon_core::Pipel
183236 ( paths, state)
184237}
185238
239+ fn status_layout_keys ( out : & str ) -> Vec < String > {
240+ out. lines ( )
241+ . skip_while ( |line| * line != "deadreckon status" )
242+ . skip ( 1 )
243+ . take_while ( |line| !line. trim ( ) . is_empty ( ) )
244+ . filter_map ( |line| line. split_once ( ':' ) . map ( |( key, _) | key. trim ( ) . to_string ( ) ) )
245+ . collect ( )
246+ }
247+
186248fn repo_tempdir ( ) -> TempDir {
187249 let root = PathBuf :: from ( "/Users/gdc/deadreckon/.test-tmp" ) ;
188250 fs:: create_dir_all ( & root) . expect ( "test tmp root" ) ;
0 commit comments