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
18 #include "libabckit/include/c/abckit.h"
19 #include "helpers/helpers.h"
20
21 namespace libabckit::test {
22
23 static auto g_impl = AbckitGetApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
24 static auto g_implI = AbckitGetInspectApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
25 static auto g_implM = AbckitGetModifyApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
26 static auto g_implG = AbckitGetGraphApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
27
28 class LibAbcKitAbcStuff : public ::testing::Test {};
29
30 struct ClassData {
31 const char *className = nullptr;
32 std::vector<const char *> classMethods = {};
33 };
34
35 struct ModuleData {
36 const char *moduleName = nullptr;
37 std::vector<const char *> moduleMethods = {};
38 };
39
40 // Test: test-kind=api, api=ApiImpl::openAbc, abc-kind=ArkTS2, category=positive, extension=c
TEST_F(LibAbcKitAbcStuff,OpenAbcStatic)41 TEST_F(LibAbcKitAbcStuff, OpenAbcStatic)
42 {
43 constexpr auto INPUT_PATH = ABCKIT_ABC_DIR "internal/implementation_api/abc_static.abc";
44 auto *file = g_impl->openAbc(INPUT_PATH, strlen(INPUT_PATH));
45 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
46
47 std::vector<struct ClassData> userData = {{"ClassA", {"foo", "bar"}}, {"ClassB", {"baz", "func"}}};
48
49 g_implI->fileEnumerateModules(file, &userData, [](AbckitCoreModule *m, void *data) {
50 auto *userData = reinterpret_cast<std::vector<struct ClassData> *>(data);
51
52 for (const auto &classData : *userData) {
53 helpers::ClassByNameContext classCtxFinder = {nullptr, classData.className};
54 g_implI->moduleEnumerateClasses(m, &classCtxFinder, helpers::ClassByNameFinder);
55 EXPECT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
56 EXPECT_NE(classCtxFinder.klass, nullptr);
57
58 for (auto *method : classData.classMethods) {
59 helpers::MethodByNameContext methodCtxFinder = {nullptr, method};
60 g_implI->classEnumerateMethods(classCtxFinder.klass, &methodCtxFinder, helpers::MethodByNameFinder);
61 EXPECT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
62 EXPECT_NE(methodCtxFinder.method, nullptr);
63 }
64 }
65
66 return true;
67 });
68 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
69
70 g_impl->closeFile(file);
71 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
72 }
73
74 // Test: test-kind=api, api=ApiImpl::writeAbc, abc-kind=ArkTS2, category=positive, extension=c
TEST_F(LibAbcKitAbcStuff,WriteAbcStatic)75 TEST_F(LibAbcKitAbcStuff, WriteAbcStatic)
76 {
77 constexpr auto INPUT_PATH = ABCKIT_ABC_DIR "internal/implementation_api/abc_static.abc";
78 auto *file = g_impl->openAbc(INPUT_PATH, strlen(INPUT_PATH));
79 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
80 g_impl->writeAbc(file, INPUT_PATH, strlen(INPUT_PATH));
81 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
82 g_impl->closeFile(file);
83 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
84 file = g_impl->openAbc(INPUT_PATH, strlen(INPUT_PATH));
85 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
86
87 std::vector<struct ClassData> userData = {{"ClassA", {"foo", "bar"}}, {"ClassB", {"baz", "func"}}};
88
89 g_implI->fileEnumerateModules(file, &userData, [](AbckitCoreModule *m, void *data) {
90 auto *userData = reinterpret_cast<std::vector<struct ClassData> *>(data);
91
92 for (const auto &classData : *userData) {
93 helpers::ClassByNameContext classCtxFinder = {nullptr, classData.className};
94 g_implI->moduleEnumerateClasses(m, &classCtxFinder, helpers::ClassByNameFinder);
95 EXPECT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
96 EXPECT_NE(classCtxFinder.klass, nullptr);
97
98 for (auto *method : classData.classMethods) {
99 helpers::MethodByNameContext methodCtxFinder = {nullptr, method};
100 g_implI->classEnumerateMethods(classCtxFinder.klass, &methodCtxFinder, helpers::MethodByNameFinder);
101 EXPECT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
102 EXPECT_NE(methodCtxFinder.method, nullptr);
103 }
104 }
105
106 return true;
107 });
108 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
109
110 g_impl->closeFile(file);
111 }
112
113 // Test: test-kind=api, api=ApiImpl::closeFile, abc-kind=ArkTS2, category=positive, extension=c
TEST_F(LibAbcKitAbcStuff,CloseFileStatic)114 TEST_F(LibAbcKitAbcStuff, CloseFileStatic)
115 {
116 constexpr auto INPUT_PATH = ABCKIT_ABC_DIR "internal/implementation_api/abc_static.abc";
117 auto *file = g_impl->openAbc(INPUT_PATH, strlen(INPUT_PATH));
118 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
119 g_impl->closeFile(file);
120 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
121 }
122
123 // Test: test-kind=api, api=ApiImpl::openAbc, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitAbcStuff,OpenAbcDynamic)124 TEST_F(LibAbcKitAbcStuff, OpenAbcDynamic)
125 {
126 constexpr auto INPUT_PATH = ABCKIT_ABC_DIR "internal/implementation_api/abc_dynamic.abc";
127 auto *file = g_impl->openAbc(INPUT_PATH, strlen(INPUT_PATH));
128 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
129
130 struct ModuleData userData = {"abc_dynamic", {"foo", "bar", "baz", "func"}};
131
132 helpers::ModuleByNameContext moduleCtxFinder = {nullptr, userData.moduleName};
133 g_implI->fileEnumerateModules(file, &moduleCtxFinder, helpers::ModuleByNameFinder);
134 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
135 ASSERT_NE(moduleCtxFinder.module, nullptr);
136
137 for (auto method : userData.moduleMethods) {
138 auto *found = helpers::FindMethodByName(file, method);
139 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
140 ASSERT_NE(found, nullptr);
141 }
142
143 std::set<std::string> anonymousMethods = {
144 "abc_dynamic.#*#",
145 "abc_dynamic.#*#^1",
146 "abc_dynamic.#*#anonymousfunc",
147 };
148 helpers::EnumerateAllMethods(file, [&anonymousMethods](AbckitCoreFunction *method) {
149 auto methodName = helpers::AbckitStringToString(g_implI->functionGetName(method));
150 bool isAnonymous = g_implI->functionIsAnonymous(method);
151 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
152 if (isAnonymous) {
153 EXPECT_EQ(anonymousMethods.count(methodName.data()), 1);
154 anonymousMethods.erase(methodName.data());
155 } else {
156 EXPECT_EQ(anonymousMethods.count(methodName.data()), 0);
157 }
158 });
159 ASSERT_TRUE(anonymousMethods.empty());
160
161 g_impl->closeFile(file);
162 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
163 }
164
165 // Test: test-kind=api, api=ApiImpl::writeAbc, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitAbcStuff,WriteAbcDynamic)166 TEST_F(LibAbcKitAbcStuff, WriteAbcDynamic)
167 {
168 constexpr auto INPUT_PATH = ABCKIT_ABC_DIR "internal/implementation_api/abc_dynamic.abc";
169 auto *file = g_impl->openAbc(INPUT_PATH, strlen(INPUT_PATH));
170 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
171 g_impl->writeAbc(file, INPUT_PATH, strlen(INPUT_PATH));
172 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
173 g_impl->closeFile(file);
174 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
175 file = g_impl->openAbc(INPUT_PATH, strlen(INPUT_PATH));
176 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
177
178 struct ModuleData userData = {"abc_dynamic", {"foo", "bar", "baz", "func"}};
179
180 helpers::ModuleByNameContext moduleCtxFinder = {nullptr, userData.moduleName};
181 g_implI->fileEnumerateModules(file, &moduleCtxFinder, helpers::ModuleByNameFinder);
182 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
183 ASSERT_NE(moduleCtxFinder.module, nullptr);
184
185 for (auto method : userData.moduleMethods) {
186 auto *found = helpers::FindMethodByName(file, method);
187 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
188 ASSERT_NE(found, nullptr);
189 }
190
191 g_impl->closeFile(file);
192 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
193 }
194
195 // Test: test-kind=api, api=ApiImpl::closeFile, abc-kind=ArkTS1, category=positive, extension=c
TEST_F(LibAbcKitAbcStuff,CloseFileDynamic)196 TEST_F(LibAbcKitAbcStuff, CloseFileDynamic)
197 {
198 constexpr auto INPUT_PATH = ABCKIT_ABC_DIR "internal/implementation_api/abc_dynamic.abc";
199 auto *file = g_impl->openAbc(INPUT_PATH, strlen(INPUT_PATH));
200 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
201 g_impl->closeFile(file);
202 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
203 }
204
205 } // namespace libabckit::test
206