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 <cassert>
17 #include <cstring>
18 #include <gtest/gtest.h>
19
20 #include "libabckit/include/c/abckit.h"
21 #include "helpers/helpers.h"
22 #include "libabckit/include/c/metadata_core.h"
23 #include "libabckit/include/c/extensions/arkts/metadata_arkts.h"
24 #include "helpers/visit_helper/visit_helper-inl.h"
25
26 namespace libabckit::test {
27
28 static auto g_impl = AbckitGetApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
29 static auto g_implI = AbckitGetInspectApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
30 static auto g_implG = AbckitGetGraphApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
31 static auto g_implArktsI = AbckitGetArktsInspectApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
32
33 class LibAbcKitInspectApiMethodsTest : public ::testing::Test {};
34
35 // ========================================
36 // Helpers
37 // ========================================
38
MethodGetModuleTest(AbckitFile * file,const char * methodName)39 static std::string_view MethodGetModuleTest(AbckitFile *file, const char *methodName)
40 {
41 auto *method = helpers::FindMethodByName(file, methodName);
42 auto *sourceRaw = g_implI->moduleGetName(g_implI->functionGetModule(method));
43 return helpers::AbckitStringToString(sourceRaw);
44 }
45
46 // ========================================
47 // Methods Tests
48 // ========================================
49
50 // Test: test-kind=api, api=InspectApiImpl::functionGetName, abc-kind=ArkTS2, category=positive, extension=c
TEST_F(LibAbcKitInspectApiMethodsTest,StaticMethodGetName)51 TEST_F(LibAbcKitInspectApiMethodsTest, StaticMethodGetName)
52 {
53 AbckitFile *file = nullptr;
54 helpers::AssertOpenAbc(ABCKIT_ABC_DIR "ut/metadata_core/inspect_api/methods/methods_static.abc", &file);
55
56 std::set<std::string> names = {
57 "m0F0:void;",
58 "m0F1:void;",
59 "m0F2$asyncimpl:std.core.Object;",
60 "m0F2:std.core.Promise;",
61 "m0N0F0:void;",
62 "m0N0F1:void;",
63 "m0N0F2$asyncimpl:std.core.Object;",
64 "m0N0F2:std.core.Promise;",
65 "m0N0N0F0:void;",
66 "_cctor_:void;",
67 "lambda$invoke$0:void;",
68 "lambda$invoke$1:void;",
69 "M0C0F0:methods_static.M0C0;void;",
70 "M0C0F1:void;",
71 "M0C0F2$asyncimpl:methods_static.M0C0;std.core.Object;",
72 "M0C0F2:methods_static.M0C0;std.core.Promise;",
73 "_ctor_:methods_static.M0C0;void;",
74 "M0N0C0F0:methods_static.M0N0C0;void;",
75 "M0N0C0F1:void;",
76 "M0N0C0F2$asyncimpl:methods_static.M0N0C0;std.core.Object;",
77 "M0N0C0F2:methods_static.M0N0C0;std.core.Promise;",
78 "_ctor_:methods_static.M0N0C0;void;",
79 };
80
81 helpers::EnumerateAllMethods(file, [&](AbckitCoreFunction *m) {
82 auto *abckitname = g_implI->functionGetName(m);
83 EXPECT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
84 EXPECT_NE(abckitname, nullptr);
85 auto name = helpers::AbckitStringToString(abckitname);
86 EXPECT_EQ(names.count(name.data()), 1);
87 names.erase(name.data());
88 });
89 ASSERT_TRUE(names.empty());
90
91 g_impl->closeFile(file);
92 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
93 }
94
95 // Test: test-kind=api, api=InspectApiImpl::functionGetName, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitInspectApiMethodsTest,DynamicFunctionGetName)96 TEST_F(LibAbcKitInspectApiMethodsTest, DynamicFunctionGetName)
97 {
98 AbckitFile *file = nullptr;
99 helpers::AssertOpenAbc(ABCKIT_ABC_DIR "ut/metadata_core/inspect_api/methods/methods_dynamic.abc", &file);
100
101 std::set<std::string> names = {
102 "M0C0",
103 "M0C0F1",
104 "M0C0F0",
105 "M0C0F2",
106 "M0N0C0",
107 "M0N0C0F1",
108 "M0N0C0F0",
109 "M0N0C0F2",
110 "m0N0N0F0",
111 "m0N0F0",
112 "m0N0F1",
113 "m0N0F2",
114 "m0F0",
115 "methods_dynamic.#*@0*#m0F0F0",
116 "m0F1",
117 "m0F2",
118 "methods_dynamic.#*@0*#",
119 "methods_dynamic.#*@0*#^1",
120 "func_main_0",
121 };
122
123 helpers::EnumerateAllMethods(file, [&](AbckitCoreFunction *m) {
124 auto *abckitname = g_implI->functionGetName(m);
125 EXPECT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
126 EXPECT_NE(abckitname, nullptr);
127 auto name = helpers::AbckitStringToString(abckitname);
128 EXPECT_EQ(names.count(name.data()), 1);
129 names.erase(name.data());
130 });
131 ASSERT_TRUE(names.empty());
132
133 g_impl->closeFile(file);
134 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
135 }
136
137 // Test: test-kind=api, api=InspectApiImpl::functionGetFile, abc-kind=ArkTS2, category=positive, extension=c
TEST_F(LibAbcKitInspectApiMethodsTest,FunctionGetFile)138 TEST_F(LibAbcKitInspectApiMethodsTest, FunctionGetFile)
139 {
140 AbckitFile *file = nullptr;
141 helpers::AssertOpenAbc(ABCKIT_ABC_DIR "ut/metadata_core/inspect_api/methods/methods_static.abc", &file);
142
143 g_implI->fileEnumerateModules(file, nullptr, [](AbckitCoreModule *m, [[maybe_unused]] void *data) -> bool {
144 helpers::ClassByNameContext ctxClassFinder = {nullptr, "M0C0"};
145 g_implI->moduleEnumerateClasses(m, &ctxClassFinder, helpers::ClassByNameFinder);
146 EXPECT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
147 EXPECT_NE(ctxClassFinder.klass, nullptr);
148
149 helpers::MethodByNameContext ctxMethodFinder = {nullptr, "M0C0F0"};
150 g_implI->classEnumerateMethods(ctxClassFinder.klass, &ctxMethodFinder, helpers::MethodByNameFinder);
151 EXPECT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
152 EXPECT_NE(ctxMethodFinder.method, nullptr);
153
154 auto *ctxClass = g_implI->classGetFile(ctxClassFinder.klass);
155 auto *ctxMethod = g_implI->functionGetFile(ctxMethodFinder.method);
156 EXPECT_EQ(ctxClass, ctxMethod);
157
158 return true;
159 });
160
161 g_impl->closeFile(file);
162 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
163 }
164
165 // Test: test-kind=api, api=InspectApiImpl::functionGetFile, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitInspectApiMethodsTest,DynamicFunctionGetFile)166 TEST_F(LibAbcKitInspectApiMethodsTest, DynamicFunctionGetFile)
167 {
168 AbckitFile *file = nullptr;
169 helpers::AssertOpenAbc(ABCKIT_ABC_DIR "ut/metadata_core/inspect_api/methods/methods_dynamic.abc", &file);
170
171 g_implI->fileEnumerateModules(file, nullptr, [](AbckitCoreModule *m, [[maybe_unused]] void *data) -> bool {
172 helpers::ClassByNameContext ctxClassFinder = {nullptr, "M0C0"};
173 g_implI->moduleEnumerateClasses(m, &ctxClassFinder, helpers::ClassByNameFinder);
174 EXPECT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
175 EXPECT_NE(ctxClassFinder.klass, nullptr);
176
177 helpers::MethodByNameContext ctxMethodFinder = {nullptr, "M0C0F0"};
178 g_implI->classEnumerateMethods(ctxClassFinder.klass, &ctxMethodFinder, helpers::MethodByNameFinder);
179 EXPECT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
180 EXPECT_NE(ctxMethodFinder.method, nullptr);
181
182 auto *ctxClass = g_implI->classGetFile(ctxClassFinder.klass);
183 auto *ctxMethod = g_implI->functionGetFile(ctxMethodFinder.method);
184 EXPECT_EQ(ctxClass, ctxMethod);
185
186 return true;
187 });
188
189 g_impl->closeFile(file);
190 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
191 }
192
193 // Test: test-kind=api, api=InspectApiImpl::functionIsCtor, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitInspectApiMethodsTest,DynamicFunctionIsCtor)194 TEST_F(LibAbcKitInspectApiMethodsTest, DynamicFunctionIsCtor)
195 {
196 AbckitFile *file = nullptr;
197 helpers::AssertOpenAbc(ABCKIT_ABC_DIR "ut/metadata_core/inspect_api/methods/methods_dynamic.abc", &file);
198
199 std::set<std::string> ctorMethods = {
200 "M0C0",
201 "M0N0C0",
202 };
203
204 helpers::EnumerateAllMethods(file, [&ctorMethods](AbckitCoreFunction *method) {
205 auto methodName = helpers::AbckitStringToString(g_implI->functionGetName(method));
206 bool isCtor = g_implI->functionIsCtor(method);
207 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
208 if (isCtor) {
209 EXPECT_EQ(ctorMethods.count(methodName.data()), 1);
210 ctorMethods.erase(methodName.data());
211 } else {
212 EXPECT_EQ(ctorMethods.count(methodName.data()), 0);
213 }
214 });
215 ASSERT_TRUE(ctorMethods.empty());
216
217 g_impl->closeFile(file);
218 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
219 }
220
221 // Test: test-kind=api, api=InspectApiImpl::functionIsCtor, abc-kind=ArkTS2, category=positive, extension=c
TEST_F(LibAbcKitInspectApiMethodsTest,StaticFunctionIsCtor)222 TEST_F(LibAbcKitInspectApiMethodsTest, StaticFunctionIsCtor)
223 {
224 AbckitFile *file = nullptr;
225 helpers::AssertOpenAbc(ABCKIT_ABC_DIR "ut/metadata_core/inspect_api/methods/methods_static.abc", &file);
226
227 std::set<std::string> ctorMethods = {"_ctor_:methods_static.M0C0;void;", "_ctor_:methods_static.M0N0C0;void;"};
228
229 helpers::EnumerateAllMethods(file, [&ctorMethods](AbckitCoreFunction *method) {
230 auto methodName = helpers::AbckitStringToString(g_implI->functionGetName(method));
231 bool isCtor = g_implI->functionIsCtor(method);
232 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
233 if (isCtor) {
234 EXPECT_EQ(ctorMethods.count(methodName.data()), 1);
235 ctorMethods.erase(methodName.data());
236 } else {
237 EXPECT_EQ(ctorMethods.count(methodName.data()), 0);
238 }
239 });
240 ASSERT_TRUE(ctorMethods.empty());
241
242 g_impl->closeFile(file);
243 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
244 }
245
246 // Test: test-kind=api, api=InspectApiImpl::functionIsStatic, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitInspectApiMethodsTest,DynamicFunctionIsStatic)247 TEST_F(LibAbcKitInspectApiMethodsTest, DynamicFunctionIsStatic)
248 {
249 AbckitFile *file = nullptr;
250 helpers::AssertOpenAbc(ABCKIT_ABC_DIR "ut/metadata_core/inspect_api/methods/methods_dynamic.abc", &file);
251
252 std::set<std::string> staticMethods = {
253 "M0C0F1",
254 "M0N0C0F1",
255 "m0N0N0F0",
256 "m0N0F0",
257 "m0N0F1",
258 "m0N0F2",
259 "m0F0",
260 "methods_dynamic.#*@0*#m0F0F0",
261 "m0F1",
262 "m0F2",
263 "methods_dynamic.#*@0*#",
264 "methods_dynamic.#*@0*#^1",
265 "func_main_0",
266 };
267
268 helpers::EnumerateAllMethods(file, [&staticMethods](AbckitCoreFunction *method) {
269 auto methodName = helpers::AbckitStringToString(g_implI->functionGetName(method));
270 bool isStatic = g_implI->functionIsStatic(method);
271 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
272 if (isStatic) {
273 EXPECT_EQ(staticMethods.count(methodName.data()), 1);
274 staticMethods.erase(methodName.data());
275 } else {
276 EXPECT_EQ(staticMethods.count(methodName.data()), 0);
277 }
278 });
279 ASSERT_TRUE(staticMethods.empty());
280
281 g_impl->closeFile(file);
282 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
283 }
284
285 // Test: test-kind=api, api=InspectApiImpl::functionIsStatic, abc-kind=ArkTS2, category=positive, extension=c
TEST_F(LibAbcKitInspectApiMethodsTest,StaticFunctionIsStatic)286 TEST_F(LibAbcKitInspectApiMethodsTest, StaticFunctionIsStatic)
287 {
288 AbckitFile *file = nullptr;
289 helpers::AssertOpenAbc(ABCKIT_ABC_DIR "ut/metadata_core/inspect_api/methods/methods_static.abc", &file);
290
291 std::set<std::string> staticMethods = {
292 "M0N0C0F1:void;",
293 "M0C0F1:void;",
294 "m0F0:void;",
295 "m0F1:void;",
296 "m0F2$asyncimpl:std.core.Object;",
297 "m0F2:std.core.Promise;",
298 "m0N0F0:void;",
299 "m0N0F1:void;",
300 "m0N0F2$asyncimpl:std.core.Object;",
301 "m0N0F2:std.core.Promise;",
302 "m0N0N0F0:void;",
303 "_cctor_:void;",
304 "lambda$invoke$0:void;",
305 "lambda$invoke$1:void;",
306 };
307
308 helpers::EnumerateAllMethods(file, [&staticMethods](AbckitCoreFunction *method) {
309 auto methodName = helpers::AbckitStringToString(g_implI->functionGetName(method));
310 bool isStatic = g_implI->functionIsStatic(method);
311 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
312 if (isStatic) {
313 EXPECT_EQ(staticMethods.count(methodName.data()), 1);
314 staticMethods.erase(methodName.data());
315 } else {
316 EXPECT_EQ(staticMethods.count(methodName.data()), 0);
317 }
318 });
319 ASSERT_TRUE(staticMethods.empty());
320
321 g_impl->closeFile(file);
322 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
323 }
324
325 // Test: test-kind=api, api=InspectApiImpl::functionIsAnonymous, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitInspectApiMethodsTest,DynamicFunctionIsAnonymous)326 TEST_F(LibAbcKitInspectApiMethodsTest, DynamicFunctionIsAnonymous)
327 {
328 AbckitFile *file = nullptr;
329 helpers::AssertOpenAbc(ABCKIT_ABC_DIR "ut/metadata_core/inspect_api/methods/methods_dynamic.abc", &file);
330
331 std::set<std::string> anonymousMethods = {
332 "methods_dynamic.#*@0*#",
333 "methods_dynamic.#*@0*#^1",
334 "methods_dynamic.#*@0*#m0F0F0",
335 };
336
337 helpers::EnumerateAllMethods(file, [&anonymousMethods](AbckitCoreFunction *method) {
338 auto methodName = helpers::AbckitStringToString(g_implI->functionGetName(method));
339 bool isAnonymous = g_implI->functionIsAnonymous(method);
340 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
341 if (isAnonymous) {
342 EXPECT_EQ(anonymousMethods.count(methodName.data()), 1);
343 anonymousMethods.erase(methodName.data());
344 } else {
345 EXPECT_EQ(anonymousMethods.count(methodName.data()), 0);
346 }
347 });
348 ASSERT_TRUE(anonymousMethods.empty());
349
350 g_impl->closeFile(file);
351 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
352 }
353
354 // Test: test-kind=api, api=InspectApiImpl::functionIsAnonymous, abc-kind=ArkTS2, category=positive, extension=c
TEST_F(LibAbcKitInspectApiMethodsTest,StaticFunctionIsAnonymous)355 TEST_F(LibAbcKitInspectApiMethodsTest, StaticFunctionIsAnonymous)
356 {
357 AbckitFile *file = nullptr;
358 helpers::AssertOpenAbc(ABCKIT_ABC_DIR "ut/metadata_core/inspect_api/methods/methods_static.abc", &file);
359
360 std::set<std::string> anonymousMethods = {
361 "lambda$invoke$0:void;",
362 "lambda$invoke$1:void;",
363 };
364
365 helpers::EnumerateAllMethods(file, [&anonymousMethods](AbckitCoreFunction *method) {
366 auto methodName = helpers::AbckitStringToString(g_implI->functionGetName(method));
367 bool isAnonymous = g_implI->functionIsAnonymous(method);
368 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
369 if (isAnonymous) {
370 EXPECT_EQ(anonymousMethods.count(methodName.data()), 1);
371 anonymousMethods.erase(methodName.data());
372 } else {
373 EXPECT_EQ(anonymousMethods.count(methodName.data()), 0);
374 }
375 anonymousMethods.erase(methodName.data());
376 });
377 ASSERT_TRUE(anonymousMethods.empty());
378
379 g_impl->closeFile(file);
380 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
381 }
382
383 // Test: test-kind=api, api=InspectApiImpl::functionGetParentFunction, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitInspectApiMethodsTest,DynamicFunctionGetParentFunction)384 TEST_F(LibAbcKitInspectApiMethodsTest, DynamicFunctionGetParentFunction)
385 {
386 AbckitFile *file = nullptr;
387 helpers::AssertOpenAbc(ABCKIT_ABC_DIR "ut/metadata_core/inspect_api/methods/methods_dynamic.abc", &file);
388
389 std::unordered_map<std::string, std::string> parentFunctions = {
390 {"M0C0F1", ""},
391 {"M0C0", ""},
392 {"M0C0F0", ""},
393 {"M0C0F2", ""},
394 {"M0N0C0F1", ""},
395 {"M0N0C0", ""},
396 {"M0N0C0F0", ""},
397 {"M0N0C0F2", ""},
398 {"m0N0N0F0", ""},
399 {"m0N0F0", ""},
400 {"m0N0F1", ""},
401 {"m0N0F2", ""},
402 {"m0F0", ""},
403 {"methods_dynamic.#*@0*#m0F0F0", ""},
404 {"m0F1", ""},
405 {"m0F2", ""},
406 {"methods_dynamic.#*@0*#", ""},
407 {"methods_dynamic.#*@0*#^1", ""},
408 {"func_main_0", ""},
409 };
410
411 helpers::EnumerateAllMethods(file, [&parentFunctions](AbckitCoreFunction *method) {
412 auto methodName = helpers::AbckitStringToString(g_implI->functionGetName(method));
413 ASSERT_EQ(parentFunctions.count(methodName.data()), 1);
414 AbckitCoreFunction *parentFunction = g_implI->functionGetParentFunction(method);
415 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
416 if (parentFunction == nullptr) {
417 ASSERT_EQ(parentFunctions.at(methodName.data()), "");
418 } else {
419 auto className = helpers::AbckitStringToString(g_implI->functionGetName(parentFunction));
420 ASSERT_EQ(parentFunctions.at(methodName.data()), className);
421 }
422 parentFunctions.erase(methodName.data());
423 });
424 ASSERT_TRUE(parentFunctions.empty());
425
426 g_impl->closeFile(file);
427 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
428 }
429
430 // Test: test-kind=api, api=InspectApiImpl::functionGetParentClass, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitInspectApiMethodsTest,DynamicFunctionGetParentClass)431 TEST_F(LibAbcKitInspectApiMethodsTest, DynamicFunctionGetParentClass)
432 {
433 AbckitFile *file = nullptr;
434 helpers::AssertOpenAbc(ABCKIT_ABC_DIR "ut/metadata_core/inspect_api/methods/methods_dynamic.abc", &file);
435
436 std::unordered_map<std::string, std::string> methodClasses = {
437 {"M0C0F1", "M0C0"},
438 {"M0C0", "M0C0"},
439 {"M0C0F0", "M0C0"},
440 {"M0C0F2", "M0C0"},
441 {"M0N0C0F1", "M0N0C0"},
442 {"M0N0C0", "M0N0C0"},
443 {"M0N0C0F0", "M0N0C0"},
444 {"M0N0C0F2", "M0N0C0"},
445 {"m0N0N0F0", ""},
446 {"m0N0F0", ""},
447 {"m0N0F1", ""},
448 {"m0N0F2", ""},
449 {"m0F0", ""},
450 {"m0F1", ""},
451 {"m0F2", ""},
452 {"methods_dynamic.#*@0*#m0F0F0", ""},
453 {"methods_dynamic.#*@0*#", ""},
454 {"methods_dynamic.#*@0*#^1", ""},
455 {"func_main_0", ""},
456 };
457
458 helpers::EnumerateAllMethods(file, [&methodClasses](AbckitCoreFunction *method) {
459 auto methodName = helpers::AbckitStringToString(g_implI->functionGetName(method));
460 ASSERT_EQ(methodClasses.count(methodName.data()), 1);
461 AbckitCoreClass *methodClass = g_implI->functionGetParentClass(method);
462 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
463 if (methodClass == nullptr) {
464 ASSERT_EQ(methodClasses.at(methodName.data()), "");
465 } else {
466 auto className = helpers::AbckitStringToString(g_implI->classGetName(methodClass));
467 ASSERT_EQ(methodClasses.at(methodName.data()), className);
468 }
469 methodClasses.erase(methodName.data());
470 });
471 ASSERT_TRUE(methodClasses.empty());
472
473 g_impl->closeFile(file);
474 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
475 }
476
477 // Test: test-kind=api, api=InspectApiImpl::functionGetParentClass, abc-kind=ArkTS2, category=positive, extension=c
TEST_F(LibAbcKitInspectApiMethodsTest,StaticFunctionGetParentClass)478 TEST_F(LibAbcKitInspectApiMethodsTest, StaticFunctionGetParentClass)
479 {
480 AbckitFile *file = nullptr;
481 helpers::AssertOpenAbc(ABCKIT_ABC_DIR "ut/metadata_core/inspect_api/methods/methods_static.abc", &file);
482
483 std::unordered_map<std::string, std::string> methodClasses = {
484 {"m0F0:void;", ""},
485 {"m0F1:void;", ""},
486 {"m0F2$asyncimpl:std.core.Object;", ""},
487 {"m0F2:std.core.Promise;", ""},
488 {"m0N0F0:void;", ""},
489 {"m0N0F1:void;", ""},
490 {"m0N0F2$asyncimpl:std.core.Object;", ""},
491 {"m0N0F2:std.core.Promise;", ""},
492 {"m0N0N0F0:void;", ""},
493 {"_cctor_:void;", ""},
494 {"lambda$invoke$0:void;", ""},
495 {"lambda$invoke$1:void;", ""},
496 {"M0C0F0:methods_static.M0C0;void;", "M0C0"},
497 {"M0C0F1:void;", "M0C0"},
498 {"M0C0F2$asyncimpl:methods_static.M0C0;std.core.Object;", "M0C0"},
499 {"M0C0F2:methods_static.M0C0;std.core.Promise;", "M0C0"},
500 {"_ctor_:methods_static.M0C0;void;", "M0C0"},
501 {"M0N0C0F0:methods_static.M0N0C0;void;", "M0N0C0"},
502 {"M0N0C0F1:void;", "M0N0C0"},
503 {"M0N0C0F2$asyncimpl:methods_static.M0N0C0;std.core.Object;", "M0N0C0"},
504 {"M0N0C0F2:methods_static.M0N0C0;std.core.Promise;", "M0N0C0"},
505 {"_ctor_:methods_static.M0N0C0;void;", "M0N0C0"},
506 };
507
508 helpers::EnumerateAllMethods(file, [&methodClasses](AbckitCoreFunction *method) {
509 auto methodName = helpers::AbckitStringToString(g_implI->functionGetName(method));
510 ASSERT_EQ(methodClasses.count(methodName.data()), 1);
511 AbckitCoreClass *methodClass = g_implI->functionGetParentClass(method);
512 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
513 if (methodClass == nullptr) {
514 ASSERT_EQ(methodClasses.at(methodName.data()), "");
515 } else {
516 auto className = helpers::AbckitStringToString(g_implI->classGetName(methodClass));
517 ASSERT_EQ(methodClasses.at(methodName.data()), className);
518 }
519 methodClasses.erase(methodName.data());
520 });
521 ASSERT_TRUE(methodClasses.empty());
522
523 g_impl->closeFile(file);
524 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
525 }
526
527 // Test: test-kind=api, api=InspectApiImpl::functionGetModule, abc-kind=ArkTS2, category=positive, extension=c
TEST_F(LibAbcKitInspectApiMethodsTest,StaticFunctionGetModule)528 TEST_F(LibAbcKitInspectApiMethodsTest, StaticFunctionGetModule)
529 {
530 AbckitFile *file = nullptr;
531 helpers::AssertOpenAbc(ABCKIT_ABC_DIR "ut/metadata_core/inspect_api/methods/methods_static.abc", &file);
532 auto moduleName = MethodGetModuleTest(file, "m0F0");
533 ASSERT_EQ("methods_static", moduleName);
534 g_impl->closeFile(file);
535 }
536
537 // Test: test-kind=api, api=InspectApiImpl::functionGetModule, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitInspectApiMethodsTest,DynamicFunctionGetModule)538 TEST_F(LibAbcKitInspectApiMethodsTest, DynamicFunctionGetModule)
539 {
540 AbckitFile *file = nullptr;
541 helpers::AssertOpenAbc(ABCKIT_ABC_DIR "ut/metadata_core/inspect_api/methods/methods_dynamic.abc", &file);
542 auto moduleName = MethodGetModuleTest(file, "m0F0");
543 ASSERT_EQ("methods_dynamic", moduleName);
544 g_impl->closeFile(file);
545 }
546
547 // Test: test-kind=api, api=ArktsInspectApiImpl::functionIsNative, abc-kind=ArkTS2, category=positive, extension=c
TEST_F(LibAbcKitInspectApiMethodsTest,StaticMethodIsNative)548 TEST_F(LibAbcKitInspectApiMethodsTest, StaticMethodIsNative)
549 {
550 AbckitFile *file = nullptr;
551 helpers::AssertOpenAbc(ABCKIT_ABC_DIR "ut/metadata_core/inspect_api/methods/native_method.abc", &file);
552
553 g_implI->fileEnumerateModules(file, nullptr, [](AbckitCoreModule *m, [[maybe_unused]] void *data) {
554 helpers::ClassByNameContext ctxFinder = {nullptr, "Y"};
555 g_implI->moduleEnumerateClasses(m, &ctxFinder, helpers::ClassByNameFinder);
556 EXPECT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
557 EXPECT_NE(ctxFinder.klass, nullptr);
558
559 helpers::MethodByNameContext methodCtxFinder = {nullptr, "bar"};
560 g_implI->classEnumerateMethods(ctxFinder.klass, &methodCtxFinder, helpers::MethodByNameFinder);
561 EXPECT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
562 EXPECT_NE(methodCtxFinder.method, nullptr);
563
564 AbckitArktsFunction *methodArkTS = g_implArktsI->coreFunctionToArktsFunction(methodCtxFinder.method);
565 bool isAbstract = g_implArktsI->functionIsNative(methodArkTS);
566 EXPECT_EQ(isAbstract, true);
567
568 return true;
569 });
570
571 g_impl->closeFile(file);
572 }
573
574 } // namespace libabckit::test
575