1 #include "locale_test.h"
2
3 #if !defined (STLPORT) || !defined (_STLP_USE_NO_IOSTREAMS)
4 # include <locale>
5 # include <stdexcept>
6 # include <algorithm>
7 # include <vector>
8
9 # if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)
10 using namespace std;
11 # endif
12
13 //
14 // tests implementation
15 //
collate_facet()16 void LocaleTest::collate_facet()
17 {
18 {
19 CPPUNIT_ASSERT( has_facet<collate<char> >(locale::classic()) );
20 collate<char> const& col = use_facet<collate<char> >(locale::classic());
21
22 char const str1[] = "abcdef1";
23 char const str2[] = "abcdef2";
24 const size_t size1 = sizeof(str1) / sizeof(str1[0]) - 1;
25 const size_t size2 = sizeof(str2) / sizeof(str2[0]) - 1;
26
27 CPPUNIT_ASSERT( col.compare(str1, str1 + size1 - 1, str2, str2 + size2 - 1) == 0 );
28 CPPUNIT_ASSERT( col.compare(str1, str1 + size1, str2, str2 + size2) == -1 );
29
30 //Smallest string should be before largest one:
31 CPPUNIT_ASSERT( col.compare(str1, str1 + size1 - 2, str2, str2 + size2 - 1) == -1 );
32 CPPUNIT_ASSERT( col.compare(str1, str1 + size1 - 1, str2, str2 + size2 - 2) == 1 );
33 }
34
35 # if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
36 try {
37 locale loc("fr_FR");
38 {
39 CPPUNIT_ASSERT( has_facet<collate<char> >(loc) );
40 collate<char> const& col = use_facet<collate<char> >(loc);
41
42 char const str1[] = "abcdef1";
43 char const str2[] = "abcdef2";
44 const size_t size1 = sizeof(str1) / sizeof(str1[0]) - 1;
45 const size_t size2 = sizeof(str2) / sizeof(str2[0]) - 1;
46
47 CPPUNIT_ASSERT( col.compare(str1, str1 + size1 - 1, str2, str2 + size2 - 1) == 0 );
48 CPPUNIT_ASSERT( col.compare(str1, str1 + size1, str2, str2 + size2) == -1 );
49
50 //Smallest string should be before largest one:
51 CPPUNIT_ASSERT( col.compare(str1, str1 + size1 - 2, str2, str2 + size2 - 1) == -1 );
52 CPPUNIT_ASSERT( col.compare(str1, str1 + size1 - 1, str2, str2 + size2 - 2) == 1 );
53 }
54 {
55 CPPUNIT_ASSERT( has_facet<collate<char> >(loc) );
56 collate<char> const& col = use_facet<collate<char> >(loc);
57
58 string strs[] = {"abdd", "ab�d", "abbd", "abcd"};
59
60 string transformed[4];
61 for (size_t i = 0; i < 4; ++i) {
62 transformed[i] = col.transform(strs[i].data(), strs[i].data() + strs[i].size());
63 }
64
65 sort(strs, strs + 4, loc);
66 CPPUNIT_ASSERT( strs[0] == "abbd" );
67 CPPUNIT_ASSERT( strs[1] == "abcd" );
68 CPPUNIT_ASSERT( strs[2] == "ab�d" );
69 CPPUNIT_ASSERT( strs[3] == "abdd" );
70
71 sort(transformed, transformed + 4);
72
73 CPPUNIT_ASSERT( col.transform(strs[0].data(), strs[0].data() + strs[0].size()) == transformed[0] );
74 CPPUNIT_ASSERT( col.transform(strs[1].data(), strs[1].data() + strs[1].size()) == transformed[1] );
75 CPPUNIT_ASSERT( col.transform(strs[2].data(), strs[2].data() + strs[2].size()) == transformed[2] );
76 CPPUNIT_ASSERT( col.transform(strs[3].data(), strs[3].data() + strs[3].size()) == transformed[3] );
77
78 // Check empty string result in empty key.
79 CPPUNIT_ASSERT( col.transform(strs[0].data(), strs[0].data()).empty() );
80
81 // Check that only characters that matter are taken into accout to build the key.
82 CPPUNIT_ASSERT( col.transform(strs[0].data(), strs[0].data() + 2) == col.transform(strs[1].data(), strs[1].data() + 2) );
83 }
84 # if !defined (STLPORT) || !defined (_STLP_NO_WCHAR_T)
85 {
86 CPPUNIT_ASSERT( has_facet<collate<wchar_t> >(loc) );
87 collate<wchar_t> const& col = use_facet<collate<wchar_t> >(loc);
88
89 wchar_t const str1[] = L"abcdef1";
90 wchar_t const str2[] = L"abcdef2";
91 const size_t size1 = sizeof(str1) / sizeof(str1[0]) - 1;
92 const size_t size2 = sizeof(str2) / sizeof(str2[0]) - 1;
93
94 CPPUNIT_ASSERT( col.compare(str1, str1 + size1 - 1, str2, str2 + size2 - 1) == 0 );
95 CPPUNIT_ASSERT( col.compare(str1, str1 + size1, str2, str2 + size2) == -1 );
96
97 //Smallest string should be before largest one:
98 CPPUNIT_ASSERT( col.compare(str1, str1 + size1 - 2, str2, str2 + size2 - 1) == -1 );
99 CPPUNIT_ASSERT( col.compare(str1, str1 + size1 - 1, str2, str2 + size2 - 2) == 1 );
100 }
101 {
102 size_t i;
103 CPPUNIT_ASSERT( has_facet<collate<wchar_t> >(loc) );
104 collate<wchar_t> const& col = use_facet<collate<wchar_t> >(loc);
105
106 // Here we would like to use L"ab�d" but it looks like all compilers
107 // do not support storage of unicode characters in exe resulting in
108 // compilation error. We avoid this test for the moment.
109 wstring strs[] = {L"abdd", L"abcd", L"abbd", L"abcd"};
110
111 wstring transformed[4];
112 for (i = 0; i < 4; ++i) {
113 transformed[i] = col.transform(strs[i].data(), strs[i].data() + strs[i].size());
114 }
115
116 sort(strs, strs + 4, loc);
117 CPPUNIT_ASSERT( strs[0] == L"abbd" );
118 CPPUNIT_ASSERT( strs[1] == L"abcd" );
119 CPPUNIT_ASSERT( strs[2] == L"abcd" );
120 CPPUNIT_ASSERT( strs[3] == L"abdd" );
121
122 sort(transformed, transformed + 4);
123
124 CPPUNIT_ASSERT( col.transform(strs[0].data(), strs[0].data() + strs[0].size()) == transformed[0] );
125 CPPUNIT_ASSERT( col.transform(strs[1].data(), strs[1].data() + strs[1].size()) == transformed[1] );
126 CPPUNIT_ASSERT( col.transform(strs[2].data(), strs[2].data() + strs[2].size()) == transformed[2] );
127 CPPUNIT_ASSERT( col.transform(strs[3].data(), strs[3].data() + strs[3].size()) == transformed[3] );
128
129 CPPUNIT_ASSERT( col.transform(strs[0].data(), strs[0].data()).empty() );
130
131 CPPUNIT_ASSERT( col.transform(strs[0].data(), strs[0].data() + 2) == col.transform(strs[1].data(), strs[1].data() + 2) );
132 }
133 # endif
134 }
135 catch (runtime_error const&) {
136 CPPUNIT_MESSAGE("No french locale to check collate facet");
137 }
138 # endif
139 }
140
collate_by_name()141 void LocaleTest::collate_by_name()
142 {
143 /*
144 * Check of the 22.1.1.2.7 standard point. Construction of a locale
145 * instance from a null pointer or an unknown name should result in
146 * a runtime_error exception.
147 */
148 # if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
149 # if defined (STLPORT) || !defined (__GNUC__)
150 try {
151 locale loc(locale::classic(), new collate_byname<char>(static_cast<char const*>(0)));
152 CPPUNIT_FAIL;
153 }
154 catch (runtime_error const& /* e */) {
155 //CPPUNIT_MESSAGE( e.what() );
156 }
157 catch (...) {
158 CPPUNIT_FAIL;
159 }
160 # endif
161
162 try {
163 locale loc(locale::classic(), new collate_byname<char>("yasli_language"));
164 CPPUNIT_FAIL;
165 }
166 catch (runtime_error const& /* e */) {
167 //CPPUNIT_MESSAGE( e.what() );
168 }
169 catch (...) {
170 CPPUNIT_FAIL;
171 }
172
173 try {
174 string veryLongFacetName("LC_COLLATE=");
175 veryLongFacetName.append(512, '?');
176 locale loc(locale::classic(), new collate_byname<char>(veryLongFacetName.c_str()));
177 CPPUNIT_FAIL;
178 }
179 catch (runtime_error const& /* e */) {
180 //CPPUNIT_MESSAGE( e.what() );
181 }
182 catch (...) {
183 CPPUNIT_FAIL;
184 }
185
186 try {
187 locale loc(locale::classic(), "C", locale::collate);
188 }
189 catch (runtime_error const& e) {
190 CPPUNIT_MESSAGE( e.what() );
191 CPPUNIT_FAIL;
192 }
193 catch (...) {
194 CPPUNIT_FAIL;
195 }
196
197 try {
198 // On platform without real localization support we should rely on the "C" facet.
199 locale loc(locale::classic(), "", locale::collate);
200 }
201 catch (runtime_error const& e) {
202 CPPUNIT_MESSAGE( e.what() );
203 CPPUNIT_FAIL;
204 }
205 catch (...) {
206 CPPUNIT_FAIL;
207 }
208
209 try {
210 locale loc(locale::classic(), new collate_byname<char>("C"));
211
212 //We check that the C locale gives a lexicographical comparison:
213 collate<char> const& cfacet_byname = use_facet<collate<char> >(loc);
214 collate<char> const& cfacet = use_facet<collate<char> >(locale::classic());
215
216 char const str1[] = "abcdef1";
217 char const str2[] = "abcdef2";
218 const size_t size1 = sizeof(str1) / sizeof(str1[0]) - 1;
219 const size_t size2 = sizeof(str2) / sizeof(str2[0]) - 1;
220
221 CPPUNIT_ASSERT( cfacet_byname.compare(str1, str1 + size1 - 1, str2, str2 + size2 - 1) ==
222 cfacet.compare(str1, str1 + size1 - 1, str2, str2 + size2 - 1) );
223 CPPUNIT_ASSERT( cfacet_byname.compare(str1, str1 + size1, str2, str2 + size2) ==
224 cfacet.compare(str1, str1 + size1, str2, str2 + size2) );
225
226 //Smallest string should be before largest one:
227 CPPUNIT_ASSERT( cfacet_byname.compare(str1, str1 + size1 - 2, str2, str2 + size2 - 1) ==
228 cfacet.compare(str1, str1 + size1 - 2, str2, str2 + size2 - 1) );
229 CPPUNIT_ASSERT( cfacet_byname.compare(str1, str1 + size1 - 1, str2, str2 + size2 - 2) ==
230 cfacet.compare(str1, str1 + size1 - 1, str2, str2 + size2 - 2) );
231
232 // We cannot play with '�' char here because doing so would make test result
233 // dependant on char being consider as signed or not...
234 string strs[] = {"abdd", /* "ab�d",*/ "abbd", "abcd"};
235
236 vector<string> v1(strs, strs + sizeof(strs) / sizeof(strs[0]));
237 sort(v1.begin(), v1.end(), loc);
238 vector<string> v2(strs, strs + sizeof(strs) / sizeof(strs[0]));
239 sort(v2.begin(), v2.end(), locale::classic());
240 CPPUNIT_ASSERT( v1 == v2 );
241
242 CPPUNIT_ASSERT( (cfacet_byname.transform(v1[0].data(), v1[0].data() + v1[0].size()).compare(cfacet_byname.transform(v1[1].data(), v1[1].data() + v1[1].size())) ==
243 v1[0].compare(v1[1])) );
244 }
245 catch (runtime_error const& /* e */) {
246 /* CPPUNIT_MESSAGE( e.what() ); */
247 CPPUNIT_FAIL;
248 }
249 catch (...) {
250 CPPUNIT_FAIL;
251 }
252
253 # if !defined (STLPORT) || !defined (_STLP_NO_WCHAR_T)
254 # if defined (STLPORT) || !defined (__GNUC__)
255 try {
256 locale loc(locale::classic(), new collate_byname<wchar_t>(static_cast<char const*>(0)));
257 CPPUNIT_FAIL;
258 }
259 catch (runtime_error const&) {
260 }
261 catch (...) {
262 CPPUNIT_FAIL;
263 }
264 # endif
265
266 try {
267 locale loc(locale::classic(), new collate_byname<wchar_t>("yasli_language"));
268 CPPUNIT_FAIL;
269 }
270 catch (runtime_error const&) {
271 }
272 catch (...) {
273 CPPUNIT_FAIL;
274 }
275 # endif
276 # endif
277 }
278
279 #endif
280