github.com/markusbkk/elvish@v0.0.0-20231204143114-91dc52438621/pkg/eval/vals/num_test.go (about) 1 package vals 2 3 import ( 4 "math" 5 "math/big" 6 "testing" 7 8 "github.com/markusbkk/elvish/pkg/testutil" 9 . "github.com/markusbkk/elvish/pkg/tt" 10 ) 11 12 // Test utilities. 13 14 const ( 15 zeros = "0000000000000000000" 16 // Values that exceed the range of int64, used for testing BigInt. 17 z = "1" + zeros + "0" 18 z1 = "1" + zeros + "1" // z+1 19 z2 = "1" + zeros + "2" // z+2 20 z3 = "1" + zeros + "3" // z+3 21 zz = "2" + zeros + "0" // 2z 22 zz1 = "2" + zeros + "1" // 2z+1 23 zz2 = "2" + zeros + "2" // 2z+2 24 zz3 = "2" + zeros + "3" // 2z+3 25 ) 26 27 func TestParseNum(t *testing.T) { 28 Test(t, Fn("ParseNum", ParseNum), Table{ 29 Args("1").Rets(1), 30 31 Args(z).Rets(bigInt(z)), 32 33 Args("1/2").Rets(big.NewRat(1, 2)), 34 Args("2/1").Rets(2), 35 Args(z + "/1").Rets(bigInt(z)), 36 37 Args("1.0").Rets(1.0), 38 Args("1e-5").Rets(1e-5), 39 40 Args("x").Rets(nil), 41 Args("x/y").Rets(nil), 42 }) 43 } 44 45 func TestUnifyNums(t *testing.T) { 46 Test(t, Fn("UnifyNums", UnifyNums), Table{ 47 Args([]Num{1, 2, 3, 4}, Int). 48 Rets([]int{1, 2, 3, 4}), 49 50 Args([]Num{1, 2, 3, bigInt(z)}, Int). 51 Rets([]*big.Int{big.NewInt(1), big.NewInt(2), big.NewInt(3), bigInt(z)}), 52 53 Args([]Num{1, 2, 3, big.NewRat(1, 2)}, Int). 54 Rets([]*big.Rat{ 55 big.NewRat(1, 1), big.NewRat(2, 1), 56 big.NewRat(3, 1), big.NewRat(1, 2)}), 57 Args([]Num{1, 2, bigInt(z), big.NewRat(1, 2)}, Int). 58 Rets([]*big.Rat{ 59 big.NewRat(1, 1), big.NewRat(2, 1), bigRat(z), big.NewRat(1, 2)}), 60 61 Args([]Num{1, 2, 3, 4.0}, Int). 62 Rets([]float64{1, 2, 3, 4}), 63 Args([]Num{1, 2, big.NewRat(1, 2), 4.0}, Int). 64 Rets([]float64{1, 2, 0.5, 4}), 65 Args([]Num{1, 2, big.NewInt(3), 4.0}, Int). 66 Rets([]float64{1, 2, 3, 4}), 67 Args([]Num{1, 2, bigInt(z), 4.0}, Int). 68 Rets([]float64{1, 2, math.Inf(1), 4}), 69 70 Args([]Num{1, 2, 3, 4}, BigInt). 71 Rets([]*big.Int{ 72 big.NewInt(1), big.NewInt(2), big.NewInt(3), big.NewInt(4)}), 73 }) 74 } 75 76 func TestUnifyNums2(t *testing.T) { 77 Test(t, Fn("UnifyNums2", UnifyNums2), Table{ 78 Args(1, 2, Int).Rets(1, 2), 79 Args(1, bigInt(z), Int).Rets(big.NewInt(1), bigInt(z)), 80 Args(1, big.NewRat(1, 2), Int).Rets(big.NewRat(1, 1), big.NewRat(1, 2)), 81 Args(1, 2.0, Int).Rets(1.0, 2.0), 82 83 Args(1, 2, BigInt).Rets(big.NewInt(1), big.NewInt(2)), 84 }) 85 } 86 87 func TestInvalidNumType(t *testing.T) { 88 Test(t, Fn("Recover", testutil.Recover), Table{ 89 Args(func() { UnifyNums([]Num{int32(0)}, 0) }).Rets("invalid num type int32"), 90 Args(func() { PromoteToBigInt(int32(0)) }).Rets("invalid num type int32"), 91 Args(func() { PromoteToBigRat(int32(0)) }).Rets("invalid num type int32"), 92 Args(func() { ConvertToFloat64(int32(0)) }).Rets("invalid num type int32"), 93 }) 94 } 95 96 func bigInt(s string) *big.Int { 97 z, ok := new(big.Int).SetString(s, 0) 98 if !ok { 99 panic("cannot parse as big int: " + s) 100 } 101 return z 102 } 103 104 func bigRat(s string) *big.Rat { 105 z, ok := new(big.Rat).SetString(s) 106 if !ok { 107 panic("cannot parse as big rat: " + s) 108 } 109 return z 110 }