Skip to content

Commit

Permalink
Support for else if and if (#13)
Browse files Browse the repository at this point in the history
Closes #11

Also enable CI on all branch pushes
  • Loading branch information
gamebox authored Jan 6, 2024
1 parent aa3e38a commit b065ac2
Show file tree
Hide file tree
Showing 8 changed files with 203 additions and 31 deletions.
4 changes: 1 addition & 3 deletions .github/workflows/master.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
name: CI
on:
push:
branches: master
on: [push]
jobs:
build:
name: Build, lint, and test with Go version ${{ matrix.go }} and ${{ matrix.os }}
Expand Down
10 changes: 9 additions & 1 deletion gwirl-example/templates/testAll.html.gwirl
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,13 @@
@if index > 0 {
<hr />
}
<h2>@name</h2>
@if name == "Jeff" {
<h2>JEFF</h2>
} @else if name == "Sue" {
<h2>SuE</h2> {
} @else if name == "Bob" {
<h2>B.O.B.</h2>
} @else {
<h2>@name</h2>
}
</div>
106 changes: 83 additions & 23 deletions internal/gen/generator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,89 @@ import (
//go:embed testdata/simple_gwirl.go
var simple string

func TestGenerator(t *testing.T) {
template := parser.NewTemplate2(
parser.NewPosString("Testing"),
nil,
parser.NewPosString("(name string, index int)"),
[]parser.PosString{},
[]parser.TemplateTree2{
parser.NewTT2Plain("<div>\n\t"),
parser.NewTT2If("if index > 0", []parser.TemplateTree2{
parser.NewTT2Plain("\n\t\t<hr />\n\t"),
}, nil, nil),
parser.NewTT2Plain("\n\t<h2>"),
parser.NewTT2GoExp("name", true, nil),
parser.NewTT2Plain("</h2>\n"),
},
)
//go:embed testdata/testAll_gwirl.go
var testAll string

func ptr(t parser.TemplateTree2) *parser.TemplateTree2 {
return &t
}

gen := NewGenerator(false)
writer := strings.Builder{}
gen.Generate(template, "views", &writer)
if writer.String() != simple {
edits := myers.ComputeEdits(span.URI("testdata/simple_gwirl.go"), simple, writer.String())
diff := gotextdiff.ToUnified("expected", "received", simple, edits)
t.Fatalf("Generated template did not match golden:\n%s", diff)
var tests = []struct {
filename string
template parser.Template2
expected string
}{
{
"testdata/simple_gwirl.go",
parser.NewTemplate2(
parser.NewPosString("Testing"),
nil,
parser.NewPosString("(name string, index int)"),
[]parser.PosString{},
[]parser.TemplateTree2{
parser.NewTT2Plain("<div>\n\t"),
parser.NewTT2If("if index > 0", []parser.TemplateTree2{
parser.NewTT2Plain("\n\t\t<hr />\n\t"),
}, nil, nil),
parser.NewTT2Plain("\n\t<h2>"),
parser.NewTT2GoExp("name", true, nil),
parser.NewTT2Plain("</h2>\n"),
},
),
simple,
},
{
"testdata/testAll_gwirl.go",
parser.NewTemplate2(
parser.NewPosString("TestAll"),
ptr(parser.NewTT2BlockComment("*****************\n* Test Component *\n*****************")),
parser.NewPosString("(name string, index int)"),
[]parser.PosString{},
[]parser.TemplateTree2{
parser.NewTT2Plain("<div "),
parser.NewTT2If(" index == 0 ", []parser.TemplateTree2{
parser.NewTT2Plain(` class="first" `),
}, []parser.TemplateTree2{}, nil),
parser.NewTT2Plain(">\n "),
parser.NewTT2If(" index > 0 ", []parser.TemplateTree2{
parser.NewTT2Plain("\n <hr />\n "),
}, []parser.TemplateTree2{}, nil),
parser.NewTT2Plain("\n "),
parser.NewTT2If(` name == "Jeff" `, []parser.TemplateTree2{
parser.NewTT2Plain("\n <h2>JEFF</h2>\n "),
}, []parser.TemplateTree2{
parser.NewTT2ElseIf(` name == "Sue" `, []parser.TemplateTree2{
parser.NewTT2Plain("\n <h2>SuE</h2>\n "),
}),
parser.NewTT2ElseIf(` name == "Bob" `, []parser.TemplateTree2{
parser.NewTT2Plain("\n <h2>B.O.B.</h2>\n "),
}),
}, ptr(parser.NewTT2Else([]parser.TemplateTree2{
parser.NewTT2Plain("\n <h2>"),
parser.NewTT2GoExp("name", false, []parser.TemplateTree2{}),
parser.NewTT2Plain("</h2>\n "),
}))),
parser.NewTT2Plain("\n</div>\n"),
},
),
testAll,
},
}

func TestGenerator(t *testing.T) {
for _, test := range tests {
res := t.Run(test.filename, func(t *testing.T) {
gen := NewGenerator(false)
writer := strings.Builder{}
gen.Generate(test.template, "views", &writer)
if writer.String() != test.expected {
edits := myers.ComputeEdits(span.URI("testdata/simple_gwirl.go"), test.expected, writer.String())
diff := gotextdiff.ToUnified("expected", "received", test.expected, edits)
t.Fatalf("Generated template did not match golden:\n%s", diff)
}
})
if !res {
t.Fail()
}
}
}
62 changes: 62 additions & 0 deletions internal/gen/testdata/testAll_gwirl.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package views

import (
"github.com/gamebox/gwirl"
)


func TestAll(name string, index int) string {
sb_ := gwirl.TemplateBuilder{}

sb_.WriteString(`<div `)

if index == 0 {
sb_.WriteString(` class="first" `)

}

sb_.WriteString(`>
`)

if index > 0 {
sb_.WriteString(`
<hr />
`)

}

sb_.WriteString(`
`)

if name == "Jeff" {
sb_.WriteString(`
<h2>JEFF</h2>
`)

} else if name == "Sue" {
sb_.WriteString(`
<h2>SuE</h2>
`)

} else if name == "Bob" {
sb_.WriteString(`
<h2>B.O.B.</h2>
`)

} else {
sb_.WriteString(`
<h2>`)

sb_.WriteString(name)

sb_.WriteString(`</h2>
`)

}

sb_.WriteString(`
</div>
`)

return sb_.String()
}
8 changes: 8 additions & 0 deletions internal/parser/nodesv2.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,14 @@ func NewTT2If(condition string, content []TemplateTree2, elseIfTree []TemplateTr
}
}

func NewTT2ElseIf(condition string, content []TemplateTree2) TemplateTree2 {
return TemplateTree2{
Type: TT2ElseIf,
Text: condition,
Children: [][]TemplateTree2{content},
}
}

func NewTT2Else(content []TemplateTree2) TemplateTree2 {
return TemplateTree2{
Type: TT2Else,
Expand Down
2 changes: 2 additions & 0 deletions internal/parser/parser2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,6 @@ func TestParseTestAll2(t *testing.T) {
if len(result.Errors) > 0 {
t.Errorf("Expected no errors, found %d errors", len(result.Errors))
}
// TODO: Test content parsing better - maybe through parser/pretty print roundtrip?
t.Logf("%v", result.Template.Content)
}
30 changes: 28 additions & 2 deletions internal/parser/parserv2.go
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,32 @@ func (p *Parser2) forExpression() *TemplateTree2 {
return result
}

func (p *Parser2) elseIfs() []TemplateTree2 {
trees := []TemplateTree2{}
for {
pos := p.input.offset()
p.whitespaceNoBreak()
if p.checkStr("@else if") {
condition := p.ifOrForDeclaration()
if condition == "" {
p.error("No condition found for else if", p.input.offset())
break
}
blk := p.expressionPart(true)
if blk == nil {
p.error("Empty block for else if", p.input.offset())
break
}
tree := NewTT2ElseIf(condition, *blk)
trees = append(trees, tree)
} else {
p.input.regressTo(pos)
break
}
}
return trees
}

func (p *Parser2) ifExpression() *TemplateTree2 {
var result *TemplateTree2 = nil
pos := p.input.offset()
Expand All @@ -459,7 +485,7 @@ func (p *Parser2) ifExpression() *TemplateTree2 {
p.logf("Got blk %v", blk)
if blk != nil {
// TODO: Get elseIfs

elseIfTrees = p.elseIfs()
elseTree = p.elseCall()

ifTree := NewTT2If(condition, *blk, elseIfTrees, elseTree)
Expand All @@ -479,7 +505,7 @@ func (p *Parser2) ifExpression() *TemplateTree2 {
func (p *Parser2) elseCall() *TemplateTree2 {
reset := p.input.offset()
p.whitespaceNoBreak()
if p.checkStr("else") {
if p.checkStr("@else") {
p.whitespaceNoBreak()
blk := p.expressionPart(true)
if blk != nil {
Expand Down
12 changes: 10 additions & 2 deletions internal/parser/testdata/testAll.html.gwirl
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,17 @@
*****************@
@(name string, index int)

<div>
<div @if index == 0 { class="first" }>
@if index > 0 {
<hr />
}
<h2>@!name</h2>
@if name == "Jeff" {
<h2>JEFF</h2>
} @else if name == "Sue" {
<h2>SuE</h2> {
} @else if name == "Bob" {
<h2>B.O.B.</h2>
} @else {
<h2>@name</h2>
}
</div>

0 comments on commit b065ac2

Please sign in to comment.