1/*
2 * Copyright (c) 2024 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#ifndef TEST_COMMON_H
16#define TEST_COMMON_H
17#include "ecmascript/builtins/builtins_regexp.h"
18#include "ecmascript/containers/containers_private.h"
19#include "ecmascript/global_env.h"
20#include "ecmascript/object_factory.h"
21#include "ecmascript/tests/test_helper.h"
22namespace panda::test {
23using namespace panda;
24using namespace panda::ecmascript;
25using namespace panda::ecmascript::containers;
26using ecmascript::base::BuiltinsBase;
27using BuiltinsRegExp = builtins::BuiltinsRegExp;
28
29class TestCommon {
30public:
31    static JSTaggedValue CreateContainerTaggedValue(JSThread *thread, ContainerTag tag)
32    {
33        ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
34        JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
35
36        JSHandle<JSTaggedValue> globalObject = env->GetJSGlobalObject();
37        JSHandle<JSTaggedValue> key(factory->NewFromASCII("ArkPrivate"));
38        JSHandle<JSTaggedValue> value =
39            JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(globalObject), key).GetValue();
40
41        auto objCallInfo =
42            TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);  // 6 means the value
43        objCallInfo->SetFunction(JSTaggedValue::Undefined());
44        objCallInfo->SetThis(value.GetTaggedValue());
45        objCallInfo->SetCallArg(0, JSTaggedValue(static_cast<int>(tag)));
46
47        [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
48        JSTaggedValue result = ContainersPrivate::Load(objCallInfo);
49        TestHelper::TearDownFrame(thread, prev);
50        return result;
51    }
52
53    static JSTaggedValue CreateJSRegexpByPatternAndFlags(JSThread *thread, const JSHandle<EcmaString> &pattern,
54                                                         const JSHandle<EcmaString> &flags)
55    {
56        JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
57        JSHandle<JSFunction> regexp(env->GetRegExpFunction());
58        JSHandle<JSObject> globalObject(thread, env->GetGlobalObject());
59        // 8 : test case
60        auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*regexp), 8);
61        ecmaRuntimeCallInfo->SetFunction(regexp.GetTaggedValue());
62        ecmaRuntimeCallInfo->SetThis(globalObject.GetTaggedValue());
63        ecmaRuntimeCallInfo->SetCallArg(0, pattern.GetTaggedValue());
64        ecmaRuntimeCallInfo->SetCallArg(1, flags.GetTaggedValue());
65
66        [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
67        // call RegExpConstructor method
68        JSTaggedValue result = BuiltinsRegExp::RegExpConstructor(ecmaRuntimeCallInfo);
69        TestHelper::TearDownFrame(thread, prev);
70        return result;
71    }
72
73    static JSTaggedValue TestCompareFunction(EcmaRuntimeCallInfo *argv)
74    {
75        JSThread *thread = argv->GetThread();
76        JSHandle<JSTaggedValue> valueX = BuiltinsBase::GetCallArg(argv, 0);
77        JSHandle<JSTaggedValue> valueY = BuiltinsBase::GetCallArg(argv, 1);
78
79        if (valueX->IsString() && valueY->IsString()) {
80            auto xHandle = JSHandle<EcmaString>(valueX);
81            auto yHandle = JSHandle<EcmaString>(valueY);
82            int result = EcmaStringAccessor::Compare(thread->GetEcmaVM(), xHandle, yHandle);
83            if (result < 0) {
84                return JSTaggedValue(1);
85            }
86            if (result == 0) {
87                return JSTaggedValue(0);
88            }
89            return JSTaggedValue(-1);
90        }
91
92        if (valueX->IsNumber() && valueY->IsString()) {
93            return JSTaggedValue(1);
94        }
95        if (valueX->IsString() && valueY->IsNumber()) {
96            return JSTaggedValue(-1);
97        }
98
99        ComparisonResult res = ComparisonResult::UNDEFINED;
100        if (valueX->IsNumber() && valueY->IsNumber()) {
101            res = JSTaggedValue::StrictNumberCompare(valueY->GetNumber(), valueX->GetNumber());
102        } else {
103            res = JSTaggedValue::Compare(thread, valueY, valueX);
104        }
105        return res == ComparisonResult::GREAT ? JSTaggedValue(1)
106                                              : (res == ComparisonResult::LESS ? JSTaggedValue(-1) : JSTaggedValue(0));
107    }
108};
109};  // namespace panda::test
110
111#endif
112