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 BUILTIN_TEST_UTIL_H
16#define BUILTIN_TEST_UTIL_H
17#include "ecmascript/builtins/builtins_arraybuffer.h"
18#include "ecmascript/builtins/builtins_date_time_format.h"
19#include "ecmascript/builtins/builtins_list_format.h"
20#include "ecmascript/builtins/builtins_sendable_arraybuffer.h"
21#include "ecmascript/builtins/builtins_sharedarraybuffer.h"
22#include "ecmascript/builtins/builtins_shared_typedarray.h"
23#include "ecmascript/builtins/builtins_typedarray.h"
24#include "ecmascript/ecma_runtime_call_info.h"
25#include "ecmascript/ecma_vm.h"
26#include "ecmascript/global_env.h"
27#include "ecmascript/js_arraybuffer.h"
28#include "ecmascript/js_date_time_format.h"
29#include "ecmascript/js_handle.h"
30#include "ecmascript/shared_objects/js_shared_array.h"
31#include "ecmascript/shared_objects/js_shared_typed_array.h"
32#include "ecmascript/js_tagged_value.h"
33#include "ecmascript/js_typed_array.h"
34#include "ecmascript/tests/test_helper.h"
35namespace panda::test {
36using namespace panda::ecmascript;
37using namespace panda::ecmascript::builtins;
38class BuiltTestUtil {
39public:
40    static JSTaggedValue CreateBuiltinsArrayBuffer(JSThread *thread, int32_t length)
41    {
42        JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
43        JSHandle<JSFunction> arrayBuffer(thread, env->GetArrayBufferFunction().GetTaggedValue());
44        JSHandle<JSObject> globalObject(thread, env->GetGlobalObject());
45        // 6 : test case
46        auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, arrayBuffer.GetTaggedValue(), 6);
47        ecmaRuntimeCallInfo->SetFunction(arrayBuffer.GetTaggedValue());
48        ecmaRuntimeCallInfo->SetThis(globalObject.GetTaggedValue());
49        ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(length));
50
51        [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
52        JSTaggedValue result = BuiltinsArrayBuffer::ArrayBufferConstructor(ecmaRuntimeCallInfo);
53        TestHelper::TearDownFrame(thread, prev);
54        return result;
55    }
56
57    static JSTaggedValue CreateBuiltinsSendableArrayBuffer(JSThread *thread, int32_t length)
58    {
59        JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
60        JSHandle<JSFunction> arrayBuffer(thread, env->GetSBuiltininArrayBufferFunction().GetTaggedValue());
61        JSHandle<JSObject> globalObject(thread, env->GetGlobalObject());
62        // 6 : test case
63        auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, arrayBuffer.GetTaggedValue(), 6);
64        ecmaRuntimeCallInfo->SetFunction(arrayBuffer.GetTaggedValue());
65        ecmaRuntimeCallInfo->SetThis(globalObject.GetTaggedValue());
66        ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(length));
67
68        [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
69        JSTaggedValue result = BuiltinsSendableArrayBuffer::ArrayBufferConstructor(ecmaRuntimeCallInfo);
70        TestHelper::TearDownFrame(thread, prev);
71        return result;
72    }
73
74    static JSTaggedValue CreateBuiltinsSharedArrayBuffer(JSThread *thread, int32_t length)
75    {
76        JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
77        JSHandle<JSFunction> sharedArrayBuffer(thread, env->GetSharedArrayBufferFunction().GetTaggedValue());
78        JSHandle<JSObject> globalObject(thread, env->GetGlobalObject());
79        // 6 : test case
80        auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, sharedArrayBuffer.GetTaggedValue(), 6);
81        ecmaRuntimeCallInfo->SetFunction(sharedArrayBuffer.GetTaggedValue());
82        ecmaRuntimeCallInfo->SetThis(globalObject.GetTaggedValue());
83        ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(length));
84
85        [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
86        JSTaggedValue result = BuiltinsSharedArrayBuffer::SharedArrayBufferConstructor(ecmaRuntimeCallInfo);
87        TestHelper::TearDownFrame(thread, prev);
88        return result;
89    }
90
91    static JSTypedArray *CreateTypedArray(JSThread *thread, const JSHandle<TaggedArray> &array)
92    {
93        auto ecmaVM = thread->GetEcmaVM();
94        JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
95
96        JSHandle<JSTaggedValue> jsarray(JSArray::CreateArrayFromList(thread, array));
97        JSHandle<JSFunction> int8_array(env->GetInt8ArrayFunction());
98        JSHandle<JSObject> globalObject(thread, env->GetGlobalObject());
99        //  6 : test case
100        auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*int8_array), 6);
101        ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue(*int8_array));
102        ecmaRuntimeCallInfo1->SetThis(JSTaggedValue(*globalObject));
103        ecmaRuntimeCallInfo1->SetCallArg(0, jsarray.GetTaggedValue());
104
105        [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
106        JSTaggedValue result = BuiltinsTypedArray::Int8ArrayConstructor(ecmaRuntimeCallInfo1);
107        TestHelper::TearDownFrame(thread, prev);
108
109        EXPECT_TRUE(result.IsECMAObject());
110        JSTypedArray *int8arr = JSTypedArray::Cast(reinterpret_cast<TaggedObject *>(result.GetRawData()));
111        return int8arr;
112    }
113
114    static JSSharedTypedArray *CreateSharedTypedArray(JSThread *thread, const JSHandle<TaggedArray> &array)
115    {
116        auto ecmaVM = thread->GetEcmaVM();
117        JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
118
119        JSHandle<JSTaggedValue> jsarray(JSSharedArray::CreateArrayFromList(thread, array));
120        JSHandle<JSFunction> int8_array(env->GetSharedInt8ArrayFunction());
121        JSHandle<JSObject> globalObject(thread, env->GetGlobalObject());
122        //  6 : test case
123        auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*int8_array), 6);
124        ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue(*int8_array));
125        ecmaRuntimeCallInfo1->SetThis(JSTaggedValue(*globalObject));
126        ecmaRuntimeCallInfo1->SetCallArg(0, jsarray.GetTaggedValue());
127
128        [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
129        JSTaggedValue result = BuiltinsSharedTypedArray::Int8ArrayConstructor(ecmaRuntimeCallInfo1);
130        TestHelper::TearDownFrame(thread, prev);
131
132        EXPECT_TRUE(result.IsECMAObject());
133        JSSharedTypedArray *int8arr = JSSharedTypedArray::Cast(reinterpret_cast<TaggedObject *>(result.GetRawData()));
134        return int8arr;
135    }
136
137    static JSHandle<TaggedArray> DateTimeGlobalSet(JSThread *thread)
138    {
139        auto globalConst = thread->GlobalConstants();
140        ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
141
142        JSHandle<TaggedArray> keyArray = factory->NewTaggedArray(6); // 6 : 6 length
143        keyArray->Set(thread, 0, globalConst->GetHandledYearString()); // 0 : 0 first position
144        keyArray->Set(thread, 1, globalConst->GetHandledMonthString()); // 1 : 1 second position
145        keyArray->Set(thread, 2, globalConst->GetHandledDayString()); // 2 : 2 third position
146        keyArray->Set(thread, 3, globalConst->GetHandledHourString()); // 3 : 3 fourth position
147        keyArray->Set(thread, 4, globalConst->GetHandledMinuteString()); // 4 : 4 fifth position
148        keyArray->Set(thread, 5, globalConst->GetHandledSecondString()); // 5 : 5 sixth position
149        return keyArray;
150    }
151
152    static JSTaggedValue BuiltinsDateTimeOptionsSet(JSThread *thread)
153    {
154        auto globalConst = thread->GlobalConstants();
155        JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
156        ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
157
158        JSHandle<JSTaggedValue> objFun = env->GetObjectFunction();
159        JSHandle<JSObject> optionsObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun);
160
161        JSHandle<JSTaggedValue> weekDay = globalConst->GetHandledWeekdayString();
162        JSHandle<JSTaggedValue> dayPeriod = globalConst->GetHandledDayPeriodString();
163        JSHandle<JSTaggedValue> hourCycle = globalConst->GetHandledHourCycleString();
164        JSHandle<JSTaggedValue> timeZone = globalConst->GetHandledTimeZoneString();
165        JSHandle<JSTaggedValue> numicValue(factory->NewFromASCII("numeric")); // test numeric
166        JSHandle<JSTaggedValue> weekDayValue(factory->NewFromASCII("short")); // test short
167        JSHandle<JSTaggedValue> dayPeriodValue(factory->NewFromASCII("long")); // test long
168        JSHandle<JSTaggedValue> hourCycleValue(factory->NewFromASCII("h24")); // test h24
169        JSHandle<JSTaggedValue> timeZoneValue(factory->NewFromASCII("UTC")); // test UTC
170
171        JSHandle<TaggedArray> keyArray = DateTimeGlobalSet(thread);
172
173        uint32_t arrayLen = keyArray->GetLength();
174        JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
175        for (uint32_t i = 0; i < arrayLen; i++) {
176            key.Update(keyArray->Get(thread, i));
177            JSObject::SetProperty(thread, optionsObj, key, numicValue);
178        }
179        JSObject::SetProperty(thread, optionsObj, weekDay, weekDayValue);
180        JSObject::SetProperty(thread, optionsObj, dayPeriod, dayPeriodValue);
181        JSObject::SetProperty(thread, optionsObj, hourCycle, hourCycleValue);
182        JSObject::SetProperty(thread, optionsObj, timeZone, timeZoneValue);
183        return optionsObj.GetTaggedValue();
184    }
185
186    static JSTaggedValue JSDateTimeFormatCreateWithLocaleTest(JSThread *thread, JSHandle<JSTaggedValue> &locale)
187    {
188        JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
189        JSHandle<JSFunction> newTarget(env->GetDateTimeFormatFunction());
190        JSHandle<JSObject> optionsObj(thread, BuiltTestUtil::BuiltinsDateTimeOptionsSet(thread));
191
192        JSHandle<JSTaggedValue> localesString = locale;
193        auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*newTarget), 8);
194        ecmaRuntimeCallInfo->SetFunction(newTarget.GetTaggedValue());
195        ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
196        ecmaRuntimeCallInfo->SetCallArg(0, localesString.GetTaggedValue());
197        ecmaRuntimeCallInfo->SetCallArg(1, optionsObj.GetTaggedValue());
198
199        [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
200        JSTaggedValue result = BuiltinsDateTimeFormat::DateTimeFormatConstructor(ecmaRuntimeCallInfo);
201        EXPECT_TRUE(result.IsJSDateTimeFormat());
202        TestHelper::TearDownFrame(thread, prev);
203        return result;
204    }
205
206    static JSTaggedValue JSListFormatCreateWithOptionTest(JSThread *thread, JSHandle<JSTaggedValue> &locale,
207                                                      JSHandle<JSTaggedValue> &typeValue)
208    {
209        ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
210        JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
211        JSHandle<JSFunction> newTarget(env->GetListFormatFunction());
212        JSHandle<JSTaggedValue> objFun = env->GetObjectFunction();
213        JSHandle<JSObject> optionsObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun);
214
215        JSHandle<JSTaggedValue> typeKey = thread->GlobalConstants()->GetHandledTypeString();
216        JSObject::SetProperty(thread, optionsObj, typeKey, typeValue);
217
218        auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*newTarget), 8);
219        ecmaRuntimeCallInfo->SetFunction(newTarget.GetTaggedValue());
220        ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
221        ecmaRuntimeCallInfo->SetCallArg(0, locale.GetTaggedValue());
222        ecmaRuntimeCallInfo->SetCallArg(1, optionsObj.GetTaggedValue());
223
224        [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
225        JSTaggedValue result = BuiltinsListFormat::ListFormatConstructor(ecmaRuntimeCallInfo);
226        TestHelper::TearDownFrame(thread, prev);
227
228        EXPECT_TRUE(result.IsJSListFormat());
229        return result;
230    }
231};
232};  // namespace panda::test
233#endif
234