]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/locale/test/test_formatting.cpp
2 // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
4 // Distributed under the Boost Software License, Version 1.0. (See
5 // accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
8 #ifndef BOOST_LOCALE_WITH_ICU
12 std::cout
<< "ICU is not build... Skipping" << std::endl
;
17 #define _CRT_SECURE_NO_WARNINGS
18 // Disable this "security crap"
21 #include <boost/locale/formatting.hpp>
22 #include <boost/locale/format.hpp>
23 #include <boost/locale/date_time.hpp>
24 #include <boost/locale/generator.hpp>
25 #include "test_locale.hpp"
26 #include "test_locale_tools.hpp"
32 #include <unicode/uversion.h>
34 using namespace boost::locale
;
38 #define _CRT_SECURE_NO_WARNINGS
42 #undef BOOST_LOCALE_ENABLE_CHAR16_T
43 #undef BOOST_LOCALE_ENABLE_CHAR32_T
45 void print_diff(T
const &,T
const &,int)
49 void print_diff(std::string
const &l
,std::string
const &r
,int line
)
52 std::cerr
<< "----[" << l
<<"]!=\n----["<<r
<<"] in " << line
<< std::endl
;
56 #define TESTEQ(x,y) do { print_diff((x),(y),__LINE__); TEST((x)==(y)); } while(0)
58 #define TESTEQ(x,y) TEST((x)==(y))
61 #define TEST_FMT(manip,value,expected) \
63 std::basic_ostringstream<CharType> ss; \
65 ss << manip << value; \
66 TESTEQ(ss.str(),to_correct_string<CharType>(expected,loc)); \
69 #ifndef _LIBCPP_VERSION
70 static bool parsing_fails()
75 static bool parsing_fails()
77 static bool checked
=false;
81 std::istringstream
ss("x");
82 ss
.exceptions(std::ios_base::failbit
);
87 catch(std::ios_base::failure
const &) {
95 std::cerr
<< "!!! Warning: libc++ library does not throw an exception on failbit !!!" << std::endl
;
103 #define TEST_NOPAR(manip,actual,type) \
106 std::basic_string<CharType> act= \
107 to_correct_string<CharType>(actual,loc); \
109 std::basic_istringstream<CharType> ss; \
115 if(parsing_fails()){ \
116 std::basic_istringstream<CharType> ss; \
119 ss.exceptions(std::ios_base::failbit); \
121 TEST_THROWS(ss >> v,std::ios_base::failure); \
125 #define TEST_PAR(manip,type,actual,expected) \
128 {std::basic_istringstream<CharType> ss; \
130 ss.str(to_correct_string<CharType>(actual,loc)); \
131 ss >> manip >> v >> std::ws; \
132 TESTEQ(v,expected); \
134 {std::basic_istringstream<CharType> ss; \
136 ss.str(to_correct_string<CharType>(std::string(actual)+"@",loc)); \
138 ss >> manip >> v >> std::skipws >> tmp_c; \
139 TESTEQ(v,expected); \
140 TEST(tmp_c=='@'); } \
143 #define TEST_FP1(manip,value_in,str,type,value_out) \
145 TEST_FMT(manip,value_in,str); \
146 TEST_PAR(manip,type,str,value_out); \
149 #define TEST_FP2(m1,m2,value_in,str,type,value_out) \
151 TEST_FMT(m1<<m2,value_in,str); \
152 TEST_PAR(m1>>m2,type,str,value_out); \
155 #define TEST_FP3(m1,m2,m3,value_in,str,type,value_out) \
157 TEST_FMT(m1<<m2<<m3,value_in,str); \
158 TEST_PAR(m1>>m2>>m3,type,str,value_out); \
161 #define TEST_FP4(m1,m2,m3,m4,value_in,str,type,value_out) \
163 TEST_FMT(m1<<m2<<m3<<m4,value_in,str); \
164 TEST_PAR(m1>>m2>>m3>>m4,type,str,value_out); \
168 #define FORMAT(f,v,exp) \
170 std::basic_ostringstream<CharType> ss; \
172 std::basic_string<CharType> fmt = to_correct_string<CharType>(f,loc); \
173 ss << boost::locale::basic_format<CharType>(fmt) % v; \
174 TESTEQ(ss.str(),to_correct_string<CharType>(exp,loc)); \
175 ss.str(to_correct_string<CharType>("",loc)); \
176 ss << boost::locale::basic_format<CharType>(boost::locale::translate(fmt.c_str())) % v; \
177 /*ss << boost::locale::basic_format<CharType>(fmt) % v; */ \
178 TESTEQ(ss.str(),to_correct_string<CharType>(exp,loc)); \
179 TESTEQ( (boost::locale::basic_format<CharType>(fmt) % v).str(loc),to_correct_string<CharType>(exp,loc)); \
183 #define TEST_MIN_MAX_FMT(type,minval,maxval) \
185 TEST_FMT(as::number,std::numeric_limits<type>::min(),minval); \
186 TEST_FMT(as::number,std::numeric_limits<type>::max(),maxval); \
189 #define TEST_MIN_MAX_PAR(type,minval,maxval) \
191 TEST_PAR(as::number,type,minval,std::numeric_limits<type>::min()); \
192 TEST_PAR(as::number,type,maxval,std::numeric_limits<type>::max()); \
195 #define TEST_MIN_MAX(type,minval,maxval) \
197 TEST_MIN_MAX_FMT(type,minval,maxval); \
198 TEST_MIN_MAX_PAR(type,minval,maxval); \
202 #define BOOST_ICU_VER (U_ICU_VERSION_MAJOR_NUM*100 + U_ICU_VERSION_MINOR_NUM)
203 #define BOOST_ICU_EXACT_VER (U_ICU_VERSION_MAJOR_NUM*10000 + U_ICU_VERSION_MINOR_NUM * 100 + U_ICU_VERSION_PATCHLEVEL_NUM)
205 bool short_parsing_fails()
207 static bool fails
= false;
208 static bool get_result
= false;
211 std::stringstream
ss("65000");
212 ss
.imbue(std::locale::classic());
220 template<typename CharType
>
221 void test_manip(std::string e_charset
="UTF-8")
223 boost::locale::generator g
;
224 std::locale loc
=g("en_US."+e_charset
);
226 TEST_FP1(as::posix
,1200.1,"1200.1",double,1200.1);
227 TEST_FP1(as::number
,1200.1,"1,200.1",double,1200.1);
228 TEST_FMT(as::number
<<std::setfill(CharType('_'))<<std::setw(6),1534,"_1,534");
229 TEST_FMT(as::number
<<std::left
<<std::setfill(CharType('_'))<<std::setw(6),1534,"1,534_");
232 if(sizeof(short) == 2) {
233 TEST_MIN_MAX(short,"-32,768","32,767");
234 TEST_MIN_MAX(unsigned short,"0","65,535");
235 TEST_NOPAR(as::number
,"-1",unsigned short);
236 if(short_parsing_fails()) {
237 TEST_NOPAR(as::number
,"65,535",short);
241 TEST_MIN_MAX(int,"-2,147,483,648","2,147,483,647");
242 TEST_MIN_MAX(unsigned int,"0","4,294,967,295");
243 TEST_NOPAR(as::number
,"-1",unsigned int);
244 TEST_NOPAR(as::number
,"4,294,967,295",int);
246 if(sizeof(long)==4) {
247 TEST_MIN_MAX(long,"-2,147,483,648","2,147,483,647");
248 TEST_MIN_MAX(unsigned long,"0","4,294,967,295");
249 TEST_NOPAR(as::number
,"-1",unsigned long);
250 TEST_NOPAR(as::number
,"4,294,967,295",long);
252 if(sizeof(long)==8) {
253 TEST_MIN_MAX(long,"-9,223,372,036,854,775,808","9,223,372,036,854,775,807");
254 TEST_MIN_MAX_FMT(unsigned long,"0","18446744073709551615"); // Unsupported range by icu - ensure fallback
255 TEST_NOPAR(as::number
,"-1",unsigned long);
257 #ifndef BOOST_NO_LONG_LONG
258 if(sizeof(long long)==8) {
259 TEST_MIN_MAX(long long,"-9,223,372,036,854,775,808","9,223,372,036,854,775,807");
260 // we can't really parse this as ICU does not support this range, only format
261 TEST_MIN_MAX_FMT(unsigned long long,"0","18446744073709551615"); // Unsupported range by icu - ensure fallback
262 TEST_FMT(as::number
,9223372036854775807ULL,"9,223,372,036,854,775,807");
263 TEST_FMT(as::number
,9223372036854775808ULL,"9223372036854775808"); // Unsupported range by icu - ensure fallback
264 TEST_NOPAR(as::number
,"-1",unsigned long long);
270 TEST_FP3(as::number
,std::left
,std::setw(3),15,"15 ",int,15);
271 TEST_FP3(as::number
,std::right
,std::setw(3),15," 15",int,15);
272 TEST_FP3(as::number
,std::setprecision(3),std::fixed
,13.1,"13.100",double,13.1);
273 TEST_FP3(as::number
,std::setprecision(3),std::scientific
,13.1,"1.310E1",double,13.1);
275 TEST_NOPAR(as::number
,"",int);
276 TEST_NOPAR(as::number
,"--3",int);
277 TEST_NOPAR(as::number
,"y",int);
279 TEST_FP1(as::percent
,0.1,"10%",double,0.1);
280 TEST_FP3(as::percent
,std::fixed
,std::setprecision(1),0.10,"10.0%",double,0.1);
282 TEST_NOPAR(as::percent
,"1",double);
284 TEST_FP1(as::currency
,1345,"$1,345.00",int,1345);
285 TEST_FP1(as::currency
,1345.34,"$1,345.34",double,1345.34);
287 TEST_NOPAR(as::currency
,"$",double);
290 #if BOOST_ICU_VER >= 402
291 TEST_FP2(as::currency
,as::currency_national
,1345,"$1,345.00",int,1345);
292 TEST_FP2(as::currency
,as::currency_national
,1345.34,"$1,345.34",double,1345.34);
293 TEST_FP2(as::currency
,as::currency_iso
,1345,"USD1,345.00",int,1345);
294 TEST_FP2(as::currency
,as::currency_iso
,1345.34,"USD1,345.34",double,1345.34);
296 TEST_FP1(as::spellout
,10,"ten",int,10);
297 #if 402 <= BOOST_ICU_VER && BOOST_ICU_VER < 408
298 if(e_charset
=="UTF-8") {
299 TEST_FMT(as::ordinal
,1,"1\xcb\xa2\xe1\xb5\x97"); // 1st with st as ligatures
302 TEST_FMT(as::ordinal
,1,"1st");
305 time_t a_date
= 3600*24*(31+4); // Feb 5th
306 time_t a_time
= 3600*15+60*33; // 15:33:05
307 time_t a_timesec
= 13;
308 time_t a_datetime
= a_date
+ a_time
+ a_timesec
;
310 TEST_FP2(as::date
, as::gmt
,a_datetime
,"Feb 5, 1970",time_t,a_date
);
311 TEST_FP3(as::date
,as::date_short
,as::gmt
,a_datetime
,"2/5/70",time_t,a_date
);
312 TEST_FP3(as::date
,as::date_medium
,as::gmt
,a_datetime
,"Feb 5, 1970",time_t,a_date
);
313 TEST_FP3(as::date
,as::date_long
,as::gmt
,a_datetime
,"February 5, 1970",time_t,a_date
);
314 TEST_FP3(as::date
,as::date_full
,as::gmt
,a_datetime
,"Thursday, February 5, 1970",time_t,a_date
);
316 TEST_NOPAR(as::date
>>as::date_short
,"aa/bb/cc",double);
318 TEST_FP2(as::time
, as::gmt
,a_datetime
,"3:33:13 PM",time_t,a_time
+a_timesec
);
319 TEST_FP3(as::time
,as::time_short
,as::gmt
,a_datetime
,"3:33 PM",time_t,a_time
);
320 TEST_FP3(as::time
,as::time_medium
,as::gmt
,a_datetime
,"3:33:13 PM",time_t,a_time
+a_timesec
);
321 #if BOOST_ICU_VER >= 408
322 TEST_FP3(as::time
,as::time_long
,as::gmt
,a_datetime
,"3:33:13 PM GMT",time_t,a_time
+a_timesec
);
323 #if BOOST_ICU_EXACT_VER != 40800
325 TEST_FP3(as::time
,as::time_full
,as::gmt
,a_datetime
,"3:33:13 PM GMT",time_t,a_time
+a_timesec
);
328 TEST_FP3(as::time
,as::time_long
,as::gmt
,a_datetime
,"3:33:13 PM GMT+00:00",time_t,a_time
+a_timesec
);
329 TEST_FP3(as::time
,as::time_full
,as::gmt
,a_datetime
,"3:33:13 PM GMT+00:00",time_t,a_time
+a_timesec
);
332 TEST_NOPAR(as::time
,"AM",double);
334 TEST_FP2(as::time
, as::time_zone("GMT+01:00"),a_datetime
,"4:33:13 PM",time_t,a_time
+a_timesec
);
335 TEST_FP3(as::time
,as::time_short
,as::time_zone("GMT+01:00"),a_datetime
,"4:33 PM",time_t,a_time
);
336 TEST_FP3(as::time
,as::time_medium
,as::time_zone("GMT+01:00"),a_datetime
,"4:33:13 PM",time_t,a_time
+a_timesec
);
338 #if U_ICU_VERSION_MAJOR_NUM >= 52
339 #define GMT_P100 "GMT+1"
341 #define GMT_P100 "GMT+01:00"
344 #if U_ICU_VERSION_MAJOR_NUM >= 50
352 TEST_FP3(as::time
,as::time_long
,as::time_zone("GMT+01:00"),a_datetime
,"4:33:13 PM " GMT_P100
,time_t,a_time
+a_timesec
);
353 #if BOOST_ICU_VER == 308 && defined(__CYGWIN__)
354 // Known faliture ICU issue
356 TEST_FP3(as::time
,as::time_full
,as::time_zone("GMT+01:00"),a_datetime
,"4:33:13 PM GMT+01:00",time_t,a_time
+a_timesec
);
359 TEST_FP2(as::datetime
, as::gmt
,a_datetime
,"Feb 5, 1970" PERIOD
" 3:33:13 PM",time_t,a_datetime
);
360 TEST_FP4(as::datetime
,as::date_short
,as::time_short
,as::gmt
,a_datetime
,"2/5/70" PERIOD
" 3:33 PM",time_t,a_date
+a_time
);
361 TEST_FP4(as::datetime
,as::date_medium
,as::time_medium
,as::gmt
,a_datetime
,"Feb 5, 1970" PERIOD
" 3:33:13 PM",time_t,a_datetime
);
362 #if BOOST_ICU_VER >= 408
363 TEST_FP4(as::datetime
,as::date_long
,as::time_long
,as::gmt
,a_datetime
,"February 5, 1970" ICUAT
" 3:33:13 PM GMT",time_t,a_datetime
);
364 #if BOOST_ICU_EXACT_VER != 40800
366 TEST_FP4(as::datetime
,as::date_full
,as::time_full
,as::gmt
,a_datetime
,"Thursday, February 5, 1970" ICUAT
" 3:33:13 PM GMT",time_t,a_datetime
);
369 TEST_FP4(as::datetime
,as::date_long
,as::time_long
,as::gmt
,a_datetime
,"February 5, 1970" PERIOD
" 3:33:13 PM GMT+00:00",time_t,a_datetime
);
370 TEST_FP4(as::datetime
,as::date_full
,as::time_full
,as::gmt
,a_datetime
,"Thursday, February 5, 1970" PERIOD
" 3:33:13 PM GMT+00:00",time_t,a_datetime
);
374 time_t lnow
= now
+ 3600 * 4;
375 char local_time_str
[256];
376 std::string format
="%H:%M:%S";
377 std::basic_string
<CharType
> format_string(format
.begin(),format
.end());
378 strftime(local_time_str
,sizeof(local_time_str
),format
.c_str(),gmtime(&lnow
));
379 TEST_FMT(as::ftime(format_string
),now
,local_time_str
);
380 TEST_FMT(as::ftime(format_string
)<<as::gmt
<<as::local_time
,now
,local_time_str
);
391 std::string result
[]= {
392 "Thu","Thursday","Feb","February", // aAbB
393 #if BOOST_ICU_VER >= 408
394 "Thursday, February 5, 1970" ICUAT
" 3:33:13 PM GMT", // c
396 "Thursday, February 5, 1970 3:33:13 PM GMT+00:00", // c
398 "05","5","Feb", // deh
399 "15","03","36","02", // HIjm
400 "33","\n","PM", "03:33:13 PM",// Mnpr
401 "15:33","13","\t","15:33:13", // RStT
402 "Feb 5, 1970","3:33:13 PM","70","1970", // xXyY
403 #if BOOST_ICU_VER >= 408
410 for(unsigned i
=0;i
<marks
.size();i
++) {
411 format_string
.clear();
412 format_string
+=static_cast<CharType
>('%');
413 format_string
+=static_cast<CharType
>(marks
[i
]);
414 TEST_FMT(as::ftime(format_string
)<<as::gmt
,a_datetime
,result
[i
]);
417 std::string sample_f
[]={
418 "Now is %A, %H o'clo''ck ' or not ' ",
423 std::string expected_f
[] = {
424 "Now is Thursday, 15 o'clo''ck ' or not ' ",
430 for(unsigned i
=0;i
<sizeof(sample_f
)/sizeof(sample_f
[0]);i
++) {
431 format_string
.assign(sample_f
[i
].begin(),sample_f
[i
].end());
432 TEST_FMT(as::ftime(format_string
)<<as::gmt
,a_datetime
,expected_f
[i
]);
437 template<typename CharType
>
438 void test_format(std::string charset
="UTF-8")
440 boost::locale::generator g
;
441 std::locale loc
=g("en_US."+charset
);
443 FORMAT("{3} {1} {2}", 1 % 2 % 3,"3 1 2");
444 FORMAT("{1} {2}", "hello" % 2,"hello 2");
445 FORMAT("{1}",1200.1,"1200.1");
446 FORMAT("Test {1,num}",1200.1,"Test 1,200.1");
447 FORMAT("{{}} {1,number}",1200.1,"{} 1,200.1");
448 FORMAT("{1,num=sci,p=3}",13.1,"1.310E1");
449 FORMAT("{1,num=scientific,p=3}",13.1,"1.310E1");
450 FORMAT("{1,num=fix,p=3}",13.1,"13.100");
451 FORMAT("{1,num=fixed,p=3}",13.1,"13.100");
452 FORMAT("{1,<,w=3,num}",-1,"-1 ");
453 FORMAT("{1,>,w=3,num}",1," 1");
454 FORMAT("{per,1}",0.1,"10%");
455 FORMAT("{percent,1}",0.1,"10%");
456 FORMAT("{1,cur}",1234,"$1,234.00");
457 FORMAT("{1,currency}",1234,"$1,234.00");
458 if(charset
=="UTF-8") {
459 if(U_ICU_VERSION_MAJOR_NUM
>=4)
460 FORMAT("{1,cur,locale=de_DE}",10,"10,00\xC2\xA0€");
462 FORMAT("{1,cur,locale=de_DE}",10,"10,00 €");
464 #if BOOST_ICU_VER >= 402
465 FORMAT("{1,cur=nat}",1234,"$1,234.00");
466 FORMAT("{1,cur=national}",1234,"$1,234.00");
467 FORMAT("{1,cur=iso}",1234,"USD1,234.00");
469 FORMAT("{1,spell}",10,"ten");
470 FORMAT("{1,spellout}",10,"ten");
471 #if 402 <= BOOST_ICU_VER && BOOST_ICU_VER < 408
472 if(charset
=="UTF-8") {
473 FORMAT("{1,ord}",1,"1\xcb\xa2\xe1\xb5\x97");
474 FORMAT("{1,ordinal}",1,"1\xcb\xa2\xe1\xb5\x97");
477 FORMAT("{1,ord}",1,"1st");
478 FORMAT("{1,ordinal}",1,"1st");
482 time_t lnow
= now
+ 3600 * 4;
483 char local_time_str
[256];
484 std::string format
="'%H:%M:%S'";
485 std::basic_string
<CharType
> format_string(format
.begin(),format
.end());
486 strftime(local_time_str
,sizeof(local_time_str
),format
.c_str(),gmtime(&lnow
));
488 FORMAT("{1,ftime='''%H:%M:%S'''}",now
,local_time_str
);
489 FORMAT("{1,local,ftime='''%H:%M:%S'''}",now
,local_time_str
);
490 FORMAT("{1,ftime='''%H:%M:%S'''}",now
,local_time_str
);
492 time_t a_date
= 3600*24*(31+4); // Feb 5th
493 time_t a_time
= 3600*15+60*33; // 15:33:05
494 time_t a_timesec
= 13;
495 time_t a_datetime
= a_date
+ a_time
+ a_timesec
;
496 FORMAT("{1,date,gmt};{1,time,gmt};{1,datetime,gmt};{1,dt,gmt}",a_datetime
,
497 "Feb 5, 1970;3:33:13 PM;Feb 5, 1970" PERIOD
" 3:33:13 PM;Feb 5, 1970" PERIOD
" 3:33:13 PM");
498 #if BOOST_ICU_VER >= 408
499 FORMAT("{1,time=short,gmt};{1,time=medium,gmt};{1,time=long,gmt};{1,date=full,gmt}",a_datetime
,
500 "3:33 PM;3:33:13 PM;3:33:13 PM GMT;Thursday, February 5, 1970");
501 FORMAT("{1,time=s,gmt};{1,time=m,gmt};{1,time=l,gmt};{1,date=f,gmt}",a_datetime
,
502 "3:33 PM;3:33:13 PM;3:33:13 PM GMT;Thursday, February 5, 1970");
504 FORMAT("{1,time=short,gmt};{1,time=medium,gmt};{1,time=long,gmt};{1,date=full,gmt}",a_datetime
,
505 "3:33 PM;3:33:13 PM;3:33:13 PM GMT+00:00;Thursday, February 5, 1970");
506 FORMAT("{1,time=s,gmt};{1,time=m,gmt};{1,time=l,gmt};{1,date=f,gmt}",a_datetime
,
507 "3:33 PM;3:33:13 PM;3:33:13 PM GMT+00:00;Thursday, February 5, 1970");
509 FORMAT("{1,time=s,tz=GMT+01:00}",a_datetime
,"4:33 PM");
510 FORMAT("{1,time=s,timezone=GMT+01:00}",a_datetime
,"4:33 PM");
512 FORMAT("{1,gmt,ftime='%H'''}",a_datetime
,"15'");
513 FORMAT("{1,gmt,ftime='''%H'}",a_datetime
,"'15");
514 FORMAT("{1,gmt,ftime='%H o''clock'}",a_datetime
,"15 o'clock");
521 boost::locale::time_zone::global("GMT+4:00");
522 std::cout
<< "Testing char, UTF-8" << std::endl
;
525 std::cout
<< "Testing char, ISO8859-1" << std::endl
;
526 test_manip
<char>("ISO8859-1");
527 test_format
<char>("ISO8859-1");
529 std::cout
<< "Testing wchar_t" << std::endl
;
530 test_manip
<wchar_t>();
531 test_format
<wchar_t>();
533 #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
534 std::cout
<< "Testing char16_t" << std::endl
;
535 test_manip
<char16_t
>();
536 test_format
<char16_t
>();
539 #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
540 std::cout
<< "Testing char32_t" << std::endl
;
541 test_manip
<char32_t
>();
542 test_format
<char32_t
>();
546 catch(std::exception
const &e
) {
547 std::cerr
<< "Failed " << e
.what() << std::endl
;
555 // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
556 // boostinspect:noascii