shiyanhui / hero

A handy, fast and powerful go template engine.
https://shiyanhui.github.io/hero
Other
1.57k stars 96 forks source link

one key multi type of structs #73

Closed iDevoid closed 5 years ago

iDevoid commented 5 years ago

Hi, I found something unusual/unique when I was creating the unit test for generated .html.go file. this generated file has been used around half a year, and no error reported since you may ask why unit test for generated file. but anyway

there's an Args which is map[string]interface{} there are 2 html files included here. <%~ "head.html" %> inside all.html

the generated file all.html.go, there are

info.Args["samekey"].(strcut1).ID // from head.html
info.Args["samekey"].(struct2).Date // from all.html

I was confused, because I cannot set both struct in the same key on unit test. so, I decided to change the other key inside the second html file, and generated (html.go) it again.

shiyanhui commented 5 years ago

I cannot set both struct in the same key on unit test.

Why can't you set both? Could you please show me your test code?

iDevoid commented 5 years ago

Here is the example: body.html.go

line 200: int64(info.Args["samekey"].(NewStrcut).ID)
line 1500: info.Args["samekey"].(CompletelyDifferentStruct).CreateDate.(string)

the test:

args: args{
    info: Args{
        Title:             "The Title",
        Args: map[string]interface{}{
            "samekey" : NewStruct {
                ID : 1,
            },
        },
    },
},

resulting:

panic: interface conversion: interface {} is nil, not template.CompletelyDifferentStruct [recovered]
... :1500 +0x353f
args: args{
    info: Args{
        Title:             "The Title",
        Args: map[string]interface{}{
            "samekey" : CompletelyDifferentStruct {
                CreateDate : "2019-09-09",
            },
        },
    },
},

resulting:

panic: interface conversion: interface {} is nil, not template.NewStruct [recovered]
... :200 +0x353f

The HTML: inside head.html

var something = new Object();
something.id ="<%==i info.Args["samekey"].(NewStruct).ID %>";

inside body.html

<%~ "head.html" %>
var newsomething = new Object();
newsomething.create_date ="<%==i info.Args["samekey"].(CompletelyDifferentStruct).CreateDate %>";

I solved this by changing the key inside body.html and regenerate this, so the unit test can easily be done new inside body.html

<%~ "head.html" %>
var newsomething = new Object();
newsomething.create_date ="<%==i info.Args["newkey"].(CompletelyDifferentStruct).CreateDate %>";
shiyanhui commented 5 years ago

I guess your test cases share the same variable args. And when test run, it got the wrong value. And it's dangerous asserting type of interface{} without boolean checking. You can do it like something as below,

<% if v, ok := info.Args["samekey"].(CompletelyDifferentStruct); ok { %>
    <%==i v.CreateDate %>
<% } %>
shiyanhui commented 5 years ago

Closed for no response.