@@ -4527,6 +4527,46 @@ mod tests {
45274527 eval : EvalArgs ,
45284528 }
45294529
4530+ fn base_args ( ) -> BaseArgs {
4531+ BaseArgs {
4532+ json : false ,
4533+ quiet : false ,
4534+ no_color : false ,
4535+ profile : None ,
4536+ org_name : None ,
4537+ project : None ,
4538+ api_key : None ,
4539+ prefer_profile : false ,
4540+ no_input : false ,
4541+ api_url : None ,
4542+ app_url : None ,
4543+ env_file : None ,
4544+ }
4545+ }
4546+
4547+ fn make_eval_args ( files : Vec < String > ) -> EvalArgs {
4548+ EvalArgs {
4549+ files,
4550+ runner : None ,
4551+ language : None ,
4552+ sandbox : EvalSandbox :: Local ,
4553+ no_send_logs : false ,
4554+ jsonl : false ,
4555+ terminate_on_failure : false ,
4556+ num_workers : None ,
4557+ list : false ,
4558+ filter : Vec :: new ( ) ,
4559+ verbose : false ,
4560+ watch : false ,
4561+ extra_args : Vec :: new ( ) ,
4562+ dev : false ,
4563+ dev_host : "localhost" . to_string ( ) ,
4564+ dev_port : 8300 ,
4565+ dev_org_name : None ,
4566+ dev_allowed_origin : Vec :: new ( ) ,
4567+ }
4568+ }
4569+
45304570 fn env_test_lock ( ) -> & ' static Mutex < ( ) > {
45314571 static LOCK : OnceLock < Mutex < ( ) > > = OnceLock :: new ( ) ;
45324572 LOCK . get_or_init ( || Mutex :: new ( ( ) ) )
@@ -4616,6 +4656,12 @@ mod tests {
46164656 }
46174657 }
46184658
4659+ fn write_eval_file ( dir : & Path , name : & str ) -> String {
4660+ let path = dir. join ( name) ;
4661+ fs:: write ( & path, "export {};" ) . expect ( "eval file should be written" ) ;
4662+ path. to_string_lossy ( ) . to_string ( )
4663+ }
4664+
46194665 #[ test]
46204666 fn join_app_url_normalizes_slashes ( ) {
46214667 let joined =
@@ -5787,6 +5833,105 @@ mod tests {
57875833 }
57885834 }
57895835
5836+ #[ test]
5837+ fn eval_args_parse_sandbox_flag ( ) {
5838+ let parsed =
5839+ EvalArgsHarness :: try_parse_from ( [ "bt" , "--sandbox" , "lambda" , "sample.eval.ts" ] )
5840+ . expect ( "sandbox flag should parse" ) ;
5841+ assert_eq ! ( parsed. eval. sandbox, EvalSandbox :: Lambda ) ;
5842+ assert_eq ! ( parsed. eval. files, vec![ "sample.eval.ts" . to_string( ) ] ) ;
5843+ }
5844+
5845+ #[ tokio:: test]
5846+ async fn sandbox_eval_rejects_dev_mode ( ) {
5847+ let dir = make_temp_dir ( "sandbox-dev" ) ;
5848+ let file = write_eval_file ( & dir, "sample.eval.ts" ) ;
5849+ let mut args = make_eval_args ( vec ! [ file] ) ;
5850+ args. sandbox = EvalSandbox :: Lambda ;
5851+ args. dev = true ;
5852+
5853+ let err = run ( base_args ( ) , args)
5854+ . await
5855+ . expect_err ( "sandbox+dev should fail" ) ;
5856+ assert ! ( err
5857+ . to_string( )
5858+ . contains( "--sandbox is not supported with --dev." ) ) ;
5859+
5860+ let _ = fs:: remove_dir_all ( & dir) ;
5861+ }
5862+
5863+ #[ tokio:: test]
5864+ async fn sandbox_eval_rejects_watch_mode ( ) {
5865+ let dir = make_temp_dir ( "sandbox-watch" ) ;
5866+ let file = write_eval_file ( & dir, "sample.eval.ts" ) ;
5867+ let mut args = make_eval_args ( vec ! [ file] ) ;
5868+ args. sandbox = EvalSandbox :: Lambda ;
5869+ args. watch = true ;
5870+
5871+ let err = run ( base_args ( ) , args)
5872+ . await
5873+ . expect_err ( "sandbox+watch should fail" ) ;
5874+ assert ! ( err
5875+ . to_string( )
5876+ . contains( "--sandbox is not supported with --watch." ) ) ;
5877+
5878+ let _ = fs:: remove_dir_all ( & dir) ;
5879+ }
5880+
5881+ #[ tokio:: test]
5882+ async fn sandbox_eval_rejects_list_mode ( ) {
5883+ let dir = make_temp_dir ( "sandbox-list" ) ;
5884+ let file = write_eval_file ( & dir, "sample.eval.ts" ) ;
5885+ let mut args = make_eval_args ( vec ! [ file] ) ;
5886+ args. sandbox = EvalSandbox :: Lambda ;
5887+ args. list = true ;
5888+
5889+ let err = run ( base_args ( ) , args)
5890+ . await
5891+ . expect_err ( "sandbox+list should fail" ) ;
5892+ assert ! ( err
5893+ . to_string( )
5894+ . contains( "--sandbox is not supported with --list." ) ) ;
5895+
5896+ let _ = fs:: remove_dir_all ( & dir) ;
5897+ }
5898+
5899+ #[ tokio:: test]
5900+ async fn sandbox_eval_rejects_no_send_logs ( ) {
5901+ let dir = make_temp_dir ( "sandbox-local" ) ;
5902+ let file = write_eval_file ( & dir, "sample.eval.ts" ) ;
5903+ let mut args = make_eval_args ( vec ! [ file] ) ;
5904+ args. sandbox = EvalSandbox :: Lambda ;
5905+ args. no_send_logs = true ;
5906+
5907+ let err = run ( base_args ( ) , args)
5908+ . await
5909+ . expect_err ( "sandbox+no-send-logs should fail" ) ;
5910+ assert ! ( err
5911+ . to_string( )
5912+ . contains( "--sandbox lambda is not supported with --no-send-logs." ) ) ;
5913+
5914+ let _ = fs:: remove_dir_all ( & dir) ;
5915+ }
5916+
5917+ #[ tokio:: test]
5918+ async fn sandbox_eval_rejects_multiple_files ( ) {
5919+ let dir = make_temp_dir ( "sandbox-multi" ) ;
5920+ let first = write_eval_file ( & dir, "first.eval.ts" ) ;
5921+ let second = write_eval_file ( & dir, "second.eval.ts" ) ;
5922+ let mut args = make_eval_args ( vec ! [ first, second] ) ;
5923+ args. sandbox = EvalSandbox :: Lambda ;
5924+
5925+ let err = run ( base_args ( ) , args)
5926+ . await
5927+ . expect_err ( "sandbox+multiple files should fail" ) ;
5928+ assert ! ( err
5929+ . to_string( )
5930+ . contains( "`bt eval --sandbox lambda` currently supports exactly one eval file." ) ) ;
5931+
5932+ let _ = fs:: remove_dir_all ( & dir) ;
5933+ }
5934+
57905935 #[ test]
57915936 fn build_sandbox_summary_query_includes_timestamp_filter ( ) {
57925937 let query = build_sandbox_summary_query ( "exp'123" , "2026-03-19T12:00:00.000Z" ) ;
0 commit comments