zk/adapter/handlebars/handlebars_test.go
Mickaël Menu 08cc4a3c3f
Filter notes by tags (#6)
Filter notes by their tags using `--tag "history, europe"`. To match notes associated with either tags, use a pipe `|` or `OR` (all caps), e.g. `--tag "inbox OR todo"`.
2021-03-07 17:00:09 +01:00

186 lines
4.8 KiB
Go

package handlebars
import (
"fmt"
"testing"
"time"
"github.com/mickael-menu/zk/core/style"
"github.com/mickael-menu/zk/util"
"github.com/mickael-menu/zk/util/fixtures"
"github.com/mickael-menu/zk/util/test/assert"
)
func init() {
Init("en", true, &util.NullLogger, &styler{})
}
// styler is a test double for core.Styler
// "hello", "red" -> "red(hello)"
type styler struct{}
func (s *styler) Style(text string, rules ...style.Rule) (string, error) {
return s.MustStyle(text, rules...), nil
}
func (s *styler) MustStyle(text string, rules ...style.Rule) string {
for _, rule := range rules {
text = fmt.Sprintf("%s(%s)", rule, text)
}
return text
}
func testString(t *testing.T, template string, context interface{}, expected string) {
sut := NewLoader()
templ, err := sut.Load(template)
assert.Nil(t, err)
actual, err := templ.Render(context)
assert.Nil(t, err)
assert.Equal(t, actual, expected)
}
func testFile(t *testing.T, name string, context interface{}, expected string) {
sut := NewLoader()
templ, err := sut.LoadFile(fixtures.Path(name))
assert.Nil(t, err)
actual, err := templ.Render(context)
assert.Nil(t, err)
assert.Equal(t, actual, expected)
}
func TestRenderString(t *testing.T) {
testString(t,
"Goodbye, {{name}}",
map[string]string{"name": "Ed"},
"Goodbye, Ed",
)
}
func TestRenderFile(t *testing.T) {
testFile(t,
"template.txt",
map[string]string{"name": "Thom"},
"Hello, Thom\n",
)
}
func TestUnknownVariable(t *testing.T) {
testString(t,
"Hi, {{unknown}}!",
nil,
"Hi, !",
)
}
func TestDoesntEscapeHTML(t *testing.T) {
testString(t,
"Salut, {{name}}!",
map[string]string{"name": "l'ami"},
"Salut, l'ami!",
)
testFile(t,
"unescape.txt",
map[string]string{"name": "l'ami"},
"Salut, l'ami!\n",
)
}
func TestConcatHelper(t *testing.T) {
testString(t, "{{concat '> ' 'A quote'}}", nil, "> A quote")
}
func TestJoinHelper(t *testing.T) {
test := func(items []string, expected string) {
context := map[string]interface{}{"items": items}
testString(t, "{{join items '-'}}", context, expected)
}
test([]string{}, "")
test([]string{"Item 1"}, "Item 1")
test([]string{"Item 1", "Item 2"}, "Item 1-Item 2")
test([]string{"Item 1", "Item 2", "Item 3"}, "Item 1-Item 2-Item 3")
}
func TestPrependHelper(t *testing.T) {
// inline
testString(t, "{{prepend '> ' 'A quote'}}", nil, "> A quote")
// block
testString(t, "{{#prepend '> '}}A quote{{/prepend}}", nil, "> A quote")
testString(t, "{{#prepend '> '}}A quote on\nseveral lines{{/prepend}}", nil, "> A quote on\n> several lines")
}
func TestListHelper(t *testing.T) {
test := func(items []string, expected string) {
context := map[string]interface{}{"items": items}
testString(t, "{{list items}}", context, expected)
}
test([]string{}, "")
test([]string{"Item 1"}, " ‣ Item 1\n")
test([]string{"Item 1", "Item 2"}, " ‣ Item 1\n ‣ Item 2\n")
test([]string{"Item 1", "Item 2", "Item 3"}, " ‣ Item 1\n ‣ Item 2\n ‣ Item 3\n")
test([]string{"An item\non several\nlines\n"}, " ‣ An item\n on several\n lines\n")
}
func TestSlugHelper(t *testing.T) {
// inline
testString(t,
`{{slug "This will be slugified!"}}`,
nil,
"this-will-be-slugified",
)
// block
testString(t,
"{{#slug}}This will be slugified!{{/slug}}",
nil,
"this-will-be-slugified",
)
}
func TestDateHelper(t *testing.T) {
context := map[string]interface{}{"now": time.Date(2009, 11, 17, 20, 34, 58, 651387237, time.UTC)}
testString(t, "{{date now}}", context, "2009-11-17")
testString(t, "{{date now 'short'}}", context, "11/17/2009")
testString(t, "{{date now 'medium'}}", context, "Nov 17, 2009")
testString(t, "{{date now 'long'}}", context, "November 17, 2009")
testString(t, "{{date now 'full'}}", context, "Tuesday, November 17, 2009")
testString(t, "{{date now 'year'}}", context, "2009")
testString(t, "{{date now 'time'}}", context, "20:34")
testString(t, "{{date now 'timestamp'}}", context, "200911172034")
testString(t, "{{date now 'timestamp-unix'}}", context, "1258490098")
testString(t, "{{date now 'cust: %Y-%m'}}", context, "cust: 2009-11")
testString(t, "{{date now 'elapsed'}}", context, "12 years ago")
}
func TestShellHelper(t *testing.T) {
// block is passed as piped input
testString(t,
`{{#sh "tr '[a-z]' '[A-Z]'"}}Hello, world!{{/sh}}`,
nil,
"HELLO, WORLD!",
)
// inline
testString(t,
`{{sh "echo 'Hello, world!'"}}`,
nil,
"Hello, world!",
)
// using pipes
testString(t, `{{sh "echo hello | tr '[:lower:]' '[:upper:]'"}}`, nil, "HELLO")
}
func TestStyleHelper(t *testing.T) {
// inline
testString(t, "{{style 'single' 'Some text'}}", nil, "single(Some text)")
testString(t, "{{style 'red bold' 'Another text'}}", nil, "bold(red(Another text))")
// block
testString(t, "{{#style 'single'}}A multiline\ntext{{/style}}", nil, "single(A multiline\ntext)")
}