View Javadoc
1   /*-
2    * #%L
3    * io.earcam.instrumental.reflect
4    * %%
5    * Copyright (C) 2018 earcam
6    * %%
7    * SPDX-License-Identifier: (BSD-3-Clause OR EPL-1.0 OR Apache-2.0 OR MIT)
8    * 
9    * You <b>must</b> choose to accept, in full - any individual or combination of 
10   * the following licenses:
11   * <ul>
12   * 	<li><a href="https://opensource.org/licenses/BSD-3-Clause">BSD-3-Clause</a></li>
13   * 	<li><a href="https://www.eclipse.org/legal/epl-v10.html">EPL-1.0</a></li>
14   * 	<li><a href="https://www.apache.org/licenses/LICENSE-2.0">Apache-2.0</a></li>
15   * 	<li><a href="https://opensource.org/licenses/MIT">MIT</a></li>
16   * </ul>
17   * #L%
18   */
19  package io.earcam.instrumental.reflect;
20  
21  import static io.earcam.instrumental.reflect.Names.descriptorToTypeName;
22  import static io.earcam.instrumental.reflect.Names.descriptorsToTypeNames;
23  import static io.earcam.instrumental.reflect.Names.typeToInternalName;
24  import static io.earcam.instrumental.reflect.Names.typeToDescriptor;
25  import static java.util.stream.Collectors.toList;
26  import static org.hamcrest.MatcherAssert.assertThat;
27  import static org.hamcrest.Matchers.*;
28  
29  import java.lang.reflect.Method;
30  import java.util.Comparator;
31  import java.util.List;
32  import java.util.Map;
33  import java.util.function.Supplier;
34  
35  import org.junit.jupiter.api.Test;
36  
37  public class NamesTest {
38  
39  	@Test
40  	public void booleanDescriptorToTypeName()
41  	{
42  		assertThat(descriptorToTypeName("Z"), is(equalTo(boolean.class.getCanonicalName())));
43  	}
44  
45  
46  	@Test
47  	public void stringDescriptorToTypeName()
48  	{
49  		assertThat(descriptorToTypeName("Ljava.lang.String;"), is(equalTo(String.class.getCanonicalName())));
50  	}
51  
52  
53  	@Test
54  	public void singleDimensionDoubleDescriptorToTypeName()
55  	{
56  		double[] d1 = new double[0];
57  
58  		assertThat(descriptorToTypeName(d1.getClass().getName()), is(equalTo(d1.getClass().getCanonicalName())));
59  	}
60  
61  
62  	@Test
63  	public void biDimensionShortDescriptorToTypeName()
64  	{
65  		assertThat(descriptorToTypeName("[[S"), is(equalTo(short[][].class.getCanonicalName())));
66  	}
67  
68  
69  	@Test
70  	public void triDimensionStringDescriptorToTypeName()
71  	{
72  		String[][][] d3 = new String[0][][];
73  
74  		assertThat(descriptorToTypeName(d3.getClass().getName()), is(equalTo("java.lang.String[][][]")));
75  	}
76  
77  
78  	@Test
79  	public void intIntDouble_typeDescriptorsToTypeNames()
80  	{
81  		assertThat(descriptorsToTypeNames("IID"), contains("int", "int", "double"));
82  	}
83  
84  
85  	@Test
86  	public void StringListString2dArray_typeDescriptorsToTypeNames()
87  	{
88  		String desc = "Ljava/lang/String;Ljava/util/List;[[Ljava/lang/String;";
89  		assertThat(descriptorsToTypeNames(desc), contains(cn(String.class), cn(List.class), cn(String[][].class)));
90  	}
91  
92  
93  	private static String cn(Class<?> type)
94  	{
95  		return type.getCanonicalName();
96  	}
97  
98  
99  	@Test
100 	public void typeToDescriptor_void()
101 	{
102 		assertThat(typeToDescriptor(void.class).toString(), is(equalTo("V")));
103 	}
104 
105 
106 	@Test
107 	public void typeToDescriptor_2DStringArray()
108 	{
109 		String typeToDescriptor = Names.typeToDescriptor(String[][].class).toString();
110 
111 		assertThat(typeToDescriptor, is(equalTo("[[Ljava/lang/String;")));
112 	}
113 
114 
115 	@Test
116 	public void typeToDescriptor_innerClass()
117 	{
118 		// EARCAM_SNIPPET_BEGIN: type-to-binary
119 		String typeToDescriptor = Names.typeToDescriptor(Map.Entry.class).toString();
120 
121 		assertThat(typeToDescriptor, is(equalTo("Ljava/util/Map$Entry;")));
122 		// EARCAM_SNIPPET_END: type-to-binary
123 	}
124 
125 
126 	@Test
127 	public void binaryToTypeName_NoPrimitiveValues()  // Would be a class named B, C, J, I, S, D, F or V
128 	{
129 		String binaryName = Names.internalToTypeName("I");
130 
131 		assertThat(binaryName, is(equalTo("I")));
132 	}
133 
134 
135 	@Test
136 	public void binaryToTypeName_primitiveBooleanArray()
137 	{
138 		String binaryName = Names.internalToTypeName("[Z");
139 
140 		assertThat(binaryName, is(equalTo(boolean[].class.getTypeName())));
141 	}
142 
143 
144 	@Test
145 	public void binaryToTypeName_discriptorInvalidUnlessArrayType()
146 	{
147 		String binaryName = Names.internalToTypeName("Ljava/lang/String;");
148 
149 		assertThat(binaryName, is(not(equalTo("java.lang.String"))));
150 	}
151 
152 
153 	@Test
154 	public void binaryToTypeName_objectArray()
155 	{
156 		String binaryName = Names.internalToTypeName("[Ljava/lang/Number;");
157 
158 		assertThat(binaryName, is(equalTo(Number[].class.getTypeName())));
159 	}
160 
161 
162 	@Test
163 	public void binaryToTypeName_object2DArray()
164 	{
165 		// EARCAM_SNIPPET_BEGIN: binary-to-type
166 		String binaryName = Names.internalToTypeName("[[Ljava/lang/Object;");
167 
168 		assertThat(binaryName, is(equalTo(Object[][].class.getTypeName())));
169 		// EARCAM_SNIPPET_END: binary-to-type
170 	}
171 
172 
173 	@Test
174 	public void descriptorsToTypeNames_regression() throws Exception
175 	{
176 		String descriptor = "Lorg/slf4j/event/Level;Ljava/lang/String;[Ljava/lang/Object;Ljava/lang/Throwable;";
177 
178 		List<String> names = Names.descriptorsToTypeNames(descriptor);
179 
180 		assertThat(names, contains("org.slf4j.event.Level", "java.lang.String", "java.lang.Object[]", "java.lang.Throwable"));
181 	}
182 
183 
184 	protected List<String> describeMe(String arg)
185 	{
186 		return null;
187 	}
188 
189 
190 	@Test
191 	public void descriptorForMethod() throws NoSuchMethodException, SecurityException
192 	{
193 		String expected = "(Ljava/lang/String;)Ljava/util/List;";
194 
195 		Method method = getClass().getDeclaredMethod("describeMe", String.class);
196 		String actual = Names.descriptorFor(method).toString();
197 
198 		assertThat(actual, is(equalTo(expected)));
199 	}
200 
201 	@SuppressWarnings("unused")
202 	// EARCAM_SNIPPET_BEGIN: declared-binaries
203 	private class Declares {
204 		private class DeclaredTop {
205 			private class DeclaredMiddle {
206 				private class DeclaredBottom {}
207 
208 				private final Comparator<String> anon = new Comparator<String>() {
209 					@Override
210 					public int compare(String o1, String o2)
211 					{
212 						return 0;
213 					}
214 				};
215 
216 
217 				public String x()
218 				{
219 					Supplier<String> supplier = new Supplier<String>() {
220 
221 						@Override
222 						public String get()
223 						{
224 							return "hello";
225 						}
226 
227 					};
228 					return supplier.get();
229 				}
230 			}
231 		}
232 	}
233 	// EARCAM_SNIPPET_END: declared-binaries
234 
235 
236 	@Test
237 	void classesOf()
238 	{
239 		// EARCAM_SNIPPET_BEGIN: declared-binary-names
240 		List<String> classes = Names.declaredInternalNamesOf(Declares.class).collect(toList());
241 
242 		assertThat(classes, containsInAnyOrder(
243 				typeToInternalName(Declares.DeclaredTop.class),
244 				typeToInternalName(Declares.DeclaredTop.DeclaredMiddle.class),
245 				typeToInternalName(Declares.DeclaredTop.DeclaredMiddle.class) + "$1",
246 				typeToInternalName(Declares.DeclaredTop.DeclaredMiddle.class) + "$2",
247 				typeToInternalName(Declares.DeclaredTop.DeclaredMiddle.DeclaredBottom.class)));
248 		// EARCAM_SNIPPET_END: declared-binary-names
249 	}
250 }