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, ¶ms), 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, ÷Result, 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