diff options
Diffstat (limited to 'funcs')
| -rw-r--r-- | funcs/math.go | 72 | ||||
| -rw-r--r-- | funcs/math_test.go | 61 |
2 files changed, 133 insertions, 0 deletions
diff --git a/funcs/math.go b/funcs/math.go new file mode 100644 index 00000000..e26e42dc --- /dev/null +++ b/funcs/math.go @@ -0,0 +1,72 @@ +package funcs + +import ( + "fmt" + gmath "math" + "sync" + + "github.com/hairyhenderson/gomplate/conv" + + "github.com/hairyhenderson/gomplate/math" +) + +var ( + mathNS *MathFuncs + mathNSInit sync.Once +) + +// MathNS - the math namespace +func MathNS() *MathFuncs { + mathNSInit.Do(func() { mathNS = &MathFuncs{} }) + return mathNS +} + +// AddMathFuncs - +func AddMathFuncs(f map[string]interface{}) { + f["math"] = MathNS + + f["add"] = MathNS().Add + f["sub"] = MathNS().Sub + f["mul"] = MathNS().Mul + f["div"] = MathNS().Div + f["rem"] = MathNS().Rem + f["pow"] = MathNS().Pow +} + +// MathFuncs - +type MathFuncs struct{} + +// Add - +func (f *MathFuncs) Add(n ...interface{}) int64 { + return math.AddInt(conv.ToInt64s(n...)...) +} + +// Mul - +func (f *MathFuncs) Mul(n ...interface{}) int64 { + return math.MulInt(conv.ToInt64s(n...)...) +} + +// Sub - +func (f *MathFuncs) Sub(a, b interface{}) int64 { + return conv.ToInt64(a) - conv.ToInt64(b) +} + +// Div - +func (f *MathFuncs) Div(a, b interface{}) (int64, error) { + divisor := conv.ToInt64(a) + dividend := conv.ToInt64(b) + if dividend == 0 { + return 0, fmt.Errorf("Error: division by 0") + } + return divisor / dividend, nil +} + +// Rem - +func (f *MathFuncs) Rem(a, b interface{}) int64 { + return conv.ToInt64(a) % conv.ToInt64(b) +} + +// Pow - +func (f *MathFuncs) Pow(a, b interface{}) int64 { + return conv.ToInt64(gmath.Pow(conv.ToFloat64(a), conv.ToFloat64(b))) +} diff --git a/funcs/math_test.go b/funcs/math_test.go new file mode 100644 index 00000000..cb0a0922 --- /dev/null +++ b/funcs/math_test.go @@ -0,0 +1,61 @@ +package funcs + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestAdd(t *testing.T) { + m := MathNS() + assert.Equal(t, int64(12), m.Add(1, 1, 2, 3, 5)) + assert.Equal(t, int64(2), m.Add(1, 1)) + assert.Equal(t, int64(1), m.Add(1)) + assert.Equal(t, int64(0), m.Add(-5, 5)) +} + +func TestMul(t *testing.T) { + m := MathNS() + assert.Equal(t, int64(30), m.Mul(1, 1, 2, 3, 5)) + assert.Equal(t, int64(1), m.Mul(1, 1)) + assert.Equal(t, int64(1), m.Mul(1)) + assert.Equal(t, int64(-25), m.Mul("-5", 5)) + assert.Equal(t, int64(28), m.Mul(14, "2")) +} + +func TestSub(t *testing.T) { + m := MathNS() + assert.Equal(t, int64(0), m.Sub(1, 1)) + assert.Equal(t, int64(-10), m.Sub(-5, 5)) + assert.Equal(t, int64(-41), m.Sub(true, "42")) +} + +func mustDiv(a, b interface{}) int64 { + m := MathNS() + r, err := m.Div(a, b) + if err != nil { + return -1 + } + return r +} + +func TestDiv(t *testing.T) { + m := MathNS() + _, err := m.Div(1, 0) + assert.Error(t, err) + assert.Equal(t, int64(1), mustDiv(1, 1)) + assert.Equal(t, int64(-1), mustDiv(-5, 5)) + assert.Equal(t, int64(0), mustDiv(true, "42")) +} + +func TestRem(t *testing.T) { + m := MathNS() + assert.Equal(t, int64(0), m.Rem(1, 1)) + assert.Equal(t, int64(2), m.Rem(5, 3.0)) + // assert.Equal(t, int64(1), m.Mod(true, "42")) +} + +func TestPow(t *testing.T) { + m := MathNS() + assert.Equal(t, int64(4), m.Pow(2, "2")) +} |
