1 /*
2 * Copyright (c) 2022 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/template_string.h"
17 #include "ecmascript/builtins/builtins_string.h"
18 #include "ecmascript/global_env.h"
19 #include "ecmascript/template_map.h"
20 #include "ecmascript/tests/test_helper.h"
21
22 using namespace panda;
23 using namespace panda::ecmascript;
24
25 namespace panda::test {
26 using BuiltinsString = ecmascript::builtins::BuiltinsString;
27 class TemplateStringTest : public testing::Test {
28 public:
SetUpTestCase()29 static void SetUpTestCase()
30 {
31 GTEST_LOG_(INFO) << "SetUpTestCase";
32 }
33
TearDownTestCase()34 static void TearDownTestCase()
35 {
36 GTEST_LOG_(INFO) << "TearDownCase";
37 }
38
SetUp()39 void SetUp() override
40 {
41 TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
42 }
43
TearDown()44 void TearDown() override
45 {
46 TestHelper::DestroyEcmaVMWithScope(instance, scope);
47 }
48
49 EcmaVM *instance {nullptr};
50 EcmaHandleScope *scope {nullptr};
51 JSThread *thread {nullptr};
52 };
53
54 /*
55 * @tc.name: GetTemplateObject
56 * @tc.desc: Call the function "arraycreate" to create a jsarray object, add key value pairs, and then call the
57 * "NewTagedArray" function to nest the jsarray object. Call the function createarrayfromlist to create
58 * a template literal, pass it to the "GetTemplateObject" function, check whether the templatemap object
59 * getted from env can find the jsarray object, then call the 'Raw' function to check whether the returned
60 * value is within expectations.
61 * @tc.type: FUNC
62 * @tc.require:
63 */
HWTEST_F_L0(TemplateStringTest,GetTemplateObject)64 HWTEST_F_L0(TemplateStringTest, GetTemplateObject)
65 {
66 uint32_t arrayLength = 3;
67 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
68 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
69 JSHandle<JSTaggedValue> templateMapTag = env->GetTemplateMap();
70 JSHandle<TemplateMap> templateMap(templateMapTag);
71 JSHandle<JSTaggedValue> rawKey(factory->NewFromASCII("raw"));
72 JSHandle<EcmaString> testString = factory->NewFromASCII("bar2bazJavaScriptbaz");
73 JSHandle<EcmaString> javaScript = factory->NewFromASCII("JavaScript");
74 JSHandle<TaggedArray> elements = factory->NewTaggedArray(arrayLength);
75 // create jsArray object
76 JSArray *arr = JSArray::ArrayCreate(thread, JSTaggedNumber(arrayLength)).GetObject<JSArray>();
77 JSHandle<JSTaggedValue> jsArrayObj(thread, arr);
78 // add key and value to the first index
79 JSHandle<JSTaggedValue> arrayObjVal(factory->NewFromASCII("bar"));
80 PropertyDescriptor propertyDesc(thread, arrayObjVal, true, true, true);
81 JSHandle<JSTaggedValue> arrayObjKey(factory->NewFromASCII("0"));
82 JSArray::DefineOwnProperty(thread, JSHandle<JSObject>(jsArrayObj), arrayObjKey, propertyDesc);
83 // add key and value to the second index
84 JSHandle<JSTaggedValue> arrayObjVal1(factory->NewFromASCII("baz"));
85 PropertyDescriptor propertyDesc1(thread, arrayObjVal1, true, true, true);
86 JSHandle<JSTaggedValue> arrayObjKey1(factory->NewFromASCII("1"));
87 JSArray::DefineOwnProperty(thread, JSHandle<JSObject>(jsArrayObj), arrayObjKey1, propertyDesc1);
88 // add key and value to the third index
89 JSHandle<JSTaggedValue> arrayObjVal2(factory->NewFromASCII("foo"));
90 PropertyDescriptor propertyDesc2(thread, arrayObjVal1, true, true, true);
91 JSHandle<JSTaggedValue> arrayObjKey2(factory->NewFromASCII("2"));
92 JSArray::DefineOwnProperty(thread, JSHandle<JSObject>(jsArrayObj), arrayObjKey2, propertyDesc2);
93 // create the list from jsArray
94 elements->Set(thread, 0, jsArrayObj);
95 elements->Set(thread, 1, jsArrayObj);
96 JSHandle<JSTaggedValue> templateLiteral(JSArray::CreateArrayFromList(thread, elements));
97 // call "GetTemplateObject" function
98 JSHandle<JSTaggedValue> templateObject = TemplateString::GetTemplateObject(thread, templateLiteral);
99 // find jsArray in templateMap
100 int resultEntry = templateMap->FindEntry(jsArrayObj.GetTaggedValue());
101 EXPECT_NE(resultEntry, -1);
102 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 10);
103 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
104 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
105 ecmaRuntimeCallInfo->SetCallArg(0, templateObject.GetTaggedValue());
106 ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue(static_cast<int32_t>(2)));
107 ecmaRuntimeCallInfo->SetCallArg(2, javaScript.GetTaggedValue());
108 // call "Raw" function
109 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
110 JSTaggedValue result = BuiltinsString::Raw(ecmaRuntimeCallInfo);
111 TestHelper::TearDownFrame(thread, prev);
112
113 EXPECT_TRUE(result.IsString());
114 EXPECT_TRUE(EcmaStringAccessor::StringsAreEqual(reinterpret_cast<EcmaString *>(result.GetRawData()), *testString));
115 }
116 } // namespace panda::test