mirror of https://github.com/databricks/cli.git
Convert between integer and float in normalization (#1371)
## Changes We currently issue a warning if an integer is used where a floating point number is expected. But if they are convertible, we should convert and not issue a warning. This change fixes normalization if they are convertible between each other. We still produce a warning if the type conversion leads to a loss in precision. ## Tests Unit tests pass.
This commit is contained in:
parent
c949655f9f
commit
77d6820075
|
@ -293,6 +293,16 @@ func (n normalizeOptions) normalizeInt(typ reflect.Type, src dyn.Value, path dyn
|
||||||
switch src.Kind() {
|
switch src.Kind() {
|
||||||
case dyn.KindInt:
|
case dyn.KindInt:
|
||||||
out = src.MustInt()
|
out = src.MustInt()
|
||||||
|
case dyn.KindFloat:
|
||||||
|
out = int64(src.MustFloat())
|
||||||
|
if src.MustFloat() != float64(out) {
|
||||||
|
return dyn.InvalidValue, diags.Append(diag.Diagnostic{
|
||||||
|
Severity: diag.Warning,
|
||||||
|
Summary: fmt.Sprintf(`cannot accurately represent "%g" as integer due to precision loss`, src.MustFloat()),
|
||||||
|
Location: src.Location(),
|
||||||
|
Path: path,
|
||||||
|
})
|
||||||
|
}
|
||||||
case dyn.KindString:
|
case dyn.KindString:
|
||||||
var err error
|
var err error
|
||||||
out, err = strconv.ParseInt(src.MustString(), 10, 64)
|
out, err = strconv.ParseInt(src.MustString(), 10, 64)
|
||||||
|
@ -326,6 +336,16 @@ func (n normalizeOptions) normalizeFloat(typ reflect.Type, src dyn.Value, path d
|
||||||
switch src.Kind() {
|
switch src.Kind() {
|
||||||
case dyn.KindFloat:
|
case dyn.KindFloat:
|
||||||
out = src.MustFloat()
|
out = src.MustFloat()
|
||||||
|
case dyn.KindInt:
|
||||||
|
out = float64(src.MustInt())
|
||||||
|
if src.MustInt() != int64(out) {
|
||||||
|
return dyn.InvalidValue, diags.Append(diag.Diagnostic{
|
||||||
|
Severity: diag.Warning,
|
||||||
|
Summary: fmt.Sprintf(`cannot accurately represent "%d" as floating point number due to precision loss`, src.MustInt()),
|
||||||
|
Location: src.Location(),
|
||||||
|
Path: path,
|
||||||
|
})
|
||||||
|
}
|
||||||
case dyn.KindString:
|
case dyn.KindString:
|
||||||
var err error
|
var err error
|
||||||
out, err = strconv.ParseFloat(src.MustString(), 64)
|
out, err = strconv.ParseFloat(src.MustString(), 64)
|
||||||
|
|
|
@ -555,6 +555,27 @@ func TestNormalizeIntNil(t *testing.T) {
|
||||||
}, err[0])
|
}, err[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestNormalizeIntFromFloat(t *testing.T) {
|
||||||
|
var typ int
|
||||||
|
vin := dyn.V(float64(1.0))
|
||||||
|
vout, err := Normalize(&typ, vin)
|
||||||
|
assert.Empty(t, err)
|
||||||
|
assert.Equal(t, dyn.V(int64(1)), vout)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNormalizeIntFromFloatError(t *testing.T) {
|
||||||
|
var typ int
|
||||||
|
vin := dyn.V(1.5)
|
||||||
|
_, err := Normalize(&typ, vin)
|
||||||
|
assert.Len(t, err, 1)
|
||||||
|
assert.Equal(t, diag.Diagnostic{
|
||||||
|
Severity: diag.Warning,
|
||||||
|
Summary: `cannot accurately represent "1.5" as integer due to precision loss`,
|
||||||
|
Location: vin.Location(),
|
||||||
|
Path: dyn.EmptyPath,
|
||||||
|
}, err[0])
|
||||||
|
}
|
||||||
|
|
||||||
func TestNormalizeIntFromString(t *testing.T) {
|
func TestNormalizeIntFromString(t *testing.T) {
|
||||||
var typ int
|
var typ int
|
||||||
vin := dyn.V("123")
|
vin := dyn.V("123")
|
||||||
|
@ -618,6 +639,31 @@ func TestNormalizeFloatNil(t *testing.T) {
|
||||||
}, err[0])
|
}, err[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestNormalizeFloatFromInt(t *testing.T) {
|
||||||
|
var typ float64
|
||||||
|
|
||||||
|
// Maximum safe integer that can be accurately represented as a float.
|
||||||
|
vin := dyn.V(int64(9007199254740992))
|
||||||
|
vout, err := Normalize(&typ, vin)
|
||||||
|
assert.Empty(t, err)
|
||||||
|
assert.Equal(t, dyn.V(float64(9007199254740992)), vout)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNormalizeFloatFromIntError(t *testing.T) {
|
||||||
|
var typ float64
|
||||||
|
|
||||||
|
// Minimum integer that cannot be accurately represented as a float.
|
||||||
|
vin := dyn.V(9007199254740992 + 1)
|
||||||
|
_, err := Normalize(&typ, vin)
|
||||||
|
assert.Len(t, err, 1)
|
||||||
|
assert.Equal(t, diag.Diagnostic{
|
||||||
|
Severity: diag.Warning,
|
||||||
|
Summary: `cannot accurately represent "9007199254740993" as floating point number due to precision loss`,
|
||||||
|
Location: vin.Location(),
|
||||||
|
Path: dyn.EmptyPath,
|
||||||
|
}, err[0])
|
||||||
|
}
|
||||||
|
|
||||||
func TestNormalizeFloatFromString(t *testing.T) {
|
func TestNormalizeFloatFromString(t *testing.T) {
|
||||||
var typ float64
|
var typ float64
|
||||||
vin := dyn.V("1.2")
|
vin := dyn.V("1.2")
|
||||||
|
|
Loading…
Reference in New Issue