diff options
author | Artem Sidorenko <artem@posteo.de> | 2017-07-03 00:20:49 +0200 |
---|---|---|
committer | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2017-07-03 00:20:48 +0200 |
commit | 34c566773a1364077e1397daece85b22948dc721 (patch) | |
tree | f38c7405225de9b4f861450ec3c69003746d94d1 /tpl | |
parent | 41805dca9e40e9b0952e04d06074e6fc91140495 (diff) |
tpl/math: Add log function
It might be very useful for building tag clouds.
Diffstat (limited to 'tpl')
-rw-r--r-- | tpl/math/init.go | 7 | ||||
-rw-r--r-- | tpl/math/math.go | 13 | ||||
-rw-r--r-- | tpl/math/math_test.go | 37 |
3 files changed, 57 insertions, 0 deletions
diff --git a/tpl/math/init.go b/tpl/math/init.go index 3faf0e3a6..4d740c537 100644 --- a/tpl/math/init.go +++ b/tpl/math/init.go @@ -43,6 +43,13 @@ func init() { }, ) + ns.AddMethodMapping(ctx.Log, + nil, + [][2]string{ + {"{{math.Log 1}}", "0"}, + }, + ) + ns.AddMethodMapping(ctx.Mod, []string{"mod"}, [][2]string{ diff --git a/tpl/math/math.go b/tpl/math/math.go index 57e7baf12..303f029af 100644 --- a/tpl/math/math.go +++ b/tpl/math/math.go @@ -15,7 +15,10 @@ package math import ( "errors" + "math" "reflect" + + "github.com/spf13/cast" ) // New returns a new instance of the math-namespaced template functions. @@ -34,6 +37,16 @@ func (ns *Namespace) Div(a, b interface{}) (interface{}, error) { return DoArithmetic(a, b, '/') } +func (ns *Namespace) Log(a interface{}) (float64, error) { + af, err := cast.ToFloat64E(a) + + if err != nil { + return 0, errors.New("Log operator can't be used with non integer or float value") + } + + return math.Log(af), nil +} + // Mod returns a % b. func (ns *Namespace) Mod(a, b interface{}) (int64, error) { av := reflect.ValueOf(a) diff --git a/tpl/math/math_test.go b/tpl/math/math_test.go index 40bed5539..49ac053fd 100644 --- a/tpl/math/math_test.go +++ b/tpl/math/math_test.go @@ -15,6 +15,7 @@ package math import ( "fmt" + "math" "testing" "github.com/stretchr/testify/assert" @@ -142,6 +143,42 @@ func TestDoArithmetic(t *testing.T) { } } +func TestLog(t *testing.T) { + t.Parallel() + + ns := New() + + for i, test := range []struct { + a interface{} + expect interface{} + }{ + {1, float64(0)}, + {3, float64(1.0986)}, + {0, float64(math.Inf(-1))}, + {1.0, float64(0)}, + {3.1, float64(1.1314)}, + {"abc", false}, + } { + errMsg := fmt.Sprintf("[%d] %v", i, test) + + result, err := ns.Log(test.a) + + if b, ok := test.expect.(bool); ok && !b { + require.Error(t, err, errMsg) + continue + } + + // we compare only 4 digits behind point if its a real float + // otherwise we usually get different float values on the last positions + if result != math.Inf(-1) { + result = float64(int(result*10000)) / 10000 + } + + require.NoError(t, err, errMsg) + assert.Equal(t, test.expect, result, errMsg) + } +} + func TestMod(t *testing.T) { t.Parallel() |