drone-matrix/vendor/github.com/aymerick/raymond/handlebars/data_test.go
2018-01-08 09:54:13 +01:00

301 lines
8.0 KiB
Go

package handlebars
import (
"testing"
"github.com/aymerick/raymond"
)
//
// Those tests come from:
// https://github.com/wycats/handlebars.js/blob/master/spec/data.js
//
var dataTests = []Test{
{
"passing in data to a compiled function that expects data - works with helpers",
"{{hello}}",
map[string]string{"noun": "cat"},
map[string]interface{}{"adjective": "happy"},
map[string]interface{}{"hello": func(options *raymond.Options) string {
return options.DataStr("adjective") + " " + options.ValueStr("noun")
}},
nil,
"happy cat",
},
{
"data can be looked up via @foo",
"{{@hello}}",
nil,
map[string]interface{}{"hello": "hello"},
nil, nil,
"hello",
},
{
"deep @foo triggers automatic top-level data",
`{{#let world="world"}}{{#if foo}}{{#if foo}}Hello {{@world}}{{/if}}{{/if}}{{/let}}`,
map[string]bool{"foo": true},
map[string]interface{}{"hello": "hello"},
map[string]interface{}{"let": func(options *raymond.Options) string {
frame := options.NewDataFrame()
for k, v := range options.Hash() {
frame.Set(k, v)
}
return options.FnData(frame)
}},
nil,
"Hello world",
},
{
"parameter data can be looked up via @foo",
`{{hello @world}}`,
nil,
map[string]interface{}{"world": "world"},
map[string]interface{}{"hello": func(context string) string {
return "Hello " + context
}},
nil,
"Hello world",
},
{
"hash values can be looked up via @foo",
`{{hello noun=@world}}`,
nil,
map[string]interface{}{"world": "world"},
map[string]interface{}{"hello": func(options *raymond.Options) string {
return "Hello " + options.HashStr("noun")
}},
nil,
"Hello world",
},
{
"nested parameter data can be looked up via @foo.bar",
`{{hello @world.bar}}`,
nil,
map[string]interface{}{"world": map[string]string{"bar": "world"}},
map[string]interface{}{"hello": func(context string) string {
return "Hello " + context
}},
nil,
"Hello world",
},
{
"nested parameter data does not fail with @world.bar",
`{{hello @world.bar}}`,
nil,
map[string]interface{}{"foo": map[string]string{"bar": "world"}},
map[string]interface{}{"hello": func(context string) string {
return "Hello " + context
}},
nil,
// @todo Test differs with JS implementation: we don't output `undefined`
"Hello ",
},
// @todo "parameter data throws when using complex scope references",
{
"data can be functions",
`{{@hello}}`,
nil,
map[string]interface{}{"hello": func() string { return "hello" }},
nil, nil,
"hello",
},
{
"data can be functions with params",
`{{@hello "hello"}}`,
nil,
map[string]interface{}{"hello": func(context string) string { return context }},
nil, nil,
"hello",
},
{
"data is inherited downstream",
`{{#let foo=1 bar=2}}{{#let foo=bar.baz}}{{@bar}}{{@foo}}{{/let}}{{@foo}}{{/let}}`,
map[string]map[string]string{"bar": {"baz": "hello world"}},
nil,
map[string]interface{}{"let": func(options *raymond.Options) string {
frame := options.NewDataFrame()
for k, v := range options.Hash() {
frame.Set(k, v)
}
return options.FnData(frame)
}},
nil,
"2hello world1",
},
{
"passing in data to a compiled function that expects data - works with helpers in partials",
`{{>myPartial}}`,
map[string]string{"noun": "cat"},
map[string]interface{}{"adjective": "happy"},
map[string]interface{}{"hello": func(options *raymond.Options) string {
return options.DataStr("adjective") + " " + options.ValueStr("noun")
}},
map[string]string{
"myPartial": "{{hello}}",
},
"happy cat",
},
{
"passing in data to a compiled function that expects data - works with helpers and parameters",
`{{hello world}}`,
map[string]interface{}{"exclaim": true, "world": "world"},
map[string]interface{}{"adjective": "happy"},
map[string]interface{}{"hello": func(context string, options *raymond.Options) string {
str := "error"
if b, ok := options.Value("exclaim").(bool); ok {
if b {
str = "!"
} else {
str = ""
}
}
return options.DataStr("adjective") + " " + context + str
}},
nil,
"happy world!",
},
{
"passing in data to a compiled function that expects data - works with block helpers",
`{{#hello}}{{world}}{{/hello}}`,
map[string]bool{"exclaim": true},
map[string]interface{}{"adjective": "happy"},
map[string]interface{}{
"hello": func(options *raymond.Options) string {
return options.Fn()
},
"world": func(options *raymond.Options) string {
str := "error"
if b, ok := options.Value("exclaim").(bool); ok {
if b {
str = "!"
} else {
str = ""
}
}
return options.DataStr("adjective") + " world" + str
},
},
nil,
"happy world!",
},
{
"passing in data to a compiled function that expects data - works with block helpers that use ..",
`{{#hello}}{{world ../zomg}}{{/hello}}`,
map[string]interface{}{"exclaim": true, "zomg": "world"},
map[string]interface{}{"adjective": "happy"},
map[string]interface{}{
"hello": func(options *raymond.Options) string {
return options.FnWith(map[string]string{"exclaim": "?"})
},
"world": func(context string, options *raymond.Options) string {
return options.DataStr("adjective") + " " + context + options.ValueStr("exclaim")
},
},
nil,
"happy world?",
},
{
"passing in data to a compiled function that expects data - data is passed to with block helpers where children use ..",
`{{#hello}}{{world ../zomg}}{{/hello}}`,
map[string]interface{}{"exclaim": true, "zomg": "world"},
map[string]interface{}{"adjective": "happy", "accessData": "#win"},
map[string]interface{}{
"hello": func(options *raymond.Options) string {
return options.DataStr("accessData") + " " + options.FnWith(map[string]string{"exclaim": "?"})
},
"world": func(context string, options *raymond.Options) string {
return options.DataStr("adjective") + " " + context + options.ValueStr("exclaim")
},
},
nil,
"#win happy world?",
},
{
"you can override inherited data when invoking a helper",
`{{#hello}}{{world zomg}}{{/hello}}`,
map[string]interface{}{"exclaim": true, "zomg": "planet"},
map[string]interface{}{"adjective": "happy"},
map[string]interface{}{
"hello": func(options *raymond.Options) string {
ctx := map[string]string{"exclaim": "?", "zomg": "world"}
data := options.NewDataFrame()
data.Set("adjective", "sad")
return options.FnCtxData(ctx, data)
},
"world": func(context string, options *raymond.Options) string {
return options.DataStr("adjective") + " " + context + options.ValueStr("exclaim")
},
},
nil,
"sad world?",
},
{
"you can override inherited data when invoking a helper with depth",
`{{#hello}}{{world ../zomg}}{{/hello}}`,
map[string]interface{}{"exclaim": true, "zomg": "world"},
map[string]interface{}{"adjective": "happy"},
map[string]interface{}{
"hello": func(options *raymond.Options) string {
ctx := map[string]string{"exclaim": "?"}
data := options.NewDataFrame()
data.Set("adjective", "sad")
return options.FnCtxData(ctx, data)
},
"world": func(context string, options *raymond.Options) string {
return options.DataStr("adjective") + " " + context + options.ValueStr("exclaim")
},
},
nil,
"sad world?",
},
{
"@root - the root context can be looked up via @root",
`{{@root.foo}}`,
map[string]interface{}{"foo": "hello"},
nil, nil, nil,
"hello",
},
{
"@root - passed root values take priority",
`{{@root.foo}}`,
nil,
map[string]interface{}{"root": map[string]string{"foo": "hello"}},
nil, nil,
"hello",
},
{
"nesting - the root context can be looked up via @root",
`{{#helper}}{{#helper}}{{@./depth}} {{@../depth}} {{@../../depth}}{{/helper}}{{/helper}}`,
map[string]interface{}{"foo": "hello"},
map[string]interface{}{"depth": 0},
map[string]interface{}{
"helper": func(options *raymond.Options) string {
data := options.NewDataFrame()
if depth, ok := options.Data("depth").(int); ok {
data.Set("depth", depth+1)
}
return options.FnData(data)
},
},
nil,
"2 1 0",
},
}
func TestData(t *testing.T) {
launchTests(t, dataTests)
}