• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2025 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 "ani_gtest.h"
17 
18 // NOLINTBEGIN(cppcoreguidelines-pro-type-vararg, modernize-avoid-c-arrays)
19 namespace ark::ets::ani::testing {
20 class ClassFindMethodTest : public AniTest {
21 protected:
22     static constexpr ani_int TEST_EXPECTED_VALUE1 = 5;
23     static constexpr ani_int TEST_EXPECTED_VALUE2 = 4;
24     static constexpr ani_int TEST_EXPECTED_VALUE3 = 9;
25     static constexpr ani_int TEST_EXPECTED_VALUE4 = 2;
26     static constexpr ani_int TEST_EXPECTED_VALUE5 = 6;
27     static constexpr ani_int TEST_EXPECTED_VALUE6 = 3;
28 
29     static constexpr ani_int TEST_ARG1 = 2;
30     static constexpr ani_int TEST_ARG2 = 3;
31     static constexpr ani_double TEST_ARG3 = 1.0;
32     static constexpr ani_boolean TEST_ARG4 = ANI_TRUE;
33     static constexpr ani_float TEST_ARG5 = 3.0;
34     static constexpr ani_float TEST_ARG6 = 4.0;
35 
36     static constexpr ani_int TEST_NATIVE_PARAM1 = 2;
37     static constexpr ani_int TEST_NATIVE_PARAM2 = 3;
38 
39     static constexpr std::string_view ARG_STRING = "abab";
40 
41 private:
GetFunc(ani_function * fn,const char * funcName)42     void GetFunc(ani_function *fn, const char *funcName)
43     {
44         ani_module module;
45         ASSERT_EQ(env_->FindModule("Ltest;", &module), ANI_OK);
46         ASSERT_NE(module, nullptr);
47 
48         ASSERT_EQ(env_->Module_FindFunction(module, funcName, nullptr, fn), ANI_OK);
49         ASSERT_NE(fn, nullptr);
50     }
51 
GetObject(ani_object * objectResult,ani_class cls)52     void GetObject(ani_object *objectResult, ani_class cls)
53     {
54         ani_method ctor;
55         ASSERT_EQ(env_->Class_FindMethod(cls, "<ctor>", ":V", &ctor), ANI_OK);
56         ASSERT_EQ(env_->Object_New(cls, ctor, objectResult), ANI_OK);
57     }
58 
59 public:
60     template <bool HAS_METHOD>
CheckClassFindMethod(const char * clsDescriptor,const char * methodName,const char * methodSignature,const ani_value * args=nullptr,ani_int expectedResult=TEST_EXPECTED_VALUE1)61     void CheckClassFindMethod(const char *clsDescriptor, const char *methodName, const char *methodSignature,
62                               const ani_value *args = nullptr, ani_int expectedResult = TEST_EXPECTED_VALUE1)
63     {
64         ani_module module;
65         ASSERT_EQ(env_->FindModule("Ltest;", &module), ANI_OK);
66         ani_class cls;
67         ASSERT_EQ(env_->Module_FindClass(module, clsDescriptor, &cls), ANI_OK);
68         ASSERT_NE(cls, nullptr);
69 
70         ani_method method;
71         auto status = env_->Class_FindMethod(cls, methodName, methodSignature, &method);
72 
73         if constexpr (!HAS_METHOD) {
74             ASSERT_EQ(status, ANI_NOT_FOUND);
75             return;
76         }
77 
78         ASSERT_EQ(status, ANI_OK);
79         ASSERT_NE(method, nullptr);
80 
81         ani_object obj;
82         GetObject(&obj, cls);
83 
84         ani_int result;
85         ASSERT_EQ(env_->Object_CallMethod_Int_A(obj, method, &result, args), ANI_OK);
86         ASSERT_EQ(result, expectedResult);
87     }
88 
CheckIntrinsicsFindMethod(const char * moduleDescriptor,const char * clsDescriptor,const char * methodName,const char * methodSignature)89     void CheckIntrinsicsFindMethod(const char *moduleDescriptor, const char *clsDescriptor, const char *methodName,
90                                    const char *methodSignature)
91     {
92         ani_module module;
93         ASSERT_EQ(env_->FindModule(moduleDescriptor, &module), ANI_OK);
94         ani_class cls;
95         ASSERT_EQ(env_->Module_FindClass(module, clsDescriptor, &cls), ANI_OK);
96         ASSERT_NE(cls, nullptr);
97 
98         ani_method method;
99         auto status = env_->Class_FindMethod(cls, methodName, methodSignature, &method);
100         ASSERT_EQ(status, ANI_OK);
101     }
102 
TupleCreator(ani_ref * result)103     void TupleCreator(ani_ref *result)
104     {
105         ani_function fn {};
106         ani_value args[2U];
107         args[0U].i = TEST_ARG1;
108         args[1U].l = TEST_ARG2;
109         GetFunc(&fn, "CreateTuple");
110         env_->Function_Call_Ref_A(fn, result, args);
111     }
112 
PartialCreator(ani_ref * result,ani_int arg=TEST_ARG1)113     void PartialCreator(ani_ref *result, ani_int arg = TEST_ARG1)
114     {
115         ani_function fn {};
116         GetFunc(&fn, "CreatePartial");
117         env_->Function_Call_Ref(fn, result, arg);
118     }
119 
RequiredCreator(ani_ref * result)120     void RequiredCreator(ani_ref *result)
121     {
122         ani_function fn {};
123         GetFunc(&fn, "CreateRequired");
124         env_->Function_Call_Ref(fn, result, TEST_ARG1);
125     }
126 
ReadonlyCreator(ani_ref * result)127     void ReadonlyCreator(ani_ref *result)
128     {
129         ani_function fn {};
130         GetFunc(&fn, "CreateReadonly");
131         env_->Function_Call_Ref(fn, result, TEST_ARG1);
132     }
133 
RecordCreator(ani_class * cls,ani_object * result)134     void RecordCreator(ani_class *cls, ani_object *result)
135     {
136         ASSERT_EQ(env_->FindClass("Lescompat/Record;", cls), ANI_OK);
137         ASSERT_NE(cls, nullptr);
138 
139         ani_method ctor;
140         ASSERT_EQ(env_->Class_FindMethod(*cls, "<ctor>", ":V", &ctor), ANI_OK);
141 
142         ASSERT_EQ(env_->Object_New(*cls, ctor, result), ANI_OK);
143     }
144 
BigintCreator(ani_class * cls,ani_object * result)145     void BigintCreator(ani_class *cls, ani_object *result)
146     {
147         ASSERT_EQ(env_->FindClass("Lescompat/BigInt;", cls), ANI_OK);
148         ASSERT_NE(cls, nullptr);
149 
150         ani_method ctor;
151         ASSERT_EQ(env_->Class_FindMethod(*cls, "<ctor>", "I:V", &ctor), ANI_OK);
152 
153         ani_int arg = TEST_ARG1;
154 
155         ASSERT_EQ(env_->Object_New(*cls, ctor, result, arg), ANI_OK);
156     }
157 
LambdaCreator(ani_ref * result,const char * funcName)158     void LambdaCreator(ani_ref *result, const char *funcName)
159     {
160         ani_function fn {};
161         GetFunc(&fn, funcName);
162         env_->Function_Call_Ref(fn, result);
163     }
164 
Int(ani_object * obj,ani_int value)165     void Int(ani_object *obj, ani_int value)
166     {
167         ani_class cls;
168         ASSERT_EQ(env_->FindClass("Lstd/core/Int;", &cls), ANI_OK);
169         ASSERT_NE(cls, nullptr);
170 
171         ani_method ctor;
172         ASSERT_EQ(env_->Class_FindMethod(cls, "<ctor>", "I:V", &ctor), ANI_OK);
173 
174         ASSERT_EQ(env_->Object_New(cls, ctor, obj, value), ANI_OK);
175     }
176 
177     // NOLINTNEXTLINE(readability-named-parameter)
NativeMethodsFooNative(ani_env *,ani_class)178     static ani_int NativeMethodsFooNative(ani_env *, ani_class)
179     {
180         const ani_int answer = 42U;
181         return answer;
182     }
183 };
184 
TEST_F(ClassFindMethodTest,has_method__A_B)185 TEST_F(ClassFindMethodTest, has_method__A_B)
186 {
187     ani_value args[2U];
188     args[0U].i = TEST_ARG1;
189     args[1U].i = TEST_ARG2;
190 
191     CheckClassFindMethod<true>("LA;", "int_method", "II:I", args, TEST_EXPECTED_VALUE1);
192     CheckClassFindMethod<true>("LA;", "int_method", nullptr, args, TEST_EXPECTED_VALUE1);
193     CheckClassFindMethod<true>("LB;", "int_method", "II:I", args, TEST_EXPECTED_VALUE1);
194     CheckClassFindMethod<true>("LB;", "int_method", nullptr, args, TEST_EXPECTED_VALUE1);
195 
196     CheckClassFindMethod<true>("LA;", "int_override_method", "II:I", args, TEST_EXPECTED_VALUE2);
197     CheckClassFindMethod<true>("LA;", "int_override_method", nullptr, args, TEST_EXPECTED_VALUE2);
198 
199     CheckClassFindMethod<true>("LB;", "int_override_method", "II:I", args, TEST_EXPECTED_VALUE3);
200     CheckClassFindMethod<true>("LB;", "int_override_method", nullptr, args, TEST_EXPECTED_VALUE3);
201 }
202 
TEST_F(ClassFindMethodTest,has_method_C)203 TEST_F(ClassFindMethodTest, has_method_C)
204 {
205     ani_value arg;
206     arg.i = TEST_ARG1;
207 
208     CheckClassFindMethod<true>("LC;", "imethod", "I:I", &arg, TEST_EXPECTED_VALUE4);
209 
210     ani_string string {};
211     ASSERT_EQ(env_->String_NewUTF8(ARG_STRING.data(), ARG_STRING.size(), &string), ANI_OK);
212     arg.r = string;
213 
214     CheckClassFindMethod<true>("LC;", "imethod", "Lstd/core/String;:I", &arg, TEST_EXPECTED_VALUE2);
215 }
216 
TEST_F(ClassFindMethodTest,has_method_C_unusual_types)217 TEST_F(ClassFindMethodTest, has_method_C_unusual_types)
218 {
219     ani_value args;
220     ani_string string {};
221     {
222         ASSERT_EQ(env_->String_NewUTF8(ARG_STRING.data(), ARG_STRING.size(), &string), ANI_OK);
223         args.r = string;
224 
225         CheckClassFindMethod<true>("LC;", "imethod_optional", nullptr, &args, TEST_EXPECTED_VALUE2);
226 
227         env_->GetUndefined(&args.r);
228         CheckClassFindMethod<true>("LC;", "imethod_optional", nullptr, &args, TEST_EXPECTED_VALUE1);
229 
230         TupleCreator(&args.r);
231         CheckClassFindMethod<true>("LC;", "imethod_tuple", nullptr, &args, TEST_EXPECTED_VALUE1);
232     }
233     {
234         ani_array_int params;
235         ASSERT_EQ(env_->FixedArray_New_Int(2U, &params), ANI_OK);
236         ani_int nativeParams[] = {TEST_NATIVE_PARAM1, TEST_NATIVE_PARAM2};
237         const ani_size offset = 0;
238         ASSERT_EQ(env_->Array_SetRegion_Int(params, offset, 2U, nativeParams), ANI_OK);
239 
240         args.r = params;
241         CheckClassFindMethod<true>("LC;", "method_rest", nullptr, &args, TEST_EXPECTED_VALUE1);
242     }
243     {
244         args.r = string;
245         CheckClassFindMethod<true>("LC;", "method_union", nullptr, &args, TEST_EXPECTED_VALUE2);
246     }
247     {
248         ani_object intValue;
249         Int(&intValue, TEST_ARG1);
250         args.r = intValue;
251         CheckClassFindMethod<true>("LC;", "method_union", nullptr, &args, TEST_EXPECTED_VALUE4);
252     }
253 }
254 
TEST_F(ClassFindMethodTest,has_method_Derived)255 TEST_F(ClassFindMethodTest, has_method_Derived)
256 {
257     ani_value args;
258     args.i = TEST_ARG1;
259     CheckClassFindMethod<true>("LDerived;", "abstract_method", nullptr, &args, TEST_EXPECTED_VALUE4);
260 
261     CheckClassFindMethod<true>("LDerived;", "method", nullptr, &args, TEST_EXPECTED_VALUE2);
262 }
263 
TEST_F(ClassFindMethodTest,has_method_Overload)264 TEST_F(ClassFindMethodTest, has_method_Overload)
265 {
266     ani_value args;
267     args.i = TEST_ARG1;
268     CheckClassFindMethod<true>("LOverload;", "method", "I:I", &args, TEST_EXPECTED_VALUE4);
269 
270     ani_value params[2U];
271     params[0U].i = TEST_ARG1;
272     params[1U].z = TEST_ARG4;
273     CheckClassFindMethod<true>("LOverload;", "method", "IZ:I", params, TEST_EXPECTED_VALUE2);
274 
275     params[1U].d = TEST_ARG3;
276     CheckClassFindMethod<true>("LOverload;", "method", "ID:I", params, TEST_EXPECTED_VALUE5);
277 }
278 
TEST_F(ClassFindMethodTest,special_types1)279 TEST_F(ClassFindMethodTest, special_types1)
280 {
281     ani_value args;
282     {
283         PartialCreator(&args.r);
284         CheckClassFindMethod<true>("LSpecialTypes;", "partial_method", nullptr, &args, TEST_EXPECTED_VALUE1);
285         PartialCreator(&args.r, TEST_ARG2);
286         CheckClassFindMethod<true>("LSpecialTypes;", "partial_method", nullptr, &args, TEST_EXPECTED_VALUE6);
287     }
288     {
289         RequiredCreator(&args.r);
290         CheckClassFindMethod<true>("LSpecialTypes;", "required_method", nullptr, &args, TEST_EXPECTED_VALUE4);
291 
292         ReadonlyCreator(&args.r);
293         CheckClassFindMethod<true>("LSpecialTypes;", "readonly_method", nullptr, &args, TEST_EXPECTED_VALUE4);
294     }
295     {
296         ani_class cls;
297         ani_object mapValue;
298         RecordCreator(&cls, &mapValue);
299         ani_method setter;
300         ASSERT_EQ(env_->Class_FindIndexableSetter(cls, nullptr, &setter), ANI_OK);
301 
302         ani_string string {};
303         ASSERT_EQ(env_->String_NewUTF8(ARG_STRING.data(), ARG_STRING.size(), &string), ANI_OK);
304 
305         ani_object intValue;
306         Int(&intValue, TEST_ARG1);
307         ASSERT_EQ(env_->Object_CallMethod_Void(mapValue, setter, string, intValue), ANI_OK);
308 
309         args.r = mapValue;
310         CheckClassFindMethod<true>("LSpecialTypes;", "record_method", nullptr, &args, TEST_EXPECTED_VALUE4);
311     }
312 }
313 
TEST_F(ClassFindMethodTest,special_types2)314 TEST_F(ClassFindMethodTest, special_types2)
315 {
316     ani_value args;
317 
318     // NOTE(ypigunova) change native args. Issue #23595
319     // NOTE(daizihan) remove this test commented out, since the arg was not correct, need wait #23595
320     {
321         env_->GetUndefined(&args.r);
322         CheckClassFindMethod<true>("LSpecialTypes;", "null_method", nullptr, &args, TEST_EXPECTED_VALUE1);
323     }
324     {
325         ani_string string {};
326         ASSERT_EQ(env_->String_NewUTF8(ARG_STRING.data(), ARG_STRING.size(), &string), ANI_OK);
327 
328         args.r = string;
329         CheckClassFindMethod<true>("LSpecialTypes;", "string_literal_method", nullptr, &args, TEST_EXPECTED_VALUE2);
330     }
331     {
332         ani_class cls;
333         ani_object bigIntValue;
334         BigintCreator(&cls, &bigIntValue);
335         args.r = bigIntValue;
336         CheckClassFindMethod<true>("LSpecialTypes;", "bigint_method", nullptr, &args, TEST_EXPECTED_VALUE4);
337     }
338 }
339 
TEST_F(ClassFindMethodTest,lambdas)340 TEST_F(ClassFindMethodTest, lambdas)
341 {
342     ani_value arg;
343 
344     {
345         LambdaCreator(&arg.r, "LambdaOneArg");
346         CheckClassFindMethod<true>("LLambdaTypes;", "one_arg_method", nullptr, &arg, TEST_EXPECTED_VALUE1);
347     }
348     {
349         LambdaCreator(&arg.r, "LambdaTwoArgs");
350         CheckClassFindMethod<true>("LLambdaTypes;", "two_arg_method", nullptr, &arg, TEST_EXPECTED_VALUE6);
351     }
352     {
353         LambdaCreator(&arg.r, "LambdaOptArg");
354         CheckClassFindMethod<true>("LLambdaTypes;", "opt_arg_method", nullptr, &arg, TEST_EXPECTED_VALUE4);
355     }
356 }
357 
TEST_F(ClassFindMethodTest,generics)358 TEST_F(ClassFindMethodTest, generics)
359 {
360     ani_value arg;
361 
362     ani_object intValue;
363     Int(&intValue, TEST_ARG1);
364     arg.r = intValue;
365     CheckClassFindMethod<true>("LGeneric0;", "method", nullptr, &arg, TEST_EXPECTED_VALUE1);
366 
367     Int(&intValue, TEST_ARG1);
368     arg.r = intValue;
369     CheckClassFindMethod<true>("LGeneric1;", "method", nullptr, &arg, TEST_EXPECTED_VALUE4);
370 }
371 
TEST_F(ClassFindMethodTest,binded_method)372 TEST_F(ClassFindMethodTest, binded_method)
373 {
374     ani_module module;
375     ASSERT_EQ(env_->FindModule("Ltest;", &module), ANI_OK);
376     ani_class cls;
377     ASSERT_EQ(env_->Module_FindClass(module, "LFindNativeMethods;", &cls), ANI_OK);
378     ASSERT_NE(cls, nullptr);
379 
380     std::array methods = {
381         ani_native_function {"foo", ":I", reinterpret_cast<void *>(NativeMethodsFooNative)},
382     };
383     ASSERT_EQ(env_->Class_BindNativeMethods(cls, methods.data(), methods.size()), ANI_OK);
384 
385     ani_method method;
386     ASSERT_EQ(env_->Class_FindMethod(cls, "foo", ":I", &method), ANI_OK);
387     ASSERT_NE(method, nullptr);
388 }
389 
TEST_F(ClassFindMethodTest,find_intrinsics)390 TEST_F(ClassFindMethodTest, find_intrinsics)
391 {
392     {
393         const char *moduleName = "Lstd/core;";
394         const char *className = "LString;";
395 
396         CheckIntrinsicsFindMethod(moduleName, className, "compareTo", "Lstd/core/String;:I");
397         CheckIntrinsicsFindMethod(moduleName, className, "repeat", "I:Lstd/core/String;");
398     }
399     {
400         const char *moduleName = "Lescompat;";
401         const char *className = "LArrayBuffer;";
402 
403         CheckIntrinsicsFindMethod(moduleName, className, "set", "IB:V");
404         CheckIntrinsicsFindMethod(moduleName, className, "setValues", "Lescompat/ArrayBuffer;I:V");
405     }
406     {
407         const char *moduleName = "Lstd/core;";
408         const char *className = "LClass;";
409 
410         CheckIntrinsicsFindMethod(moduleName, className, "createInstance", ":Lstd/core/Object;");
411         CheckIntrinsicsFindMethod(moduleName, className, "getDescriptor", ":Lstd/core/String;");
412     }
413     {
414         const char *moduleName = "Lescompat;";
415         const char *className = "LArrayBuffer;";
416 
417         CheckIntrinsicsFindMethod(moduleName, className, "atomicAndI32", "III:D");
418         CheckIntrinsicsFindMethod(moduleName, className, "atomicXorI32", "III:D");
419     }
420 }
421 
TEST_F(ClassFindMethodTest,method_not_found)422 TEST_F(ClassFindMethodTest, method_not_found)
423 {
424     CheckClassFindMethod<false>("LA;", "bla_bla_bla", nullptr);
425     CheckClassFindMethod<false>("LA;", "int_method", "bla_bla_bla");
426     CheckClassFindMethod<false>("LOverload;", "method", "DD:I");
427     CheckClassFindMethod<false>("LOverload;", "method", "ILstd/core/String;:I");
428 }
429 
TEST_F(ClassFindMethodTest,invalid_argument_name)430 TEST_F(ClassFindMethodTest, invalid_argument_name)
431 {
432     ani_class cls;
433     ASSERT_EQ(env_->FindClass(nullptr, &cls), ANI_INVALID_ARGS);
434 
435     ani_method method;
436     ASSERT_EQ(env_->Class_FindMethod(cls, nullptr, nullptr, &method), ANI_INVALID_ARGS);
437 }
438 
TEST_F(ClassFindMethodTest,invalid_argument_cls)439 TEST_F(ClassFindMethodTest, invalid_argument_cls)
440 {
441     ani_method method;
442     ASSERT_EQ(env_->Class_FindMethod(nullptr, "int_method", nullptr, &method), ANI_INVALID_ARGS);
443 }
444 
TEST_F(ClassFindMethodTest,invalid_arguments)445 TEST_F(ClassFindMethodTest, invalid_arguments)
446 {
447     ani_class cls {};
448     ASSERT_EQ(env_->FindClass("Ltest/A;", &cls), ANI_OK);
449     ASSERT_NE(cls, nullptr);
450 
451     ani_method method {};
452     ASSERT_EQ(env_->Class_FindMethod(cls, "int_method", nullptr, nullptr), ANI_INVALID_ARGS);
453 
454     ASSERT_EQ(env_->c_api->Class_FindMethod(nullptr, cls, "int_method", nullptr, &method), ANI_INVALID_ARGS);
455 
456     ASSERT_EQ(env_->Class_FindMethod(cls, "", "II:I", &method), ANI_NOT_FOUND);
457     ASSERT_EQ(env_->Class_FindMethod(cls, "\t", "II:I", &method), ANI_NOT_FOUND);
458 
459     ASSERT_EQ(env_->Class_FindMethod(cls, "int_method", "", &method), ANI_NOT_FOUND);
460     ASSERT_EQ(env_->Class_FindMethod(cls, "int_method", "\t", &method), ANI_NOT_FOUND);
461 }
462 
TEST_F(ClassFindMethodTest,has_static_method_1)463 TEST_F(ClassFindMethodTest, has_static_method_1)
464 {
465     ani_class cls {};
466     ASSERT_EQ(env_->FindClass("Ltest/Phone;", &cls), ANI_OK);
467     ASSERT_NE(cls, nullptr);
468 
469     ani_static_method method {};
470     ASSERT_EQ(env_->Class_FindStaticMethod(cls, "get_button_names", ":[Lstd/core/String;", &method), ANI_OK);
471     ASSERT_NE(method, nullptr);
472 }
473 
TEST_F(ClassFindMethodTest,has_static_method_2)474 TEST_F(ClassFindMethodTest, has_static_method_2)
475 {
476     ani_class cls {};
477     ASSERT_EQ(env_->FindClass("Ltest/Phone;", &cls), ANI_OK);
478     ASSERT_NE(cls, nullptr);
479 
480     ani_static_method method {};
481     ASSERT_EQ(env_->Class_FindStaticMethod(cls, "get_button_names", nullptr, &method), ANI_OK);
482     ASSERT_NE(method, nullptr);
483 }
484 
TEST_F(ClassFindMethodTest,static_method_not_found_1)485 TEST_F(ClassFindMethodTest, static_method_not_found_1)
486 {
487     ani_class cls {};
488     ASSERT_EQ(env_->FindClass("Ltest/Phone;", &cls), ANI_OK);
489     ASSERT_NE(cls, nullptr);
490 
491     ani_static_method method {};
492     ASSERT_EQ(env_->Class_FindStaticMethod(cls, "bla_bla_bla", nullptr, &method), ANI_NOT_FOUND);
493 }
494 
TEST_F(ClassFindMethodTest,static_method_not_found_2)495 TEST_F(ClassFindMethodTest, static_method_not_found_2)
496 {
497     ani_class cls {};
498     ASSERT_EQ(env_->FindClass("Ltest/Phone;", &cls), ANI_OK);
499     ASSERT_NE(cls, nullptr);
500 
501     ani_static_method method {};
502     ASSERT_EQ(env_->Class_FindStaticMethod(cls, "get_button_names", "bla_bla_bla", &method), ANI_NOT_FOUND);
503 }
504 
TEST_F(ClassFindMethodTest,static_method_invalid_argument_name)505 TEST_F(ClassFindMethodTest, static_method_invalid_argument_name)
506 {
507     ani_class cls {};
508     ASSERT_EQ(env_->FindClass("Ltest/Phone;", &cls), ANI_OK);
509     ASSERT_NE(cls, nullptr);
510 
511     ani_static_method method {};
512     ASSERT_EQ(env_->Class_FindStaticMethod(cls, nullptr, nullptr, &method), ANI_INVALID_ARGS);
513 }
514 
TEST_F(ClassFindMethodTest,static_method_invalid_argument_cls)515 TEST_F(ClassFindMethodTest, static_method_invalid_argument_cls)
516 {
517     ani_static_method method {};
518     ASSERT_EQ(env_->Class_FindStaticMethod(nullptr, "get_button_names", nullptr, &method), ANI_INVALID_ARGS);
519 }
520 
TEST_F(ClassFindMethodTest,static_method_invalid_arguments)521 TEST_F(ClassFindMethodTest, static_method_invalid_arguments)
522 {
523     ani_class cls {};
524     ASSERT_EQ(env_->FindClass("Ltest/Phone;", &cls), ANI_OK);
525     ASSERT_NE(cls, nullptr);
526 
527     ani_static_method method {};
528     ASSERT_EQ(env_->Class_FindStaticMethod(cls, "get_button_names", nullptr, nullptr), ANI_INVALID_ARGS);
529 
530     ASSERT_EQ(env_->c_api->Class_FindStaticMethod(nullptr, cls, "get_button_names", nullptr, &method),
531               ANI_INVALID_ARGS);
532     ASSERT_EQ(env_->Class_FindStaticMethod(cls, "", ":[Lstd/core/String;", &method), ANI_NOT_FOUND);
533     ASSERT_EQ(env_->Class_FindStaticMethod(cls, "\t", ":[Lstd/core/String;", &method), ANI_NOT_FOUND);
534     ASSERT_EQ(env_->Class_FindStaticMethod(cls, "get_button_names", "", &method), ANI_NOT_FOUND);
535     ASSERT_EQ(env_->Class_FindStaticMethod(cls, "get_button_names", "\t", &method), ANI_NOT_FOUND);
536 }
537 
TEST_F(ClassFindMethodTest,static_method_find_static_method_001)538 TEST_F(ClassFindMethodTest, static_method_find_static_method_001)
539 {
540     ani_class cls {};
541     ASSERT_EQ(env_->FindClass("Ltest/Operations;", &cls), ANI_OK);
542     ASSERT_NE(cls, nullptr);
543 
544     ani_static_method method {};
545     ASSERT_EQ(env_->Class_FindStaticMethod(cls, "sum", "II:I", &method), ANI_OK);
546     ASSERT_NE(method, nullptr);
547 
548     ani_int sum = 0;
549     ASSERT_EQ(env_->Class_CallStaticMethod_Int(cls, method, &sum, TEST_EXPECTED_VALUE1, TEST_EXPECTED_VALUE5), ANI_OK);
550     ASSERT_EQ(sum, TEST_EXPECTED_VALUE1 + TEST_EXPECTED_VALUE5);
551 }
552 
TEST_F(ClassFindMethodTest,static_method_find_static_method_002)553 TEST_F(ClassFindMethodTest, static_method_find_static_method_002)
554 {
555     ani_class cls {};
556     ASSERT_EQ(env_->FindClass("Ltest/ClassA;", &cls), ANI_OK);
557     ASSERT_NE(cls, nullptr);
558 
559     ani_static_method methodA {};
560     ASSERT_EQ(env_->Class_FindStaticMethod(cls, "calculateSquareArea", "II:I", &methodA), ANI_OK);
561     ASSERT_NE(methodA, nullptr);
562 
563     ani_static_method methodB {};
564     ASSERT_EQ(env_->Class_FindStaticMethod(cls, "calculateSquareArea", "III:I", &methodB), ANI_OK);
565     ASSERT_NE(methodB, nullptr);
566 
567     ani_int sumA = 0;
568     ani_value args[2U];
569     args[0U].i = TEST_EXPECTED_VALUE1;
570     args[1U].i = TEST_EXPECTED_VALUE5;
571     ASSERT_EQ(env_->Class_CallStaticMethod_Int_A(cls, methodA, &sumA, args), ANI_OK);
572     ASSERT_EQ(sumA, TEST_EXPECTED_VALUE1 * TEST_EXPECTED_VALUE5);
573 
574     ani_int sumB = 0;
575     ani_value argsB[TEST_EXPECTED_VALUE6];
576     argsB[0U].i = TEST_EXPECTED_VALUE1;
577     argsB[1U].i = TEST_EXPECTED_VALUE1;
578     argsB[2U].i = TEST_EXPECTED_VALUE5;
579     ASSERT_EQ(env_->Class_CallStaticMethod_Int_A(cls, methodB, &sumB, argsB), ANI_OK);
580     ASSERT_EQ(sumB, TEST_EXPECTED_VALUE1 * TEST_EXPECTED_VALUE1 * TEST_EXPECTED_VALUE5);
581 }
582 
TEST_F(ClassFindMethodTest,static_method_find_static_method_003)583 TEST_F(ClassFindMethodTest, static_method_find_static_method_003)
584 {
585     ani_class cls {};
586     ASSERT_EQ(env_->FindClass("Ltest/ClassA;", &cls), ANI_OK);
587     ASSERT_NE(cls, nullptr);
588 
589     ani_static_method methodB {};
590     ASSERT_EQ(env_->Class_FindStaticMethod(cls, "sumB", "III:I", &methodB), ANI_OK);
591     ASSERT_NE(methodB, nullptr);
592 
593     ani_int sumB = 0;
594     ani_value argsB[TEST_EXPECTED_VALUE6];
595     argsB[0].i = TEST_EXPECTED_VALUE1;
596     argsB[1].i = TEST_EXPECTED_VALUE1;
597     argsB[2U].i = TEST_EXPECTED_VALUE5;
598     ASSERT_EQ(env_->Class_CallStaticMethod_Int_A(cls, methodB, &sumB, argsB), ANI_OK);
599     ASSERT_EQ(sumB, TEST_EXPECTED_VALUE1 + TEST_EXPECTED_VALUE1 + TEST_EXPECTED_VALUE5);
600 }
601 
TEST_F(ClassFindMethodTest,static_method_find_static_method_004)602 TEST_F(ClassFindMethodTest, static_method_find_static_method_004)
603 {
604     ani_class cls {};
605     ASSERT_EQ(env_->FindClass("Ltest/ClassB;", &cls), ANI_OK);
606     ASSERT_NE(cls, nullptr);
607 
608     ani_static_method methodA {};
609     ASSERT_EQ(env_->Class_FindStaticMethod(cls, "sumA", "II:I", &methodA), ANI_OK);
610     ASSERT_NE(methodA, nullptr);
611 
612     ani_int sumB = 0;
613     ani_value args[2U];
614     args[0].i = TEST_EXPECTED_VALUE1;
615     args[1].i = TEST_EXPECTED_VALUE5;
616     ASSERT_EQ(env_->Class_CallStaticMethod_Int_A(cls, methodA, &sumB, args), ANI_OK);
617     ASSERT_EQ(sumB, TEST_EXPECTED_VALUE1 + TEST_EXPECTED_VALUE5);
618 }
619 
TEST_F(ClassFindMethodTest,static_method_find_static_method_005)620 TEST_F(ClassFindMethodTest, static_method_find_static_method_005)
621 {
622     ani_class cls {};
623     ASSERT_EQ(env_->FindClass("Ltest/ClassA;", &cls), ANI_OK);
624     ASSERT_NE(cls, nullptr);
625 
626     ani_static_method methodA {};
627     ASSERT_EQ(env_->Class_FindStaticMethod(cls, "calculateSquareArea", "II:I", &methodA), ANI_OK);
628     ASSERT_NE(methodA, nullptr);
629 
630     ani_int sumA = 0;
631     ani_value args[2U];
632     args[0].i = TEST_EXPECTED_VALUE1;
633     args[1].i = TEST_EXPECTED_VALUE5;
634     ASSERT_EQ(env_->Class_CallStaticMethod_Int_A(cls, methodA, &sumA, args), ANI_OK);
635     ASSERT_EQ(sumA, TEST_EXPECTED_VALUE1 * TEST_EXPECTED_VALUE5);
636 }
637 
TEST_F(ClassFindMethodTest,static_method_find_static_method_006)638 TEST_F(ClassFindMethodTest, static_method_find_static_method_006)
639 {
640     ani_class cls {};
641     ASSERT_EQ(env_->FindClass("Ltest/BasicCalculator;", &cls), ANI_OK);
642     ASSERT_NE(cls, nullptr);
643 
644     ani_static_method staticMethod {};
645     ASSERT_EQ(env_->Class_FindStaticMethod(cls, "multiply", "II:I", &staticMethod), ANI_OK);
646     ASSERT_NE(staticMethod, nullptr);
647     ani_int multiply = 0;
648     ASSERT_EQ(
649         env_->Class_CallStaticMethod_Int(cls, staticMethod, &multiply, TEST_EXPECTED_VALUE1, TEST_EXPECTED_VALUE5),
650         ANI_OK);
651     ASSERT_EQ(multiply, TEST_EXPECTED_VALUE1 * TEST_EXPECTED_VALUE5);
652 
653     ani_class subCls {};
654     ASSERT_EQ(env_->FindClass("Ltest/SubCalculator;", &subCls), ANI_OK);
655     ASSERT_NE(subCls, nullptr);
656 
657     ani_method constructorMethod {};
658     ASSERT_EQ(env_->Class_FindMethod(cls, "<ctor>", nullptr, &constructorMethod), ANI_OK);
659     ASSERT_NE(constructorMethod, nullptr);
660 
661     ani_method addNormalMethod {};
662     ASSERT_EQ(env_->Class_FindMethod(subCls, "add", nullptr, &addNormalMethod), ANI_OK);
663     ASSERT_NE(addNormalMethod, nullptr);
664 
665     ani_object object1 {};
666     ASSERT_EQ(env_->Object_New(subCls, constructorMethod, &object1, 5U, 6U), ANI_OK);
667     ASSERT_NE(object1, nullptr);
668     ani_int result = 0;
669     ani_value args[2U];
670     args[0U].i = TEST_EXPECTED_VALUE1;
671     args[1U].i = TEST_EXPECTED_VALUE5;
672     ASSERT_EQ(env_->Object_CallMethod_Int_A(object1, addNormalMethod, &result, args), ANI_OK);
673     ASSERT_EQ(result, TEST_EXPECTED_VALUE1 + TEST_EXPECTED_VALUE5);
674 
675     ani_static_method subStaticMethod {};
676     ASSERT_EQ(env_->Class_FindStaticMethod(subCls, "divide", nullptr, &subStaticMethod), ANI_OK);
677     ASSERT_NE(subStaticMethod, nullptr);
678 
679     ani_int divideResult = 0;
680     ani_value args2[2U];
681     args2[0U].i = TEST_EXPECTED_VALUE5;
682     args2[1U].i = TEST_EXPECTED_VALUE6;
683     ASSERT_EQ(env_->Class_CallStaticMethod_Int_A(cls, subStaticMethod, &divideResult, args2), ANI_OK);
684     ASSERT_EQ(divideResult, TEST_EXPECTED_VALUE5 / TEST_EXPECTED_VALUE6);
685 }
686 
TEST_F(ClassFindMethodTest,find_method_combine_scenes_002)687 TEST_F(ClassFindMethodTest, find_method_combine_scenes_002)
688 {
689     ani_namespace ns {};
690     ASSERT_EQ(env_->FindNamespace("Ltest/test002A;", &ns), ANI_OK);
691     ASSERT_NE(ns, nullptr);
692 
693     ani_namespace result {};
694     ASSERT_EQ(env_->Namespace_FindNamespace(ns, "Ltest002B;", &result), ANI_OK);
695     ASSERT_NE(result, nullptr);
696 
697     ani_class cls {};
698     ASSERT_EQ(env_->Namespace_FindClass(result, "LTestA002;", &cls), ANI_OK);
699     ASSERT_NE(cls, nullptr);
700 
701     ani_method method {};
702     ASSERT_EQ(env_->Class_FindMethod(cls, "sum", "II:I", &method), ANI_OK);
703     ASSERT_NE(method, nullptr);
704 
705     ani_object object {};
706     ASSERT_EQ(env_->Object_New(cls, method, &object, TEST_EXPECTED_VALUE1, TEST_EXPECTED_VALUE5), ANI_OK);
707     ASSERT_NE(object, nullptr);
708 
709     ani_value args[2U];
710     ani_int arg1 = TEST_EXPECTED_VALUE4;
711     ani_int arg2 = TEST_EXPECTED_VALUE6;
712     args[0U].i = arg1;
713     args[1U].i = arg2;
714     ani_int sum = 0;
715     ASSERT_EQ(env_->Object_CallMethod_Int_A(object, method, &sum, args), ANI_OK);
716     ASSERT_EQ(sum, arg1 + arg2);
717 }
718 
TEST_F(ClassFindMethodTest,find_method_combine_scenes_003)719 TEST_F(ClassFindMethodTest, find_method_combine_scenes_003)
720 {
721     ani_class cls {};
722     ASSERT_EQ(env_->FindClass("Ltest/TestA003;", &cls), ANI_OK);
723     ASSERT_NE(cls, nullptr);
724 
725     ani_method constructorMethod {};
726     ASSERT_EQ(env_->Class_FindMethod(cls, "<ctor>", nullptr, &constructorMethod), ANI_OK);
727     ASSERT_NE(constructorMethod, nullptr);
728 
729     ani_method publicMethod {};
730     ASSERT_EQ(env_->Class_FindMethod(cls, "int_method", nullptr, &publicMethod), ANI_OK);
731     ASSERT_NE(publicMethod, nullptr);
732 
733     ani_method protectedMethod {};
734     ASSERT_EQ(env_->Class_FindMethod(cls, "float_method", nullptr, &protectedMethod), ANI_OK);
735     ASSERT_NE(protectedMethod, nullptr);
736 
737     ani_method privateMethod {};
738     ASSERT_EQ(env_->Class_FindMethod(cls, "bool_method", nullptr, &privateMethod), ANI_OK);
739     ASSERT_NE(privateMethod, nullptr);
740 
741     ani_object object {};
742     ASSERT_EQ(env_->Object_New(cls, constructorMethod, &object, TEST_EXPECTED_VALUE1, TEST_EXPECTED_VALUE5), ANI_OK);
743     ASSERT_NE(object, nullptr);
744 
745     ani_value args[2U];
746     ani_int arg1 = TEST_EXPECTED_VALUE4;
747     ani_int arg2 = TEST_EXPECTED_VALUE6;
748     args[0U].i = arg1;
749     args[1U].i = arg2;
750     ani_int publicResult = 0;
751     ASSERT_EQ(env_->Object_CallMethod_Int_A(object, publicMethod, &publicResult, args), ANI_OK);
752     ASSERT_EQ(publicResult, arg1 * arg2);
753 
754     ani_value args2[2U];
755     ani_float arg3 = TEST_ARG5;
756     ani_float arg4 = TEST_ARG6;
757     args2[0U].f = arg3;
758     args2[1U].f = arg4;
759     ani_float protectedResult = 0.F;
760     ASSERT_EQ(env_->Object_CallMethod_Float_A(object, protectedMethod, &protectedResult, args2), ANI_OK);
761     ASSERT_FLOAT_EQ(protectedResult, arg3 + arg4);
762 
763     ani_boolean privateResult = ANI_FALSE;
764     ani_value args3[2U];
765     args3[0U].z = ANI_TRUE;
766     args3[1U].z = ANI_FALSE;
767     ASSERT_EQ(env_->Object_CallMethod_Boolean_A(object, privateMethod, &privateResult, args3), ANI_OK);
768     ASSERT_EQ(privateResult, ANI_TRUE);
769 }
770 
TEST_F(ClassFindMethodTest,find_method_combine_scenes_004)771 TEST_F(ClassFindMethodTest, find_method_combine_scenes_004)
772 {
773     ani_class cls {};
774     ASSERT_EQ(env_->FindClass("Ltest/TestA004;", &cls), ANI_OK);
775     ASSERT_NE(cls, nullptr);
776 
777     ani_method constructorMethod {};
778     ASSERT_EQ(env_->Class_FindMethod(cls, "<ctor>", nullptr, &constructorMethod), ANI_OK);
779     ASSERT_NE(constructorMethod, nullptr);
780 
781     ani_method funcAMethod {};
782     ASSERT_EQ(env_->Class_FindMethod(cls, "int_method", nullptr, &funcAMethod), ANI_OK);
783     ASSERT_NE(funcAMethod, nullptr);
784 
785     ani_method funcBMethod {};
786     ASSERT_EQ(env_->Class_FindMethod(cls, "float_method", nullptr, &funcBMethod), ANI_OK);
787     ASSERT_NE(funcBMethod, nullptr);
788 
789     ani_method funcCMethod {};
790     ASSERT_EQ(env_->Class_FindMethod(cls, "bool_method", nullptr, &funcCMethod), ANI_OK);
791     ASSERT_NE(funcCMethod, nullptr);
792 
793     ani_object object {};
794     ASSERT_EQ(env_->Object_New(cls, constructorMethod, &object, TEST_EXPECTED_VALUE1, TEST_EXPECTED_VALUE5), ANI_OK);
795     ASSERT_NE(object, nullptr);
796 
797     ani_value args[2U];
798     ani_int arg1 = TEST_EXPECTED_VALUE4;
799     ani_int arg2 = TEST_EXPECTED_VALUE6;
800     args[0U].i = arg1;
801     args[1U].i = arg2;
802     ani_int funAResult = 0;
803     ASSERT_EQ(env_->Object_CallMethod_Int_A(object, funcAMethod, &funAResult, args), ANI_OK);
804     ASSERT_EQ(funAResult, arg1 * arg2);
805 
806     ani_value args2[2U];
807     ani_float arg3 = TEST_ARG5;
808     ani_float arg4 = TEST_ARG6;
809     args2[0U].f = arg3;
810     args2[1U].f = arg4;
811     ani_float funBResult = 0.F;
812     ASSERT_EQ(env_->Object_CallMethod_Float_A(object, funcBMethod, &funBResult, args2), ANI_OK);
813     ASSERT_FLOAT_EQ(funBResult, arg3 + arg4);
814 
815     ani_boolean funCResult = ANI_FALSE;
816     ani_value args3[2U];
817     args3[0U].z = ANI_TRUE;
818     args3[1U].z = ANI_FALSE;
819     ASSERT_EQ(env_->Object_CallMethod_Boolean_A(object, funcCMethod, &funCResult, args3), ANI_OK);
820     ASSERT_EQ(funCResult, ANI_TRUE);
821 }
822 
TEST_F(ClassFindMethodTest,find_method_combine_scenes_005)823 TEST_F(ClassFindMethodTest, find_method_combine_scenes_005)
824 {
825     ani_class cls {};
826     ASSERT_EQ(env_->FindClass("Ltest/TestA005;", &cls), ANI_OK);
827     ASSERT_NE(cls, nullptr);
828 
829     ani_method constructorMethod {};
830     ASSERT_EQ(env_->Class_FindMethod(cls, "<ctor>", nullptr, &constructorMethod), ANI_OK);
831     ASSERT_NE(constructorMethod, nullptr);
832 
833     ani_method method {};
834     ASSERT_EQ(env_->Class_FindMethod(cls, "int_method", nullptr, &method), ANI_OK);
835     ASSERT_NE(method, nullptr);
836 
837     ani_object object {};
838     ASSERT_EQ(env_->Object_New(cls, constructorMethod, &object), ANI_OK);
839     ASSERT_NE(object, nullptr);
840 
841     ani_value args[2U];
842     ani_int arg1 = TEST_EXPECTED_VALUE4;
843     ani_int arg2 = TEST_EXPECTED_VALUE6;
844     args[0U].i = arg1;
845     args[1U].i = arg2;
846     ani_int result = 0;
847     ASSERT_EQ(env_->Object_CallMethod_Int_A(object, method, &result, args), ANI_OK);
848     ASSERT_EQ(result, arg1 + arg2);
849 }
850 
TEST_F(ClassFindMethodTest,find_method_combine_scenes_006)851 TEST_F(ClassFindMethodTest, find_method_combine_scenes_006)
852 {
853     ani_class cls {};
854     ASSERT_EQ(env_->FindClass("Ltest/Child;", &cls), ANI_OK);
855     ASSERT_NE(cls, nullptr);
856 
857     ani_method constructorMethod {};
858     ASSERT_EQ(env_->Class_FindMethod(cls, "<ctor>", nullptr, &constructorMethod), ANI_OK);
859     ASSERT_NE(constructorMethod, nullptr);
860 
861     ani_method method {};
862     ASSERT_EQ(env_->Class_FindMethod(cls, "add_method", nullptr, &method), ANI_OK);
863     ASSERT_NE(method, nullptr);
864 
865     ani_object object {};
866     ASSERT_EQ(env_->Object_New(cls, constructorMethod, &object), ANI_OK);
867     ASSERT_NE(object, nullptr);
868 
869     ani_value args[2U];
870     ani_int arg1 = TEST_EXPECTED_VALUE4;
871     ani_int arg2 = TEST_EXPECTED_VALUE6;
872     args[0U].i = arg1;
873     args[1U].i = arg2;
874     ani_int result = 0;
875     ASSERT_EQ(env_->Object_CallMethod_Int_A(object, method, &result, args), ANI_OK);
876     ASSERT_EQ(result, arg1 * arg2);
877 }
878 
TEST_F(ClassFindMethodTest,find_method_combine_scenes_007)879 TEST_F(ClassFindMethodTest, find_method_combine_scenes_007)
880 {
881     ani_class cls {};
882     ASSERT_EQ(env_->FindClass("Ltest/Student;", &cls), ANI_OK);
883     ASSERT_NE(cls, nullptr);
884 
885     ani_method constructorMethod {};
886     ASSERT_EQ(env_->Class_FindMethod(cls, "<ctor>", nullptr, &constructorMethod), ANI_OK);
887     ASSERT_NE(constructorMethod, nullptr);
888 
889     ani_method method {};
890     ASSERT_EQ(env_->Class_FindMethod(cls, "add_method", nullptr, &method), ANI_OK);
891     ASSERT_NE(method, nullptr);
892 
893     ani_object object {};
894     ASSERT_EQ(env_->Object_New(cls, constructorMethod, &object), ANI_OK);
895     ASSERT_NE(object, nullptr);
896 
897     ani_value args[2U];
898     ani_int arg1 = TEST_EXPECTED_VALUE4;
899     ani_int arg2 = TEST_EXPECTED_VALUE6;
900     args[0U].i = arg1;
901     args[1U].i = arg2;
902     ani_int result = 0;
903     ASSERT_EQ(env_->Object_CallMethod_Int_A(object, method, &result, args), ANI_OK);
904     ASSERT_EQ(result, arg1 + arg2);
905 }
906 
TEST_F(ClassFindMethodTest,find_method_combine_scenes_008)907 TEST_F(ClassFindMethodTest, find_method_combine_scenes_008)
908 {
909     ani_class clsB {};
910     ASSERT_EQ(env_->FindClass("Ltest/TestB008;", &clsB), ANI_OK);
911     ASSERT_NE(clsB, nullptr);
912 
913     ani_class clsA {};
914     ASSERT_EQ(env_->FindClass("Ltest/TestA008;", &clsA), ANI_OK);
915     ASSERT_NE(clsA, nullptr);
916 
917     ani_method constructorMethodB {};
918     ASSERT_EQ(env_->Class_FindMethod(clsB, "<ctor>", nullptr, &constructorMethodB), ANI_OK);
919     ASSERT_NE(constructorMethodB, nullptr);
920 
921     ani_method constructorMethodA {};
922     ASSERT_EQ(env_->Class_FindMethod(clsA, "<ctor>", nullptr, &constructorMethodA), ANI_OK);
923     ASSERT_NE(constructorMethodA, nullptr);
924 
925     ani_method method {};
926     ASSERT_EQ(env_->Class_FindMethod(clsB, "int_method", "Ltest/TestA008;:I", &method), ANI_OK);
927     ASSERT_NE(method, nullptr);
928 
929     ani_object objectB {};
930     ASSERT_EQ(env_->Object_New(clsB, constructorMethodB, &objectB), ANI_OK);
931     ASSERT_NE(objectB, nullptr);
932 
933     ani_object objectA {};
934     ASSERT_EQ(env_->Object_New(clsA, constructorMethodA, &objectA), ANI_OK);
935     ASSERT_NE(objectA, nullptr);
936 
937     ani_value args[1];
938     args[0].r = objectA;
939     ani_int result = 0;
940     ASSERT_EQ(env_->Object_CallMethod_Int_A(objectB, method, &result, args), ANI_OK);
941     ASSERT_EQ(result, 66U);
942 }
943 
TEST_F(ClassFindMethodTest,find_func_abstract)944 TEST_F(ClassFindMethodTest, find_func_abstract)
945 {
946     ani_class cls {};
947     ASSERT_EQ(env_->FindClass("Ltest/CombineA;", &cls), ANI_OK);
948     ASSERT_NE(cls, nullptr);
949     ani_method method {};
950     ASSERT_EQ(env_->Class_FindMethod(cls, "func", "II:I", &method), ANI_OK);
951     ASSERT_NE(method, nullptr);
952 
953     ani_class clsB {};
954     ASSERT_EQ(env_->FindClass("Ltest/CombineB;", &clsB), ANI_OK);
955     ASSERT_NE(clsB, nullptr);
956     ani_method ctor {};
957     ASSERT_EQ(env_->Class_FindMethod(cls, "<ctor>", ":V", &ctor), ANI_OK);
958 
959     ani_object object {};
960     ASSERT_EQ(env_->Object_New(clsB, ctor, &object), ANI_OK);
961     ani_value args[2];  // NOLINT(modernize-avoid-c-arrays)
962     args[0].i = TEST_EXPECTED_VALUE4;
963     args[1].i = TEST_EXPECTED_VALUE6;
964 
965     ani_int res = 0;
966     // Call the method and verify the return value.
967     ASSERT_EQ(env_->Object_CallMethod_Int_A(object, method, &res, args), ANI_OK);
968     ASSERT_EQ(res, TEST_EXPECTED_VALUE4 - TEST_EXPECTED_VALUE6);
969 }
970 
TEST_F(ClassFindMethodTest,find_func_final)971 TEST_F(ClassFindMethodTest, find_func_final)
972 {
973     ani_class cls {};
974     ASSERT_EQ(env_->FindClass("Ltest/AF;", &cls), ANI_OK);
975     ASSERT_NE(cls, nullptr);
976     ani_method method {};
977     ASSERT_EQ(env_->Class_FindMethod(cls, "func", "II:I", &method), ANI_OK);
978     ASSERT_NE(method, nullptr);
979 
980     ani_method ctor {};
981     ASSERT_EQ(env_->Class_FindMethod(cls, "<ctor>", ":V", &ctor), ANI_OK);
982 
983     ani_object object {};
984     ASSERT_EQ(env_->Object_New(cls, ctor, &object), ANI_OK);
985     ani_value args[2];  // NOLINT(modernize-avoid-c-arrays)
986     args[0].i = TEST_EXPECTED_VALUE4;
987     args[1].i = TEST_EXPECTED_VALUE6;
988 
989     ani_int res = 0;
990     // Call the method and verify the return value.
991     ASSERT_EQ(env_->Object_CallMethod_Int_A(object, method, &res, args), ANI_OK);
992     ASSERT_EQ(res, TEST_EXPECTED_VALUE4 + TEST_EXPECTED_VALUE6);
993 }
994 
TEST_F(ClassFindMethodTest,find_func_in_class_c)995 TEST_F(ClassFindMethodTest, find_func_in_class_c)
996 {
997     ani_class cls {};
998     ASSERT_EQ(env_->FindClass("Ltest/CombineC;", &cls), ANI_OK);
999     ASSERT_NE(cls, nullptr);
1000     ani_method method {};
1001     ASSERT_EQ(env_->Class_FindMethod(cls, "func", "II:I", &method), ANI_OK);
1002     ASSERT_NE(method, nullptr);
1003 
1004     ani_method ctor {};
1005     ASSERT_EQ(env_->Class_FindMethod(cls, "<ctor>", ":V", &ctor), ANI_OK);
1006 
1007     ani_object object {};
1008     ASSERT_EQ(env_->Object_New(cls, ctor, &object), ANI_OK);
1009     ani_value args[2];  // NOLINT(modernize-avoid-c-arrays)
1010     args[0].i = TEST_EXPECTED_VALUE4;
1011     args[1].i = TEST_EXPECTED_VALUE6;
1012 
1013     ani_int res = 0;
1014     // Call the method and verify the return value.
1015     ASSERT_EQ(env_->Object_CallMethod_Int_A(object, method, &res, args), ANI_OK);
1016     ASSERT_EQ(res, TEST_EXPECTED_VALUE4 - TEST_EXPECTED_VALUE6 - 1);
1017 }
1018 
TEST_F(ClassFindMethodTest,find_func_in_namespace)1019 TEST_F(ClassFindMethodTest, find_func_in_namespace)
1020 {
1021     ani_class cls {};
1022     ASSERT_EQ(env_->FindClass("Ltest/nsa/nsb/A;", &cls), ANI_OK);
1023     ASSERT_NE(cls, nullptr);
1024     ani_method method {};
1025     ASSERT_EQ(env_->Class_FindMethod(cls, "func", "II:I", &method), ANI_OK);
1026     ASSERT_NE(method, nullptr);
1027 
1028     ani_method ctor {};
1029     ASSERT_EQ(env_->Class_FindMethod(cls, "<ctor>", ":V", &ctor), ANI_OK);
1030 
1031     ani_object object {};
1032     ASSERT_EQ(env_->Object_New(cls, ctor, &object), ANI_OK);
1033     ani_value args[2];  // NOLINT(modernize-avoid-c-arrays)
1034     args[0].i = TEST_EXPECTED_VALUE4;
1035     args[1].i = TEST_EXPECTED_VALUE6;
1036 
1037     ani_int res = 0;
1038     // Call the method and verify the return value.
1039     ASSERT_EQ(env_->Object_CallMethod_Int_A(object, method, &res, args), ANI_OK);
1040     ASSERT_EQ(res, TEST_EXPECTED_VALUE4 + TEST_EXPECTED_VALUE6);
1041 }
1042 
TEST_F(ClassFindMethodTest,duplicate_no_signature)1043 TEST_F(ClassFindMethodTest, duplicate_no_signature)
1044 {
1045     ani_class baseCls {};
1046     ASSERT_EQ(env_->FindClass("Ltest/A;", &baseCls), ANI_OK);
1047     ASSERT_NE(baseCls, nullptr);
1048 
1049     ani_method method {};
1050     ASSERT_EQ(env_->Class_FindMethod(baseCls, "overloadedBase", nullptr, &method), ANI_AMBIGUOUS);
1051 
1052     ani_class cls;
1053     ASSERT_EQ(env_->FindClass("Ltest/B;", &cls), ANI_OK);
1054     ASSERT_NE(cls, nullptr);
1055     ASSERT_EQ(env_->Class_FindMethod(cls, "overloadedBase", nullptr, &method), ANI_AMBIGUOUS);
1056     ASSERT_EQ(env_->Class_FindMethod(cls, "overloaded", nullptr, &method), ANI_AMBIGUOUS);
1057 }
1058 
TEST_F(ClassFindMethodTest,static_duplicate_no_signature)1059 TEST_F(ClassFindMethodTest, static_duplicate_no_signature)
1060 {
1061     ani_class baseCls {};
1062     ASSERT_EQ(env_->FindClass("Ltest/A;", &baseCls), ANI_OK);
1063     ASSERT_NE(baseCls, nullptr);
1064 
1065     ani_static_method method {};
1066     ASSERT_EQ(env_->Class_FindStaticMethod(baseCls, "staticOverloadedBase", nullptr, &method), ANI_AMBIGUOUS);
1067 
1068     ani_class cls;
1069     ASSERT_EQ(env_->FindClass("Ltest/B;", &cls), ANI_OK);
1070     ASSERT_NE(cls, nullptr);
1071     ASSERT_EQ(env_->Class_FindStaticMethod(cls, "staticOverloadedBase", nullptr, &method), ANI_AMBIGUOUS);
1072     ASSERT_EQ(env_->Class_FindStaticMethod(cls, "staticOverloaded", nullptr, &method), ANI_AMBIGUOUS);
1073 }
1074 
TEST_F(ClassFindMethodTest,same_name_static_virtual_function)1075 TEST_F(ClassFindMethodTest, same_name_static_virtual_function)
1076 {
1077     ani_class cls {};
1078     ASSERT_EQ(env_->FindClass("Ltest/AllFunctions;", &cls), ANI_OK);
1079     ASSERT_NE(cls, nullptr);
1080 
1081     ani_method ctor {};
1082     ASSERT_EQ(env_->Class_FindMethod(cls, "<ctor>", ":V", &ctor), ANI_OK);
1083     ASSERT_NE(ctor, nullptr);
1084 
1085     ani_static_method staticMethod {};
1086     ASSERT_EQ(env_->Class_FindStaticMethod(cls, "foo", ":I", &staticMethod), ANI_OK);
1087     ASSERT_NE(staticMethod, nullptr);
1088 
1089     ani_method method {};
1090     ASSERT_EQ(env_->Class_FindMethod(cls, "foo", ":I", &method), ANI_OK);
1091     ASSERT_NE(method, nullptr);
1092 
1093     ani_object object {};
1094     ASSERT_EQ(env_->Object_New(cls, ctor, &object), ANI_OK);
1095     ASSERT_NE(object, nullptr);
1096 
1097     ani_int fooVal {};
1098     ASSERT_EQ(env_->Object_CallMethod_Int(object, method, &fooVal), ANI_OK);
1099     ASSERT_EQ(fooVal, 43U);
1100 
1101     ani_int staticFooVal {};
1102     ASSERT_EQ(env_->Class_CallStaticMethod_Int(cls, staticMethod, &staticFooVal), ANI_OK);
1103     ASSERT_EQ(staticFooVal, 42U);
1104 }
1105 
TEST_F(ClassFindMethodTest,no_static_virtual_function)1106 TEST_F(ClassFindMethodTest, no_static_virtual_function)
1107 {
1108     ani_class cls {};
1109     ASSERT_EQ(env_->FindClass("Ltest/MixedFunctions;", &cls), ANI_OK);
1110     ASSERT_NE(cls, nullptr);
1111 
1112     ani_static_method staticMethod {};
1113     ASSERT_EQ(env_->Class_FindStaticMethod(cls, "bar", ":I", &staticMethod), ANI_NOT_FOUND);
1114 
1115     ani_method method {};
1116     ASSERT_EQ(env_->Class_FindMethod(cls, "foo", ":I", &method), ANI_NOT_FOUND);
1117 }
1118 
TEST_F(ClassFindMethodTest,static_no_duplicate)1119 TEST_F(ClassFindMethodTest, static_no_duplicate)
1120 {
1121     ani_class baseCls {};
1122     ASSERT_EQ(env_->FindClass("Ltest/NotOverloaded;", &baseCls), ANI_OK);
1123     ASSERT_NE(baseCls, nullptr);
1124 
1125     ani_static_method smethod {};
1126     ASSERT_EQ(env_->Class_FindStaticMethod(baseCls, "notOverloaded", nullptr, &smethod), ANI_OK);
1127 
1128     ani_method method {};
1129     ASSERT_EQ(env_->Class_FindMethod(baseCls, "notOverloaded", nullptr, &method), ANI_OK);
1130 }
1131 
TEST_F(ClassFindMethodTest,check_initalization)1132 TEST_F(ClassFindMethodTest, check_initalization)
1133 {
1134     ani_class cls {};
1135     ASSERT_EQ(env_->FindClass("test.NotOverloaded", &cls), ANI_OK);
1136 
1137     ASSERT_FALSE(IsRuntimeClassInitialized("test.NotOverloaded"));
1138     ani_method method {};
1139     ASSERT_EQ(env_->Class_FindMethod(cls, "notOverloaded", nullptr, &method), ANI_OK);
1140     ASSERT_FALSE(IsRuntimeClassInitialized("test.NotOverloaded"));
1141 }
1142 
1143 }  // namespace ark::ets::ani::testing
1144 // NOLINTEND(cppcoreguidelines-pro-type-vararg, modernize-avoid-c-arrays)
1145