mirror of
https://github.com/retailcrm/mg-transport-core.git
synced 2025-01-31 05:41:41 +03:00
avoid panic if template was added twice
This commit is contained in:
parent
21031e285d
commit
17b69ea3a3
@ -11,23 +11,29 @@ import (
|
|||||||
type Renderer struct {
|
type Renderer struct {
|
||||||
multitemplate.Renderer
|
multitemplate.Renderer
|
||||||
TemplatesBox *packr.Box
|
TemplatesBox *packr.Box
|
||||||
FuncMap template.FuncMap
|
FuncMap template.FuncMap
|
||||||
|
alreadyAdded map[string]*template.Template
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRenderer is a Renderer constructor
|
// NewRenderer is a Renderer constructor
|
||||||
func NewRenderer(funcMap template.FuncMap) Renderer {
|
func NewRenderer(funcMap template.FuncMap) Renderer {
|
||||||
return Renderer{
|
return Renderer{
|
||||||
Renderer: multitemplate.NewRenderer(),
|
Renderer: multitemplate.NewRenderer(),
|
||||||
FuncMap: funcMap,
|
FuncMap: funcMap,
|
||||||
|
alreadyAdded: map[string]*template.Template{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push is an AddFromFilesFuncs wrapper
|
// Push is an AddFromFilesFuncs wrapper
|
||||||
func (r *Renderer) Push(name string, files ...string) *template.Template {
|
func (r *Renderer) Push(name string, files ...string) *template.Template {
|
||||||
|
if tpl := r.getTemplate(name); tpl != nil {
|
||||||
|
return tpl
|
||||||
|
}
|
||||||
|
|
||||||
if r.TemplatesBox == nil {
|
if r.TemplatesBox == nil {
|
||||||
return r.AddFromFilesFuncs(name, r.FuncMap, files...)
|
return r.storeTemplate(name, r.AddFromFilesFuncs(name, r.FuncMap, files...))
|
||||||
} else {
|
} else {
|
||||||
return r.addFromBox(name, r.FuncMap, files...)
|
return r.storeTemplate(name, r.addFromBox(name, r.FuncMap, files...))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,4 +48,32 @@ func (r *Renderer) addFromBox(name string, funcMap template.FuncMap, files ...st
|
|||||||
}
|
}
|
||||||
|
|
||||||
return r.AddFromStringsFuncs(name, funcMap, filesData...)
|
return r.AddFromStringsFuncs(name, funcMap, filesData...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// storeTemplate stores built template if multitemplate.DynamicRender is used.
|
||||||
|
// Dynamic render doesn't store templates - it stores builders, that's why we can't just extract them.
|
||||||
|
// It possibly can cause data inconsistency in developer enviroments where return value from Renderer.Push is used.
|
||||||
|
func (r *Renderer) storeTemplate(name string, tpl *template.Template) *template.Template {
|
||||||
|
if _, ok := r.Renderer.(multitemplate.DynamicRender); ok {
|
||||||
|
r.alreadyAdded[name] = tpl
|
||||||
|
}
|
||||||
|
|
||||||
|
return tpl
|
||||||
|
}
|
||||||
|
|
||||||
|
// getTemplate returns template from render or from storage
|
||||||
|
func (r *Renderer) getTemplate(name string) *template.Template {
|
||||||
|
if renderer, ok := r.Renderer.(multitemplate.Render); ok {
|
||||||
|
if i, ok := renderer[name]; ok {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := r.Renderer.(multitemplate.DynamicRender); ok {
|
||||||
|
if i, ok := r.alreadyAdded[name]; ok {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -24,6 +24,11 @@ type TemplateTest struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *TemplateTest) SetupSuite() {
|
func (t *TemplateTest) SetupSuite() {
|
||||||
|
t.initTestData()
|
||||||
|
t.renderer = t.initRenderer()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *TemplateTest) initTestData() {
|
||||||
if _, err := os.Stat(testTemplatesDir); err != nil && os.IsNotExist(err) {
|
if _, err := os.Stat(testTemplatesDir); err != nil && os.IsNotExist(err) {
|
||||||
err := os.Mkdir(testTemplatesDir, os.ModePerm)
|
err := os.Mkdir(testTemplatesDir, os.ModePerm)
|
||||||
require.Nil(t.T(), err)
|
require.Nil(t.T(), err)
|
||||||
@ -34,8 +39,10 @@ func (t *TemplateTest) SetupSuite() {
|
|||||||
require.Nil(t.T(), err1)
|
require.Nil(t.T(), err1)
|
||||||
require.Nil(t.T(), err2)
|
require.Nil(t.T(), err2)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
t.renderer = NewRenderer(template.FuncMap{
|
func (t *TemplateTest) initRenderer() Renderer {
|
||||||
|
return NewRenderer(template.FuncMap{
|
||||||
"trans": func(data string) string {
|
"trans": func(data string) string {
|
||||||
if data == "test" {
|
if data == "test" {
|
||||||
return "ok"
|
return "ok"
|
||||||
@ -51,6 +58,25 @@ func (t *TemplateTest) Test_Push() {
|
|||||||
assert.Equal(t.T(), 3, len(tpl.Templates()))
|
assert.Equal(t.T(), 3, len(tpl.Templates()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *TemplateTest) Test_PushAlreadyExists() {
|
||||||
|
defer func() {
|
||||||
|
assert.Nil(t.T(), recover())
|
||||||
|
}()
|
||||||
|
|
||||||
|
tpl := t.renderer.Push("index", fmt.Sprintf(testTemplatesFile, 1), fmt.Sprintf(testTemplatesFile, 2))
|
||||||
|
assert.Equal(t.T(), 3, len(tpl.Templates()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *TemplateTest) Test_PushNewInstance() {
|
||||||
|
defer func() {
|
||||||
|
assert.Nil(t.T(), recover())
|
||||||
|
}()
|
||||||
|
|
||||||
|
newInstance := t.initRenderer()
|
||||||
|
tpl := newInstance.Push("index", fmt.Sprintf(testTemplatesFile, 1), fmt.Sprintf(testTemplatesFile, 2))
|
||||||
|
assert.Equal(t.T(), 3, len(tpl.Templates()))
|
||||||
|
}
|
||||||
|
|
||||||
func TestTemplate_Suite(t *testing.T) {
|
func TestTemplate_Suite(t *testing.T) {
|
||||||
suite.Run(t, new(TemplateTest))
|
suite.Run(t, new(TemplateTest))
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user