diff options
author | Joe Mooring <joe.mooring@veriphor.com> | 2021-05-27 08:34:49 -0700 |
---|---|---|
committer | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2021-05-28 20:38:45 +0200 |
commit | 01758f99b915f34fe7ca4621e4d1ee09efe385b1 (patch) | |
tree | f5f83d15a90fe261e96feb1c676980dabcca1d8e /tpl | |
parent | 845a7ba4fc30c61842148d67d31d0fa3db8f40b9 (diff) |
Add math.Max and math.Min
Closes #8583
Diffstat (limited to 'tpl')
-rw-r--r-- | tpl/math/init.go | 18 | ||||
-rw-r--r-- | tpl/math/math.go | 37 | ||||
-rw-r--r-- | tpl/math/math_test.go | 78 |
3 files changed, 124 insertions, 9 deletions
diff --git a/tpl/math/init.go b/tpl/math/init.go index ddbd2fc73..4d8a23fde 100644 --- a/tpl/math/init.go +++ b/tpl/math/init.go @@ -64,10 +64,17 @@ func init() { }, ) - ns.AddMethodMapping(ctx.Sqrt, + ns.AddMethodMapping(ctx.Max, nil, [][2]string{ - {"{{math.Sqrt 81}}", "9"}, + {"{{math.Max 1 2 }}", "2"}, + }, + ) + + ns.AddMethodMapping(ctx.Min, + nil, + [][2]string{ + {"{{math.Min 1 2 }}", "1"}, }, ) @@ -106,6 +113,13 @@ func init() { }, ) + ns.AddMethodMapping(ctx.Sqrt, + nil, + [][2]string{ + {"{{math.Sqrt 81}}", "9"}, + }, + ) + ns.AddMethodMapping(ctx.Sub, []string{"sub"}, [][2]string{ diff --git a/tpl/math/math.go b/tpl/math/math.go index badc189c8..d70a3f833 100644 --- a/tpl/math/math.go +++ b/tpl/math/math.go @@ -71,15 +71,28 @@ func (ns *Namespace) Log(a interface{}) (float64, error) { return math.Log(af), nil } -// Sqrt returns the square root of a number. -// NOTE: will return for NaN for negative values of a -func (ns *Namespace) Sqrt(a interface{}) (float64, error) { - af, err := cast.ToFloat64E(a) - if err != nil { - return 0, errors.New("Sqrt operator can't be used with non integer or float value") +// Max returns the greater of two numbers. +func (ns *Namespace) Max(a, b interface{}) (float64, error) { + af, erra := cast.ToFloat64E(a) + bf, errb := cast.ToFloat64E(b) + + if erra != nil || errb != nil { + return 0, errors.New("Max operator can't be used with non-float value") } - return math.Sqrt(af), nil + return math.Max(af, bf), nil +} + +// Min returns the smaller of two numbers. +func (ns *Namespace) Min(a, b interface{}) (float64, error) { + af, erra := cast.ToFloat64E(a) + bf, errb := cast.ToFloat64E(b) + + if erra != nil || errb != nil { + return 0, errors.New("Min operator can't be used with non-float value") + } + + return math.Min(af, bf), nil } // Mod returns a % b. @@ -135,6 +148,16 @@ func (ns *Namespace) Round(x interface{}) (float64, error) { return _round(xf), nil } +// Sqrt returns the square root of a number. +func (ns *Namespace) Sqrt(a interface{}) (float64, error) { + af, err := cast.ToFloat64E(a) + if err != nil { + return 0, errors.New("Sqrt operator can't be used with non integer or float value") + } + + return math.Sqrt(af), nil +} + // Sub subtracts two numbers. func (ns *Namespace) Sub(a, b interface{}) (interface{}, error) { return _math.DoArithmetic(a, b, '-') diff --git a/tpl/math/math_test.go b/tpl/math/math_test.go index da59d7938..45f28e093 100644 --- a/tpl/math/math_test.go +++ b/tpl/math/math_test.go @@ -357,3 +357,81 @@ func TestPow(t *testing.T) { c.Assert(result, qt.Equals, test.expect) } } + +func TestMax(t *testing.T) { + t.Parallel() + c := qt.New(t) + + ns := New() + + for _, test := range []struct { + a interface{} + b interface{} + expect interface{} + }{ + {-1, -1, float64(-1)}, + {-1, 0, float64(0)}, + {-1, 1, float64(1)}, + {0, -1, float64(0)}, + {0, 0, float64(0)}, + {0, 1, float64(1)}, + {1, -1, float64(1)}, + {1, 0, float64(1)}, + {1, 1, float64(1)}, + {1.2, 1.23, float64(1.23)}, + {-1.2, -1.23, float64(-1.2)}, + {0, "a", false}, + {"a", 0, false}, + {"a", "b", false}, + } { + + result, err := ns.Max(test.a, test.b) + + if b, ok := test.expect.(bool); ok && !b { + c.Assert(err, qt.Not(qt.IsNil)) + continue + } + + c.Assert(err, qt.IsNil) + c.Assert(result, qt.Equals, test.expect) + } +} + +func TestMin(t *testing.T) { + t.Parallel() + c := qt.New(t) + + ns := New() + + for _, test := range []struct { + a interface{} + b interface{} + expect interface{} + }{ + {-1, -1, float64(-1)}, + {-1, 0, float64(-1)}, + {-1, 1, float64(-1)}, + {0, -1, float64(-1)}, + {0, 0, float64(0)}, + {0, 1, float64(0)}, + {1, -1, float64(-1)}, + {1, 0, float64(0)}, + {1, 1, float64(1)}, + {1.2, 1.23, float64(1.2)}, + {-1.2, -1.23, float64(-1.23)}, + {0, "a", false}, + {"a", 0, false}, + {"a", "b", false}, + } { + + result, err := ns.Min(test.a, test.b) + + if b, ok := test.expect.(bool); ok && !b { + c.Assert(err, qt.Not(qt.IsNil)) + continue + } + + c.Assert(err, qt.IsNil) + c.Assert(result, qt.Equals, test.expect) + } +} |