@@ -662,10 +662,12 @@ mod test {
662
662
use std:: str:: FromStr ;
663
663
664
664
use crate :: format:: {
665
- num_format:: { Case , ForceDecimal } ,
666
- ExtendedBigDecimal ,
665
+ num_format:: { Case , Float , ForceDecimal , UnsignedInt } ,
666
+ ExtendedBigDecimal , Format ,
667
667
} ;
668
668
669
+ use super :: { Formatter , SignedInt } ;
670
+
669
671
#[ test]
670
672
fn unsigned_octal ( ) {
671
673
use super :: { Formatter , NumberAlignment , Prefix , UnsignedInt , UnsignedIntVariant } ;
@@ -1025,4 +1027,166 @@ mod test {
1025
1027
assert_eq ! ( f( 0.00001 ) , "1e-05" ) ;
1026
1028
assert_eq ! ( f( 0.000001 ) , "1e-06" ) ;
1027
1029
}
1030
+
1031
+ // Wrapper function to get a string out of Format.fmt()
1032
+ fn fmt < U , T > ( format : & Format < U , T > , n : T ) -> String
1033
+ where
1034
+ U : Formatter < T > ,
1035
+ {
1036
+ let mut v = Vec :: < u8 > :: new ( ) ;
1037
+ format. fmt ( & mut v, n as T ) . unwrap ( ) ;
1038
+ String :: from_utf8_lossy ( & v) . to_string ( )
1039
+ }
1040
+
1041
+ // Some end-to-end tests, `printf` will also test some of those but it's easier to add more
1042
+ // tests here. We mostly focus on padding, negative numbers, and format specifiers that are not
1043
+ // covered above.
1044
+ #[ test]
1045
+ fn format_signed_int ( ) {
1046
+ let format = Format :: < SignedInt , i64 > :: parse ( "%d" ) . unwrap ( ) ;
1047
+ assert_eq ! ( fmt( & format, 123i64 ) , "123" ) ;
1048
+ assert_eq ! ( fmt( & format, -123i64 ) , "-123" ) ;
1049
+
1050
+ let format = Format :: < SignedInt , i64 > :: parse ( "%i" ) . unwrap ( ) ;
1051
+ assert_eq ! ( fmt( & format, 123i64 ) , "123" ) ;
1052
+ assert_eq ! ( fmt( & format, -123i64 ) , "-123" ) ;
1053
+
1054
+ let format = Format :: < SignedInt , i64 > :: parse ( "%6d" ) . unwrap ( ) ;
1055
+ assert_eq ! ( fmt( & format, 123i64 ) , " 123" ) ;
1056
+ assert_eq ! ( fmt( & format, -123i64 ) , " -123" ) ;
1057
+
1058
+ let format = Format :: < SignedInt , i64 > :: parse ( "%06d" ) . unwrap ( ) ;
1059
+ assert_eq ! ( fmt( & format, 123i64 ) , "000123" ) ;
1060
+ assert_eq ! ( fmt( & format, -123i64 ) , "-00123" ) ;
1061
+
1062
+ let format = Format :: < SignedInt , i64 > :: parse ( "%+6d" ) . unwrap ( ) ;
1063
+ assert_eq ! ( fmt( & format, 123i64 ) , " +123" ) ;
1064
+ assert_eq ! ( fmt( & format, -123i64 ) , " -123" ) ;
1065
+
1066
+ let format = Format :: < SignedInt , i64 > :: parse ( "% d" ) . unwrap ( ) ;
1067
+ assert_eq ! ( fmt( & format, 123i64 ) , " 123" ) ;
1068
+ assert_eq ! ( fmt( & format, -123i64 ) , "-123" ) ;
1069
+ }
1070
+
1071
+ #[ test]
1072
+ #[ ignore = "Need issue #7509 to be fixed" ]
1073
+ fn format_signed_int_precision_zero ( ) {
1074
+ let format = Format :: < SignedInt , i64 > :: parse ( "%.0d" ) . unwrap ( ) ;
1075
+ assert_eq ! ( fmt( & format, 123i64 ) , "123" ) ;
1076
+ // From cppreference.com: "If both the converted value and the precision are 0 the conversion results in no characters."
1077
+ assert_eq ! ( fmt( & format, 0i64 ) , "" ) ;
1078
+ }
1079
+
1080
+ #[ test]
1081
+ fn format_unsigned_int ( ) {
1082
+ let f = |fmt_str : & str , n : u64 | {
1083
+ let format = Format :: < UnsignedInt , u64 > :: parse ( fmt_str) . unwrap ( ) ;
1084
+ fmt ( & format, n)
1085
+ } ;
1086
+
1087
+ assert_eq ! ( f( "%u" , 123u64 ) , "123" ) ;
1088
+ assert_eq ! ( f( "%o" , 123u64 ) , "173" ) ;
1089
+ assert_eq ! ( f( "%#o" , 123u64 ) , "0173" ) ;
1090
+ assert_eq ! ( f( "%6x" , 123u64 ) , " 7b" ) ;
1091
+ assert_eq ! ( f( "%#6x" , 123u64 ) , " 0x7b" ) ;
1092
+ assert_eq ! ( f( "%06X" , 123u64 ) , "00007B" ) ;
1093
+ assert_eq ! ( f( "%+6u" , 123u64 ) , " 123" ) ; // '+' is ignored for unsigned numbers.
1094
+ assert_eq ! ( f( "% u" , 123u64 ) , "123" ) ; // ' ' is ignored for unsigned numbers.
1095
+ assert_eq ! ( f( "%#x" , 0 ) , "0" ) ; // No prefix for 0
1096
+ }
1097
+
1098
+ #[ test]
1099
+ #[ ignore = "Need issues #7509 and #7510 to be fixed" ]
1100
+ fn format_unsigned_int_broken ( ) {
1101
+ // TODO: Merge this back into format_unsigned_int.
1102
+ let f = |fmt_str : & str , n : u64 | {
1103
+ let format = Format :: < UnsignedInt , u64 > :: parse ( fmt_str) . unwrap ( ) ;
1104
+ fmt ( & format, n)
1105
+ } ;
1106
+
1107
+ // #7509
1108
+ assert_eq ! ( f( "%.0o" , 0 ) , "" ) ;
1109
+ assert_eq ! ( f( "%#0o" , 0 ) , "0" ) ; // Already correct, but probably an accident.
1110
+ assert_eq ! ( f( "%.0x" , 0 ) , "" ) ;
1111
+ // #7510
1112
+ assert_eq ! ( f( "%#06x" , 123u64 ) , "0x007b" ) ;
1113
+ }
1114
+
1115
+ #[ test]
1116
+ fn format_float_decimal ( ) {
1117
+ let format = Format :: < Float , & ExtendedBigDecimal > :: parse ( "%f" ) . unwrap ( ) ;
1118
+ assert_eq ! ( fmt( & format, & 123.0 . into( ) ) , "123.000000" ) ;
1119
+ assert_eq ! ( fmt( & format, & ( -123.0 ) . into( ) ) , "-123.000000" ) ;
1120
+ assert_eq ! ( fmt( & format, & 123.15e-8 . into( ) ) , "0.000001" ) ;
1121
+ assert_eq ! ( fmt( & format, & ( -123.15e8 ) . into( ) ) , "-12315000000.000000" ) ;
1122
+ let zero_exp = |exp| ExtendedBigDecimal :: BigDecimal ( BigDecimal :: from_bigint ( 0 . into ( ) , exp) ) ;
1123
+ // We've had issues with "0e10"/"0e-10" formatting, and our current workaround is in Format.fmt function.
1124
+ assert_eq ! ( fmt( & format, & zero_exp( 0 ) ) , "0.000000" ) ;
1125
+ assert_eq ! ( fmt( & format, & zero_exp( 10 ) ) , "0.000000" ) ;
1126
+ assert_eq ! ( fmt( & format, & zero_exp( -10 ) ) , "0.000000" ) ;
1127
+
1128
+ let format = Format :: < Float , & ExtendedBigDecimal > :: parse ( "%12f" ) . unwrap ( ) ;
1129
+ assert_eq ! ( fmt( & format, & 123.0 . into( ) ) , " 123.000000" ) ;
1130
+ assert_eq ! ( fmt( & format, & ( -123.0 ) . into( ) ) , " -123.000000" ) ;
1131
+ assert_eq ! ( fmt( & format, & 123.15e-8 . into( ) ) , " 0.000001" ) ;
1132
+ assert_eq ! ( fmt( & format, & ( -123.15e8 ) . into( ) ) , "-12315000000.000000" ) ;
1133
+ assert_eq ! (
1134
+ fmt( & format, & ( ExtendedBigDecimal :: Infinity ) ) ,
1135
+ " inf"
1136
+ ) ;
1137
+ assert_eq ! (
1138
+ fmt( & format, & ( ExtendedBigDecimal :: MinusInfinity ) ) ,
1139
+ " -inf"
1140
+ ) ;
1141
+ assert_eq ! ( fmt( & format, & ( ExtendedBigDecimal :: Nan ) ) , " nan" ) ;
1142
+ assert_eq ! (
1143
+ fmt( & format, & ( ExtendedBigDecimal :: MinusNan ) ) ,
1144
+ " -nan"
1145
+ ) ;
1146
+
1147
+ let format = Format :: < Float , & ExtendedBigDecimal > :: parse ( "%+#.0f" ) . unwrap ( ) ;
1148
+ assert_eq ! ( fmt( & format, & 123.0 . into( ) ) , "+123." ) ;
1149
+ assert_eq ! ( fmt( & format, & ( -123.0 ) . into( ) ) , "-123." ) ;
1150
+ assert_eq ! ( fmt( & format, & 123.15e-8 . into( ) ) , "+0." ) ;
1151
+ assert_eq ! ( fmt( & format, & ( -123.15e8 ) . into( ) ) , "-12315000000." ) ;
1152
+ assert_eq ! ( fmt( & format, & ( ExtendedBigDecimal :: Infinity ) ) , "+inf" ) ;
1153
+ assert_eq ! ( fmt( & format, & ( ExtendedBigDecimal :: Nan ) ) , "+nan" ) ;
1154
+ assert_eq ! ( fmt( & format, & ( ExtendedBigDecimal :: MinusZero ) ) , "-0." ) ;
1155
+
1156
+ let format = Format :: < Float , & ExtendedBigDecimal > :: parse ( "%#06.0f" ) . unwrap ( ) ;
1157
+ assert_eq ! ( fmt( & format, & 123.0 . into( ) ) , "00123." ) ;
1158
+ assert_eq ! ( fmt( & format, & ( -123.0 ) . into( ) ) , "-0123." ) ;
1159
+ assert_eq ! ( fmt( & format, & 123.15e-8 . into( ) ) , "00000." ) ;
1160
+ assert_eq ! ( fmt( & format, & ( -123.15e8 ) . into( ) ) , "-12315000000." ) ;
1161
+ assert_eq ! ( fmt( & format, & ( ExtendedBigDecimal :: Infinity ) ) , " inf" ) ;
1162
+ assert_eq ! ( fmt( & format, & ( ExtendedBigDecimal :: MinusInfinity ) ) , " -inf" ) ;
1163
+ assert_eq ! ( fmt( & format, & ( ExtendedBigDecimal :: Nan ) ) , " nan" ) ;
1164
+ assert_eq ! ( fmt( & format, & ( ExtendedBigDecimal :: MinusNan ) ) , " -nan" ) ;
1165
+ }
1166
+
1167
+ #[ test]
1168
+ fn format_float_others ( ) {
1169
+ let f = |fmt_str : & str , n : & ExtendedBigDecimal | {
1170
+ let format = Format :: < Float , & ExtendedBigDecimal > :: parse ( fmt_str) . unwrap ( ) ;
1171
+ fmt ( & format, n)
1172
+ } ;
1173
+
1174
+ assert_eq ! ( f( "%e" , & ( -123.0 ) . into( ) ) , "-1.230000e+02" ) ;
1175
+ assert_eq ! ( f( "%#09.e" , & ( -100.0 ) . into( ) ) , "-001.e+02" ) ;
1176
+ assert_eq ! ( f( "%# 9.E" , & 100.0 . into( ) ) , " 1.E+02" ) ;
1177
+ assert_eq ! ( f( "% 12.2A" , & ( -100.0 ) . into( ) ) , " -0xC.80P+3" ) ;
1178
+ }
1179
+
1180
+ #[ test]
1181
+ #[ ignore = "Need issue #7510 to be fixed" ]
1182
+ fn format_float_others_broken ( ) {
1183
+ // TODO: Merge this back into format_float_others.
1184
+ let f = |fmt_str : & str , n : & ExtendedBigDecimal | {
1185
+ let format = Format :: < Float , & ExtendedBigDecimal > :: parse ( fmt_str) . unwrap ( ) ;
1186
+ fmt ( & format, n)
1187
+ } ;
1188
+
1189
+ // #7510
1190
+ assert_eq ! ( f( "%012.2a" , & ( -100.0 ) . into( ) ) , "-0x00c.80p+3" ) ;
1191
+ }
1028
1192
}
0 commit comments