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