aboutsummaryrefslogtreecommitdiff
path: root/starlark/int_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'starlark/int_test.go')
-rw-r--r--starlark/int_test.go102
1 files changed, 102 insertions, 0 deletions
diff --git a/starlark/int_test.go b/starlark/int_test.go
new file mode 100644
index 0000000..ad1bf92
--- /dev/null
+++ b/starlark/int_test.go
@@ -0,0 +1,102 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package starlark
+
+import (
+ "fmt"
+ "math"
+ "math/big"
+ "testing"
+)
+
+// TestIntOpts exercises integer arithmetic, especially at the boundaries.
+func TestIntOpts(t *testing.T) {
+ f := MakeInt64
+ left, right := big.NewInt(math.MinInt32), big.NewInt(math.MaxInt32)
+
+ for i, test := range []struct {
+ val Int
+ want string
+ }{
+ // Add
+ {f(math.MaxInt32).Add(f(1)), "80000000"},
+ {f(math.MinInt32).Add(f(-1)), "-80000001"},
+ // Mul
+ {f(math.MaxInt32).Mul(f(math.MaxInt32)), "3fffffff00000001"},
+ {f(math.MinInt32).Mul(f(math.MinInt32)), "4000000000000000"},
+ {f(math.MaxUint32).Mul(f(math.MaxUint32)), "fffffffe00000001"},
+ {f(math.MinInt32).Mul(f(-1)), "80000000"},
+ // Div
+ {f(math.MinInt32).Div(f(-1)), "80000000"},
+ {f(1 << 31).Div(f(2)), "40000000"},
+ // And
+ {f(math.MaxInt32).And(f(math.MaxInt32)), "7fffffff"},
+ {f(math.MinInt32).And(f(math.MinInt32)), "-80000000"},
+ {f(1 << 33).And(f(1 << 32)), "0"},
+ // Mod
+ {f(1 << 32).Mod(f(2)), "0"},
+ // Or
+ {f(1 << 32).Or(f(0)), "100000000"},
+ {f(math.MaxInt32).Or(f(0)), "7fffffff"},
+ {f(math.MaxUint32).Or(f(0)), "ffffffff"},
+ {f(math.MinInt32).Or(f(math.MinInt32)), "-80000000"},
+ // Xor
+ {f(math.MinInt32).Xor(f(-1)), "7fffffff"},
+ // Not
+ {f(math.MinInt32).Not(), "7fffffff"},
+ {f(math.MaxInt32).Not(), "-80000000"},
+ // Shift
+ {f(1).Lsh(31), "80000000"},
+ {f(1).Lsh(32), "100000000"},
+ {f(math.MaxInt32 + 1).Rsh(1), "40000000"},
+ {f(math.MinInt32 * 2).Rsh(1), "-80000000"},
+ } {
+ if got := fmt.Sprintf("%x", test.val); got != test.want {
+ t.Errorf("%d equals %s, want %s", i, got, test.want)
+ }
+ small, big := test.val.get()
+ if small < math.MinInt32 || math.MaxInt32 < small {
+ t.Errorf("expected big, %d %s", i, test.val)
+ }
+ if big == nil {
+ continue
+ }
+ if small != 0 {
+ t.Errorf("expected 0 small, %d %s with %d", i, test.val, small)
+ }
+ if big.Cmp(left) >= 0 && big.Cmp(right) <= 0 {
+ t.Errorf("expected small, %d %s", i, test.val)
+ }
+ }
+}
+
+func TestImmutabilityMakeBigInt(t *testing.T) {
+ // use max int64 for the test
+ expect := int64(^uint64(0) >> 1)
+
+ mutint := big.NewInt(expect)
+ value := MakeBigInt(mutint)
+ mutint.Set(big.NewInt(1))
+
+ got, _ := value.Int64()
+ if got != expect {
+ t.Errorf("expected %d, got %d", expect, got)
+ }
+}
+
+func TestImmutabilityBigInt(t *testing.T) {
+ // use 1 and max int64 for the test
+ for _, expect := range []int64{1, int64(^uint64(0) >> 1)} {
+ value := MakeBigInt(big.NewInt(expect))
+
+ bigint := value.BigInt()
+ bigint.Set(big.NewInt(2))
+
+ got, _ := value.Int64()
+ if got != expect {
+ t.Errorf("expected %d, got %d", expect, got)
+ }
+ }
+}