11use std:: borrow:: Cow ;
2- use std:: ffi:: OsString ;
32use std:: fs;
3+ use std:: io:: { Read , Write } ;
44use std:: net:: SocketAddr ;
55use std:: path:: Path ;
6+ use std:: { ffi:: OsString , path:: PathBuf } ;
67
78use anyhow:: { anyhow, Context , Error } ;
89use rouille:: { Request , Response , Server } ;
@@ -16,9 +17,30 @@ pub fn spawn(
1617 tests : & [ String ] ,
1718 no_module : bool ,
1819 worker : bool ,
20+ coverage : Option < PathBuf > ,
1921) -> Result < Server < impl Fn ( & Request ) -> Response + Send + Sync > , Error > {
2022 let mut js_to_execute = String :: new ( ) ;
2123
24+ let ( cov_import, cov_dump) = if coverage. is_some ( ) {
25+ (
26+ if no_module {
27+ "let __wbgtest_cov_dump = wasm_bindgen.__wbgtest_cov_dump;"
28+ } else {
29+ "__wbgtest_cov_dump,"
30+ } ,
31+ r#"
32+ // Dump the coverage data collected during the tests
33+ const coverage = __wbgtest_cov_dump();
34+ await fetch("/__coverage/dump", {
35+ method: "POST",
36+ body: coverage
37+ });
38+ "# ,
39+ )
40+ } else {
41+ ( "" , "" )
42+ } ;
43+
2244 let wbg_import_script = if no_module {
2345 String :: from (
2446 r#"
@@ -28,6 +50,7 @@ pub fn spawn(
2850 let __wbgtest_console_info = wasm_bindgen.__wbgtest_console_info;
2951 let __wbgtest_console_warn = wasm_bindgen.__wbgtest_console_warn;
3052 let __wbgtest_console_error = wasm_bindgen.__wbgtest_console_error;
53+ {cov_import}
3154 let init = wasm_bindgen;
3255 "# ,
3356 )
@@ -41,6 +64,7 @@ pub fn spawn(
4164 __wbgtest_console_info,
4265 __wbgtest_console_warn,
4366 __wbgtest_console_error,
67+ {cov_import}
4468 default as init,
4569 }} from './{}';
4670 "# ,
@@ -95,6 +119,7 @@ pub fn spawn(
95119
96120 cx.args({1:?});
97121 await cx.run(tests.map(s => wasm[s]));
122+ {cov_dump}
98123 }}
99124
100125 onmessage = function(e) {{
@@ -175,6 +200,7 @@ pub fn spawn(
175200 cx.args({1:?});
176201
177202 await cx.run(test.map(s => wasm[s]));
203+ {cov_dump}
178204 }}
179205
180206 const tests = [];
@@ -218,6 +244,25 @@ pub fn spawn(
218244 )
219245 } ;
220246 return set_isolate_origin_headers ( Response :: from_data ( "text/html" , s) ) ;
247+ } else if request. url ( ) == "/__coverage/dump" {
248+ let profraw_path = coverage. as_ref ( ) . expect (
249+ "Received coverage dump request but server wasn't set up to accept coverage" ,
250+ ) ;
251+ // This is run after all tests are done and dumps the data received in the request
252+ // into a single profraw file
253+ let mut profraw =
254+ std:: fs:: File :: create ( profraw_path) . expect ( "Couldn't create .profraw for coverage" ) ;
255+ let mut data = Vec :: new ( ) ;
256+ request
257+ . data ( )
258+ . expect ( "Expected coverage data in body" )
259+ . read_to_end ( & mut data)
260+ . expect ( "Failed to read message body" ) ;
261+
262+ profraw
263+ . write_all ( & data)
264+ . expect ( "Couldn't dump coverage data to profraw" ) ;
265+ return Response :: text ( "Coverage dumped" ) ;
221266 }
222267
223268 // Otherwise we need to find the asset here. It may either be in our
0 commit comments