1 /**
2 * Copyright (c) 2023 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 <cmath>
17
18 #include "arkplatform_jsnapi.h"
19 #include "libpandabase/utils/bit_utils.h"
20 #include <gtest/gtest.h>
21
22 namespace arkplatform {
23 namespace test {
24 class JSNapiTest : public ::testing::Test {
25 public:
26
ToJSTaggedValue(JSValueRef *obj)27 JSTaggedType ToJSTaggedValue(JSValueRef *obj)
28 {
29 return *reinterpret_cast<JSTaggedType*>(obj);
30 }
31
ConvertDouble(double val)32 JSTaggedType ConvertDouble(double val)
33 {
34 return panda::bit_cast<JSTaggedType>(val) + JSValueRefInternals::DOUBLE_ENCODE_OFFSET;
35 }
36
37 template<typename T>
TestNumberRef(T val, JSTaggedType expected)38 void TestNumberRef(T val, JSTaggedType expected)
39 {
40 LocalScope scope(vm_);
41 Local<NumberRef> obj = NumberRef::New(vm_, val);
42 ASSERT_TRUE(obj->IsNumber());
43 JSTaggedType res = ToJSTaggedValue(*obj);
44 ASSERT_EQ(res, expected);
45 if constexpr (std::is_floating_point_v<T>) {
46 if (std::isnan(val)) {
47 ASSERT_TRUE(std::isnan(obj->Value()));
48 } else {
49 ASSERT_EQ(obj->Value(), val);
50 }
51 } else if constexpr (sizeof(T) >= sizeof(int32_t)) {
52 ASSERT_EQ(obj->IntegerValue(vm_), val);
53 } else if constexpr (std::is_signed_v<T>) {
54 ASSERT_EQ(obj->Int32Value(vm_), val);
55 } else {
56 ASSERT_EQ(obj->Uint32Value(vm_), val);
57 }
58 }
59
60 void SetUp() override
61 {
62 panda::RuntimeOption option;
63 option.SetLogLevel(panda::RuntimeOption::LOG_LEVEL::ERROR);
64 vm_ = JSNApi::CreateJSVM(option);
65 ASSERT_TRUE(vm_ != nullptr) << "Cannot create Runtime";
66 }
67
68 void TearDown() override
69 {
70 JSNApi::DestroyJSVM(vm_);
71 }
72
73 protected:
74 panda::JSThread *thread_ = nullptr;
75 panda::ecmascript::EcmaVM *vm_ = nullptr;
76 };
77
78 // If this test failed, please contact with Chernykh Sergey
TEST_F(JSNapiTest, ArkplatformJSNApiTest_NumberRef)79 TEST_F(JSNapiTest, ArkplatformJSNApiTest_NumberRef)
80 {
81 // double
82 double dinput = 0.;
83 TestNumberRef(dinput, JSValueRefInternals::DOUBLE_ENCODE_OFFSET);
84 static constexpr double NAN_VALUE = std::numeric_limits<double>::quiet_NaN();
85 TestNumberRef(NAN_VALUE, ConvertDouble(NAN_VALUE));
86
87 // int32_t
88 TestNumberRef(static_cast<int32_t>(0), JSValueRefInternals::TAG_INT);
89 TestNumberRef(INT32_MIN, static_cast<JSTaggedType>(INT32_MIN) | JSValueRefInternals::TAG_INT);
90 TestNumberRef(INT32_MAX, static_cast<JSTaggedType>(INT32_MAX) | JSValueRefInternals::TAG_INT);
91
92 // uint32_t
93 TestNumberRef(static_cast<uint32_t>(0), JSValueRefInternals::TAG_INT);
94 auto u32input = static_cast<uint32_t>(INT32_MAX);
95 TestNumberRef(u32input, u32input | JSValueRefInternals::TAG_INT);
96 u32input = static_cast<uint32_t>(INT32_MAX + 1UL);
97 TestNumberRef(u32input, ConvertDouble(static_cast<double>(u32input)));
98 TestNumberRef(UINT32_MAX, ConvertDouble(static_cast<double>(UINT32_MAX)));
99
100 // int64_t
101 auto i64input = static_cast<int64_t>(INT32_MIN);
102 TestNumberRef(i64input, i64input | JSValueRefInternals::TAG_INT);
103 i64input = static_cast<int64_t>(INT32_MIN);
104 TestNumberRef(i64input, i64input | JSValueRefInternals::TAG_INT);
105 TestNumberRef(INT64_MIN, ConvertDouble(static_cast<double>(INT64_MIN)));
106 TestNumberRef(INT64_MAX, ConvertDouble(static_cast<double>(INT64_MAX)));
107 }
108
109 // If this test failed, please contact with Chernykh Sergey
TEST_F(JSNapiTest, ArkplatformJSNApiTest_BooleanRef)110 TEST_F(JSNapiTest, ArkplatformJSNApiTest_BooleanRef)
111 {
112 bool input = true;
113 Local<BooleanRef> res = BooleanRef::New(vm_, input);
114 EXPECT_TRUE(res->IsBoolean());
115 EXPECT_TRUE(res->BooleaValue(vm_));
116 ASSERT_EQ(ToJSTaggedValue(*res), JSValueRefInternals::VALUE_TRUE);
117
118 input = false;
119 res = BooleanRef::New(vm_, input);
120 EXPECT_TRUE(res->IsBoolean());
121 EXPECT_FALSE(res->BooleaValue(vm_));
122 ASSERT_EQ(ToJSTaggedValue(*res), JSValueRefInternals::VALUE_FALSE);
123 }
124
125 // If this test failed, please contact with Chernykh Sergey
TEST_F(JSNapiTest, ArkplatformJSNApiTest_NullUndefined)126 TEST_F(JSNapiTest, ArkplatformJSNApiTest_NullUndefined)
127 {
128 LocalScope scope(vm_);
129 Local<JSValueRef> null = JSValueRef::Null(vm_);
130 ASSERT_TRUE(null->IsNull());
131 ASSERT_EQ(ToJSTaggedValue(*null), JSValueRefInternals::VALUE_NULL);
132
133 Local<JSValueRef> undefined = JSValueRef::Undefined(vm_);
134 ASSERT_TRUE(undefined->IsUndefined());
135 ASSERT_EQ(ToJSTaggedValue(*undefined), JSValueRefInternals::VALUE_UNDEFINED);
136 }
137
138 } // namespace test
139 } // namespace arkplatform
140