1// Copyright 2017 The Bazel Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package starlark 6 7import ( 8 "fmt" 9 "math" 10 "math/big" 11 "testing" 12) 13 14// TestIntOpts exercises integer arithmetic, especially at the boundaries. 15func TestIntOpts(t *testing.T) { 16 f := MakeInt64 17 left, right := big.NewInt(math.MinInt32), big.NewInt(math.MaxInt32) 18 19 for i, test := range []struct { 20 val Int 21 want string 22 }{ 23 // Add 24 {f(math.MaxInt32).Add(f(1)), "80000000"}, 25 {f(math.MinInt32).Add(f(-1)), "-80000001"}, 26 // Mul 27 {f(math.MaxInt32).Mul(f(math.MaxInt32)), "3fffffff00000001"}, 28 {f(math.MinInt32).Mul(f(math.MinInt32)), "4000000000000000"}, 29 {f(math.MaxUint32).Mul(f(math.MaxUint32)), "fffffffe00000001"}, 30 {f(math.MinInt32).Mul(f(-1)), "80000000"}, 31 // Div 32 {f(math.MinInt32).Div(f(-1)), "80000000"}, 33 {f(1 << 31).Div(f(2)), "40000000"}, 34 // And 35 {f(math.MaxInt32).And(f(math.MaxInt32)), "7fffffff"}, 36 {f(math.MinInt32).And(f(math.MinInt32)), "-80000000"}, 37 {f(1 << 33).And(f(1 << 32)), "0"}, 38 // Mod 39 {f(1 << 32).Mod(f(2)), "0"}, 40 // Or 41 {f(1 << 32).Or(f(0)), "100000000"}, 42 {f(math.MaxInt32).Or(f(0)), "7fffffff"}, 43 {f(math.MaxUint32).Or(f(0)), "ffffffff"}, 44 {f(math.MinInt32).Or(f(math.MinInt32)), "-80000000"}, 45 // Xor 46 {f(math.MinInt32).Xor(f(-1)), "7fffffff"}, 47 // Not 48 {f(math.MinInt32).Not(), "7fffffff"}, 49 {f(math.MaxInt32).Not(), "-80000000"}, 50 // Shift 51 {f(1).Lsh(31), "80000000"}, 52 {f(1).Lsh(32), "100000000"}, 53 {f(math.MaxInt32 + 1).Rsh(1), "40000000"}, 54 {f(math.MinInt32 * 2).Rsh(1), "-80000000"}, 55 } { 56 if got := fmt.Sprintf("%x", test.val); got != test.want { 57 t.Errorf("%d equals %s, want %s", i, got, test.want) 58 } 59 small, big := test.val.get() 60 if small < math.MinInt32 || math.MaxInt32 < small { 61 t.Errorf("expected big, %d %s", i, test.val) 62 } 63 if big == nil { 64 continue 65 } 66 if small != 0 { 67 t.Errorf("expected 0 small, %d %s with %d", i, test.val, small) 68 } 69 if big.Cmp(left) >= 0 && big.Cmp(right) <= 0 { 70 t.Errorf("expected small, %d %s", i, test.val) 71 } 72 } 73} 74 75func TestImmutabilityMakeBigInt(t *testing.T) { 76 // use max int64 for the test 77 expect := int64(^uint64(0) >> 1) 78 79 mutint := big.NewInt(expect) 80 value := MakeBigInt(mutint) 81 mutint.Set(big.NewInt(1)) 82 83 got, _ := value.Int64() 84 if got != expect { 85 t.Errorf("expected %d, got %d", expect, got) 86 } 87} 88 89func TestImmutabilityBigInt(t *testing.T) { 90 // use 1 and max int64 for the test 91 for _, expect := range []int64{1, int64(^uint64(0) >> 1)} { 92 value := MakeBigInt(big.NewInt(expect)) 93 94 bigint := value.BigInt() 95 bigint.Set(big.NewInt(2)) 96 97 got, _ := value.Int64() 98 if got != expect { 99 t.Errorf("expected %d, got %d", expect, got) 100 } 101 } 102} 103