@@ -185,6 +185,18 @@ hyperlight_js_runtime::native_modules! {
185185 "test_math_macro" => js_test_math,
186186}
187187
188+ // ── custom_globals! macro ──────────────────────────────────────────────────
189+
190+ fn setup_test_constant ( ctx : & rquickjs:: Ctx < ' _ > ) -> rquickjs:: Result < ( ) > {
191+ ctx. eval :: < ( ) , _ > ( "globalThis.TEST_CUSTOM_GLOBAL = 99;" ) ?;
192+ Ok ( ( ) )
193+ }
194+
195+ // The macro generates init_custom_globals() which calls each setup function
196+ hyperlight_js_runtime:: custom_globals! {
197+ setup_test_constant,
198+ }
199+
188200#[ test]
189201fn macro_generated_init_registers_modules ( ) {
190202 init_native_modules ( ) ;
@@ -445,3 +457,120 @@ fn full_pipeline_console_log_with_custom_modules() {
445457 let lines: Vec < & str > = stdout. trim ( ) . lines ( ) . collect ( ) ;
446458 assert_eq ! ( lines, [ "computed: 54" , "Handler result: 54" ] ) ;
447459}
460+
461+ // ── custom_globals! tests ──────────────────────────────────────────────────
462+
463+ #[ test]
464+ fn e2e_custom_globals_are_available_in_handlers ( ) {
465+ let mut runtime =
466+ hyperlight_js_runtime:: JsRuntime :: new ( NoOpHost ) . expect ( "Failed to create JsRuntime" ) ;
467+
468+ let handler_script = r#"
469+ export function handler(event) {
470+ return TEST_CUSTOM_GLOBAL;
471+ }
472+ "# ;
473+
474+ runtime
475+ . register_handler ( "globals_handler" , handler_script, "." )
476+ . expect ( "Failed to register handler" ) ;
477+
478+ let result = runtime
479+ . run_handler ( "globals_handler" . to_string ( ) , "{}" . to_string ( ) , false )
480+ . expect ( "Failed to run handler" ) ;
481+
482+ assert_eq ! ( result, "99" ) ;
483+ }
484+
485+ #[ test]
486+ fn e2e_custom_globals_coexist_with_builtins ( ) {
487+ let mut runtime =
488+ hyperlight_js_runtime:: JsRuntime :: new ( NoOpHost ) . expect ( "Failed to create JsRuntime" ) ;
489+
490+ let handler_script = r#"
491+ export function handler(event) {
492+ // Built-in console should still work
493+ console.log("custom global value: " + TEST_CUSTOM_GLOBAL);
494+ return TEST_CUSTOM_GLOBAL;
495+ }
496+ "# ;
497+
498+ runtime
499+ . register_handler ( "globals_coexist" , handler_script, "." )
500+ . expect ( "Failed to register handler" ) ;
501+
502+ let result = runtime
503+ . run_handler ( "globals_coexist" . to_string ( ) , "{}" . to_string ( ) , false )
504+ . expect ( "Failed to run handler" ) ;
505+
506+ assert_eq ! ( result, "99" ) ;
507+ }
508+
509+ // ── Full pipeline custom globals tests ─────────────────────────────────────
510+
511+ #[ test]
512+ fn full_pipeline_custom_globals_available ( ) {
513+ let binary = & * EXTENDED_RUNTIME_BINARY ;
514+ let dir = tempfile:: tempdir ( ) . unwrap ( ) ;
515+
516+ std:: fs:: write (
517+ dir. path ( ) . join ( "handler.js" ) ,
518+ r#"
519+ function handler(event) {
520+ return CUSTOM_GLOBAL_TEST;
521+ }
522+ "# ,
523+ )
524+ . unwrap ( ) ;
525+
526+ let output = Command :: new ( binary)
527+ . arg ( dir. path ( ) . join ( "handler.js" ) )
528+ . arg ( "{}" )
529+ . output ( )
530+ . unwrap ( ) ;
531+
532+ assert ! (
533+ output. status. success( ) ,
534+ "Failed:\n {}" ,
535+ String :: from_utf8_lossy( & output. stderr)
536+ ) ;
537+ let stdout = String :: from_utf8_lossy ( & output. stdout ) ;
538+ assert ! (
539+ stdout. contains( "Handler result: 42" ) ,
540+ "Expected custom global to be 42, got: {stdout}"
541+ ) ;
542+ }
543+
544+ #[ test]
545+ fn full_pipeline_custom_globals_with_modules ( ) {
546+ let binary = & * EXTENDED_RUNTIME_BINARY ;
547+ let dir = tempfile:: tempdir ( ) . unwrap ( ) ;
548+
549+ std:: fs:: write (
550+ dir. path ( ) . join ( "handler.js" ) ,
551+ r#"
552+ import { add } from "math";
553+ function handler(event) {
554+ return add(CUSTOM_GLOBAL_TEST, event.x);
555+ }
556+ "# ,
557+ )
558+ . unwrap ( ) ;
559+
560+ let output = Command :: new ( binary)
561+ . arg ( dir. path ( ) . join ( "handler.js" ) )
562+ . arg ( r#"{"x":8}"# )
563+ . output ( )
564+ . unwrap ( ) ;
565+
566+ assert ! (
567+ output. status. success( ) ,
568+ "Failed:\n {}" ,
569+ String :: from_utf8_lossy( & output. stderr)
570+ ) ;
571+ let stdout = String :: from_utf8_lossy ( & output. stdout ) ;
572+ assert ! (
573+ stdout. contains( "Handler result: 50" ) ,
574+ "Expected 42 + 8 = 50, got: {stdout}"
575+ ) ;
576+ }
0 commit comments