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  }