Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: consistent whitespace around go keywords #371

Merged
merged 2 commits into from
Jan 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.2.543
0.2.544
39 changes: 21 additions & 18 deletions generator/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ func (g *generator) writeTemplate(nodeIdx int, t parser.HTMLTemplate) error {
return err
}
// Nodes.
if err = g.writeNodes(indentLevel, stripWhitespace(t.Children)); err != nil {
if err = g.writeNodes(indentLevel, stripWhitespace(t.Children), nil); err != nil {
return err
}
// Return the buffer.
Expand Down Expand Up @@ -479,13 +479,16 @@ func stripLeadingAndTrailingWhitespace(nodes []parser.Node) []parser.Node {
return stripTrailingWhitespace(stripLeadingWhitespace(nodes))
}

func (g *generator) writeNodes(indentLevel int, nodes []parser.Node) error {
func (g *generator) writeNodes(indentLevel int, nodes []parser.Node, next parser.Node) error {
for i, curr := range nodes {
var next parser.Node
var nextNode parser.Node
if i+1 < len(nodes) {
next = nodes[i+1]
nextNode = nodes[i+1]
}
if err := g.writeNode(indentLevel, curr, next); err != nil {
if nextNode == nil {
nextNode = next
}
if err := g.writeNode(indentLevel, curr, nextNode); err != nil {
return err
}
}
Expand All @@ -505,15 +508,15 @@ func (g *generator) writeNode(indentLevel int, current parser.Node, next parser.
case parser.RawElement:
err = g.writeRawElement(indentLevel, n)
case parser.ForExpression:
err = g.writeForExpression(indentLevel, n)
err = g.writeForExpression(indentLevel, n, next)
case parser.CallTemplateExpression:
err = g.writeCallTemplateExpression(indentLevel, n)
case parser.TemplElementExpression:
err = g.writeTemplElementExpression(indentLevel, n)
case parser.IfExpression:
err = g.writeIfExpression(indentLevel, n)
err = g.writeIfExpression(indentLevel, n, next)
case parser.SwitchExpression:
err = g.writeSwitchExpression(indentLevel, n)
err = g.writeSwitchExpression(indentLevel, n, next)
case parser.StringExpression:
err = g.writeStringExpression(indentLevel, n.Expression)
case parser.Whitespace:
Expand Down Expand Up @@ -583,7 +586,7 @@ func (g *generator) writeDocType(indentLevel int, n parser.DocType) (err error)
return nil
}

func (g *generator) writeIfExpression(indentLevel int, n parser.IfExpression) (err error) {
func (g *generator) writeIfExpression(indentLevel int, n parser.IfExpression, nextNode parser.Node) (err error) {
var r parser.Range
// if
if _, err = g.w.WriteIndent(indentLevel, `if `); err != nil {
Expand All @@ -600,7 +603,7 @@ func (g *generator) writeIfExpression(indentLevel int, n parser.IfExpression) (e
}
{
indentLevel++
if err = g.writeNodes(indentLevel, stripLeadingAndTrailingWhitespace(n.Then)); err != nil {
if err = g.writeNodes(indentLevel, stripLeadingAndTrailingWhitespace(n.Then), nextNode); err != nil {
return err
}
indentLevel--
Expand All @@ -621,7 +624,7 @@ func (g *generator) writeIfExpression(indentLevel int, n parser.IfExpression) (e
}
{
indentLevel++
if err = g.writeNodes(indentLevel, stripLeadingAndTrailingWhitespace(elseIf.Then)); err != nil {
if err = g.writeNodes(indentLevel, stripLeadingAndTrailingWhitespace(elseIf.Then), nextNode); err != nil {
return err
}
indentLevel--
Expand All @@ -634,7 +637,7 @@ func (g *generator) writeIfExpression(indentLevel int, n parser.IfExpression) (e
}
{
indentLevel++
if err = g.writeNodes(indentLevel, stripLeadingAndTrailingWhitespace(n.Else)); err != nil {
if err = g.writeNodes(indentLevel, stripLeadingAndTrailingWhitespace(n.Else), nextNode); err != nil {
return err
}
indentLevel--
Expand All @@ -647,7 +650,7 @@ func (g *generator) writeIfExpression(indentLevel int, n parser.IfExpression) (e
return nil
}

func (g *generator) writeSwitchExpression(indentLevel int, n parser.SwitchExpression) (err error) {
func (g *generator) writeSwitchExpression(indentLevel int, n parser.SwitchExpression, next parser.Node) (err error) {
var r parser.Range
// switch
if _, err = g.w.WriteIndent(indentLevel, `switch `); err != nil {
Expand All @@ -672,7 +675,7 @@ func (g *generator) writeSwitchExpression(indentLevel int, n parser.SwitchExpres
}
g.sourceMap.Add(c.Expression, r)
indentLevel++
if err = g.writeNodes(indentLevel, stripLeadingAndTrailingWhitespace(c.Children)); err != nil {
if err = g.writeNodes(indentLevel, stripLeadingAndTrailingWhitespace(c.Children), next); err != nil {
return err
}
indentLevel--
Expand Down Expand Up @@ -712,7 +715,7 @@ func (g *generator) writeBlockTemplElementExpression(indentLevel int, n parser.T
if err := g.writeTemplBuffer(indentLevel); err != nil {
return err
}
if err = g.writeNodes(indentLevel, stripLeadingAndTrailingWhitespace(n.Children)); err != nil {
if err = g.writeNodes(indentLevel, stripLeadingAndTrailingWhitespace(n.Children), nil); err != nil {
return err
}
// Return the buffer.
Expand Down Expand Up @@ -795,7 +798,7 @@ func (g *generator) writeCallTemplateExpression(indentLevel int, n parser.CallTe
return nil
}

func (g *generator) writeForExpression(indentLevel int, n parser.ForExpression) (err error) {
func (g *generator) writeForExpression(indentLevel int, n parser.ForExpression, next parser.Node) (err error) {
var r parser.Range
// for
if _, err = g.w.WriteIndent(indentLevel, `for `); err != nil {
Expand All @@ -812,7 +815,7 @@ func (g *generator) writeForExpression(indentLevel int, n parser.ForExpression)
}
// Children.
indentLevel++
if err = g.writeNodes(indentLevel, stripLeadingAndTrailingWhitespace(n.Children)); err != nil {
if err = g.writeNodes(indentLevel, stripLeadingAndTrailingWhitespace(n.Children), next); err != nil {
return err
}
indentLevel--
Expand Down Expand Up @@ -909,7 +912,7 @@ func (g *generator) writeStandardElement(indentLevel int, n parser.Element) (err
}
}
// Children.
if err = g.writeNodes(indentLevel, stripWhitespace(n.Children)); err != nil {
if err = g.writeNodes(indentLevel, stripWhitespace(n.Children), nil); err != nil {
return err
}
// </div>
Expand Down
78 changes: 78 additions & 0 deletions generator/test-whitespace-around-go-keywords/render_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package testwhitespacearoundgokeywords

import (
"context"
"strings"
"testing"

"github.com/a-h/templ"
"github.com/google/go-cmp/cmp"
)

func TestTextWhitespace(t *testing.T) {
for _, test := range []struct {
name string
input templ.Component
expected string
}{
{
name: "whitespace is consistent in a true evaluated if statement",
input: WhitespaceIsConsistentInIf(true, false),
expected: WhitespaceIsConsistentInTrueIfExpected,
},
{
name: "whitespace is consistent in a true evaluated else if statement",
input: WhitespaceIsConsistentInIf(false, true),
expected: WhitespaceIsConsistentInTrueElseIfExpected,
},
{
name: "whitespace is consistent in a true evaluated else statement",
input: WhitespaceIsConsistentInIf(false, false),
expected: WhitespaceIsConsistentInTrueElseExpected,
},
{
name: "whitespace is consistent in a false evaluated if statement",
input: WhitespaceIsConsistentInFalseIf(),
expected: WhitespaceIsConsistentInFalseIfExpected,
},
{
name: "whitespace is consistent in a switch statment with a true case",
input: WhitespaceIsConsistentInSwitch(1),
expected: WhitespaceIsConsistentInOneSwitchExpected,
},
{
name: "whitespace is consistent in a switch statment with a default case",
input: WhitespaceIsConsistentInSwitch(2),
expected: WhitespaceIsConsistentInDefaultSwitchExpected,
},
{
name: "whitespace is consistent in a switch statment with no default case and no true cases",
input: WhitespaceIsConsistentInSwitchNoDefault(),
expected: WhitespaceIsConsistentInSwitchNoDefaultExpected,
},
{
name: "whitespace is consistent in a for statment that runs 0 times",
input: WhitespaceIsConsistentInFor(0),
expected: WhitespaceIsConsistentInForZeroExpected,
},
{
name: "whitespace is consistent in a for statment that runs 1 times",
input: WhitespaceIsConsistentInFor(1),
expected: WhitespaceIsConsistentInForOneExpected,
},
{
name: "whitespace is consistent in a for statment that runs 3 times",
input: WhitespaceIsConsistentInFor(3),
expected: WhitespaceIsConsistentInForThreeExpected,
},
} {
w := new(strings.Builder)
err := test.input.Render(context.Background(), w)
if err != nil {
t.Errorf("failed to render: %v", err)
}
if diff := cmp.Diff(test.expected, w.String()); diff != "" {
t.Error(diff)
}
}
}
66 changes: 66 additions & 0 deletions generator/test-whitespace-around-go-keywords/template.templ
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package testwhitespacearoundgokeywords

import "fmt"

templ WhitespaceIsConsistentInIf(firstIf, secondIf bool) {
<button>Start</button>
if firstIf {
<button>If</button>
} else if secondIf {
<button>ElseIf</button>
} else {
<button>Else</button>
}
<button>End</button>
}

const WhitespaceIsConsistentInTrueIfExpected = `<button>Start</button> <button>If</button> <button>End</button>`
const WhitespaceIsConsistentInTrueElseIfExpected = `<button>Start</button> <button>ElseIf</button> <button>End</button>`
const WhitespaceIsConsistentInTrueElseExpected = `<button>Start</button> <button>Else</button> <button>End</button>`

templ WhitespaceIsConsistentInFalseIf() {
<button>Start</button>
if false {
<button>Will Not Render</button>
}
<button>End</button>
}

const WhitespaceIsConsistentInFalseIfExpected = `<button>Start</button> <button>End</button>`

templ WhitespaceIsConsistentInSwitch(i int) {
<button>Start</button>
switch i {
case 1:
<button>1</button>
default:
<button>default</button>
}
<button>End</button>
}

const WhitespaceIsConsistentInOneSwitchExpected = `<button>Start</button> <button>1</button> <button>End</button>`
const WhitespaceIsConsistentInDefaultSwitchExpected = `<button>Start</button> <button>default</button> <button>End</button>`

templ WhitespaceIsConsistentInSwitchNoDefault() {
<button>Start</button>
switch false {
case true:
<button>Will Not Render</button>
}
<button>End</button>
}

const WhitespaceIsConsistentInSwitchNoDefaultExpected = `<button>Start</button> <button>End</button>`

templ WhitespaceIsConsistentInFor(i int) {
<button>Start</button>
for j := 0; j < i; j++ {
<button>{ fmt.Sprint(j) }</button>
}
<button>End</button>
}

const WhitespaceIsConsistentInForZeroExpected = `<button>Start</button> <button>End</button>`
const WhitespaceIsConsistentInForOneExpected = `<button>Start</button> <button>0</button> <button>End</button>`
const WhitespaceIsConsistentInForThreeExpected = `<button>Start</button> <button>0</button> <button>1</button> <button>2</button> <button>End</button>`
Loading
Loading