@@ -56,11 +56,18 @@ async fn test_number_format_integer_factories() -> Result<()> {
5656 let text: ClassInstanceRef < String > = jvm. invoke_virtual ( & integer, "format" , "(D)Ljava/lang/String;" , ( 1234.6f64 , ) ) . await ?;
5757 assert_eq ! ( JavaLangString :: to_rust_string( & jvm, & text) . await ?, "1,235" ) ;
5858
59- let source = JavaLangString :: from_rust_string ( & jvm, "1,234.5" ) . await ?;
59+ let source = JavaLangString :: from_rust_string ( & jvm, "1,234.5rest" ) . await ?;
60+ let position: ClassInstanceRef < ParsePosition > = jvm. new_class ( "java/text/ParsePosition" , "(I)V" , ( 0 , ) ) . await ?. into ( ) ;
6061 let parsed: ClassInstanceRef < Long > = jvm
61- . invoke_virtual ( & integer, "parse" , "(Ljava/lang/String;)Ljava/lang/Number;" , ( source, ) )
62+ . invoke_virtual (
63+ & integer,
64+ "parse" ,
65+ "(Ljava/lang/String;Ljava/text/ParsePosition;)Ljava/lang/Number;" ,
66+ ( source, position. clone ( ) ) ,
67+ )
6268 . await ?;
6369 assert_eq ! ( jvm. invoke_virtual:: <_, i64 >( & parsed, "longValue" , "()J" , ( ) ) . await ?, 1234 ) ;
70+ assert_eq ! ( jvm. invoke_virtual:: <_, i32 >( & position, "getIndex" , "()I" , ( ) ) . await ?, 5 ) ;
6471
6572 Ok ( ( ) )
6673}
@@ -201,3 +208,92 @@ async fn test_decimal_format_quoted_affixes_and_integer_boundaries() -> Result<(
201208
202209 Ok ( ( ) )
203210}
211+
212+ #[ tokio:: test]
213+ async fn test_decimal_format_uses_utf16_positions_and_negative_suffixes ( ) -> Result < ( ) > {
214+ let jvm = test_jvm ( ) . await ?;
215+ let pattern = JavaLangString :: from_rust_string ( & jvm, "'\u{1f600} '0.0" ) . await ?;
216+ let format: ClassInstanceRef < DecimalFormat > = jvm
217+ . new_class ( "java/text/DecimalFormat" , "(Ljava/lang/String;)V" , ( pattern, ) )
218+ . await ?
219+ . into ( ) ;
220+
221+ let buffer: ClassInstanceRef < StringBuffer > = jvm. new_class ( "java/lang/StringBuffer" , "()V" , ( ) ) . await ?. into ( ) ;
222+ let integer_position: ClassInstanceRef < FieldPosition > = jvm. new_class ( "java/text/FieldPosition" , "(I)V" , ( 0 , ) ) . await ?. into ( ) ;
223+ let _: ClassInstanceRef < StringBuffer > = jvm
224+ . invoke_virtual (
225+ & format,
226+ "format" ,
227+ "(DLjava/lang/StringBuffer;Ljava/text/FieldPosition;)Ljava/lang/StringBuffer;" ,
228+ ( 12.3f64 , buffer, integer_position. clone ( ) ) ,
229+ )
230+ . await ?;
231+ assert_eq ! ( jvm. invoke_virtual:: <_, i32 >( & integer_position, "getBeginIndex" , "()I" , ( ) ) . await ?, 2 ) ;
232+ assert_eq ! ( jvm. invoke_virtual:: <_, i32 >( & integer_position, "getEndIndex" , "()I" , ( ) ) . await ?, 4 ) ;
233+
234+ let buffer: ClassInstanceRef < StringBuffer > = jvm. new_class ( "java/lang/StringBuffer" , "()V" , ( ) ) . await ?. into ( ) ;
235+ let fraction_position: ClassInstanceRef < FieldPosition > = jvm. new_class ( "java/text/FieldPosition" , "(I)V" , ( 1 , ) ) . await ?. into ( ) ;
236+ let _: ClassInstanceRef < StringBuffer > = jvm
237+ . invoke_virtual (
238+ & format,
239+ "format" ,
240+ "(DLjava/lang/StringBuffer;Ljava/text/FieldPosition;)Ljava/lang/StringBuffer;" ,
241+ ( 12.3f64 , buffer, fraction_position. clone ( ) ) ,
242+ )
243+ . await ?;
244+ assert_eq ! ( jvm. invoke_virtual:: <_, i32 >( & fraction_position, "getBeginIndex" , "()I" , ( ) ) . await ?, 5 ) ;
245+ assert_eq ! ( jvm. invoke_virtual:: <_, i32 >( & fraction_position, "getEndIndex" , "()I" , ( ) ) . await ?, 6 ) ;
246+
247+ let plain_pattern = JavaLangString :: from_rust_string ( & jvm, "0" ) . await ?;
248+ let _: ( ) = jvm
249+ . invoke_virtual ( & format, "applyPattern" , "(Ljava/lang/String;)V" , ( plain_pattern, ) )
250+ . await ?;
251+ let source = JavaLangString :: from_rust_string ( & jvm, "\u{1f600} 12" ) . await ?;
252+ let position: ClassInstanceRef < ParsePosition > = jvm. new_class ( "java/text/ParsePosition" , "(I)V" , ( 2 , ) ) . await ?. into ( ) ;
253+ let parsed: ClassInstanceRef < Long > = jvm
254+ . invoke_virtual (
255+ & format,
256+ "parse" ,
257+ "(Ljava/lang/String;Ljava/text/ParsePosition;)Ljava/lang/Number;" ,
258+ ( source, position. clone ( ) ) ,
259+ )
260+ . await ?;
261+ assert_eq ! ( jvm. invoke_virtual:: <_, i64 >( & parsed, "longValue" , "()J" , ( ) ) . await ?, 12 ) ;
262+ assert_eq ! ( jvm. invoke_virtual:: <_, i32 >( & position, "getIndex" , "()I" , ( ) ) . await ?, 4 ) ;
263+
264+ let prefix_pattern = JavaLangString :: from_rust_string ( & jvm, "'\u{1f600} '0x" ) . await ?;
265+ let _: ( ) = jvm
266+ . invoke_virtual ( & format, "applyPattern" , "(Ljava/lang/String;)V" , ( prefix_pattern, ) )
267+ . await ?;
268+ let source = JavaLangString :: from_rust_string ( & jvm, "\u{1f600} 12y" ) . await ?;
269+ let position: ClassInstanceRef < ParsePosition > = jvm. new_class ( "java/text/ParsePosition" , "(I)V" , ( 0 , ) ) . await ?. into ( ) ;
270+ let parsed: ClassInstanceRef < Number > = jvm
271+ . invoke_virtual (
272+ & format,
273+ "parse" ,
274+ "(Ljava/lang/String;Ljava/text/ParsePosition;)Ljava/lang/Number;" ,
275+ ( source, position. clone ( ) ) ,
276+ )
277+ . await ?;
278+ assert ! ( parsed. is_null( ) ) ;
279+ assert_eq ! ( jvm. invoke_virtual:: <_, i32 >( & position, "getErrorIndex" , "()I" , ( ) ) . await ?, 4 ) ;
280+
281+ let suffix_pattern = JavaLangString :: from_rust_string ( & jvm, "0;0-" ) . await ?;
282+ let _: ( ) = jvm
283+ . invoke_virtual ( & format, "applyPattern" , "(Ljava/lang/String;)V" , ( suffix_pattern, ) )
284+ . await ?;
285+ let source = JavaLangString :: from_rust_string ( & jvm, "12-" ) . await ?;
286+ let position: ClassInstanceRef < ParsePosition > = jvm. new_class ( "java/text/ParsePosition" , "(I)V" , ( 0 , ) ) . await ?. into ( ) ;
287+ let parsed: ClassInstanceRef < Long > = jvm
288+ . invoke_virtual (
289+ & format,
290+ "parse" ,
291+ "(Ljava/lang/String;Ljava/text/ParsePosition;)Ljava/lang/Number;" ,
292+ ( source, position. clone ( ) ) ,
293+ )
294+ . await ?;
295+ assert_eq ! ( jvm. invoke_virtual:: <_, i64 >( & parsed, "longValue" , "()J" , ( ) ) . await ?, -12 ) ;
296+ assert_eq ! ( jvm. invoke_virtual:: <_, i32 >( & position, "getIndex" , "()I" , ( ) ) . await ?, 3 ) ;
297+
298+ Ok ( ( ) )
299+ }
0 commit comments