• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "ecmascript/builtins/builtins_number.h"
17 
18 #include <cmath>
19 #include <iostream>
20 #include <limits>
21 
22 #include "ecmascript/base/number_helper.h"
23 #include "ecmascript/base/string_helper.h"
24 #include "ecmascript/ecma_runtime_call_info.h"
25 #include "ecmascript/ecma_string.h"
26 #include "ecmascript/ecma_vm.h"
27 #include "ecmascript/global_env.h"
28 #include "ecmascript/js_function.h"
29 #include "ecmascript/js_global_object.h"
30 #include "ecmascript/js_handle.h"
31 #include "ecmascript/js_primitive_ref.h"
32 #include "ecmascript/js_tagged_value-inl.h"
33 #include "ecmascript/js_thread.h"
34 #include "ecmascript/object_factory.h"
35 #include "ecmascript/tests/test_helper.h"
36 
37 using namespace panda::ecmascript;
38 using namespace panda::ecmascript::builtins;
39 
40 namespace panda::test {
41 class BuiltinsNumberTest : public testing::Test {
42 public:
SetUpTestCase()43     static void SetUpTestCase()
44     {
45         GTEST_LOG_(INFO) << "SetUpTestCase";
46     }
47 
TearDownTestCase()48     static void TearDownTestCase()
49     {
50         GTEST_LOG_(INFO) << "TearDownCase";
51     }
52 
SetUp()53     void SetUp() override
54     {
55         TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
56     }
57 
TearDown()58     void TearDown() override
59     {
60         TestHelper::DestroyEcmaVMWithScope(instance, scope);
61     }
62 
63     EcmaVM *instance {nullptr};
64     EcmaHandleScope *scope {nullptr};
65     JSThread *thread {nullptr};
66 };
67 
68 // new Number(10)
HWTEST_F_L0(BuiltinsNumberTest,NumberConstructor)69 HWTEST_F_L0(BuiltinsNumberTest, NumberConstructor)
70 {
71     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
72 
73     JSHandle<JSFunction> number(env->GetNumberFunction());
74     JSHandle<JSObject> globalObject(thread, env->GetGlobalObject());
75 
76     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*number), 6);
77     ecmaRuntimeCallInfo->SetFunction(number.GetTaggedValue());
78     ecmaRuntimeCallInfo->SetThis(globalObject.GetTaggedValue());
79     ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast<double>(5)));
80 
81     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
82     JSTaggedValue result = BuiltinsNumber::NumberConstructor(ecmaRuntimeCallInfo);
83     TestHelper::TearDownFrame(thread, prev);
84     JSTaggedValue value(static_cast<JSTaggedType>(result.GetRawData()));
85     ASSERT_TRUE(value.IsECMAObject());
86     JSPrimitiveRef *ref = JSPrimitiveRef::Cast(value.GetTaggedObject());
87     ASSERT_EQ(ref->GetValue().GetDouble(), 5.0);
88 }
89 
90 // Number.isFinite(-10)
HWTEST_F_L0(BuiltinsNumberTest,IsFinite)91 HWTEST_F_L0(BuiltinsNumberTest, IsFinite)
92 {
93     const double value = -10;
94     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
95     ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
96     ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
97     ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast<double>(value)));
98 
99     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
100     JSTaggedValue result = BuiltinsNumber::IsFinite(ecmaRuntimeCallInfo);
101     ASSERT_EQ(result.GetRawData(), JSTaggedValue::True().GetRawData());
102     TestHelper::TearDownFrame(thread, prev);
103 }
104 
105 // Number.isFinite(Number.MAX_VALUE)
HWTEST_F_L0(BuiltinsNumberTest,IsFinite1)106 HWTEST_F_L0(BuiltinsNumberTest, IsFinite1)
107 {
108     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
109     ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
110     ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
111     ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(base::MAX_VALUE));
112 
113     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
114     JSTaggedValue result = BuiltinsNumber::IsFinite(ecmaRuntimeCallInfo);
115     ASSERT_EQ(result.GetRawData(), JSTaggedValue::True().GetRawData());
116     TestHelper::TearDownFrame(thread, prev);
117 }
118 
119 // Number.isFinite("helloworld")
HWTEST_F_L0(BuiltinsNumberTest,IsFinite2)120 HWTEST_F_L0(BuiltinsNumberTest, IsFinite2)
121 {
122     JSHandle<EcmaString> test = thread->GetEcmaVM()->GetFactory()->NewFromASCII("helloworld");
123     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
124     ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
125     ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
126     ecmaRuntimeCallInfo->SetCallArg(0, test.GetTaggedValue());
127 
128     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
129     JSTaggedValue result = BuiltinsNumber::IsFinite(ecmaRuntimeCallInfo);
130     ASSERT_EQ(result.GetRawData(), JSTaggedValue::False().GetRawData());
131     TestHelper::TearDownFrame(thread, prev);
132 }
133 
134 // Number.isFinite(NaN)
HWTEST_F_L0(BuiltinsNumberTest,IsFinite3)135 HWTEST_F_L0(BuiltinsNumberTest, IsFinite3)
136 {
137     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
138     ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
139     ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
140     ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(base::NAN_VALUE));
141 
142     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
143     JSTaggedValue result = BuiltinsNumber::IsFinite(ecmaRuntimeCallInfo);
144     ASSERT_EQ(result.GetRawData(), JSTaggedValue::False().GetRawData());
145     TestHelper::TearDownFrame(thread, prev);
146 }
147 
148 // Number.isFinite(Infinity)
HWTEST_F_L0(BuiltinsNumberTest,IsFinite4)149 HWTEST_F_L0(BuiltinsNumberTest, IsFinite4)
150 {
151     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
152     ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
153     ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
154     ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(base::POSITIVE_INFINITY));
155 
156     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
157     JSTaggedValue result = BuiltinsNumber::IsFinite(ecmaRuntimeCallInfo);
158     ASSERT_EQ(result.GetRawData(), JSTaggedValue::False().GetRawData());
159     TestHelper::TearDownFrame(thread, prev);
160 }
161 
162 // Number.isFinite(undefined)
HWTEST_F_L0(BuiltinsNumberTest,IsFinite5)163 HWTEST_F_L0(BuiltinsNumberTest, IsFinite5)
164 {
165     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
166     ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
167     ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
168     ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue::Undefined());
169 
170     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
171     JSTaggedValue result = BuiltinsNumber::IsFinite(ecmaRuntimeCallInfo);
172     ASSERT_EQ(result.GetRawData(), JSTaggedValue::False().GetRawData());
173     TestHelper::TearDownFrame(thread, prev);
174 }
175 
176 // Number.isFinite(null)
HWTEST_F_L0(BuiltinsNumberTest,IsFinite6)177 HWTEST_F_L0(BuiltinsNumberTest, IsFinite6)
178 {
179     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
180     ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
181     ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
182     ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue::Null());
183 
184     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
185     JSTaggedValue result = BuiltinsNumber::IsFinite(ecmaRuntimeCallInfo);
186     ASSERT_EQ(result.GetRawData(), JSTaggedValue::False().GetRawData());
187     TestHelper::TearDownFrame(thread, prev);
188 }
189 
190 // Number.isInteger(0.1)
HWTEST_F_L0(BuiltinsNumberTest,IsInteger)191 HWTEST_F_L0(BuiltinsNumberTest, IsInteger)
192 {
193     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
194     ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
195     ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
196     ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(0.1));
197 
198     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
199     JSTaggedValue result = BuiltinsNumber::IsInteger(ecmaRuntimeCallInfo);
200     ASSERT_EQ(result.GetRawData(), JSTaggedValue::False().GetRawData());
201     TestHelper::TearDownFrame(thread, prev);
202 }
203 
204 // Number.isNaN(0.1)
HWTEST_F_L0(BuiltinsNumberTest,IsNaN)205 HWTEST_F_L0(BuiltinsNumberTest, IsNaN)
206 {
207     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
208     ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
209     ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
210     ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(0.1));
211 
212     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
213     JSTaggedValue result = BuiltinsNumber::IsNaN(ecmaRuntimeCallInfo);
214     ASSERT_EQ(result.GetRawData(), JSTaggedValue::False().GetRawData());
215     TestHelper::TearDownFrame(thread, prev);
216 }
217 
218 // new Number(123.456).toString(7)
HWTEST_F_L0(BuiltinsNumberTest,ToString)219 HWTEST_F_L0(BuiltinsNumberTest, ToString)
220 {
221     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
222     auto ecmaVM = thread->GetEcmaVM();
223     JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
224 
225     JSHandle<JSFunction> numberObject(env->GetNumberFunction());
226     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(123.456));
227     JSHandle<JSPrimitiveRef> number = thread->GetEcmaVM()->GetFactory()->NewJSPrimitiveRef(numberObject, value);
228 
229     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
230     ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
231     ecmaRuntimeCallInfo->SetThis(number.GetTaggedValue());
232     ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(7.0));
233 
234     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
235     JSTaggedValue result = BuiltinsNumber::ToString(ecmaRuntimeCallInfo);
236     ASSERT_TRUE(result.IsString());
237     JSHandle<EcmaString> res(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
238     JSHandle<EcmaString> correctResult = factory->NewFromASCII("234.312256641535441");
239     ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(*res, *correctResult));
240     TestHelper::TearDownFrame(thread, prev);
241 }
242 
243 // new Number(123.456).toExponential(5)
HWTEST_F_L0(BuiltinsNumberTest,IsExponential)244 HWTEST_F_L0(BuiltinsNumberTest, IsExponential)
245 {
246     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
247     auto ecmaVM = thread->GetEcmaVM();
248     JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
249 
250     JSHandle<JSFunction> numberObject(env->GetNumberFunction());
251     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(123.456));
252     JSHandle<JSPrimitiveRef> number = factory->NewJSPrimitiveRef(numberObject, value);
253 
254     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
255     ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
256     ecmaRuntimeCallInfo->SetThis(number.GetTaggedValue());
257     ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(5.0));
258 
259     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
260     JSTaggedValue result = BuiltinsNumber::ToExponential(ecmaRuntimeCallInfo);
261     ASSERT_TRUE(result.IsString());
262     JSHandle<EcmaString> res(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
263     JSHandle<EcmaString> correctResult = factory->NewFromASCII("1.23456e+2");
264     ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(*res, *correctResult));
265     TestHelper::TearDownFrame(thread, prev);
266 }
267 
268 // new Number(123.456).toFixed(10)
HWTEST_F_L0(BuiltinsNumberTest,ToFixed)269 HWTEST_F_L0(BuiltinsNumberTest, ToFixed)
270 {
271     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
272     auto ecmaVM = thread->GetEcmaVM();
273     JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
274 
275     JSHandle<JSFunction> numberObject(env->GetNumberFunction());
276     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(123.456));
277     JSHandle<JSPrimitiveRef> number = factory->NewJSPrimitiveRef(numberObject, value);
278 
279     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
280     ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
281     ecmaRuntimeCallInfo->SetThis(number.GetTaggedValue());
282     ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(10.0));
283 
284     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
285     JSTaggedValue result = BuiltinsNumber::ToFixed(ecmaRuntimeCallInfo);
286     ASSERT_TRUE(result.IsString());
287     JSHandle<EcmaString> res(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
288     JSHandle<EcmaString> correctResult = factory->NewFromASCII("123.4560000000");
289     ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(*res, *correctResult));
290     TestHelper::TearDownFrame(thread, prev);
291 }
292 
293 // new Number(123.456).toFixed(30)
HWTEST_F_L0(BuiltinsNumberTest,ToFixed1)294 HWTEST_F_L0(BuiltinsNumberTest, ToFixed1)
295 {
296     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
297     auto ecmaVM = thread->GetEcmaVM();
298     JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
299 
300     JSHandle<JSFunction> numberObject(env->GetNumberFunction());
301     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(123.456));
302     JSHandle<JSPrimitiveRef> number = factory->NewJSPrimitiveRef(numberObject, value);
303 
304     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
305     ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
306     ecmaRuntimeCallInfo->SetThis(number.GetTaggedValue());
307     ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(30.0));
308 
309     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
310     JSTaggedValue result = BuiltinsNumber::ToFixed(ecmaRuntimeCallInfo);
311     ASSERT_TRUE(result.IsString());
312     JSHandle<EcmaString> res(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
313     JSHandle<EcmaString> correctResult = factory->NewFromASCII("123.456000000000003069544618483633");
314     ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(*res, *correctResult));
315     TestHelper::TearDownFrame(thread, prev);
316 }
317 
318 // new Number(1e21).toFixed(20)
HWTEST_F_L0(BuiltinsNumberTest,ToFixed2)319 HWTEST_F_L0(BuiltinsNumberTest, ToFixed2) {
320     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
321     auto ecmaVM = thread->GetEcmaVM();
322     JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
323 
324     JSHandle<JSFunction> numberObject(env->GetNumberFunction());
325     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1e21));
326     JSHandle<JSPrimitiveRef> number = factory->NewJSPrimitiveRef(numberObject, value);
327 
328     auto ecmaRuntimeCallInfo =
329         TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
330     ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
331     ecmaRuntimeCallInfo->SetThis(number.GetTaggedValue());
332     ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(20.0));
333 
334     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
335     JSTaggedValue result = BuiltinsNumber::ToFixed(ecmaRuntimeCallInfo);
336     ASSERT_TRUE(result.IsString());
337     JSHandle<EcmaString> res(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
338     JSHandle<EcmaString> correctResult = factory->NewFromASCII("1e+21");
339     ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(*res, *correctResult));
340     TestHelper::TearDownFrame(thread, prev);
341 }
342 
343 // new Number(123.456).toPrecision(8)
HWTEST_F_L0(BuiltinsNumberTest,ToPrecision)344 HWTEST_F_L0(BuiltinsNumberTest, ToPrecision)
345 {
346     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
347     auto ecmaVM = thread->GetEcmaVM();
348     JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
349 
350     JSHandle<JSFunction> numberObject(env->GetNumberFunction());
351     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(123.456));
352     JSHandle<JSPrimitiveRef> number = factory->NewJSPrimitiveRef(numberObject, value);
353 
354     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
355     ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
356     ecmaRuntimeCallInfo->SetThis(number.GetTaggedValue());
357     ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(8.0));
358 
359     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
360     JSTaggedValue result = BuiltinsNumber::ToPrecision(ecmaRuntimeCallInfo);
361     ASSERT_TRUE(result.IsString());
362     JSHandle<EcmaString> res(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
363     JSHandle<EcmaString> correctResult = factory->NewFromASCII("123.45600");
364     ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(*res, *correctResult));
365     TestHelper::TearDownFrame(thread, prev);
366 }
367 
368 // Number.parseFloat(0x123)
HWTEST_F_L0(BuiltinsNumberTest,parseFloat)369 HWTEST_F_L0(BuiltinsNumberTest, parseFloat)
370 {
371     JSHandle<EcmaString> param = thread->GetEcmaVM()->GetFactory()->NewFromASCII("0x123");
372     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
373     ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
374     ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
375     ecmaRuntimeCallInfo->SetCallArg(0, param.GetTaggedValue());
376 
377     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
378     JSTaggedValue result = BuiltinsNumber::ParseFloat(ecmaRuntimeCallInfo);
379     ASSERT_EQ(result.GetRawData(), JSTaggedValue(static_cast<double>(0)).GetRawData());
380     TestHelper::TearDownFrame(thread, prev);
381 }
382 
383 // Number.parseFloat(0x123xx)
HWTEST_F_L0(BuiltinsNumberTest,parseFloat1)384 HWTEST_F_L0(BuiltinsNumberTest, parseFloat1)
385 {
386     JSHandle<EcmaString> param = thread->GetEcmaVM()->GetFactory()->NewFromASCII("0x123xx");
387     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
388     ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
389     ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
390     ecmaRuntimeCallInfo->SetCallArg(0, param.GetTaggedValue());
391 
392     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
393     JSTaggedValue result = BuiltinsNumber::ParseFloat(ecmaRuntimeCallInfo);
394     ASSERT_EQ(result.GetRawData(), JSTaggedValue(static_cast<double>(0)).GetRawData());
395     TestHelper::TearDownFrame(thread, prev);
396 }
397 
398 // Number.parseInt(0x123)
HWTEST_F_L0(BuiltinsNumberTest,parseInt)399 HWTEST_F_L0(BuiltinsNumberTest, parseInt)
400 {
401     const char *number = "0x123";
402 
403     JSHandle<EcmaString> param = thread->GetEcmaVM()->GetFactory()->NewFromASCII(number);
404     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
405     ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
406     ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
407     ecmaRuntimeCallInfo->SetCallArg(0, param.GetTaggedValue());
408     ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue(16.0));
409 
410     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
411     JSTaggedValue result = BuiltinsNumber::ParseInt(ecmaRuntimeCallInfo);
412     ASSERT_EQ(result.GetRawData(), JSTaggedValue(static_cast<int>(291)).GetRawData());
413     TestHelper::TearDownFrame(thread, prev);
414 }
415 
416 // testcases of StringToDouble flags
HWTEST_F_L0(BuiltinsNumberTest,StringToDoubleFlags)417 HWTEST_F_L0(BuiltinsNumberTest, StringToDoubleFlags)
418 {
419     JSHandle<EcmaString> str;
420     Span<const uint8_t> sp;
421     [[maybe_unused]] CVector<uint8_t> buf;
422 
423     // flags of IGNORE_TRAILING
424 
425     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("0a");
426     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
427     ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::IGNORE_TRAILING), 0);
428     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("0b");
429     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
430     ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::IGNORE_TRAILING), 0);
431     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("0o");
432     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
433     ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::IGNORE_TRAILING), 0);
434     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII(" 00x");
435     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
436     ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::IGNORE_TRAILING), 0);
437     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII(" 000.4_");
438     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
439     ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::IGNORE_TRAILING), 0.4);
440     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII(" 0010.s ");
441     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
442     ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::IGNORE_TRAILING), 10);
443     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII(" 0010e2");
444     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
445     ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::IGNORE_TRAILING), 1000);
446     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII(" 0010e+3_0");
447     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
448     ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::IGNORE_TRAILING), 10000);
449 
450     // flags of ALLOW_HEX
451     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("0x");
452     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
453     ASSERT_TRUE(std::isnan(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::ALLOW_HEX)));
454     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("  0x10 ");
455     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
456     ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::ALLOW_HEX), 16);
457     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("0x1g");
458     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
459     ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::ALLOW_HEX + base::IGNORE_TRAILING), 1);
460     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("0xh");
461     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
462     ASSERT_TRUE(std::isnan(
463         base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::ALLOW_HEX + base::IGNORE_TRAILING)));
464 
465     // flags of ALLOW_OCTAL
466     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("0O");
467     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
468     ASSERT_TRUE(std::isnan(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::ALLOW_OCTAL)));
469     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("  0o10 ");
470     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
471     ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::ALLOW_OCTAL), 8);
472     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("0o1d");
473     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
474     ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::ALLOW_OCTAL | base::IGNORE_TRAILING),
475               1);
476     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("0o8");
477     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
478     ASSERT_TRUE(std::isnan(
479         base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::ALLOW_OCTAL | base::IGNORE_TRAILING)));
480 
481     // flags of ALLOW_BINARY
482     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("0b");
483     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
484     ASSERT_TRUE(std::isnan(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::ALLOW_BINARY)));
485     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("  0b10 ");
486     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
487     ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::ALLOW_BINARY), 2);
488     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("0b1d");
489     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
490     ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::ALLOW_BINARY | base::IGNORE_TRAILING),
491               1);
492     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("0b2");
493     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
494     ASSERT_TRUE(std::isnan(
495         base::NumberHelper::StringToDouble(sp.begin(), sp.end(), 0, base::ALLOW_BINARY | base::IGNORE_TRAILING)));
496 }
497 
498 // testcases of StringToDouble radix
HWTEST_F_L0(BuiltinsNumberTest,StringToDoubleRadix)499 HWTEST_F_L0(BuiltinsNumberTest, StringToDoubleRadix)
500 {
501     JSHandle<EcmaString> str;
502     Span<const uint8_t> sp;
503     [[maybe_unused]] CVector<uint8_t> buf;
504     int radix;
505 
506     radix = 0;  // default 10
507     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII(" 100 ");
508     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
509     ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 100);
510     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII(" 100.3e2 ");
511     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
512     ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 10030);
513     radix = 1;
514     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("  0000 ");
515     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
516     ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 0);
517     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("  0001 ");
518     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
519     ASSERT_TRUE(std::isnan(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS)));
520     radix = 2;
521     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("  100 ");
522     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
523     ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 4);
524     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("  11 ");
525     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
526     ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 3);
527     radix = 3;
528     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("  100 ");
529     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
530     ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 9);
531     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("  21 ");
532     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
533     ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 7);
534     radix = 4;
535     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("  100 ");
536     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
537     ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 16);
538     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("  31 ");
539     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
540     ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 13);
541     radix = 8;
542     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("  100 ");
543     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
544     ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 64);
545     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("  71 ");
546     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
547     ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 57);
548     radix = 10;
549     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("  100 ");
550     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
551     ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 100);
552     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("  0020 ");
553     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
554     ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 20);
555     radix = 16;
556     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("  100 ");
557     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
558     ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 256);
559     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("  1e ");
560     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
561     ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 30);
562     radix = 18;
563     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("  100 ");
564     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
565     ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 324);
566     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("  1g ");
567     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
568     ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 34);
569     radix = 25;
570     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("  100 ");
571     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
572     ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 625);
573     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("  1g ");
574     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
575     ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 41);
576     radix = 36;
577     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("  100 ");
578     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
579     ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 1296);
580     str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("  1z ");
581     sp = EcmaStringAccessor(str).ToUtf8Span(buf);
582     ASSERT_EQ(base::NumberHelper::StringToDouble(sp.begin(), sp.end(), radix, base::NO_FLAGS), 71);
583 }
584 
HWTEST_F_L0(BuiltinsNumberTest,NumberToString)585 HWTEST_F_L0(BuiltinsNumberTest, NumberToString)
586 {
587     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
588     JSHandle<EcmaString> res = factory->NewFromASCII("100");
589     ASSERT_EQ(EcmaStringAccessor::Compare(*base::NumberHelper::NumberToString(thread, JSTaggedValue(100)), *res), 0);
590     res = factory->NewFromASCII("11223344");
591     ASSERT_EQ(EcmaStringAccessor::Compare(
592         *base::NumberHelper::NumberToString(thread, JSTaggedValue(11223344)), *res), 0);
593     res = factory->NewFromASCII("1234567890");
594     ASSERT_EQ(EcmaStringAccessor::Compare(
595         *base::NumberHelper::NumberToString(thread, JSTaggedValue(1234567890)), *res), 0);
596     res = factory->NewFromASCII("100");
597     ASSERT_EQ(EcmaStringAccessor::Compare(
598         *base::NumberHelper::NumberToString(thread, JSTaggedValue(double(100.0))), *res), 0);
599     res = factory->NewFromASCII("100.5");
600     ASSERT_EQ(EcmaStringAccessor::Compare(
601         *base::NumberHelper::NumberToString(thread, JSTaggedValue(double(100.5))), *res), 0);
602     res = factory->NewFromASCII("100.25");
603     ASSERT_EQ(EcmaStringAccessor::Compare(
604         *base::NumberHelper::NumberToString(thread, JSTaggedValue(double(100.25))), *res), 0);
605     res = factory->NewFromASCII("100.125");
606     ASSERT_EQ(EcmaStringAccessor::Compare(
607         *base::NumberHelper::NumberToString(thread, JSTaggedValue(double(100.125))), *res), 0);
608     res = factory->NewFromASCII("100.6125");
609     ASSERT_EQ(EcmaStringAccessor::Compare(
610         *base::NumberHelper::NumberToString(thread, JSTaggedValue(double(100.6125))), *res), 0);
611     res = factory->NewFromASCII("0.0006125");
612     ASSERT_EQ(EcmaStringAccessor::Compare(
613         *base::NumberHelper::NumberToString(thread, JSTaggedValue(double(0.0006125))), *res), 0);
614     res = factory->NewFromASCII("-0.0006125");
615     ASSERT_EQ(EcmaStringAccessor::Compare(
616         *base::NumberHelper::NumberToString(thread, JSTaggedValue(double(-0.0006125))), *res), 0);
617     res = factory->NewFromASCII("-1234567890.0006125");
618     ASSERT_EQ(EcmaStringAccessor::Compare(
619         *base::NumberHelper::NumberToString(thread, JSTaggedValue(double(-1234567890.0006125))), *res), 0);
620     res = factory->NewFromASCII("1234567890.0006125");
621     ASSERT_EQ(EcmaStringAccessor::Compare(
622         *base::NumberHelper::NumberToString(thread, JSTaggedValue(double(1234567890.0006125))), *res), 0);
623     res = factory->NewFromASCII("11234567890.000612");
624     ASSERT_EQ(EcmaStringAccessor::Compare(
625         *base::NumberHelper::NumberToString(thread, JSTaggedValue(double(11234567890.0006125))), *res), 0);
626 }
627 }  // namespace panda::test
628