github.com/vugu/vugu@v0.3.6-0.20240430171613-3f6f402e014b/gen/missing-fixer_test.go (about)

     1  package gen
     2  
     3  import (
     4  	"os"
     5  	"os/exec"
     6  	"path/filepath"
     7  	"runtime"
     8  	"strings"
     9  	"testing"
    10  )
    11  
    12  func TestMissingFixer(t *testing.T) {
    13  
    14  	// NOTE: for more complex testing, see TestRun which is easier to add more general cases to.
    15  
    16  	tmpDir, err := os.MkdirTemp("", "TestMissingFixer")
    17  	if err != nil {
    18  		t.Fatal(err)
    19  	}
    20  	defer os.RemoveAll(tmpDir)
    21  
    22  	must := func(err error) {
    23  		if err != nil {
    24  			_, file, line, _ := runtime.Caller(1)
    25  			t.Fatalf("from %s:%d: %v", file, line, err)
    26  		}
    27  	}
    28  	vuguAbs, _ := filepath.Abs("..")
    29  
    30  	must(os.WriteFile(filepath.Join(tmpDir, "go.mod"), []byte("module missingfixertest\n\nreplace github.com/vugu/vugu => "+vuguAbs+"\n"), 0644))
    31  	must(os.WriteFile(filepath.Join(tmpDir, "events.go"), []byte("package main\n\n//vugugen:event Something\n//vugugen:event SomeOtherThing\n//vugugen:event SomeOtherThing\n"), 0644))
    32  	must(os.WriteFile(filepath.Join(tmpDir, "root.vugu"), []byte("<div>root</div>"), 0644))
    33  	must(os.WriteFile(filepath.Join(tmpDir, "root_gen.go"), []byte("package main\n\nimport \"github.com/vugu/vugu\"\n\nfunc (c *Root)Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) {return nil}"), 0644))
    34  	// a second component that does include it's own struct definition
    35  	must(os.WriteFile(filepath.Join(tmpDir, "comp1.vugu"), []byte("<div>comp1</div>"), 0644))
    36  	must(os.WriteFile(filepath.Join(tmpDir, "comp1_gen.go"), []byte("package main\n\nimport \"github.com/vugu/vugu\"\n\ntype Comp1 struct{}\n\nfunc (c *Comp1)Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) {return nil}"), 0644))
    37  	// a file with an event where the event type is declared but not the handler interface or func
    38  	must(os.WriteFile(filepath.Join(tmpDir, "epart.go"), []byte("package main\n\n//vugugen:event Part\ntype PartEvent struct { A string }\n"), 0644))
    39  
    40  	// 	// TEMP
    41  	// 	must(os.WriteFile(filepath.Join(tmpDir, "root_gen.go"), []byte(`
    42  	// package main
    43  
    44  	// import "github.com/vugu/vugu"
    45  
    46  	// type Root struct {}
    47  
    48  	// func (c *Root)Build(vgin *vugu.BuildIn) (vgout *vugu.BuildOut) {return nil}
    49  
    50  	// `), 0644))
    51  
    52  	mf := newMissingFixer(tmpDir, "main", map[string]string{
    53  		"root.vugu": "root_gen.go",
    54  		// "comp1.vugu": "comp1_gen.go",
    55  	})
    56  	err = mf.run()
    57  	if err != nil {
    58  		t.Fatal(err)
    59  	}
    60  
    61  	b, err := os.ReadFile(filepath.Join(tmpDir, "0_missing_gen.go"))
    62  	must(err)
    63  	t.Logf("0_missing_gen.go result:\n%s", b)
    64  	s := string(b)
    65  	checks := []string{
    66  		"type Root struct",
    67  
    68  		"!type Comp1 struct",
    69  
    70  		"type SomethingEvent struct",
    71  		"type SomethingHandler interface",
    72  		"type SomethingFunc func",
    73  		"func (f SomethingFunc) SomethingHandle(",
    74  		"var _ SomethingHandler =",
    75  
    76  		// "type PartEvent struct", // should exist only in epart.go
    77  
    78  		// "type SomeOtherThingEvent interface",
    79  		// "type SomeOtherThingHandler interface",
    80  		// "type SomeOtherThingHandlerFunc func",
    81  		// "func (f SomeOtherThingHandlerFunc) SomeOtherThingHandle(",
    82  		// "var _ SomeOtherThingHandler =",
    83  	}
    84  	for _, check := range checks {
    85  		if check[0] == '!' {
    86  			if strings.Contains(s, check[1:]) {
    87  				t.Errorf("found unexpected %q", check[1:])
    88  			}
    89  		} else if !strings.Contains(s, check) {
    90  			t.Errorf("missing %q", check)
    91  		}
    92  	}
    93  
    94  	if t.Failed() {
    95  		return
    96  	}
    97  	// if the above worked, try compiling it
    98  	must(os.WriteFile(filepath.Join(tmpDir, "main.go"), []byte("package main\n\nfunc main(){}\n"), 0644))
    99  
   100  	cmd := exec.Command("go", "mod", "tidy")
   101  	cmd.Dir = tmpDir
   102  	_, err = cmd.CombinedOutput()
   103  	if err != nil {
   104  		t.Logf("build output: %s", b)
   105  		t.Fatal(err)
   106  	}
   107  	cmd = exec.Command("go", "build", "-o", "a.out", ".")
   108  	cmd.Dir = tmpDir
   109  	b, err = cmd.CombinedOutput()
   110  	if err != nil {
   111  		t.Logf("build output: %s", b)
   112  		t.Fatal(err)
   113  	}
   114  
   115  	// ensure the output is there
   116  	_, err = os.Stat(filepath.Join(tmpDir, "a.out"))
   117  	if err != nil {
   118  		t.Fatal(err)
   119  	}
   120  }