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
16 #include <gtest/gtest.h>
17 #include <cstring>
18
19 #include "libabckit/include/c/abckit.h"
20 #include "helpers/helpers.h"
21 #include "helpers/helpers_runtime.h"
22 #include "libabckit/include/c/metadata_core.h"
23 #include "libabckit/include/c/extensions/arkts/metadata_arkts.h"
24 #include "ir_impl.h"
25 #include "libabckit/include/c/isa/isa_dynamic.h"
26 #include "metadata_inspect_impl.h"
27 #include "libabckit/include/c/statuses.h"
28
29 namespace libabckit::test {
30
31 static auto g_impl = AbckitGetApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
32 static auto g_implI = AbckitGetInspectApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
33 static auto g_implArkI = AbckitGetArktsInspectApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
34 static auto g_implM = AbckitGetModifyApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
35 static auto g_implArkM = AbckitGetArktsModifyApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
36 static auto g_implG = AbckitGetGraphApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
37 static auto g_dynG = AbckitGetIsaApiDynamicImpl(ABCKIT_VERSION_RELEASE_1_0_0);
38
39 class LibAbcKitArkTSModifyApiModulesTest : public ::testing::Test {};
40
41 constexpr auto MAIN_MODULE_NAME = "modules_dynamic_modify";
42
43 // ========================================
44 // Helpers
45 // ========================================
46
ModifyMetaDynModuleRemoveImport(AbckitFile * file,const std::string & name,bool shouldBeRemoved)47 static void ModifyMetaDynModuleRemoveImport(AbckitFile *file, const std::string &name, bool shouldBeRemoved)
48 {
49 helpers::ModuleByNameContext ctxFinder = {nullptr, MAIN_MODULE_NAME};
50 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
51 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
52 ASSERT_NE(ctxFinder.module, nullptr);
53 auto *module = ctxFinder.module;
54
55 std::set<AbckitCoreImportDescriptor *> gotImports;
56 g_implI->moduleEnumerateImports(module, &gotImports, helpers::ModuleImportsCollector);
57 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
58 ASSERT_EQ(gotImports.empty(), false);
59
60 bool removed = false;
61 for (auto &gotImport : gotImports) {
62 auto impName = g_implI->importDescriptorGetAlias(gotImport);
63 auto strName = helpers::AbckitStringToString(impName);
64 if (strName == name) {
65 g_implArkM->moduleRemoveImport(g_implArkI->coreModuleToArktsModule(module),
66 g_implArkI->coreImportDescriptorToArktsImportDescriptor(gotImport));
67 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
68 removed = true;
69 break;
70 }
71 }
72
73 ASSERT_EQ(removed, shouldBeRemoved);
74
75 std::set<AbckitCoreImportDescriptor *> gotImportsAfter;
76 g_implI->moduleEnumerateImports(module, &gotImportsAfter, helpers::ModuleImportsCollector);
77 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
78 ASSERT_EQ(gotImportsAfter.empty(), false);
79
80 for (auto &gotImportAfter : gotImportsAfter) {
81 auto impName = g_implI->importDescriptorGetAlias(gotImportAfter);
82 auto strName = helpers::AbckitStringToString(impName);
83 ASSERT_NE(strName, name);
84 }
85 }
86
ModifyMetaDynModuleRemoveExport(AbckitFile * file,const std::string & exportName,bool shouldBeRemoved)87 static void ModifyMetaDynModuleRemoveExport(AbckitFile *file, const std::string &exportName, bool shouldBeRemoved)
88 {
89 helpers::ModuleByNameContext ctxFinder = {nullptr, MAIN_MODULE_NAME};
90 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
91 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
92 ASSERT_NE(ctxFinder.module, nullptr);
93 auto *module = ctxFinder.module;
94
95 std::set<AbckitCoreExportDescriptor *> gotExports;
96 g_implI->moduleEnumerateExports(module, &gotExports, helpers::ModuleExportsCollector);
97 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
98
99 bool removed = false;
100 for (auto &gotExport : gotExports) {
101 auto expName = g_implI->exportDescriptorGetAlias(gotExport);
102 auto strName = helpers::AbckitStringToString(expName);
103 if (strName == exportName) {
104 g_implArkM->moduleRemoveExport(g_implArkI->coreModuleToArktsModule(module),
105 g_implArkI->coreExportDescriptorToArktsExportDescriptor(gotExport));
106 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
107 removed = true;
108 break;
109 }
110 }
111
112 ASSERT_EQ(removed, shouldBeRemoved);
113
114 std::set<AbckitCoreExportDescriptor *> gotExportsAfter;
115 g_implI->moduleEnumerateExports(module, &gotExportsAfter, helpers::ModuleExportsCollector);
116 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
117
118 for (auto &gotExportAfter : gotExportsAfter) {
119 auto expName = g_implI->exportDescriptorGetAlias(gotExportAfter);
120 auto strName = helpers::AbckitStringToString(expName);
121 ASSERT_NE(strName, exportName);
122 }
123 }
124
TransformIrDynModuleRemoveImport(AbckitGraph * graph,const std::string & name)125 static void TransformIrDynModuleRemoveImport(AbckitGraph *graph, const std::string &name)
126 {
127 AbckitInst *instWithName = helpers::FindFirstInst(
128 graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_THROW_UNDEFINEDIFHOLEWITHNAME, [&](AbckitInst *inst) {
129 auto nameOffset = g_implG->iGetImmediate(inst, 0);
130 auto nameStr = graph->irInterface->GetStringIdByOffset(nameOffset);
131 return nameStr == name;
132 });
133
134 ASSERT_NE(instWithName, nullptr);
135 auto ldExternalModuleVarInst = g_implG->iGetPrev(instWithName);
136 ASSERT_NE(ldExternalModuleVarInst, nullptr);
137 auto callArg0Inst = g_implG->iGetNext(instWithName);
138 ASSERT_NE(callArg0Inst, nullptr);
139
140 g_implG->iRemove(instWithName);
141 g_implG->iRemove(ldExternalModuleVarInst);
142 g_implG->iRemove(callArg0Inst);
143 }
144
TransformIrDynModuleRemoveNSImport(AbckitGraph * graph,const std::string & name)145 static void TransformIrDynModuleRemoveNSImport(AbckitGraph *graph, const std::string &name)
146 {
147 AbckitInst *ldObjByNameInst =
148 helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_LDOBJBYNAME, [&](AbckitInst *inst) {
149 auto nameOffset = g_implG->iGetImmediate(inst, 1);
150 auto nameStr = graph->irInterface->GetStringIdByOffset(nameOffset);
151 return nameStr == name;
152 });
153
154 ASSERT_NE(ldObjByNameInst, nullptr);
155 auto callThis0Inst = g_implG->iGetNext(ldObjByNameInst);
156 ASSERT_NE(callThis0Inst, nullptr);
157
158 g_implG->iRemove(ldObjByNameInst);
159 g_implG->iRemove(callThis0Inst);
160 }
161
TransformIrDynModuleRemoveExport(AbckitGraph * graph,const std::string & exportName)162 static void TransformIrDynModuleRemoveExport(AbckitGraph *graph, const std::string &exportName)
163 {
164 AbckitInst *instWithName = helpers::FindFirstInst(
165 graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_THROW_UNDEFINEDIFHOLEWITHNAME, [&](AbckitInst *inst) {
166 auto nameOffset = g_implG->iGetImmediate(inst, 0);
167 auto nameStr = graph->irInterface->GetStringIdByOffset(nameOffset);
168 return nameStr == exportName;
169 });
170
171 ASSERT_NE(instWithName, nullptr);
172 auto ldLocalModuleVarInst = g_implG->iGetPrev(instWithName);
173 ASSERT_NE(ldLocalModuleVarInst, nullptr);
174 auto callArg1Inst = g_implG->iGetNext(instWithName);
175 ASSERT_NE(callArg1Inst, nullptr);
176
177 g_implG->iRemove(instWithName);
178 g_implG->iRemove(ldLocalModuleVarInst);
179 g_implG->iRemove(callArg1Inst);
180
181 AbckitInst *stModuleVarInst =
182 helpers::FindFirstInst(graph, ABCKIT_ISA_API_DYNAMIC_OPCODE_STMODULEVAR, [&](AbckitInst *inst) {
183 return g_implG->iGetImmediate(inst, 0) == g_implG->iGetImmediate(ldLocalModuleVarInst, 0);
184 });
185
186 ASSERT_NE(stModuleVarInst, nullptr);
187 g_implG->iRemove(stModuleVarInst);
188 }
189
190 struct UserTransformerData {
191 std::string name;
192 std::string alias;
193 std::string moduleName;
194 bool isRegular = false;
195 AbckitDynamicExportKind kind = ABCKIT_DYNAMIC_EXPORT_KIND_LOCAL_EXPORT;
196 };
197
AddImportFromDynamicModuleImpl(AbckitCoreModule * module,void * data)198 static void AddImportFromDynamicModuleImpl(AbckitCoreModule *module, void *data)
199 {
200 auto userTransformerData = reinterpret_cast<UserTransformerData *>(data);
201 AbckitFile *file = g_implI->moduleGetFile(module);
202
203 helpers::ModuleByNameContext ctxFinder = {nullptr, (userTransformerData->moduleName).c_str()};
204 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
205 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
206 ASSERT_NE(ctxFinder.module, nullptr);
207
208 AbckitArktsImportFromDynamicModuleCreateParams params {};
209 params.name = (userTransformerData->name).c_str();
210 params.alias = (userTransformerData->alias).c_str();
211
212 auto newImport = g_implArkM->moduleAddImportFromArktsV1ToArktsV1(
213 g_implArkI->coreModuleToArktsModule(module), g_implArkI->coreModuleToArktsModule(ctxFinder.module), ¶ms);
214 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
215
216 std::set<AbckitCoreImportDescriptor *> gotImports;
217 g_implI->moduleEnumerateImports(module, &gotImports, helpers::ModuleImportsCollector);
218
219 bool existed = false;
220 for (auto &gotImport : gotImports) {
221 if (g_implArkI->coreImportDescriptorToArktsImportDescriptor(gotImport) != newImport) {
222 continue;
223 }
224 existed = true;
225
226 auto impName = g_implI->importDescriptorGetName(gotImport);
227 auto strName = helpers::AbckitStringToString(impName);
228 auto impAlias = g_implI->importDescriptorGetAlias(gotImport);
229 auto strAlias = helpers::AbckitStringToString(impAlias);
230 ASSERT_EQ(userTransformerData->name, strName);
231 ASSERT_EQ(userTransformerData->alias, strAlias);
232 ASSERT_EQ(g_implI->importDescriptorGetImportedModule(gotImport), ctxFinder.module);
233 ASSERT_EQ(g_implI->importDescriptorGetImportingModule(gotImport), module);
234 ASSERT_EQ(gotImport->GetArkTSImpl()->payload.GetDynId().isRegularImport, userTransformerData->isRegular);
235 }
236
237 ASSERT_EQ(existed, true);
238 }
239
DynamicModuleAddExportImpl(AbckitCoreModule * module,void * data)240 static void DynamicModuleAddExportImpl(AbckitCoreModule *module, void *data)
241 {
242 auto userTransformerData = reinterpret_cast<UserTransformerData *>(data);
243 AbckitFile *file = g_implI->moduleGetFile(module);
244
245 AbckitArktsDynamicModuleExportCreateParams params {};
246
247 AbckitCoreModule *exported = nullptr;
248 if (!userTransformerData->moduleName.empty()) {
249 helpers::ModuleByNameContext ctxFinder = {nullptr, (userTransformerData->moduleName).c_str()};
250 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
251 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
252 ASSERT_NE(ctxFinder.module, nullptr);
253 exported = ctxFinder.module;
254 }
255 params.name = (userTransformerData->name).c_str();
256
257 if (userTransformerData->alias.empty()) {
258 params.alias = nullptr;
259 } else {
260 params.alias = (userTransformerData->alias).c_str();
261 }
262
263 auto newExport = g_implArkM->moduleAddExportFromArktsV1ToArktsV1(
264 g_implArkI->coreModuleToArktsModule(module), g_implArkI->coreModuleToArktsModule(exported), ¶ms);
265 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
266
267 std::set<AbckitCoreExportDescriptor *> gotExports;
268 g_implI->moduleEnumerateExports(module, &gotExports, helpers::ModuleExportsCollector);
269
270 bool existed = false;
271 for (auto &gotExport : gotExports) {
272 if (g_implArkI->coreExportDescriptorToArktsExportDescriptor(gotExport) != newExport) {
273 continue;
274 }
275 existed = true;
276
277 auto expName = g_implI->exportDescriptorGetName(gotExport);
278 auto strName = helpers::AbckitStringToString(expName);
279 auto expAlias = g_implI->exportDescriptorGetAlias(gotExport);
280 auto strAlias = helpers::AbckitStringToString(expAlias);
281 ASSERT_EQ(userTransformerData->name, strName);
282 ASSERT_EQ(userTransformerData->alias, strAlias);
283 ASSERT_EQ(userTransformerData->kind, gotExport->GetArkTSImpl()->payload.GetDynamicPayload().kind);
284 if (userTransformerData->kind == AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_LOCAL_EXPORT) {
285 ASSERT_EQ(g_implI->exportDescriptorGetExportedModule(gotExport), module);
286 } else {
287 ASSERT_EQ(g_implI->exportDescriptorGetExportedModule(gotExport), exported);
288 }
289 ASSERT_EQ(g_implI->exportDescriptorGetExportingModule(gotExport), module);
290 }
291
292 ASSERT_EQ(existed, true);
293 }
294
TransformIrAddImportedFunctionCall(AbckitGraph * graph,AbckitFile * file,const std::string & funcName)295 static void TransformIrAddImportedFunctionCall(AbckitGraph *graph, AbckitFile *file, const std::string &funcName)
296 {
297 auto abckitStrName = g_implM->createString(file, funcName.c_str(), funcName.size());
298 helpers::ModuleByNameContext ctxFinder = {nullptr, MAIN_MODULE_NAME};
299 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
300 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
301 ASSERT_NE(ctxFinder.module, nullptr);
302 helpers::ImportByAliasContext importFinder = {nullptr, funcName.c_str()};
303 g_implI->moduleEnumerateImports(ctxFinder.module, &importFinder, helpers::ImportByAliasFinder);
304 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
305 ASSERT_NE(importFinder.id, nullptr);
306
307 AbckitBasicBlock *mainBB = g_implG->bbGetSuccBlock(g_implG->gGetStartBasicBlock(graph), 0);
308 AbckitInst *lastInst = g_implG->bbGetLastInst(mainBB);
309 auto ldExternalModuleVarInst = g_dynG->iCreateLdexternalmodulevar(graph, importFinder.id);
310 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
311 auto throwUndef = g_dynG->iCreateThrowUndefinedifholewithname(graph, ldExternalModuleVarInst, abckitStrName);
312 auto callInst = g_dynG->iCreateCallarg0(graph, ldExternalModuleVarInst);
313 g_implG->iInsertBefore(ldExternalModuleVarInst, lastInst);
314 g_implG->iInsertBefore(throwUndef, lastInst);
315 g_implG->iInsertBefore(callInst, lastInst);
316 }
317
TransformIrAddImportedFunctionCallNS(AbckitGraph * graph,AbckitFile * file,const std::string & funcName,const std::string & moduleName)318 static void TransformIrAddImportedFunctionCallNS(AbckitGraph *graph, AbckitFile *file, const std::string &funcName,
319 const std::string &moduleName)
320 {
321 auto abckitStrName = g_implM->createString(file, funcName.c_str(), funcName.size());
322 helpers::ModuleByNameContext ctxFinder = {nullptr, moduleName.c_str()};
323 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
324 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
325 ASSERT_NE(ctxFinder.module, nullptr);
326
327 AbckitBasicBlock *mainBB = g_implG->bbGetSuccBlock(g_implG->gGetStartBasicBlock(graph), 0);
328 AbckitInst *lastInst = g_implG->bbGetLastInst(mainBB);
329 auto getModuleNamespaceInst = g_dynG->iCreateGetmodulenamespace(graph, ctxFinder.module);
330 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
331 auto ldObjByNameInst = g_dynG->iCreateLdobjbyname(graph, getModuleNamespaceInst, abckitStrName);
332 auto callInst = g_dynG->iCreateCallthis0(graph, ldObjByNameInst, getModuleNamespaceInst);
333 g_implG->iInsertBefore(getModuleNamespaceInst, lastInst);
334 g_implG->iInsertBefore(ldObjByNameInst, lastInst);
335 g_implG->iInsertBefore(callInst, lastInst);
336 }
337
TransformIrAddLocalExport(AbckitGraph * graph,AbckitFile * file,const std::string & varName,const std::string & moduleName)338 static void TransformIrAddLocalExport(AbckitGraph *graph, AbckitFile *file, const std::string &varName,
339 const std::string &moduleName)
340 {
341 AbckitBasicBlock *mainBB = g_implG->bbGetSuccBlock(g_implG->gGetStartBasicBlock(graph), 0);
342 AbckitInst *lastInst = g_implG->bbGetLastInst(mainBB);
343
344 AbckitString *abckitStr = g_implM->createString(file, "print", strlen("print"));
345 auto tryLdGlobalByNameInst = g_dynG->iCreateTryldglobalbyname(graph, abckitStr);
346
347 helpers::ModuleByNameContext ctxFinder = {nullptr, moduleName.c_str()};
348 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
349 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
350 ASSERT_NE(ctxFinder.module, nullptr);
351
352 helpers::ExportByAliasContext exportFinder = {nullptr, varName.c_str()};
353 g_implI->moduleEnumerateExports(ctxFinder.module, &exportFinder, helpers::ExportByAliasFinder);
354 ASSERT_NE(exportFinder.ed, nullptr);
355
356 auto constant = g_implG->gFindOrCreateConstantI32(graph, 5);
357 auto stModuleVarInst = g_dynG->iCreateStmodulevar(graph, constant, exportFinder.ed);
358 auto ldLocalModuleVarInst = g_dynG->iCreateLdlocalmodulevar(graph, exportFinder.ed);
359 AbckitString *varNameStr = g_implM->createString(file, varName.c_str(), varName.size());
360 auto throwUndef = g_dynG->iCreateThrowUndefinedifholewithname(graph, ldLocalModuleVarInst, varNameStr);
361 auto callInst = g_dynG->iCreateCallarg1(graph, tryLdGlobalByNameInst, ldLocalModuleVarInst);
362
363 g_implG->iInsertBefore(stModuleVarInst, lastInst);
364 g_implG->iInsertBefore(tryLdGlobalByNameInst, lastInst);
365 g_implG->iInsertBefore(ldLocalModuleVarInst, lastInst);
366 g_implG->iInsertBefore(throwUndef, lastInst);
367 g_implG->iInsertBefore(callInst, lastInst);
368 }
369
TransformIrAddIndirectExport(AbckitGraph * graph,AbckitFile * file,const std::string & varName,const std::string & moduleName)370 static void TransformIrAddIndirectExport(AbckitGraph *graph, AbckitFile *file, const std::string &varName,
371 const std::string &moduleName)
372 {
373 AbckitBasicBlock *mainBB = g_implG->bbGetSuccBlock(g_implG->gGetStartBasicBlock(graph), 0);
374 AbckitInst *lastInst = g_implG->bbGetLastInst(mainBB);
375
376 AbckitString *abckitStr = g_implM->createString(file, "print", strlen("print"));
377 auto tryLdGlobalByNameInst = g_dynG->iCreateTryldglobalbyname(graph, abckitStr);
378
379 helpers::ModuleByNameContext ctxFinder = {nullptr, moduleName.c_str()};
380 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
381 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
382 ASSERT_NE(ctxFinder.module, nullptr);
383
384 helpers::ImportByAliasContext importFinder = {nullptr, varName.c_str()};
385 g_implI->moduleEnumerateImports(ctxFinder.module, &importFinder, helpers::ImportByAliasFinder);
386 ASSERT_NE(importFinder.id, nullptr);
387
388 auto ldExternalModuleVarInst = g_dynG->iCreateLdexternalmodulevar(graph, importFinder.id);
389 AbckitString *varNameStr = g_implM->createString(file, varName.c_str(), varName.size());
390 auto throwUndef = g_dynG->iCreateThrowUndefinedifholewithname(graph, ldExternalModuleVarInst, varNameStr);
391 auto callInst = g_dynG->iCreateCallarg1(graph, tryLdGlobalByNameInst, ldExternalModuleVarInst);
392 g_implG->iInsertBefore(tryLdGlobalByNameInst, lastInst);
393 g_implG->iInsertBefore(ldExternalModuleVarInst, lastInst);
394 g_implG->iInsertBefore(throwUndef, lastInst);
395 g_implG->iInsertBefore(callInst, lastInst);
396 }
397
TransformIrAddStarExport(AbckitGraph * graph,AbckitFile * file,const std::string & funcName,const std::string & moduleName)398 static void TransformIrAddStarExport(AbckitGraph *graph, AbckitFile *file, const std::string &funcName,
399 const std::string &moduleName)
400 {
401 AbckitBasicBlock *mainBB = g_implG->bbGetSuccBlock(g_implG->gGetStartBasicBlock(graph), 0);
402 AbckitInst *lastInst = g_implG->bbGetLastInst(mainBB);
403
404 helpers::ModuleByNameContext ctxFinder = {nullptr, moduleName.c_str()};
405 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
406 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
407 ASSERT_NE(ctxFinder.module, nullptr);
408
409 auto getModuleNamespaceInst = g_dynG->iCreateGetmodulenamespace(graph, ctxFinder.module);
410 AbckitString *funcNameStr = g_implM->createString(file, funcName.c_str(), funcName.size());
411 auto ldObjByNameInst = g_dynG->iCreateLdobjbyname(graph, getModuleNamespaceInst, funcNameStr);
412 auto callInst = g_dynG->iCreateCallthis0(graph, ldObjByNameInst, getModuleNamespaceInst);
413 g_implG->iInsertBefore(getModuleNamespaceInst, lastInst);
414 g_implG->iInsertBefore(ldObjByNameInst, lastInst);
415 g_implG->iInsertBefore(callInst, lastInst);
416 }
417
TransformIrAddStarExportFunc(AbckitGraph * graph,AbckitFile * file,const std::string & exportName,const std::string & moduleName)418 static void TransformIrAddStarExportFunc(AbckitGraph *graph, AbckitFile *file, const std::string &exportName,
419 const std::string &moduleName)
420 {
421 AbckitBasicBlock *mainBB = g_implG->bbGetSuccBlock(g_implG->gGetStartBasicBlock(graph), 0);
422 AbckitInst *lastInst = g_implG->bbGetLastInst(mainBB);
423
424 helpers::ModuleByNameContext ctxFinder = {nullptr, moduleName.c_str()};
425 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
426 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
427 ASSERT_NE(ctxFinder.module, nullptr);
428
429 helpers::ModuleByNameContext ctxFinder2 = {nullptr, "modules/module4"};
430 g_implI->fileEnumerateModules(file, &ctxFinder2, helpers::ModuleByNameFinder);
431 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
432 ASSERT_NE(ctxFinder2.module, nullptr);
433
434 helpers::ExportByAliasContext exportFinder = {nullptr, exportName.c_str()};
435 g_implI->moduleEnumerateExports(ctxFinder2.module, &exportFinder, helpers::ExportByAliasFinder);
436 ASSERT_NE(exportFinder.ed, nullptr);
437
438 auto getModuleNamespaceInst = g_dynG->iCreateGetmodulenamespace(graph, ctxFinder.module); // module3
439 auto stModuleVarInst = g_dynG->iCreateStmodulevar(graph, getModuleNamespaceInst, exportFinder.ed); // NewStarExport
440 g_implG->iInsertBefore(getModuleNamespaceInst, lastInst);
441 g_implG->iInsertBefore(stModuleVarInst, lastInst);
442 }
443
TransformIrAddStarExportFunc2(AbckitGraph * graph,AbckitFile * file,const std::string & funcName,const std::string & moduleName)444 static void TransformIrAddStarExportFunc2(AbckitGraph *graph, AbckitFile *file, const std::string &funcName,
445 const std::string &moduleName)
446 {
447 AbckitBasicBlock *mainBB = g_implG->bbGetSuccBlock(g_implG->gGetStartBasicBlock(graph), 0);
448 AbckitInst *lastInst = g_implG->bbGetLastInst(mainBB);
449
450 helpers::ModuleByNameContext ctxFinder = {nullptr, moduleName.c_str()};
451 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
452 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
453 ASSERT_NE(ctxFinder.module, nullptr);
454
455 helpers::ImportByAliasContext importFinder = {nullptr, "NewStarExport"};
456 g_implI->moduleEnumerateImports(ctxFinder.module, &importFinder, helpers::ImportByAliasFinder);
457 ASSERT_NE(importFinder.id, nullptr);
458
459 auto ldExternalModuleVarInst = g_dynG->iCreateLdexternalmodulevar(graph, importFinder.id);
460 auto exportStarName = g_implM->createString(file, "NewStarExport", strlen("NewStarExport"));
461 auto throwUndef = g_dynG->iCreateThrowUndefinedifholewithname(graph, ldExternalModuleVarInst, exportStarName);
462 auto funcNameStr = g_implM->createString(file, funcName.c_str(), funcName.size());
463 auto ldObjByNameInst = g_dynG->iCreateLdobjbyname(graph, ldExternalModuleVarInst, funcNameStr);
464 auto callInst = g_dynG->iCreateCallthis0(graph, ldObjByNameInst, ldExternalModuleVarInst);
465 g_implG->iInsertBefore(ldExternalModuleVarInst, lastInst);
466 g_implG->iInsertBefore(throwUndef, lastInst);
467 g_implG->iInsertBefore(ldObjByNameInst, lastInst);
468 g_implG->iInsertBefore(callInst, lastInst);
469 }
470
471 // ========================================
472 // Modules Tests
473 // ========================================
474
475 constexpr auto UNMODIFIED_EXPECTED_OUTPUT =
476 "regular import func1 from module1\nregular import func1 from module2\nregular default import func1 from "
477 "module3\nregular default import func2 from module2\nnamespace import func2 from module1\nnamespace import "
478 "func3 from module1\n1\n2\nnamespace import func3 from module2\nthe same func from module3\n";
479
480 constexpr auto OUTPUT_PATH =
481 ABCKIT_ABC_DIR "ut/extensions/arkts/modify_api/modules/modules_dynamic_modify_modified.abc";
482
483 constexpr auto INPUT_PATH = ABCKIT_ABC_DIR "ut/extensions/arkts/modify_api/modules/modules_dynamic_modify.abc";
484
485 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleRemoveImport, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DynamicModuleRemoveImport)486 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DynamicModuleRemoveImport)
487 {
488 auto output = helpers::ExecuteDynamicAbc(INPUT_PATH, MAIN_MODULE_NAME);
489 auto expected = UNMODIFIED_EXPECTED_OUTPUT;
490 EXPECT_TRUE(helpers::Match(output, expected));
491
492 helpers::TransformMethod(INPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
493 [](AbckitFile *file, AbckitCoreFunction *, AbckitGraph *graph) {
494 TransformIrDynModuleRemoveImport(graph, "regularImportFunc1FromModule1");
495 ModifyMetaDynModuleRemoveImport(file, "regularImportFunc1FromModule1", true);
496 });
497
498 output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
499 expected =
500 "regular import func1 from module2\nregular default import func1 from module3\nregular default import func2 "
501 "from module2\nnamespace import func2 from module1\nnamespace import func3 from module1\n1\n2\nnamespace "
502 "import func3 from module2\nthe same func from module3\n";
503 EXPECT_TRUE(helpers::Match(output, expected));
504 }
505
506 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleRemoveImport, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DynamicModuleRemoveNSImport)507 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DynamicModuleRemoveNSImport)
508 {
509 auto output = helpers::ExecuteDynamicAbc(INPUT_PATH, MAIN_MODULE_NAME);
510 auto expected = UNMODIFIED_EXPECTED_OUTPUT;
511 EXPECT_TRUE(helpers::Match(output, expected));
512
513 helpers::TransformMethod(INPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
514 [](AbckitFile *file, AbckitCoreFunction *, AbckitGraph *graph) {
515 TransformIrDynModuleRemoveNSImport(graph, "namespaceImportFunc2FromModule1");
516 TransformIrDynModuleRemoveNSImport(graph, "namespaceImportFunc3FromModule1");
517 ModifyMetaDynModuleRemoveImport(file, "NS1", true);
518 });
519
520 output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
521 expected =
522 "regular import func1 from module1\nregular import func1 from module2\nregular default import func1 from "
523 "module3\nregular default import func2 from module2\n1\n2\nnamespace import func3 from module2\nthe same func "
524 "from module3\n";
525 EXPECT_TRUE(helpers::Match(output, expected));
526 }
527
528 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleRemoveImport, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DynamicModuleRemoveImportAndModule)529 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DynamicModuleRemoveImportAndModule)
530 {
531 auto output = helpers::ExecuteDynamicAbc(INPUT_PATH, MAIN_MODULE_NAME);
532 auto expected = UNMODIFIED_EXPECTED_OUTPUT;
533 EXPECT_TRUE(helpers::Match(output, expected));
534
535 helpers::TransformMethod(INPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
536 [](AbckitFile *file, AbckitCoreFunction *, AbckitGraph *graph) {
537 TransformIrDynModuleRemoveImport(graph, "regularDefaultImportFunc1FromModule3");
538 ModifyMetaDynModuleRemoveImport(file, "regularDefaultImportFunc1FromModule3", true);
539 });
540
541 output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
542 expected =
543 "regular import func1 from module1\nregular import func1 from module2\nregular default import func2 from "
544 "module2\nnamespace import func2 from module1\nnamespace import func3 from module1\n1\n2\nnamespace import "
545 "func3 from module2\nthe same func from module3\n";
546 EXPECT_TRUE(helpers::Match(output, expected));
547 }
548
549 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleRemoveImport, abc-kind=ArkTS1, category=negative
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DynamicModuleRemoveImportWithWrongName)550 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DynamicModuleRemoveImportWithWrongName)
551 {
552 auto output = helpers::ExecuteDynamicAbc(INPUT_PATH, MAIN_MODULE_NAME);
553 auto expected = UNMODIFIED_EXPECTED_OUTPUT;
554 EXPECT_TRUE(helpers::Match(output, expected));
555
556 helpers::TransformMethod(INPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
557 [](AbckitFile *file, AbckitCoreFunction *, AbckitGraph *) {
558 ModifyMetaDynModuleRemoveImport(file, "R", false);
559 });
560
561 output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
562 expected = UNMODIFIED_EXPECTED_OUTPUT;
563 EXPECT_TRUE(helpers::Match(output, expected));
564 }
565
566 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleRemoveImport, abc-kind=ArkTS1, category=negative
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DynamicModuleRemoveWrongImport)567 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DynamicModuleRemoveWrongImport)
568 {
569 auto output = helpers::ExecuteDynamicAbc(INPUT_PATH, MAIN_MODULE_NAME);
570 auto expected = UNMODIFIED_EXPECTED_OUTPUT;
571 EXPECT_TRUE(helpers::Match(output, expected));
572
573 helpers::TransformMethod(
574 INPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
575 [](AbckitFile *file, AbckitCoreFunction *method, AbckitGraph *) {
576 auto *newID = new AbckitCoreImportDescriptor();
577 auto newAID = std::make_unique<AbckitArktsImportDescriptor>();
578 newAID->core = newID;
579 newID->impl = std::move(newAID);
580 newID->importingModule = method->owningModule;
581 newID->importedModule = method->owningModule; // just to make object newID valid
582 helpers::ModuleByNameContext ctxFinder = {nullptr, MAIN_MODULE_NAME};
583 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
584 EXPECT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
585 EXPECT_NE(ctxFinder.module, nullptr);
586 auto *module = ctxFinder.module;
587 g_implArkM->moduleRemoveImport(g_implArkI->coreModuleToArktsModule(module),
588 g_implArkI->coreImportDescriptorToArktsImportDescriptor(newID));
589 EXPECT_EQ(g_impl->getLastError(), ABCKIT_STATUS_BAD_ARGUMENT);
590 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder); // just to clear last error
591 delete newID;
592 });
593
594 output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
595 expected = UNMODIFIED_EXPECTED_OUTPUT;
596 EXPECT_TRUE(helpers::Match(output, expected));
597 }
598
599 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleRemoveImport, abc-kind=ArkTS1, category=negative, extension=c
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DISABLED_DynamicModuleRemoveImport_WrongTargets)600 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DISABLED_DynamicModuleRemoveImport_WrongTargets)
601 {
602 // Test is disabled
603 // importDescriptorGetAlias has no ArkTS_V2 support, aliases for imports are not implemented
604
605 AbckitFile *file = nullptr;
606 helpers::AssertOpenAbc(INPUT_PATH, &file);
607
608 helpers::ModuleByNameContext ctxFinder = {nullptr, MAIN_MODULE_NAME};
609 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
610 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
611 ASSERT_NE(ctxFinder.module, nullptr);
612 auto *module = ctxFinder.module;
613
614 // Find import from module/module4 in module/module3
615 ctxFinder = {nullptr, "modules/module3"};
616 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
617 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
618 ASSERT_NE(ctxFinder.module, nullptr);
619 auto *module2 = ctxFinder.module;
620 // Set another module target
621 module2->target = ABCKIT_TARGET_ARK_TS_V2;
622
623 std::set<AbckitCoreImportDescriptor *> gotImports;
624 g_implI->moduleEnumerateImports(module2, &gotImports, helpers::ModuleImportsCollector);
625 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
626 ASSERT_EQ(gotImports.empty(), false);
627
628 // Try to remove found import from main module
629 auto importName = "regularImportFunc1FromModule1";
630 for (auto &gotImport : gotImports) {
631 auto impName = g_implI->importDescriptorGetAlias(gotImport);
632 auto strName = helpers::AbckitStringToString(impName);
633 if (strName == importName) {
634 g_implArkM->moduleRemoveImport(g_implArkI->coreModuleToArktsModule(module),
635 g_implArkI->coreImportDescriptorToArktsImportDescriptor(gotImport));
636 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_WRONG_TARGET);
637 break;
638 }
639 }
640
641 g_impl->closeFile(file);
642 }
643
644 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleRemoveExport, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DynamicModuleRemoveExport)645 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DynamicModuleRemoveExport)
646 {
647 auto output = helpers::ExecuteDynamicAbc(INPUT_PATH, MAIN_MODULE_NAME);
648 auto expected = UNMODIFIED_EXPECTED_OUTPUT;
649 EXPECT_TRUE(helpers::Match(output, expected));
650
651 helpers::TransformMethod(INPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
652 [](AbckitFile *file, AbckitCoreFunction *, AbckitGraph *graph) {
653 TransformIrDynModuleRemoveExport(graph, "LocalExportConst");
654 ModifyMetaDynModuleRemoveExport(file, "LocalExportConst", true);
655 });
656
657 output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
658 expected =
659 "regular import func1 from module1\nregular import func1 from module2\nregular default import func1 from "
660 "module3\nregular default import func2 from module2\nnamespace import func2 from module1\nnamespace import "
661 "func3 from module1\n2\nnamespace import func3 from module2\nthe same func from module3\n";
662 EXPECT_TRUE(helpers::Match(output, expected));
663 }
664
665 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleRemoveExport, abc-kind=ArkTS1, category=negative
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DynamicModuleRemoveExportWithWrongName)666 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DynamicModuleRemoveExportWithWrongName)
667 {
668 auto output = helpers::ExecuteDynamicAbc(INPUT_PATH, MAIN_MODULE_NAME);
669 auto expected = UNMODIFIED_EXPECTED_OUTPUT;
670 EXPECT_TRUE(helpers::Match(output, expected));
671
672 helpers::TransformMethod(INPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
673 [](AbckitFile *file, AbckitCoreFunction *, AbckitGraph *) {
674 ModifyMetaDynModuleRemoveExport(file, "R", false);
675 });
676
677 output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
678 expected = UNMODIFIED_EXPECTED_OUTPUT;
679 EXPECT_TRUE(helpers::Match(output, expected));
680 }
681
682 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleRemoveExport, abc-kind=ArkTS1, category=negative
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DynamicModuleRemoveWrongExport)683 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DynamicModuleRemoveWrongExport)
684 {
685 auto output = helpers::ExecuteDynamicAbc(INPUT_PATH, MAIN_MODULE_NAME);
686 auto expected = UNMODIFIED_EXPECTED_OUTPUT;
687 EXPECT_TRUE(helpers::Match(output, expected));
688
689 helpers::TransformMethod(
690 INPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
691 [](AbckitFile *file, AbckitCoreFunction *method, AbckitGraph *) {
692 auto *newED = new AbckitCoreExportDescriptor();
693 auto newAED = std::make_unique<AbckitArktsExportDescriptor>();
694 newAED->core = newED;
695 newED->impl = std::move(newAED);
696 newED->exportingModule = method->owningModule;
697 newED->exportedModule = method->owningModule; // just to make object newED valid
698 helpers::ModuleByNameContext ctxFinder = {nullptr, MAIN_MODULE_NAME};
699 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
700 EXPECT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
701 EXPECT_NE(ctxFinder.module, nullptr);
702 auto *module = ctxFinder.module;
703 g_implArkM->moduleRemoveExport(g_implArkI->coreModuleToArktsModule(module),
704 g_implArkI->coreExportDescriptorToArktsExportDescriptor(newED));
705 EXPECT_EQ(g_impl->getLastError(), ABCKIT_STATUS_BAD_ARGUMENT);
706 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder); // just to clear last error
707 delete newED;
708 });
709
710 output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
711 expected = UNMODIFIED_EXPECTED_OUTPUT;
712 EXPECT_TRUE(helpers::Match(output, expected));
713 }
714
715 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleRemoveExport, abc-kind=ArkTS1, category=negative
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DISABLED_DynamicModuleRemoveExport_WrongTargets)716 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DISABLED_DynamicModuleRemoveExport_WrongTargets)
717 {
718 // Test is disabled
719 // exportDescriptorGetAlias has no ArkTS_V2 support, aliases for exports are not implemented
720
721 AbckitFile *file = nullptr;
722 helpers::AssertOpenAbc(INPUT_PATH, &file);
723
724 helpers::ModuleByNameContext ctxFinder = {nullptr, MAIN_MODULE_NAME};
725 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
726 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
727 ASSERT_NE(ctxFinder.module, nullptr);
728 auto *module = ctxFinder.module;
729
730 // Find export in module/module3
731 ctxFinder = {nullptr, "modules/module3"};
732 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
733 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
734 ASSERT_NE(ctxFinder.module, nullptr);
735 auto *module2 = ctxFinder.module;
736 // Set another module target
737 module2->target = ABCKIT_TARGET_ARK_TS_V2;
738
739 std::set<AbckitCoreExportDescriptor *> gotExports;
740 g_implI->moduleEnumerateExports(module2, &gotExports, helpers::ModuleExportsCollector);
741 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
742 ASSERT_EQ(gotExports.empty(), false);
743
744 auto exportName = "regularDefaultImportFunc1FromModule3";
745 for (auto &gotExport : gotExports) {
746 auto expName = g_implI->exportDescriptorGetAlias(gotExport);
747 auto strName = helpers::AbckitStringToString(expName);
748 if (strName == exportName) {
749 g_implArkM->moduleRemoveExport(g_implArkI->coreModuleToArktsModule(module),
750 g_implArkI->coreExportDescriptorToArktsExportDescriptor(gotExport));
751 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_WRONG_TARGET);
752 break;
753 }
754 }
755
756 g_impl->closeFile(file);
757 }
758
759 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleAddImportFromArktsV1ToArktsV1, abc-kind=ArkTS1,
760 // category=positive
TEST_F(LibAbcKitArkTSModifyApiModulesTest,ModuleAddImportFromDynamicModule_RegularImport)761 TEST_F(LibAbcKitArkTSModifyApiModulesTest, ModuleAddImportFromDynamicModule_RegularImport)
762 {
763 AbckitFile *file = nullptr;
764 helpers::AssertOpenAbc(INPUT_PATH, &file);
765
766 helpers::ModuleByNameContext ctxFinder = {nullptr, MAIN_MODULE_NAME};
767 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
768 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
769 ASSERT_NE(ctxFinder.module, nullptr);
770 auto module = ctxFinder.module;
771 UserTransformerData utd;
772 utd.name = "newImportedFunc";
773 utd.alias = "newImportedFunc";
774 utd.moduleName = "modules/module3";
775 utd.isRegular = true;
776 AddImportFromDynamicModuleImpl(module, &utd);
777 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
778
779 g_impl->writeAbc(file, OUTPUT_PATH, strlen(OUTPUT_PATH));
780 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
781 g_impl->closeFile(file);
782 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
783
784 auto output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
785 auto expected = UNMODIFIED_EXPECTED_OUTPUT;
786 EXPECT_TRUE(helpers::Match(output, expected));
787
788 helpers::TransformMethod(
789 OUTPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
790 [](AbckitFile *, AbckitCoreFunction *method, AbckitGraph *graph) {
791 TransformIrAddImportedFunctionCall(graph, g_implI->functionGetFile(method), "newImportedFunc");
792 },
793 []([[maybe_unused]] AbckitGraph *graph) {});
794
795 output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
796 expected =
797 "regular import func1 from module1\nregular import func1 from module2\nregular default import func1 from "
798 "module3\nregular default import func2 from module2\nnamespace import func2 from module1\nnamespace import "
799 "func3 from module1\n1\n2\nnamespace import func3 from module2\nthe same func from module3\nnew imported func "
800 "from module3\n";
801 EXPECT_TRUE(helpers::Match(output, expected));
802 }
803
804 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleAddImportFromArktsV1ToArktsV1, abc-kind=ArkTS1,
805 // category=positive
TEST_F(LibAbcKitArkTSModifyApiModulesTest,ModuleAddImportFromDynamicModule_RegularImport2)806 TEST_F(LibAbcKitArkTSModifyApiModulesTest, ModuleAddImportFromDynamicModule_RegularImport2)
807 {
808 AbckitFile *file = nullptr;
809 helpers::AssertOpenAbc(INPUT_PATH, &file);
810
811 helpers::ModuleByNameContext ctxFinder = {nullptr, MAIN_MODULE_NAME};
812 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
813 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
814 ASSERT_NE(ctxFinder.module, nullptr);
815 auto module = ctxFinder.module;
816 UserTransformerData utd;
817 utd.name = "newImportedFunc";
818 utd.alias = "NewImportedFuncAlias";
819 utd.moduleName = "modules/module3";
820 utd.isRegular = true;
821 AddImportFromDynamicModuleImpl(module, &utd);
822 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
823
824 g_impl->writeAbc(file, OUTPUT_PATH, strlen(OUTPUT_PATH));
825 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
826 g_impl->closeFile(file);
827 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
828
829 auto output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
830 auto expected = UNMODIFIED_EXPECTED_OUTPUT;
831 EXPECT_TRUE(helpers::Match(output, expected));
832
833 helpers::TransformMethod(
834 OUTPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
835 [](AbckitFile *, AbckitCoreFunction *method, AbckitGraph *graph) {
836 TransformIrAddImportedFunctionCall(graph, g_implI->functionGetFile(method), "NewImportedFuncAlias");
837 },
838 []([[maybe_unused]] AbckitGraph *graph) {});
839
840 output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
841 expected =
842 "regular import func1 from module1\nregular import func1 from module2\nregular default import func1 from "
843 "module3\nregular default import func2 from module2\nnamespace import func2 from module1\nnamespace import "
844 "func3 from module1\n1\n2\nnamespace import func3 from module2\nthe same func from module3\nnew imported func "
845 "from module3\n";
846 EXPECT_TRUE(helpers::Match(output, expected));
847 }
848
849 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleAddImportFromArktsV1ToArktsV1, abc-kind=ArkTS1,
850 // category=positive
TEST_F(LibAbcKitArkTSModifyApiModulesTest,ModuleAddImportFromDynamicModule_RegularImport3)851 TEST_F(LibAbcKitArkTSModifyApiModulesTest, ModuleAddImportFromDynamicModule_RegularImport3)
852 {
853 auto output = helpers::ExecuteDynamicAbc(INPUT_PATH, MAIN_MODULE_NAME);
854 auto expected = UNMODIFIED_EXPECTED_OUTPUT;
855 EXPECT_TRUE(helpers::Match(output, expected));
856 AbckitFile *file = nullptr;
857
858 helpers::AssertOpenAbc(INPUT_PATH, &file);
859
860 helpers::ModuleByNameContext ctxFinder = {nullptr, MAIN_MODULE_NAME};
861 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
862 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
863 ASSERT_NE(ctxFinder.module, nullptr);
864 auto module = ctxFinder.module;
865 UserTransformerData utd;
866 utd.name = "newImportedFuncFromModule4";
867 utd.alias = "NewImportedFuncAlias";
868 utd.moduleName = "modules/module4";
869 utd.isRegular = true;
870 AddImportFromDynamicModuleImpl(module, &utd);
871 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
872
873 g_impl->writeAbc(file, OUTPUT_PATH, strlen(OUTPUT_PATH));
874 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
875 g_impl->closeFile(file);
876 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
877
878 output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
879 expected = UNMODIFIED_EXPECTED_OUTPUT;
880 EXPECT_TRUE(helpers::Match(output, expected));
881
882 helpers::TransformMethod(
883 OUTPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
884 [](AbckitFile *, AbckitCoreFunction *method, AbckitGraph *graph) {
885 TransformIrAddImportedFunctionCall(graph, g_implI->functionGetFile(method), "NewImportedFuncAlias");
886 },
887 []([[maybe_unused]] AbckitGraph *graph) {});
888
889 output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
890 expected =
891 "regular import func1 from module1\nregular import func1 from module2\nregular default import func1 from "
892 "module3\nregular default import func2 from module2\nnamespace import func2 from module1\nnamespace import "
893 "func3 from module1\n1\n2\nnamespace import func3 from module2\nthe same func from module3\nnew imported func "
894 "from module4\n";
895 EXPECT_TRUE(helpers::Match(output, expected));
896 }
897
898 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleAddImportFromArktsV1ToArktsV1, abc-kind=ArkTS1,
899 // category=positive
TEST_F(LibAbcKitArkTSModifyApiModulesTest,ModuleAddImportFromDynamicModule_RegularImport4)900 TEST_F(LibAbcKitArkTSModifyApiModulesTest, ModuleAddImportFromDynamicModule_RegularImport4)
901 {
902 auto output = helpers::ExecuteDynamicAbc(INPUT_PATH, MAIN_MODULE_NAME);
903 auto expected = UNMODIFIED_EXPECTED_OUTPUT;
904 EXPECT_TRUE(helpers::Match(output, expected));
905 AbckitFile *file = nullptr;
906
907 helpers::AssertOpenAbc(INPUT_PATH, &file);
908
909 helpers::ModuleByNameContext ctxFinder = {nullptr, MAIN_MODULE_NAME};
910 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
911 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
912 ASSERT_NE(ctxFinder.module, nullptr);
913 auto module = ctxFinder.module;
914 UserTransformerData utd;
915 utd.name = "default";
916 utd.alias = "newImportedDefaultFuncFromModule4";
917 utd.moduleName = "modules/module4";
918 utd.isRegular = true;
919 AddImportFromDynamicModuleImpl(module, &utd);
920 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
921
922 g_impl->writeAbc(file, OUTPUT_PATH, strlen(OUTPUT_PATH));
923 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
924 g_impl->closeFile(file);
925 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
926
927 output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
928 expected = UNMODIFIED_EXPECTED_OUTPUT;
929 EXPECT_TRUE(helpers::Match(output, expected));
930
931 helpers::TransformMethod(
932 OUTPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
933 [](AbckitFile *, AbckitCoreFunction *method, AbckitGraph *graph) {
934 TransformIrAddImportedFunctionCall(graph, g_implI->functionGetFile(method),
935 "newImportedDefaultFuncFromModule4");
936 },
937 []([[maybe_unused]] AbckitGraph *graph) {});
938
939 output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
940 expected =
941 "regular import func1 from module1\nregular import func1 from module2\nregular default import func1 from "
942 "module3\nregular default import func2 from module2\nnamespace import func2 from module1\nnamespace import "
943 "func3 from module1\n1\n2\nnamespace import func3 from module2\nthe same func from module3\nnew imported "
944 "default func from module4\n";
945 EXPECT_TRUE(helpers::Match(output, expected));
946 }
947
948 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleAddImportFromArktsV1ToArktsV1, abc-kind=ArkTS1,
949 // category=positive
TEST_F(LibAbcKitArkTSModifyApiModulesTest,ModuleAddImportFromDynamicModule_NamespaceImport)950 TEST_F(LibAbcKitArkTSModifyApiModulesTest, ModuleAddImportFromDynamicModule_NamespaceImport)
951 {
952 auto output = helpers::ExecuteDynamicAbc(INPUT_PATH, MAIN_MODULE_NAME);
953 auto expected = UNMODIFIED_EXPECTED_OUTPUT;
954 EXPECT_TRUE(helpers::Match(output, expected));
955 AbckitFile *file = nullptr;
956
957 helpers::AssertOpenAbc(INPUT_PATH, &file);
958
959 helpers::ModuleByNameContext ctxFinder = {nullptr, MAIN_MODULE_NAME};
960 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
961 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
962 ASSERT_NE(ctxFinder.module, nullptr);
963 auto module = ctxFinder.module;
964 UserTransformerData utd;
965 utd.name = "*";
966 utd.alias = "NewImport";
967 utd.moduleName = "modules/module3";
968 utd.isRegular = false;
969 AddImportFromDynamicModuleImpl(module, &utd);
970 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
971
972 g_impl->writeAbc(file, OUTPUT_PATH, strlen(OUTPUT_PATH));
973 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
974 g_impl->closeFile(file);
975 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
976
977 output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
978 expected = UNMODIFIED_EXPECTED_OUTPUT;
979 EXPECT_TRUE(helpers::Match(output, expected));
980
981 helpers::TransformMethod(
982 OUTPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
983 [](AbckitFile *, AbckitCoreFunction *method, AbckitGraph *graph) {
984 TransformIrAddImportedFunctionCallNS(graph, g_implI->functionGetFile(method), "newImportedFunc",
985 "modules/module3");
986 },
987 []([[maybe_unused]] AbckitGraph *graph) {});
988
989 output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
990 expected =
991 "regular import func1 from module1\nregular import func1 from module2\nregular default import func1 from "
992 "module3\nregular default import func2 from module2\nnamespace import func2 from module1\nnamespace import "
993 "func3 from module1\n1\n2\nnamespace import func3 from module2\nthe same func from module3\nnew imported func "
994 "from module3\n";
995 EXPECT_TRUE(helpers::Match(output, expected));
996 }
997
998 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleAddImportFromArktsV1ToArktsV1, abc-kind=ArkTS1,
999 // category=positive
TEST_F(LibAbcKitArkTSModifyApiModulesTest,ModuleAddImportFromDynamicModule_NamespaceImport2)1000 TEST_F(LibAbcKitArkTSModifyApiModulesTest, ModuleAddImportFromDynamicModule_NamespaceImport2)
1001 {
1002 auto output = helpers::ExecuteDynamicAbc(INPUT_PATH, MAIN_MODULE_NAME);
1003 auto expected = UNMODIFIED_EXPECTED_OUTPUT;
1004 EXPECT_TRUE(helpers::Match(output, expected));
1005 AbckitFile *file = nullptr;
1006
1007 helpers::AssertOpenAbc(INPUT_PATH, &file);
1008
1009 helpers::ModuleByNameContext ctxFinder = {nullptr, MAIN_MODULE_NAME};
1010 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
1011 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1012 ASSERT_NE(ctxFinder.module, nullptr);
1013 auto module = ctxFinder.module;
1014 UserTransformerData utd = {"*", "NewImport", "modules/module4", false};
1015 AddImportFromDynamicModuleImpl(module, &utd);
1016 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1017
1018 g_impl->writeAbc(file, OUTPUT_PATH, strlen(OUTPUT_PATH));
1019 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1020 g_impl->closeFile(file);
1021 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1022
1023 output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1024 expected = UNMODIFIED_EXPECTED_OUTPUT;
1025 EXPECT_TRUE(helpers::Match(output, expected));
1026
1027 helpers::TransformMethod(
1028 OUTPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
1029 [](AbckitFile *, AbckitCoreFunction *method, AbckitGraph *graph) {
1030 TransformIrAddImportedFunctionCallNS(graph, g_implI->functionGetFile(method), "newImportedFuncFromModule4",
1031 "modules/module4");
1032 },
1033 []([[maybe_unused]] AbckitGraph *graph) {});
1034
1035 output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1036 expected =
1037 "regular import func1 from module1\nregular import func1 from module2\nregular default import func1 from "
1038 "module3\nregular default import func2 from module2\nnamespace import func2 from module1\nnamespace import "
1039 "func3 from module1\n1\n2\nnamespace import func3 from module2\nthe same func from module3\nnew imported func "
1040 "from module4\n";
1041 EXPECT_TRUE(helpers::Match(output, expected));
1042 }
1043
1044 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleAddImportFromArktsV1ToArktsV1, abc-kind=ArkTS1,
1045 // category=negative
TEST_F(LibAbcKitArkTSModifyApiModulesTest,ModuleAddImportFromDynamicModule_WrongTargets)1046 TEST_F(LibAbcKitArkTSModifyApiModulesTest, ModuleAddImportFromDynamicModule_WrongTargets)
1047 {
1048 AbckitFile *file = nullptr;
1049 helpers::AssertOpenAbc(INPUT_PATH, &file);
1050
1051 helpers::ModuleByNameContext ctxFinder = {nullptr, MAIN_MODULE_NAME};
1052 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
1053 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1054 ASSERT_NE(ctxFinder.module, nullptr);
1055 auto *module = ctxFinder.module;
1056
1057 helpers::ModuleByNameContext ctxFinder2 = {nullptr, "modules/module4"};
1058 g_implI->fileEnumerateModules(file, &ctxFinder2, helpers::ModuleByNameFinder);
1059 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1060 ASSERT_NE(ctxFinder2.module, nullptr);
1061 auto *importedModule = ctxFinder2.module;
1062
1063 AbckitArktsImportFromDynamicModuleCreateParams params {};
1064 params.name = "*";
1065 params.alias = "NewImport";
1066
1067 importedModule->target = ABCKIT_TARGET_ARK_TS_V2;
1068
1069 g_implArkM->moduleAddImportFromArktsV1ToArktsV1(g_implArkI->coreModuleToArktsModule(module),
1070 g_implArkI->coreModuleToArktsModule(importedModule), ¶ms);
1071 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_WRONG_TARGET);
1072
1073 g_impl->closeFile(file);
1074 }
1075
1076 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleAddExportFromArktsV1ToArktsV1, abc-kind=ArkTS1,
1077 // category=positive
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DynamicModuleAddExport_LocalExport)1078 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DynamicModuleAddExport_LocalExport)
1079 {
1080 AbckitFile *file = nullptr;
1081 helpers::AssertOpenAbc(INPUT_PATH, &file);
1082
1083 helpers::ModuleByNameContext ctxFinder = {nullptr, MAIN_MODULE_NAME};
1084 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
1085 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1086 ASSERT_NE(ctxFinder.module, nullptr);
1087 auto module = ctxFinder.module;
1088 UserTransformerData utd;
1089 utd.name = "NewExportedVar";
1090 utd.alias = "NewExportedVar";
1091 utd.kind = AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_LOCAL_EXPORT;
1092 utd.moduleName = MAIN_MODULE_NAME;
1093 DynamicModuleAddExportImpl(module, &utd);
1094 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1095
1096 g_impl->writeAbc(file, OUTPUT_PATH, strlen(OUTPUT_PATH));
1097 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1098 g_impl->closeFile(file);
1099 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1100
1101 auto output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1102 auto expected = UNMODIFIED_EXPECTED_OUTPUT;
1103 EXPECT_TRUE(helpers::Match(output, expected));
1104
1105 helpers::TransformMethod(
1106 OUTPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
1107 [&utd](AbckitFile *, AbckitCoreFunction *method, AbckitGraph *graph) {
1108 TransformIrAddLocalExport(graph, g_implI->functionGetFile(method), utd.alias, MAIN_MODULE_NAME);
1109 },
1110 []([[maybe_unused]] AbckitGraph *graph) {});
1111
1112 output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1113 expected =
1114 "regular import func1 from module1\nregular import func1 from module2\nregular default import func1 from "
1115 "module3\nregular default import func2 from module2\nnamespace import func2 from module1\nnamespace import "
1116 "func3 from module1\n1\n2\nnamespace import func3 from module2\nthe same func from module3\n5\n";
1117 EXPECT_TRUE(helpers::Match(output, expected));
1118 }
1119
1120 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleAddExportFromArktsV1ToArktsV1, abc-kind=ArkTS1,
1121 // category=positive
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DynamicModuleAddExport_LocalExport2)1122 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DynamicModuleAddExport_LocalExport2)
1123 {
1124 AbckitFile *file = nullptr;
1125 helpers::AssertOpenAbc(INPUT_PATH, &file);
1126
1127 helpers::ModuleByNameContext ctxFinder = {nullptr, MAIN_MODULE_NAME};
1128 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
1129 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1130 ASSERT_NE(ctxFinder.module, nullptr);
1131 auto module = ctxFinder.module;
1132 UserTransformerData utd;
1133 utd.name = "NewExportedVar";
1134 utd.alias = "NewExportedVarAlias";
1135 utd.kind = AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_LOCAL_EXPORT;
1136 utd.moduleName = MAIN_MODULE_NAME;
1137 DynamicModuleAddExportImpl(module, &utd);
1138 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1139
1140 g_impl->writeAbc(file, OUTPUT_PATH, strlen(OUTPUT_PATH));
1141 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1142 g_impl->closeFile(file);
1143 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1144
1145 auto output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1146 auto expected = UNMODIFIED_EXPECTED_OUTPUT;
1147 EXPECT_TRUE(helpers::Match(output, expected));
1148
1149 helpers::TransformMethod(
1150 OUTPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
1151 [&utd](AbckitFile *, AbckitCoreFunction *method, AbckitGraph *graph) {
1152 TransformIrAddLocalExport(graph, g_implI->functionGetFile(method), utd.alias, MAIN_MODULE_NAME);
1153 },
1154 []([[maybe_unused]] AbckitGraph *graph) {});
1155
1156 output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1157 expected =
1158 "regular import func1 from module1\nregular import func1 from module2\nregular default import func1 from "
1159 "module3\nregular default import func2 from module2\nnamespace import func2 from module1\nnamespace import "
1160 "func3 from module1\n1\n2\nnamespace import func3 from module2\nthe same func from module3\n5\n";
1161 EXPECT_TRUE(helpers::Match(output, expected));
1162 }
1163
1164 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleAddExportFromArktsV1ToArktsV1, abc-kind=ArkTS1,
1165 // category=positive
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DynamicModuleAddExport_LocalExport3)1166 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DynamicModuleAddExport_LocalExport3)
1167 {
1168 AbckitFile *file = nullptr;
1169 helpers::AssertOpenAbc(INPUT_PATH, &file);
1170
1171 helpers::ModuleByNameContext ctxFinder = {nullptr, MAIN_MODULE_NAME};
1172 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
1173 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1174 ASSERT_NE(ctxFinder.module, nullptr);
1175 auto module = ctxFinder.module;
1176 UserTransformerData utd;
1177 utd.name = "default";
1178 utd.alias = "NewExportedVarDefault";
1179 utd.kind = AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_LOCAL_EXPORT;
1180 utd.moduleName = MAIN_MODULE_NAME;
1181 DynamicModuleAddExportImpl(module, &utd);
1182 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1183
1184 g_impl->writeAbc(file, OUTPUT_PATH, strlen(OUTPUT_PATH));
1185 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1186 g_impl->closeFile(file);
1187 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1188
1189 auto output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1190 auto expected = UNMODIFIED_EXPECTED_OUTPUT;
1191 EXPECT_TRUE(helpers::Match(output, expected));
1192
1193 helpers::TransformMethod(
1194 OUTPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
1195 [&utd](AbckitFile *, AbckitCoreFunction *method, AbckitGraph *graph) {
1196 TransformIrAddLocalExport(graph, g_implI->functionGetFile(method), utd.alias, MAIN_MODULE_NAME);
1197 },
1198 []([[maybe_unused]] AbckitGraph *graph) {});
1199
1200 output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1201 expected =
1202 "regular import func1 from module1\nregular import func1 from module2\nregular default import func1 from "
1203 "module3\nregular default import func2 from module2\nnamespace import func2 from module1\nnamespace import "
1204 "func3 from module1\n1\n2\nnamespace import func3 from module2\nthe same func from module3\n5\n";
1205 EXPECT_TRUE(helpers::Match(output, expected));
1206 }
1207
1208 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleAddExportFromArktsV1ToArktsV1, abc-kind=ArkTS1,
1209 // category=positive
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DynamicModuleAddExport_IndirectExport)1210 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DynamicModuleAddExport_IndirectExport)
1211 {
1212 AbckitFile *file = nullptr;
1213 helpers::AssertOpenAbc(INPUT_PATH, &file);
1214
1215 helpers::ModuleByNameContext ctxFinder = {nullptr, "modules/module2"};
1216 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
1217 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1218 ASSERT_NE(ctxFinder.module, nullptr);
1219 auto module = ctxFinder.module;
1220 UserTransformerData utd;
1221 utd.name = "NewLocalExportLet";
1222 utd.alias = "NewLocalExportLet";
1223 utd.moduleName = "modules/module1";
1224 utd.kind = AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_INDIRECT_EXPORT;
1225 DynamicModuleAddExportImpl(module, &utd);
1226 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1227
1228 UserTransformerData utd2;
1229 utd2.name = utd.name;
1230 utd2.alias = utd.alias;
1231 utd2.moduleName = "modules/module2";
1232 utd2.isRegular = true;
1233 ctxFinder = {nullptr, MAIN_MODULE_NAME};
1234 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
1235 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1236 ASSERT_NE(ctxFinder.module, nullptr);
1237 AddImportFromDynamicModuleImpl(ctxFinder.module, &utd2);
1238 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1239
1240 g_impl->writeAbc(file, OUTPUT_PATH, strlen(OUTPUT_PATH));
1241 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1242 g_impl->closeFile(file);
1243 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1244
1245 auto output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1246 auto expected = UNMODIFIED_EXPECTED_OUTPUT;
1247 EXPECT_TRUE(helpers::Match(output, expected));
1248
1249 helpers::TransformMethod(
1250 OUTPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
1251 [&utd2](AbckitFile *, AbckitCoreFunction *method, AbckitGraph *graph) {
1252 TransformIrAddIndirectExport(graph, g_implI->functionGetFile(method), utd2.alias, MAIN_MODULE_NAME);
1253 },
1254 []([[maybe_unused]] AbckitGraph *graph) {});
1255
1256 output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1257 expected =
1258 "regular import func1 from module1\nregular import func1 from module2\nregular default import func1 from "
1259 "module3\nregular default import func2 from module2\nnamespace import func2 from module1\nnamespace import "
1260 "func3 from module1\n1\n2\nnamespace import func3 from module2\nthe same func from module3\n3\n";
1261 EXPECT_TRUE(helpers::Match(output, expected));
1262 }
1263
1264 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleAddExportFromArktsV1ToArktsV1, abc-kind=ArkTS1,
1265 // category=positive
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DynamicModuleAddExport_IndirectExport2)1266 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DynamicModuleAddExport_IndirectExport2)
1267 {
1268 AbckitFile *file = nullptr;
1269 helpers::AssertOpenAbc(INPUT_PATH, &file);
1270
1271 helpers::ModuleByNameContext ctxFinder = {nullptr, "modules/module2"};
1272 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
1273 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1274 ASSERT_NE(ctxFinder.module, nullptr);
1275 auto module = ctxFinder.module;
1276 UserTransformerData utd;
1277 utd.name = "NewLocalExportVar";
1278 utd.alias = "NewLocalExportVarAlias";
1279 utd.moduleName = "modules/module4";
1280 utd.kind = AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_INDIRECT_EXPORT;
1281 DynamicModuleAddExportImpl(module, &utd);
1282 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1283
1284 UserTransformerData utd2 = {utd.alias, "NewLocalExportVarFromModule4", "modules/module2", true};
1285 ctxFinder = {nullptr, MAIN_MODULE_NAME};
1286 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
1287 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1288 ASSERT_NE(ctxFinder.module, nullptr);
1289 AddImportFromDynamicModuleImpl(ctxFinder.module, &utd2);
1290 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1291
1292 g_impl->writeAbc(file, OUTPUT_PATH, strlen(OUTPUT_PATH));
1293 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1294 g_impl->closeFile(file);
1295 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1296
1297 auto output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1298 auto expected = UNMODIFIED_EXPECTED_OUTPUT;
1299 EXPECT_TRUE(helpers::Match(output, expected));
1300
1301 helpers::TransformMethod(
1302 OUTPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
1303 [&utd2](AbckitFile *, AbckitCoreFunction *method, AbckitGraph *graph) {
1304 TransformIrAddIndirectExport(graph, g_implI->functionGetFile(method), utd2.alias, MAIN_MODULE_NAME);
1305 },
1306 []([[maybe_unused]] AbckitGraph *graph) {});
1307
1308 output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1309 expected =
1310 "regular import func1 from module1\nregular import func1 from module2\nregular default import func1 from "
1311 "module3\nregular default import func2 from module2\nnamespace import func2 from module1\nnamespace import "
1312 "func3 from module1\n1\n2\nnamespace import func3 from module2\nthe same func from module3\n6\n";
1313 EXPECT_TRUE(helpers::Match(output, expected));
1314 }
1315
1316 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleAddExportFromArktsV1ToArktsV1, abc-kind=ArkTS1,
1317 // category=positive
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DynamicModuleAddExport_StarExport)1318 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DynamicModuleAddExport_StarExport)
1319 {
1320 AbckitFile *file = nullptr;
1321 helpers::AssertOpenAbc(INPUT_PATH, &file);
1322
1323 helpers::ModuleByNameContext ctxFinder = {nullptr, "modules/module4"};
1324 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
1325 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1326 ASSERT_NE(ctxFinder.module, nullptr);
1327 auto module = ctxFinder.module;
1328 UserTransformerData utd = {"*", "", "modules/module3", false,
1329 AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_STAR_EXPORT};
1330 DynamicModuleAddExportImpl(module, &utd);
1331 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1332
1333 ctxFinder = {nullptr, MAIN_MODULE_NAME};
1334 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
1335 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1336 ASSERT_NE(ctxFinder.module, nullptr);
1337 module = ctxFinder.module;
1338 UserTransformerData utd2 = {"*", "NS4", "modules/module4", false};
1339 AddImportFromDynamicModuleImpl(module, &utd2);
1340 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1341
1342 g_impl->writeAbc(file, OUTPUT_PATH, strlen(OUTPUT_PATH));
1343 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1344 g_impl->closeFile(file);
1345 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1346
1347 auto output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1348 auto expected = UNMODIFIED_EXPECTED_OUTPUT;
1349 EXPECT_TRUE(helpers::Match(output, expected));
1350
1351 helpers::TransformMethod(
1352 OUTPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
1353 [&utd2](AbckitFile *, AbckitCoreFunction *method, AbckitGraph *graph) {
1354 TransformIrAddStarExport(graph, g_implI->functionGetFile(method), "newExportedFunc", utd2.moduleName);
1355 },
1356 []([[maybe_unused]] AbckitGraph *graph) {});
1357
1358 output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1359 expected =
1360 "regular import func1 from module1\nregular import func1 from module2\nregular default import func1 from "
1361 "module3\nregular default import func2 from module2\nnamespace import func2 from module1\nnamespace import "
1362 "func3 from module1\n1\n2\nnamespace import func3 from module2\nthe same func from module3\nnew exported func "
1363 "from module3\n";
1364 EXPECT_TRUE(helpers::Match(output, expected));
1365 }
1366
1367 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleAddExportFromArktsV1ToArktsV1, abc-kind=ArkTS1,
1368 // category=positive
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DynamicModuleAddExport_StarExport2)1369 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DynamicModuleAddExport_StarExport2)
1370 {
1371 AbckitFile *file = nullptr;
1372 helpers::AssertOpenAbc(INPUT_PATH, &file);
1373
1374 helpers::ModuleByNameContext ctxFinder = {nullptr, "modules/module3"};
1375 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
1376 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1377 ASSERT_NE(ctxFinder.module, nullptr);
1378 auto module = ctxFinder.module;
1379 UserTransformerData utd;
1380 utd.name = "*";
1381 utd.moduleName = "modules/module4";
1382 utd.kind = AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_STAR_EXPORT;
1383 DynamicModuleAddExportImpl(module, &utd);
1384 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1385
1386 g_impl->writeAbc(file, OUTPUT_PATH, strlen(OUTPUT_PATH));
1387 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1388 g_impl->closeFile(file);
1389 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1390
1391 auto output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1392 auto expected = UNMODIFIED_EXPECTED_OUTPUT;
1393 EXPECT_TRUE(helpers::Match(output, expected));
1394
1395 helpers::TransformMethod(
1396 OUTPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
1397 [](AbckitFile *, AbckitCoreFunction *method, AbckitGraph *graph) {
1398 TransformIrAddStarExport(graph, g_implI->functionGetFile(method), "newExportedFuncFromModule4",
1399 "modules/module3");
1400 },
1401 []([[maybe_unused]] AbckitGraph *graph) {});
1402
1403 output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1404 expected =
1405 "regular import func1 from module1\nregular import func1 from module2\nregular default import func1 from "
1406 "module3\nregular default import func2 from module2\nnamespace import func2 from module1\nnamespace import "
1407 "func3 from module1\n1\n2\nnamespace import func3 from module2\nthe same func from module3\nnew exported func "
1408 "from module4\n";
1409 EXPECT_TRUE(helpers::Match(output, expected));
1410 }
1411
1412 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleAddExportFromArktsV1ToArktsV1, abc-kind=ArkTS1,
1413 // category=positive
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DynamicModuleAddExport_StarExport3)1414 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DynamicModuleAddExport_StarExport3)
1415 {
1416 AbckitFile *file = nullptr;
1417 helpers::AssertOpenAbc(INPUT_PATH, &file);
1418
1419 helpers::ModuleByNameContext ctxFinder = {nullptr, "modules/module4"};
1420 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
1421 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1422 ASSERT_NE(ctxFinder.module, nullptr);
1423 UserTransformerData utd = {"*", "NewStarExport", "modules/module3", false,
1424 AbckitDynamicExportKind::ABCKIT_DYNAMIC_EXPORT_KIND_STAR_EXPORT};
1425 DynamicModuleAddExportImpl(ctxFinder.module, &utd);
1426 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1427
1428 ctxFinder = {nullptr, MAIN_MODULE_NAME};
1429 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
1430 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1431 ASSERT_NE(ctxFinder.module, nullptr);
1432 UserTransformerData utd2 = {"NewStarExport", "NewStarExport", "modules/module4", true};
1433 AddImportFromDynamicModuleImpl(ctxFinder.module, &utd2);
1434 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1435
1436 g_impl->writeAbc(file, OUTPUT_PATH, strlen(OUTPUT_PATH));
1437 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1438 g_impl->closeFile(file);
1439 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1440
1441 auto output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1442 auto expected = UNMODIFIED_EXPECTED_OUTPUT;
1443 EXPECT_TRUE(helpers::Match(output, expected));
1444
1445 helpers::TransformMethod(
1446 OUTPUT_PATH, OUTPUT_PATH, "modules/module4.func_main_0",
1447 [&utd2, &utd](AbckitFile *, AbckitCoreFunction *method, AbckitGraph *graph) {
1448 TransformIrAddStarExportFunc(graph, g_implI->functionGetFile(method), utd2.alias, utd.moduleName);
1449 },
1450 []([[maybe_unused]] AbckitGraph *graph) {});
1451
1452 helpers::TransformMethod(
1453 OUTPUT_PATH, OUTPUT_PATH, "modules_dynamic_modify.func_main_0",
1454 [](AbckitFile *, AbckitCoreFunction *method, AbckitGraph *graph) {
1455 TransformIrAddStarExportFunc2(graph, g_implI->functionGetFile(method), "newExportedFunc", MAIN_MODULE_NAME);
1456 },
1457 []([[maybe_unused]] AbckitGraph *graph) {});
1458
1459 output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1460 expected =
1461 "regular import func1 from module1\nregular import func1 from module2\nregular default import func1 from "
1462 "module3\nregular default import func2 from module2\nnamespace import func2 from module1\nnamespace import "
1463 "func3 from module1\n1\n2\nnamespace import func3 from module2\nthe same func from module3\nnew exported func "
1464 "from module3\n";
1465 EXPECT_TRUE(helpers::Match(output, expected));
1466 }
1467
1468 // Test: test-kind=api, api=ArktsModifyApiImpl::moduleAddExportFromArktsV1ToArktsV1, abc-kind=ArkTS1,
1469 // category=negative, extension=c
TEST_F(LibAbcKitArkTSModifyApiModulesTest,DynamicModuleAddExport_WrongTargets)1470 TEST_F(LibAbcKitArkTSModifyApiModulesTest, DynamicModuleAddExport_WrongTargets)
1471 {
1472 AbckitFile *file = nullptr;
1473 helpers::AssertOpenAbc(INPUT_PATH, &file);
1474
1475 helpers::ModuleByNameContext ctxFinder = {nullptr, "modules/module2"};
1476 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
1477 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1478 ASSERT_NE(ctxFinder.module, nullptr);
1479 auto *module = ctxFinder.module;
1480
1481 helpers::ModuleByNameContext ctxFinder2 = {nullptr, "modules/module1"};
1482 g_implI->fileEnumerateModules(file, &ctxFinder2, helpers::ModuleByNameFinder);
1483 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1484 ASSERT_NE(ctxFinder2.module, nullptr);
1485 auto *exportedModule = ctxFinder2.module;
1486
1487 AbckitArktsDynamicModuleExportCreateParams params {};
1488 params.name = "NewLocalExportLet";
1489 params.alias = "NewLocalExportLet";
1490
1491 exportedModule->target = ABCKIT_TARGET_ARK_TS_V2;
1492
1493 g_implArkM->moduleAddExportFromArktsV1ToArktsV1(g_implArkI->coreModuleToArktsModule(module),
1494 g_implArkI->coreModuleToArktsModule(exportedModule), ¶ms);
1495 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_WRONG_TARGET);
1496
1497 g_impl->closeFile(file);
1498 }
1499
1500 // Test: test-kind=api, api=ArktsModifyApiImpl::fileAddExternalModuleArktsV1, abc-kind=ArkTS1, category=positive,
1501 // extension=c
TEST_F(LibAbcKitArkTSModifyApiModulesTest,fileAddExternalModuleArktsV1)1502 TEST_F(LibAbcKitArkTSModifyApiModulesTest, fileAddExternalModuleArktsV1)
1503 {
1504 AbckitFile *file = nullptr;
1505 helpers::AssertOpenAbc(INPUT_PATH, &file);
1506
1507 AbckitArktsV1ExternalModuleCreateParams params {};
1508 params.name = "ExternalModule";
1509 AbckitArktsModule *arkTsModule = g_implArkM->fileAddExternalModuleArktsV1(file, ¶ms);
1510 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1511 ASSERT_NE(arkTsModule, nullptr);
1512
1513 AbckitCoreModule *coreModule = g_implArkI->arktsModuleToCoreModule(arkTsModule);
1514 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1515 ASSERT_NE(coreModule, nullptr);
1516
1517 helpers::ModuleByNameContext ctxFinder = {nullptr, params.name};
1518 g_implI->fileEnumerateModules(file, &ctxFinder, helpers::ModuleByNameFinder);
1519 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1520 ASSERT_NE(ctxFinder.module, nullptr);
1521 ASSERT_EQ(g_implI->moduleIsExternal(ctxFinder.module), true);
1522
1523 g_impl->writeAbc(file, OUTPUT_PATH, strlen(OUTPUT_PATH));
1524 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1525 g_impl->closeFile(file);
1526 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
1527
1528 auto output = helpers::ExecuteDynamicAbc(OUTPUT_PATH, MAIN_MODULE_NAME);
1529 auto expected = UNMODIFIED_EXPECTED_OUTPUT;
1530 EXPECT_TRUE(helpers::Match(output, expected));
1531 }
1532
1533 } // namespace libabckit::test
1534