1 /* 2 * Copyright (c) Facebook, Inc. and its affiliates. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.facebook.jni; 18 19 import static org.assertj.core.api.Assertions.assertThat; 20 import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown; 21 22 import com.facebook.soloader.nativeloader.NativeLoader; 23 import java.nio.ByteBuffer; 24 import java.util.Arrays; 25 import java.util.HashSet; 26 import java.util.List; 27 import java.util.Map; 28 import java.util.TreeMap; 29 import org.junit.BeforeClass; 30 import org.junit.Test; 31 32 public class DocTests extends BaseFBJniTests { 33 @BeforeClass setup()34 public static void setup() { 35 BaseFBJniTests.setup(); 36 NativeLoader.loadLibrary("doc_tests"); 37 } 38 toString()39 public String toString() { 40 return "instance of DocTests"; 41 } 42 43 // SECTION basic_methods nativeVoidMethod()44 native void nativeVoidMethod(); staticNativeVoidMethod()45 static native void staticNativeVoidMethod(); voidMethod()46 void voidMethod() {} staticVoidMethod()47 static void staticVoidMethod() {} 48 // END 49 50 @Test testVoids()51 public void testVoids() { 52 nativeVoidMethod(); 53 staticNativeVoidMethod(); 54 } 55 56 // SECTION primitives addSomeNumbers(byte b, short s, int i)57 static native long addSomeNumbers(byte b, short s, int i); doubler(int i)58 static long doubler(int i) { return i + i; } 59 // END 60 61 @Test testNumbers()62 public void testNumbers() { 63 assertThat(addSomeNumbers((byte) 1, (short) 2, 3)).isEqualTo(14); 64 } 65 66 // SECTION strings 67 // Java methods used by the C++ code below. fancyCat(String s1, String s2)68 static native String fancyCat(String s1, String s2); getCString()69 static native String getCString(); doubler(String s)70 static String doubler(String s) { return s + s; } 71 // END 72 73 @Test testStrings()74 public void testStrings() { 75 assertThat(fancyCat("a", "b")).isEqualTo("aaabbbb"); 76 assertThat(getCString()).isEqualTo("Watch your memory."); 77 } 78 79 // SECTION primitive_arrays primitiveArrays(int[] arr)80 static native int[] primitiveArrays(int[] arr); 81 // END 82 83 @Test testPrimitiveArrays()84 public void testPrimitiveArrays() { 85 assertThat(primitiveArrays(new int[] {1, 2})).contains(1, 2, 3); 86 } 87 convertReferences(MyDerivedClass derived)88 static native Object convertReferences(MyDerivedClass derived); 89 90 @Test testConvertReferences()91 public void testConvertReferences() { 92 MyDerivedClass derived = new MyDerivedClass(); 93 Object obj = convertReferences(derived); 94 assertThat(obj).isSameAs(derived); 95 } 96 castReferences(MyBaseClass base)97 static native void castReferences(MyBaseClass base); 98 99 @Test testCastReferences()100 public void testCastReferences() { 101 castReferences(new MyDerivedClass()); 102 try { 103 castReferences(new MyBaseClass()); 104 failBecauseExceptionWasNotThrown(ClassCastException.class); 105 } catch (ClassCastException e) { 106 assertThat(e).hasMessageContaining("MyBaseClass"); 107 assertThat(e).hasMessageContaining("MyDerivedClass"); 108 } 109 } 110 runConstructor()111 static native DataHolder runConstructor(); 112 113 @Test testRunConstructor()114 public void testRunConstructor() { 115 DataHolder d = runConstructor(); 116 assertThat(d.i).isEqualTo(1); 117 assertThat(d.s).isEqualTo("hi"); 118 } 119 callGetAndSetFields(DataHolder data)120 static native void callGetAndSetFields(DataHolder data); 121 122 @Test testCallGetAndSetFields()123 public void testCallGetAndSetFields() { 124 synchronized (DataHolder.class) { 125 DataHolder dh1 = new DataHolder(1, "1"); 126 DataHolder dh2 = new DataHolder(3, "3"); 127 DataHolder.someInstance = null; 128 callGetAndSetFields(dh1); 129 assertThat(dh1.i).isEqualTo(2); 130 assertThat(dh1.s).isEqualTo("11"); 131 assertThat(DataHolder.someInstance).isSameAs(dh1); 132 callGetAndSetFields(dh2); 133 assertThat(dh2.i).isEqualTo(4); 134 assertThat(dh2.s).isEqualTo("31"); 135 assertThat(DataHolder.someInstance).isSameAs(dh1); 136 DataHolder.someInstance = null; 137 } 138 } 139 showJObject(Object obj, DataHolder data)140 static native String showJObject(Object obj, DataHolder data); 141 142 @Test testShowJObject()143 public void testShowJObject() { 144 String str = showJObject(new Object(), new DataHolder(1, "hi")); 145 assertThat(str).startsWith("data=com.facebook.jni.DataHolder@"); 146 } 147 catchAndThrow()148 static native void catchAndThrow(); 149 150 @Test testCatchAndThrow()151 public void testCatchAndThrow() { 152 try { 153 catchAndThrow(); 154 failBecauseExceptionWasNotThrown(RuntimeException.class); 155 } catch (RuntimeException e) { 156 assertThat(e) 157 .hasMessageStartingWith("Caught 'java.lang.NoSuchMethodError:") 158 .hasMessageContaining("doesNotExist") 159 ; 160 } 161 } 162 163 // SECTION boxed scaleUp(Integer number)164 static native Double scaleUp(Integer number); 165 // END 166 167 @Test testScaleUp()168 public void testScaleUp() { 169 assertThat(scaleUp(5)).isEqualTo(7.5); 170 } 171 172 // SECTION iterables concatMatches(List<Integer> values, Map<String, Integer> names)173 static native String concatMatches(List<Integer> values, Map<String, Integer> names); 174 // END 175 176 @Test testConcatMatches()177 public void testConcatMatches() { 178 Map<String, Integer> names = new TreeMap<>(); 179 names.put("a", 1); 180 names.put("b", 3); 181 names.put("c", 3); 182 names.put("d", 7); 183 assertThat(concatMatches(Arrays.asList(1, 2), names)).isEqualTo("bc"); 184 } 185 186 // SECTION collections buildCollections()187 static native Map<String, List<Integer>> buildCollections(); 188 // END 189 190 @Test testBuildCollections()191 public void testBuildCollections() { 192 Map<String, List<Integer>> ret = buildCollections(); 193 assertThat(ret.keySet()).isEqualTo(new HashSet<>(Arrays.asList("primes"))); 194 assertThat(ret.get("primes")).isEqualTo(Arrays.asList(2, 3)); 195 } 196 197 // SECTION byte_buffer transformBuffer(ByteBuffer data)198 static native ByteBuffer transformBuffer(ByteBuffer data); receiveBuffer(ByteBuffer buffer)199 static void receiveBuffer(ByteBuffer buffer) { 200 assertThat(buffer.capacity()).isEqualTo(2); 201 assertThat(buffer.get(0)).isEqualTo((byte)2); 202 assertThat(buffer.get(1)).isEqualTo((byte)3); 203 } 204 @Test testByteBuffers()205 public void testByteBuffers() { 206 ByteBuffer data = ByteBuffer.allocateDirect(2); 207 data.put(new byte[] {1, 2}); 208 ByteBuffer transformed = transformBuffer(data); 209 receiveBuffer(transformed); 210 } 211 // END 212 } 213 214 // SECTION inheritance 215 class MyBaseClass {} 216 class MyDerivedClass extends MyBaseClass {} 217 // END 218 219 // SECTION nested_class 220 class Outer { 221 class Nested {} 222 } 223 // END 224 225 // SECTION constructor 226 class DataHolder { 227 int i; 228 String s; DataHolder(int i, String s)229 DataHolder(int i, String s) { 230 this.i = i; 231 this.s = s; 232 } 233 static DataHolder someInstance; 234 } 235 // END 236