1
0
mirror of https://github.com/danog/liquid.git synced 2024-11-26 19:24:45 +01:00
liquid/render/context_test.go
2023-05-26 23:36:28 +02:00

127 lines
3.8 KiB
Go

package render
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"os"
"testing"
"github.com/danog/liquid/parser"
"github.com/stretchr/testify/require"
)
func addContextTestTags(s Config) {
s.AddTag("test_evaluate_string", func(string) (func(io.Writer, Context) error, error) {
return func(w io.Writer, c Context) error {
v, err := c.EvaluateString(c.TagArgs())
if err != nil {
return err
}
_, err = fmt.Fprint(w, v)
return err
}, nil
})
s.AddBlock("parse").Compiler(func(c BlockNode) (func(io.Writer, Context) error, error) {
a := c.Args
return func(w io.Writer, c Context) error {
_, err := io.WriteString(w, a)
return err
}, nil
})
s.AddTag("test_tag_name", func(string) (func(io.Writer, Context) error, error) {
return func(w io.Writer, c Context) error {
_, err := io.WriteString(w, c.TagName())
return err
}, nil
})
s.AddTag("test_expand_tag_arg", func(string) (func(w io.Writer, c Context) error, error) {
return func(w io.Writer, c Context) error {
s, err := c.ExpandTagArg()
if err != nil {
return err
}
_, err = io.WriteString(w, s)
return err
}, nil
})
s.AddTag("test_render_file", func(filename string) (func(w io.Writer, c Context) error, error) {
return func(w io.Writer, c Context) error {
s, err := c.RenderFile(filename, map[string]interface{}{"shadowed": 2})
if err != nil {
return err
}
_, err = io.WriteString(w, s)
return err
}, nil
})
}
var contextTests = []struct{ in, out string }{
{`{% parse args %}{% endparse %}`, "args"},
{`{% test_evaluate_string x %}`, "123"},
{`{% test_expand_tag_arg x %}`, "x"},
{`{% test_expand_tag_arg {{x}} %}`, "123"},
{`{% test_tag_name %}`, "test_tag_name"},
{`{% test_render_file testdata/render_file.txt %}; unshadowed={{ shadowed }}`,
"rendered shadowed=2; unshadowed=1"},
}
var contextErrorTests = []struct{ in, expect string }{
{`{% test_evaluate_string syntax error %}`, "syntax error"},
{`{% test_expand_tag_arg {{ syntax error }} %}`, "syntax error"},
{`{% test_expand_tag_arg {{ x | undefined_filter }} %}`, "undefined filter"},
{`{% test_render_file testdata/render_file_syntax_error.txt %}`, "syntax error"},
{`{% test_render_file testdata/render_file_runtime_error.txt %}`, "undefined tag"},
}
var contextTestBindings = map[string]interface{}{
"x": 123,
"shadowed": 1,
}
func TestContext(t *testing.T) {
cfg := NewConfig()
addContextTestTags(cfg)
for i, test := range contextTests {
t.Run(fmt.Sprintf("%02d", i+1), func(t *testing.T) {
root, err := cfg.Compile(test.in, parser.SourceLoc{})
require.NoErrorf(t, err, test.in)
buf := new(bytes.Buffer)
err = Render(root, buf, contextTestBindings, cfg)
require.NoErrorf(t, err, test.in)
require.Equalf(t, test.out, buf.String(), test.in)
})
}
}
func TestContext_errors(t *testing.T) {
cfg := NewConfig()
addContextTestTags(cfg)
for i, test := range contextErrorTests {
t.Run(fmt.Sprintf("%02d", i+1), func(t *testing.T) {
root, err := cfg.Compile(test.in, parser.SourceLoc{})
require.NoErrorf(t, err, test.in)
err = Render(root, ioutil.Discard, contextTestBindings, cfg)
require.Errorf(t, err, test.in)
require.Containsf(t, err.Error(), test.expect, test.in)
})
}
}
func TestContext_file_not_found_error(t *testing.T) {
// Test the cause instead of looking for a string, since the error message is
// different between Darwin and Linux ("no such file") and Windows ("The
// system cannot find the file specified"), at least.
//
// Also see TestIncludeTag_file_not_found_error.
cfg := NewConfig()
addContextTestTags(cfg)
root, err := cfg.Compile(`{% test_render_file testdata/missing_file %}`, parser.SourceLoc{})
require.NoError(t, err)
err = Render(root, ioutil.Discard, contextTestBindings, cfg)
require.Error(t, err)
require.True(t, os.IsNotExist(err.Cause()))
}