/* * Copyright (c) Facebook, Inc. and its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include "expect.h" using namespace facebook::jni; jboolean nativeTestListIterator( alias_ref, alias_ref> jlist) { EXPECT(jlist); EXPECT(jlist->size() == 3); std::vector vs1; for (const auto& elem : *jlist) { vs1.push_back(elem->toStdString()); } EXPECT(vs1.size() == 3); EXPECT(vs1[0] == "red"); EXPECT(vs1[1] == "green"); EXPECT(vs1[2] == "blue"); std::vector vs2; std::transform( jlist->begin(), jlist->end(), std::back_inserter(vs2), [](local_ref elem) { return elem->toStdString(); }); EXPECT(vs1 == vs2); std::vector vs3 = {"red", "green", "blue"}; EXPECT(vs1 == vs3); static auto iteratorMethod = JIterable::javaClassStatic()->getMethod()>( "iterator"); auto iter = iteratorMethod(jlist); EXPECT(std::equal(iter->begin(), iter->end(), jlist->begin())); EXPECT(std::equal( iter->begin(), iter->end(), vs3.begin(), [](const local_ref& a, const std::string& b) { return a->toStdString() == b; })); return JNI_TRUE; } jboolean nativeTestMapIterator( alias_ref, alias_ref> jmap) { EXPECT(jmap); EXPECT(jmap->size() == 3); std::unordered_map umap; for (const auto& entry : *jmap) { umap[entry.first->toStdString()] = entry.second->intValue(); } EXPECT(umap.size() == 3); EXPECT(umap["one"] == 1); EXPECT(umap["two"] == 2); EXPECT(umap["four"] == 4); // For an empty map, any types will do; the cast will only happen on null // pointers, which will always succeed. typedef JHashMap TestMap; static auto testmapCtor = TestMap::javaClassStatic()->getConstructor(); auto emptyMap = TestMap::javaClassStatic()->newObject(testmapCtor); EXPECT(emptyMap->size() == 0); JHashMap::Iterator i1 = emptyMap->begin(); JHashMap::Iterator i2 = emptyMap->end(); EXPECT(i1 == i2); return JNI_TRUE; } jboolean nativeTestIterateWrongType( alias_ref, alias_ref> jmap) { EXPECT(jmap); EXPECT(jmap->size() == 3); for (const auto& entry : *jmap) { (void)entry; } // The above should throw an exception. EXPECT(false); return JNI_FALSE; } jboolean nativeTestIterateNullKey( alias_ref, alias_ref> jmap) { EXPECT(jmap); EXPECT(jmap->size() == 3); std::unordered_map umap; std::unordered_set nullValues; for (const auto& entry : *jmap) { if (entry.first) { umap[entry.first->toStdString()] = entry.second->intValue(); } else { nullValues.insert(entry.second->intValue()); } } EXPECT(umap.size() == 2); EXPECT(umap["one"] == 1); EXPECT(umap["four"] == 4); EXPECT(nullValues.size() == 1); EXPECT(*nullValues.begin() == -99); return JNI_TRUE; } jboolean nativeTestLargeMapIteration( alias_ref, alias_ref> jmap) { EXPECT(jmap); EXPECT(jmap->size() == 3000); for (const auto& entry : *jmap) { if (!entry.first) { return JNI_FALSE; } } return JNI_TRUE; } void RegisterIteratorTests() { registerNatives( "com/facebook/jni/IteratorTests", { makeNativeMethod("nativeTestListIterator", nativeTestListIterator), makeNativeMethod("nativeTestMapIterator", nativeTestMapIterator), makeNativeMethod( "nativeTestIterateWrongType", nativeTestIterateWrongType), makeNativeMethod( "nativeTestIterateNullKey", nativeTestIterateNullKey), makeNativeMethod( "nativeTestLargeMapIteration", nativeTestLargeMapIteration), }); }