From 32e8ffc6fd604e48254aff32c7d3f64d7d4db7cf Mon Sep 17 00:00:00 2001 From: Jan Heuermann Date: Mon, 17 Oct 2022 14:05:22 +0200 Subject: [PATCH] Fix large number processing for unsigned types --- mapper.go | 5 ++++- mapper_test.go | 55 ++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 48 insertions(+), 12 deletions(-) diff --git a/mapper.go b/mapper.go index 6d36b15..65f9814 100644 --- a/mapper.go +++ b/mapper.go @@ -392,9 +392,12 @@ func uintDecoder(bits int) MapperFunc { // nolint: dupl case string: sv = v - case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64: + case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64: sv = fmt.Sprintf("%v", v) + case float32, float64: + sv = fmt.Sprintf("%0.f", v) + default: return fmt.Errorf("expected an int but got %q (%T)", t, t.Value) } diff --git a/mapper_test.go b/mapper_test.go index 804ac39..e86fed7 100644 --- a/mapper_test.go +++ b/mapper_test.go @@ -401,18 +401,51 @@ func TestNumbers(t *testing.T) { } func TestJSONLargeNumber(t *testing.T) { - // https://github.com/alecthomas/kong/pull/334 - const n = 1000000 - var cli struct { - N int64 + // Make sure that large numbers are not internally converted to + // scientific notation when the mapper parses the values. + // (Scientific notation is e.g. `1e+06` instead of `1000000`.) + + // Large signed integers: + { + var cli struct { + N int64 + } + json := `{"n": 1000000}` + r, err := kong.JSON(strings.NewReader(json)) + assert.NoError(t, err) + parser := mustNew(t, &cli, kong.Resolvers(r)) + _, err = parser.Parse([]string{}) + assert.NoError(t, err) + assert.Equal(t, int64(1000000), cli.N) + } + + // Large unsigned integers: + { + var cli struct { + N uint64 + } + json := `{"n": 1000000}` + r, err := kong.JSON(strings.NewReader(json)) + assert.NoError(t, err) + parser := mustNew(t, &cli, kong.Resolvers(r)) + _, err = parser.Parse([]string{}) + assert.NoError(t, err) + assert.Equal(t, uint64(1000000), cli.N) + } + + // Large floats: + { + var cli struct { + N float64 + } + json := `{"n": 1000000.1}` + r, err := kong.JSON(strings.NewReader(json)) + assert.NoError(t, err) + parser := mustNew(t, &cli, kong.Resolvers(r)) + _, err = parser.Parse([]string{}) + assert.NoError(t, err) + assert.Equal(t, float64(1000000.1), cli.N) } - json := fmt.Sprintf(`{"n": %d}`, n) - r, err := kong.JSON(strings.NewReader(json)) - assert.NoError(t, err) - parser := mustNew(t, &cli, kong.Resolvers(r)) - _, err = parser.Parse([]string{}) - assert.NoError(t, err) - assert.Equal(t, n, cli.N) } func TestFileMapper(t *testing.T) {