@ -198,8 +198,15 @@ impl Test {
context . run_jobs ( ) ;
context . run_jobs ( ) ;
if let Err ( e ) = async_result . inner . borrow ( ) . as_ref ( ) {
match * async_result . inner . borrow ( ) {
return ( false , format! ( "Uncaught {e}" ) ) ;
UninitResult ::Err ( ref e ) = > return ( false , format! ( "Uncaught {e}" ) ) ,
UninitResult ::Uninit if self . flags . contains ( TestFlags ::ASYNC ) = > {
return (
false ,
"async test did not print \"Test262:AsyncTestComplete\"" . to_string ( ) ,
)
}
_ = > { }
}
}
( true , value . display ( ) . to_string ( ) )
( true , value . display ( ) . to_string ( ) )
@ -423,9 +430,19 @@ fn register_print_fn(context: &mut Context<'_>, async_result: AsyncResult) {
. get_or_undefined ( 0 )
. get_or_undefined ( 0 )
. to_string ( context ) ?
. to_string ( context ) ?
. to_std_string_escaped ( ) ;
. to_std_string_escaped ( ) ;
if message ! = "Test262:AsyncTestComplete" {
let mut result = async_result . inner . borrow_mut ( ) ;
* async_result . inner . borrow_mut ( ) = Err ( message ) ;
match * result {
UninitResult ::Uninit | UninitResult ::Ok ( _ ) = > {
if message = = "Test262:AsyncTestComplete" {
* result = UninitResult ::Ok ( ( ) ) ;
} else {
* result = UninitResult ::Err ( message ) ;
}
}
UninitResult ::Err ( _ ) = > { }
}
}
Ok ( JsValue ::undefined ( ) )
Ok ( JsValue ::undefined ( ) )
} )
} )
} ,
} ,
@ -440,17 +457,35 @@ fn register_print_fn(context: &mut Context<'_>, async_result: AsyncResult) {
Attribute ::WRITABLE | Attribute ::NON_ENUMERABLE | Attribute ::CONFIGURABLE ,
Attribute ::WRITABLE | Attribute ::NON_ENUMERABLE | Attribute ::CONFIGURABLE ,
) ;
) ;
}
}
/// A `Result` value that is possibly uninitialized.
///
/// This is mainly used to check if an async test did call `print` to signal the termination of
/// a test. Otherwise, all async tests that result in `UninitResult::Uninit` are considered
/// as failed.
///
/// The Test262 [interpreting guide][guide] contains more information about how to run async tests.
///
/// [guide]: https://github.com/tc39/test262/blob/main/INTERPRETING.md#flags
#[ derive(Debug, Clone, Copy, Default) ]
enum UninitResult < T , E > {
#[ default ]
Uninit ,
Ok ( T ) ,
Err ( E ) ,
}
/// Object which includes the result of the async operation.
/// Object which includes the result of the async operation.
#[ derive(Debug, Clone) ]
#[ derive(Debug, Clone) ]
struct AsyncResult {
struct AsyncResult {
inner : Rc < RefCell < Result < ( ) , String > > > ,
inner : Rc < RefCell < Uninit Result< ( ) , String > > > ,
}
}
impl Default for AsyncResult {
impl Default for AsyncResult {
#[ inline ]
#[ inline ]
fn default ( ) -> Self {
fn default ( ) -> Self {
Self {
Self {
inner : Rc ::new ( RefCell ::new ( Ok ( ( ) ) ) ) ,
inner : Rc ::new ( RefCell ::new ( UninitResult ::default ( ) ) ) ,
}
}
}
}
}
}