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_boolean.h"
17
18#include "ecmascript/ecma_runtime_call_info.h"
19#include "ecmascript/ecma_string.h"
20#include "ecmascript/ecma_vm.h"
21#include "ecmascript/global_env.h"
22#include "ecmascript/js_primitive_ref.h"
23#include "ecmascript/js_tagged_value-inl.h"
24#include "ecmascript/js_thread.h"
25#include "ecmascript/object_factory.h"
26#include "ecmascript/tests/test_helper.h"
27
28using namespace panda::ecmascript;
29using namespace panda::ecmascript::builtins;
30using BuiltinsBase = panda::ecmascript::base::BuiltinsBase;
31
32namespace panda::test {
33class BuiltinsBooleanTest : public BaseTestWithScope<false> {
34};
35
36// new Boolean(123)
37HWTEST_F_L0(BuiltinsBooleanTest, BooleanConstructor)
38{
39    JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
40
41    JSHandle<JSFunction> boolean(env->GetBooleanFunction());
42    JSHandle<JSObject> globalObject(thread, env->GetGlobalObject());
43
44    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*boolean), 6);
45    ecmaRuntimeCallInfo->SetFunction(boolean.GetTaggedValue());
46    ecmaRuntimeCallInfo->SetThis(globalObject.GetTaggedValue());
47    ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(123)));
48
49    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
50    JSTaggedValue result = BuiltinsBoolean::BooleanConstructor(ecmaRuntimeCallInfo);
51
52    ASSERT_TRUE(result.IsECMAObject());
53    ASSERT_EQ(JSPrimitiveRef::Cast(result.GetTaggedObject())->GetValue().IsTrue(), 1);
54}
55
56// new Boolean(undefined)
57HWTEST_F_L0(BuiltinsBooleanTest, BooleanConstructor1)
58{
59    JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
60
61    JSHandle<JSFunction> boolean(env->GetBooleanFunction());
62    JSHandle<JSObject> globalObject(thread, env->GetGlobalObject());
63
64    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*boolean), 6);
65    ecmaRuntimeCallInfo->SetFunction(boolean.GetTaggedValue());
66    ecmaRuntimeCallInfo->SetThis(globalObject.GetTaggedValue());
67    ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue::Undefined());
68
69    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
70    JSTaggedValue result = BuiltinsBoolean::BooleanConstructor(ecmaRuntimeCallInfo);
71
72    ASSERT_TRUE(result.IsECMAObject());
73    ASSERT_EQ(JSPrimitiveRef::Cast(result.GetTaggedObject())->GetValue().IsFalse(), 1);
74}
75
76// Boolean("helloworld")
77HWTEST_F_L0(BuiltinsBooleanTest, BooleanConstructor2)
78{
79    JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
80
81    JSHandle<JSFunction> boolean(env->GetBooleanFunction());
82    JSHandle<JSObject> globalObject(thread, env->GetGlobalObject());
83    JSHandle<EcmaString> str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("helloworld");
84
85    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
86    ecmaRuntimeCallInfo->SetFunction(boolean.GetTaggedValue());
87    ecmaRuntimeCallInfo->SetThis(globalObject.GetTaggedValue());
88    ecmaRuntimeCallInfo->SetCallArg(0, str.GetTaggedValue());
89
90    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
91    JSTaggedValue result = BuiltinsBoolean::BooleanConstructor(ecmaRuntimeCallInfo);
92
93    JSTaggedValue ruler = BuiltinsBase::GetTaggedBoolean(true);
94    ASSERT_EQ(result.GetRawData(), ruler.GetRawData());
95}
96
97// false.toString()
98HWTEST_F_L0(BuiltinsBooleanTest, BooleanPrototypeToString)
99{
100    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
101    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
102    ecmaRuntimeCallInfo->SetThis(JSTaggedValue::False());
103
104    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
105    JSTaggedValue result = BuiltinsBoolean::BooleanPrototypeToString(ecmaRuntimeCallInfo);
106    ASSERT_TRUE(result.IsString());
107    JSHandle<EcmaString> res(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
108    auto ruler = thread->GetEcmaVM()->GetFactory()->NewFromASCII("false");
109    ASSERT_EQ(EcmaStringAccessor::Compare(instance, res, ruler), 0);
110}
111
112// (new Boolean(true)).toString()
113HWTEST_F_L0(BuiltinsBooleanTest, BooleanPrototypeToString1)
114{
115    auto ecmaVM = thread->GetEcmaVM();
116    JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
117
118    JSHandle<JSFunction> booleanObject(env->GetBooleanFunction());
119    JSHandle<JSTaggedValue> value(thread, JSTaggedValue::True());
120    JSHandle<JSPrimitiveRef> boolean = thread->GetEcmaVM()->GetFactory()->NewJSPrimitiveRef(booleanObject, value);
121
122    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
123    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
124    ecmaRuntimeCallInfo->SetThis(boolean.GetTaggedValue());
125
126    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
127    JSTaggedValue result = BuiltinsBoolean::BooleanPrototypeToString(ecmaRuntimeCallInfo);
128    ASSERT_TRUE(result.IsString());
129    JSHandle<EcmaString> res(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
130    auto ruler = thread->GetEcmaVM()->GetFactory()->NewFromASCII("true");
131    ASSERT_EQ(EcmaStringAccessor::Compare(instance, res, ruler), 0);
132}
133
134// true.valueOf()
135HWTEST_F_L0(BuiltinsBooleanTest, BooleanPrototypeValueOf)
136{
137    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
138    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
139    ecmaRuntimeCallInfo->SetThis(JSTaggedValue::True());
140
141    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
142    JSTaggedValue result = BuiltinsBoolean::BooleanPrototypeValueOf(ecmaRuntimeCallInfo);
143
144    JSTaggedValue ruler = BuiltinsBase::GetTaggedBoolean(true);
145    ASSERT_EQ(result.GetRawData(), ruler.GetRawData());
146}
147
148// (new Boolean(false)).valueOf()
149HWTEST_F_L0(BuiltinsBooleanTest, BooleanPrototypeValueOf1)
150{
151    auto ecmaVM = thread->GetEcmaVM();
152    JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
153
154    JSHandle<JSFunction> booleanObject(env->GetBooleanFunction());
155    JSHandle<JSTaggedValue> value(thread, JSTaggedValue::False());
156    JSHandle<JSPrimitiveRef> boolean = thread->GetEcmaVM()->GetFactory()->NewJSPrimitiveRef(booleanObject, value);
157
158    auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
159    ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
160    ecmaRuntimeCallInfo->SetThis(boolean.GetTaggedValue());
161
162    [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
163    JSTaggedValue result = BuiltinsBoolean::BooleanPrototypeValueOf(ecmaRuntimeCallInfo);
164
165    JSTaggedValue ruler = BuiltinsBase::GetTaggedBoolean(false);
166    ASSERT_EQ(result.GetRawData(), ruler.GetRawData());
167}
168}  // namespace panda::test
169