| // Copyright 2026 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package stringintconv_test |
| |
| import ( |
| "fmt" |
| "math" |
| "testing" |
| "unicode/utf8" |
| ) |
| |
| // TestFixPreservesBehavior checks that the expressions produced by |
| // the analyzer's "Convert [a] single rune to [a] string" fixes are |
| // equivalent to the original string(x) conversion. |
| // |
| // We can't write string(x) here (vet would reject it, as would |
| // go1.28), so we use the spec's definition as an oracle: |
| // "Converting a signed or unsigned integer value to a string type |
| // yields a string containing the UTF-8 representation of the |
| // integer. Values outside the range of valid Unicode code points |
| // are converted to "\uFFFD"." |
| func TestFixPreservesBehavior(t *testing.T) { |
| oracle := func(x int64, inRange bool) string { |
| if !inRange || x < 0 || x > utf8.MaxRune { |
| return "\uFFFD" |
| } |
| return string(rune(x)) // (surrogates also yield "\uFFFD") |
| } |
| |
| // Types wider than 32 bits use fmt.Sprintf("%c", x). |
| signed := []int64{ |
| math.MinInt64, math.MinInt32 - 1, math.MinInt32, -1, 0, 'x', |
| 0xD800, utf8.MaxRune, utf8.MaxRune + 1, math.MaxInt32, math.MaxInt32 + 1, |
| 1<<32 + 'x', // truncates to 'x' |
| math.MaxInt64, |
| } |
| for _, x := range signed { |
| if got, want := fmt.Sprintf("%c", x), oracle(x, true); got != want { |
| t.Errorf("int64 %#x: got %q, want %q", x, got, want) |
| } |
| } |
| |
| unsigned := []uint64{ |
| 0, 'x', 0xD800, utf8.MaxRune, utf8.MaxRune + 1, |
| math.MaxInt32, math.MaxInt32 + 1, math.MaxUint32, |
| 1<<32 + 'x', // truncates to 'x' |
| math.MaxUint64, |
| } |
| for _, x := range unsigned { |
| if got, want := fmt.Sprintf("%c", x), oracle(int64(x), x <= math.MaxInt64); got != want { |
| t.Errorf("uint64 %#x: got %q, want %q", x, got, want) |
| } |
| } |
| |
| // uint32 and narrower use string(rune(x)). |
| for _, x := range []uint32{0, 'x', utf8.MaxRune + 1, math.MaxInt32 + 1, 1<<31 + 'x', math.MaxUint32} { |
| if got, want := string(rune(x)), oracle(int64(x), true); got != want { |
| t.Errorf("uint32 %#x: got %q, want %q", x, got, want) |
| } |
| } |
| } |