• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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/js_object-inl.h"
17 #include "ecmascript/tests/test_helper.h"
18 #include "ecmascript/ecma_vm.h"
19 #include "ecmascript/module/static/static_module_loader.h"
20 #include "ecmascript/js_promise.h"
21 #include "ecmascript/module/napi_module_loader.h"
22 #include "ecmascript/js_array.h"
23 #include "ecmascript/global_env.h"
24 #include "ecmascript/module/module_path_helper.h"
25 
26 using namespace panda;
27 using namespace panda::ecmascript;
28 using namespace panda::ecmascript::builtins;
29 using FunctionCallbackInfo = Local<JSValueRef> (*)(JsiRuntimeCallInfo *);
30 using namespace panda::ecmascript;
31 using ModulePathHelper = ecmascript::ModulePathHelper;
32 
33 namespace panda::test {
34 class StaticModuleLoaderTest : public testing::Test {
35 public:
SetUpTestCase()36     static void SetUpTestCase()
37     {
38         GTEST_LOG_(INFO) << "SetUpTestCase";
39     }
40 
TearDownTestCase()41     static void TearDownTestCase()
42     {
43         GTEST_LOG_(INFO) << "TearDownCase";
44     }
45 
SetUp()46     void SetUp() override
47     {
48         TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
49     }
50 
TearDown()51     void TearDown() override
52     {
53         TestHelper::DestroyEcmaVMWithScope(instance, scope);
54     }
55     static Local<JSValueRef> MockGetModule(JsiRuntimeCallInfo *runtimeCallInfo);
56     static Local<JSValueRef> MockGetModuleJSError(JsiRuntimeCallInfo *runtimeCallInfo);
57     EcmaVM *instance {nullptr};
58     ecmascript::EcmaHandleScope *scope {nullptr};
59     JSThread *thread {nullptr};
60 };
61 
MockGetModule(JsiRuntimeCallInfo * runtimeCallInfo)62 Local<JSValueRef> StaticModuleLoaderTest::MockGetModule(JsiRuntimeCallInfo *runtimeCallInfo)
63 {
64     auto *thread = runtimeCallInfo->GetThread();
65     auto vm = thread->GetEcmaVM();
66     Local<StringRef> requestPath = StringRef::NewFromUtf8(vm, "requestPath");
67     Local<ObjectRef> exportObejct = ObjectRef::New(vm);
68     exportObejct->Set(vm, requestPath, runtimeCallInfo->GetCallArgRef(0));
69     return exportObejct;
70 }
71 
72 
MockGetModuleJSError(JsiRuntimeCallInfo * runtimeCallInfo)73 Local<JSValueRef> StaticModuleLoaderTest::MockGetModuleJSError(JsiRuntimeCallInfo *runtimeCallInfo)
74 {
75     auto *thread = runtimeCallInfo->GetThread();
76     auto vm = thread->GetEcmaVM();
77     JsiFastNativeScope fastNativeScope(vm);
78     Local<JSValueRef> error(JSValueRef::Undefined(vm));
79     error = Exception::Error(vm, runtimeCallInfo->GetCallArgRef(0));
80     Local<JSValueRef> codeKey = StringRef::NewFromUtf8(vm, "code");
81     Local<JSValueRef> codeValue = runtimeCallInfo->GetCallArgRef(0);
82     Local<ObjectRef> errorObj(error);
83     errorObj->Set(vm, codeKey, codeValue);
84     JSNApi::ThrowException(vm, error);
85     return runtimeCallInfo->GetCallArgRef(0);
86 }
87 
HWTEST_F_L0(StaticModuleLoaderTest,CanTryLoadStaticModulePath)88 HWTEST_F_L0(StaticModuleLoaderTest, CanTryLoadStaticModulePath)
89 {
90     CString inputFileName = "./test";
91     bool res1 = StaticModuleLoader::CanTryLoadStaticModulePath(inputFileName);
92     EXPECT_FALSE(res1);
93 
94     inputFileName = "test";
95     bool res2 = StaticModuleLoader::CanTryLoadStaticModulePath(inputFileName);
96     EXPECT_TRUE(res2);
97 
98     inputFileName = "test.js";
99     bool res3 = StaticModuleLoader::CanTryLoadStaticModulePath(inputFileName);
100     EXPECT_FALSE(res3);
101 
102     inputFileName = "test.ts";
103     bool res4 = StaticModuleLoader::CanTryLoadStaticModulePath(inputFileName);
104     EXPECT_FALSE(res4);
105 
106     inputFileName = "test.ets";
107     bool res5 = StaticModuleLoader::CanTryLoadStaticModulePath(inputFileName);
108     EXPECT_FALSE(res5);
109 
110     inputFileName = "@bundle:";
111     bool res6 = StaticModuleLoader::CanTryLoadStaticModulePath(inputFileName);
112     EXPECT_FALSE(res6);
113 
114     inputFileName = "@normalized:";
115     bool res7 = StaticModuleLoader::CanTryLoadStaticModulePath(inputFileName);
116     EXPECT_FALSE(res7);
117 
118     inputFileName = "@package:";
119     bool res8 = StaticModuleLoader::CanTryLoadStaticModulePath(inputFileName);
120     EXPECT_FALSE(res8);
121 }
122 
HWTEST_F_L0(StaticModuleLoaderTest,GetStaticModuleLoadFunc)123 HWTEST_F_L0(StaticModuleLoaderTest, GetStaticModuleLoadFunc)
124 {
125     auto vm = thread->GetEcmaVM();
126     Local<JSValueRef> undefinedFunc =  StaticModuleLoader::GetStaticModuleLoadFunc(vm);
127     EXPECT_TRUE(undefinedFunc->IsUndefined());
128 
129     auto globalConstants = thread->GlobalConstants();
130     JSArray *arr = JSArray::Cast(JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetTaggedValue().GetTaggedObject());
131     EXPECT_TRUE(arr != nullptr);
132     JSHandle<JSTaggedValue> pandaObject(thread, arr);
133     JSTaggedValue::SetProperty(thread, pandaObject,
134         globalConstants->GetHandledGetModuleString(),
135         JSNApiHelper::ToJSHandle(FunctionRef::New(const_cast<panda::EcmaVM*>(vm), MockGetModule)));
136     Local<ObjectRef> globalObject = JSNApi::GetGlobalObject(vm);
137     globalObject->Set(vm,
138         JSNApiHelper::ToLocal<StringRef>(globalConstants->GetHandledPandaString()),
139         JSNApiHelper::ToLocal<JSValueRef>(pandaObject));
140     Local<JSValueRef> func =  StaticModuleLoader::GetStaticModuleLoadFunc(vm);
141     EXPECT_FALSE(func->IsUndefined());
142 }
143 
HWTEST_F_L0(StaticModuleLoaderTest,LoadStaticModule)144 HWTEST_F_L0(StaticModuleLoaderTest, LoadStaticModule)
145 {
146     auto vm = thread->GetEcmaVM();
147     ObjectFactory *factory = vm->GetFactory();
148 
149     Local<FunctionRef> func = FunctionRef::New(const_cast<panda::EcmaVM *>(vm), MockGetModule);
150     JSHandle<JSTaggedValue> specifier(factory->NewFromASCII("exportFile"));
151     JSHandle<EcmaString> specifierString = JSTaggedValue::ToString(thread, specifier);
152     CString path = ModulePathHelper::Utf8ConvertToString(thread, specifierString.GetTaggedValue());
153     JSHandle<JSTaggedValue>  result = StaticModuleLoader::LoadStaticModule(thread, func, path);
154 
155     EXPECT_EQ(result->IsJSProxy(), true);
156     JSHandle<JSTaggedValue> requestPath(factory->NewFromASCII("requestPath"));
157     EXPECT_EQ(JSTaggedValue::SameValue(thread, JSTaggedValue::GetProperty(thread, result, requestPath).GetValue(),
158                                        specifier), true);
159 }
160 
161 
HWTEST_F_L0(StaticModuleLoaderTest,LoadStaticModuleError)162 HWTEST_F_L0(StaticModuleLoaderTest, LoadStaticModuleError)
163 {
164     auto vm = thread->GetEcmaVM();
165     ObjectFactory *factory = vm->GetFactory();
166 
167     Local<FunctionRef> func = FunctionRef::New(const_cast<panda::EcmaVM *>(vm), MockGetModuleJSError);
168     JSHandle<JSTaggedValue> specifier(factory->NewFromASCII("exportFile"));
169     JSHandle<EcmaString> specifierString = JSTaggedValue::ToString(thread, specifier);
170     CString path = ModulePathHelper::Utf8ConvertToString(thread, specifierString.GetTaggedValue());
171     StaticModuleLoader::LoadStaticModule(thread, func, path);
172     EXPECT_EQ(thread->HasPendingException(), true);
173     JSHandle<JSTaggedValue> error(thread, thread->GetException());
174     JSHandle<JSTaggedValue> code(factory->NewFromASCII("code"));
175     JSHandle<JSTaggedValue> message = JSTaggedValue::GetProperty(thread, error, code).GetValue();
176     EXPECT_EQ(JSTaggedValue::SameValue(thread, message, specifier), true);
177     thread->ClearException();
178 }
179 
180 }  // namespace panda::test
181