• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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