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