github.com/vugu/vugu@v0.3.6-0.20240430171613-3f6f402e014b/devutil/compiler_test.go (about) 1 package devutil 2 3 import ( 4 "bytes" 5 "io" 6 "net/http" 7 "net/http/httptest" 8 "os" 9 "path/filepath" 10 "strings" 11 "testing" 12 ) 13 14 func TestWasmCompiler(t *testing.T) { 15 16 tmpDir, err := os.MkdirTemp("", "TestWasmCompiler") 17 must(err) 18 defer os.RemoveAll(tmpDir) 19 t.Logf("Using temporary dir: %s", tmpDir) 20 21 wc := NewWasmCompiler().SetBuildDir(tmpDir) 22 23 must(os.WriteFile(filepath.Join(tmpDir, "go.mod"), []byte(`module TestWasmCompiler 24 `), 0644)) 25 26 // just build 27 must(os.WriteFile(filepath.Join(tmpDir, "main.go"), []byte(`package main 28 func main() {}`), 0644)) 29 outpath, err := wc.Execute() 30 if err != nil { 31 t.Fatal(err) 32 } 33 defer os.Remove(outpath) 34 _, err = os.Stat(outpath) 35 if err != nil { 36 t.Fatal(err) 37 } 38 39 // build with error 40 err = os.WriteFile(filepath.Join(tmpDir, "main.go"), []byte(`package main 41 func main() { not valid go code }`), 0644) 42 must(err) 43 _, err = wc.Execute() 44 if err == nil { 45 t.Fatal("should have gotten error here but didn't") 46 } 47 t.Logf("we correctly got a build error here: %v", err) 48 49 // with generate 50 must(os.WriteFile(filepath.Join(tmpDir, "main.go"), []byte(`package main 51 import "fmt" 52 //go:generate go run gen.go 53 func main() { fmt.Println(other) }`), 0644)) 54 must(os.WriteFile(filepath.Join(tmpDir, "gen.go"), []byte(`// +build ignore 55 56 package main 57 import "os" 58 func main() { os.WriteFile("./other.go", []byte("package main\nvar other = 123\n"), 0644) }`), 0644)) 59 wc.SetGenerateDir(tmpDir) 60 outpath, err = wc.Execute() 61 if err != nil { 62 t.Fatal(err) 63 } 64 defer os.Remove(outpath) 65 _, err = os.Stat(outpath) 66 if err != nil { 67 t.Fatal(err) 68 } 69 70 // new temp dir 71 tmpDir, err = os.MkdirTemp("", "TestWasmCompiler") 72 must(err) 73 defer os.RemoveAll(tmpDir) 74 t.Logf("Using temporary dir: %s", tmpDir) 75 wc = NewWasmCompiler().SetBuildDir(tmpDir) 76 var h http.Handler 77 78 must(os.WriteFile(filepath.Join(tmpDir, "go.mod"), []byte(`module TestWasmCompiler 79 `), 0644)) 80 81 // main wasm handler without error 82 must(os.WriteFile(filepath.Join(tmpDir, "main.go"), []byte(`package main 83 func main() {}`), 0644)) 84 h = NewMainWasmHandler(wc) 85 req, err := http.NewRequest("GET", "/main.wasm", nil) 86 must(err) 87 wr := httptest.NewRecorder() 88 h.ServeHTTP(wr, req) 89 res := wr.Result() 90 defer res.Body.Close() 91 // resb, _ := httputil.DumpResponse(res, true) 92 // t.Logf("RESPONSE: %s", resb) 93 if res.StatusCode != 200 { 94 t.Errorf("unexpected http status code: %d", res.StatusCode) 95 } 96 ct := res.Header.Get("Content-Type") 97 if !strings.HasPrefix(ct, "application/wasm") { 98 t.Errorf("unexpected value for Content-Type header: %s", ct) 99 } 100 b, err := io.ReadAll(res.Body) 101 must(err) 102 if !bytes.Equal(b[:4], []byte("\x00asm")) { 103 t.Errorf("got back bytes that do not look like a wasm file: %X (len=%d, cap=%d)", b[:4], len(b), cap(b)) 104 } 105 106 // main wasm handler with error 107 must(os.WriteFile(filepath.Join(tmpDir, "main.go"), []byte(`package main 108 func main() { not valid go code }`), 0644)) 109 h = NewMainWasmHandler(wc) 110 req, err = http.NewRequest("GET", "/main.wasm", nil) 111 must(err) 112 wr = httptest.NewRecorder() 113 h.ServeHTTP(wr, req) 114 res = wr.Result() 115 defer res.Body.Close() 116 // resb, _ := httputil.DumpResponse(res, true) 117 // t.Logf("RESPONSE: %s", resb) 118 if res.StatusCode != 500 { 119 t.Errorf("unexpected http status code: %d", res.StatusCode) 120 } 121 ct = res.Header.Get("Content-Type") 122 if !strings.HasPrefix(ct, "text/plain") { 123 t.Errorf("unexpected value for Content-Type header: %s", ct) 124 } 125 b, err = io.ReadAll(res.Body) 126 must(err) 127 if !bytes.Contains(b, []byte("build error")) { 128 t.Errorf("unexpected error result: %s", b) 129 } 130 131 // wasm exec js handler 132 h = NewWasmExecJSHandler(wc) 133 req, err = http.NewRequest("GET", "/wasm_exec.js", nil) 134 must(err) 135 wr = httptest.NewRecorder() 136 h.ServeHTTP(wr, req) 137 res = wr.Result() 138 defer res.Body.Close() 139 if res.StatusCode != 200 { 140 t.Errorf("unexpected http status code: %d", res.StatusCode) 141 } 142 ct = res.Header.Get("Content-Type") 143 if !strings.HasPrefix(ct, "text/javascript") { 144 t.Errorf("unexpected value for Content-Type header: %s", ct) 145 } 146 b, err = io.ReadAll(res.Body) 147 must(err) 148 if !bytes.Contains(b, []byte("The Go Authors")) { 149 t.Errorf("unexpected js result: %s", b) 150 } 151 152 } 153 154 func must(err error) { 155 if err != nil { 156 panic(err) 157 } 158 }