Skip to content

Commit

Permalink
More modernization
Browse files Browse the repository at this point in the history
  • Loading branch information
danog committed Oct 17, 2024
1 parent 9816eb6 commit 667643a
Show file tree
Hide file tree
Showing 23 changed files with 103 additions and 61 deletions.
14 changes: 13 additions & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ issues:

# go generate introduces these
- path: expressions/scanner.go
linters: [deadcode, unused, varcheck]
linters: [deadcode, unused, varcheck, revive, stylecheck, gocritic, unconvert]
linters:
enable-all: true
disable:
Expand All @@ -30,4 +30,16 @@ linters:
- inamedparam
- lll
- paralleltest
- gocognit
- goconst
- cyclop
- dupword
- whitespace
- nolintlint
- nestif
- forcetypeassert

# Todo: re-add
- err113
- errorlint
fix: true
3 changes: 3 additions & 0 deletions engine_examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ func ExampleEngine_ParseAndRenderString() {
fmt.Println(out)
// Output: Hola Mundo
}

func ExampleEngine_ParseTemplate() {
engine := NewEngine()
source := `{{ hello | capitalize | append: " Mundo" }}`
Expand All @@ -50,6 +51,7 @@ func ExampleEngine_ParseTemplate() {
fmt.Println(out)
// Output: Hola Mundo
}

func ExampleEngine_RegisterFilter() {
engine := NewEngine()
engine.RegisterFilter("has_prefix", strings.HasPrefix)
Expand All @@ -64,6 +66,7 @@ func ExampleEngine_RegisterFilter() {
fmt.Println(out)
// Output: true
}

func ExampleEngine_RegisterFilter_optional_argument() {
engine := NewEngine()
// func(a, b int) int) would default the second argument to zero.
Expand Down
10 changes: 5 additions & 5 deletions engine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package liquid
import (
"bytes"
"encoding/json"
"fmt"
"io"
"strconv"
"strings"
"testing"

Expand Down Expand Up @@ -32,7 +32,7 @@ var testBindings = map[string]interface{}{
func TestEngine_ParseAndRenderString(t *testing.T) {
engine := NewEngine()
for i, test := range liquidTests {
t.Run(fmt.Sprint(i+1), func(t *testing.T) {
t.Run(strconv.Itoa(i+1), func(t *testing.T) {
out, err := engine.ParseAndRenderString(test.in, testBindings)
require.NoErrorf(t, err, test.in)
require.Equalf(t, test.expected, out, test.in)
Expand All @@ -51,7 +51,7 @@ func (c *capWriter) Write(bs []byte) (int, error) {
func TestEngine_ParseAndFRender(t *testing.T) {
engine := NewEngine()
for i, test := range liquidTests {
t.Run(fmt.Sprint(i+1), func(t *testing.T) {
t.Run(strconv.Itoa(i+1), func(t *testing.T) {
wr := capWriter{}
err := engine.ParseAndFRender(&wr, []byte(test.in), testBindings)
require.NoErrorf(t, err, test.in)
Expand Down Expand Up @@ -103,7 +103,7 @@ func TestEngine_ParseAndRender_errors(t *testing.T) {
func BenchmarkEngine_Parse(b *testing.B) {
engine := NewEngine()
buf := new(bytes.Buffer)
for i := 0; i < 1000; i++ {
for range 1000 {
_, err := io.WriteString(buf, `if{% if true %}true{% elsif %}elsif{% else %}else{% endif %}`)
require.NoError(b, err)
_, err = io.WriteString(buf, `loop{% for item in array %}loop{% break %}{% endfor %}`)
Expand All @@ -115,7 +115,7 @@ func BenchmarkEngine_Parse(b *testing.B) {
}
s := buf.Bytes()
b.ResetTimer()
for i := 0; i < b.N; i++ {
for range b.N {
_, err := engine.ParseTemplate(s)
require.NoError(b, err)
}
Expand Down
12 changes: 7 additions & 5 deletions expressions/filters.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ func (c *Config) AddFilter(name string, fn interface{}) {
rf := reflect.ValueOf(fn)
switch {
case rf.Kind() != reflect.Func:
panic(fmt.Errorf("a filter must be a function"))
panic("a filter must be a function")
case rf.Type().NumIn() < 1:
panic(fmt.Errorf("a filter function must have at least one input"))
panic("a filter function must have at least one input")
case rf.Type().NumOut() < 1 || 2 < rf.Type().NumOut():
panic(fmt.Errorf("a filter must be have one or two outputs"))
panic("a filter must be have one or two outputs")
// case rf.Type().Out(1).Implements(…):
// panic(typeError("a filter's second output must be type error"))
}
Expand All @@ -52,8 +52,10 @@ func (c *Config) AddFilter(name string, fn interface{}) {
c.filters[name] = fn
}

var closureType = reflect.TypeOf(closure{})
var interfaceType = reflect.TypeOf([]interface{}{}).Elem()
var (
closureType = reflect.TypeOf(closure{})
interfaceType = reflect.TypeOf([]interface{}{}).Elem()
)

func isClosureInterfaceType(t reflect.Type) bool {
return closureType.ConvertibleTo(t) && !interfaceType.ConvertibleTo(t)
Expand Down
1 change: 1 addition & 0 deletions expressions/functional_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ func TestConstant(t *testing.T) {
require.NoError(t, err)
require.Equal(t, 10, v)
}

func TestNot(t *testing.T) {
ctx := NewContext(map[string]interface{}{}, NewConfig())
k := Constant(10)
Expand Down
8 changes: 5 additions & 3 deletions expressions/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,11 @@ var _expression_eof_trans = []int16{
67, 67, 50,
}

const expression_start int = 23
const expression_first_final int = 23
const expression_error int = -1
const (
expression_start int = 23
expression_first_final int = 23
expression_error int = -1
)

const expression_en_main int = 23

Expand Down
8 changes: 4 additions & 4 deletions filters/standard_filters.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,11 @@ func AddStandardFilters(fd FilterDictionary) { //nolint: gocyclo
fd.AddFilter("remove_first", func(s, old string) string {
return strings.Replace(s, old, "", 1)
})
fd.AddFilter("replace", func(s, old, new string) string {
return strings.Replace(s, old, new, -1)
fd.AddFilter("replace", func(s, old, n string) string {
return strings.Replace(s, old, n, -1)
})
fd.AddFilter("replace_first", func(s, old, new string) string {
return strings.Replace(s, old, new, 1)
fd.AddFilter("replace_first", func(s, old, n string) string {
return strings.Replace(s, old, n, 1)
})
fd.AddFilter("sort_natural", sortNaturalFilter)
fd.AddFilter("slice", func(s string, start int, length func(int) int) string {
Expand Down
2 changes: 1 addition & 1 deletion parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func (c Config) parseTokens(tokens []Token) (ASTNode, Error) { //nolint: gocyclo
*ap = append(*ap, &ASTText{Token: tok})
case tok.Type == TagTokenType:
if g == nil {
return nil, Errorf(tok, "Grammer field is nil")
return nil, Errorf(tok, "Grammar field is nil")
}
if cs, ok := g.BlockSyntax(tok.Name); ok {
switch {
Expand Down
6 changes: 4 additions & 2 deletions parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ import (
"github.com/stretchr/testify/require"
)

type grammarFake struct{}
type blockSyntaxFake string
type (
grammarFake struct{}
blockSyntaxFake string
)

func (g grammarFake) BlockSyntax(w string) (BlockSyntax, bool) {
return blockSyntaxFake(w), true
Expand Down
1 change: 0 additions & 1 deletion parser/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (

// Scan breaks a string into a sequence of Tokens.
func Scan(data string, loc SourceLoc, delims []string) (tokens []Token) {

// Apply defaults
if len(delims) != 4 {
delims = []string{"{{", "}}", "{%", "%}"}
Expand Down
2 changes: 1 addition & 1 deletion render/compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func (c Config) Compile(source string, loc parser.SourceLoc) (Node, parser.Error
return c.compileNode(root)
}

//nolint: gocyclo
// nolint: gocyclo
func (c Config) compileNode(n parser.ASTNode) (Node, parser.Error) {
switch n := n.(type) {
case *parser.ASTBlock:
Expand Down
1 change: 0 additions & 1 deletion render/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ func (c rendererContext) Errorf(format string, a ...interface{}) Error {
default:
return renderErrorf(invalidLoc, format, a...)
}

}

func (c rendererContext) WrapError(err error) Error {
Expand Down
6 changes: 4 additions & 2 deletions render/context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,10 @@ var contextTests = []struct{ in, out string }{
{`{% 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"},
{
`{% test_render_file testdata/render_file.txt %}; unshadowed={{ shadowed }}`,
"rendered shadowed=2; unshadowed=1",
},
{`{% test_block_sourcefile %}x{% endtest_block_sourcefile %}`, ``},
}

Expand Down
2 changes: 1 addition & 1 deletion render/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ func writeObject(w io.Writer, value interface{}) error {
rt := reflect.ValueOf(value)
switch rt.Kind() {
case reflect.Array, reflect.Slice:
for i := 0; i < rt.Len(); i++ {
for i := range rt.Len() {
item := rt.Index(i)
if item.IsValid() {
if err := writeObject(w, item.Interface()); err != nil {
Expand Down
1 change: 1 addition & 0 deletions render/trimwriter.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ func (tw *trimWriter) Write(b []byte) (int, error) {
_, err := tw.w.Write(nonWS)
return n, err
}

func (tw *trimWriter) Flush() (err error) {
if tw.buf.Len() > 0 {
_, err = tw.buf.WriteTo(tw.w)
Expand Down
6 changes: 4 additions & 2 deletions tags/iteration_tags.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ type IterationKeyedMap map[string]interface{}

const forloopVarName = "forloop"

var errLoopContinueLoop = fmt.Errorf("continue outside a loop")
var errLoopBreak = fmt.Errorf("break outside a loop")
var (
errLoopContinueLoop = fmt.Errorf("continue outside a loop")
errLoopBreak = fmt.Errorf("break outside a loop")
)

type iterable interface {
Len() int
Expand Down
36 changes: 24 additions & 12 deletions tags/iteration_tags_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,10 @@ var iterationTests = []struct{ in, expected string }{
{`{% for a in array %}{{ forloop.rindex0 }}.{% endfor %}`, "2.1.0."},
{`{% for a in array %}{{ forloop.length }}.{% endfor %}`, "3.3.3."},

{`{% for i in array %}{{ forloop.index }}[{% for j in array %}{{ forloop.index }}{% endfor %}]{{ forloop.index }}{% endfor %}`,
"1[123]12[123]23[123]3"},
{
`{% for i in array %}{{ forloop.index }}[{% for j in array %}{{ forloop.index }}{% endfor %}]{{ forloop.index }}{% endfor %}`,
"1[123]12[123]23[123]3",
},

{`{% for a in array reversed %}{{ forloop.first }}.{% endfor %}`, "true.false.false."},
{`{% for a in array reversed %}{{ forloop.last }}.{% endfor %}`, "false.false.true."},
Expand Down Expand Up @@ -90,30 +92,40 @@ var iterationTests = []struct{ in, expected string }{
{`{% assign l = (3..5) %}{% for i in l %}{{i}}.{% endfor %}`, "3.4.5."},

// tablerow
{`{% tablerow product in products %}{{ product }}{% endtablerow %}`,
{
`{% tablerow product in products %}{{ product }}{% endtablerow %}`,
`<tr class="row1"><td class="col1">Cool Shirt</td>
<td class="col2">Alien Poster</td>
<td class="col3">Batman Poster</td>
<td class="col4">Bullseye Shirt</td>
<td class="col5">Another Classic Vinyl</td>
<td class="col6">Awesome Jeans</td></tr>`},
<td class="col6">Awesome Jeans</td></tr>`,
},

{`{% tablerow product in products cols:2 %}{{ product }}{% endtablerow %}`,
{
`{% tablerow product in products cols:2 %}{{ product }}{% endtablerow %}`,
`<tr class="row1"><td class="col1">Cool Shirt</td><td class="col2">Alien Poster</td></tr>
<tr class="row2"><td class="col1">Batman Poster</td><td class="col2">Bullseye Shirt</td></tr>
<tr class="row3"><td class="col1">Another Classic Vinyl</td><td class="col2">Awesome Jeans</td></tr>`},
{`{% tablerow product in products cols: cols %}{{ product }}{% endtablerow %}`,
<tr class="row3"><td class="col1">Another Classic Vinyl</td><td class="col2">Awesome Jeans</td></tr>`,
},
{
`{% tablerow product in products cols: cols %}{{ product }}{% endtablerow %}`,
`<tr class="row1"><td class="col1">Cool Shirt</td><td class="col2">Alien Poster</td></tr>
<tr class="row2"><td class="col1">Batman Poster</td><td class="col2">Bullseye Shirt</td></tr>
<tr class="row3"><td class="col1">Another Classic Vinyl</td><td class="col2">Awesome Jeans</td></tr>`},
{`{% tablerow product in products cols: loopmods.cols %}{{ product }}{% endtablerow %}`,
<tr class="row3"><td class="col1">Another Classic Vinyl</td><td class="col2">Awesome Jeans</td></tr>`,
},
{
`{% tablerow product in products cols: loopmods.cols %}{{ product }}{% endtablerow %}`,
`<tr class="row1"><td class="col1">Cool Shirt</td><td class="col2">Alien Poster</td></tr>
<tr class="row2"><td class="col1">Batman Poster</td><td class="col2">Bullseye Shirt</td></tr>
<tr class="row3"><td class="col1">Another Classic Vinyl</td><td class="col2">Awesome Jeans</td></tr>`},
{`{% tablerow product in products cols: loopmods.cols %}{{ product }}{% endtablerow %}`,
<tr class="row3"><td class="col1">Another Classic Vinyl</td><td class="col2">Awesome Jeans</td></tr>`,
},
{
`{% tablerow product in products cols: loopmods.cols %}{{ product }}{% endtablerow %}`,
`<tr class="row1"><td class="col1">Cool Shirt</td><td class="col2">Alien Poster</td></tr>
<tr class="row2"><td class="col1">Batman Poster</td><td class="col2">Bullseye Shirt</td></tr>
<tr class="row3"><td class="col1">Another Classic Vinyl</td><td class="col2">Awesome Jeans</td></tr>`},
<tr class="row3"><td class="col1">Another Classic Vinyl</td><td class="col2">Awesome Jeans</td></tr>`,
},
}

var iterationSyntaxErrorTests = []struct{ in, expected string }{
Expand Down
8 changes: 4 additions & 4 deletions template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func TestTemplate_Parse_race(t *testing.T) {
count = 10
wg sync.WaitGroup
)
for i := 0; i < count; i++ {
for i := range count {
wg.Add(1)
go func(i int) {
path := fmt.Sprintf("path %d", i)
Expand All @@ -77,7 +77,7 @@ func TestTemplate_Render_race(t *testing.T) {
ts = make([]*Template, count)
wg sync.WaitGroup
)
for i := 0; i < count; i++ {
for i := range count {
paths[i] = fmt.Sprintf("path %d", i)
wg.Add(1)
go func(i int) {
Expand All @@ -90,7 +90,7 @@ func TestTemplate_Render_race(t *testing.T) {
wg.Wait()

var wg2 sync.WaitGroup
for i := 0; i < count; i++ {
for i := range count {
wg2.Add(1)
go func(i int) {
defer wg2.Done()
Expand All @@ -110,7 +110,7 @@ func BenchmarkTemplate_Render(b *testing.B) {
b.Fatal(err)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
for range b.N {
_, err := tpl.Render(bindings)
require.NoError(b, err)
}
Expand Down
2 changes: 1 addition & 1 deletion values/compare.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func Equal(a, b interface{}) bool { //nolint: gocyclo
if ra.Len() != rb.Len() {
return false
}
for i := 0; i < ra.Len(); i++ {
for i := range ra.Len() {
if !Equal(ra.Index(i).Interface(), rb.Index(i).Interface()) {
return false
}
Expand Down
6 changes: 4 additions & 2 deletions values/compare_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ import (
"github.com/stretchr/testify/require"
)

var eqTestObj = struct{ a, b int }{1, 2}
var eqArrayTestObj = [2]int{1, 2}
var (
eqTestObj = struct{ a, b int }{1, 2}
eqArrayTestObj = [2]int{1, 2}
)

var eqTests = []struct {
a, b interface{}
Expand Down
5 changes: 2 additions & 3 deletions values/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ func conversionError(modifier string, value interface{}, typ reflect.Type) error
if modifier != "" {
modifier += " "
}
switch ref := value.(type) {
case reflect.Value:
if ref, ok := value.(reflect.Value); ok {
value = ref.Interface()
}
return typeErrorf("can't convert %s%T(%v) to type %s", modifier, value, value, typ)
Expand Down Expand Up @@ -208,7 +207,7 @@ func Convert(value interface{}, typ reflect.Type) (interface{}, error) { //nolin
switch rv.Kind() {
case reflect.Array, reflect.Slice:
result := reflect.MakeSlice(typ, 0, rv.Len())
for i := 0; i < rv.Len(); i++ {
for i := range rv.Len() {
item, err := Convert(rv.Index(i).Interface(), typ.Elem())
if err != nil {
return nil, err
Expand Down
Loading

0 comments on commit 667643a

Please sign in to comment.