github.com/vugu/vugu@v0.3.6-0.20240430171613-3f6f402e014b/staticrender/renderer-static_test.go (about)

     1  package staticrender
     2  
     3  import (
     4  	"os"
     5  	"os/exec"
     6  	"path/filepath"
     7  	"regexp"
     8  	"testing"
     9  
    10  	"github.com/vugu/vugu/gen"
    11  )
    12  
    13  func TestRendererStaticTable(t *testing.T) {
    14  
    15  	debug := false
    16  
    17  	vuguDir, err := filepath.Abs("..")
    18  	if err != nil {
    19  		t.Fatal(err)
    20  	}
    21  
    22  	type tcase struct {
    23  		name          string
    24  		opts          gen.ParserGoPkgOpts
    25  		recursive     bool
    26  		infiles       map[string]string              // file structure to start with
    27  		outReMatch    []string                       // regexps that must match against output
    28  		outReNotMatch []string                       // regexps that must not match against output
    29  		afterRun      func(dir string, t *testing.T) // called after Run
    30  		bfiles        map[string]string              // additional files to write before building
    31  	}
    32  
    33  	tcList := []tcase{
    34  		{
    35  			name:      "simple",
    36  			opts:      gen.ParserGoPkgOpts{},
    37  			recursive: false,
    38  			infiles: map[string]string{
    39  				"root.vugu": `<div>root here</div>`,
    40  			},
    41  			outReMatch:    []string{`root here`},
    42  			outReNotMatch: []string{`should not match`},
    43  		},
    44  		{
    45  			name:      "full-html",
    46  			opts:      gen.ParserGoPkgOpts{},
    47  			recursive: false,
    48  			infiles: map[string]string{
    49  				"root.vugu": `<html><title vg-if='true'>test title</title><body><div>root here</div></body></html><script src="/a.js"></script>`,
    50  			},
    51  			outReMatch: []string{
    52  				`root here`,
    53  				`<title>test title</title>`, // if statement should have fired
    54  				`</div><script src="/a.js"></script></body>`, // js should have be written directly inside the body tag
    55  			},
    56  			outReNotMatch: []string{`should not match`},
    57  		},
    58  		{
    59  			name:      "comp",
    60  			opts:      gen.ParserGoPkgOpts{},
    61  			recursive: false,
    62  			infiles: map[string]string{
    63  				"root.vugu": `<html>
    64  <head>
    65  <title>testing!</title>
    66  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"/>
    67  <script>
    68  console.log("Some script here");
    69  </script>
    70  </head>
    71  <body>
    72  <div>
    73  	This is a test!
    74  	Component here:
    75  	<main:Comp1/>
    76  </div>
    77  </body>
    78  </html>`,
    79  				"comp1.vugu": `<span>
    80  comp1 in the house
    81  <div vg-content='vugu.HTML("<p>Some <strong>nested</strong> craziness</p>")'></div>
    82  </span>`,
    83  			},
    84  			outReMatch: []string{
    85  				`<div><p>Some <strong>nested</strong> craziness</p></div>`,
    86  				`bootstrap.min.css`,
    87  				`Some script here`,
    88  			},
    89  			outReNotMatch: []string{`should not match`},
    90  		},
    91  		{
    92  			name:      "vg-template",
    93  			opts:      gen.ParserGoPkgOpts{},
    94  			recursive: false,
    95  			infiles: map[string]string{
    96  				"root.vugu": `<div><span>example1</span><vg-template vg-if='true'>text here</vg-template></div>`,
    97  			},
    98  			outReMatch: []string{
    99  				`<span>example1</span>text here`,
   100  			},
   101  			outReNotMatch: []string{`vg-template`},
   102  		},
   103  	}
   104  
   105  	for _, tc := range tcList {
   106  		tc := tc
   107  		t.Run(tc.name, func(t *testing.T) {
   108  
   109  			tmpDir, err := os.MkdirTemp("", "TestRendererStaticTable")
   110  			if err != nil {
   111  				t.Fatal(err)
   112  			}
   113  
   114  			if debug {
   115  				t.Logf("Test %q using tmpDir: %s", tc.name, tmpDir)
   116  			} else {
   117  				t.Parallel()
   118  			}
   119  
   120  			// write a sensible go.mod and main.go, individual tests can override if they really want
   121  			startf := make(map[string]string, 2)
   122  			startf["go.mod"] = "module testcase\nreplace github.com/vugu/vugu => " + vuguDir + "\n"
   123  			startf["main.go"] = `// +build !wasm
   124  
   125  package main
   126  
   127  import (
   128  	"os"
   129  
   130  	"github.com/vugu/vugu"
   131  	"github.com/vugu/vugu/staticrender"
   132  )
   133  
   134  func main() {
   135  
   136  	rootBuilder := &Root{}
   137  
   138  	buildEnv, err := vugu.NewBuildEnv()
   139  	if err != nil { panic(err) }
   140  
   141  	renderer := staticrender.New(os.Stdout)
   142  
   143  	buildResults := buildEnv.RunBuild(rootBuilder)
   144  
   145  	err = renderer.Render(buildResults)
   146  	if err != nil { panic(err) }
   147  	
   148  }
   149  `
   150  			tstWriteFiles(tmpDir, startf)
   151  
   152  			tstWriteFiles(tmpDir, tc.infiles)
   153  
   154  			tc.opts.SkipGoMod = true
   155  			tc.opts.SkipMainGo = true
   156  			if tc.recursive {
   157  				err = gen.RunRecursive(tmpDir, &tc.opts)
   158  			} else {
   159  				err = gen.Run(tmpDir, &tc.opts)
   160  			}
   161  			if err != nil {
   162  				t.Fatal(err)
   163  			}
   164  
   165  			if tc.afterRun != nil {
   166  				tc.afterRun(tmpDir, t)
   167  			}
   168  
   169  			tstWriteFiles(tmpDir, tc.bfiles)
   170  
   171  			// build executable for this platform
   172  			cmd := exec.Command("go", "mod", "tidy")
   173  			cmd.Dir = tmpDir
   174  			b, err := cmd.CombinedOutput()
   175  			if err != nil {
   176  				t.Fatalf("build error: %s; OUTPUT:\n%s", err, b)
   177  			}
   178  			cmd = exec.Command("go", "build", "-o", "main.out", ".")
   179  			cmd.Dir = tmpDir
   180  			b, err = cmd.CombinedOutput()
   181  			if err != nil {
   182  				t.Fatalf("build error: %s; OUTPUT:\n%s", err, b)
   183  			}
   184  
   185  			// now execute the command and capture the output
   186  			cmd = exec.Command(filepath.Join(tmpDir, "main.out"))
   187  			cmd.Dir = tmpDir
   188  			b, err = cmd.CombinedOutput()
   189  			if err != nil {
   190  				t.Fatalf("run error: %s; OUTPUT:\n%s", err, b)
   191  			}
   192  
   193  			// verify the output
   194  			for _, reTxt := range tc.outReMatch {
   195  				re := regexp.MustCompile(reTxt)
   196  				if !re.Match(b) {
   197  					t.Errorf("Failed to match regexp %q on output", reTxt)
   198  				}
   199  			}
   200  			for _, reTxt := range tc.outReNotMatch {
   201  				re := regexp.MustCompile(reTxt)
   202  				if re.Match(b) {
   203  					t.Errorf("Unexpected match for regexp %q on output", reTxt)
   204  				}
   205  			}
   206  
   207  			// only if everthing is golden do we remove
   208  			if !t.Failed() {
   209  				os.RemoveAll(tmpDir)
   210  			} else {
   211  				// and if not then dump the output that was produced
   212  				t.Logf("FULL OUTPUT:\n%s", b)
   213  			}
   214  
   215  		})
   216  	}
   217  
   218  }
   219  
   220  func tstWriteFiles(dir string, m map[string]string) {
   221  
   222  	for name, contents := range m {
   223  		p := filepath.Join(dir, name)
   224  		err := os.MkdirAll(filepath.Dir(p), 0755)
   225  		if err != nil {
   226  			panic(err)
   227  		}
   228  		err = os.WriteFile(p, []byte(contents), 0644)
   229  		if err != nil {
   230  			panic(err)
   231  		}
   232  	}
   233  
   234  }
   235  
   236  // NOTE: this was moved into the table test above
   237  // func TestRendererStatic(t *testing.T) {
   238  
   239  // 	cachekiller := 0
   240  // 	_ = cachekiller
   241  
   242  // 	// make a temp dir
   243  
   244  // 	tmpDir, err := os.MkdirTemp("", "TestRendererStatic")
   245  // 	if err != nil {
   246  // 		t.Fatal(err)
   247  // 	}
   248  // 	log.Printf("tmpDir: %s", tmpDir)
   249  // 	// defer os.RemoveAll(tmpDir)
   250  
   251  // 	wd, err := os.Getwd()
   252  // 	if err != nil {
   253  // 		t.Fatal(err)
   254  // 	}
   255  // 	vuguwd, err := filepath.Abs(filepath.Join(wd, ".."))
   256  // 	if err != nil {
   257  // 		t.Fatal(err)
   258  // 	}
   259  
   260  // 	// put a go.mod here that points back to the local copy of vugu
   261  // 	err = os.WriteFile(filepath.Join(tmpDir, "go.mod"), []byte(fmt.Sprintf(`module test-render-static
   262  // replace github.com/vugu/vugu => %s
   263  // require github.com/vugu/vugu v0.0.0-00010101000000-000000000000
   264  // `, vuguwd)), 0644)
   265  
   266  // 	// output some components
   267  
   268  // 	err = os.WriteFile(filepath.Join(tmpDir, "root.vugu"), []byte(`<html>
   269  // <head>
   270  // <title>testing!</title>
   271  // <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"/>
   272  // <script>
   273  // console.log("Some script here");
   274  // </script>
   275  // </head>
   276  // <body>
   277  // <div>
   278  // 	This is a test!
   279  // 	Component here:
   280  // 	<main:Comp1/>
   281  // </div>
   282  // </body>
   283  // </html>`), 0644)
   284  // 	if err != nil {
   285  // 		t.Fatal(err)
   286  // 	}
   287  
   288  // 	err = os.WriteFile(filepath.Join(tmpDir, "comp1.vugu"), []byte(`<span>
   289  // comp1 in the house
   290  // <div vg-content='vugu.HTML("<p>Some <strong>nested</strong> craziness</p>")'></div>
   291  // </span>`), 0644)
   292  // 	if err != nil {
   293  // 		t.Fatal(err)
   294  // 	}
   295  
   296  // 	// run the vugu codegen
   297  
   298  // 	p := gen.NewParserGoPkg(tmpDir, nil)
   299  // 	err = p.Run()
   300  // 	if err != nil {
   301  // 		t.Fatal(err)
   302  // 	}
   303  
   304  // 	// put our static output generation code here
   305  
   306  // 	err = os.WriteFile(filepath.Join(tmpDir, "staticout.go"), []byte(`// +build !wasm
   307  
   308  // package main
   309  
   310  // import (
   311  // 	"log"
   312  // 	//"fmt"
   313  // 	"flag"
   314  // 	"os"
   315  
   316  // 	"github.com/vugu/vugu"
   317  // 	"github.com/vugu/vugu/staticrender"
   318  // )
   319  
   320  // func main() {
   321  
   322  // 	//mountPoint := flag.String("mount-point", "#vugu_mount_point", "The query selector for the mount point for the root component, if it is not a full HTML component")
   323  // 	flag.Parse()
   324  
   325  // 	//fmt.Printf("Entering main(), -mount-point=%q\n", *mountPoint)
   326  // 	//defer fmt.Printf("Exiting main()\n")
   327  
   328  // 	rootBuilder := &Root{}
   329  
   330  // 	buildEnv, err := vugu.NewBuildEnv()
   331  // 	if err != nil {
   332  // 		log.Fatal(err)
   333  // 	}
   334  
   335  // 	renderer := staticrender.New(os.Stdout)
   336  
   337  // 	buildResults := buildEnv.RunBuild(rootBuilder)
   338  
   339  // 	err = renderer.Render(buildResults)
   340  // 	if err != nil {
   341  // 		panic(err)
   342  // 	}
   343  
   344  // }
   345  // 	`), 0644)
   346  // 	if err != nil {
   347  // 		t.Fatal(err)
   348  // 	}
   349  
   350  // 	// build it
   351  // 	cmd := exec.Command("go", "build", "-v", "-o", "staticout")
   352  // 	cmd.Dir = tmpDir
   353  // 	b, err := cmd.CombinedOutput()
   354  // 	log.Printf("go build produced:\n%s", b)
   355  // 	if err != nil {
   356  // 		t.Fatal(err)
   357  // 	}
   358  
   359  // 	// run it and see what it output
   360  
   361  // 	cmd = exec.Command("./staticout")
   362  // 	cmd.Dir = tmpDir
   363  // 	b, err = cmd.CombinedOutput()
   364  // 	log.Printf("staticout produced:\n%s", b)
   365  
   366  // 	if err != nil {
   367  // 		t.Fatal(err)
   368  // 	}
   369  
   370  // 	if !strings.Contains(string(b), "<div><p>Some <strong>nested</strong> craziness</p></div>") {
   371  // 		t.Errorf("falied to find target string in output")
   372  // 	}
   373  // 	if !strings.Contains(string(b), "bootstrap.min.css") {
   374  // 		t.Errorf("falied to find target string in output")
   375  // 	}
   376  // 	if !strings.Contains(string(b), "Some script here") {
   377  // 		t.Errorf("falied to find target string in output")
   378  // 	}
   379  
   380  // }