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/jspandafile/module_data_extractor.h"
26 #include "ecmascript/module/js_module_manager.h"
27 #include "ecmascript/module/js_module_source_text.h"
28 #include "ecmascript/tests/test_helper.h"
29 #include "ecmascript/linked_hash_table.h"
30
31
32 using namespace panda::ecmascript;
33 using namespace panda::panda_file;
34 using namespace panda::pandasm;
35 using PathHelper = panda::ecmascript::base::PathHelper;
36 namespace panda::test {
37 class EcmaModuleTest : public testing::Test {
38 public:
SetUpTestCase()39 static void SetUpTestCase()
40 {
41 GTEST_LOG_(INFO) << "SetUpTestCase";
42 }
43
TearDownTestCase()44 static void TearDownTestCase()
45 {
46 GTEST_LOG_(INFO) << "TearDownCase";
47 }
48
SetUp()49 void SetUp() override
50 {
51 TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
52 }
53
TearDown()54 void TearDown() override
55 {
56 TestHelper::DestroyEcmaVMWithScope(instance, scope);
57 }
58 EcmaVM *instance {nullptr};
59 ecmascript::EcmaHandleScope *scope {nullptr};
60 JSThread *thread {nullptr};
61 };
62
63 /*
64 * Feature: Module
65 * Function: AddImportEntry
66 * SubFunction: AddImportEntry
67 * FunctionPoints: Add import entry
68 * CaseDescription: Add two import item and check module import entries size
69 */
HWTEST_F_L0(EcmaModuleTest,AddImportEntry)70 HWTEST_F_L0(EcmaModuleTest, AddImportEntry)
71 {
72 ObjectFactory *objectFactory = thread->GetEcmaVM()->GetFactory();
73 JSHandle<SourceTextModule> module = objectFactory->NewSourceTextModule();
74 JSHandle<ImportEntry> importEntry1 = objectFactory->NewImportEntry();
75 SourceTextModule::AddImportEntry(thread, module, importEntry1, 0, 2);
76 JSHandle<ImportEntry> importEntry2 = objectFactory->NewImportEntry();
77 SourceTextModule::AddImportEntry(thread, module, importEntry2, 1, 2);
78 JSHandle<TaggedArray> importEntries(thread, module->GetImportEntries());
79 EXPECT_TRUE(importEntries->GetLength() == 2U);
80 }
81
82 /*
83 * Feature: Module
84 * Function: AddLocalExportEntry
85 * SubFunction: AddLocalExportEntry
86 * FunctionPoints: Add local export entry
87 * CaseDescription: Add two local export item and check module local export entries size
88 */
HWTEST_F_L0(EcmaModuleTest,AddLocalExportEntry)89 HWTEST_F_L0(EcmaModuleTest, AddLocalExportEntry)
90 {
91 ObjectFactory *objectFactory = thread->GetEcmaVM()->GetFactory();
92 JSHandle<SourceTextModule> module = objectFactory->NewSourceTextModule();
93 JSHandle<LocalExportEntry> localExportEntry1 = objectFactory->NewLocalExportEntry();
94 SourceTextModule::AddLocalExportEntry(thread, module, localExportEntry1, 0, 2);
95 JSHandle<LocalExportEntry> localExportEntry2 = objectFactory->NewLocalExportEntry();
96 SourceTextModule::AddLocalExportEntry(thread, module, localExportEntry2, 1, 2);
97 JSHandle<TaggedArray> localExportEntries(thread, module->GetLocalExportEntries());
98 EXPECT_TRUE(localExportEntries->GetLength() == 2U);
99 }
100
101 /*
102 * Feature: Module
103 * Function: AddIndirectExportEntry
104 * SubFunction: AddIndirectExportEntry
105 * FunctionPoints: Add indirect export entry
106 * CaseDescription: Add two indirect export item and check module indirect export entries size
107 */
HWTEST_F_L0(EcmaModuleTest,AddIndirectExportEntry)108 HWTEST_F_L0(EcmaModuleTest, AddIndirectExportEntry)
109 {
110 ObjectFactory *objectFactory = thread->GetEcmaVM()->GetFactory();
111 JSHandle<SourceTextModule> module = objectFactory->NewSourceTextModule();
112 JSHandle<IndirectExportEntry> indirectExportEntry1 = objectFactory->NewIndirectExportEntry();
113 SourceTextModule::AddIndirectExportEntry(thread, module, indirectExportEntry1, 0, 2);
114 JSHandle<IndirectExportEntry> indirectExportEntry2 = objectFactory->NewIndirectExportEntry();
115 SourceTextModule::AddIndirectExportEntry(thread, module, indirectExportEntry2, 1, 2);
116 JSHandle<TaggedArray> indirectExportEntries(thread, module->GetIndirectExportEntries());
117 EXPECT_TRUE(indirectExportEntries->GetLength() == 2U);
118 }
119
120 /*
121 * Feature: Module
122 * Function: StarExportEntries
123 * SubFunction: StarExportEntries
124 * FunctionPoints: Add start export entry
125 * CaseDescription: Add two start export item and check module start export entries size
126 */
HWTEST_F_L0(EcmaModuleTest,AddStarExportEntry)127 HWTEST_F_L0(EcmaModuleTest, AddStarExportEntry)
128 {
129 ObjectFactory *objectFactory = thread->GetEcmaVM()->GetFactory();
130 JSHandle<SourceTextModule> module = objectFactory->NewSourceTextModule();
131 JSHandle<StarExportEntry> starExportEntry1 = objectFactory->NewStarExportEntry();
132 SourceTextModule::AddStarExportEntry(thread, module, starExportEntry1, 0, 2);
133 JSHandle<StarExportEntry> starExportEntry2 = objectFactory->NewStarExportEntry();
134 SourceTextModule::AddStarExportEntry(thread, module, starExportEntry2, 1, 2);
135 JSHandle<TaggedArray> startExportEntries(thread, module->GetStarExportEntries());
136 EXPECT_TRUE(startExportEntries->GetLength() == 2U);
137 }
138
139 /*
140 * Feature: Module
141 * Function: StoreModuleValue
142 * SubFunction: StoreModuleValue/GetModuleValue
143 * FunctionPoints: store a module export item in module
144 * CaseDescription: Simulated implementation of "export foo as bar", set foo as "hello world",
145 * use "import bar" in same js file
146 */
HWTEST_F_L0(EcmaModuleTest,StoreModuleValue)147 HWTEST_F_L0(EcmaModuleTest, StoreModuleValue)
148 {
149 ObjectFactory* objFactory = thread->GetEcmaVM()->GetFactory();
150 CString localName = "foo";
151 CString exportName = "bar";
152 CString value = "hello world";
153
154 JSHandle<JSTaggedValue> localNameHandle = JSHandle<JSTaggedValue>::Cast(objFactory->NewFromUtf8(localName));
155 JSHandle<JSTaggedValue> exportNameHandle = JSHandle<JSTaggedValue>::Cast(objFactory->NewFromUtf8(exportName));
156 JSHandle<LocalExportEntry> localExportEntry =
157 objFactory->NewLocalExportEntry(exportNameHandle, localNameHandle);
158 JSHandle<SourceTextModule> module = objFactory->NewSourceTextModule();
159 SourceTextModule::AddLocalExportEntry(thread, module, localExportEntry, 0, 1);
160
161 JSHandle<JSTaggedValue> storeKey = JSHandle<JSTaggedValue>::Cast(objFactory->NewFromUtf8(localName));
162 JSHandle<JSTaggedValue> valueHandle = JSHandle<JSTaggedValue>::Cast(objFactory->NewFromUtf8(value));
163 module->StoreModuleValue(thread, storeKey, valueHandle);
164
165 JSHandle<JSTaggedValue> loadKey = JSHandle<JSTaggedValue>::Cast(objFactory->NewFromUtf8(localName));
166 JSTaggedValue loadValue = module->GetModuleValue(thread, loadKey.GetTaggedValue(), false);
167 EXPECT_EQ(valueHandle.GetTaggedValue(), loadValue);
168 }
169
170 /*
171 * Feature: Module
172 * Function: GetModuleValue
173 * SubFunction: StoreModuleValue/GetModuleValue
174 * FunctionPoints: load module value from module
175 * CaseDescription: Simulated implementation of "export default let foo = 'hello world'",
176 * use "import C from 'xxx' to get default value"
177 */
HWTEST_F_L0(EcmaModuleTest,GetModuleValue)178 HWTEST_F_L0(EcmaModuleTest, GetModuleValue)
179 {
180 ObjectFactory* objFactory = thread->GetEcmaVM()->GetFactory();
181 // export entry
182 CString exportLocalName = "*default*";
183 CString exportName = "default";
184 CString exportValue = "hello world";
185 JSHandle<JSTaggedValue> exportLocalNameHandle =
186 JSHandle<JSTaggedValue>::Cast(objFactory->NewFromUtf8(exportLocalName));
187 JSHandle<JSTaggedValue> exportNameHandle =
188 JSHandle<JSTaggedValue>::Cast(objFactory->NewFromUtf8(exportName));
189 JSHandle<LocalExportEntry> localExportEntry =
190 objFactory->NewLocalExportEntry(exportNameHandle, exportLocalNameHandle);
191 JSHandle<SourceTextModule> moduleExport = objFactory->NewSourceTextModule();
192 SourceTextModule::AddLocalExportEntry(thread, moduleExport, localExportEntry, 0, 1);
193 // store module value
194 JSHandle<JSTaggedValue> exportValueHandle = JSHandle<JSTaggedValue>::Cast(objFactory->NewFromUtf8(exportValue));
195 moduleExport->StoreModuleValue(thread, exportLocalNameHandle, exportValueHandle);
196
197 JSTaggedValue importDefaultValue =
198 moduleExport->GetModuleValue(thread, exportLocalNameHandle.GetTaggedValue(), false);
199 EXPECT_EQ(exportValueHandle.GetTaggedValue(), importDefaultValue);
200 }
201
HWTEST_F_L0(EcmaModuleTest,GetRecordName1)202 HWTEST_F_L0(EcmaModuleTest, GetRecordName1)
203 {
204 std::string baseFileName = MODULE_ABC_PATH "module_test_module_test_module_base.abc";
205
206 JSNApi::EnableUserUncaughtErrorHandler(instance);
207
208 bool result = JSNApi::Execute(instance, baseFileName, "module_test_module_test_module_base");
209 EXPECT_TRUE(result);
210 }
211
HWTEST_F_L0(EcmaModuleTest,GetRecordName2)212 HWTEST_F_L0(EcmaModuleTest, GetRecordName2)
213 {
214 std::string baseFileName = MODULE_ABC_PATH "module_test_module_test_A.abc";
215
216 JSNApi::EnableUserUncaughtErrorHandler(instance);
217
218 bool result = JSNApi::Execute(instance, baseFileName, "module_test_module_test_A");
219 EXPECT_TRUE(result);
220 }
221
HWTEST_F_L0(EcmaModuleTest,GetExportObjectIndex)222 HWTEST_F_L0(EcmaModuleTest, GetExportObjectIndex)
223 {
224 std::string baseFileName = MODULE_ABC_PATH "module_test_module_test_C.abc";
225
226 JSNApi::EnableUserUncaughtErrorHandler(instance);
227
228 bool result = JSNApi::Execute(instance, baseFileName, "module_test_module_test_C");
229 JSNApi::GetExportObject(instance, "module_test_module_test_B", "a");
230 EXPECT_TRUE(result);
231 }
232
HWTEST_F_L0(EcmaModuleTest,HostResolveImportedModule)233 HWTEST_F_L0(EcmaModuleTest, HostResolveImportedModule)
234 {
235 std::string baseFileName = MODULE_ABC_PATH "module_test_module_test_C.abc";
236
237 JSNApi::EnableUserUncaughtErrorHandler(instance);
238
239 ModuleManager *moduleManager = instance->GetModuleManager();
240 ObjectFactory *factory = instance->GetFactory();
241 JSHandle<SourceTextModule> module = factory->NewSourceTextModule();
242 JSHandle<JSTaggedValue> moduleRecord(thread, module.GetTaggedValue());
243 moduleManager->AddResolveImportedModule(baseFileName.c_str(), moduleRecord);
244 JSHandle<JSTaggedValue> res = moduleManager->HostResolveImportedModule(baseFileName.c_str());
245
246 EXPECT_EQ(moduleRecord->GetRawData(), res.GetTaggedValue().GetRawData());
247 }
248
HWTEST_F_L0(EcmaModuleTest,PreventExtensions_IsExtensible)249 HWTEST_F_L0(EcmaModuleTest, PreventExtensions_IsExtensible)
250 {
251 ObjectFactory *objectFactory = thread->GetEcmaVM()->GetFactory();
252 JSHandle<SourceTextModule> module = objectFactory->NewSourceTextModule();
253 JSHandle<LocalExportEntry> localExportEntry1 = objectFactory->NewLocalExportEntry();
254 SourceTextModule::AddLocalExportEntry(thread, module, localExportEntry1, 0, 2);
255 JSHandle<LocalExportEntry> localExportEntry2 = objectFactory->NewLocalExportEntry();
256 SourceTextModule::AddLocalExportEntry(thread, module, localExportEntry2, 1, 2);
257 JSHandle<TaggedArray> localExportEntries(thread, module->GetLocalExportEntries());
258 JSHandle<ModuleNamespace> np =
259 ModuleNamespace::ModuleNamespaceCreate(thread, JSHandle<JSTaggedValue>::Cast(module), localExportEntries);
260 EXPECT_FALSE(np->IsExtensible());
261 EXPECT_TRUE(ModuleNamespace::PreventExtensions());
262 }
263
HWTEST_F_L0(EcmaModuleTest,Instantiate_Evaluate_GetNamespace_SetNamespace)264 HWTEST_F_L0(EcmaModuleTest, Instantiate_Evaluate_GetNamespace_SetNamespace)
265 {
266 std::string baseFileName = MODULE_ABC_PATH "module_test_module_test_C.abc";
267
268 JSNApi::EnableUserUncaughtErrorHandler(instance);
269
270 bool result = JSNApi::Execute(instance, baseFileName, "module_test_module_test_C");
271 EXPECT_TRUE(result);
272 ModuleManager *moduleManager = instance->GetModuleManager();
273 JSHandle<SourceTextModule> module = moduleManager->HostGetImportedModule("module_test_module_test_C");
274 module->SetStatus(ModuleStatus::UNINSTANTIATED);
275 ModuleRecord::Instantiate(thread, JSHandle<JSTaggedValue>(module));
276 int res = ModuleRecord::Evaluate(thread, JSHandle<JSTaggedValue>(module));
277 ModuleRecord::GetNamespace(module.GetTaggedValue());
278 ModuleRecord::SetNamespace(thread, module.GetTaggedValue(), JSTaggedValue::Undefined());
279 EXPECT_TRUE(res == SourceTextModule::UNDEFINED_INDEX);
280 }
281
HWTEST_F_L0(EcmaModuleTest,ConcatFileNameWithMerge1)282 HWTEST_F_L0(EcmaModuleTest, ConcatFileNameWithMerge1)
283 {
284 CString baseFilename = "merge.abc";
285 const char *data = R"(
286 .language ECMAScript
287 .function any func_main_0(any a0, any a1, any a2) {
288 ldai 1
289 return
290 }
291 )";
292 JSPandaFileManager *pfManager = JSPandaFileManager::GetInstance();
293 Parser parser;
294 auto res = parser.Parse(data);
295 std::unique_ptr<const File> pfPtr = pandasm::AsmEmitter::Emit(res.Value());
296 JSPandaFile *pf = pfManager->NewJSPandaFile(pfPtr.release(), baseFilename);
297
298 // Test moduleRequestName start with "@bundle"
299 CString moduleRecordName = "moduleTest1";
300 CString moduleRequestName = "@bundle:com.bundleName.test/moduleName/requestModuleName1";
301 CString result = "com.bundleName.test/moduleName/requestModuleName1";
302 CString entryPoint = PathHelper::ConcatFileNameWithMerge(thread, pf, baseFilename, moduleRecordName,
303 moduleRequestName);
304 EXPECT_EQ(result, entryPoint);
305
306 // Test cross application
307 moduleRecordName = "@bundle:com.bundleName1.test/moduleName/requestModuleName1";
308 CString newBaseFileName = "/data/storage/el1/bundle/com.bundleName.test/moduleName/moduleName/ets/modules.abc";
309 PathHelper::ConcatFileNameWithMerge(thread, pf, baseFilename, moduleRecordName, moduleRequestName);
310 EXPECT_EQ(baseFilename, newBaseFileName);
311 }
312
HWTEST_F_L0(EcmaModuleTest,ConcatFileNameWithMerge2)313 HWTEST_F_L0(EcmaModuleTest, ConcatFileNameWithMerge2)
314 {
315 CString baseFilename = "merge.abc";
316 const char *data = R"(
317 .language ECMAScript
318 .function any func_main_0(any a0, any a1, any a2) {
319 ldai 1
320 return
321 }
322 )";
323 JSPandaFileManager *pfManager = JSPandaFileManager::GetInstance();
324 Parser parser;
325 auto res = parser.Parse(data);
326 std::unique_ptr<const File> pfPtr = pandasm::AsmEmitter::Emit(res.Value());
327 JSPandaFile *pf = pfManager->NewJSPandaFile(pfPtr.release(), baseFilename);
328
329 // Test moduleRequestName start with "./"
330 CString moduleRecordName = "moduleTest2";
331 CString moduleRequestName = "./requestModule.js";
332 CString result = "requestModule";
333 pf->InsertJSRecordInfo(result);
334 CString entryPoint = PathHelper::ConcatFileNameWithMerge(thread, pf, baseFilename, moduleRecordName,
335 moduleRequestName);
336 EXPECT_EQ(result, entryPoint);
337
338 // Test moduleRecordName with "/"
339 moduleRecordName = "moduleName/moduleTest2";
340 moduleRequestName = "./requestModule.js";
341 result = "moduleName/requestModule";
342 pf->InsertJSRecordInfo(result);
343 entryPoint = PathHelper::ConcatFileNameWithMerge(thread, pf, baseFilename, moduleRecordName, moduleRequestName);
344 EXPECT_EQ(result, entryPoint);
345 }
346
HWTEST_F_L0(EcmaModuleTest,ConcatFileNameWithMerge3)347 HWTEST_F_L0(EcmaModuleTest, ConcatFileNameWithMerge3)
348 {
349 CString baseFilename = "merge.abc";
350 const char *data = R"(
351 .language ECMAScript
352 .function any func_main_0(any a0, any a1, any a2) {
353 ldai 1
354 return
355 }
356 )";
357 JSPandaFileManager *pfManager = JSPandaFileManager::GetInstance();
358 Parser parser;
359 auto res = parser.Parse(data);
360 std::unique_ptr<const File> pfPtr = pandasm::AsmEmitter::Emit(res.Value());
361 JSPandaFile *pf = pfManager->NewJSPandaFile(pfPtr.release(), baseFilename);
362
363 // Test RecordName is not in JSPandaFile
364 CString moduleRecordName = "moduleTest3";
365 CString moduleRequestName = "./secord.js";
366 CString result = "secord";
367 CString requestFileName = "secord.abc";
368 CString entryPoint =
369 PathHelper::ConcatFileNameWithMerge(thread, pf, baseFilename, moduleRecordName, moduleRequestName);
370 EXPECT_EQ(baseFilename, requestFileName);
371 EXPECT_EQ(result, entryPoint);
372
373 // Test RecordName is not in JSPandaFile and baseFilename with "/" and moduleRequestName with "/"
374 baseFilename = "test/merge.abc";
375 std::unique_ptr<const File> pfPtr2 = pandasm::AsmEmitter::Emit(res.Value());
376 JSPandaFile *pf2 = pfManager->NewJSPandaFile(pfPtr2.release(), baseFilename);
377
378 moduleRecordName = "moduleTest3";
379 moduleRequestName = "./test/secord.js";
380 result = "secord";
381 requestFileName = "test/test/secord.abc";
382 entryPoint = PathHelper::ConcatFileNameWithMerge(thread, pf2, baseFilename, moduleRecordName,
383 moduleRequestName);
384 EXPECT_EQ(baseFilename, requestFileName);
385 EXPECT_EQ(result, entryPoint);
386 }
387
HWTEST_F_L0(EcmaModuleTest,ConcatFileNameWithMerge4)388 HWTEST_F_L0(EcmaModuleTest, ConcatFileNameWithMerge4)
389 {
390 CString baseFilename = "merge.abc";
391 const char *data = R"(
392 .language ECMAScript
393 .function any func_main_0(any a0, any a1, any a2) {
394 ldai 1
395 return
396 }
397 )";
398 JSPandaFileManager *pfManager = JSPandaFileManager::GetInstance();
399 Parser parser;
400 auto res = parser.Parse(data);
401 std::unique_ptr<const File> pfPtr = pandasm::AsmEmitter::Emit(res.Value());
402 JSPandaFile *pf = pfManager->NewJSPandaFile(pfPtr.release(), baseFilename);
403 const CUnorderedMap<CString, JSPandaFile::JSRecordInfo> &recordInfo = pf->GetJSRecordInfo();
404 // Test moduleRequestName is npm package
405 CString moduleRecordName = "node_modules/0/moduleTest4/index";
406 CString moduleRequestName = "json/index";
407 CString result = "node_modules/0/moduleTest4/node_modules/json/index";
408 JSPandaFile::JSRecordInfo info;
409 info.npmPackageName = "node_modules/0/moduleTest4";
410 const_cast<CUnorderedMap<CString, JSPandaFile::JSRecordInfo> &>(recordInfo).insert({moduleRecordName, info});
411 const_cast<CUnorderedMap<CString, JSPandaFile::JSRecordInfo> &>(recordInfo).insert({result, info});
412 CString entryPoint = PathHelper::ConcatFileNameWithMerge(thread, pf, baseFilename, moduleRecordName,
413 moduleRequestName);
414 EXPECT_EQ(result, entryPoint);
415 }
416
HWTEST_F_L0(EcmaModuleTest,NormalizePath)417 HWTEST_F_L0(EcmaModuleTest, NormalizePath)
418 {
419 CString res1 = "node_modules/0/moduleTest/index";
420 CString moduleRecordName1 = "node_modules///0//moduleTest/index";
421
422 CString res2 = "node_modules/0/moduleTest/index";
423 CString moduleRecordName2 = "./node_modules///0//moduleTest/index";
424
425 CString res3 = "../node_modules/0/moduleTest/index";
426 CString moduleRecordName3 = "../node_modules/0/moduleTest///index";
427
428 CString res4 = "moduleTest/index";
429 CString moduleRecordName4 = "./node_modules/..//moduleTest////index";
430
431 CString res5 = "node_modules/moduleTest/index";
432 CString moduleRecordName5 = "node_modules/moduleTest/index/";
433
434 CString normalName1 = PathHelper::NormalizePath(moduleRecordName1);
435 CString normalName2 = PathHelper::NormalizePath(moduleRecordName2);
436 CString normalName3 = PathHelper::NormalizePath(moduleRecordName3);
437 CString normalName4 = PathHelper::NormalizePath(moduleRecordName4);
438 CString normalName5 = PathHelper::NormalizePath(moduleRecordName5);
439
440 EXPECT_EQ(res1, normalName1);
441 EXPECT_EQ(res2, normalName2);
442 EXPECT_EQ(res3, normalName3);
443 EXPECT_EQ(res4, normalName4);
444 EXPECT_EQ(res5, normalName5);
445 }
446
HWTEST_F_L0(EcmaModuleTest,ParseOhmUrl)447 HWTEST_F_L0(EcmaModuleTest, ParseOhmUrl)
448 {
449 // old pages url
450 instance->SetBundleName("com.bundleName.test");
451 instance->SetModuleName("moduleName");
452 CString inputFileName = "pages/index.abc";
453 CString outFileName = "";
454 CString res1 = "com.bundleName.test/moduleName/ets/pages/index";
455 CString entryPoint = PathHelper::ParseOhmUrl(instance, inputFileName, outFileName);
456 EXPECT_EQ(entryPoint, res1);
457 EXPECT_EQ(outFileName, "");
458
459 // new pages url
460 inputFileName = "@bundle:com.bundleName.test/moduleName/ets/pages/index.abc";
461 entryPoint = PathHelper::ParseOhmUrl(instance, inputFileName, outFileName);
462 EXPECT_EQ(entryPoint, res1);
463 EXPECT_EQ(outFileName, "");
464
465 // new pages url Intra-application cross hap
466 inputFileName = "@bundle:com.bundleName.test/moduleName1/ets/pages/index.abc";
467 CString outRes = "/data/storage/el1/bundle/moduleName1/ets/modules.abc";
468 CString res2 = "com.bundleName.test/moduleName1/ets/pages/index";
469 entryPoint = PathHelper::ParseOhmUrl(instance, inputFileName, outFileName);
470 EXPECT_EQ(entryPoint, res2);
471 EXPECT_EQ(outFileName, outRes);
472
473 // new pages url Cross-application
474 inputFileName = "@bundle:com.bundleName.test1/moduleName1/ets/pages/index.abc";
475 CString outRes1 = "/data/storage/el1/bundle/com.bundleName.test1/moduleName1/moduleName1/ets/modules.abc";
476 CString res3 = "com.bundleName.test1/moduleName1/ets/pages/index";
477 entryPoint = PathHelper::ParseOhmUrl(instance, inputFileName, outFileName);
478 EXPECT_EQ(entryPoint, res3);
479 EXPECT_EQ(outFileName, outRes1);
480
481 // worker url Intra-application cross hap
482 inputFileName = "/data/storage/el1/bundle/entry/ets/mainAbility.abc";
483 CString outRes2 = "/data/storage/el1/bundle/entry/ets/modules.abc";
484 CString res4 = "com.bundleName.test/entry/ets/mainAbility";
485 entryPoint = PathHelper::ParseOhmUrl(instance, inputFileName, outFileName);
486 EXPECT_EQ(entryPoint, res4);
487 EXPECT_EQ(outFileName, outRes2);
488
489 // worker url
490 outFileName = "";
491 inputFileName = "/data/storage/el1/bundle/moduleName/ets/mainAbility.abc";
492 CString res5 = "com.bundleName.test/moduleName/ets/mainAbility";
493 entryPoint = PathHelper::ParseOhmUrl(instance, inputFileName, outFileName);
494 EXPECT_EQ(entryPoint, res5);
495 EXPECT_EQ(outFileName, "");
496 }
497 } // namespace panda::test
498