1 /*
2  * Copyright (C) 2009 The Android Open Source Project
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 signature.comparator;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertNotNull;
21 import static org.junit.Assert.assertNull;
22 import static org.junit.Assert.assertSame;
23 
24 import org.junit.Test;
25 
26 import signature.comparator.util.AbstractComparatorTest;
27 import signature.compare.model.IAnnotationDelta;
28 import signature.compare.model.IApiDelta;
29 import signature.compare.model.IClassDefinitionDelta;
30 import signature.compare.model.DeltaType;
31 import signature.compare.model.ITypeReferenceDelta;
32 import signature.converter.util.CompilationUnit;
33 import signature.model.IApi;
34 
35 import java.io.IOException;
36 import java.lang.reflect.ParameterizedType;
37 import java.lang.reflect.Type;
38 import java.lang.reflect.TypeVariable;
39 import java.util.Set;
40 
41 public abstract class ClassCompareTest extends AbstractComparatorTest {
42 
43     @Test
compareEqualClasses()44     public void compareEqualClasses() throws IOException{
45          CompilationUnit A = new CompilationUnit("a.A",
46                     "package a; " +
47                     "public class A {}");
48          CompilationUnit B = new CompilationUnit("a.B",
49                     "package a; " +
50                     "public class B {}");
51           IApi fromApi = convert(A, B);
52           IApi toApi = convert(A, B);
53           assertNull(compare(fromApi, toApi));
54     }
55 
56     @Test
compareMissingClass()57     public void compareMissingClass() throws IOException{
58          CompilationUnit A = new CompilationUnit("a.A",
59                     "package a; " +
60                     "public class A {}");
61          CompilationUnit B = new CompilationUnit("a.B",
62                     "package a; " +
63                     "public class B {}");
64           IApi fromApi = convert(A, B);
65           IApi toApi = convert(A);
66 
67           IApiDelta delta = compare(fromApi, toApi);
68           IClassDefinitionDelta classDelta = getSingleClassDelta(delta);
69           assertSame(DeltaType.REMOVED, classDelta.getType());
70     }
71 
72     @Test
compareAddedClass()73     public void compareAddedClass() throws IOException{
74          CompilationUnit A = new CompilationUnit("a.A",
75                     "package a; " +
76                     "public class A {}");
77          CompilationUnit B = new CompilationUnit("a.B",
78                     "package a; " +
79                     "public class B {}");
80           IApi fromApi = convert(A);
81           IApi toApi = convert(A, B);
82 
83           IApiDelta delta = compare(fromApi, toApi);
84           IClassDefinitionDelta classDelta = getSingleClassDelta(delta);
85           assertSame(DeltaType.ADDED, classDelta.getType());
86     }
87 
88     @Test
compareAnnotationsOnClass()89     public void compareAnnotationsOnClass() throws IOException{
90          CompilationUnit A = new CompilationUnit("a.A",
91                     "package a; " +
92                     "public class A {}");
93          CompilationUnit AnnotA = new CompilationUnit("a.A",
94                     "package a; " +
95                     "@Deprecated " +
96                     "public class A {}");
97           IApi fromApi = convert(A);
98           IApi toApi = convert(AnnotA);
99 
100           IApiDelta delta = compare(fromApi, toApi);
101           IClassDefinitionDelta classDelta = getSingleClassDelta(delta);
102 
103           System.out.println(classDelta);
104 
105           Set<IAnnotationDelta> annotationDeltas = classDelta.getAnnotationDeltas();
106           assertEquals(1, annotationDeltas.size());
107 
108           IAnnotationDelta annotationDelta = annotationDeltas.iterator().next();
109           assertSame(DeltaType.ADDED, annotationDelta.getType());
110     }
111 
112     @Test
compareDefaultedAnnotationElementOnClass()113     public void compareDefaultedAnnotationElementOnClass() throws IOException{
114         CompilationUnit annot = new CompilationUnit("a.A",
115                 "package a; " +
116                 "public @interface A {" +
117                 "  String name() default \"NAME\" ;" +
118                 "}");
119          CompilationUnit AnnotBDefault = new CompilationUnit("a.B",
120                     "package a; " +
121                     "@A " +
122                     "public class B {}");
123          CompilationUnit AnnotB = new CompilationUnit("a.B",
124                     "package a; " +
125                     "@A(name=\"NAME\") " +
126                     "public class B {}");
127           IApi fromApi = convert(annot, AnnotBDefault);
128           IApi toApi = convert(annot, AnnotB);
129           assertNull(compare(fromApi, toApi));
130     }
131 
132     @Test
compareSameInterfaces()133     public void compareSameInterfaces() throws IOException{
134          CompilationUnit A = new CompilationUnit("a.A",
135                     "package a; " +
136                     "public class A implements Comparable<String>{ " +
137                     "  public int compareTo(String another){return 0;}" +
138                     "}");
139           IApi fromApi = convert(A);
140           IApi toApi = convert(A);
141           assertNull(compare(fromApi, toApi));
142     }
143 
144     @Test
compareMissingInterface()145     public void compareMissingInterface() throws IOException{
146          CompilationUnit A0 = new CompilationUnit("a.A",
147                  "package a; " +
148                  "public class A implements Cloneable{}");
149          CompilationUnit A1 = new CompilationUnit("a.A",
150                  "package a; " +
151                  "public class A {}");
152           IApi fromApi = convert(A0);
153           IApi toApi = convert(A1);
154           IApiDelta apiDelta = compare(fromApi, toApi);
155           IClassDefinitionDelta classDelta =  getSingleClassDelta(apiDelta);
156           assertEquals(1, classDelta.getInterfaceDeltas().size());
157           ITypeReferenceDelta<?> interfaceDelta = classDelta.getInterfaceDeltas().iterator().next();
158           assertNotNull(interfaceDelta);
159     }
160 
161     @Test
compareMissingGenericInterface0()162     public void compareMissingGenericInterface0() throws IOException{
163         CompilationUnit I = new CompilationUnit("a.I",
164                 "package a; " +
165                 "public interface I<T>{}");
166         CompilationUnit B = new CompilationUnit("a.B",
167                 "package a; " +
168                 "public class B implements I<String>{}");
169          CompilationUnit A0 = new CompilationUnit("a.A",
170                 "package a; " +
171                 "public class A extends B implements I<String>{}");
172          CompilationUnit A1 = new CompilationUnit("a.A",
173                  "package a; " +
174                  "public class A extends B {}");
175           IApi fromApi = convert(I, B, A0);
176           IApi toApi = convert(I, B, A1);
177           IApiDelta apiDelta = compare(fromApi, toApi);
178           assertNull(apiDelta);
179     }
180 
181     @Test
compareMissingGenericInterface1()182     public void compareMissingGenericInterface1() throws IOException{
183         CompilationUnit I = new CompilationUnit("a.I",
184                 "package a; " +
185                 "public interface I<T>{}");
186         CompilationUnit B = new CompilationUnit("a.B",
187                 "package a; " +
188                 "public class B<T> implements I<T>{}");
189          CompilationUnit A0 = new CompilationUnit("a.A",
190                 "package a; " +
191                 "public class A<T> extends B<T> implements I<T>{}");
192                  //generic declaration of 'T' in I<T> is A<T>
193          CompilationUnit A1 = new CompilationUnit("a.A",
194                  "package a; " +
195                  "public class A<T> extends B<T> {}");
196                  //generic declaration of 'T' in I<T> is B<T>
197           IApi fromApi = convert(I, B, A0);
198           IApi toApi = convert(I, B, A1);
199           IApiDelta apiDelta = compare(fromApi, toApi);
200           assertNull(apiDelta);
201     }
202 
203     static interface I<T>{}
204     static class B<T> implements I<T>{}
205     static class A0<E extends Number> extends B<E> implements I<E>{}
206     static class A1<S extends Number> extends B<S>{}
207 
208     @Test
compareMissingGenericInterfaceReflection()209     public void compareMissingGenericInterfaceReflection() {
210         ParameterizedType sC = (ParameterizedType)A0.class.getGenericSuperclass();
211         Type[] bounds = ((TypeVariable<?>)sC.getActualTypeArguments()[0]).getBounds();
212         Type[] a1Int = A1.class.getGenericInterfaces();
213         assertEquals(0,a1Int.length);
214     }
215 
216     @Test
compareInterfaceClosure()217     public void compareInterfaceClosure() throws IOException{
218          CompilationUnit I0 = new CompilationUnit("a.I0",
219                  "package a; " +
220                  "public interface I0{}");
221          CompilationUnit I1 = new CompilationUnit("a.I1",
222                  "package a; " +
223                  "public interface I1 extends I0{}");
224          CompilationUnit C0 = new CompilationUnit("a.C0",
225                  "package a; " +
226                  "public class C0 implements I1{}");
227          CompilationUnit C0_I1 = new CompilationUnit("a.C0",
228                  "package a; " +
229                  "public class C0 implements I1, I0{}");
230           IApi fromApi = convert(I0, I1, C0);
231           IApi toApi = convert(I0, I1, C0_I1);
232           IApiDelta apiDelta = compare(fromApi, toApi);
233           assertNull(apiDelta);
234     }
235 
236     @Test
compareUpperBounds0()237     public void compareUpperBounds0() throws IOException{
238         CompilationUnit Number = new CompilationUnit("a.Number",
239                     "package a; " +
240                     "public class Number implements java.io.Serializable{}");
241          CompilationUnit I0 = new CompilationUnit("a.I",
242                     "package a; " +
243                     "public interface I<T extends Number & java.io.Serializable>{}");
244          CompilationUnit I1 = new CompilationUnit("a.I",
245                      "package a; " +
246                      "public interface I<T extends Number>{}");
247           IApi fromApi = convert(I0,Number);
248           IApi toApi = convert(I1,Number);
249           IApiDelta apiDelta = compare(fromApi, toApi);
250           assertNull(apiDelta);
251     }
252 
253     @Test
compareUpperBounds1()254     public void compareUpperBounds1() throws IOException{
255         CompilationUnit Number = new CompilationUnit("a.Number",
256                     "package a; " +
257                     "public class Number {}");
258          CompilationUnit I0 = new CompilationUnit("a.I",
259                     "package a; " +
260                     "public interface I<T extends Number & java.io.Serializable>{}");
261          CompilationUnit I1 = new CompilationUnit("a.I",
262                      "package a; " +
263                      "public interface I<T extends Number>{}");
264           IApi fromApi = convert(I0,Number);
265           IApi toApi = convert(I1,Number);
266           IApiDelta apiDelta = compare(fromApi, toApi);
267           assertNotNull(apiDelta);
268     }
269 
270     @Test
compareTypeVariables0()271     public void compareTypeVariables0() throws IOException{
272         CompilationUnit C0 = new CompilationUnit("a.C",
273                     "package a; " +
274                     "public class C<T,S> {}");
275         CompilationUnit C1 = new CompilationUnit("a.C",
276                     "package a; " +
277                     "public class C<S,T> {}");
278           IApi fromApi = convert(C0);
279           IApi toApi = convert(C1);
280           IApiDelta apiDelta = compare(fromApi, toApi);
281           assertNull(apiDelta);
282     }
283 
284     @Test
compareTypeVariables1()285     public void compareTypeVariables1() throws IOException{
286         CompilationUnit C0 = new CompilationUnit("a.C",
287                     "package a; " +
288                     "public class C<T,S> {}");
289         CompilationUnit C1 = new CompilationUnit("a.C",
290                     "package a; " +
291                     "public class C<T,S,R> {}");
292           IApi fromApi = convert(C0);
293           IApi toApi = convert(C1);
294           IApiDelta apiDelta = compare(fromApi, toApi);
295           assertNotNull(apiDelta);
296     }
297 
298     @Test
compareTypeVariables2()299     public void compareTypeVariables2() throws IOException{
300         CompilationUnit C0 = new CompilationUnit("a.C",
301                     "package a; " +
302                     "public class C<T,S> {" +
303                     "  public void m(T t, S s){} " +
304                     "}");
305         CompilationUnit C1 = new CompilationUnit("a.C",
306                     "package a; " +
307                     "public class C<S,T> {" +
308                     "  public void m(S s, T t){} " +
309                     "}");
310           IApi fromApi = convert(C0);
311           IApi toApi = convert(C1);
312           IApiDelta apiDelta = compare(fromApi, toApi);
313           assertNull(apiDelta);
314     }
315 
316     @Test
compareTypeVariables3()317     public void compareTypeVariables3() throws IOException{
318         CompilationUnit C0 = new CompilationUnit("a.C",
319                     "package a; " +
320                     "public class C<T,S> {" +
321                     "  public void m(T t, S s){} " +
322                     "}");
323         CompilationUnit C1 = new CompilationUnit("a.C",
324                     "package a; " +
325                     "public class C<S,T> {" +
326                     "  public void m(T t, S s){} " +
327                     "}");
328           IApi fromApi = convert(C0);
329           IApi toApi = convert(C1);
330           IApiDelta apiDelta = compare(fromApi, toApi);
331           assertNotNull(apiDelta);
332     }
333 
334     @Test
compareTypeVariables4()335     public void compareTypeVariables4() throws IOException{
336         CompilationUnit C0 = new CompilationUnit("a.C",
337                     "package a; " +
338                     "public class C<T> {" +
339                     "  public class I{" +
340                     "    public void m(T t){}" +
341                     "  } " +
342                     "}");
343         CompilationUnit C1 = new CompilationUnit("a.C",
344                     "package a; " +
345                     "public class C {" +
346                     "  public class I<T>{" +
347                     "    public void m(T t){}" +
348                     "  } " +
349                     "}");
350           IApi fromApi = convert(C0);
351           IApi toApi = convert(C1);
352           IApiDelta apiDelta = compare(fromApi, toApi);
353           assertNotNull(apiDelta);
354     }
355 
356     @Test
interfaceClosureTest()357     public void interfaceClosureTest() throws IOException{
358         CompilationUnit B = new CompilationUnit("a.B",
359                     "package a; " +
360                     "public class  B<S> {}");
361         CompilationUnit C = new CompilationUnit("a.C",
362                 "package a; " +
363                 "public class C<R> extends B<R>  {}");
364         CompilationUnit E = new CompilationUnit("a.E",
365                 "package a; " +
366                 "public class E<Q> extends C<Q> {}");
367         CompilationUnit F = new CompilationUnit("a.F",
368                 "package a; " +
369                 "public class F<P> extends E<P> {}");
370         CompilationUnit G = new CompilationUnit("a.G",
371                 "package a; " +
372                 "public class G<O> extends F<O> {}");
373         CompilationUnit H = new CompilationUnit("a.H",
374                 "package a; " +
375                 "public class H<R> extends G<R> {}");
376 //        IApi fromApi = convert(B,C, E, F);
377 //        IApi toApi = convert(B,C,E, F);
378           IApi fromApi = convert(B,C, E,F, G, H);
379           IApi toApi = convert(B,C,E,F, G, H);
380 
381 
382           long start = System.currentTimeMillis();
383           IApiDelta apiDelta = compare(fromApi, toApi);
384           System.out.println("compare took :" + (System.currentTimeMillis() -start) + "ms");
385           assertNull(apiDelta);
386     }
387 
388 }