diff --git a/pkg/eval/builtin_fn_container_test.go b/pkg/eval/builtin_fn_container_test.go index 55be0a46..f589abdf 100644 --- a/pkg/eval/builtin_fn_container_test.go +++ b/pkg/eval/builtin_fn_container_test.go @@ -1,9 +1,7 @@ package eval_test import ( - "math/big" "testing" - "unsafe" "src.elv.sh/pkg/eval/errs" @@ -43,95 +41,6 @@ func TestMakeMap(t *testing.T) { ) } -var ( - maxInt = 1<<((unsafe.Sizeof(0)*8)-1) - 1 - minInt = -maxInt - 1 - - maxDenseIntInFloat = float64(1 << 53) -) - -func TestRange(t *testing.T) { - Test(t, - // Basic argument sanity checks. - That("range").Throws(ErrorWithType(errs.ArityMismatch{})), - That("range 0 1 2").Throws(ErrorWithType(errs.ArityMismatch{})), - - // Int count up. - That("range 3").Puts(0, 1, 2), - That("range 1 3").Puts(1, 2), - // Int count down. - That("range -1 10 &step=3").Puts(-1, 2, 5, 8), - That("range 3 -3").Puts(3, 2, 1, 0, -1, -2), - // Near maxInt or minInt. - That("range "+args(maxInt-2, maxInt)).Puts(maxInt-2, maxInt-1), - That("range "+args(maxInt, maxInt-2)).Puts(maxInt, maxInt-1), - That("range "+args(minInt, minInt+2)).Puts(minInt, minInt+1), - That("range "+args(minInt+2, minInt)).Puts(minInt+2, minInt+1), - // Invalid step given the "start" and "end" values of the range. - That("range &step=-1 1"). - Throws(errs.BadValue{What: "step", Valid: "positive", Actual: "-1"}), - That("range &step=1 1 0"). - Throws(errs.BadValue{What: "step", Valid: "negative", Actual: "1"}), - thatOutputErrorIsBubbled("range 2"), - - // Big int count up. - That("range "+z+" "+z3).Puts(bigInt(z), bigInt(z1), bigInt(z2)), - That("range "+z+" "+z3+" &step=2").Puts(bigInt(z), bigInt(z2)), - // Big int count down. - That("range "+z3+" "+z).Puts(bigInt(z3), bigInt(z2), bigInt(z1)), - That("range "+z3+" "+z+" &step=-2").Puts(bigInt(z3), bigInt(z1)), - // Invalid big int step. - That("range &step=-"+z+" 10"). - Throws(errs.BadValue{What: "step", Valid: "positive", Actual: "-" + z}), - That("range &step="+z+" 10 0"). - Throws(errs.BadValue{What: "step", Valid: "negative", Actual: z}), - thatOutputErrorIsBubbled("range "+z+" "+z1), - - // Rational count up. - That("range 23/10").Puts(0, 1, 2), - That("range 1/10 23/10").Puts( - big.NewRat(1, 10), big.NewRat(11, 10), big.NewRat(21, 10)), - That("range 23/10 1/10").Puts( - big.NewRat(23, 10), big.NewRat(13, 10), big.NewRat(3, 10)), - That("range 1/10 9/10 &step=3/10").Puts( - big.NewRat(1, 10), big.NewRat(4, 10), big.NewRat(7, 10)), - // Rational count down. - That("range 9/10 0/10 &step=-3/10").Puts( - big.NewRat(9, 10), big.NewRat(6, 10), big.NewRat(3, 10)), - // Invalid rational step. - That("range &step=-1/2 10"). - Throws(errs.BadValue{What: "step", Valid: "positive", Actual: "-1/2"}), - That("range &step=1/2 10 0"). - Throws(errs.BadValue{What: "step", Valid: "negative", Actual: "1/2"}), - thatOutputErrorIsBubbled("range 1/2 3/2"), - - // Float64 count up. - That("range 1.2").Puts(0.0, 1.0), - That("range &step=0.5 1 3").Puts(1.0, 1.5, 2.0, 2.5), - // Float64 count down. - That("range 1.2 -1.2").Puts(1.2, Approximately{F: 0.2}, Approximately{F: -0.8}), - That("range &step=-0.5 3 1").Puts(3.0, 2.5, 2.0, 1.5), - // Near maxDenseIntInFloat. - That("range "+args(maxDenseIntInFloat-2, "+inf")). - Puts(maxDenseIntInFloat-2, maxDenseIntInFloat-1, maxDenseIntInFloat), - That("range "+args(maxDenseIntInFloat, maxDenseIntInFloat-2)). - Puts(maxDenseIntInFloat, maxDenseIntInFloat-1), - // Invalid float64 step. - That("range &step=-0.5 10"). - Throws(errs.BadValue{What: "step", Valid: "positive", Actual: "-0.5"}), - That("range &step=0.5 10 0"). - Throws(errs.BadValue{What: "step", Valid: "negative", Actual: "0.5"}), - thatOutputErrorIsBubbled("range 1.2"), - ) -} - -func TestRepeat(t *testing.T) { - Test(t, - That(`repeat 4 foo`).Puts("foo", "foo", "foo", "foo"), - thatOutputErrorIsBubbled("repeat 1 foo"), - ) -} - func TestAssoc(t *testing.T) { Test(t, That(`put (assoc [0] 0 zero)[0]`).Puts("zero"), diff --git a/pkg/eval/builtin_fn_io_test.go b/pkg/eval/builtin_fn_io_test.go index 2cb49e5a..5014852e 100644 --- a/pkg/eval/builtin_fn_io_test.go +++ b/pkg/eval/builtin_fn_io_test.go @@ -20,6 +20,13 @@ func TestPut(t *testing.T) { ) } +func TestRepeat(t *testing.T) { + Test(t, + That(`repeat 4 foo`).Puts("foo", "foo", "foo", "foo"), + thatOutputErrorIsBubbled("repeat 1 foo"), + ) +} + func TestReadUpto(t *testing.T) { Test(t, That("print abcd | read-upto c").Puts("abc"), diff --git a/pkg/eval/builtin_fn_num_test.go b/pkg/eval/builtin_fn_num_test.go index 11599bb5..1dd90ba9 100644 --- a/pkg/eval/builtin_fn_num_test.go +++ b/pkg/eval/builtin_fn_num_test.go @@ -7,6 +7,7 @@ import ( "strings" "testing" "time" + "unsafe" . "src.elv.sh/pkg/eval" "src.elv.sh/pkg/eval/errs" @@ -258,6 +259,88 @@ func TestRandSeed(t *testing.T) { ) } +var ( + maxInt = 1<<((unsafe.Sizeof(0)*8)-1) - 1 + minInt = -maxInt - 1 + + maxDenseIntInFloat = float64(1 << 53) +) + +func TestRange(t *testing.T) { + Test(t, + // Basic argument sanity checks. + That("range").Throws(ErrorWithType(errs.ArityMismatch{})), + That("range 0 1 2").Throws(ErrorWithType(errs.ArityMismatch{})), + + // Int count up. + That("range 3").Puts(0, 1, 2), + That("range 1 3").Puts(1, 2), + // Int count down. + That("range -1 10 &step=3").Puts(-1, 2, 5, 8), + That("range 3 -3").Puts(3, 2, 1, 0, -1, -2), + // Near maxInt or minInt. + That("range "+args(maxInt-2, maxInt)).Puts(maxInt-2, maxInt-1), + That("range "+args(maxInt, maxInt-2)).Puts(maxInt, maxInt-1), + That("range "+args(minInt, minInt+2)).Puts(minInt, minInt+1), + That("range "+args(minInt+2, minInt)).Puts(minInt+2, minInt+1), + // Invalid step given the "start" and "end" values of the range. + That("range &step=-1 1"). + Throws(errs.BadValue{What: "step", Valid: "positive", Actual: "-1"}), + That("range &step=1 1 0"). + Throws(errs.BadValue{What: "step", Valid: "negative", Actual: "1"}), + thatOutputErrorIsBubbled("range 2"), + + // Big int count up. + That("range "+z+" "+z3).Puts(bigInt(z), bigInt(z1), bigInt(z2)), + That("range "+z+" "+z3+" &step=2").Puts(bigInt(z), bigInt(z2)), + // Big int count down. + That("range "+z3+" "+z).Puts(bigInt(z3), bigInt(z2), bigInt(z1)), + That("range "+z3+" "+z+" &step=-2").Puts(bigInt(z3), bigInt(z1)), + // Invalid big int step. + That("range &step=-"+z+" 10"). + Throws(errs.BadValue{What: "step", Valid: "positive", Actual: "-" + z}), + That("range &step="+z+" 10 0"). + Throws(errs.BadValue{What: "step", Valid: "negative", Actual: z}), + thatOutputErrorIsBubbled("range "+z+" "+z1), + + // Rational count up. + That("range 23/10").Puts(0, 1, 2), + That("range 1/10 23/10").Puts( + big.NewRat(1, 10), big.NewRat(11, 10), big.NewRat(21, 10)), + That("range 23/10 1/10").Puts( + big.NewRat(23, 10), big.NewRat(13, 10), big.NewRat(3, 10)), + That("range 1/10 9/10 &step=3/10").Puts( + big.NewRat(1, 10), big.NewRat(4, 10), big.NewRat(7, 10)), + // Rational count down. + That("range 9/10 0/10 &step=-3/10").Puts( + big.NewRat(9, 10), big.NewRat(6, 10), big.NewRat(3, 10)), + // Invalid rational step. + That("range &step=-1/2 10"). + Throws(errs.BadValue{What: "step", Valid: "positive", Actual: "-1/2"}), + That("range &step=1/2 10 0"). + Throws(errs.BadValue{What: "step", Valid: "negative", Actual: "1/2"}), + thatOutputErrorIsBubbled("range 1/2 3/2"), + + // Float64 count up. + That("range 1.2").Puts(0.0, 1.0), + That("range &step=0.5 1 3").Puts(1.0, 1.5, 2.0, 2.5), + // Float64 count down. + That("range 1.2 -1.2").Puts(1.2, Approximately{F: 0.2}, Approximately{F: -0.8}), + That("range &step=-0.5 3 1").Puts(3.0, 2.5, 2.0, 1.5), + // Near maxDenseIntInFloat. + That("range "+args(maxDenseIntInFloat-2, "+inf")). + Puts(maxDenseIntInFloat-2, maxDenseIntInFloat-1, maxDenseIntInFloat), + That("range "+args(maxDenseIntInFloat, maxDenseIntInFloat-2)). + Puts(maxDenseIntInFloat, maxDenseIntInFloat-1), + // Invalid float64 step. + That("range &step=-0.5 10"). + Throws(errs.BadValue{What: "step", Valid: "positive", Actual: "-0.5"}), + That("range &step=0.5 10 0"). + Throws(errs.BadValue{What: "step", Valid: "negative", Actual: "0.5"}), + thatOutputErrorIsBubbled("range 1.2"), + ) +} + func bigInt(s string) *big.Int { z, ok := new(big.Int).SetString(s, 0) if !ok {