Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
TestString.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7#include <gtest/gtest.h>
8
9#include "arccore/base/String.h"
10#include "arccore/base/TraceInfo.h"
11#include "arccore/base/StringView.h"
13#include "arccore/base/CoreArray.h"
14#include "arccore/base/BasicTranscoder.h"
15
16#include <vector>
17
18using namespace Arccore;
19
20namespace
21{
22// Classe pour restaurer automatiquement les flags() d'un 'std::ostream'
23class IosFlagsWrapper
24{
25 public:
26
27 explicit IosFlagsWrapper(std::ostream* o)
28 : m_stream(o)
29 , m_flags(o->flags())
30 {}
31 ~IosFlagsWrapper() { m_stream->flags(m_flags); }
32
33 private:
34
35 std::ostream* m_stream;
36 std::ios_base::fmtflags m_flags;
37};
38
39void _doConvertTest(const char* name, const String& str)
40{
41 std::cout << "Name=" << name << "\n";
42 std::cout << "OrigUtf8 size=" << str.utf8() << "\n";
43 {
44 CoreArray<Byte> utf8_orig_bytes(str.bytes());
45 CoreArray<Byte> utf8_final_bytes;
46 CoreArray<UChar> utf16_bytes;
47 BasicTranscoder::transcodeFromUtf8ToUtf16(utf8_orig_bytes, utf16_bytes);
48 BasicTranscoder::transcodeFromUtf16ToUtf8(utf16_bytes, utf8_final_bytes);
49 std::cout << "OrigBytes=" << utf8_orig_bytes.constView() << "\n";
50 std::cout << "FinalTranscoderUtf16=" << utf16_bytes.constView() << "\n";
51 std::cout << "FinalTranscoderUtf8=" << utf8_final_bytes.constView() << "\n";
52 ASSERT_EQ(utf8_orig_bytes.constView(), utf8_final_bytes.constView());
53 }
55 ASSERT_EQ(str, str2);
56
57 std::vector<UChar> utf16_vector{ StringUtils::asUtf16BE(str) };
58 Span<const UChar> utf16_bytes(utf16_vector.data(), utf16_vector.size());
59 std::cout << "Utf16 bytes = " << utf16_bytes << "\n";
60 String str3(utf16_bytes.smallView());
61 std::cout << "ToUtf8 size=" << str3.bytes() << "\n";
62 ASSERT_EQ(str, str3);
63}
64
65} // namespace
66
67#ifndef ARCCORE_OS_WIN32
68// TODO: Regarder pourquoi le test ne passe pas sous windows sur le CI de github
69// (alors qu'il fonctionne sur un PC perso. Il faudrait regarder si cela n'est pas
70// un problème d'encodage par défaut).
71TEST(String, Utf8AndUtf16)
72{
73 IosFlagsWrapper io_wrapper(&std::cout);
74 {
75 String str1("▲▼●■◆");
76 std::vector<UChar> utf16_vector{ StringUtils::asUtf16BE(str1) };
77 std::vector<UChar> big_endian_ref_vector{ 0x25b2, 0x25bc, 0x25cf, 0x25a0, 0x25c6 };
78 for (int x : utf16_vector)
79 std::cout << "Utf16: " << std::hex << x << "\n";
80 ASSERT_EQ(big_endian_ref_vector, utf16_vector);
81 Span<const UChar> utf16_bytes(utf16_vector.data(), utf16_vector.size());
82 std::cout << "Utf16_size=" << utf16_bytes.smallView() << "\n";
83
84 std::cout << "BEFORE_CREATE_STR2\n";
85 String str2(utf16_bytes.smallView());
86 std::cout << "str1.utf16=" << str1.utf16() << "\n";
87 std::cout << "str2.utf16=" << str2.utf16() << "\n";
88
89 bool is_same = (str1 == str2);
90
91 std::cout << "is_same=" << is_same << "\n";
92 ASSERT_EQ(str1, str2);
93
94 std::cout << "str1.utf16=" << str1.utf16() << "\n";
95 std::cout << "str2.utf16=" << str2.utf16() << "\n";
96 std::cout.flush();
97
98 ASSERT_EQ(str1.utf16().size(), 6);
99 ASSERT_EQ(str2.utf16().size(), 6);
100
101 ASSERT_EQ(str1.utf8().size(), str2.utf8().size());
102 ASSERT_EQ(str1.utf16().size(), str2.utf16().size());
103 }
104 {
105 String str2;
106 Span<const Byte> b = str2.bytes();
107 ASSERT_EQ(b.size(), 0);
108 ByteConstArrayView u = str2.utf8();
109 ASSERT_EQ(u.size(), 0);
110 }
111
112 {
113 String str3("TX");
114 Span<const Byte> b = str3.bytes();
115 ASSERT_EQ(b.size(), 2);
116 ByteConstArrayView u = str3.utf8();
117 ASSERT_EQ(u.size(), 3);
118 ASSERT_EQ(u[2], 0);
119 }
120 {
121 String str4("€");
122 std::array<Byte, 3> ref_a{ 0xe2, 0x82, 0xac };
123 Span<const Byte> ref_a_view{ ref_a };
124 Span<const Byte> b = str4.bytes();
125 ASSERT_EQ(b.size(), 3);
126 ASSERT_EQ(b, ref_a_view);
127 ByteConstArrayView u = str4.utf8();
128 ASSERT_EQ(u.size(), 4);
129 ASSERT_EQ(u[3], 0);
130 for (Integer i = 0; i < 3; ++i) {
131 ASSERT_EQ(u[i], ref_a[i]);
132 ASSERT_EQ(b[i], ref_a[i]);
133 }
134 }
135 {
136 String x2 = "\xc3\xb1";
137 _doConvertTest("X2", x2);
138 String x3 = "\xe2\x82\xa1";
139 _doConvertTest("X3", x3);
140 String x4 = "\xf0\x90\x8c\xbc";
141 _doConvertTest("X4", x4);
142 }
143}
144#endif
145
146TEST(String, Misc)
147{
148 String e = "Titi";
149 String f = "Toto23";
150 ASSERT_TRUE(f.endsWith("23")) << "Bad compare 1";
151 ASSERT_TRUE(f.startsWith("Toto")) << "Bad compare 2";
152 ASSERT_FALSE(f.startsWith("Toto1")) << "Bad compare 3";
153 ASSERT_FALSE(f.endsWith("Toto1")) << "Bad compare 4";
154 ASSERT_FALSE(f.startsWith("Toto234")) << "Bad compare 5";
155
156 ASSERT_FALSE(f.endsWith("Toto234")) << "Bad compare 6";
157
158 String s2 = f.substring(3);
159 ASSERT_TRUE(s2=="o23") << "Bad compare 7";
160
161 s2 = f.substring(3,2);
162 std::cout << "S2_8=" << s2 << '\n';
163 ASSERT_FALSE(s2!="o2") << "Bad compare 8";
164
165 s2 = f.substring(1,2);
166 std::cout << "S2_9=" << s2 << '\n';
167 ASSERT_FALSE(s2!="ot") << "Bad compare 9";
168
169 s2 = f.substring(7,2);
170 std::cout << "S2_10=" << s2 << '\n';
171 ASSERT_FALSE(s2!="") << "Bad compare 10";
172
173 s2 = f.substring(2,1);
174 std::cout << "S2_11=" << s2 << '\n';
175 ASSERT_FALSE(s2!="t") << "Bad compare 11";
176
177 s2 = f.substring(5,1);
178 std::cout << "S2_12=" << s2 << '\n';
179 ASSERT_FALSE(s2!="3") << "Bad compare 12";
180
181 s2 = f.substring(0);
182 std::cout << "S2_13=" << s2 << '\n';
183 ASSERT_FALSE(s2!=f) << "Bad compare 13";
184
185 String g = " \tceci \tcela ";
186 std::cout << " G= '" << g << "'" << '\n';
188 std::cout << " G2= '" << g2 << "'" << '\n';
190 std::cout << " G3= '" << g3 << "'" << '\n';
191 String expected_g3 =" ceci cela ";
192 ASSERT_EQ(g3,expected_g3);
193 String expected_g2 ="ceci cela";
194 ASSERT_EQ(g2,expected_g2);
195
196 String gnull;
197 String gnull2 = String::collapseWhiteSpace(gnull);
198 std::cout << "GNULL2='" << gnull2 << "'" << '\n';
199 ASSERT_EQ(gnull2,String());
200
201 String gempty("");
202 String gempty2 = String::collapseWhiteSpace(gempty);
203 std::cout << "GEMPTY2='" << gempty2 << "'" << '\n';
204 String expected_gempty2 = "";
205 ASSERT_EQ(gempty2,expected_gempty2);
206
207 {
208 String knull;
209 String kempty { gempty };
210 String k1 { "titi" };
211 String k2 { "ti" };
212 String k3 { "to" };
213 ASSERT_TRUE(knull.contains(gnull)) << "Bad null contains null";
214 ASSERT_FALSE(knull.contains(gempty)) << "Bad null contains empty";
215 ASSERT_TRUE(kempty.contains(gnull)) << "Bad empty contains null";
216 ASSERT_TRUE(kempty.contains(gempty)) << "Bad empty contains null";
217 ASSERT_TRUE(k1.contains(gnull)) << "Bad null contains null";
218 ASSERT_TRUE(k1.contains(gempty)) << "Bad contains empty";
219 ASSERT_TRUE(k1.contains(k2)) << "Bad k1 contains k2";
220 ASSERT_FALSE(k2.contains(k1)) << "Bad k2 contains k1";
221 ASSERT_FALSE(k1.contains(k3)) << "Bad k1 contains k3";
222 }
223 {
224 String k0 = ":Toto::Titi:::Tata::::Tutu:Tete:";
225 //String k0 = ":Toto:Titi";
226 //String k0 = ":Toto::Titi";
227 std::cout << "ORIGINAL STRING TO STRING = '" << k0 << "'" << '\n';
228 std::vector<String> k0_list;
229 k0.split(k0_list,':');
230 for( size_t i=0, n=k0_list.size(); i<n; ++i ){
231 std::cout << "K i=" << i << " v='" << k0_list[i] << "' is_null?=" << k0_list[i].null() << '\n';
232 }
233 ASSERT_EQ(k0_list[0],String(":Toto"));
234 ASSERT_EQ(k0_list[1],String(":Titi"));
235 ASSERT_EQ(k0_list[2],String(":"));
236 ASSERT_EQ(k0_list[3],String("Tata"));
237 ASSERT_EQ(k0_list[4],String(":"));
238 ASSERT_EQ(k0_list[5],String(":Tutu"));
239 ASSERT_EQ(k0_list[6],String("Tete"));
240 }
241}
242
243TEST(String, StdStringView)
244{
245 const char* ref1 = "S1éà";
246 const char* ref2 = "ù*aXZáé";
247 // Ref3 = Ref1 + Ref2
248 const char* ref3 = "S1éàù*aXZáé";
249 std::string std_ref3 { ref3 };
250 String snull;
251 String sempty { "" };
252 String s1 = ref1;
253 String s2 = ref2;
254 String s3 = ref1;
255 s3 = s3 + ref2;
256 std::cout << "S1 '" << s1 << "'_SIZE=" << s1.length() << '\n';
257 std::cout << "S2 '" << s2 << "'_SIZE=" << s2.length() << '\n';
258 std::cout << "S3 '" << s3 << "'_SIZE=" << s3.length() << '\n';
259 std::string_view vempty = sempty.toStdStringView();
260 ASSERT_EQ((Int64)vempty.size(),0) << "vempty.size()==0";
261 std::string_view vnull = snull.toStdStringView();
262 ASSERT_EQ((Int64)vnull.size(),0) << "vnull.size()==0";
263 std::string_view v1 = s1.toStdStringView();
264 ASSERT_EQ(v1,ref1) << "v1==ref1";
265 std::string_view v2 = s2.toStdStringView();
266 ASSERT_EQ(v2,ref2) << "v2==ref2";
267 std::string_view v3 = s3.toStdStringView();
268 ASSERT_EQ(v3,std_ref3) << "v3==ref3";
269
270 String s4 = s3 + snull;
271 std::string_view v4 = s4.toStdStringView();
272 ASSERT_EQ(v4,v3) << "v4==v3";
273
274 String s5 = s3 + sempty;
275 std::string_view v5 = s5.toStdStringView();
276 ASSERT_EQ(v5,v4) << "v5==v4";
277
278 String s6 = s2;
279 const char* t1 = "testà1";
280 const char* t2 = "testé2";
281 std::string st1 = t1;
282 std::string_view st1v = st1;
283 std::string st1_2 = st1 + t2;
284 s6 = t1;
285 ASSERT_EQ(s6.toStdStringView(),st1v) << "s6==st1";
286
287 String s7 = s3;
288 s7 = st1_2;
289 ASSERT_EQ(s7,st1_2) << "s7==st1_2";
290 String s8 = s6 + t2;
291 ASSERT_EQ(s8,st1_2) << "s8==st1_2";
292 String s9 = s7 + snull;
293 ASSERT_EQ(s9,st1_2) << "s9==st1_2";
294 String s10 = s7 + sempty;
295 ASSERT_EQ(s10,st1_2) << "s10==st1_2";
296}
#define ASSERT_FALSE(condition)
Vérifie que condition est faux.
Definition Assertion.h:138
#define ASSERT_TRUE(condition)
Vérifie que condition est vrai.
Definition Assertion.h:126
Fonctions utilitaires sur les chaînes de caractères.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
static void transcodeFromUtf16ToUtf8(Span< const UChar > utf16, CoreArray< Byte > &utf8)
Traduit depuis UTF16 vers UTF8.
Vue constante d'un tableau de type T.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
Span< const DataType > constView() const
Vue constante.
constexpr ARCCORE_HOST_DEVICE SizeType size() const noexcept
Retourne la taille du tableau.
Definition Span.h:209
Vue d'un tableau d'éléments de type T.
Definition Span.h:510
Chaîne de caractères unicode.
ByteConstArrayView utf8() const
Retourne la conversion de l'instance dans l'encodage UTF-8.
Definition String.cc:275
bool contains(const String &s) const
Indique si la chaîne contient s.
Definition String.cc:1067
Span< const Byte > bytes() const
Retourne la conversion de l'instance dans l'encodage UTF-8.
Definition String.cc:291
void split(StringContainer &str_array, char c) const
Découpe la chaîne suivant le caractère c.
static String collapseWhiteSpace(const String &rhs)
Effectue une normalisation des caractères espaces.
Definition String.cc:452
bool startsWith(const String &s) const
Indique si la chaîne commence par les caractères de s.
Definition String.cc:1099
Int64 length() const
Retourne la longueur de la chaîne.
Definition String.cc:338
static String replaceWhiteSpace(const String &rhs)
Effectue une normalisation des caractères espaces.
Definition String.cc:440
std::string_view toStdStringView() const
Retourne une vue de la STL sur la chaîne actuelle.
Definition String.cc:348
String substring(Int64 pos) const
Sous-chaîne commençant à la position pos.
Definition String.cc:1114
bool endsWith(const String &s) const
Indique si la chaîne se termine par les caractères de s.
Definition String.cc:1083
Espace de nom de Arccore.
Definition ArcaneTypes.h:24
Int32 Integer
Type représentant un entier.