char/avril
(wip) why'd you have to go and make things so complicaaaaated?
git clone https://git.t4t.associates/char/avril
688e96e
main
1use std:: process::{ Command , Output }; 2 3fn run ( source : & str , args : & [ & str ]) ->( tempfile:: TempDir , Output ) { 4let dir = tempfile:: tempdir (). unwrap (); 5 std:: fs:: write ( dir. path (). join ( "main.ts" ), source). unwrap (); 6let output =Command :: new ( env! ( "CARGO_BIN_EXE_avril" )) 7. current_dir ( dir. path ()) 8. arg ( "run" ) 9. args ( args) 10. arg ( "main.ts" ) 11. output () 12. unwrap (); 13( dir, output) 14} 15 16fn success ( output : & Output ) ->String { 17assert! ( 18 output. status . success (), 19"{}" , 20String :: from_utf8_lossy ( & output. stderr ) 21); 22String :: from_utf8 ( output. stdout . clone ()). unwrap () 23} 24 25# [ test ] 26fn process_and_runtime_report_this_host () { 27let ( dir, output) =run ( 28r#" 29import { process, runtime } from 'avril:std'; 30console.log(process.pid > 0, process.cwd(), process.hostname().length > 0, 31process.osRelease().length > 0, process.uptime() >= 0, 32process.loadavg().length === 3, process.loadavg().every((value) => value >= 0)); 33console.log(runtime.os, runtime.arch, runtime.version, runtime.v8.length > 0); 34console.log(Object.isFrozen(process), Object.isFrozen(runtime)); 35"# , 36& [], 37); 38let text =success ( & output); 39let lines: Vec < & str > = text. lines (). collect (); 40assert_eq! ( lines. len (), 3 ); 41assert_eq! ( 42 lines[ 0 ], 43format! ( 44"true {} true true true true true" , 45 dir. path (). canonicalize (). unwrap (). display () 46) 47); 48assert_eq! ( 49 lines[ 1 ], 50format! ( 51"{} {} {} true" , 52 std:: env:: consts:: OS , 53 std:: env:: consts:: ARCH , 54env! ( "CARGO_PKG_VERSION" ) 55) 56); 57assert_eq! ( lines[ 2 ], "true true" ); 58} 59 60# [ test ] 61fn sys_and_cwd_are_gated_independently () { 62let ( _dir, output) =run ( 63r#" 64import { errors, process, runtime } from 'avril:std'; 65function denied(call) { 66try { call(); return false; } 67catch (error) { return error instanceof errors.PermissionDenied; } 68} 69console.log(process.pid > 0, runtime.os.length > 0); 70console.log(denied(() => process.cwd()), denied(() => process.hostname()), 71process.uptime() >= 0, denied(() => process.loadavg())); 72"# , 73& [ "-0" , "--allow-sys=uptime" ], 74); 75assert_eq! ( success ( & output), "true true\ntrue true true true\n" ); 76} 77 78# [ test ] 79fn grants_and_pledges_narrow_sys_and_cwd () { 80let ( _dir, output) =run ( 81r#" 82import { pledge, process } from 'avril:std'; 83function denied(call) { 84try { call(); return false; } 85catch (error) { return error.name === 'PermissionDenied'; } 86} 87console.log(process.cwd().length > 0, process.hostname().length > 0); 88pledge({ sys: { allow: ['hostname'] } }); 89console.log(process.hostname().length > 0, denied(() => process.osRelease()), 90denied(() => process.uptime())); 91pledge({ read: false }); 92console.log(denied(() => process.cwd()), process.hostname().length > 0); 93pledge({ sys: false }); 94console.log(denied(() => process.hostname())); 95try { pledge({ sys: { allow: ['bogus'] } }); console.log('accepted'); } 96catch (error) { console.log(error instanceof TypeError); } 97"# , 98& [], 99); 100assert_eq! ( 101success ( & output), 102"true true\ntrue true true\ntrue true\ntrue\ntrue\n" 103); 104} 105 106# [ test ] 107fn unknown_sys_names_are_rejected_at_startup () { 108let ( _dir, output) =run ( 109"import { process } from 'avril:std'; console.log(process.hostname());" , 110& [ "-0" , "--allow-sys=bogus" ], 111); 112assert! ( !output. status . success ()); 113assert! ( 114String :: from_utf8_lossy ( & output. stderr ). contains ( "Unknown system information name: bogus" ), 115"{}" , 116String :: from_utf8_lossy ( & output. stderr ) 117); 118}