diff --git a/internal/reflect/number.go b/internal/reflect/number.go index 1960d7e1..3b48d611 100644 --- a/internal/reflect/number.go +++ b/internal/reflect/number.go @@ -11,11 +11,12 @@ import ( "reflect" "strconv" + "github.com/hashicorp/terraform-plugin-go/tftypes" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/attr/xattr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-go/tftypes" ) // Number creates a *big.Float and populates it with the data in `val`. It then @@ -24,9 +25,7 @@ import ( // *big.Int). // // Number will loudly fail when a number cannot be losslessly represented using -// the requested type, unless opts.AllowRoundingNumbers is set to true. This -// setting is mildly dangerous, because Terraform does not like when you round -// things, as a general rule of thumb. +// the requested type. // // It is meant to be called through Into, not directly. func Number(ctx context.Context, typ attr.Type, val tftypes.Value, target reflect.Value, opts Options, path path.Path) (reflect.Value, diag.Diagnostics) { @@ -53,73 +52,50 @@ func Number(ctx context.Context, typ attr.Type, val tftypes.Value, target reflec return reflect.ValueOf(result), diags case reflect.TypeOf(big.NewInt(0)): intResult, acc := result.Int(nil) - if acc != big.Exact && !opts.AllowRoundingNumbers { + if acc != big.Exact { return reflect.ValueOf(result), append(diags, roundingErrorDiag) } return reflect.ValueOf(intResult), diags } + switch target.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: intResult, acc := result.Int64() - if acc != big.Exact && !opts.AllowRoundingNumbers { + if acc != big.Exact { return target, append(diags, roundingErrorDiag) } switch target.Kind() { case reflect.Int: if strconv.IntSize == 32 && intResult > math.MaxInt32 { - if !opts.AllowRoundingNumbers { - return target, append(diags, roundingErrorDiag) - } - intResult = math.MaxInt32 + return target, append(diags, roundingErrorDiag) } if strconv.IntSize == 32 && intResult < math.MinInt32 { - if !opts.AllowRoundingNumbers { - return target, append(diags, roundingErrorDiag) - } - intResult = math.MinInt32 + return target, append(diags, roundingErrorDiag) } return reflect.ValueOf(int(intResult)), diags case reflect.Int8: if intResult > math.MaxInt8 { - if !opts.AllowRoundingNumbers { - return target, append(diags, roundingErrorDiag) - } - intResult = math.MaxInt8 + return target, append(diags, roundingErrorDiag) } if intResult < math.MinInt8 { - if !opts.AllowRoundingNumbers { - return target, append(diags, roundingErrorDiag) - } - intResult = math.MinInt8 + return target, append(diags, roundingErrorDiag) } return reflect.ValueOf(int8(intResult)), diags case reflect.Int16: if intResult > math.MaxInt16 { - if !opts.AllowRoundingNumbers { - return target, append(diags, roundingErrorDiag) - } - intResult = math.MaxInt16 + return target, append(diags, roundingErrorDiag) } if intResult < math.MinInt16 { - if !opts.AllowRoundingNumbers { - return target, append(diags, roundingErrorDiag) - } - intResult = math.MinInt16 + return target, append(diags, roundingErrorDiag) } return reflect.ValueOf(int16(intResult)), diags case reflect.Int32: if intResult > math.MaxInt32 { - if !opts.AllowRoundingNumbers { - return target, append(diags, roundingErrorDiag) - } - intResult = math.MaxInt32 + return target, append(diags, roundingErrorDiag) } if intResult < math.MinInt32 { - if !opts.AllowRoundingNumbers { - return target, append(diags, roundingErrorDiag) - } - intResult = math.MinInt32 + return target, append(diags, roundingErrorDiag) } return reflect.ValueOf(int32(intResult)), diags case reflect.Int64: @@ -128,113 +104,67 @@ func Number(ctx context.Context, typ attr.Type, val tftypes.Value, target reflec case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: uintResult, acc := result.Uint64() - if acc != big.Exact && !opts.AllowRoundingNumbers { + if acc != big.Exact { return target, append(diags, roundingErrorDiag) } switch target.Kind() { case reflect.Uint: if strconv.IntSize == 32 && uintResult > math.MaxUint32 { - if !opts.AllowRoundingNumbers { - return target, append(diags, roundingErrorDiag) - } - uintResult = math.MaxUint32 + return target, append(diags, roundingErrorDiag) } return reflect.ValueOf(uint(uintResult)), diags case reflect.Uint8: if uintResult > math.MaxUint8 { - if !opts.AllowRoundingNumbers { - return target, append(diags, roundingErrorDiag) - } - uintResult = math.MaxUint8 + return target, append(diags, roundingErrorDiag) } return reflect.ValueOf(uint8(uintResult)), diags case reflect.Uint16: if uintResult > math.MaxUint16 { - if !opts.AllowRoundingNumbers { - return target, append(diags, roundingErrorDiag) - } - uintResult = math.MaxUint16 + return target, append(diags, roundingErrorDiag) } return reflect.ValueOf(uint16(uintResult)), diags case reflect.Uint32: if uintResult > math.MaxUint32 { - if !opts.AllowRoundingNumbers { - return target, append(diags, roundingErrorDiag) - } - uintResult = math.MaxUint32 + return target, append(diags, roundingErrorDiag) } return reflect.ValueOf(uint32(uintResult)), diags case reflect.Uint64: return reflect.ValueOf(uintResult), diags } case reflect.Float32: - floatResult, acc := result.Float32() - if acc != big.Exact && !opts.AllowRoundingNumbers { - return target, append(diags, roundingErrorDiag) - } else if acc == big.Above { - floatResult = math.MaxFloat32 - } else if acc == big.Below { - floatResult = math.SmallestNonzeroFloat32 - } else if acc != big.Exact { - err := fmt.Errorf("unsure how to round %s and %f", acc, floatResult) - diags.AddAttributeError( - path, - "Value Conversion Error", - "An unexpected error was encountered trying to convert to number. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), - ) + floatResult, _ := result.Float32() + + bf := big.NewFloat(float64(floatResult)) + + if result.Text('f', -1) != bf.Text('f', -1) { + diags.Append(roundingErrorDiag) + return target, diags } + return reflect.ValueOf(floatResult), diags case reflect.Float64: - floatResult, acc := result.Float64() - if acc != big.Exact && !opts.AllowRoundingNumbers { - return target, append(diags, roundingErrorDiag) - } - if acc == big.Above { - if floatResult == math.Inf(1) || floatResult == math.MaxFloat64 { - floatResult = math.MaxFloat64 - } else if floatResult == 0.0 || floatResult == math.SmallestNonzeroFloat64 { - floatResult = -math.SmallestNonzeroFloat64 - } else { - err := fmt.Errorf("not sure how to round %s and %f", acc, floatResult) - diags.AddAttributeError( - path, - "Value Conversion Error", - "An unexpected error was encountered trying to convert to number. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), - ) - return target, diags - } - } else if acc == big.Below { - if floatResult == math.Inf(-1) || floatResult == -math.MaxFloat64 { - floatResult = -math.MaxFloat64 - } else if floatResult == -0.0 || floatResult == -math.SmallestNonzeroFloat64 { //nolint:staticcheck - floatResult = math.SmallestNonzeroFloat64 - } else { - err := fmt.Errorf("not sure how to round %s and %f", acc, floatResult) - diags.AddAttributeError( - path, - "Value Conversion Error", - "An unexpected error was encountered trying to convert to number. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), - ) - return target, diags - } - } else if acc != big.Exact { - err := fmt.Errorf("not sure how to round %s and %f", acc, floatResult) - diags.AddAttributeError( - path, - "Value Conversion Error", - "An unexpected error was encountered trying to convert to number. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), - ) + floatResult, _ := result.Float64() + + bf := big.NewFloat(floatResult) + + if result.Text('f', -1) != bf.Text('f', -1) { + diags.Append(roundingErrorDiag) + return target, diags } + return reflect.ValueOf(floatResult), diags } + err = fmt.Errorf("cannot convert number to %s", target.Type()) + diags.AddAttributeError( path, "Value Conversion Error", "An unexpected error was encountered trying to convert to number. This is always an error in the provider. Please report the following to the provider developer:\n\n"+err.Error(), ) + return target, diags } diff --git a/internal/reflect/number_test.go b/internal/reflect/number_test.go index 20934799..14373332 100644 --- a/internal/reflect/number_test.go +++ b/internal/reflect/number_test.go @@ -8,17 +8,17 @@ import ( "math" "math/big" "reflect" - "strconv" "testing" "github.com/google/go-cmp/cmp" + "github.com/hashicorp/terraform-plugin-go/tftypes" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" refl "github.com/hashicorp/terraform-plugin-framework/internal/reflect" "github.com/hashicorp/terraform-plugin-framework/internal/testing/testtypes" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/hashicorp/terraform-plugin-go/tftypes" ) var ( @@ -69,27 +69,6 @@ func TestNumber_bigInt(t *testing.T) { } } -func TestNumber_bigIntRounded(t *testing.T) { - t.Parallel() - - var n *big.Int - - result, diags := refl.Number(context.Background(), types.NumberType, tftypes.NewValue(tftypes.Number, 123456.123), reflect.ValueOf(n), refl.Options{ - AllowRoundingNumbers: true, - }, path.Empty()) - if diags.HasError() { - t.Errorf("Unexpected error: %v", diags) - } - reflect.ValueOf(&n).Elem().Set(result) - if n == nil { - t.Error("Expected value, got nil") - return - } - if n.Cmp(big.NewInt(123456)) != 0 { - t.Errorf("Expected %v, got %v", big.NewInt(123456), n) - } -} - func TestNumber_bigIntRoundingError(t *testing.T) { t.Parallel() @@ -124,25 +103,6 @@ func TestNumber_int(t *testing.T) { } } -func TestNumber_intOverflow(t *testing.T) { - t.Parallel() - - var n int - - result, diags := refl.Number(context.Background(), types.NumberType, tftypes.NewValue(tftypes.Number, overflowInt), reflect.ValueOf(n), refl.Options{ - AllowRoundingNumbers: true, - }, path.Empty()) - if diags.HasError() { - t.Errorf("Unexpected error: %v", diags) - } - reflect.ValueOf(&n).Elem().Set(result) - if strconv.IntSize == 64 && n != math.MaxInt64 { - t.Errorf("Expected %v, got %v", math.MaxInt64, n) - } else if strconv.IntSize == 32 && n != math.MaxInt32 { - t.Errorf("Expected %v, got %v", math.MaxInt32, n) - } -} - func TestNumber_intOverflowError(t *testing.T) { t.Parallel() @@ -162,25 +122,6 @@ func TestNumber_intOverflowError(t *testing.T) { } } -func TestNumber_intUnderflow(t *testing.T) { - t.Parallel() - - var n int - - result, diags := refl.Number(context.Background(), types.NumberType, tftypes.NewValue(tftypes.Number, underflowInt), reflect.ValueOf(n), refl.Options{ - AllowRoundingNumbers: true, - }, path.Empty()) - if diags.HasError() { - t.Errorf("Unexpected error: %v", diags) - } - reflect.ValueOf(&n).Elem().Set(result) - if strconv.IntSize == 64 && n != math.MinInt64 { - t.Errorf("Expected %v, got %v", math.MinInt64, n) - } else if strconv.IntSize == 32 && n != math.MinInt32 { - t.Errorf("Expected %v, got %v", math.MinInt32, n) - } -} - func TestNumber_intUnderflowError(t *testing.T) { t.Parallel() @@ -215,23 +156,6 @@ func TestNumber_int8(t *testing.T) { } } -func TestNumber_int8Overflow(t *testing.T) { - t.Parallel() - - var n int8 - - result, diags := refl.Number(context.Background(), types.NumberType, tftypes.NewValue(tftypes.Number, math.MaxInt8+1), reflect.ValueOf(n), refl.Options{ - AllowRoundingNumbers: true, - }, path.Empty()) - if diags.HasError() { - t.Errorf("Unexpected error: %v", diags) - } - reflect.ValueOf(&n).Elem().Set(result) - if n != math.MaxInt8 { - t.Errorf("Expected %v, got %v", math.MaxInt8, n) - } -} - func TestNumber_int8OverflowError(t *testing.T) { t.Parallel() @@ -251,23 +175,6 @@ func TestNumber_int8OverflowError(t *testing.T) { } } -func TestNumber_int8Underflow(t *testing.T) { - t.Parallel() - - var n int8 - - result, diags := refl.Number(context.Background(), types.NumberType, tftypes.NewValue(tftypes.Number, math.MinInt8-1), reflect.ValueOf(n), refl.Options{ - AllowRoundingNumbers: true, - }, path.Empty()) - if diags.HasError() { - t.Errorf("Unexpected error: %v", diags) - } - reflect.ValueOf(&n).Elem().Set(result) - if n != math.MinInt8 { - t.Errorf("Expected %v, got %v", math.MinInt8, n) - } -} - func TestNumber_int8UnderflowError(t *testing.T) { t.Parallel() @@ -291,23 +198,6 @@ func TestNumber_int16(t *testing.T) { t.Parallel() } -func TestNumber_int16Overflow(t *testing.T) { - t.Parallel() - - var n int16 - - result, diags := refl.Number(context.Background(), types.NumberType, tftypes.NewValue(tftypes.Number, math.MaxInt16+1), reflect.ValueOf(n), refl.Options{ - AllowRoundingNumbers: true, - }, path.Empty()) - if diags.HasError() { - t.Errorf("Unexpected error: %v", diags) - } - reflect.ValueOf(&n).Elem().Set(result) - if n != math.MaxInt16 { - t.Errorf("Expected %v, got %v", math.MaxInt16, n) - } -} - func TestNumber_int16OverflowError(t *testing.T) { t.Parallel() @@ -327,23 +217,6 @@ func TestNumber_int16OverflowError(t *testing.T) { } } -func TestNumber_int16Underflow(t *testing.T) { - t.Parallel() - - var n int16 - - result, diags := refl.Number(context.Background(), types.NumberType, tftypes.NewValue(tftypes.Number, math.MinInt16-1), reflect.ValueOf(n), refl.Options{ - AllowRoundingNumbers: true, - }, path.Empty()) - if diags.HasError() { - t.Errorf("Unexpected error: %v", diags) - } - reflect.ValueOf(&n).Elem().Set(result) - if n != math.MinInt16 { - t.Errorf("Expected %v, got %v", math.MinInt16, n) - } -} - func TestNumber_int16UnderflowError(t *testing.T) { t.Parallel() @@ -367,23 +240,6 @@ func TestNumber_int32(t *testing.T) { t.Parallel() } -func TestNumber_int32Overflow(t *testing.T) { - t.Parallel() - - var n int32 - - result, diags := refl.Number(context.Background(), types.NumberType, tftypes.NewValue(tftypes.Number, math.MaxInt32+1), reflect.ValueOf(n), refl.Options{ - AllowRoundingNumbers: true, - }, path.Empty()) - if diags.HasError() { - t.Errorf("Unexpected error: %v", diags) - } - reflect.ValueOf(&n).Elem().Set(result) - if n != math.MaxInt32 { - t.Errorf("Expected %v, got %v", math.MaxInt32, n) - } -} - func TestNumber_int32OverflowError(t *testing.T) { t.Parallel() @@ -403,23 +259,6 @@ func TestNumber_int32OverflowError(t *testing.T) { } } -func TestNumber_int32Underflow(t *testing.T) { - t.Parallel() - - var n int32 - - result, diags := refl.Number(context.Background(), types.NumberType, tftypes.NewValue(tftypes.Number, math.MinInt32-1), reflect.ValueOf(n), refl.Options{ - AllowRoundingNumbers: true, - }, path.Empty()) - if diags.HasError() { - t.Errorf("Unexpected error: %v", diags) - } - reflect.ValueOf(&n).Elem().Set(result) - if n != math.MinInt32 { - t.Errorf("Expected %v, got %v", math.MinInt32, n) - } -} - func TestNumber_int32UnderflowError(t *testing.T) { t.Parallel() @@ -454,23 +293,6 @@ func TestNumber_int64(t *testing.T) { } } -func TestNumber_int64Overflow(t *testing.T) { - t.Parallel() - - var n int64 - - result, diags := refl.Number(context.Background(), types.NumberType, tftypes.NewValue(tftypes.Number, overflowInt), reflect.ValueOf(n), refl.Options{ - AllowRoundingNumbers: true, - }, path.Empty()) - if diags.HasError() { - t.Errorf("Unexpected error: %v", diags) - } - reflect.ValueOf(&n).Elem().Set(result) - if n != math.MaxInt64 { - t.Errorf("Expected %v, got %v", math.MaxInt64, n) - } -} - func TestNumber_int64OverflowError(t *testing.T) { t.Parallel() @@ -490,23 +312,6 @@ func TestNumber_int64OverflowError(t *testing.T) { } } -func TestNumber_int64Underflow(t *testing.T) { - t.Parallel() - - var n int64 - - result, diags := refl.Number(context.Background(), types.NumberType, tftypes.NewValue(tftypes.Number, underflowInt), reflect.ValueOf(n), refl.Options{ - AllowRoundingNumbers: true, - }, path.Empty()) - if diags.HasError() { - t.Errorf("Unexpected error: %v", diags) - } - reflect.ValueOf(&n).Elem().Set(result) - if n != math.MinInt64 { - t.Errorf("Expected %v, got %v", math.MinInt64, n) - } -} - func TestNumber_int64UnderflowError(t *testing.T) { t.Parallel() @@ -541,25 +346,6 @@ func TestNumber_uint(t *testing.T) { } } -func TestNumber_uintOverflow(t *testing.T) { - t.Parallel() - - var n uint - - result, diags := refl.Number(context.Background(), types.NumberType, tftypes.NewValue(tftypes.Number, overflowUint), reflect.ValueOf(n), refl.Options{ - AllowRoundingNumbers: true, - }, path.Empty()) - if diags.HasError() { - t.Errorf("Unexpected error: %v", diags) - } - reflect.ValueOf(&n).Elem().Set(result) - if strconv.IntSize == 64 && n != math.MaxUint64 { - t.Errorf("Expected %v, got %v", uint64(math.MaxUint64), n) - } else if strconv.IntSize == 32 && n != math.MaxUint32 { - t.Errorf("Expected %v, got %v", math.MaxUint32, n) - } -} - func TestNumber_uintOverflowError(t *testing.T) { t.Parallel() @@ -579,23 +365,6 @@ func TestNumber_uintOverflowError(t *testing.T) { } } -func TestNumber_uintUnderflow(t *testing.T) { - t.Parallel() - - var n uint - - result, diags := refl.Number(context.Background(), types.NumberType, tftypes.NewValue(tftypes.Number, -1), reflect.ValueOf(n), refl.Options{ - AllowRoundingNumbers: true, - }, path.Empty()) - if diags.HasError() { - t.Errorf("Unexpected error: %v", diags) - } - reflect.ValueOf(&n).Elem().Set(result) - if n != 0 { - t.Errorf("Expected %v, got %v", 0, n) - } -} - func TestNumber_uintUnderflowError(t *testing.T) { t.Parallel() @@ -630,23 +399,6 @@ func TestNumber_uint8(t *testing.T) { } } -func TestNumber_uint8Overflow(t *testing.T) { - t.Parallel() - - var n uint8 - - result, diags := refl.Number(context.Background(), types.NumberType, tftypes.NewValue(tftypes.Number, math.MaxUint8+1), reflect.ValueOf(n), refl.Options{ - AllowRoundingNumbers: true, - }, path.Empty()) - if diags.HasError() { - t.Errorf("Unexpected error: %v", diags) - } - reflect.ValueOf(&n).Elem().Set(result) - if n != math.MaxUint8 { - t.Errorf("Expected %v, got %v", math.MaxUint8, n) - } -} - func TestNumber_uint8OverflowError(t *testing.T) { t.Parallel() @@ -666,23 +418,6 @@ func TestNumber_uint8OverflowError(t *testing.T) { } } -func TestNumber_uint8Underflow(t *testing.T) { - t.Parallel() - - var n uint8 - - result, diags := refl.Number(context.Background(), types.NumberType, tftypes.NewValue(tftypes.Number, -1), reflect.ValueOf(n), refl.Options{ - AllowRoundingNumbers: true, - }, path.Empty()) - if diags.HasError() { - t.Errorf("Unexpected error: %v", diags) - } - reflect.ValueOf(&n).Elem().Set(result) - if n != 0 { - t.Errorf("Expected %v, got %v", 0, n) - } -} - func TestNumber_uint8UnderflowError(t *testing.T) { t.Parallel() @@ -706,23 +441,6 @@ func TestNumber_uint16(t *testing.T) { t.Parallel() } -func TestNumber_uint16Overflow(t *testing.T) { - t.Parallel() - - var n uint16 - - result, diags := refl.Number(context.Background(), types.NumberType, tftypes.NewValue(tftypes.Number, math.MaxUint16+1), reflect.ValueOf(n), refl.Options{ - AllowRoundingNumbers: true, - }, path.Empty()) - if diags.HasError() { - t.Errorf("Unexpected error: %v", diags) - } - reflect.ValueOf(&n).Elem().Set(result) - if n != math.MaxUint16 { - t.Errorf("Expected %v, got %v", math.MaxUint16, n) - } -} - func TestNumber_uint16OverflowError(t *testing.T) { t.Parallel() @@ -742,23 +460,6 @@ func TestNumber_uint16OverflowError(t *testing.T) { } } -func TestNumber_uint16Underflow(t *testing.T) { - t.Parallel() - - var n uint16 - - result, diags := refl.Number(context.Background(), types.NumberType, tftypes.NewValue(tftypes.Number, -1), reflect.ValueOf(n), refl.Options{ - AllowRoundingNumbers: true, - }, path.Empty()) - if diags.HasError() { - t.Errorf("Unexpected error: %v", diags) - } - reflect.ValueOf(&n).Elem().Set(result) - if n != 0 { - t.Errorf("Expected %v, got %v", 0, n) - } -} - func TestNumber_uint16UnderflowError(t *testing.T) { t.Parallel() @@ -782,23 +483,6 @@ func TestNumber_uint32(t *testing.T) { t.Parallel() } -func TestNumber_uint32Overflow(t *testing.T) { - t.Parallel() - - var n uint32 - - result, diags := refl.Number(context.Background(), types.NumberType, tftypes.NewValue(tftypes.Number, math.MaxUint32+1), reflect.ValueOf(n), refl.Options{ - AllowRoundingNumbers: true, - }, path.Empty()) - if diags.HasError() { - t.Errorf("Unexpected error: %v", diags) - } - reflect.ValueOf(&n).Elem().Set(result) - if n != math.MaxUint32 { - t.Errorf("Expected %v, got %v", math.MaxUint32, n) - } -} - func TestNumber_uint32OverflowError(t *testing.T) { t.Parallel() @@ -818,23 +502,6 @@ func TestNumber_uint32OverflowError(t *testing.T) { } } -func TestNumber_uint32Underflow(t *testing.T) { - t.Parallel() - - var n uint32 - - result, diags := refl.Number(context.Background(), types.NumberType, tftypes.NewValue(tftypes.Number, -1), reflect.ValueOf(n), refl.Options{ - AllowRoundingNumbers: true, - }, path.Empty()) - if diags.HasError() { - t.Errorf("Unexpected error: %v", diags) - } - reflect.ValueOf(&n).Elem().Set(result) - if n != 0 { - t.Errorf("Expected %v, got %v", 0, n) - } -} - func TestNumber_uint32UnderflowError(t *testing.T) { t.Parallel() @@ -869,23 +536,6 @@ func TestNumber_uint64(t *testing.T) { } } -func TestNumber_uint64Overflow(t *testing.T) { - t.Parallel() - - var n uint64 - - result, diags := refl.Number(context.Background(), types.NumberType, tftypes.NewValue(tftypes.Number, overflowUint), reflect.ValueOf(n), refl.Options{ - AllowRoundingNumbers: true, - }, path.Empty()) - if diags.HasError() { - t.Errorf("Unexpected error: %v", diags) - } - reflect.ValueOf(&n).Elem().Set(result) - if n != math.MaxUint64 { - t.Errorf("Expected %v, got %v", uint64(math.MaxUint64), n) - } -} - func TestNumber_uint64OverflowError(t *testing.T) { t.Parallel() @@ -905,23 +555,6 @@ func TestNumber_uint64OverflowError(t *testing.T) { } } -func TestNumber_uint64Underflow(t *testing.T) { - t.Parallel() - - var n uint64 - - result, diags := refl.Number(context.Background(), types.NumberType, tftypes.NewValue(tftypes.Number, -1), reflect.ValueOf(n), refl.Options{ - AllowRoundingNumbers: true, - }, path.Empty()) - if diags.HasError() { - t.Errorf("Unexpected error: %v", diags) - } - reflect.ValueOf(&n).Elem().Set(result) - if n != 0 { - t.Errorf("Expected %v, got %v", 0, n) - } -} - func TestNumber_uint64UnderflowError(t *testing.T) { t.Parallel() @@ -945,23 +578,6 @@ func TestNumber_float32(t *testing.T) { t.Parallel() } -func TestNumber_float32Overflow(t *testing.T) { - t.Parallel() - - var n float32 - - result, diags := refl.Number(context.Background(), types.NumberType, tftypes.NewValue(tftypes.Number, math.MaxFloat64), reflect.ValueOf(n), refl.Options{ - AllowRoundingNumbers: true, - }, path.Empty()) - if diags.HasError() { - t.Errorf("Unexpected error: %v", diags) - } - reflect.ValueOf(&n).Elem().Set(result) - if n != math.MaxFloat32 { - t.Errorf("Expected %v, got %v", math.MaxFloat32, n) - } -} - func TestNumber_float32OverflowError(t *testing.T) { t.Parallel() @@ -981,23 +597,6 @@ func TestNumber_float32OverflowError(t *testing.T) { } } -func TestNumber_float32Underflow(t *testing.T) { - t.Parallel() - - var n float32 - - result, diags := refl.Number(context.Background(), types.NumberType, tftypes.NewValue(tftypes.Number, math.SmallestNonzeroFloat64), reflect.ValueOf(n), refl.Options{ - AllowRoundingNumbers: true, - }, path.Empty()) - if diags.HasError() { - t.Errorf("Unexpected error: %v", diags) - } - reflect.ValueOf(&n).Elem().Set(result) - if n != math.SmallestNonzeroFloat32 { - t.Errorf("Expected %v, got %v", math.SmallestNonzeroFloat32, n) - } -} - func TestNumber_float32UnderflowError(t *testing.T) { t.Parallel() @@ -1032,23 +631,6 @@ func TestNumber_float64(t *testing.T) { } } -func TestNumber_float64Overflow(t *testing.T) { - t.Parallel() - - var n float64 - - result, diags := refl.Number(context.Background(), types.NumberType, tftypes.NewValue(tftypes.Number, overflowFloat), reflect.ValueOf(n), refl.Options{ - AllowRoundingNumbers: true, - }, path.Empty()) - if diags.HasError() { - t.Errorf("Unexpected error: %v", diags) - } - reflect.ValueOf(&n).Elem().Set(result) - if n != math.MaxFloat64 { - t.Errorf("Expected %v, got %v", math.MaxFloat64, n) - } -} - func TestNumber_float64OverflowError(t *testing.T) { t.Parallel() @@ -1068,23 +650,6 @@ func TestNumber_float64OverflowError(t *testing.T) { } } -func TestNumber_float64OverflowNegative(t *testing.T) { - t.Parallel() - - var n float64 - - result, diags := refl.Number(context.Background(), types.NumberType, tftypes.NewValue(tftypes.Number, overflowNegativeFloat), reflect.ValueOf(n), refl.Options{ - AllowRoundingNumbers: true, - }, path.Empty()) - if diags.HasError() { - t.Errorf("Unexpected error: %v", diags) - } - reflect.ValueOf(&n).Elem().Set(result) - if n != -math.MaxFloat64 { - t.Errorf("Expected %v, got %v", -math.MaxFloat64, n) - } -} - func TestNumber_float64OverflowNegativeError(t *testing.T) { t.Parallel() @@ -1104,23 +669,6 @@ func TestNumber_float64OverflowNegativeError(t *testing.T) { } } -func TestNumber_float64Underflow(t *testing.T) { - t.Parallel() - - var n float64 - - result, diags := refl.Number(context.Background(), types.NumberType, tftypes.NewValue(tftypes.Number, underflowFloat), reflect.ValueOf(n), refl.Options{ - AllowRoundingNumbers: true, - }, path.Empty()) - if diags.HasError() { - t.Errorf("Unexpected error: %v", diags) - } - reflect.ValueOf(&n).Elem().Set(result) - if n != math.SmallestNonzeroFloat64 { - t.Errorf("Expected %v, got %v", math.SmallestNonzeroFloat64, n) - } -} - func TestNumber_float64UnderflowError(t *testing.T) { t.Parallel() @@ -1140,23 +688,6 @@ func TestNumber_float64UnderflowError(t *testing.T) { } } -func TestNumber_float64UnderflowNegative(t *testing.T) { - t.Parallel() - - var n float64 - - result, diags := refl.Number(context.Background(), types.NumberType, tftypes.NewValue(tftypes.Number, underflowNegativeFloat), reflect.ValueOf(n), refl.Options{ - AllowRoundingNumbers: true, - }, path.Empty()) - if diags.HasError() { - t.Errorf("Unexpected error: %v", diags) - } - reflect.ValueOf(&n).Elem().Set(result) - if n != -math.SmallestNonzeroFloat64 { - t.Errorf("Expected %v, got %v", -math.SmallestNonzeroFloat64, n) - } -} - func TestNumber_float64UnderflowNegativeError(t *testing.T) { t.Parallel() diff --git a/internal/reflect/options.go b/internal/reflect/options.go index 96d29fdb..a59abd97 100644 --- a/internal/reflect/options.go +++ b/internal/reflect/options.go @@ -15,9 +15,4 @@ type Options struct { // translated into empty values without provider interaction, or if // they must be explicitly handled. UnhandledUnknownAsEmpty bool - - // AllowRoundingNumbers silently rounds numbers that don't fit - // perfectly in the types they're being stored in, rather than - // returning errors. Numbers will always be rounded towards 0. - AllowRoundingNumbers bool }