xref: /aosp_15_r20/external/fbjni/test/jni/iterator_tests.cpp (revision 65c59e023c5336bbd4a23be7af78407e3d80e7e7)
1*65c59e02SInna Palant /*
2*65c59e02SInna Palant  * Copyright (c) Facebook, Inc. and its affiliates.
3*65c59e02SInna Palant  *
4*65c59e02SInna Palant  * Licensed under the Apache License, Version 2.0 (the "License");
5*65c59e02SInna Palant  * you may not use this file except in compliance with the License.
6*65c59e02SInna Palant  * You may obtain a copy of the License at
7*65c59e02SInna Palant  *
8*65c59e02SInna Palant  *     http://www.apache.org/licenses/LICENSE-2.0
9*65c59e02SInna Palant  *
10*65c59e02SInna Palant  * Unless required by applicable law or agreed to in writing, software
11*65c59e02SInna Palant  * distributed under the License is distributed on an "AS IS" BASIS,
12*65c59e02SInna Palant  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*65c59e02SInna Palant  * See the License for the specific language governing permissions and
14*65c59e02SInna Palant  * limitations under the License.
15*65c59e02SInna Palant  */
16*65c59e02SInna Palant 
17*65c59e02SInna Palant #include <algorithm>
18*65c59e02SInna Palant #include <unordered_map>
19*65c59e02SInna Palant #include <unordered_set>
20*65c59e02SInna Palant #include <vector>
21*65c59e02SInna Palant 
22*65c59e02SInna Palant #include <fbjni/fbjni.h>
23*65c59e02SInna Palant 
24*65c59e02SInna Palant #include "expect.h"
25*65c59e02SInna Palant 
26*65c59e02SInna Palant using namespace facebook::jni;
27*65c59e02SInna Palant 
nativeTestListIterator(alias_ref<jclass>,alias_ref<JList<jstring>> jlist)28*65c59e02SInna Palant jboolean nativeTestListIterator(
29*65c59e02SInna Palant     alias_ref<jclass>,
30*65c59e02SInna Palant     alias_ref<JList<jstring>> jlist) {
31*65c59e02SInna Palant   EXPECT(jlist);
32*65c59e02SInna Palant 
33*65c59e02SInna Palant   EXPECT(jlist->size() == 3);
34*65c59e02SInna Palant 
35*65c59e02SInna Palant   std::vector<std::string> vs1;
36*65c59e02SInna Palant   for (const auto& elem : *jlist) {
37*65c59e02SInna Palant     vs1.push_back(elem->toStdString());
38*65c59e02SInna Palant   }
39*65c59e02SInna Palant 
40*65c59e02SInna Palant   EXPECT(vs1.size() == 3);
41*65c59e02SInna Palant   EXPECT(vs1[0] == "red");
42*65c59e02SInna Palant   EXPECT(vs1[1] == "green");
43*65c59e02SInna Palant   EXPECT(vs1[2] == "blue");
44*65c59e02SInna Palant 
45*65c59e02SInna Palant   std::vector<std::string> vs2;
46*65c59e02SInna Palant   std::transform(
47*65c59e02SInna Palant       jlist->begin(),
48*65c59e02SInna Palant       jlist->end(),
49*65c59e02SInna Palant       std::back_inserter(vs2),
50*65c59e02SInna Palant       [](local_ref<jstring> elem) { return elem->toStdString(); });
51*65c59e02SInna Palant 
52*65c59e02SInna Palant   EXPECT(vs1 == vs2);
53*65c59e02SInna Palant 
54*65c59e02SInna Palant   std::vector<std::string> vs3 = {"red", "green", "blue"};
55*65c59e02SInna Palant 
56*65c59e02SInna Palant   EXPECT(vs1 == vs3);
57*65c59e02SInna Palant 
58*65c59e02SInna Palant   static auto iteratorMethod =
59*65c59e02SInna Palant       JIterable<jstring>::javaClassStatic()->getMethod<JIterator<jstring>()>(
60*65c59e02SInna Palant           "iterator");
61*65c59e02SInna Palant   auto iter = iteratorMethod(jlist);
62*65c59e02SInna Palant 
63*65c59e02SInna Palant   EXPECT(std::equal(iter->begin(), iter->end(), jlist->begin()));
64*65c59e02SInna Palant   EXPECT(std::equal(
65*65c59e02SInna Palant       iter->begin(),
66*65c59e02SInna Palant       iter->end(),
67*65c59e02SInna Palant       vs3.begin(),
68*65c59e02SInna Palant       [](const local_ref<jstring>& a, const std::string& b) {
69*65c59e02SInna Palant         return a->toStdString() == b;
70*65c59e02SInna Palant       }));
71*65c59e02SInna Palant 
72*65c59e02SInna Palant   return JNI_TRUE;
73*65c59e02SInna Palant }
74*65c59e02SInna Palant 
nativeTestMapIterator(alias_ref<jclass>,alias_ref<JMap<jstring,JInteger>> jmap)75*65c59e02SInna Palant jboolean nativeTestMapIterator(
76*65c59e02SInna Palant     alias_ref<jclass>,
77*65c59e02SInna Palant     alias_ref<JMap<jstring, JInteger>> jmap) {
78*65c59e02SInna Palant   EXPECT(jmap);
79*65c59e02SInna Palant 
80*65c59e02SInna Palant   EXPECT(jmap->size() == 3);
81*65c59e02SInna Palant 
82*65c59e02SInna Palant   std::unordered_map<std::string, int> umap;
83*65c59e02SInna Palant 
84*65c59e02SInna Palant   for (const auto& entry : *jmap) {
85*65c59e02SInna Palant     umap[entry.first->toStdString()] = entry.second->intValue();
86*65c59e02SInna Palant   }
87*65c59e02SInna Palant 
88*65c59e02SInna Palant   EXPECT(umap.size() == 3);
89*65c59e02SInna Palant 
90*65c59e02SInna Palant   EXPECT(umap["one"] == 1);
91*65c59e02SInna Palant   EXPECT(umap["two"] == 2);
92*65c59e02SInna Palant   EXPECT(umap["four"] == 4);
93*65c59e02SInna Palant 
94*65c59e02SInna Palant   // For an empty map, any types will do; the cast will only happen on null
95*65c59e02SInna Palant   // pointers, which will always succeed.
96*65c59e02SInna Palant   typedef JHashMap<jclass, jthrowable> TestMap;
97*65c59e02SInna Palant 
98*65c59e02SInna Palant   static auto testmapCtor =
99*65c59e02SInna Palant       TestMap::javaClassStatic()->getConstructor<TestMap::javaobject()>();
100*65c59e02SInna Palant   auto emptyMap = TestMap::javaClassStatic()->newObject(testmapCtor);
101*65c59e02SInna Palant   EXPECT(emptyMap->size() == 0);
102*65c59e02SInna Palant 
103*65c59e02SInna Palant   JHashMap<jclass, jthrowable>::Iterator i1 = emptyMap->begin();
104*65c59e02SInna Palant   JHashMap<jclass, jthrowable>::Iterator i2 = emptyMap->end();
105*65c59e02SInna Palant 
106*65c59e02SInna Palant   EXPECT(i1 == i2);
107*65c59e02SInna Palant 
108*65c59e02SInna Palant   return JNI_TRUE;
109*65c59e02SInna Palant }
110*65c59e02SInna Palant 
nativeTestIterateWrongType(alias_ref<jclass>,alias_ref<JMap<jstring,JInteger::javaobject>> jmap)111*65c59e02SInna Palant jboolean nativeTestIterateWrongType(
112*65c59e02SInna Palant     alias_ref<jclass>,
113*65c59e02SInna Palant     alias_ref<JMap<jstring, JInteger::javaobject>> jmap) {
114*65c59e02SInna Palant   EXPECT(jmap);
115*65c59e02SInna Palant 
116*65c59e02SInna Palant   EXPECT(jmap->size() == 3);
117*65c59e02SInna Palant 
118*65c59e02SInna Palant   for (const auto& entry : *jmap) {
119*65c59e02SInna Palant     (void)entry;
120*65c59e02SInna Palant   }
121*65c59e02SInna Palant 
122*65c59e02SInna Palant   // The above should throw an exception.
123*65c59e02SInna Palant   EXPECT(false);
124*65c59e02SInna Palant 
125*65c59e02SInna Palant   return JNI_FALSE;
126*65c59e02SInna Palant }
127*65c59e02SInna Palant 
nativeTestIterateNullKey(alias_ref<jclass>,alias_ref<JMap<jstring,JInteger>> jmap)128*65c59e02SInna Palant jboolean nativeTestIterateNullKey(
129*65c59e02SInna Palant     alias_ref<jclass>,
130*65c59e02SInna Palant     alias_ref<JMap<jstring, JInteger>> jmap) {
131*65c59e02SInna Palant   EXPECT(jmap);
132*65c59e02SInna Palant 
133*65c59e02SInna Palant   EXPECT(jmap->size() == 3);
134*65c59e02SInna Palant 
135*65c59e02SInna Palant   std::unordered_map<std::string, int> umap;
136*65c59e02SInna Palant   std::unordered_set<int> nullValues;
137*65c59e02SInna Palant 
138*65c59e02SInna Palant   for (const auto& entry : *jmap) {
139*65c59e02SInna Palant     if (entry.first) {
140*65c59e02SInna Palant       umap[entry.first->toStdString()] = entry.second->intValue();
141*65c59e02SInna Palant     } else {
142*65c59e02SInna Palant       nullValues.insert(entry.second->intValue());
143*65c59e02SInna Palant     }
144*65c59e02SInna Palant   }
145*65c59e02SInna Palant 
146*65c59e02SInna Palant   EXPECT(umap.size() == 2);
147*65c59e02SInna Palant 
148*65c59e02SInna Palant   EXPECT(umap["one"] == 1);
149*65c59e02SInna Palant   EXPECT(umap["four"] == 4);
150*65c59e02SInna Palant 
151*65c59e02SInna Palant   EXPECT(nullValues.size() == 1);
152*65c59e02SInna Palant   EXPECT(*nullValues.begin() == -99);
153*65c59e02SInna Palant 
154*65c59e02SInna Palant   return JNI_TRUE;
155*65c59e02SInna Palant }
156*65c59e02SInna Palant 
nativeTestLargeMapIteration(alias_ref<jclass>,alias_ref<JMap<jstring,jstring>> jmap)157*65c59e02SInna Palant jboolean nativeTestLargeMapIteration(
158*65c59e02SInna Palant     alias_ref<jclass>,
159*65c59e02SInna Palant     alias_ref<JMap<jstring, jstring>> jmap) {
160*65c59e02SInna Palant   EXPECT(jmap);
161*65c59e02SInna Palant   EXPECT(jmap->size() == 3000);
162*65c59e02SInna Palant 
163*65c59e02SInna Palant   for (const auto& entry : *jmap) {
164*65c59e02SInna Palant     if (!entry.first) {
165*65c59e02SInna Palant       return JNI_FALSE;
166*65c59e02SInna Palant     }
167*65c59e02SInna Palant   }
168*65c59e02SInna Palant   return JNI_TRUE;
169*65c59e02SInna Palant }
170*65c59e02SInna Palant 
RegisterIteratorTests()171*65c59e02SInna Palant void RegisterIteratorTests() {
172*65c59e02SInna Palant   registerNatives(
173*65c59e02SInna Palant       "com/facebook/jni/IteratorTests",
174*65c59e02SInna Palant       {
175*65c59e02SInna Palant           makeNativeMethod("nativeTestListIterator", nativeTestListIterator),
176*65c59e02SInna Palant           makeNativeMethod("nativeTestMapIterator", nativeTestMapIterator),
177*65c59e02SInna Palant           makeNativeMethod(
178*65c59e02SInna Palant               "nativeTestIterateWrongType", nativeTestIterateWrongType),
179*65c59e02SInna Palant           makeNativeMethod(
180*65c59e02SInna Palant               "nativeTestIterateNullKey", nativeTestIterateNullKey),
181*65c59e02SInna Palant           makeNativeMethod(
182*65c59e02SInna Palant               "nativeTestLargeMapIteration", nativeTestLargeMapIteration),
183*65c59e02SInna Palant       });
184*65c59e02SInna Palant }
185