// Copyright 2014 beego Author. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package beego import ( "bytes" "github.com/astaxie/beego/testdata" "github.com/elazarl/go-bindata-assetfs" "net/http" "os" "path/filepath" "testing" ) var header = `{{define "header"}}

Hello, astaxie!

{{end}}` var index = ` beego welcome template {{template "block"}} {{template "header"}} {{template "blocks/block.tpl"}} ` var block = `{{define "block"}}

Hello, blocks!

{{end}}` func TestTemplate(t *testing.T) { dir := "_beeTmp" files := []string{ "header.tpl", "index.tpl", "blocks/block.tpl", } if err := os.MkdirAll(dir, 0777); err != nil { t.Fatal(err) } for k, name := range files { os.MkdirAll(filepath.Dir(filepath.Join(dir, name)), 0777) if f, err := os.Create(filepath.Join(dir, name)); err != nil { t.Fatal(err) } else { if k == 0 { f.WriteString(header) } else if k == 1 { f.WriteString(index) } else if k == 2 { f.WriteString(block) } f.Close() } } if err := AddViewPath(dir); err != nil { t.Fatal(err) } beeTemplates := beeViewPathTemplates[dir] if len(beeTemplates) != 3 { t.Fatalf("should be 3 but got %v", len(beeTemplates)) } if err := beeTemplates["index.tpl"].ExecuteTemplate(os.Stdout, "index.tpl", nil); err != nil { t.Fatal(err) } for _, name := range files { os.RemoveAll(filepath.Join(dir, name)) } os.RemoveAll(dir) } var menu = ` ` var user = ` beego welcome template {{template "../public/menu.tpl"}} ` func TestRelativeTemplate(t *testing.T) { dir := "_beeTmp" //Just add dir to known viewPaths if err := AddViewPath(dir); err != nil { t.Fatal(err) } files := []string{ "easyui/public/menu.tpl", "easyui/rbac/user.tpl", } if err := os.MkdirAll(dir, 0777); err != nil { t.Fatal(err) } for k, name := range files { os.MkdirAll(filepath.Dir(filepath.Join(dir, name)), 0777) if f, err := os.Create(filepath.Join(dir, name)); err != nil { t.Fatal(err) } else { if k == 0 { f.WriteString(menu) } else if k == 1 { f.WriteString(user) } f.Close() } } if err := BuildTemplate(dir, files[1]); err != nil { t.Fatal(err) } beeTemplates := beeViewPathTemplates[dir] if err := beeTemplates["easyui/rbac/user.tpl"].ExecuteTemplate(os.Stdout, "easyui/rbac/user.tpl", nil); err != nil { t.Fatal(err) } for _, name := range files { os.RemoveAll(filepath.Join(dir, name)) } os.RemoveAll(dir) } var add = `{{ template "layout_blog.tpl" . }} {{ define "css" }} {{ end}} {{ define "content" }}

{{ .Title }}

This is SomeVar: {{ .SomeVar }}

{{ end }} {{ define "js" }} {{ end}}` var layoutBlog = ` Lin Li {{ block "css" . }}{{ end }}
{{ block "content" . }}{{ end }}
{{ block "js" . }}{{ end }} ` var output = ` Lin Li

Hello

This is SomeVar: val

` func TestTemplateLayout(t *testing.T) { dir := "_beeTmp" files := []string{ "add.tpl", "layout_blog.tpl", } if err := os.MkdirAll(dir, 0777); err != nil { t.Fatal(err) } for k, name := range files { os.MkdirAll(filepath.Dir(filepath.Join(dir, name)), 0777) if f, err := os.Create(filepath.Join(dir, name)); err != nil { t.Fatal(err) } else { if k == 0 { f.WriteString(add) } else if k == 1 { f.WriteString(layoutBlog) } f.Close() } } if err := AddViewPath(dir); err != nil { t.Fatal(err) } beeTemplates := beeViewPathTemplates[dir] if len(beeTemplates) != 2 { t.Fatalf("should be 2 but got %v", len(beeTemplates)) } out := bytes.NewBufferString("") if err := beeTemplates["add.tpl"].ExecuteTemplate(out, "add.tpl", map[string]string{"Title": "Hello", "SomeVar": "val"}); err != nil { t.Fatal(err) } if out.String() != output { t.Log(out.String()) t.Fatal("Compare failed") } for _, name := range files { os.RemoveAll(filepath.Join(dir, name)) } os.RemoveAll(dir) } type TestingFileSystem struct { assetfs *assetfs.AssetFS } func (d TestingFileSystem) Open(name string) (http.File, error) { return d.assetfs.Open(name) } func (d TestingFileSystem) Walk(root string, walkFn filepath.WalkFunc) error { f, err := d.Open(root) if err != nil { return err } info, err := f.Stat() if err != nil { err = walkFn(root, nil, err) } else { err = d.walk(root, info, walkFn) } if err == filepath.SkipDir { return nil } return err } // walk recursively descends path, calling walkFn. func (d TestingFileSystem) walk(path string, info os.FileInfo, walkFn filepath.WalkFunc) error { var err error if !info.IsDir() { return walkFn(path, info, nil) } dir, err := d.Open(path) defer dir.Close() dirs, err := dir.Readdir(-1) err1 := walkFn(path, info, err) // If err != nil, walk can't walk into this directory. // err1 != nil means walkFn want walk to skip this directory or stop walking. // Therefore, if one of err and err1 isn't nil, walk will return. if err != nil || err1 != nil { // The caller's behavior is controlled by the return value, which is decided // by walkFn. walkFn may ignore err and return nil. // If walkFn returns SkipDir, it will be handled by the caller. // So walk should return whatever walkFn returns. return err1 } for _, fileInfo := range dirs { filename := filepath.Join(path, fileInfo.Name()) err = d.walk(filename, fileInfo, walkFn) if err != nil { if !fileInfo.IsDir() || err != filepath.SkipDir { return err } } } return nil } var outputBinData = ` beego welcome template

Hello, blocks!

Hello, astaxie!

Hello

This is SomeVar: val

` func TestFsBinData(t *testing.T) { SetTemplateFSFunc(func() IFileSystem { return TestingFileSystem{&assetfs.AssetFS{Asset: testdata.Asset, AssetDir: testdata.AssetDir, AssetInfo: testdata.AssetInfo}} }) dir := "views" if err := AddViewPath("views"); err != nil { t.Fatal(err) } beeTemplates := beeViewPathTemplates[dir] if len(beeTemplates) != 3 { t.Fatalf("should be 3 but got %v", len(beeTemplates)) } if err := beeTemplates["index.tpl"].ExecuteTemplate(os.Stdout, "index.tpl", map[string]string{"Title": "Hello", "SomeVar": "val"}); err != nil { t.Fatal(err) } out := bytes.NewBufferString("") if err := beeTemplates["index.tpl"].ExecuteTemplate(out, "index.tpl", map[string]string{"Title": "Hello", "SomeVar": "val"}); err != nil { t.Fatal(err) } if out.String() != outputBinData { t.Log(out.String()) t.Fatal("Compare failed") } }