From 8daf547899beedae6354f27aceb4e7ae30afe16c Mon Sep 17 00:00:00 2001 From: joshs Date: Fri, 16 Dec 2016 13:02:33 -0500 Subject: [PATCH] making filters context aware --- core/condition_test.go | 2 +- core/dynamicvalue.go | 9 ++++---- core/filter.go | 4 +++- core/parser.go | 9 +++++--- core/parser_test.go | 3 ++- filters/append.go | 4 +++- filters/append_test.go | 6 ++--- filters/capitalize.go | 3 ++- filters/capitalize_test.go | 6 ++--- filters/date.go | 3 ++- filters/date_test.go | 6 ++--- filters/debug.go | 3 ++- filters/default.go | 3 ++- filters/default_test.go | 6 ++--- filters/divideby.go | 4 +++- filters/divideby_test.go | 24 ++++++++++---------- filters/downcase.go | 3 ++- filters/downcase_test.go | 6 ++--- filters/escape.go | 3 ++- filters/escape_test.go | 2 +- filters/escapeonce.go | 3 ++- filters/escapeonce_test.go | 4 ++-- filters/first.go | 3 ++- filters/first_test.go | 12 +++++----- filters/join.go | 3 ++- filters/join_test.go | 10 ++++----- filters/last.go | 3 ++- filters/last_test.go | 12 +++++----- filters/minus.go | 4 +++- filters/minus_test.go | 18 +++++++-------- filters/modulo.go | 3 ++- filters/modulo_test.go | 10 ++++----- filters/newlinetobr.go | 3 ++- filters/newlinetobr_test.go | 2 +- filters/plus.go | 3 ++- filters/plus_test.go | 20 ++++++++--------- filters/prepend.go | 4 +++- filters/prepend_test.go | 6 ++--- filters/remove.go | 4 +++- filters/remove_test.go | 2 +- filters/removefirst.go | 4 +++- filters/removefirst_test.go | 2 +- filters/replace.go | 3 ++- filters/replace_test.go | 4 ++-- filters/replacefirst.go | 4 +++- filters/replacefirst_test.go | 2 +- filters/reverse.go | 3 ++- filters/reverse_test.go | 14 ++++++------ filters/size.go | 4 +++- filters/size_test.go | 12 +++++----- filters/sort.go | 3 ++- filters/sort_test.go | 12 +++++----- filters/split.go | 3 ++- filters/split_test.go | 6 ++--- filters/striphtml.go | 3 ++- filters/striphtml_test.go | 2 +- filters/stripnewlines.go | 3 ++- filters/stripnewlines_test.go | 2 +- filters/times.go | 3 ++- filters/times_test.go | 26 +++++++++++----------- filters/truncate.go | 4 +++- filters/truncate_test.go | 16 ++++++------- filters/truncatewords.go | 4 +++- filters/truncatewords_test.go | 10 ++++----- filters/upcase.go | 3 ++- filters/upcase_test.go | 6 ++--- output_test.go | 26 +++++++++++----------- readme.md | 4 ++-- tags/comment_test.go | 2 +- template.go | 19 ++++++++-------- template_test.go | 42 +++++++++++++++++------------------ 71 files changed, 269 insertions(+), 220 deletions(-) diff --git a/core/condition_test.go b/core/condition_test.go index 43877af..058d3e2 100644 --- a/core/condition_test.go +++ b/core/condition_test.go @@ -197,7 +197,7 @@ func floatValue(f float64) Value { } func dynamicValue(s string) Value { - return NewDynamicValue([]string{s}) + return NewDynamicValue(nil, []string{s}) } func emptyValue() Value { diff --git a/core/dynamicvalue.go b/core/dynamicvalue.go index 71c298d..6391b0c 100644 --- a/core/dynamicvalue.go +++ b/core/dynamicvalue.go @@ -1,6 +1,7 @@ package core import ( + "context" "reflect" "strings" ) @@ -10,10 +11,10 @@ type DynamicValue struct { index Value } -func NewDynamicValue(fields []string) *DynamicValue { +func NewDynamicValue(ctx context.Context, fields []string) *DynamicValue { value := &DynamicValue{fields, nil} last := len(fields) - 1 - if index, field, ok := unindexDynamicField(fields[last]); ok { + if index, field, ok := unindexDynamicField(ctx, fields[last]); ok { fields[last] = field value.index = index } @@ -62,7 +63,7 @@ func (v *DynamicValue) Underlying() interface{} { return nil } -func unindexDynamicField(field string) (Value, string, bool) { +func unindexDynamicField(ctx context.Context, field string) (Value, string, bool) { end := len(field) - 1 if field[end] != ']' { return nil, field, false @@ -77,7 +78,7 @@ func unindexDynamicField(field string) (Value, string, bool) { if start == 0 { return nil, field, false } - value, err := NewParser([]byte(field[start+1:end] + " ")).ReadValue() + value, err := NewParser(ctx, []byte(field[start+1:end]+" ")).ReadValue() if err != nil { return nil, field, false } diff --git a/core/filter.go b/core/filter.go index 4470b6f..865f596 100644 --- a/core/filter.go +++ b/core/filter.go @@ -1,10 +1,12 @@ package core +import "context" + // An interface function type Filter func(input interface{}, data map[string]interface{}) interface{} // A filter factory creates a filter based on the supplied parameters -type FilterFactory func(parameters []Value) Filter +type FilterFactory func(ctx context.Context, parameters []Value) Filter // A map of filter names to filter factories var FilterLookup = make(map[string]FilterFactory) diff --git a/core/parser.go b/core/parser.go index b165ef7..c9cc45e 100644 --- a/core/parser.go +++ b/core/parser.go @@ -1,6 +1,7 @@ package core import ( + "context" "errors" "fmt" "strconv" @@ -21,6 +22,7 @@ const ( ) type Parser struct { + ctx context.Context Position int Data []byte Len int @@ -28,8 +30,9 @@ type Parser struct { Line int } -func NewParser(data []byte) *Parser { +func NewParser(ctx context.Context, data []byte) *Parser { parser := &Parser{ + ctx: ctx, Position: 0, Data: data, Len: len(data), @@ -257,7 +260,7 @@ func (p *Parser) ReadDynamicValues() (Value, error) { break } } - return NewDynamicValue(TrimStrings(values)), nil + return NewDynamicValue(p.ctx, TrimStrings(values)), nil } func (p *Parser) ReadName() string { @@ -315,7 +318,7 @@ func (p *Parser) ReadFilters() ([]Filter, error) { return nil, err } } - filters = append(filters, factory(parameters)) + filters = append(filters, factory(p.ctx, parameters)) if p.SkipSpaces() == '|' { p.Forward() continue diff --git a/core/parser_test.go b/core/parser_test.go index 0172faa..cc99f7e 100644 --- a/core/parser_test.go +++ b/core/parser_test.go @@ -1,6 +1,7 @@ package core import ( + "context" "testing" "github.com/karlseguin/gspec" @@ -310,7 +311,7 @@ func TestParserReadsMultiplePartials(t *testing.T) { } func newParser(s string) *Parser { - return NewParser([]byte(s)) + return NewParser(context.Background(), []byte(s)) } func assertParsedConditionGroup(t *testing.T, group Verifiable, data ...interface{}) { diff --git a/filters/append.go b/filters/append.go index e18617c..d354d4d 100644 --- a/filters/append.go +++ b/filters/append.go @@ -1,11 +1,13 @@ package filters import ( + "context" + "github.com/acstech/liquid/core" ) // Creates an append filter -func AppendFactory(parameters []core.Value) core.Filter { +func AppendFactory(ctx context.Context, parameters []core.Value) core.Filter { if len(parameters) == 0 { return Noop } diff --git a/filters/append_test.go b/filters/append_test.go index 789f2c0..89989e9 100644 --- a/filters/append_test.go +++ b/filters/append_test.go @@ -9,19 +9,19 @@ import ( func TestAppendToAString(t *testing.T) { spec := gspec.New(t) - filter := AppendFactory([]core.Value{stringValue("?!")}) + filter := AppendFactory(nil, []core.Value{stringValue("?!")}) spec.Expect(filter("dbz", nil).(string)).ToEqual("dbz?!") } func TestAppendToBytes(t *testing.T) { spec := gspec.New(t) - filter := AppendFactory([]core.Value{stringValue("boring")}) + filter := AppendFactory(nil, []core.Value{stringValue("boring")}) spec.Expect(filter([]byte("so"), nil).(string)).ToEqual("soboring") } func TestAppendADynamicValue(t *testing.T) { spec := gspec.New(t) - filter := AppendFactory([]core.Value{dynamicValue("local.currency")}) + filter := AppendFactory(nil, []core.Value{dynamicValue("local.currency")}) data := map[string]interface{}{ "local": map[string]string{ "currency": "$", diff --git a/filters/capitalize.go b/filters/capitalize.go index 16f19c7..173837f 100644 --- a/filters/capitalize.go +++ b/filters/capitalize.go @@ -2,12 +2,13 @@ package filters import ( "bytes" + "context" "github.com/acstech/liquid/core" ) // Creates a capitalize filter -func CapitalizeFactory(parameters []core.Value) core.Filter { +func CapitalizeFactory(ctx context.Context, parameters []core.Value) core.Filter { return Capitalize } diff --git a/filters/capitalize_test.go b/filters/capitalize_test.go index 5c8842b..b8ab325 100644 --- a/filters/capitalize_test.go +++ b/filters/capitalize_test.go @@ -8,18 +8,18 @@ import ( func TestCapitalizesAString(t *testing.T) { spec := gspec.New(t) - filter := CapitalizeFactory(nil) + filter := CapitalizeFactory(nil, nil) spec.Expect(string(filter("tiger got to hunt, bird got to fly", nil).([]byte))).ToEqual("Tiger Got To Hunt, Bird Got To Fly") } func TestCapitalizesBytes(t *testing.T) { spec := gspec.New(t) - filter := CapitalizeFactory(nil) + filter := CapitalizeFactory(nil, nil) spec.Expect(string(filter([]byte("Science is magic that works "), nil).([]byte))).ToEqual("Science Is Magic That Works ") } func TestCapitalizePassThroughOnInvalidType(t *testing.T) { spec := gspec.New(t) - filter := CapitalizeFactory(nil) + filter := CapitalizeFactory(nil, nil) spec.Expect(filter(123, nil).(int)).ToEqual(123) } diff --git a/filters/date.go b/filters/date.go index b8b6e48..d924d0d 100644 --- a/filters/date.go +++ b/filters/date.go @@ -1,6 +1,7 @@ package filters import ( + "context" "time" "github.com/acstech/go-strftime" @@ -12,7 +13,7 @@ var ( ) // Creates an date filter -func DateFactory(parameters []core.Value) core.Filter { +func DateFactory(ctx context.Context, parameters []core.Value) core.Filter { if len(parameters) == 0 { return Noop } diff --git a/filters/date_test.go b/filters/date_test.go index 2f10779..1a90ecc 100644 --- a/filters/date_test.go +++ b/filters/date_test.go @@ -17,18 +17,18 @@ func init() { func TestDateNowWithBasicFormat(t *testing.T) { spec := gspec.New(t) - filter := DateFactory([]core.Value{stringValue("%Y %m %d")}) + filter := DateFactory(nil, []core.Value{stringValue("%Y %m %d")}) spec.Expect(filter("now", nil).(string)).ToEqual("2006 01 02") } func TestDateTodayWithBasicFormat(t *testing.T) { spec := gspec.New(t) - filter := DateFactory([]core.Value{stringValue("%H:%M:%S%%")}) + filter := DateFactory(nil, []core.Value{stringValue("%H:%M:%S%%")}) spec.Expect(filter("today", nil).(string)).ToEqual("15:04:05%") } func TestDateWithSillyFormat(t *testing.T) { spec := gspec.New(t) - filter := DateFactory([]core.Value{stringValue("%w %U %j")}) + filter := DateFactory(nil, []core.Value{stringValue("%w %U %j")}) spec.Expect(filter("2014-01-10 21:31:28 +0800", nil).(string)).ToEqual("5 02 10") } diff --git a/filters/debug.go b/filters/debug.go index 3eef162..e007191 100644 --- a/filters/debug.go +++ b/filters/debug.go @@ -1,12 +1,13 @@ package filters import ( + "context" "strings" "github.com/acstech/liquid/core" ) -func DebugFactory(parameter []core.Value) core.Filter { +func DebugFactory(ctx context.Context, parameter []core.Value) core.Filter { debug := &DebugFilter{parameter} return debug.Debug } diff --git a/filters/default.go b/filters/default.go index 7946da2..181f4fa 100644 --- a/filters/default.go +++ b/filters/default.go @@ -1,6 +1,7 @@ package filters import ( + "context" "reflect" "github.com/acstech/liquid/core" @@ -9,7 +10,7 @@ import ( var defaultDefaultFilter = (&DefaultFilter{EmptyValue}).Default // Creates a default filter -func DefaultFactory(parameters []core.Value) core.Filter { +func DefaultFactory(ctx context.Context, parameters []core.Value) core.Filter { if len(parameters) == 0 { return defaultDefaultFilter } diff --git a/filters/default_test.go b/filters/default_test.go index cc5b2bd..9003b73 100644 --- a/filters/default_test.go +++ b/filters/default_test.go @@ -9,18 +9,18 @@ import ( func TestDefaultWithBuiltinValue(t *testing.T) { spec := gspec.New(t) - filter := DefaultFactory(nil) + filter := DefaultFactory(nil, nil) spec.Expect(filter(nil, nil).(string)).ToEqual("") } func TestDefaultWithValueOnString(t *testing.T) { spec := gspec.New(t) - filter := DefaultFactory([]core.Value{stringValue("d")}) + filter := DefaultFactory(nil, []core.Value{stringValue("d")}) spec.Expect(filter("", nil).(string)).ToEqual("d") } func TestDefaultWithValueOnArray(t *testing.T) { spec := gspec.New(t) - filter := DefaultFactory([]core.Value{stringValue("n/a")}) + filter := DefaultFactory(nil, []core.Value{stringValue("n/a")}) spec.Expect(filter([]int{}, nil).(string)).ToEqual("n/a") } diff --git a/filters/divideby.go b/filters/divideby.go index c163aac..8e7caeb 100644 --- a/filters/divideby.go +++ b/filters/divideby.go @@ -1,10 +1,12 @@ package filters import ( + "context" + "github.com/acstech/liquid/core" ) -func DivideByFactory(parameters []core.Value) core.Filter { +func DivideByFactory(ctx context.Context, parameters []core.Value) core.Filter { if len(parameters) == 0 { return Noop } diff --git a/filters/divideby_test.go b/filters/divideby_test.go index 8a85c1b..3d28b3b 100644 --- a/filters/divideby_test.go +++ b/filters/divideby_test.go @@ -9,72 +9,72 @@ import ( func TestDivideByAnIntToAnInt(t *testing.T) { spec := gspec.New(t) - filter := DivideByFactory([]core.Value{intValue(5)}) + filter := DivideByFactory(nil, []core.Value{intValue(5)}) spec.Expect(filter(43, nil).(float64)).ToEqual(8.6) } func TestDivideByAnIntToAFloat(t *testing.T) { spec := gspec.New(t) - filter := DivideByFactory([]core.Value{intValue(2)}) + filter := DivideByFactory(nil, []core.Value{intValue(2)}) spec.Expect(filter(43.3, nil).(float64)).ToEqual(21.65) } func TestDivideByAnIntToAStringAsAnInt(t *testing.T) { spec := gspec.New(t) - filter := DivideByFactory([]core.Value{intValue(7)}) + filter := DivideByFactory(nil, []core.Value{intValue(7)}) spec.Expect(filter("33", nil).(float64)).ToEqual(4.714285714285714) } func TestDivideByAnIntToBytesAsAnInt(t *testing.T) { spec := gspec.New(t) - filter := DivideByFactory([]core.Value{intValue(7)}) + filter := DivideByFactory(nil, []core.Value{intValue(7)}) spec.Expect(filter([]byte("34"), nil).(float64)).ToEqual(4.857142857142857) } func TestDivideByAnIntToAStringAsAString(t *testing.T) { spec := gspec.New(t) - filter := DivideByFactory([]core.Value{intValue(7)}) + filter := DivideByFactory(nil, []core.Value{intValue(7)}) spec.Expect(filter("abc", nil).(string)).ToEqual("abc") } func TestDivideByAnIntToBytesAsAString(t *testing.T) { spec := gspec.New(t) - filter := DivideByFactory([]core.Value{intValue(8)}) + filter := DivideByFactory(nil, []core.Value{intValue(8)}) spec.Expect(filter([]byte("abb"), nil).(string)).ToEqual("abb") } func TestDivideByAFloatToAnInt(t *testing.T) { spec := gspec.New(t) - filter := DivideByFactory([]core.Value{floatValue(1.10)}) + filter := DivideByFactory(nil, []core.Value{floatValue(1.10)}) spec.Expect(filter(43, nil).(float64)).ToEqual(39.090909090909086) } func TestDivideByAFloatToAFloat(t *testing.T) { spec := gspec.New(t) - filter := DivideByFactory([]core.Value{floatValue(5.3)}) + filter := DivideByFactory(nil, []core.Value{floatValue(5.3)}) spec.Expect(filter(43.3, nil).(float64)).ToEqual(8.169811320754716) } func TestDivideByAFloatToAStringAsAnInt(t *testing.T) { spec := gspec.New(t) - filter := DivideByFactory([]core.Value{floatValue(7.11)}) + filter := DivideByFactory(nil, []core.Value{floatValue(7.11)}) spec.Expect(filter("33", nil).(float64)).ToEqual(4.641350210970464) } func TestDivideByADynamicIntValue(t *testing.T) { spec := gspec.New(t) - filter := DivideByFactory([]core.Value{dynamicValue("count")}) + filter := DivideByFactory(nil, []core.Value{dynamicValue("count")}) spec.Expect(filter("33", params("count", 112)).(float64)).ToEqual(0.29464285714285715) } func TestDivideByADynamicFloatValue(t *testing.T) { spec := gspec.New(t) - filter := DivideByFactory([]core.Value{dynamicValue("count")}) + filter := DivideByFactory(nil, []core.Value{dynamicValue("count")}) spec.Expect(filter("12", params("count", 44.2)).(float64)).ToEqual(0.27149321266968324) } func TestDivideByDynamicNoop(t *testing.T) { spec := gspec.New(t) - filter := DivideByFactory([]core.Value{dynamicValue("count")}) + filter := DivideByFactory(nil, []core.Value{dynamicValue("count")}) spec.Expect(filter("12", params("count", "22")).(string)).ToEqual("12") } diff --git a/filters/downcase.go b/filters/downcase.go index b3569b4..b5e1b3e 100644 --- a/filters/downcase.go +++ b/filters/downcase.go @@ -2,13 +2,14 @@ package filters import ( "bytes" + "context" "strings" "github.com/acstech/liquid/core" ) // Creates a downcase filter -func DowncaseFactory(parameters []core.Value) core.Filter { +func DowncaseFactory(ctx context.Context, parameters []core.Value) core.Filter { return Downcase } diff --git a/filters/downcase_test.go b/filters/downcase_test.go index 4c2d0f4..be02e34 100644 --- a/filters/downcase_test.go +++ b/filters/downcase_test.go @@ -8,18 +8,18 @@ import ( func TestDowncasesAString(t *testing.T) { spec := gspec.New(t) - filter := DowncaseFactory(nil) + filter := DowncaseFactory(nil, nil) spec.Expect(filter("DBZ", nil).(string)).ToEqual("dbz") } func TestDowncasesBytes(t *testing.T) { spec := gspec.New(t) - filter := DowncaseFactory(nil) + filter := DowncaseFactory(nil, nil) spec.Expect(string(filter([]byte("DBZ"), nil).([]byte))).ToEqual("dbz") } func TestDowncasesPassThroughOnInvalidType(t *testing.T) { spec := gspec.New(t) - filter := DowncaseFactory(nil) + filter := DowncaseFactory(nil, nil) spec.Expect(filter(123, nil).(int)).ToEqual(123) } diff --git a/filters/escape.go b/filters/escape.go index de37e50..3d7e989 100644 --- a/filters/escape.go +++ b/filters/escape.go @@ -1,13 +1,14 @@ package filters import ( + "context" "html" "github.com/acstech/liquid/core" ) // Creates an escape filter -func EscapeFactory(parameters []core.Value) core.Filter { +func EscapeFactory(ctx context.Context, parameters []core.Value) core.Filter { return Escape } diff --git a/filters/escape_test.go b/filters/escape_test.go index 048cbc7..4e8568d 100644 --- a/filters/escape_test.go +++ b/filters/escape_test.go @@ -8,6 +8,6 @@ import ( func TestEscapesAString(t *testing.T) { spec := gspec.New(t) - filter := EscapeFactory(nil) + filter := EscapeFactory(nil, nil) spec.Expect(filter("", nil).(string)).ToEqual("<script>hack</script>") } diff --git a/filters/escapeonce.go b/filters/escapeonce.go index a9c0bb6..4d68f6d 100644 --- a/filters/escapeonce.go +++ b/filters/escapeonce.go @@ -1,13 +1,14 @@ package filters import ( + "context" "html" "github.com/acstech/liquid/core" ) // creates an escapeonce filter -func EscapeOnceFactory(parameters []core.Value) core.Filter { +func EscapeOnceFactory(ctx context.Context, parameters []core.Value) core.Filter { return EscapeOnce } diff --git a/filters/escapeonce_test.go b/filters/escapeonce_test.go index 1cefe18..74faa70 100644 --- a/filters/escapeonce_test.go +++ b/filters/escapeonce_test.go @@ -8,12 +8,12 @@ import ( func TestEscapesOnceAString(t *testing.T) { spec := gspec.New(t) - filter := EscapeOnceFactory(nil) + filter := EscapeOnceFactory(nil, nil) spec.Expect(filter("hello", nil).(string)).ToEqual("<b>hello</b>") } func TestEscapesOnceAStringWithEscapedValues(t *testing.T) { spec := gspec.New(t) - filter := EscapeOnceFactory(nil) + filter := EscapeOnceFactory(nil, nil) spec.Expect(filter("hello<b>hello</b>", nil).(string)).ToEqual("<b>hello</b><b>hello</b>") } diff --git a/filters/first.go b/filters/first.go index d6f0073..7c8fffd 100644 --- a/filters/first.go +++ b/filters/first.go @@ -1,13 +1,14 @@ package filters import ( + "context" "reflect" "github.com/acstech/liquid/core" ) // Creates a first filter -func FirstFactory(parameters []core.Value) core.Filter { +func FirstFactory(ctx context.Context, parameters []core.Value) core.Filter { return First } diff --git a/filters/first_test.go b/filters/first_test.go index a9b72c6..7ba398d 100644 --- a/filters/first_test.go +++ b/filters/first_test.go @@ -8,39 +8,39 @@ import ( func TestReturnsTheFirstItem(t *testing.T) { spec := gspec.New(t) - filter := FirstFactory(nil) + filter := FirstFactory(nil, nil) spec.Expect(filter([]string{"leto", "atreides"}, nil).(string)).ToEqual("leto") } func TestReturnsTheFirstItemIfOnlyOneItem(t *testing.T) { spec := gspec.New(t) - filter := FirstFactory(nil) + filter := FirstFactory(nil, nil) spec.Expect(filter([]string{"leto"}, nil).(string)).ToEqual("leto") } func TestReturnsTheFirstItemOfAnArray(t *testing.T) { spec := gspec.New(t) - filter := FirstFactory(nil) + filter := FirstFactory(nil, nil) arr := [4]int{12, 2, 3, 48} spec.Expect(filter(arr, nil).(int)).ToEqual(12) } func TestFirstPassthroughOnEmptyArray(t *testing.T) { spec := gspec.New(t) - filter := FirstFactory(nil) + filter := FirstFactory(nil, nil) arr := [0]int{} spec.Expect(filter(arr, nil).([0]int)).ToEqual(arr) } func TestFirstPassthroughOnEmptySlice(t *testing.T) { spec := gspec.New(t) - filter := FirstFactory(nil) + filter := FirstFactory(nil, nil) arr := []int{} spec.Expect(len(filter(arr, nil).([]int))).ToEqual(0) } func TestFirstPassthroughOnInvalidType(t *testing.T) { spec := gspec.New(t) - filter := FirstFactory(nil) + filter := FirstFactory(nil, nil) spec.Expect(filter("hahah", nil).(string)).ToEqual("hahah") } diff --git a/filters/join.go b/filters/join.go index 6652a8b..10a7420 100644 --- a/filters/join.go +++ b/filters/join.go @@ -2,6 +2,7 @@ package filters import ( "bytes" + "context" "reflect" "github.com/acstech/liquid/core" @@ -10,7 +11,7 @@ import ( var defaultJoin = (&JoinFilter{&core.StaticStringValue{" "}}).Join // Creates a join filter -func JoinFactory(parameters []core.Value) core.Filter { +func JoinFactory(ctx context.Context, parameters []core.Value) core.Filter { if len(parameters) == 0 { return defaultJoin } diff --git a/filters/join_test.go b/filters/join_test.go index 206bedc..da1f33f 100644 --- a/filters/join_test.go +++ b/filters/join_test.go @@ -9,32 +9,32 @@ import ( func TestJoinsStringsWithTheSpecifiedGlue(t *testing.T) { spec := gspec.New(t) - filter := JoinFactory([]core.Value{stringValue("..")}) + filter := JoinFactory(nil, []core.Value{stringValue("..")}) spec.Expect(string(filter([]string{"leto", "atreides"}, nil).([]byte))).ToEqual("leto..atreides") } func TestJoinsVariousTypesWithTheDefaultGlue(t *testing.T) { spec := gspec.New(t) - filter := JoinFactory(nil) + filter := JoinFactory(nil, nil) spec.Expect(string(filter([]interface{}{"leto", 123, true}, nil).([]byte))).ToEqual("leto 123 true") } func TestJoinPassthroughOnEmptyArray(t *testing.T) { spec := gspec.New(t) - filter := JoinFactory(nil) + filter := JoinFactory(nil, nil) arr := [0]int{} spec.Expect(filter(arr, nil).([0]int)).ToEqual(arr) } func TestJoinPassthroughOnEmptySlice(t *testing.T) { spec := gspec.New(t) - filter := JoinFactory(nil) + filter := JoinFactory(nil, nil) arr := []int{} spec.Expect(len(filter(arr, nil).([]int))).ToEqual(0) } func TestJoinPassthroughOnInvalidType(t *testing.T) { spec := gspec.New(t) - filter := JoinFactory(nil) + filter := JoinFactory(nil, nil) spec.Expect(filter("hahah", nil).(string)).ToEqual("hahah") } diff --git a/filters/last.go b/filters/last.go index 8d15acc..396eafb 100644 --- a/filters/last.go +++ b/filters/last.go @@ -1,13 +1,14 @@ package filters import ( + "context" "reflect" "github.com/acstech/liquid/core" ) // Creates a last filter -func LastFactory(parameters []core.Value) core.Filter { +func LastFactory(ctx context.Context, parameters []core.Value) core.Filter { return Last } diff --git a/filters/last_test.go b/filters/last_test.go index 81bee65..cf146d0 100644 --- a/filters/last_test.go +++ b/filters/last_test.go @@ -8,39 +8,39 @@ import ( func TestReturnsTheLastItem(t *testing.T) { spec := gspec.New(t) - filter := LastFactory(nil) + filter := LastFactory(nil, nil) spec.Expect(filter([]string{"leto", "atreides"}, nil).(string)).ToEqual("atreides") } func TestReturnsTheLastItemIfOnlyOneItem(t *testing.T) { spec := gspec.New(t) - filter := LastFactory(nil) + filter := LastFactory(nil, nil) spec.Expect(filter([]string{"leto"}, nil).(string)).ToEqual("leto") } func TestReturnsTheLastItemOfAnArray(t *testing.T) { spec := gspec.New(t) - filter := LastFactory(nil) + filter := LastFactory(nil, nil) arr := [4]int{1, 2, 3, 48} spec.Expect(filter(arr, nil).(int)).ToEqual(48) } func TestLastPassthroughOnEmptyArray(t *testing.T) { spec := gspec.New(t) - filter := LastFactory(nil) + filter := LastFactory(nil, nil) arr := [0]int{} spec.Expect(filter(arr, nil).([0]int)).ToEqual(arr) } func TestLastPassthroughOnEmptySlice(t *testing.T) { spec := gspec.New(t) - filter := LastFactory(nil) + filter := LastFactory(nil, nil) arr := []int{} spec.Expect(len(filter(arr, nil).([]int))).ToEqual(0) } func TestLastPassthroughOnInvalidType(t *testing.T) { spec := gspec.New(t) - filter := LastFactory(nil) + filter := LastFactory(nil, nil) spec.Expect(filter("hahah", nil).(string)).ToEqual("hahah") } diff --git a/filters/minus.go b/filters/minus.go index e8a8c15..741b71f 100644 --- a/filters/minus.go +++ b/filters/minus.go @@ -1,13 +1,15 @@ package filters import ( + "context" + "github.com/acstech/liquid/core" ) var defaultMinus = (&IntPlusFilter{-1}).Plus // Creates a minus filter -func MinusFactory(parameters []core.Value) core.Filter { +func MinusFactory(ctx context.Context, parameters []core.Value) core.Filter { if len(parameters) == 0 { return defaultMinus } diff --git a/filters/minus_test.go b/filters/minus_test.go index 93db416..0da1f43 100644 --- a/filters/minus_test.go +++ b/filters/minus_test.go @@ -10,55 +10,55 @@ import ( func TestMinusAnIntToAnInt(t *testing.T) { spec := gspec.New(t) - filter := MinusFactory([]core.Value{intValue(5)}) + filter := MinusFactory(nil, []core.Value{intValue(5)}) spec.Expect(filter(43, nil).(int)).ToEqual(38) } func TestMinusAFloattToAnInt(t *testing.T) { spec := gspec.New(t) - filter := MinusFactory([]core.Value{floatValue(5.11)}) + filter := MinusFactory(nil, []core.Value{floatValue(5.11)}) spec.Expect(filter(43, nil).(float64)).ToEqual(37.89) } func TestMinusAnIntToAFloat(t *testing.T) { spec := gspec.New(t) - filter := MinusFactory([]core.Value{intValue(5)}) + filter := MinusFactory(nil, []core.Value{intValue(5)}) spec.Expect(filter(43.2, nil).(float64)).ToEqual(38.2) } func TestMinusAnIntToATime(t *testing.T) { spec := gspec.New(t) now := time.Now() - filter := MinusFactory([]core.Value{intValue(7)}) + filter := MinusFactory(nil, []core.Value{intValue(7)}) spec.Expect(filter(now, nil).(time.Time)).ToEqual(now.Add(time.Minute * -7)) } func TestMinusAnIntToAStringAsAnInt(t *testing.T) { spec := gspec.New(t) - filter := MinusFactory([]core.Value{intValue(7)}) + filter := MinusFactory(nil, []core.Value{intValue(7)}) spec.Expect(filter("33", nil).(int)).ToEqual(26) } func TestMinusAnIntToAStringAsAFloat(t *testing.T) { spec := gspec.New(t) - filter := MinusFactory([]core.Value{floatValue(2.2)}) + filter := MinusFactory(nil, []core.Value{floatValue(2.2)}) spec.Expect(filter("33.11", nil).(float64)).ToEqual(30.91) } func TestMinusAnIntToBytesAsAnInt(t *testing.T) { spec := gspec.New(t) - filter := MinusFactory([]core.Value{intValue(7)}) + filter := MinusFactory(nil, []core.Value{intValue(7)}) spec.Expect(filter([]byte("34"), nil).(int)).ToEqual(27) } func TestMinusAnDynamicIntToBytesAsAnInt(t *testing.T) { spec := gspec.New(t) - filter := MinusFactory([]core.Value{dynamicValue("fee")}) + filter := MinusFactory(nil, []core.Value{dynamicValue("fee")}) spec.Expect(filter([]byte("34"), params("fee", 5)).(int)).ToEqual(29) } func TestMinusAnDynamicFloatToBytesAsAnInt(t *testing.T) { spec := gspec.New(t) - filter := MinusFactory([]core.Value{dynamicValue("fee")}) + filter := MinusFactory(nil, []core.Value{dynamicValue("fee")}) spec.Expect(filter([]byte("34"), params("fee", 5.1)).(float64)).ToEqual(28.9) } diff --git a/filters/modulo.go b/filters/modulo.go index 96cebee..8d348ae 100644 --- a/filters/modulo.go +++ b/filters/modulo.go @@ -1,13 +1,14 @@ package filters import ( + "context" "strconv" "github.com/acstech/liquid/core" ) // Creates a plus filter -func ModuloFactory(parameters []core.Value) core.Filter { +func ModuloFactory(ctx context.Context, parameters []core.Value) core.Filter { if len(parameters) == 0 { return Noop } diff --git a/filters/modulo_test.go b/filters/modulo_test.go index f6cf05d..677b4e2 100644 --- a/filters/modulo_test.go +++ b/filters/modulo_test.go @@ -9,30 +9,30 @@ import ( func TestModuloAnIntToAnInt(t *testing.T) { spec := gspec.New(t) - filter := ModuloFactory([]core.Value{intValue(5)}) + filter := ModuloFactory(nil, []core.Value{intValue(5)}) spec.Expect(filter(43, nil).(int)).ToEqual(3) } func TestModuloAnFloatToAnInt(t *testing.T) { spec := gspec.New(t) - filter := ModuloFactory([]core.Value{floatValue(5.2)}) + filter := ModuloFactory(nil, []core.Value{floatValue(5.2)}) spec.Expect(filter(43, nil).(int)).ToEqual(3) } func TestModuloAnIntToAStringAsAnInt(t *testing.T) { spec := gspec.New(t) - filter := ModuloFactory([]core.Value{intValue(7)}) + filter := ModuloFactory(nil, []core.Value{intValue(7)}) spec.Expect(filter("33", nil).(int)).ToEqual(5) } func TestModuloAnIntToBytesAsAnInt(t *testing.T) { spec := gspec.New(t) - filter := ModuloFactory([]core.Value{intValue(7)}) + filter := ModuloFactory(nil, []core.Value{intValue(7)}) spec.Expect(filter([]byte("34"), nil).(int)).ToEqual(6) } func TestModuloAnDynamicIntToBytesAsAnInt(t *testing.T) { spec := gspec.New(t) - filter := ModuloFactory([]core.Value{dynamicValue("fee")}) + filter := ModuloFactory(nil, []core.Value{dynamicValue("fee")}) spec.Expect(filter([]byte("34"), params("fee", 5)).(int)).ToEqual(4) } diff --git a/filters/newlinetobr.go b/filters/newlinetobr.go index 86ba9c2..151140a 100644 --- a/filters/newlinetobr.go +++ b/filters/newlinetobr.go @@ -1,6 +1,7 @@ package filters import ( + "context" "regexp" "github.com/acstech/liquid/core" @@ -8,6 +9,6 @@ import ( var newLinesToBr = &ReplacePattern{regexp.MustCompile("(\n\r|\n|\r)"), "
\n"} -func NewLineToBrFactory(parameters []core.Value) core.Filter { +func NewLineToBrFactory(ctx context.Context, parameters []core.Value) core.Filter { return newLinesToBr.Replace } diff --git a/filters/newlinetobr_test.go b/filters/newlinetobr_test.go index 017dbec..5f140f1 100644 --- a/filters/newlinetobr_test.go +++ b/filters/newlinetobr_test.go @@ -8,6 +8,6 @@ import ( func TestReplacesNewlinesWithBr(t *testing.T) { spec := gspec.New(t) - filter := NewLineToBrFactory(nil) + filter := NewLineToBrFactory(nil, nil) spec.Expect(filter("f\no\ro\n\r", nil).(string)).ToEqual("f
\no
\no
\n") } diff --git a/filters/plus.go b/filters/plus.go index 0f3e8f8..04092af 100644 --- a/filters/plus.go +++ b/filters/plus.go @@ -1,6 +1,7 @@ package filters import ( + "context" "strconv" "time" @@ -10,7 +11,7 @@ import ( var defaultPlus = (&IntPlusFilter{1}).Plus // Creates a plus filter -func PlusFactory(parameters []core.Value) core.Filter { +func PlusFactory(ctx context.Context, parameters []core.Value) core.Filter { if len(parameters) == 0 { return defaultPlus } diff --git a/filters/plus_test.go b/filters/plus_test.go index 84ffa64..d0747da 100644 --- a/filters/plus_test.go +++ b/filters/plus_test.go @@ -10,61 +10,61 @@ import ( func TestPlusAnIntToAnInt(t *testing.T) { spec := gspec.New(t) - filter := PlusFactory([]core.Value{intValue(5)}) + filter := PlusFactory(nil, []core.Value{intValue(5)}) spec.Expect(filter(43, nil).(int)).ToEqual(48) } func TestPlusAFloattToAnInt(t *testing.T) { spec := gspec.New(t) - filter := PlusFactory([]core.Value{floatValue(5.11)}) + filter := PlusFactory(nil, []core.Value{floatValue(5.11)}) spec.Expect(filter(43, nil).(float64)).ToEqual(48.11) } func TestPlusAnIntToAFloat(t *testing.T) { spec := gspec.New(t) - filter := PlusFactory([]core.Value{intValue(5)}) + filter := PlusFactory(nil, []core.Value{intValue(5)}) spec.Expect(filter(43.2, nil).(float64)).ToEqual(48.2) } func TestPlusAnIntToNow(t *testing.T) { spec := gspec.New(t) - filter := PlusFactory([]core.Value{intValue(61)}) + filter := PlusFactory(nil, []core.Value{intValue(61)}) spec.Expect(filter("now", nil).(time.Time)).ToEqual(core.Now().Add(time.Minute * 61)) } func TestPlusAnIntToATime(t *testing.T) { spec := gspec.New(t) now := time.Now() - filter := PlusFactory([]core.Value{intValue(7)}) + filter := PlusFactory(nil, []core.Value{intValue(7)}) spec.Expect(filter(now, nil).(time.Time)).ToEqual(now.Add(time.Minute * 7)) } func TestPlusAnIntToAStringAsAnInt(t *testing.T) { spec := gspec.New(t) - filter := PlusFactory([]core.Value{intValue(7)}) + filter := PlusFactory(nil, []core.Value{intValue(7)}) spec.Expect(filter("33", nil).(int)).ToEqual(40) } func TestPlusAnIntToAStringAsAFloat(t *testing.T) { spec := gspec.New(t) - filter := PlusFactory([]core.Value{floatValue(2.2)}) + filter := PlusFactory(nil, []core.Value{floatValue(2.2)}) spec.Expect(filter("33.11", nil).(float64)).ToEqual(35.31) } func TestPlusAnIntToBytesAsAnInt(t *testing.T) { spec := gspec.New(t) - filter := PlusFactory([]core.Value{intValue(7)}) + filter := PlusFactory(nil, []core.Value{intValue(7)}) spec.Expect(filter([]byte("34"), nil).(int)).ToEqual(41) } func TestPlusAnDynamicIntToBytesAsAnInt(t *testing.T) { spec := gspec.New(t) - filter := PlusFactory([]core.Value{dynamicValue("fee")}) + filter := PlusFactory(nil, []core.Value{dynamicValue("fee")}) spec.Expect(filter([]byte("34"), params("fee", 5)).(int)).ToEqual(39) } func TestPlusAnDynamicFloatToBytesAsAnInt(t *testing.T) { spec := gspec.New(t) - filter := PlusFactory([]core.Value{dynamicValue("fee")}) + filter := PlusFactory(nil, []core.Value{dynamicValue("fee")}) spec.Expect(filter([]byte("34"), params("fee", 5.1)).(float64)).ToEqual(39.1) } diff --git a/filters/prepend.go b/filters/prepend.go index f7d273f..37f4e0b 100644 --- a/filters/prepend.go +++ b/filters/prepend.go @@ -1,11 +1,13 @@ package filters import ( + "context" + "github.com/acstech/liquid/core" ) // Creates an prepend filter -func PrependFactory(parameters []core.Value) core.Filter { +func PrependFactory(ctx context.Context, parameters []core.Value) core.Filter { if len(parameters) == 0 { return Noop } diff --git a/filters/prepend_test.go b/filters/prepend_test.go index d606a34..299a1ff 100644 --- a/filters/prepend_test.go +++ b/filters/prepend_test.go @@ -9,19 +9,19 @@ import ( func TestPrependToAString(t *testing.T) { spec := gspec.New(t) - filter := PrependFactory([]core.Value{stringValue("?!")}) + filter := PrependFactory(nil, []core.Value{stringValue("?!")}) spec.Expect(filter("dbz", nil).(string)).ToEqual("?!dbz") } func TestPrependToBytes(t *testing.T) { spec := gspec.New(t) - filter := PrependFactory([]core.Value{stringValue("boring")}) + filter := PrependFactory(nil, []core.Value{stringValue("boring")}) spec.Expect(filter([]byte("so"), nil).(string)).ToEqual("boringso") } func TestPrependADynamicValue(t *testing.T) { spec := gspec.New(t) - filter := PrependFactory([]core.Value{dynamicValue("local.currency")}) + filter := PrependFactory(nil, []core.Value{dynamicValue("local.currency")}) data := map[string]interface{}{ "local": map[string]string{ "currency": "$", diff --git a/filters/remove.go b/filters/remove.go index 910aa67..c3e82c0 100644 --- a/filters/remove.go +++ b/filters/remove.go @@ -1,10 +1,12 @@ package filters import ( + "context" + "github.com/acstech/liquid/core" ) -func RemoveFactory(parameters []core.Value) core.Filter { +func RemoveFactory(ctx context.Context, parameters []core.Value) core.Filter { if len(parameters) != 1 { return Noop } diff --git a/filters/remove_test.go b/filters/remove_test.go index 596bf8e..9206244 100644 --- a/filters/remove_test.go +++ b/filters/remove_test.go @@ -9,6 +9,6 @@ import ( func TestRemovesValuesFromAString(t *testing.T) { spec := gspec.New(t) - filter := RemoveFactory([]core.Value{stringValue("foo")}) + filter := RemoveFactory(nil, []core.Value{stringValue("foo")}) spec.Expect(filter("foobarforfoo", nil).(string)).ToEqual("barfor") } diff --git a/filters/removefirst.go b/filters/removefirst.go index 82bc3da..0f0adf5 100644 --- a/filters/removefirst.go +++ b/filters/removefirst.go @@ -1,6 +1,8 @@ package filters import ( + "context" + "github.com/acstech/liquid/core" ) @@ -8,7 +10,7 @@ var ( EmptyValue = &core.StaticStringValue{""} ) -func RemoveFirstFactory(parameters []core.Value) core.Filter { +func RemoveFirstFactory(ctx context.Context, parameters []core.Value) core.Filter { if len(parameters) != 1 { return Noop } diff --git a/filters/removefirst_test.go b/filters/removefirst_test.go index a6e3d9a..c6cfc24 100644 --- a/filters/removefirst_test.go +++ b/filters/removefirst_test.go @@ -9,6 +9,6 @@ import ( func TestRemovesFirstValueFromAString(t *testing.T) { spec := gspec.New(t) - filter := RemoveFirstFactory([]core.Value{stringValue("foo")}) + filter := RemoveFirstFactory(nil, []core.Value{stringValue("foo")}) spec.Expect(filter("foobarforfoo", nil).(string)).ToEqual("barforfoo") } diff --git a/filters/replace.go b/filters/replace.go index 15cbd41..d99ca83 100644 --- a/filters/replace.go +++ b/filters/replace.go @@ -2,12 +2,13 @@ package filters import ( "bytes" + "context" "strings" "github.com/acstech/liquid/core" ) -func ReplaceFactory(parameters []core.Value) core.Filter { +func ReplaceFactory(ctx context.Context, parameters []core.Value) core.Filter { if len(parameters) != 2 { return Noop } diff --git a/filters/replace_test.go b/filters/replace_test.go index dfcdb68..ed27421 100644 --- a/filters/replace_test.go +++ b/filters/replace_test.go @@ -9,12 +9,12 @@ import ( func TestReplaceValuesInAString(t *testing.T) { spec := gspec.New(t) - filter := ReplaceFactory([]core.Value{stringValue("foo"), stringValue("bar")}) + filter := ReplaceFactory(nil, []core.Value{stringValue("foo"), stringValue("bar")}) spec.Expect(filter("foobarforfoo", nil).(string)).ToEqual("barbarforbar") } func TestReplaceWithDynamicValues(t *testing.T) { spec := gspec.New(t) - filter := ReplaceFactory([]core.Value{dynamicValue("f"), dynamicValue("b")}) + filter := ReplaceFactory(nil, []core.Value{dynamicValue("f"), dynamicValue("b")}) spec.Expect(filter("foobarforfoo", params("f", "oo", "b", "br")).(string)).ToEqual("fbrbarforfbr") } diff --git a/filters/replacefirst.go b/filters/replacefirst.go index cb1ca5a..4054fa3 100644 --- a/filters/replacefirst.go +++ b/filters/replacefirst.go @@ -1,10 +1,12 @@ package filters import ( + "context" + "github.com/acstech/liquid/core" ) -func ReplaceFirstFactory(parameters []core.Value) core.Filter { +func ReplaceFirstFactory(ctx context.Context, parameters []core.Value) core.Filter { if len(parameters) != 2 { return Noop } diff --git a/filters/replacefirst_test.go b/filters/replacefirst_test.go index c8533af..7827822 100644 --- a/filters/replacefirst_test.go +++ b/filters/replacefirst_test.go @@ -9,6 +9,6 @@ import ( func TestReplaceFirstValueInAString(t *testing.T) { spec := gspec.New(t) - filter := ReplaceFirstFactory([]core.Value{stringValue("foo"), stringValue("bar")}) + filter := ReplaceFirstFactory(nil, []core.Value{stringValue("foo"), stringValue("bar")}) spec.Expect(filter("foobarforfoo", nil).(string)).ToEqual("barbarforfoo") } diff --git a/filters/reverse.go b/filters/reverse.go index a5fa3d8..f8b1018 100644 --- a/filters/reverse.go +++ b/filters/reverse.go @@ -1,13 +1,14 @@ package filters import ( + "context" "reflect" "github.com/acstech/liquid/core" ) // Creates a reverse filter -func ReverseFactory(parameters []core.Value) core.Filter { +func ReverseFactory(ctx context.Context, parameters []core.Value) core.Filter { return Reverse } diff --git a/filters/reverse_test.go b/filters/reverse_test.go index 842c58d..a2227a2 100644 --- a/filters/reverse_test.go +++ b/filters/reverse_test.go @@ -8,31 +8,31 @@ import ( func TestReverseDoesNothingOnInvalidType(t *testing.T) { spec := gspec.New(t) - filter := ReverseFactory(nil) + filter := ReverseFactory(nil, nil) spec.Expect(filter(123, nil).(int)).ToEqual(123) } func TestReverseAnEvenLengthString(t *testing.T) { spec := gspec.New(t) - filter := ReverseFactory(nil) + filter := ReverseFactory(nil, nil) spec.Expect(string(filter("123456", nil).([]byte))).ToEqual("654321") } func TestReverseAnOddLengthString(t *testing.T) { spec := gspec.New(t) - filter := ReverseFactory(nil) + filter := ReverseFactory(nil, nil) spec.Expect(string(filter("12345", nil).([]byte))).ToEqual("54321") } func TestReverseASingleCharacterString(t *testing.T) { spec := gspec.New(t) - filter := ReverseFactory(nil) + filter := ReverseFactory(nil, nil) spec.Expect(string(filter("1", nil).([]byte))).ToEqual("1") } func TestReverseAnEvenLengthArray(t *testing.T) { spec := gspec.New(t) - filter := ReverseFactory(nil) + filter := ReverseFactory(nil, nil) values := filter([]int{1, 2, 3, 4}, nil).([]int) spec.Expect(len(values)).ToEqual(4) spec.Expect(values[0]).ToEqual(4) @@ -43,7 +43,7 @@ func TestReverseAnEvenLengthArray(t *testing.T) { func TestReverseAnOddLengthArray(t *testing.T) { spec := gspec.New(t) - filter := ReverseFactory(nil) + filter := ReverseFactory(nil, nil) values := filter([]float64{1.1, 2.2, 3.3}, nil).([]float64) spec.Expect(len(values)).ToEqual(3) spec.Expect(values[0]).ToEqual(3.3) @@ -53,7 +53,7 @@ func TestReverseAnOddLengthArray(t *testing.T) { func TestReverseASingleElementArray(t *testing.T) { spec := gspec.New(t) - filter := ReverseFactory(nil) + filter := ReverseFactory(nil, nil) values := filter([]bool{true}, nil).([]bool) spec.Expect(len(values)).ToEqual(1) spec.Expect(values[0]).ToEqual(true) diff --git a/filters/size.go b/filters/size.go index 13e0b02..eb94f6d 100644 --- a/filters/size.go +++ b/filters/size.go @@ -1,11 +1,13 @@ package filters import ( + "context" + "github.com/acstech/liquid/core" ) // Creates a size filter -func SizeFactory(parameters []core.Value) core.Filter { +func SizeFactory(ctx context.Context, parameters []core.Value) core.Filter { return Size } diff --git a/filters/size_test.go b/filters/size_test.go index a36d80a..024117a 100644 --- a/filters/size_test.go +++ b/filters/size_test.go @@ -8,36 +8,36 @@ import ( func TestSizeOfString(t *testing.T) { spec := gspec.New(t) - filter := SizeFactory(nil) + filter := SizeFactory(nil, nil) spec.Expect(filter("dbz", nil).(int)).ToEqual(3) } func TestSizeOfByteArray(t *testing.T) { spec := gspec.New(t) - filter := SizeFactory(nil) + filter := SizeFactory(nil, nil) spec.Expect(filter([]byte("7 123"), nil).(int)).ToEqual(5) } func TestSizeOfIntArray(t *testing.T) { spec := gspec.New(t) - filter := SizeFactory(nil) + filter := SizeFactory(nil, nil) spec.Expect(filter([]int{2, 4, 5, 6}, nil).(int)).ToEqual(4) } func TestSizeOfBoolArray(t *testing.T) { spec := gspec.New(t) - filter := SizeFactory(nil) + filter := SizeFactory(nil, nil) spec.Expect(filter([]bool{true, false, true, true, false}, nil).(int)).ToEqual(5) } func TestSizeOfMap(t *testing.T) { spec := gspec.New(t) - filter := SizeFactory(nil) + filter := SizeFactory(nil, nil) spec.Expect(filter(map[string]int{"over": 9000}, nil).(int)).ToEqual(1) } func TestSizeOfSometingInvalid(t *testing.T) { spec := gspec.New(t) - filter := SizeFactory(nil) + filter := SizeFactory(nil, nil) spec.Expect(filter(false, nil).(bool)).ToEqual(false) } diff --git a/filters/sort.go b/filters/sort.go index 82c9379..d735b75 100644 --- a/filters/sort.go +++ b/filters/sort.go @@ -1,6 +1,7 @@ package filters import ( + "context" "reflect" "sort" @@ -8,7 +9,7 @@ import ( ) // Creates a sort filter -func SortFactory(parameters []core.Value) core.Filter { +func SortFactory(ctx context.Context, parameters []core.Value) core.Filter { return Sort } diff --git a/filters/sort_test.go b/filters/sort_test.go index 86f8fab..6ebc6b8 100644 --- a/filters/sort_test.go +++ b/filters/sort_test.go @@ -8,7 +8,7 @@ import ( func TestSortsAnArrayOfInteger(t *testing.T) { spec := gspec.New(t) - filter := SortFactory(nil) + filter := SortFactory(nil, nil) values := filter([]int{3, 4, 1, 2, 3}, nil).([]int) spec.Expect(len(values)).ToEqual(5) spec.Expect(values[0]).ToEqual(1) @@ -20,7 +20,7 @@ func TestSortsAnArrayOfInteger(t *testing.T) { func TestSortsAnArrayOfStrings(t *testing.T) { spec := gspec.New(t) - filter := SortFactory(nil) + filter := SortFactory(nil, nil) values := filter([]string{"cc", "b", "aa", "g"}, nil).([]string) spec.Expect(len(values)).ToEqual(4) spec.Expect(values[0]).ToEqual("aa") @@ -31,7 +31,7 @@ func TestSortsAnArrayOfStrings(t *testing.T) { func TestSortsAnArrayOfFloats(t *testing.T) { spec := gspec.New(t) - filter := SortFactory(nil) + filter := SortFactory(nil, nil) values := filter([]float64{1.1, 0.9, 1233.2, 21.994}, nil).([]float64) spec.Expect(len(values)).ToEqual(4) spec.Expect(values[0]).ToEqual(0.9) @@ -42,7 +42,7 @@ func TestSortsAnArrayOfFloats(t *testing.T) { func TestSortsSortableData(t *testing.T) { spec := gspec.New(t) - filter := SortFactory(nil) + filter := SortFactory(nil, nil) values := filter(People{&Person{"Leto"}, &Person{"Paul"}, &Person{"Jessica"}}, nil).(People) spec.Expect(len(values)).ToEqual(3) spec.Expect(values[0].Name).ToEqual("Jessica") @@ -52,7 +52,7 @@ func TestSortsSortableData(t *testing.T) { func TestSortsOtherValuesAsStrings(t *testing.T) { spec := gspec.New(t) - filter := SortFactory(nil) + filter := SortFactory(nil, nil) values := filter([]interface{}{933, "spice", true, 123.44, "123", false}, nil).([]interface{}) spec.Expect(len(values)).ToEqual(6) spec.Expect(values[0].(string)).ToEqual("123") @@ -65,7 +65,7 @@ func TestSortsOtherValuesAsStrings(t *testing.T) { func TestSortSkipsNonArrays(t *testing.T) { spec := gspec.New(t) - filter := SortFactory(nil) + filter := SortFactory(nil, nil) spec.Expect(filter(1343, nil).(int)).ToEqual(1343) } diff --git a/filters/split.go b/filters/split.go index e211e92..61928f1 100644 --- a/filters/split.go +++ b/filters/split.go @@ -1,6 +1,7 @@ package filters import ( + "context" "strings" "github.com/acstech/liquid/core" @@ -9,7 +10,7 @@ import ( var defaultSplit = (&SplitFilter{&core.StaticStringValue{" "}}).Split // Creates a join filter -func SplitFactory(parameters []core.Value) core.Filter { +func SplitFactory(ctx context.Context, parameters []core.Value) core.Filter { if len(parameters) == 0 { return defaultSplit } diff --git a/filters/split_test.go b/filters/split_test.go index ad6c73f..a673e16 100644 --- a/filters/split_test.go +++ b/filters/split_test.go @@ -9,7 +9,7 @@ import ( func TestSplitsAStringOnDefaultSpace(t *testing.T) { spec := gspec.New(t) - filter := SplitFactory([]core.Value{}) + filter := SplitFactory(nil, []core.Value{}) values := filter("hello world", nil).([]string) spec.Expect(len(values)).ToEqual(2) spec.Expect(values[0]).ToEqual("hello") @@ -18,7 +18,7 @@ func TestSplitsAStringOnDefaultSpace(t *testing.T) { func TestSplitsAStringOnSpecifiedValue(t *testing.T) { spec := gspec.New(t) - filter := SplitFactory([]core.Value{stringValue("..")}) + filter := SplitFactory(nil, []core.Value{stringValue("..")}) values := filter([]byte("hel..lowo..rl..d"), nil).([]string) spec.Expect(len(values)).ToEqual(4) spec.Expect(values[0]).ToEqual("hel") @@ -29,7 +29,7 @@ func TestSplitsAStringOnSpecifiedValue(t *testing.T) { func TestSplitsAStringOnADynamicValue(t *testing.T) { spec := gspec.New(t) - filter := SplitFactory([]core.Value{dynamicValue("sep")}) + filter := SplitFactory(nil, []core.Value{dynamicValue("sep")}) values := filter("over;9000;!", params("sep", ";")).([]string) spec.Expect(len(values)).ToEqual(3) spec.Expect(values[0]).ToEqual("over") diff --git a/filters/striphtml.go b/filters/striphtml.go index 450aecd..d48758b 100644 --- a/filters/striphtml.go +++ b/filters/striphtml.go @@ -1,6 +1,7 @@ package filters import ( + "context" "regexp" "github.com/acstech/liquid/core" @@ -8,6 +9,6 @@ import ( var stripHtml = &ReplacePattern{regexp.MustCompile("(?i)|||<.*?>"), ""} -func StripHtmlFactory(parameters []core.Value) core.Filter { +func StripHtmlFactory(ctx context.Context, parameters []core.Value) core.Filter { return stripHtml.Replace } diff --git a/filters/striphtml_test.go b/filters/striphtml_test.go index 320b45f..465f704 100644 --- a/filters/striphtml_test.go +++ b/filters/striphtml_test.go @@ -8,6 +8,6 @@ import ( func TestStringHtml(t *testing.T) { spec := gspec.New(t) - filter := StripHtmlFactory(nil) + filter := StripHtmlFactory(nil, nil) spec.Expect(filter("hello world", nil).(string)).ToEqual("hello world") } diff --git a/filters/stripnewlines.go b/filters/stripnewlines.go index 1b89ec4..1b1e55e 100644 --- a/filters/stripnewlines.go +++ b/filters/stripnewlines.go @@ -1,6 +1,7 @@ package filters import ( + "context" "regexp" "github.com/acstech/liquid/core" @@ -8,6 +9,6 @@ import ( var stripNewLines = &ReplacePattern{regexp.MustCompile("(\n|\r)"), ""} -func StripNewLinesFactory(parameters []core.Value) core.Filter { +func StripNewLinesFactory(ctx context.Context, parameters []core.Value) core.Filter { return stripNewLines.Replace } diff --git a/filters/stripnewlines_test.go b/filters/stripnewlines_test.go index 286107e..4d45222 100644 --- a/filters/stripnewlines_test.go +++ b/filters/stripnewlines_test.go @@ -8,6 +8,6 @@ import ( func TestStripsNewLinesFromStirng(t *testing.T) { spec := gspec.New(t) - filter := StripNewLinesFactory(nil) + filter := StripNewLinesFactory(nil, nil) spec.Expect(filter("f\no\ro\n\r", nil).(string)).ToEqual("foo") } diff --git a/filters/times.go b/filters/times.go index 828a556..d8e8874 100644 --- a/filters/times.go +++ b/filters/times.go @@ -1,13 +1,14 @@ package filters import ( + "context" "strconv" "github.com/acstech/liquid/core" ) // Creates a time filter -func TimesFactory(parameters []core.Value) core.Filter { +func TimesFactory(ctx context.Context, parameters []core.Value) core.Filter { if len(parameters) == 0 { return Noop } diff --git a/filters/times_test.go b/filters/times_test.go index 2877f4c..99134a4 100644 --- a/filters/times_test.go +++ b/filters/times_test.go @@ -10,73 +10,73 @@ import ( func TestTimesAnIntToAnInt(t *testing.T) { spec := gspec.New(t) - filter := TimesFactory([]core.Value{intValue(5)}) + filter := TimesFactory(nil, []core.Value{intValue(5)}) spec.Expect(filter(43, nil).(int)).ToEqual(215) } func TestTimesAnIntToAFloat(t *testing.T) { spec := gspec.New(t) - filter := TimesFactory([]core.Value{intValue(2)}) + filter := TimesFactory(nil, []core.Value{intValue(2)}) spec.Expect(filter(43.3, nil).(float64)).ToEqual(86.6) } func TestTimesAnIntToAStringAsAnInt(t *testing.T) { spec := gspec.New(t) - filter := TimesFactory([]core.Value{intValue(7)}) + filter := TimesFactory(nil, []core.Value{intValue(7)}) spec.Expect(filter("33", nil).(int)).ToEqual(231) } func TestTimesAnIntToBytesAsAnInt(t *testing.T) { spec := gspec.New(t) - filter := TimesFactory([]core.Value{intValue(7)}) + filter := TimesFactory(nil, []core.Value{intValue(7)}) spec.Expect(filter([]byte("34"), nil).(int)).ToEqual(238) } func TestTimesAnIntToAStringAsAString(t *testing.T) { spec := gspec.New(t) - filter := TimesFactory([]core.Value{intValue(7)}) + filter := TimesFactory(nil, []core.Value{intValue(7)}) spec.Expect(filter("abc", nil).(string)).ToEqual("abc") } func TestTimesAnIntToBytesAsAString(t *testing.T) { spec := gspec.New(t) - filter := TimesFactory([]core.Value{intValue(8)}) + filter := TimesFactory(nil, []core.Value{intValue(8)}) spec.Expect(filter([]byte("abb"), nil).(string)).ToEqual("abb") } func TestTimesAFloatToAnInt(t *testing.T) { spec := gspec.New(t) - filter := TimesFactory([]core.Value{floatValue(1.10)}) + filter := TimesFactory(nil, []core.Value{floatValue(1.10)}) spec.Expect(filter(43, nil).(float64)).ToEqual(47.300000000000004) } func TestTimesAFloatToAFloat(t *testing.T) { spec := gspec.New(t) - filter := TimesFactory([]core.Value{floatValue(5.3)}) + filter := TimesFactory(nil, []core.Value{floatValue(5.3)}) spec.Expect(filter(43.3, nil).(float64)).ToEqual(229.48999999999998) } func TestTimesAFloatToAStringAsAnInt(t *testing.T) { spec := gspec.New(t) - filter := TimesFactory([]core.Value{floatValue(7.11)}) + filter := TimesFactory(nil, []core.Value{floatValue(7.11)}) spec.Expect(filter("33", nil).(float64)).ToEqual(234.63000000000002) } func TestTimesADynamicIntValue(t *testing.T) { spec := gspec.New(t) - filter := TimesFactory([]core.Value{dynamicValue("count")}) + filter := TimesFactory(nil, []core.Value{dynamicValue("count")}) spec.Expect(filter("33", params("count", 112)).(int)).ToEqual(3696) } func TestTimesADynamicFloatValue(t *testing.T) { spec := gspec.New(t) - filter := TimesFactory([]core.Value{dynamicValue("count")}) + filter := TimesFactory(nil, []core.Value{dynamicValue("count")}) spec.Expect(filter("12", params("count", 44.2)).(float64)).ToEqual(530.4000000000001) } func TestTimesDynamicNoop(t *testing.T) { spec := gspec.New(t) - filter := TimesFactory([]core.Value{dynamicValue("count")}) + filter := TimesFactory(nil, []core.Value{dynamicValue("count")}) spec.Expect(filter("12", params("count", "22")).(string)).ToEqual("12") } @@ -93,7 +93,7 @@ func floatValue(f float64) core.Value { } func dynamicValue(s string) core.Value { - return core.NewDynamicValue(strings.Split(s, ".")) + return core.NewDynamicValue(nil, strings.Split(s, ".")) } func params(values ...interface{}) map[string]interface{} { diff --git a/filters/truncate.go b/filters/truncate.go index 5ffd7fe..5d1ae49 100644 --- a/filters/truncate.go +++ b/filters/truncate.go @@ -1,6 +1,8 @@ package filters import ( + "context" + "github.com/acstech/liquid/core" ) @@ -11,7 +13,7 @@ var ( ) // Creates an truncate filter -func TruncateFactory(parameters []core.Value) core.Filter { +func TruncateFactory(ctx context.Context, parameters []core.Value) core.Filter { switch len(parameters) { case 0: return defaultTruncate diff --git a/filters/truncate_test.go b/filters/truncate_test.go index d645ece..8420cf5 100644 --- a/filters/truncate_test.go +++ b/filters/truncate_test.go @@ -9,48 +9,48 @@ import ( func TestTruncateAString(t *testing.T) { spec := gspec.New(t) - filter := TruncateFactory([]core.Value{intValue(5)}) + filter := TruncateFactory(nil, []core.Value{intValue(5)}) spec.Expect(filter("1234567", nil).(string)).ToEqual("12...") } func TestTruncateAShortString(t *testing.T) { spec := gspec.New(t) - filter := TruncateFactory([]core.Value{intValue(100), stringValue("")}) + filter := TruncateFactory(nil, []core.Value{intValue(100), stringValue("")}) spec.Expect(filter("1234567", nil).(string)).ToEqual("1234567") } func TestTruncateAPerfectString(t *testing.T) { spec := gspec.New(t) - filter := TruncateFactory([]core.Value{intValue(7), stringValue("")}) + filter := TruncateFactory(nil, []core.Value{intValue(7), stringValue("")}) spec.Expect(filter("1234567", nil).(string)).ToEqual("1234567") } func TestTruncateAnAlmostPerfectString(t *testing.T) { spec := gspec.New(t) - filter := TruncateFactory([]core.Value{intValue(6), stringValue("")}) + filter := TruncateFactory(nil, []core.Value{intValue(6), stringValue("")}) spec.Expect(filter("1234567", nil).(string)).ToEqual("123456") } func TestTruncateAStringFromAFloat(t *testing.T) { spec := gspec.New(t) - filter := TruncateFactory([]core.Value{floatValue(3.3), stringValue(".")}) + filter := TruncateFactory(nil, []core.Value{floatValue(3.3), stringValue(".")}) spec.Expect(filter("1234567", nil).(string)).ToEqual("12.") } func TestTruncateAStringFromAString(t *testing.T) { spec := gspec.New(t) - filter := TruncateFactory([]core.Value{stringValue("4"), stringValue("")}) + filter := TruncateFactory(nil, []core.Value{stringValue("4"), stringValue("")}) spec.Expect(filter("1234567", nil).(string)).ToEqual("1234") } func TestTruncateAStringFromAnInvalidString(t *testing.T) { spec := gspec.New(t) - filter := TruncateFactory([]core.Value{stringValue("abc"), stringValue("")}) + filter := TruncateFactory(nil, []core.Value{stringValue("abc"), stringValue("")}) spec.Expect(filter("1234567", nil).(string)).ToEqual("1234567") } func TestTruncateAnInvalidValue(t *testing.T) { spec := gspec.New(t) - filter := TruncateFactory([]core.Value{intValue(4)}) + filter := TruncateFactory(nil, []core.Value{intValue(4)}) spec.Expect(filter(555, nil).(string)).ToEqual("5...") } diff --git a/filters/truncatewords.go b/filters/truncatewords.go index 58abced..4c34c60 100644 --- a/filters/truncatewords.go +++ b/filters/truncatewords.go @@ -1,6 +1,8 @@ package filters import ( + "context" + "github.com/acstech/liquid/core" ) @@ -10,7 +12,7 @@ var ( ) // Creates an truncatewords filter -func TruncateWordsFactory(parameters []core.Value) core.Filter { +func TruncateWordsFactory(ctx context.Context, parameters []core.Value) core.Filter { switch len(parameters) { case 0: return defaultTruncateWords diff --git a/filters/truncatewords_test.go b/filters/truncatewords_test.go index 9b45af5..1357337 100644 --- a/filters/truncatewords_test.go +++ b/filters/truncatewords_test.go @@ -9,30 +9,30 @@ import ( func TestTruncateWordsWhenTooLong(t *testing.T) { spec := gspec.New(t) - filter := TruncateWordsFactory([]core.Value{intValue(2)}) + filter := TruncateWordsFactory(nil, []core.Value{intValue(2)}) spec.Expect(filter("hello world how's it going", nil).(string)).ToEqual("hello world...") } func TestTruncateWordsWhenTooShort(t *testing.T) { spec := gspec.New(t) - filter := TruncateWordsFactory([]core.Value{intValue(6)}) + filter := TruncateWordsFactory(nil, []core.Value{intValue(6)}) spec.Expect(filter("hello world how's it going", nil).(string)).ToEqual("hello world how's it going") } func TestTruncateWordsWhenJustRight(t *testing.T) { spec := gspec.New(t) - filter := TruncateWordsFactory([]core.Value{intValue(5)}) + filter := TruncateWordsFactory(nil, []core.Value{intValue(5)}) spec.Expect(filter("hello world how's it going", nil).(string)).ToEqual("hello world how's it going") } func TestTruncateWordsWithCustomAppend(t *testing.T) { spec := gspec.New(t) - filter := TruncateWordsFactory([]core.Value{intValue(3), stringValue(" (more...)")}) + filter := TruncateWordsFactory(nil, []core.Value{intValue(3), stringValue(" (more...)")}) spec.Expect(filter("hello world how's it going", nil).(string)).ToEqual("hello world how's (more...)") } func TestTruncateWordsWithShortWords(t *testing.T) { spec := gspec.New(t) - filter := TruncateWordsFactory([]core.Value{dynamicValue("max")}) + filter := TruncateWordsFactory(nil, []core.Value{dynamicValue("max")}) spec.Expect(filter("I think a feature good", params("max", 2)).(string)).ToEqual("I think a feature...") } diff --git a/filters/upcase.go b/filters/upcase.go index ae6d1c2..6906f6a 100644 --- a/filters/upcase.go +++ b/filters/upcase.go @@ -2,13 +2,14 @@ package filters import ( "bytes" + "context" "strings" "github.com/acstech/liquid/core" ) // Creates a upcase filter -func UpcaseFactory(parameters []core.Value) core.Filter { +func UpcaseFactory(ctx context.Context, parameters []core.Value) core.Filter { return Upcase } diff --git a/filters/upcase_test.go b/filters/upcase_test.go index 1dc848e..fb38c59 100644 --- a/filters/upcase_test.go +++ b/filters/upcase_test.go @@ -8,18 +8,18 @@ import ( func TestUpcasesAString(t *testing.T) { spec := gspec.New(t) - filter := UpcaseFactory(nil) + filter := UpcaseFactory(nil, nil) spec.Expect(filter("dbz", nil).(string)).ToEqual("DBZ") } func TestUpcasesBytes(t *testing.T) { spec := gspec.New(t) - filter := UpcaseFactory(nil) + filter := UpcaseFactory(nil, nil) spec.Expect(string(filter([]byte("dbz"), nil).([]byte))).ToEqual("DBZ") } func TestUpcasesPassThroughOnInvalidType(t *testing.T) { spec := gspec.New(t) - filter := UpcaseFactory(nil) + filter := UpcaseFactory(nil, nil) spec.Expect(filter(123, nil).(int)).ToEqual(123) } diff --git a/output_test.go b/output_test.go index 0cf7437..e721f75 100644 --- a/output_test.go +++ b/output_test.go @@ -10,78 +10,78 @@ import ( func TestOutputHandlesEmptyOutput(t *testing.T) { spec := gspec.New(t) - output, err := newOutput(core.NewParser([]byte("{{}}"))) + output, err := newOutput(core.NewParser(nil, []byte("{{}}"))) spec.Expect(output).ToBeNil() spec.Expect(err).ToBeNil() } func TestOutputHandlesSpaceOnlyOutput(t *testing.T) { spec := gspec.New(t) - output, err := newOutput(core.NewParser([]byte("{{ }}"))) + output, err := newOutput(core.NewParser(nil, []byte("{{ }}"))) spec.Expect(output).ToBeNil() spec.Expect(err).ToBeNil() } func TestOutputExtractsASimpleStatic(t *testing.T) { - output, _ := newOutput(core.NewParser([]byte("{{ 'over 9000'}}"))) + output, _ := newOutput(core.NewParser(nil, []byte("{{ 'over 9000'}}"))) assertRender(t, output, nil, "over 9000") } func TestOutputExtractsAComplexStatic(t *testing.T) { - output, _ := newOutput(core.NewParser([]byte("{{'it\\'s over \\9000'}}"))) + output, _ := newOutput(core.NewParser(nil, []byte("{{'it\\'s over \\9000'}}"))) assertRender(t, output, nil, "it's over \\9000") } func TestOutputExtractsAStaticWithAnEndingQuote(t *testing.T) { - output, _ := newOutput(core.NewParser([]byte("{{'it\\''}}"))) + output, _ := newOutput(core.NewParser(nil, []byte("{{'it\\''}}"))) assertRender(t, output, nil, "it'") } func TestOutputExtractionGivesErrorForUnclosedStatic(t *testing.T) { spec := gspec.New(t) - output, err := newOutput(core.NewParser([]byte("{{ 'failure }}"))) + output, err := newOutput(core.NewParser(nil, []byte("{{ 'failure }}"))) spec.Expect(output).ToBeNil() spec.Expect(err.Error()).ToEqual(`Invalid value, a single quote might be missing ("{{ 'failure }}" - line 1)`) } func TestOutputNoFiltersForStatic(t *testing.T) { spec := gspec.New(t) - output, _ := newOutput(core.NewParser([]byte("{{'fun'}}"))) + output, _ := newOutput(core.NewParser(nil, []byte("{{'fun'}}"))) spec.Expect(len(output.(*Output).Filters)).ToEqual(0) } func TestOutputGeneratesErrorOnUnknownFilter(t *testing.T) { spec := gspec.New(t) - _, err := newOutput(core.NewParser([]byte("{{'fun' | unknown }}"))) + _, err := newOutput(core.NewParser(nil, []byte("{{'fun' | unknown }}"))) spec.Expect(err.Error()).ToEqual(`Unknown filter "unknown" ("{{'fun' | unknown }}" - line 1)`) } func TestOutputGeneratesErrorOnInvalidParameter(t *testing.T) { spec := gspec.New(t) - _, err := newOutput(core.NewParser([]byte("{{'fun' | debug: 'missing }}"))) + _, err := newOutput(core.NewParser(nil, []byte("{{'fun' | debug: 'missing }}"))) spec.Expect(err.Error()).ToEqual(`Invalid value, a single quote might be missing ("{{'fun' | debug: 'missing }}" - line 1)`) } func TestOutputWithASingleFilter(t *testing.T) { - output, _ := newOutput(core.NewParser([]byte("{{'fun' | debug }}"))) + output, _ := newOutput(core.NewParser(nil, []byte("{{'fun' | debug }}"))) assertFilters(t, output, "debug(0)") } func TestOutputWithMultipleFilters(t *testing.T) { - output, _ := newOutput(core.NewParser([]byte("{{'fun' | debug | debug}}"))) + output, _ := newOutput(core.NewParser(nil, []byte("{{'fun' | debug | debug}}"))) assertFilters(t, output, "debug(0)", "debug(1)") } func TestOutputWithMultipleFiltersHavingParameters(t *testing.T) { spec := gspec.New(t) - output, err := newOutput(core.NewParser([]byte("{{'fun' | debug:1,2 | debug:'test' | debug : 'test' , 5}}"))) + output, err := newOutput(core.NewParser(nil, []byte("{{'fun' | debug:1,2 | debug:'test' | debug : 'test' , 5}}"))) spec.Expect(err).ToBeNil() assertFilters(t, output, "debug(0, 1, 2)", "debug(1, test)", "debug(2, test, 5)") } func TestOutputWithAnEscapeParameter(t *testing.T) { spec := gspec.New(t) - output, err := newOutput(core.NewParser([]byte("{{'fun' | debug: 'te\\'st'}}"))) + output, err := newOutput(core.NewParser(nil, []byte("{{'fun' | debug: 'te\\'st'}}"))) spec.Expect(err).ToBeNil() assertFilters(t, output, "debug(0, te'st)") } diff --git a/readme.md b/readme.md index 26eaf58..b6c5b17 100644 --- a/readme.md +++ b/readme.md @@ -28,9 +28,9 @@ The following tags are missing: By default the templates are cached in a pretty dumb cache. That is, once in the cache, items stay in the cache (there's no expiry). The cache can be disabled, on a per-template basis, via: ```go -template, _ := liquid.Parse(someByteTemplate, liquid.Configure().Cache(nil)) +template, _ := liquid.Parse(ctx, someByteTemplate, liquid.Configure().Cache(nil)) //OR -template, _ := liquid.ParseString(someStringTemplate, liquid.NoCache) +template, _ := liquid.ParseString(ctx, someStringTemplate, liquid.NoCache) ``` Alternatively, you can provide your own `core.Cache` implementation which diff --git a/tags/comment_test.go b/tags/comment_test.go index 5859e04..9fd1936 100644 --- a/tags/comment_test.go +++ b/tags/comment_test.go @@ -35,5 +35,5 @@ func TestCommentFactoryHandlesUnclosedComment(t *testing.T) { } func newParser(s string) *core.Parser { - return core.NewParser([]byte(s)) + return core.NewParser(nil, []byte(s)) } diff --git a/template.go b/template.go index acc2110..dca13c9 100644 --- a/template.go +++ b/template.go @@ -2,6 +2,7 @@ package liquid import ( + "context" "crypto/sha1" "fmt" "io" @@ -32,13 +33,13 @@ func (t *Template) Name() string { } // Parse the bytes into a Liquid template -func Parse(data []byte, config *core.Configuration) (*Template, error) { +func Parse(ctx context.Context, data []byte, config *core.Configuration) (*Template, error) { if config == nil { config = defaultConfig } cache := config.GetCache() if cache == nil { - return buildTemplate(data, config) + return buildTemplate(ctx, data, config) } hasher := sha1.New() hasher.Write(data) @@ -47,7 +48,7 @@ func Parse(data []byte, config *core.Configuration) (*Template, error) { template := cache.Get(key) if template == nil { var err error - template, err = buildTemplate(data, config) + template, err = buildTemplate(ctx, data, config) if err != nil { return nil, err } @@ -57,17 +58,17 @@ func Parse(data []byte, config *core.Configuration) (*Template, error) { } // Parse the string into a liquid template -func ParseString(data string, config *core.Configuration) (*Template, error) { - return Parse([]byte(data), config) +func ParseString(ctx context.Context, data string, config *core.Configuration) (*Template, error) { + return Parse(ctx, []byte(data), config) } // Turn the contents of the specified file into a liquid template -func ParseFile(path string, config *core.Configuration) (*Template, error) { +func ParseFile(ctx context.Context, path string, config *core.Configuration) (*Template, error) { data, err := ioutil.ReadFile(path) if err != nil { return nil, err } - return Parse(data, config) + return Parse(ctx, data, config) } func (t *Template) Render(writer io.Writer, data map[string]interface{}) { @@ -86,8 +87,8 @@ func (t *Template) Execute(writer io.Writer, data map[string]interface{}) core.E return core.Normal } -func buildTemplate(data []byte, config *core.Configuration) (*Template, error) { - parser := core.NewParser(data) +func buildTemplate(ctx context.Context, data []byte, config *core.Configuration) (*Template, error) { + parser := core.NewParser(ctx, data) template := new(Template) if err := extractTokens(parser, template, config); err != nil { return nil, err diff --git a/template_test.go b/template_test.go index d23788d..b9e9d4a 100644 --- a/template_test.go +++ b/template_test.go @@ -8,7 +8,7 @@ import ( func TestParsesATextOnlyTemplate(t *testing.T) { spec := gspec.New(t) - template, _ := ParseString("it's over 9000", nil) + template, _ := ParseString(nil, "it's over 9000", nil) spec.Expect(len(template.Code)).ToEqual(1) assertLiteral(t, template, 0, "it's over 9000") } @@ -18,7 +18,7 @@ func TestRendersOutputTags(t *testing.T) { "name": "leto atreides", "colors": []string{"brown", "blue"}, } - template, _ := ParseString("hello {{name | capitalize }}, you ranked {{ colors | first }} as your favorite color", nil) + template, _ := ParseString(nil, "hello {{name | capitalize }}, you ranked {{ colors | first }} as your favorite color", nil) assertRender(t, template, d, `hello Leto Atreides, you ranked brown as your favorite color`) } @@ -26,7 +26,7 @@ func TestRendersOutputTagsWithMap(t *testing.T) { d := map[string]interface{}{ "ghola": map[string]interface{}{"incarnations": 67, "master": "LETO"}, } - template, _ := ParseString("duncan, next is {{ ghola.incarnations | plus: 1}}th. Your master is {{ ghola.master | upcase }}", nil) + template, _ := ParseString(nil, "duncan, next is {{ ghola.incarnations | plus: 1}}th. Your master is {{ ghola.master | upcase }}", nil) assertRender(t, template, d, `duncan, next is 68th. Your master is LETO`) } @@ -34,7 +34,7 @@ func TestRendersOutputTagsWithStructPointers(t *testing.T) { d := map[string]interface{}{ "ghola": &Person{"Duncan", 67, &Person{"Leto", 0, nil}}, } - template, _ := ParseString("{{ ghola | downcase }}, next is {{ ghola.incarnations | plus: 1}}th. Your master is {{ ghola.master | upcase }}", nil) + template, _ := ParseString(nil, "{{ ghola | downcase }}, next is {{ ghola.incarnations | plus: 1}}th. Your master is {{ ghola.master | upcase }}", nil) assertRender(t, template, d, `duncan, next is 68th. Your master is LETO`) } @@ -42,7 +42,7 @@ func TestRendersOutputTagsWithStructs(t *testing.T) { d := map[string]interface{}{ "ghola": PersonS{"Duncan", 67}, } - template, _ := ParseString("{{ ghola | downcase }}, next is {{ ghola.incarnations | plus: 1}}th. Your master is {{ ghola.master | upcase }}", nil) + template, _ := ParseString(nil, "{{ ghola | downcase }}, next is {{ ghola.incarnations | plus: 1}}th. Your master is {{ ghola.master | upcase }}", nil) assertRender(t, template, d, `duncan, next is 68th. Your master is {{GHOLA.MASTER}}`) } @@ -50,7 +50,7 @@ func TestRendersCaptureOfSimpleText(t *testing.T) { d := map[string]interface{}{ "ghola": PersonS{"Duncan", 67}, } - template, _ := ParseString("welcome {% capture intro %}Mr.X{% endcapture%}. {{ intro }}", nil) + template, _ := ParseString(nil, "welcome {% capture intro %}Mr.X{% endcapture%}. {{ intro }}", nil) assertRender(t, template, d, `welcome . Mr.X`) } @@ -58,22 +58,22 @@ func TestRendersCaptureWithNestedOutputs(t *testing.T) { d := map[string]interface{}{ "ghola": PersonS{"Duncan", 67}, } - template, _ := ParseString("welcome{% capture name %} {{ ghola | downcase }}{%endcapture%}! {{ name }}", nil) + template, _ := ParseString(nil, "welcome{% capture name %} {{ ghola | downcase }}{%endcapture%}! {{ name }}", nil) assertRender(t, template, d, `welcome! duncan`) } func TestRenderSimpleIfstatement(t *testing.T) { - template, _ := ParseString("A-{% if 2 == 2 %}in if{% endif %}-Z", nil) + template, _ := ParseString(nil, "A-{% if 2 == 2 %}in if{% endif %}-Z", nil) assertRender(t, template, nil, `A-in if-Z`) } func TestRenderSimpleElseIfstatement(t *testing.T) { - template, _ := ParseString("A-{% if 0 == 2 %}in if{% elseif 2 == 2 %}in elseif{% endif %}-Z", nil) + template, _ := ParseString(nil, "A-{% if 0 == 2 %}in if{% elseif 2 == 2 %}in elseif{% endif %}-Z", nil) assertRender(t, template, nil, `A-in elseif-Z`) } func TestRenderSimpleElseStatement(t *testing.T) { - template, _ := ParseString("A-{% if 0 == 2 %}in if{% elseif 2 == 0 %}in elseif{% else %}in else{% endif %}-Z", nil) + template, _ := ParseString(nil, "A-{% if 0 == 2 %}in if{% elseif 2 == 0 %}in elseif{% else %}in else{% endif %}-Z", nil) assertRender(t, template, nil, `A-in else-Z`) } @@ -81,37 +81,37 @@ func TestRenderANilCheckAgainstDynamicValue(t *testing.T) { d := map[string]interface{}{ "ghola": PersonS{"Duncan", 67}, } - template, _ := ParseString("A-{% if false %}in if{% elseif ghola %}in elseif{% else %}in else{% endif %}-Z", nil) + template, _ := ParseString(nil, "A-{% if false %}in if{% elseif ghola %}in elseif{% else %}in else{% endif %}-Z", nil) assertRender(t, template, d, `A-in elseif-Z`) } func TestRendersNothingForAFailedUnless(t *testing.T) { - template, _ := ParseString("A-{% unless true %}in unless{%endunless%}-Z", nil) + template, _ := ParseString(nil, "A-{% unless true %}in unless{%endunless%}-Z", nil) assertRender(t, template, nil, `A--Z`) } func TestRendersAnUnlessTag(t *testing.T) { - template, _ := ParseString("A-{% unless false %}in unless{%endunless%}-Z", nil) + template, _ := ParseString(nil, "A-{% unless false %}in unless{%endunless%}-Z", nil) assertRender(t, template, nil, `A-in unless-Z`) } func TestRendersElseAFailedUnless(t *testing.T) { - template, _ := ParseString("A-{% unless true %}in if{%else%}in else{%endunless%}-Z", nil) + template, _ := ParseString(nil, "A-{% unless true %}in if{%else%}in else{%endunless%}-Z", nil) assertRender(t, template, nil, `A-in else-Z`) } func TestRendersCaseWhen1(t *testing.T) { - template, _ := ParseString("A-{% case 'abc' %}{% when 'abc' %}when1{% when 1 or 123 %}when2{% else %}else{% endcase%}-Z", nil) + template, _ := ParseString(nil, "A-{% case 'abc' %}{% when 'abc' %}when1{% when 1 or 123 %}when2{% else %}else{% endcase%}-Z", nil) assertRender(t, template, nil, `A-when1-Z`) } func TestRendersCaseWhen2(t *testing.T) { - template, _ := ParseString("A-{% case 123 %}{% when 'abc' %}when1{% when 1 or 123 %}when2{% else %}else{% endcase%}-Z", nil) + template, _ := ParseString(nil, "A-{% case 123 %}{% when 'abc' %}when1{% when 1 or 123 %}when2{% else %}else{% endcase%}-Z", nil) assertRender(t, template, nil, `A-when2-Z`) } func TestRendersCaseElse(t *testing.T) { - template, _ := ParseString("A-{% case other %}{% when 'abc' %}when1{% when 1 or 123 %}when2{% else %}else{% endcase%}-Z", nil) + template, _ := ParseString(nil, "A-{% case other %}{% when 'abc' %}when1{% when 1 or 123 %}when2{% else %}else{% endcase%}-Z", nil) assertRender(t, template, nil, `A-else-Z`) } @@ -142,19 +142,19 @@ func TestTemplateRender1(t *testing.T) { "ghola": PersonS{"Duncan", 5}, "colors": []string{"blue", "red", "white"}, } - template, _ := ParseString(complexTemplate, nil) + template, _ := ParseString(nil, complexTemplate, nil) assertRender(t, template, d, "\nOut of\n\n- white \n- red \n- blue \nYour favorite color was blue.\n---\n\nYoungn'\n\n---\n 0 is 68 2 is 110 ") } func BenchmarkParseTemplateWithoutCache(b *testing.B) { for i := 0; i < b.N; i++ { - ParseString(complexTemplate, NoCache) + ParseString(nil, complexTemplate, NoCache) } } func BenchmarkParseTemplateWithCache(b *testing.B) { for i := 0; i < b.N; i++ { - ParseString(complexTemplate, nil) + ParseString(nil, complexTemplate, nil) } } @@ -163,7 +163,7 @@ func BenchmarkRenderTemplate(b *testing.B) { "ghola": PersonS{"Duncan", 5}, "colors": []string{"blue", "red", "white"}, } - template, _ := ParseString(complexTemplate, nil) + template, _ := ParseString(nil, complexTemplate, nil) writer := new(NilWriter) for i := 0; i < b.N; i++ { template.Render(writer, d)