github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/man/ftoa_test.go (about) 1 package man 2 3 import ( 4 "fmt" 5 "math/rand" 6 "reflect" 7 "regexp" 8 "strconv" 9 "strings" 10 "testing" 11 "testing/quick" 12 ) 13 14 func TestFtoa(t *testing.T) { 15 testList{ 16 {"200", Ftoa(200), "200"}, 17 {"2", Ftoa(2), "2"}, 18 {"2.2", Ftoa(2.2), "2.2"}, 19 {"2.02", Ftoa(2.02), "2.02"}, 20 {"200.02", Ftoa(200.02), "200.02"}, 21 }.validate(t) 22 } 23 24 func TestFtoaWithDigits(t *testing.T) { 25 testList{ 26 {"1.23, 0", FtoaWithDigits(1.23, 0), "1"}, 27 {"1.23, 1", FtoaWithDigits(1.23, 1), "1.2"}, 28 {"1.23, 2", FtoaWithDigits(1.23, 2), "1.23"}, 29 {"1.23, 3", FtoaWithDigits(1.23, 3), "1.23"}, 30 }.validate(t) 31 } 32 33 func TestStripTrailingDigits(t *testing.T) { 34 err := quick.Check(func(s string, digits int) bool { 35 stripped := stripTrailingDigits(s, digits) 36 37 // A stripped string will always be a prefix of its original string 38 if !strings.HasPrefix(s, stripped) { 39 return false 40 } 41 42 if strings.ContainsRune(s, '.') { 43 // If there is a dot, the part on the left of the dot will never change 44 a := strings.Split(s, ".") 45 b := strings.Split(stripped, ".") 46 if a[0] != b[0] { 47 return false 48 } 49 } else { 50 // If there's no dot in the input, the output will always be the same as the input. 51 if stripped != s { 52 return false 53 } 54 } 55 56 return true 57 }, &quick.Config{ 58 MaxCount: 10000, 59 Values: func(v []reflect.Value, r *rand.Rand) { 60 rdigs := func(n int) string { 61 digs := []rune{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'} 62 var rv []rune 63 for i := 0; i < n; i++ { 64 rv = append(rv, digs[r.Intn(len(digs))]) 65 } 66 return string(rv) 67 } 68 69 ls := r.Intn(20) 70 rs := r.Intn(20) 71 jc := "." 72 if rs == 0 { 73 jc = "" 74 } 75 s := rdigs(ls) + jc + rdigs(rs) 76 digits := r.Intn(len(s) + 1) 77 78 v[0] = reflect.ValueOf(s) 79 v[1] = reflect.ValueOf(digits) 80 }, 81 }) 82 if err != nil { 83 t.Error(err) 84 } 85 } 86 87 func BenchmarkFtoaRegexTrailing(b *testing.B) { 88 trailingZerosRegex := regexp.MustCompile(`\.?0+$`) 89 90 b.ResetTimer() 91 for i := 0; i < b.N; i++ { 92 trailingZerosRegex.ReplaceAllString("2.00000", "") 93 trailingZerosRegex.ReplaceAllString("2.0000", "") 94 trailingZerosRegex.ReplaceAllString("2.000", "") 95 trailingZerosRegex.ReplaceAllString("2.00", "") 96 trailingZerosRegex.ReplaceAllString("2.0", "") 97 trailingZerosRegex.ReplaceAllString("2", "") 98 } 99 } 100 101 func BenchmarkFtoaFunc(b *testing.B) { 102 for i := 0; i < b.N; i++ { 103 stripTrailingZeros("2.00000") 104 stripTrailingZeros("2.0000") 105 stripTrailingZeros("2.000") 106 stripTrailingZeros("2.00") 107 stripTrailingZeros("2.0") 108 stripTrailingZeros("2") 109 } 110 } 111 112 func BenchmarkFmtF(b *testing.B) { 113 for i := 0; i < b.N; i++ { 114 _ = fmt.Sprintf("%f", 2.03584) 115 } 116 } 117 118 func BenchmarkStrconvF(b *testing.B) { 119 for i := 0; i < b.N; i++ { 120 strconv.FormatFloat(2.03584, 'f', 6, 64) 121 } 122 }