• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "assembler/assembly-emitter.h"
17 #include "assembler/assembly-parser.h"
18 #include "libpandafile/class_data_accessor-inl.h"
19 
20 #include "ecmascript/base/path_helper.h"
21 #include "ecmascript/global_env.h"
22 #include "ecmascript/jspandafile/js_pandafile.h"
23 #include "ecmascript/jspandafile/js_pandafile_manager.h"
24 #include "ecmascript/jspandafile/program_object.h"
25 #include "ecmascript/module/js_module_manager.h"
26 #include "ecmascript/module/js_module_source_text.h"
27 #include "ecmascript/module/module_data_extractor.h"
28 #include "ecmascript/module/module_path_helper.h"
29 #include "ecmascript/tests/test_helper.h"
30 #include "ecmascript/linked_hash_table.h"
31 
32 
33 using namespace panda::ecmascript;
34 using namespace panda::panda_file;
35 using namespace panda::pandasm;
36 
37 namespace panda::test {
38 class EcmaModuleTest : public testing::Test {
39 public:
SetUpTestCase()40     static void SetUpTestCase()
41     {
42         GTEST_LOG_(INFO) << "SetUpTestCase";
43     }
44 
TearDownTestCase()45     static void TearDownTestCase()
46     {
47         GTEST_LOG_(INFO) << "TearDownCase";
48     }
49 
SetUp()50     void SetUp() override
51     {
52         TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
53     }
54 
TearDown()55     void TearDown() override
56     {
57         TestHelper::DestroyEcmaVMWithScope(instance, scope);
58     }
59     EcmaVM *instance {nullptr};
60     ecmascript::EcmaHandleScope *scope {nullptr};
61     JSThread *thread {nullptr};
62 };
63 
64 /*
65  * Feature: Module
66  * Function: AddImportEntry
67  * SubFunction: AddImportEntry
68  * FunctionPoints: Add import entry
69  * CaseDescription: Add two import item and check module import entries size
70  */
HWTEST_F_L0(EcmaModuleTest,AddImportEntry)71 HWTEST_F_L0(EcmaModuleTest, AddImportEntry)
72 {
73     ObjectFactory *objectFactory = thread->GetEcmaVM()->GetFactory();
74     JSHandle<SourceTextModule> module = objectFactory->NewSourceTextModule();
75     JSHandle<ImportEntry> importEntry1 = objectFactory->NewImportEntry();
76     SourceTextModule::AddImportEntry(thread, module, importEntry1, 0, 2);
77     JSHandle<ImportEntry> importEntry2 = objectFactory->NewImportEntry();
78     SourceTextModule::AddImportEntry(thread, module, importEntry2, 1, 2);
79     JSHandle<TaggedArray> importEntries(thread, module->GetImportEntries());
80     EXPECT_TRUE(importEntries->GetLength() == 2U);
81 }
82 
83 /*
84  * Feature: Module
85  * Function: AddLocalExportEntry
86  * SubFunction: AddLocalExportEntry
87  * FunctionPoints: Add local export entry
88  * CaseDescription: Add two local export item and check module local export entries size
89  */
HWTEST_F_L0(EcmaModuleTest,AddLocalExportEntry)90 HWTEST_F_L0(EcmaModuleTest, AddLocalExportEntry)
91 {
92     ObjectFactory *objectFactory = thread->GetEcmaVM()->GetFactory();
93     JSHandle<SourceTextModule> module = objectFactory->NewSourceTextModule();
94     JSHandle<LocalExportEntry> localExportEntry1 = objectFactory->NewLocalExportEntry();
95     SourceTextModule::AddLocalExportEntry(thread, module, localExportEntry1, 0, 2);
96     JSHandle<LocalExportEntry> localExportEntry2 = objectFactory->NewLocalExportEntry();
97     SourceTextModule::AddLocalExportEntry(thread, module, localExportEntry2, 1, 2);
98     JSHandle<TaggedArray> localExportEntries(thread, module->GetLocalExportEntries());
99     EXPECT_TRUE(localExportEntries->GetLength() == 2U);
100 }
101 
102 /*
103  * Feature: Module
104  * Function: AddIndirectExportEntry
105  * SubFunction: AddIndirectExportEntry
106  * FunctionPoints: Add indirect export entry
107  * CaseDescription: Add two indirect export item and check module indirect export entries size
108  */
HWTEST_F_L0(EcmaModuleTest,AddIndirectExportEntry)109 HWTEST_F_L0(EcmaModuleTest, AddIndirectExportEntry)
110 {
111     ObjectFactory *objectFactory = thread->GetEcmaVM()->GetFactory();
112     JSHandle<SourceTextModule> module = objectFactory->NewSourceTextModule();
113     JSHandle<IndirectExportEntry> indirectExportEntry1 = objectFactory->NewIndirectExportEntry();
114     SourceTextModule::AddIndirectExportEntry(thread, module, indirectExportEntry1, 0, 2);
115     JSHandle<IndirectExportEntry> indirectExportEntry2 = objectFactory->NewIndirectExportEntry();
116     SourceTextModule::AddIndirectExportEntry(thread, module, indirectExportEntry2, 1, 2);
117     JSHandle<TaggedArray> indirectExportEntries(thread, module->GetIndirectExportEntries());
118     EXPECT_TRUE(indirectExportEntries->GetLength() == 2U);
119 }
120 
121 /*
122  * Feature: Module
123  * Function: StarExportEntries
124  * SubFunction: StarExportEntries
125  * FunctionPoints: Add start export entry
126  * CaseDescription: Add two start export item and check module start export entries size
127  */
HWTEST_F_L0(EcmaModuleTest,AddStarExportEntry)128 HWTEST_F_L0(EcmaModuleTest, AddStarExportEntry)
129 {
130     ObjectFactory *objectFactory = thread->GetEcmaVM()->GetFactory();
131     JSHandle<SourceTextModule> module = objectFactory->NewSourceTextModule();
132     JSHandle<StarExportEntry> starExportEntry1 = objectFactory->NewStarExportEntry();
133     SourceTextModule::AddStarExportEntry(thread, module, starExportEntry1, 0, 2);
134     JSHandle<StarExportEntry> starExportEntry2 = objectFactory->NewStarExportEntry();
135     SourceTextModule::AddStarExportEntry(thread, module, starExportEntry2, 1, 2);
136     JSHandle<TaggedArray> startExportEntries(thread, module->GetStarExportEntries());
137     EXPECT_TRUE(startExportEntries->GetLength() == 2U);
138 }
139 
140 /*
141  * Feature: Module
142  * Function: StoreModuleValue
143  * SubFunction: StoreModuleValue/GetModuleValue
144  * FunctionPoints: store a module export item in module
145  * CaseDescription: Simulated implementation of "export foo as bar", set foo as "hello world",
146  *                  use "import bar" in same js file
147  */
HWTEST_F_L0(EcmaModuleTest,StoreModuleValue)148 HWTEST_F_L0(EcmaModuleTest, StoreModuleValue)
149 {
150     ObjectFactory* objFactory = thread->GetEcmaVM()->GetFactory();
151     CString localName = "foo";
152     CString exportName = "bar";
153     CString value = "hello world";
154 
155     JSHandle<JSTaggedValue> localNameHandle = JSHandle<JSTaggedValue>::Cast(objFactory->NewFromUtf8(localName));
156     JSHandle<JSTaggedValue> exportNameHandle = JSHandle<JSTaggedValue>::Cast(objFactory->NewFromUtf8(exportName));
157     JSHandle<LocalExportEntry> localExportEntry =
158         objFactory->NewLocalExportEntry(exportNameHandle, localNameHandle, LocalExportEntry::LOCAL_DEFAULT_INDEX);
159     JSHandle<SourceTextModule> module = objFactory->NewSourceTextModule();
160     SourceTextModule::AddLocalExportEntry(thread, module, localExportEntry, 0, 1);
161 
162     JSHandle<JSTaggedValue> storeKey = JSHandle<JSTaggedValue>::Cast(objFactory->NewFromUtf8(localName));
163     JSHandle<JSTaggedValue> valueHandle = JSHandle<JSTaggedValue>::Cast(objFactory->NewFromUtf8(value));
164     module->StoreModuleValue(thread, storeKey, valueHandle);
165 
166     JSHandle<JSTaggedValue> loadKey = JSHandle<JSTaggedValue>::Cast(objFactory->NewFromUtf8(localName));
167     JSTaggedValue loadValue = module->GetModuleValue(thread, loadKey.GetTaggedValue(), false);
168     EXPECT_EQ(valueHandle.GetTaggedValue(), loadValue);
169 }
170 
171 /*
172  * Feature: Module
173  * Function: GetModuleValue
174  * SubFunction: StoreModuleValue/GetModuleValue
175  * FunctionPoints: load module value from module
176  * CaseDescription: Simulated implementation of "export default let foo = 'hello world'",
177  *                  use "import C from 'xxx' to get default value"
178  */
HWTEST_F_L0(EcmaModuleTest,GetModuleValue)179 HWTEST_F_L0(EcmaModuleTest, GetModuleValue)
180 {
181     ObjectFactory* objFactory = thread->GetEcmaVM()->GetFactory();
182     // export entry
183     CString exportLocalName = "*default*";
184     CString exportName = "default";
185     CString exportValue = "hello world";
186     JSHandle<JSTaggedValue> exportLocalNameHandle =
187         JSHandle<JSTaggedValue>::Cast(objFactory->NewFromUtf8(exportLocalName));
188     JSHandle<JSTaggedValue> exportNameHandle =
189         JSHandle<JSTaggedValue>::Cast(objFactory->NewFromUtf8(exportName));
190     JSHandle<LocalExportEntry> localExportEntry = objFactory->NewLocalExportEntry(exportNameHandle,
191         exportLocalNameHandle, LocalExportEntry::LOCAL_DEFAULT_INDEX);
192     JSHandle<SourceTextModule> moduleExport = objFactory->NewSourceTextModule();
193     SourceTextModule::AddLocalExportEntry(thread, moduleExport, localExportEntry, 0, 1);
194     // store module value
195     JSHandle<JSTaggedValue> exportValueHandle = JSHandle<JSTaggedValue>::Cast(objFactory->NewFromUtf8(exportValue));
196     moduleExport->StoreModuleValue(thread, exportLocalNameHandle, exportValueHandle);
197 
198     JSTaggedValue importDefaultValue =
199         moduleExport->GetModuleValue(thread, exportLocalNameHandle.GetTaggedValue(), false);
200     EXPECT_EQ(exportValueHandle.GetTaggedValue(), importDefaultValue);
201 }
202 
HWTEST_F_L0(EcmaModuleTest,GetRecordName1)203 HWTEST_F_L0(EcmaModuleTest, GetRecordName1)
204 {
205     std::string baseFileName = MODULE_ABC_PATH "module_test_module_test_module_base.abc";
206 
207     JSNApi::EnableUserUncaughtErrorHandler(instance);
208 
209     bool result = JSNApi::Execute(instance, baseFileName, "module_test_module_test_module_base");
210     EXPECT_TRUE(result);
211 }
212 
HWTEST_F_L0(EcmaModuleTest,GetRecordName2)213 HWTEST_F_L0(EcmaModuleTest, GetRecordName2)
214 {
215     std::string baseFileName = MODULE_ABC_PATH "module_test_module_test_A.abc";
216 
217     JSNApi::EnableUserUncaughtErrorHandler(instance);
218 
219     bool result = JSNApi::Execute(instance, baseFileName, "module_test_module_test_A");
220     EXPECT_TRUE(result);
221 }
222 
HWTEST_F_L0(EcmaModuleTest,GetExportObjectIndex)223 HWTEST_F_L0(EcmaModuleTest, GetExportObjectIndex)
224 {
225     std::string baseFileName = MODULE_ABC_PATH "module_test_module_test_C.abc";
226 
227     JSNApi::EnableUserUncaughtErrorHandler(instance);
228 
229     bool result = JSNApi::Execute(instance, baseFileName, "module_test_module_test_C");
230     JSNApi::GetExportObject(instance, "module_test_module_test_B", "a");
231     EXPECT_TRUE(result);
232 }
233 
HWTEST_F_L0(EcmaModuleTest,HostResolveImportedModule)234 HWTEST_F_L0(EcmaModuleTest, HostResolveImportedModule)
235 {
236     std::string baseFileName = MODULE_ABC_PATH "module_test_module_test_C.abc";
237 
238     JSNApi::EnableUserUncaughtErrorHandler(instance);
239 
240     ModuleManager *moduleManager = thread->GetCurrentEcmaContext()->GetModuleManager();
241     ObjectFactory *factory = instance->GetFactory();
242     JSHandle<SourceTextModule> module = factory->NewSourceTextModule();
243     JSHandle<JSTaggedValue> moduleRecord(thread, module.GetTaggedValue());
244     moduleManager->AddResolveImportedModule(baseFileName.c_str(), moduleRecord);
245     JSHandle<JSTaggedValue> res = moduleManager->HostResolveImportedModule(baseFileName.c_str());
246 
247     EXPECT_EQ(moduleRecord->GetRawData(), res.GetTaggedValue().GetRawData());
248 }
249 
HWTEST_F_L0(EcmaModuleTest,PreventExtensions_IsExtensible)250 HWTEST_F_L0(EcmaModuleTest, PreventExtensions_IsExtensible)
251 {
252     ObjectFactory *objectFactory = thread->GetEcmaVM()->GetFactory();
253     JSHandle<SourceTextModule> module = objectFactory->NewSourceTextModule();
254     JSHandle<LocalExportEntry> localExportEntry1 = objectFactory->NewLocalExportEntry();
255     SourceTextModule::AddLocalExportEntry(thread, module, localExportEntry1, 0, 2);
256     JSHandle<LocalExportEntry> localExportEntry2 = objectFactory->NewLocalExportEntry();
257     SourceTextModule::AddLocalExportEntry(thread, module, localExportEntry2, 1, 2);
258     JSHandle<TaggedArray> localExportEntries(thread, module->GetLocalExportEntries());
259     CString baseFileName = "a.abc";
260     JSHandle<EcmaString> moduleFilename = objectFactory->NewFromUtf8(baseFileName);
261     module->SetEcmaModuleFilename(thread, moduleFilename);
262     ModuleManager *moduleManager = thread->GetCurrentEcmaContext()->GetModuleManager();
263     moduleManager->AddResolveImportedModule(baseFileName, JSHandle<JSTaggedValue>::Cast(module));
264     JSHandle<ModuleNamespace> np =
265     ModuleNamespace::ModuleNamespaceCreate(thread, JSHandle<JSTaggedValue>::Cast(module), localExportEntries);
266     EXPECT_FALSE(np->IsExtensible());
267     EXPECT_TRUE(ModuleNamespace::PreventExtensions());
268 }
269 
HWTEST_F_L0(EcmaModuleTest,Instantiate_Evaluate_GetNamespace_SetNamespace)270 HWTEST_F_L0(EcmaModuleTest, Instantiate_Evaluate_GetNamespace_SetNamespace)
271 {
272     std::string baseFileName = MODULE_ABC_PATH "module_test_module_test_C.abc";
273 
274     JSNApi::EnableUserUncaughtErrorHandler(instance);
275 
276     bool result = JSNApi::Execute(instance, baseFileName, "module_test_module_test_C");
277     EXPECT_TRUE(result);
278     ModuleManager *moduleManager = thread->GetCurrentEcmaContext()->GetModuleManager();
279     JSHandle<SourceTextModule> module = moduleManager->HostGetImportedModule("module_test_module_test_C");
280     module->SetStatus(ModuleStatus::UNINSTANTIATED);
281     ModuleRecord::Instantiate(thread, JSHandle<JSTaggedValue>(module));
282     JSTaggedValue res = ModuleRecord::Evaluate(thread, JSHandle<JSTaggedValue>(module));
283     ModuleRecord::GetNamespace(module.GetTaggedValue());
284     ModuleRecord::SetNamespace(thread, module.GetTaggedValue(), JSTaggedValue::Undefined());
285     EXPECT_TRUE(res.IsJSPromise());
286 }
287 
HWTEST_F_L0(EcmaModuleTest,ConcatFileNameWithMerge1)288 HWTEST_F_L0(EcmaModuleTest, ConcatFileNameWithMerge1)
289 {
290     CString baseFilename = "merge.abc";
291     const char *data = R"(
292         .language ECMAScript
293         .function any func_main_0(any a0, any a1, any a2) {
294             ldai 1
295             return
296         }
297     )";
298     JSPandaFileManager *pfManager = JSPandaFileManager::GetInstance();
299     Parser parser;
300     auto res = parser.Parse(data);
301     std::unique_ptr<const File> pfPtr = pandasm::AsmEmitter::Emit(res.Value());
302     std::shared_ptr<JSPandaFile> pf = pfManager->NewJSPandaFile(pfPtr.release(), baseFilename);
303 
304     // Test moduleRequestName start with "@bundle"
305     CString moduleRecordName = "moduleTest1";
306     CString moduleRequestName = "@bundle:com.bundleName.test/moduleName/requestModuleName1";
307     CString result = "com.bundleName.test/moduleName/requestModuleName1";
308     CString entryPoint = ModulePathHelper::ConcatFileNameWithMerge(thread, pf.get(), baseFilename, moduleRecordName,
309                                                              moduleRequestName);
310     EXPECT_EQ(result, entryPoint);
311 
312     // Test cross application
313     moduleRecordName = "@bundle:com.bundleName1.test/moduleName/requestModuleName1";
314     CString newBaseFileName = "/data/storage/el1/bundle/com.bundleName.test/moduleName/moduleName/ets/modules.abc";
315     ModulePathHelper::ConcatFileNameWithMerge(thread, pf.get(), baseFilename, moduleRecordName, moduleRequestName);
316     EXPECT_EQ(baseFilename, newBaseFileName);
317 }
318 
HWTEST_F_L0(EcmaModuleTest,ConcatFileNameWithMerge2)319 HWTEST_F_L0(EcmaModuleTest, ConcatFileNameWithMerge2)
320 {
321     CString baseFilename = "merge.abc";
322     const char *data = R"(
323         .language ECMAScript
324         .function any func_main_0(any a0, any a1, any a2) {
325             ldai 1
326             return
327         }
328     )";
329     JSPandaFileManager *pfManager = JSPandaFileManager::GetInstance();
330     Parser parser;
331     auto res = parser.Parse(data);
332     std::unique_ptr<const File> pfPtr = pandasm::AsmEmitter::Emit(res.Value());
333     std::shared_ptr<JSPandaFile> pf = pfManager->NewJSPandaFile(pfPtr.release(), baseFilename);
334 
335     // Test moduleRequestName start with "./"
336     CString moduleRecordName = "moduleTest2";
337     CString moduleRequestName = "./requestModule.js";
338     CString result = "requestModule";
339     pf->InsertJSRecordInfo(result);
340     CString entryPoint = ModulePathHelper::ConcatFileNameWithMerge(thread, pf.get(), baseFilename, moduleRecordName,
341                                                              moduleRequestName);
342     EXPECT_EQ(result, entryPoint);
343 
344     // Test moduleRecordName with "/"
345     moduleRecordName = "moduleName/moduleTest2";
346     moduleRequestName = "./requestModule.js";
347     result = "moduleName/requestModule";
348     pf->InsertJSRecordInfo(result);
349     entryPoint = ModulePathHelper::ConcatFileNameWithMerge(
350         thread, pf.get(), baseFilename, moduleRecordName, moduleRequestName);
351     EXPECT_EQ(result, entryPoint);
352 }
353 
HWTEST_F_L0(EcmaModuleTest,ConcatFileNameWithMerge3)354 HWTEST_F_L0(EcmaModuleTest, ConcatFileNameWithMerge3)
355 {
356     CString baseFilename = "merge.abc";
357     const char *data = R"(
358         .language ECMAScript
359         .function any func_main_0(any a0, any a1, any a2) {
360             ldai 1
361             return
362         }
363     )";
364     JSPandaFileManager *pfManager = JSPandaFileManager::GetInstance();
365     Parser parser;
366     auto res = parser.Parse(data);
367     std::unique_ptr<const File> pfPtr = pandasm::AsmEmitter::Emit(res.Value());
368     std::shared_ptr<JSPandaFile> pf = pfManager->NewJSPandaFile(pfPtr.release(), baseFilename);
369 
370     // Test RecordName is not in JSPandaFile
371     CString moduleRecordName = "moduleTest3";
372     CString moduleRequestName = "./secord.js";
373     CString result = "secord";
374     CString requestFileName = "secord.abc";
375     CString entryPoint =
376         ModulePathHelper::ConcatFileNameWithMerge(thread, pf.get(), baseFilename, moduleRecordName, moduleRequestName);
377     EXPECT_EQ(baseFilename, requestFileName);
378     EXPECT_EQ(result, entryPoint);
379 
380     // Test RecordName is not in JSPandaFile and baseFilename with "/" and moduleRequestName with "/"
381     baseFilename = "test/merge.abc";
382     std::unique_ptr<const File> pfPtr2 = pandasm::AsmEmitter::Emit(res.Value());
383     std::shared_ptr<JSPandaFile> pf2 = pfManager->NewJSPandaFile(pfPtr2.release(), baseFilename);
384 
385     moduleRecordName = "moduleTest3";
386     moduleRequestName = "./test/secord.js";
387     result = "secord";
388     requestFileName = "test/test/secord.abc";
389     entryPoint = ModulePathHelper::ConcatFileNameWithMerge(thread, pf2.get(), baseFilename, moduleRecordName,
390                                                      moduleRequestName);
391     EXPECT_EQ(baseFilename, requestFileName);
392     EXPECT_EQ(result, entryPoint);
393 }
394 
HWTEST_F_L0(EcmaModuleTest,ConcatFileNameWithMerge4)395 HWTEST_F_L0(EcmaModuleTest, ConcatFileNameWithMerge4)
396 {
397     CString baseFilename = "merge.abc";
398     const char *data = R"(
399         .language ECMAScript
400         .function any func_main_0(any a0, any a1, any a2) {
401             ldai 1
402             return
403         }
404     )";
405     JSPandaFileManager *pfManager = JSPandaFileManager::GetInstance();
406     Parser parser;
407     auto res = parser.Parse(data);
408     std::unique_ptr<const File> pfPtr = pandasm::AsmEmitter::Emit(res.Value());
409     std::shared_ptr<JSPandaFile> pf = pfManager->NewJSPandaFile(pfPtr.release(), baseFilename);
410     const CUnorderedMap<CString, JSPandaFile::JSRecordInfo> &recordInfo = pf->GetJSRecordInfo();
411     // Test moduleRequestName is npm package
412     CString moduleRecordName = "node_modules/0/moduleTest4/index";
413     CString moduleRequestName = "json/index";
414     CString result = "node_modules/0/moduleTest4/node_modules/json/index";
415     JSPandaFile::JSRecordInfo info;
416     info.npmPackageName = "node_modules/0/moduleTest4";
417     const_cast<CUnorderedMap<CString, JSPandaFile::JSRecordInfo> &>(recordInfo).insert({moduleRecordName, info});
418     const_cast<CUnorderedMap<CString, JSPandaFile::JSRecordInfo> &>(recordInfo).insert({result, info});
419     CString entryPoint = ModulePathHelper::ConcatFileNameWithMerge(thread, pf.get(), baseFilename, moduleRecordName,
420                                                              moduleRequestName);
421     EXPECT_EQ(result, entryPoint);
422 }
423 
HWTEST_F_L0(EcmaModuleTest,NormalizePath)424 HWTEST_F_L0(EcmaModuleTest, NormalizePath)
425 {
426     CString res1 = "node_modules/0/moduleTest/index";
427     CString moduleRecordName1 = "node_modules///0//moduleTest/index";
428 
429     CString res2 = "node_modules/0/moduleTest/index";
430     CString moduleRecordName2 = "./node_modules///0//moduleTest/index";
431 
432     CString res3 = "node_modules/0/moduleTest/index";
433     CString moduleRecordName3 = "../node_modules/0/moduleTest///index";
434 
435     CString res4 = "moduleTest/index";
436     CString moduleRecordName4 = "./node_modules/..//moduleTest////index";
437 
438     CString res5 = "node_modules/moduleTest/index";
439     CString moduleRecordName5 = "node_modules/moduleTest/index/";
440 
441     CString normalName1 = PathHelper::NormalizePath(moduleRecordName1);
442     CString normalName2 = PathHelper::NormalizePath(moduleRecordName2);
443     CString normalName3 = PathHelper::NormalizePath(moduleRecordName3);
444     CString normalName4 = PathHelper::NormalizePath(moduleRecordName4);
445     CString normalName5 = PathHelper::NormalizePath(moduleRecordName5);
446 
447     EXPECT_EQ(res1, normalName1);
448     EXPECT_EQ(res2, normalName2);
449     EXPECT_EQ(res3, normalName3);
450     EXPECT_EQ(res4, normalName4);
451     EXPECT_EQ(res5, normalName5);
452 }
453 
HWTEST_F_L0(EcmaModuleTest,ParseOhmUrl)454 HWTEST_F_L0(EcmaModuleTest, ParseOhmUrl)
455 {
456     // old pages url
457     instance->SetBundleName("com.bundleName.test");
458     instance->SetModuleName("moduleName");
459     CString inputFileName = "moduleName/ets/pages/index.abc";
460     CString outFileName = "";
461     CString res1 = "com.bundleName.test/moduleName/ets/pages/index";
462     CString entryPoint;
463     ModulePathHelper::ParseOhmUrl(instance, inputFileName, outFileName, entryPoint);
464     EXPECT_EQ(entryPoint, res1);
465     EXPECT_EQ(outFileName, "");
466 
467     // new pages url
468     inputFileName = "@bundle:com.bundleName.test/moduleName/ets/pages/index.abc";
469     ModulePathHelper::ParseOhmUrl(instance, inputFileName, outFileName, entryPoint);
470     EXPECT_EQ(entryPoint, res1);
471     EXPECT_EQ(outFileName, "/data/storage/el1/bundle/moduleName/ets/modules.abc");
472 
473     // new pages url Intra-application cross hap
474     inputFileName = "@bundle:com.bundleName.test/moduleName1/ets/pages/index.abc";
475     CString outRes = "/data/storage/el1/bundle/moduleName1/ets/modules.abc";
476     CString res2 = "com.bundleName.test/moduleName1/ets/pages/index";
477     ModulePathHelper::ParseOhmUrl(instance, inputFileName, outFileName, entryPoint);
478     EXPECT_EQ(entryPoint, res2);
479     EXPECT_EQ(outFileName, outRes);
480 
481     // new pages url Cross-application
482     inputFileName = "@bundle:com.bundleName.test1/moduleName1/ets/pages/index.abc";
483     CString outRes1 = "/data/storage/el1/bundle/com.bundleName.test1/moduleName1/moduleName1/ets/modules.abc";
484     CString res3 = "com.bundleName.test1/moduleName1/ets/pages/index";
485     ModulePathHelper::ParseOhmUrl(instance, inputFileName, outFileName, entryPoint);
486     EXPECT_EQ(entryPoint, res3);
487     EXPECT_EQ(outFileName, outRes1);
488 
489     // worker url Intra-application cross hap
490     inputFileName = "/data/storage/el1/bundle/entry/ets/mainAbility.abc";
491     CString outRes2 = "/data/storage/el1/bundle/entry/ets/modules.abc";
492     CString res4 = "com.bundleName.test/entry/ets/mainAbility";
493     ModulePathHelper::ParseOhmUrl(instance, inputFileName, outFileName, entryPoint);
494     EXPECT_EQ(entryPoint, res4);
495     EXPECT_EQ(outFileName, outRes2);
496 
497     // worker url
498     outFileName = "";
499     inputFileName = "/data/storage/el1/bundle/moduleName/ets/mainAbility.abc";
500     CString res5 = "com.bundleName.test/moduleName/ets/mainAbility";
501     ModulePathHelper::ParseOhmUrl(instance, inputFileName, outFileName, entryPoint);
502     EXPECT_EQ(entryPoint, res5);
503     EXPECT_EQ(outFileName, "/data/storage/el1/bundle/moduleName/ets/modules.abc");
504 }
505 
HWTEST_F_L0(EcmaModuleTest,CheckNativeModule)506 HWTEST_F_L0(EcmaModuleTest, CheckNativeModule)
507 {
508     // load file
509     CString requestName1 = "@bundle:bundleName/moduleName/ets/index";
510 
511     // load native modules
512     CString requestName2 = "@ohos:router";
513     CString requestName3 = "@app:bundleName/moduleName/lib*.so";
514     CString requestName4 = "@native:system.app";
515     CString requestName5 = "@xxx:internal";
516 
517     // load npm Packages
518     CString requestName6 = "@package:pkg_modules/.ohpm/json5@2.2.3/pkg_modules/json5/dist/index";
519     CString requestName7 = "@ohos/common";
520 
521     std::pair<bool, ModuleTypes> res1 = SourceTextModule::CheckNativeModule(requestName1);
522     EXPECT_EQ(res1.first, false);
523     EXPECT_EQ(res1.second, ModuleTypes::UNKNOWN);
524 
525     std::pair<bool, ModuleTypes> res2 = SourceTextModule::CheckNativeModule(requestName2);
526     EXPECT_EQ(res2.first, true);
527     EXPECT_EQ(res2.second, ModuleTypes::OHOS_MODULE);
528 
529     std::pair<bool, ModuleTypes> res3 = SourceTextModule::CheckNativeModule(requestName3);
530     EXPECT_EQ(res3.first, true);
531     EXPECT_EQ(res3.second, ModuleTypes::APP_MODULE);
532 
533     std::pair<bool, ModuleTypes> res4 = SourceTextModule::CheckNativeModule(requestName4);
534     EXPECT_EQ(res4.first, true);
535     EXPECT_EQ(res4.second, ModuleTypes::NATIVE_MODULE);
536 
537     std::pair<bool, ModuleTypes> res5 = SourceTextModule::CheckNativeModule(requestName5);
538     EXPECT_EQ(res5.first, true);
539     EXPECT_EQ(res5.second, ModuleTypes::INTERNAL_MODULE);
540 
541     std::pair<bool, ModuleTypes> res6 = SourceTextModule::CheckNativeModule(requestName6);
542     EXPECT_EQ(res6.first, false);
543     EXPECT_EQ(res6.second, ModuleTypes::UNKNOWN);
544 
545     std::pair<bool, ModuleTypes> res7 = SourceTextModule::CheckNativeModule(requestName7);
546     EXPECT_EQ(res7.first, false);
547     EXPECT_EQ(res7.second, ModuleTypes::UNKNOWN);
548 }
549 
HWTEST_F_L0(EcmaModuleTest,ResolveDirPath)550 HWTEST_F_L0(EcmaModuleTest, ResolveDirPath)
551 {
552     ObjectFactory *objectFactory = thread->GetEcmaVM()->GetFactory();
553 
554     CString inputFileName = "moduleName/ets/pages/index.abc";
555     CString resName1 = "moduleName/ets/pages/";
556     JSHandle<EcmaString> res1 = objectFactory->NewFromUtf8(resName1);
557     JSHandle<EcmaString> outFileName = PathHelper::ResolveDirPath(thread, inputFileName);
558     EXPECT_EQ(outFileName, res1);
559 
560     inputFileName = "moduleName\\ets\\pages\\index.abc";
561     CString resName2 = "moduleName\\ets\\pages\\";
562     JSHandle<EcmaString> res2 = objectFactory->NewFromUtf8(resName2);
563     outFileName = PathHelper::ResolveDirPath(thread, inputFileName);
564     EXPECT_EQ(outFileName, res2);
565 
566     inputFileName = "cjs";
567     CString resName3 = "";
568     JSHandle<EcmaString> res3 = objectFactory->NewFromUtf8(resName3);
569     outFileName = PathHelper::ResolveDirPath(thread, inputFileName);
570     EXPECT_EQ(outFileName, res3);
571 }
572 
HWTEST_F_L0(EcmaModuleTest,DeleteNamespace)573 HWTEST_F_L0(EcmaModuleTest, DeleteNamespace)
574 {
575     CString inputFileName = "moduleName@nameSpace";
576     CString res1 = "moduleName";
577     PathHelper::DeleteNamespace(inputFileName);
578     EXPECT_EQ(inputFileName, res1);
579 
580     inputFileName = "moduleName";
581     CString res2 = "moduleName";
582     PathHelper::DeleteNamespace(inputFileName);
583     EXPECT_EQ(inputFileName, res2);
584 }
585 
HWTEST_F_L0(EcmaModuleTest,AdaptOldIsaRecord)586 HWTEST_F_L0(EcmaModuleTest, AdaptOldIsaRecord)
587 {
588     CString inputFileName = "bundleName/moduleName@namespace/moduleName";
589     CString res1 = "moduleName";
590     PathHelper::AdaptOldIsaRecord(inputFileName);
591     EXPECT_EQ(inputFileName, res1);
592 }
593 
HWTEST_F_L0(EcmaModuleTest,GetStrippedModuleName)594 HWTEST_F_L0(EcmaModuleTest, GetStrippedModuleName)
595 {
596     CString inputFileName = "@ohos:hilog";
597     CString res1 = "hilog";
598     CString outFileName = PathHelper::GetStrippedModuleName(inputFileName);
599     EXPECT_EQ(outFileName, res1);
600 }
601 
HWTEST_F_L0(EcmaModuleTest,GetInternalModulePrefix)602 HWTEST_F_L0(EcmaModuleTest, GetInternalModulePrefix)
603 {
604     CString inputFileName = "@ohos:hilog";
605     CString res1 = "ohos";
606     CString outFileName = PathHelper::GetInternalModulePrefix(inputFileName);
607     EXPECT_EQ(outFileName, res1);
608 }
609 
HWTEST_F_L0(EcmaModuleTest,IsNativeModuleRequest)610 HWTEST_F_L0(EcmaModuleTest, IsNativeModuleRequest)
611 {
612     CString inputFileName = "json5";
613     bool res1 = ModulePathHelper::IsNativeModuleRequest(inputFileName);
614     EXPECT_TRUE(!res1);
615 
616     inputFileName = "@ohos:hilog";
617     bool res2 = ModulePathHelper::IsNativeModuleRequest(inputFileName);
618     EXPECT_TRUE(res2);
619 
620     inputFileName = "@app:xxxx";
621     bool res3 = ModulePathHelper::IsNativeModuleRequest(inputFileName);
622     EXPECT_TRUE(res3);
623 
624     inputFileName = "@native:xxxx";
625     bool res4 = ModulePathHelper::IsNativeModuleRequest(inputFileName);
626     EXPECT_TRUE(res4);
627 }
628 
HWTEST_F_L0(EcmaModuleTest,IsImportFile)629 HWTEST_F_L0(EcmaModuleTest, IsImportFile)
630 {
631     CString inputFileName = "./test";
632     bool res1 = ModulePathHelper::IsImportFile(inputFileName);
633     EXPECT_TRUE(res1);
634     CString outFileName = ModulePathHelper::RemoveSuffix(inputFileName);
635     EXPECT_EQ(outFileName, inputFileName);
636 
637     inputFileName = "test";
638     bool res2 = ModulePathHelper::IsImportFile(inputFileName);
639     EXPECT_TRUE(!res2);
640     outFileName = ModulePathHelper::RemoveSuffix(inputFileName);
641     EXPECT_EQ(outFileName, inputFileName);
642 
643     CString result = "test";
644     inputFileName = "test.js";
645     bool res3 = ModulePathHelper::IsImportFile(inputFileName);
646     EXPECT_TRUE(res3);
647     outFileName = ModulePathHelper::RemoveSuffix(inputFileName);
648     EXPECT_EQ(outFileName, result);
649 
650     inputFileName = "test.ts";
651     bool res4 = ModulePathHelper::IsImportFile(inputFileName);
652     EXPECT_TRUE(res4);
653     outFileName = ModulePathHelper::RemoveSuffix(inputFileName);
654     EXPECT_EQ(outFileName, result);
655 
656     inputFileName = "test.ets";
657     bool res5 = ModulePathHelper::IsImportFile(inputFileName);
658     EXPECT_TRUE(res5);
659     outFileName = ModulePathHelper::RemoveSuffix(inputFileName);
660     EXPECT_EQ(outFileName, result);
661 
662     inputFileName = "test.json";
663     bool res6 = ModulePathHelper::IsImportFile(inputFileName);
664     EXPECT_TRUE(res6);
665     outFileName = ModulePathHelper::RemoveSuffix(inputFileName);
666     EXPECT_EQ(outFileName, result);
667 }
668 }  // namespace panda::test
669