• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright 2006-2017 the original author or authors.
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 package org.objenesis.tck;
17 
18 import org.objenesis.Objenesis;
19 import org.objenesis.strategy.PlatformDescription;
20 
21 import java.util.ArrayList;
22 import java.util.HashMap;
23 import java.util.List;
24 import java.util.Map;
25 
26 /**
27  * <b>Technology Compatibility Kit</b> (TCK) for {@link Objenesis}s.
28  * <p>
29  * This TCK accepts a set of candidate classes (class it attempts to instantiate) and a set of
30  * Objenesis implementations. It then tries instantiating every candidate with every Objenesis
31  * implementations, reporting the results to a {@link Reporter}.
32  *
33  * <h3>Example usage</h3>
34  *
35  * <pre>
36  * TCK tck = new TCK();
37  * // register candidate classes.
38  * tck.registerCandidate(SomeClass.class, &quot;A basic class&quot;);
39  * tck.registerCandidate(SomeEvil.class, &quot;Something evil&quot;);
40  * tck.registerCandidate(NotEvil.class, &quot;Something nice&quot;);
41  * // register Objenesis instances.
42  * tck.registerObjenesisInstance(new ObjenesisStd(), &quot;Objenesis&quot;);
43  * tck.registerObjenesisInstance(new ObjenesisSerializaer(), &quot;Objenesis for serialization&quot;);
44  * // go!
45  * Reporter reporter = new TextReporter(System.out, System.err);
46  * tck.runTests(reporter);
47  * </pre>
48  *
49  * @author Joe Walnes
50  * @see org.objenesis.instantiator.ObjectInstantiator
51  * @see Reporter
52  * @see Main
53  */
54 public class TCK {
55 
56    private final List<Objenesis> objenesisInstances = new ArrayList<Objenesis>();
57    private final List<Class<?>> candidates = new ArrayList<Class<?>>();
58    private final Map<Object, String> descriptions = new HashMap<Object, String>();
59 
60    /**
61     * Register a candidate class to attempt to instantiate.
62     *
63     * @param candidateClass Class to attempt to instantiate
64     * @param description Description of the class
65     */
registerCandidate(Class<?> candidateClass, String description)66    public void registerCandidate(Class<?> candidateClass, String description) {
67       candidates.add(candidateClass);
68       descriptions.put(candidateClass, description);
69    }
70 
71    /**
72     * Register an Objenesis instance to use when attempting to instantiate a class.
73     *
74     * @param objenesis Tested Objenesis instance
75     * @param description Description of the Objenesis instance
76     */
registerObjenesisInstance(Objenesis objenesis, String description)77    public void registerObjenesisInstance(Objenesis objenesis, String description) {
78       objenesisInstances.add(objenesis);
79       descriptions.put(objenesis, description);
80    }
81 
82    /**
83     * Run all TCK tests.
84     *
85     * @param reporter Where to report the results of the test to.
86     */
runTests(Reporter reporter)87    public void runTests(Reporter reporter) {
88       reporter.startTests(describePlatform(), findAllDescriptions(candidates, descriptions),
89               findAllDescriptions(objenesisInstances, descriptions));
90 
91       for(Class<?> candidateClass : candidates) {
92          String candidateDescription = descriptions.get(candidateClass);
93 
94          for(Objenesis objenesis : objenesisInstances) {
95             String objenesisDescription = descriptions.get(objenesis);
96 
97             reporter.startTest(candidateDescription, objenesisDescription);
98 
99             runTest(reporter, candidateClass, objenesis);
100 
101             reporter.endTest();
102          }
103       }
104       reporter.endTests();
105    }
106 
runTest(Reporter reporter, Class<?> candidate, Objenesis objenesis)107    private void runTest(Reporter reporter, Class<?> candidate, Objenesis objenesis) {
108       try {
109          Object instance = objenesis.newInstance(candidate);
110          boolean success = instance != null && instance.getClass() == candidate;
111          reporter.result(success);
112       }
113       catch(Exception e) {
114          reporter.exception(e);
115       }
116    }
117 
118    /**
119     * Return the human readable description for list of TCK items (Objenesis instances or test
120     * candidates)
121     *
122     * @param keys list of items for which we are searching for a description
123     * @param descriptions all descriptions
124     * @return map of items with their description. Will contain one entry per entry in the original
125     *         key list
126     */
findAllDescriptions(List<?> keys, Map<?, String> descriptions)127    private Map<String, Object> findAllDescriptions(List<?> keys, Map<?, String> descriptions) {
128       Map<String, Object> results = new HashMap<String, Object>(keys.size());
129       for(Object o : keys) {
130          results.put(descriptions.get(o), o);
131       }
132       return results;
133    }
134 
135    /**
136     * Describes the platform. Outputs Java version and vendor. To change this behavior, override
137     * this method.
138     *
139     * @return Description of the current platform
140     */
describePlatform()141    protected String describePlatform() {
142       return PlatformDescription.describePlatform();
143    }
144 
145 }
146