196 lines
5.0 KiB
Go
196 lines
5.0 KiB
Go
package parser
|
|
|
|
import (
|
|
"reflect"
|
|
"testing"
|
|
)
|
|
|
|
func TestTemplateFileParser(t *testing.T) {
|
|
t.Run("requests migration of legacy formats", func(t *testing.T) {
|
|
input := `{% package templates %}
|
|
`
|
|
_, err := ParseString(input)
|
|
if err == nil {
|
|
t.Error("expected ErrLegacyFileFormat, got nil")
|
|
}
|
|
if err != ErrLegacyFileFormat {
|
|
t.Errorf("expected ErrLegacyFileFormat, got %v", err)
|
|
}
|
|
})
|
|
t.Run("but can accept a package expression, if one is provided", func(t *testing.T) {
|
|
input := `package goof
|
|
|
|
templ Hello() {
|
|
Hello
|
|
}`
|
|
tf, err := ParseString(input)
|
|
if err != nil {
|
|
t.Fatalf("failed to parse template, with t.Fatalf(parser %v", err)
|
|
}
|
|
if len(tf.Nodes) != 1 {
|
|
t.Errorf("expected 2 nodes, got %+v", tf.Nodes)
|
|
}
|
|
if tf.Package.Expression.Value != "package goof" {
|
|
t.Errorf("expected \"goof\", got %q", tf.Package.Expression.Value)
|
|
}
|
|
})
|
|
t.Run("can start with comments", func(t *testing.T) {
|
|
input := `// Example comment.
|
|
package goof
|
|
|
|
templ Hello() {
|
|
Hello
|
|
}`
|
|
tf, err := ParseString(input)
|
|
if err != nil {
|
|
t.Fatalf("failed to parse template, with t.Fatalf(parser %v", err)
|
|
}
|
|
if len(tf.Nodes) != 1 {
|
|
t.Errorf("expected 2 node, got %d nodes with content %+v", len(tf.Nodes), tf.Nodes)
|
|
}
|
|
})
|
|
t.Run("template files can end with Go expressions", func(t *testing.T) {
|
|
input := `package goof
|
|
|
|
const x = "123"
|
|
|
|
templ Hello() {
|
|
Hello
|
|
}
|
|
|
|
const y = "456"
|
|
`
|
|
tf, err := ParseString(input)
|
|
if err != nil {
|
|
t.Fatalf("failed to parse template, with t.Fatalf(parser %v", err)
|
|
}
|
|
if len(tf.Nodes) != 3 {
|
|
var nodeTypes []string
|
|
for _, n := range tf.Nodes {
|
|
nodeTypes = append(nodeTypes, reflect.TypeOf(n).Name())
|
|
}
|
|
t.Fatalf("expected 3 nodes, got %d nodes, %v", len(tf.Nodes), nodeTypes)
|
|
}
|
|
expr, isGoExpression := tf.Nodes[0].(TemplateFileGoExpression)
|
|
if !isGoExpression {
|
|
t.Errorf("0: expected expression, got %t", tf.Nodes[2])
|
|
}
|
|
if expr.Expression.Value != `const x = "123"` {
|
|
t.Errorf("0: unexpected expression: %q", expr.Expression.Value)
|
|
}
|
|
expr, isGoExpression = tf.Nodes[2].(TemplateFileGoExpression)
|
|
if !isGoExpression {
|
|
t.Errorf("2: expected expression, got %t", tf.Nodes[2])
|
|
}
|
|
if expr.Expression.Value != `const y = "456"` {
|
|
t.Errorf("2: unexpected expression: %q", expr.Expression.Value)
|
|
}
|
|
})
|
|
t.Run("template files can end with string literals", func(t *testing.T) {
|
|
input := `package goof
|
|
|
|
const x = "123"
|
|
|
|
templ Hello() {
|
|
Hello
|
|
}
|
|
|
|
const y = ` + "`456`"
|
|
tf, err := ParseString(input)
|
|
if err != nil {
|
|
t.Fatalf("failed to parse template, with t.Fatalf(parser %v", err)
|
|
}
|
|
if len(tf.Nodes) != 3 {
|
|
var nodeTypes []string
|
|
for _, n := range tf.Nodes {
|
|
nodeTypes = append(nodeTypes, reflect.TypeOf(n).Name())
|
|
}
|
|
t.Fatalf("expected 3 nodes, got %d nodes, %v", len(tf.Nodes), nodeTypes)
|
|
}
|
|
expr, isGoExpression := tf.Nodes[0].(TemplateFileGoExpression)
|
|
if !isGoExpression {
|
|
t.Errorf("0: expected expression, got %t", tf.Nodes[2])
|
|
}
|
|
if expr.Expression.Value != `const x = "123"` {
|
|
t.Errorf("0: unexpected expression: %q", expr.Expression.Value)
|
|
}
|
|
expr, isGoExpression = tf.Nodes[2].(TemplateFileGoExpression)
|
|
if !isGoExpression {
|
|
t.Errorf("2: expected expression, got %t", tf.Nodes[2])
|
|
}
|
|
if expr.Expression.Value != "const y = `456`" {
|
|
t.Errorf("2: unexpected expression: %q", expr.Expression.Value)
|
|
}
|
|
})
|
|
// https://github.com/a-h/templ/issues/505
|
|
t.Run("template files can contain go expressions followed by multiline templates", func(t *testing.T) {
|
|
input := `package goof
|
|
|
|
var a = "a"
|
|
|
|
templ template(
|
|
a string,
|
|
) {
|
|
}`
|
|
tf, err := ParseString(input)
|
|
if err != nil {
|
|
t.Fatalf("failed to parse template, with t.Fatalf(parser %v", err)
|
|
}
|
|
if len(tf.Nodes) != 2 {
|
|
var nodeTypes []string
|
|
for _, n := range tf.Nodes {
|
|
nodeTypes = append(nodeTypes, reflect.TypeOf(n).Name())
|
|
}
|
|
t.Fatalf("expected 2 nodes, got %d nodes, %v\n%#v", len(tf.Nodes), nodeTypes, tf)
|
|
}
|
|
expr, isGoExpression := tf.Nodes[0].(TemplateFileGoExpression)
|
|
if !isGoExpression {
|
|
t.Errorf("0: expected expression, got %t", tf.Nodes[2])
|
|
}
|
|
if expr.Expression.Value != `var a = "a"` {
|
|
t.Errorf("0: unexpected expression: %q", expr.Expression.Value)
|
|
}
|
|
_, isGoExpression = tf.Nodes[1].(HTMLTemplate)
|
|
if !isGoExpression {
|
|
t.Errorf("2: expected expression, got %t", tf.Nodes[2])
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestDefaultPackageName(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
input string
|
|
expected string
|
|
}{
|
|
{
|
|
name: "standard filename",
|
|
input: "/files/on/disk/header.templ",
|
|
expected: "disk",
|
|
},
|
|
{
|
|
name: "path that starts with numbers",
|
|
input: "/files/on/123disk/header.templ",
|
|
expected: "main",
|
|
},
|
|
{
|
|
name: "path that includes hyphens",
|
|
input: "/files/on/disk-drive/header.templ",
|
|
expected: "main",
|
|
},
|
|
{
|
|
name: "relative path",
|
|
input: "header.templ",
|
|
expected: "main",
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
actual := getDefaultPackageName(tt.input)
|
|
if actual != tt.expected {
|
|
t.Errorf("expected %q got %q", tt.expected, actual)
|
|
}
|
|
})
|
|
}
|
|
}
|