• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <gtest/gtest.h>
17 
18 #include "ets_coroutine.h"
19 #include "ets_platform_types.h"
20 #include "types/ets_box_primitive.h"
21 #include "types/ets_box_primitive-inl.h"
22 #include "types/ets_array.h"
23 #include "types/ets_string.h"
24 
25 // NOLINTBEGIN(readability-magic-numbers)
26 
27 namespace ark::ets::test {
28 class EtsStringFromCharCodeTest : public testing::Test {
29 public:
EtsStringFromCharCodeTest()30     EtsStringFromCharCodeTest()
31     {
32         options_.SetShouldLoadBootPandaFiles(true);
33         options_.SetShouldInitializeIntrinsics(false);
34         options_.SetCompilerEnableJit(false);
35         options_.SetGcType("epsilon");
36         options_.SetLoadRuntimes({"ets"});
37 
38         auto stdlib = std::getenv("PANDA_STD_LIB");
39         if (stdlib == nullptr) {
40             std::cerr << "PANDA_STD_LIB env variable should be set and point to etsstdlib.abc" << std::endl;
41             std::abort();
42         }
43         options_.SetBootPandaFiles({stdlib});
44 
45         Runtime::Create(options_);
46     }
47 
~EtsStringFromCharCodeTest()48     ~EtsStringFromCharCodeTest() override
49     {
50         Runtime::Destroy();
51     }
52 
53     NO_COPY_SEMANTIC(EtsStringFromCharCodeTest);
54     NO_MOVE_SEMANTIC(EtsStringFromCharCodeTest);
55 
SetUp()56     void SetUp() override
57     {
58         coroutine_ = EtsCoroutine::GetCurrent();
59         coroutine_->ManagedCodeBegin();
60     }
61 
TearDown()62     void TearDown() override
63     {
64         coroutine_->ManagedCodeEnd();
65     }
66 
67     template <typename DoubleIter>
CreateNewStringFromCharCodes(DoubleIter first,DoubleIter last)68     EtsString *CreateNewStringFromCharCodes(DoubleIter first, DoubleIter last)
69     {
70         using CharCodeArray = EtsString::CharCodeArray;
71         using CharCode = std::remove_pointer_t<CharCodeArray::ValueType>;
72         EtsClass *klass = CharCode::GetEtsBoxClass(coroutine_);
73         ASSERT(klass != nullptr);
74         CharCodeArray *charCodeArray = CharCodeArray::Create(klass, std::distance(first, last));
75         std::for_each(first, last, [&charCodeArray, this, idx = 0U](double d) mutable {
76             auto *boxedValue = CharCode::Create(coroutine_, d);
77             charCodeArray->Set(idx++, boxedValue);
78         });
79 
80         return EtsString::CreateNewStringFromCharCode(charCodeArray);
81     }
82 
CreateNewStringFromCharCodes(const std::vector<double> & codes)83     EtsString *CreateNewStringFromCharCodes(const std::vector<double> &codes)
84     {
85         return CreateNewStringFromCharCodes(codes.begin(), codes.end());
86     }
87 
CreateNewStringFromCharCode(double code)88     static EtsString *CreateNewStringFromCharCode(double code)
89     {
90         return EtsString::CreateNewStringFromCharCode(code);
91     }
92 
93 private:
94     RuntimeOptions options_;
95     EtsCoroutine *coroutine_ = nullptr;
96 };
97 
TEST_F(EtsStringFromCharCodeTest,CreateNewCompressedStringFromCharCodes)98 TEST_F(EtsStringFromCharCodeTest, CreateNewCompressedStringFromCharCodes)
99 {
100     EtsString *expectedCompressedString = EtsString::CreateFromMUtf8("Helloff\n");
101     EtsString *stringFromCompressedCharCodes =
102         CreateNewStringFromCharCodes({0x48, 0x65, 0x6C, 0x6C, 0x6F, 4294901862, 0xffff0066, 10.316});
103     ASSERT_TRUE(stringFromCompressedCharCodes->GetCoreType()->IsMUtf8());
104     ASSERT_TRUE(coretypes::String::StringsAreEqual(expectedCompressedString->GetCoreType(),
105                                                    stringFromCompressedCharCodes->GetCoreType()));
106 }
107 
TEST_F(EtsStringFromCharCodeTest,CreateNewCompressedStringFromCharCode)108 TEST_F(EtsStringFromCharCodeTest, CreateNewCompressedStringFromCharCode)
109 {
110     EtsString *expectedCompressedString = EtsString::CreateFromMUtf8("A");
111     EtsString *stringFromCompressedCharCodes = CreateNewStringFromCharCodes({0x41});
112     ASSERT_TRUE(stringFromCompressedCharCodes->GetCoreType()->IsMUtf8());
113     ASSERT_TRUE(coretypes::String::StringsAreEqual(expectedCompressedString->GetCoreType(),
114                                                    stringFromCompressedCharCodes->GetCoreType()));
115 
116     EtsString *stringFromCompressedCharCode = CreateNewStringFromCharCode(0x41);
117     ASSERT_TRUE(stringFromCompressedCharCode->GetCoreType()->IsMUtf8());
118     ASSERT_TRUE(coretypes::String::StringsAreEqual(expectedCompressedString->GetCoreType(),
119                                                    stringFromCompressedCharCode->GetCoreType()));
120 }
121 
TEST_F(EtsStringFromCharCodeTest,CreateNewUncompressedStringFromCharCode)122 TEST_F(EtsStringFromCharCodeTest, CreateNewUncompressedStringFromCharCode)
123 {
124     std::vector<uint16_t> data = {0x3B2};
125     EtsString *expectedUncompressedString = EtsString::CreateFromUtf16(data.data(), static_cast<ets_int>(data.size()));
126     EtsString *stringFromUncompressedCharCodes = CreateNewStringFromCharCodes({0x3B2});
127     ASSERT_TRUE(stringFromUncompressedCharCodes->GetCoreType()->IsUtf16());
128     ASSERT_TRUE(coretypes::String::StringsAreEqual(expectedUncompressedString->GetCoreType(),
129                                                    stringFromUncompressedCharCodes->GetCoreType()));
130 
131     EtsString *stringFromUncompressedCharCode = CreateNewStringFromCharCode(0x3B2);
132     ASSERT_TRUE(stringFromUncompressedCharCode->GetCoreType()->IsUtf16());
133     ASSERT_TRUE(coretypes::String::StringsAreEqual(expectedUncompressedString->GetCoreType(),
134                                                    stringFromUncompressedCharCode->GetCoreType()));
135 }
136 
TEST_F(EtsStringFromCharCodeTest,CreateNewUncompressedStringFromCharCodes)137 TEST_F(EtsStringFromCharCodeTest, CreateNewUncompressedStringFromCharCodes)
138 {
139     std::vector<uint16_t> data = {0x3B2, 'A', 'B', 'C', 'D', 0xac, 0xff9c, 0, 0xffff, 1, 0xffff, 0, 0, 0};
140     EtsString *expectedUncompressedString = EtsString::CreateFromUtf16(data.data(), static_cast<ets_int>(data.size()));
141     std::vector<double> charCodes {0x3B2,
142                                    0x41,
143                                    66.3,
144                                    67.00009,
145                                    68.99998,
146                                    172.9999,
147                                    -100,
148                                    static_cast<double>(0x7fffffffffffffff),
149                                    static_cast<double>(0x1fffffffffffff),
150                                    static_cast<double>(-0x1fffffffffffff),
151                                    static_cast<double>(0xffff),
152                                    static_cast<double>(0x10000),
153                                    static_cast<double>(0x8000000000000000),
154                                    0};
155     EtsString *stringFromUncompressedCharCodes = CreateNewStringFromCharCodes(charCodes);
156     ASSERT_TRUE(stringFromUncompressedCharCodes->GetCoreType()->IsUtf16());
157     ASSERT_TRUE(coretypes::String::StringsAreEqual(expectedUncompressedString->GetCoreType(),
158                                                    stringFromUncompressedCharCodes->GetCoreType()));
159 }
160 
TEST_F(EtsStringFromCharCodeTest,CreateNewEmptyStringFromCharCode)161 TEST_F(EtsStringFromCharCodeTest, CreateNewEmptyStringFromCharCode)
162 {
163     EtsString *emptyString = EtsString::CreateNewEmptyString();
164     EtsString *stringFromCharCodes = CreateNewStringFromCharCodes({});
165     ASSERT_TRUE(stringFromCharCodes->GetCoreType()->IsMUtf8());
166     ASSERT_TRUE(coretypes::String::StringsAreEqual(emptyString->GetCoreType(), stringFromCharCodes->GetCoreType()));
167 }
168 
TEST_F(EtsStringFromCharCodeTest,CreateNewStringFromNaNCharCode)169 TEST_F(EtsStringFromCharCodeTest, CreateNewStringFromNaNCharCode)
170 {
171     std::vector<uint16_t> data = {0};
172     EtsString *expectedUncompressedString = EtsString::CreateFromUtf16(data.data(), static_cast<ets_int>(data.size()));
173     EtsString *stringFromUncompressedCharCodes =
174         CreateNewStringFromCharCodes({std::numeric_limits<double>::quiet_NaN()});
175     ASSERT_TRUE(stringFromUncompressedCharCodes->GetCoreType()->IsUtf16());
176     ASSERT_TRUE(coretypes::String::StringsAreEqual(expectedUncompressedString->GetCoreType(),
177                                                    stringFromUncompressedCharCodes->GetCoreType()));
178 
179     EtsString *stringFromUncompressedCharCode = CreateNewStringFromCharCode(std::numeric_limits<double>::quiet_NaN());
180     ASSERT_TRUE(stringFromUncompressedCharCode->GetCoreType()->IsUtf16());
181     ASSERT_TRUE(coretypes::String::StringsAreEqual(expectedUncompressedString->GetCoreType(),
182                                                    stringFromUncompressedCharCode->GetCoreType()));
183 }
184 
TEST_F(EtsStringFromCharCodeTest,CreateNewStringFromInfinityCharCode)185 TEST_F(EtsStringFromCharCodeTest, CreateNewStringFromInfinityCharCode)
186 {
187     std::vector<uint16_t> data = {0};
188     EtsString *expectedUncompressedString = EtsString::CreateFromUtf16(data.data(), static_cast<ets_int>(data.size()));
189     EtsString *stringFromUncompressedCharCodes =
190         CreateNewStringFromCharCodes({std::numeric_limits<double>::infinity()});
191     ASSERT_TRUE(stringFromUncompressedCharCodes->GetCoreType()->IsUtf16());
192     ASSERT_TRUE(coretypes::String::StringsAreEqual(expectedUncompressedString->GetCoreType(),
193                                                    stringFromUncompressedCharCodes->GetCoreType()));
194 
195     EtsString *stringFromUncompressedCharCode = CreateNewStringFromCharCode(std::numeric_limits<double>::infinity());
196     ASSERT_TRUE(stringFromUncompressedCharCode->GetCoreType()->IsUtf16());
197     ASSERT_TRUE(coretypes::String::StringsAreEqual(expectedUncompressedString->GetCoreType(),
198                                                    stringFromUncompressedCharCode->GetCoreType()));
199 }
200 
TEST_F(EtsStringFromCharCodeTest,CreateNewStringFromNaNAndInfinityCharCodes)201 TEST_F(EtsStringFromCharCodeTest, CreateNewStringFromNaNAndInfinityCharCodes)
202 {
203     std::vector<uint16_t> data = {0, 0, 0};
204     EtsString *expectedUncompressedString = EtsString::CreateFromUtf16(data.data(), static_cast<ets_int>(data.size()));
205     EtsString *stringFromUncompressedCharCodes =
206         CreateNewStringFromCharCodes({std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::infinity(),
207                                       -std::numeric_limits<double>::infinity()});
208     ASSERT_TRUE(stringFromUncompressedCharCodes->GetCoreType()->IsUtf16());
209     ASSERT_TRUE(coretypes::String::StringsAreEqual(expectedUncompressedString->GetCoreType(),
210                                                    stringFromUncompressedCharCodes->GetCoreType()));
211 }
212 
TEST_F(EtsStringFromCharCodeTest,CreateNewStringFromMaxAvailableCharCode)213 TEST_F(EtsStringFromCharCodeTest, CreateNewStringFromMaxAvailableCharCode)
214 {
215     std::vector<uint16_t> data = {0xffff};
216     EtsString *expectedUncompressedString = EtsString::CreateFromUtf16(data.data(), static_cast<ets_int>(data.size()));
217     EtsString *stringFromMaxCharCodes1 = CreateNewStringFromCharCodes({9007199254740991.0});
218     ASSERT_TRUE(stringFromMaxCharCodes1->GetCoreType()->IsUtf16());
219     ASSERT_TRUE(coretypes::String::StringsAreEqual(expectedUncompressedString->GetCoreType(),
220                                                    stringFromMaxCharCodes1->GetCoreType()));
221 
222     EtsString *stringFromMaxCharCode1 = CreateNewStringFromCharCode(9007199254740991.0);
223     ASSERT_TRUE(stringFromMaxCharCode1->GetCoreType()->IsUtf16());
224     ASSERT_TRUE(coretypes::String::StringsAreEqual(expectedUncompressedString->GetCoreType(),
225                                                    stringFromMaxCharCode1->GetCoreType()));
226 }
227 
TEST_F(EtsStringFromCharCodeTest,CreateNewStringFromMinAvailableCharCode)228 TEST_F(EtsStringFromCharCodeTest, CreateNewStringFromMinAvailableCharCode)
229 {
230     EtsString *expectedCompressedString = EtsString::CreateFromMUtf8("\x01");
231     EtsString *stringFromMaxCharCodes1 = CreateNewStringFromCharCodes({-9007199254740991.0});
232     ASSERT_TRUE(stringFromMaxCharCodes1->GetCoreType()->IsMUtf8());
233     ASSERT_TRUE(coretypes::String::StringsAreEqual(expectedCompressedString->GetCoreType(),
234                                                    stringFromMaxCharCodes1->GetCoreType()));
235 
236     EtsString *stringFromMaxCharCode1 = CreateNewStringFromCharCode(-9007199254740991.0);
237     ASSERT_TRUE(stringFromMaxCharCode1->GetCoreType()->IsMUtf8());
238     ASSERT_TRUE(coretypes::String::StringsAreEqual(expectedCompressedString->GetCoreType(),
239                                                    stringFromMaxCharCode1->GetCoreType()));
240 }
241 
TEST_F(EtsStringFromCharCodeTest,CreateNewStringFromHugeCharCode)242 TEST_F(EtsStringFromCharCodeTest, CreateNewStringFromHugeCharCode)
243 {
244     std::vector<uint16_t> data = {0};
245     EtsString *expectedUncompressedString = EtsString::CreateFromUtf16(data.data(), static_cast<ets_int>(data.size()));
246     EtsString *stringFromHugeCharCodes1 = CreateNewStringFromCharCodes({18446744073709551616.0});
247     ASSERT_TRUE(stringFromHugeCharCodes1->GetCoreType()->IsUtf16());
248     ASSERT_TRUE(coretypes::String::StringsAreEqual(expectedUncompressedString->GetCoreType(),
249                                                    stringFromHugeCharCodes1->GetCoreType()));
250 
251     EtsString *stringFromHugeCharCode1 = CreateNewStringFromCharCode(18446744073709551616.0);
252     ASSERT_TRUE(stringFromHugeCharCode1->GetCoreType()->IsUtf16());
253     ASSERT_TRUE(coretypes::String::StringsAreEqual(expectedUncompressedString->GetCoreType(),
254                                                    stringFromHugeCharCode1->GetCoreType()));
255 
256     EtsString *stringFromHugeCharCodes2 = CreateNewStringFromCharCodes({18446744073709551617.0});
257     ASSERT_TRUE(stringFromHugeCharCodes2->GetCoreType()->IsUtf16());
258     ASSERT_TRUE(coretypes::String::StringsAreEqual(expectedUncompressedString->GetCoreType(),
259                                                    stringFromHugeCharCodes2->GetCoreType()));
260 
261     EtsString *stringFromHugeCharCode2 = CreateNewStringFromCharCode(18446744073709551617.0);
262     ASSERT_TRUE(stringFromHugeCharCode2->GetCoreType()->IsUtf16());
263     ASSERT_TRUE(coretypes::String::StringsAreEqual(expectedUncompressedString->GetCoreType(),
264                                                    stringFromHugeCharCode2->GetCoreType()));
265 
266     EtsString *stringFromHugeCharCodes3 = CreateNewStringFromCharCodes({9007199254740992.0});
267     ASSERT_TRUE(stringFromHugeCharCodes3->GetCoreType()->IsUtf16());
268     ASSERT_TRUE(coretypes::String::StringsAreEqual(expectedUncompressedString->GetCoreType(),
269                                                    stringFromHugeCharCodes3->GetCoreType()));
270 
271     EtsString *stringFromHugeCharCode3 = CreateNewStringFromCharCode(9007199254740992.0);
272     ASSERT_TRUE(stringFromHugeCharCode3->GetCoreType()->IsUtf16());
273     ASSERT_TRUE(coretypes::String::StringsAreEqual(expectedUncompressedString->GetCoreType(),
274                                                    stringFromHugeCharCode3->GetCoreType()));
275 }
276 
TEST_F(EtsStringFromCharCodeTest,CreateNewStringFromHugeNegativeCharCode)277 TEST_F(EtsStringFromCharCodeTest, CreateNewStringFromHugeNegativeCharCode)
278 {
279     std::vector<uint16_t> data = {0};
280     EtsString *expectedUncompressedString = EtsString::CreateFromUtf16(data.data(), static_cast<ets_int>(data.size()));
281     EtsString *stringFromHugeCharCodes1 = CreateNewStringFromCharCodes({-18446744073709551616.0});
282     ASSERT_TRUE(stringFromHugeCharCodes1->GetCoreType()->IsUtf16());
283     ASSERT_TRUE(coretypes::String::StringsAreEqual(expectedUncompressedString->GetCoreType(),
284                                                    stringFromHugeCharCodes1->GetCoreType()));
285 
286     EtsString *stringFromHugeCharCode1 = CreateNewStringFromCharCode(-18446744073709551616.0);
287     ASSERT_TRUE(stringFromHugeCharCode1->GetCoreType()->IsUtf16());
288     ASSERT_TRUE(coretypes::String::StringsAreEqual(expectedUncompressedString->GetCoreType(),
289                                                    stringFromHugeCharCode1->GetCoreType()));
290 
291     EtsString *stringFromHugeCharCodes2 = CreateNewStringFromCharCodes({-18446744073709551617.0});
292     ASSERT_TRUE(stringFromHugeCharCodes2->GetCoreType()->IsUtf16());
293     ASSERT_TRUE(coretypes::String::StringsAreEqual(expectedUncompressedString->GetCoreType(),
294                                                    stringFromHugeCharCodes2->GetCoreType()));
295 
296     EtsString *stringFromHugeCharCode2 = CreateNewStringFromCharCode(-18446744073709551617.0);
297     ASSERT_TRUE(stringFromHugeCharCode2->GetCoreType()->IsUtf16());
298     ASSERT_TRUE(coretypes::String::StringsAreEqual(expectedUncompressedString->GetCoreType(),
299                                                    stringFromHugeCharCode2->GetCoreType()));
300 
301     EtsString *stringFromHugeCharCodes3 = CreateNewStringFromCharCodes({-9007199254740992.0});
302     ASSERT_TRUE(stringFromHugeCharCodes3->GetCoreType()->IsUtf16());
303     ASSERT_TRUE(coretypes::String::StringsAreEqual(expectedUncompressedString->GetCoreType(),
304                                                    stringFromHugeCharCodes3->GetCoreType()));
305 
306     EtsString *stringFromHugeCharCode3 = CreateNewStringFromCharCode(-9007199254740992.0);
307     ASSERT_TRUE(stringFromHugeCharCode3->GetCoreType()->IsUtf16());
308     ASSERT_TRUE(coretypes::String::StringsAreEqual(expectedUncompressedString->GetCoreType(),
309                                                    stringFromHugeCharCode3->GetCoreType()));
310 }
311 
TEST_F(EtsStringFromCharCodeTest,CreateNewStringFromHugeCharCodes)312 TEST_F(EtsStringFromCharCodeTest, CreateNewStringFromHugeCharCodes)
313 {
314     std::vector<uint16_t> data = {0, 0, 0, 0, 0, 0, 0xffff, 0x1};
315     EtsString *expectedUncompressedString = EtsString::CreateFromUtf16(data.data(), static_cast<ets_int>(data.size()));
316     std::vector<double> charCodes {18446744073709551616.0,  18446744073709551617.0,  9007199254740992.0,
317                                    -18446744073709551616.0, -18446744073709551617.0, -9007199254740992.0,
318                                    9007199254740991.0,      -9007199254740991.0};
319     EtsString *stringFromHugeCharCodes = CreateNewStringFromCharCodes(charCodes);
320     ASSERT_TRUE(stringFromHugeCharCodes->GetCoreType()->IsUtf16());
321     ASSERT_TRUE(coretypes::String::StringsAreEqual(expectedUncompressedString->GetCoreType(),
322                                                    stringFromHugeCharCodes->GetCoreType()));
323 }
324 }  // namespace ark::ets::test
325 
326 // NOLINTEND(readability-magic-numbers)
327