From bba38b6c9041cdd04596575fc25857f69eb2ab77 Mon Sep 17 00:00:00 2001 From: John Starich Date: Tue, 20 Dec 2022 11:25:03 -0600 Subject: [PATCH] Add test coverage support (#41) * Move index.html to separate file with Go 1.16 embedded files * Add test coverage support Overrides three file system operations for the purposes of reading and writing the coverage profile file. The contents are copied out of the JS runtime and written again to the real file. * Extract FS wrappers to 'overrideFS' function Also guard use of global TextDecoder if not supported. * Wrap each FS operation, switch from writeSync() to write(), and bind "fs" as "this" --- go.mod | 2 +- handler.go | 99 ++++++++++++++---------------------------------------- index.html | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ main.go | 16 +++++++-- 4 files changed, 139 insertions(+), 77 deletions(-) create mode 100644 index.html diff --git a/go.mod b/go.mod index bd9a452..079c6a2 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/agnivade/wasmbrowsertest -go 1.12 +go 1.16 require ( github.com/chromedp/cdproto v0.0.0-20221108233440-fad8339618ab diff --git a/handler.go b/handler.go index 1b4a1a4..8fc185d 100644 --- a/handler.go +++ b/handler.go @@ -1,6 +1,7 @@ package main import ( + _ "embed" "html/template" "io/ioutil" "log" @@ -14,22 +15,27 @@ import ( "time" ) +//go:embed index.html +var indexHTML string + type wasmServer struct { - indexTmpl *template.Template - wasmFile string - wasmExecJS []byte - args []string - envMap map[string]string - logger *log.Logger + indexTmpl *template.Template + wasmFile string + wasmExecJS []byte + args []string + coverageFile string + envMap map[string]string + logger *log.Logger } -func NewWASMServer(wasmFile string, args []string, l *log.Logger) (http.Handler, error) { +func NewWASMServer(wasmFile string, args []string, coverageFile string, l *log.Logger) (http.Handler, error) { var err error srv := &wasmServer{ - wasmFile: wasmFile, - args: args, - logger: l, - envMap: make(map[string]string), + wasmFile: wasmFile, + args: args, + coverageFile: coverageFile, + logger: l, + envMap: make(map[string]string), } for _, env := range os.Environ() { @@ -56,13 +62,15 @@ func (ws *wasmServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { case "/", "/index.html": w.Header().Set("Content-Type", "text/html; charset=UTF-8") data := struct { - WASMFile string - Args []string - EnvMap map[string]string + WASMFile string + Args []string + CoverageFile string + EnvMap map[string]string }{ - WASMFile: filepath.Base(ws.wasmFile), - Args: ws.args, - EnvMap: ws.envMap, + WASMFile: filepath.Base(ws.wasmFile), + Args: ws.args, + CoverageFile: ws.coverageFile, + EnvMap: ws.envMap, } err := ws.indexTmpl.Execute(w, data) if err != nil { @@ -89,60 +97,3 @@ func (ws *wasmServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { } } } - -const indexHTML = ` - - - - - - Go wasm - - - - - - - - - -` diff --git a/index.html b/index.html new file mode 100644 index 0000000..38cadcc --- /dev/null +++ b/index.html @@ -0,0 +1,99 @@ + + + + + + + Go wasm + + + + + + + + + + diff --git a/main.go b/main.go index 3c2cbff..71b3f54 100644 --- a/main.go +++ b/main.go @@ -25,7 +25,8 @@ import ( ) var ( - cpuProfile *string + cpuProfile *string + coverageProfile *string ) func main() { @@ -45,6 +46,7 @@ func main() { } cpuProfile = flag.String("test.cpuprofile", "", "") + coverageProfile = flag.String("test.coverprofile", "", "") wasmFile := os.Args[1] ext := path.Ext(wasmFile) @@ -61,6 +63,9 @@ func main() { passon := gentleParse(flag.CommandLine, os.Args[2:]) passon = append([]string{wasmFile}, passon...) + if *coverageProfile != "" { + passon = append(passon, "-test.coverprofile="+*coverageProfile) + } // Need to generate a random port every time for tests in parallel to run. l, err := net.Listen("tcp", "localhost:") @@ -77,7 +82,7 @@ func main() { } // Setup web server. - handler, err := NewWASMServer(wasmFile, passon, logger) + handler, err := NewWASMServer(wasmFile, passon, *coverageProfile, logger) if err != nil { logger.Fatal(err) } @@ -117,10 +122,12 @@ func main() { } done <- struct{}{} }() + var coverageProfileContents string tasks := []chromedp.Action{ chromedp.Navigate(`http://localhost:` + port), chromedp.WaitEnabled(`#doneButton`), chromedp.Evaluate(`exitCode;`, &exitCode), + chromedp.Evaluate(`coverageProfileContents;`, &coverageProfileContents), } if *cpuProfile != "" { // Prepend and append profiling tasks @@ -152,6 +159,11 @@ func main() { return WriteProfile(profile, outF, funcMap) })) } + if *coverageProfile != "" { + tasks = append(tasks, chromedp.ActionFunc(func(ctx context.Context) error { + return os.WriteFile(*coverageProfile, []byte(coverageProfileContents), 0644) + })) + } err = chromedp.Run(ctx, tasks...) if err != nil {