         '[ _ run-file ] [
             restartable-tests? get
             [ dup compute-restarts empty? not ] [ f ] if
-            [ rethrow ] [ file-failure ] if
+            [ rethrow ] [ notify-test-file-failed ] if
         ] recover
     ] with-variable ;
 


<PRIVATE

: failure ( error experiment path line# -- )
    "--> test failed!" print
    <test-failure> test-failures get push
    notify-error-observers ;

SYMBOL: current-test-file

: file-failure ( error -- )
    [ f current-test-file get ] keep error-line failure ;

:: (unit-test) ( output input -- error ? )
    [ { } input with-datastack output assert-sequence= f f ] [ t ] recover ;

: short-effect ( effect -- pair )
    [ in>> length ] [ out>> length ] bi 2array ;

:: (must-infer-as) ( effect quot -- error ? )
    [ quot infer short-effect effect assert= f f ] [ t ] recover ;

:: (must-infer) ( quot -- error ? )
    [ quot infer drop f f ] [ t ] recover ;

TUPLE: did-not-fail ;
CONSTANT: did-not-fail-literal T{ did-not-fail }

M: did-not-fail summary drop "Did not fail" ;

:: (must-fail-with) ( quot pred -- error ? )
    [ { } quot with-datastack drop did-not-fail-literal t ]
    [ dup pred call( error -- ? ) [ drop f f ] [ t ] if ] recover ;

:: (must-fail) ( quot -- error ? )
    [ { } quot with-datastack drop did-not-fail-literal t ] [ drop f f ] recover ;

: experiment-title ( word -- string )
    "(" ?head drop ")" ?tail drop

    [ cleanup-unique-directory ] with-temp-directory ; inline

TEST: unit-test
TEST: long-unit-test
TEST: must-infer-as
TEST: must-infer
TEST: must-fail-with
