char/avril
(wip) why'd you have to go and make things so complicaaaaated?
git clone https://git.t4t.associates/char/avril
688e96e
main
1#! [ allow ( dead_code )] 2// Shared across test targets; each uses only part of this module. 3use std:: fs; 4use std:: io::{ Read , Write }; 5use std:: process::{ Child , Command , Output , Stdio }; 6use std:: time::{ Duration , Instant }; 7 8pub fn spawn ( source : & str ) ->( tempfile:: TempDir , Child ) { 9let dir = tempfile:: tempdir (). unwrap (); 10let path = dir. path (). join ( "main.js" ); 11 fs:: write ( & path, source). unwrap (); 12let child =Command :: new ( env! ( "CARGO_BIN_EXE_avril" )) 13. arg ( "run" ) 14. arg ( path) 15. stdin ( Stdio :: piped ()) 16. stdout ( Stdio :: piped ()) 17. stderr ( Stdio :: piped ()) 18. spawn () 19. unwrap (); 20( dir, child) 21} 22 23fn capture ( mut pipe : impl Read +Send +' static ) -> std:: thread:: JoinHandle < Vec < u8 >> { 24 std:: thread:: spawn ( move ||{ 25let mut bytes =Vec :: new (); 26 pipe. read_to_end ( & mut bytes). unwrap (); 27 bytes 28}) 29} 30 31pub fn wait ( mut child : Child ) ->Output { 32let stdout = child. stdout . take (). map ( capture); 33let stderr = child. stderr . take (). map ( capture); 34let deadline =Instant :: now () +Duration :: from_secs ( 5 ); 35let status =loop { 36if let Some ( status) = child. try_wait (). unwrap () { 37break status; 38} 39if Instant :: now () >= deadline{ 40 child. kill (). unwrap (); 41 child. wait (). unwrap (); 42panic! ( "Runtime did not exit within five seconds" ); 43} 44 std:: thread:: sleep ( Duration :: from_millis ( 10 )); 45}; 46Output { 47 status, 48stdout : stdout 49. map ( |thread| thread. join (). unwrap ()) 50. unwrap_or_default (), 51stderr : stderr 52. map ( |thread| thread. join (). unwrap ()) 53. unwrap_or_default (), 54} 55} 56 57pub fn run ( source : & str , input : & [ u8 ]) ->Output { 58let ( _dir, mut child) =spawn ( source); 59let mut stdin = child. stdin . take (). unwrap (); 60let input = input. to_vec (); 61let writer = std:: thread:: spawn ( move || stdin. write_all ( & input)); 62let output =wait ( child); 63 writer. join (). unwrap (). unwrap (); 64assert! ( 65 output. status . success (), 66"{}" , 67String :: from_utf8_lossy ( & output. stderr ) 68); 69 output 70}