178c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson/**
278c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson * Copyright 2006-2013 the original author or authors.
378c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson *
478c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson * Licensed under the Apache License, Version 2.0 (the "License");
578c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson * you may not use this file except in compliance with the License.
678c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson * You may obtain a copy of the License at
778c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson *
878c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson *     http://www.apache.org/licenses/LICENSE-2.0
978c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson *
1078c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson * Unless required by applicable law or agreed to in writing, software
1178c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson * distributed under the License is distributed on an "AS IS" BASIS,
1278c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1378c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson * See the License for the specific language governing permissions and
1478c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson * limitations under the License.
1578c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson */
1678c496fe0fac4c89993109340aec80d1afa3141fIan Parkinsonpackage org.objenesis.tck;
1778c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson
1878c496fe0fac4c89993109340aec80d1afa3141fIan Parkinsonimport java.util.ArrayList;
1978c496fe0fac4c89993109340aec80d1afa3141fIan Parkinsonimport java.util.Collection;
2078c496fe0fac4c89993109340aec80d1afa3141fIan Parkinsonimport java.util.HashMap;
2178c496fe0fac4c89993109340aec80d1afa3141fIan Parkinsonimport java.util.Iterator;
2278c496fe0fac4c89993109340aec80d1afa3141fIan Parkinsonimport java.util.List;
2378c496fe0fac4c89993109340aec80d1afa3141fIan Parkinsonimport java.util.Map;
2478c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson
2578c496fe0fac4c89993109340aec80d1afa3141fIan Parkinsonimport org.objenesis.Objenesis;
2678c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson
2778c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson/**
2878c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson * <b>Technology Compatibility Kit</b> (TCK) for {@link Objenesis}s.
2978c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson * <p/>
3078c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson * This TCK accepts a set of candidate classes (class it attempts to instantiate) and a set of
3178c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson * Objenesis implementations. It then tries instantiating every candidate with every Objenesis
3278c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson * implementations, reporting the results to a {@link Reporter}.
3378c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson * <h3>Example usage</h3>
3478c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson *
3578c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson * <pre>
3678c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson * TCK tck = new TCK();
3778c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson * // register candidate classes.
3878c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson * tck.registerCandidate(SomeClass.class, &quot;A basic class&quot;);
3978c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson * tck.registerCandidate(SomeEvil.class, &quot;Something evil&quot;);
4078c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson * tck.registerCandidate(NotEvil.class, &quot;Something nice&quot;);
4178c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson * // register Objenesis instances.
4278c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson * tck.registerObjenesisInstance(new ObjenesisStd(), &quot;Objenesis&quot;);
4378c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson * tck.registerObjenesisInstance(new ObjenesisSerializaer(), &quot;Objenesis for serialization&quot;);
4478c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson * // go!
4578c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson * Reporter reporter = new TextReporter(System.out, System.err);
4678c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson * tck.runTests(reporter);
4778c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson * </pre>
4878c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson *
4978c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson * @author Joe Walnes
5078c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson * @see org.objenesis.instantiator.ObjectInstantiator
5178c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson * @see Reporter
5278c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson * @see Main
5378c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson */
5478c496fe0fac4c89993109340aec80d1afa3141fIan Parkinsonpublic class TCK {
5578c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson
5678c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson   private final List objenesisInstances = new ArrayList();
5778c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson   private final List candidates = new ArrayList();
5878c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson   private final Map descriptions = new HashMap();
5978c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson
6078c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson   /**
6178c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson    * Register a candidate class to attempt to instantiate.
6278c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson    *
6378c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson    * @param candidateClass Class to attempt to instantiate
6478c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson    * @param description Description of the class
6578c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson    */
6678c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson   public void registerCandidate(Class candidateClass, String description) {
6778c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson      candidates.add(candidateClass);
6878c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson      descriptions.put(candidateClass, description);
6978c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson   }
7078c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson
7178c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson   /**
7278c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson    * Register an Objenesis instance to use when attempting to instantiate a class.
7378c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson    *
7478c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson    * @param objenesis Tested Objenesis instance
7578c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson    * @param description Description of the Objenesis instance
7678c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson    */
7778c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson   public void registerObjenesisInstance(Objenesis objenesis, String description) {
7878c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson      objenesisInstances.add(objenesis);
7978c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson      descriptions.put(objenesis, description);
8078c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson   }
8178c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson
8278c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson   /**
8378c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson    * Run all TCK tests.
8478c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson    *
8578c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson    * @param reporter Where to report the results of the test to.
8678c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson    */
8778c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson   public void runTests(Reporter reporter) {
8878c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson      reporter.startTests(describePlatform(), findAllDescriptions(candidates, descriptions),
8978c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson         findAllDescriptions(objenesisInstances, descriptions));
9078c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson
9178c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson      for(Iterator i = candidates.iterator(); i.hasNext();) {
9278c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson         Class candidateClass = (Class) i.next();
9378c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson         String candidateDescription = (String) descriptions.get(candidateClass);
9478c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson
9578c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson         for(Iterator j = objenesisInstances.iterator(); j.hasNext();) {
9678c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson            Objenesis objenesis = (Objenesis) j.next();
9778c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson
9878c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson            String objenesisDescription = (String) descriptions.get(objenesis);
9978c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson
10078c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson            reporter.startTest(candidateDescription, objenesisDescription);
10178c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson
10278c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson            runTest(reporter, candidateClass, objenesis, candidateDescription);
10378c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson
10478c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson            reporter.endTest();
10578c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson         }
10678c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson      }
10778c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson      reporter.endTests();
10878c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson   }
10978c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson
11078c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson   private void runTest(Reporter reporter, Class candidate, Objenesis objenesis,
11178c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson      String candidateDescription) {
11278c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson      try {
11378c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson         Object instance = objenesis.newInstance(candidate);
11478c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson         boolean success = instance != null && instance.getClass() == candidate;
11578c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson         reporter.result(success);
11678c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson      }
11778c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson      catch(Exception e) {
11878c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson         reporter.exception(e);
11978c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson      }
12078c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson   }
12178c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson
12278c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson   private Collection findAllDescriptions(List keys, Map descriptions) {
12378c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson      List results = new ArrayList(keys.size());
12478c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson      for(int i = 0; i < keys.size(); i++) {
12578c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson         results.add(descriptions.get(keys.get(i)));
12678c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson      }
12778c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson      return results;
12878c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson   }
12978c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson
13078c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson   /**
13178c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson    * Describes the platform. Outputs Java version and vendor. To change this behavior, override
13278c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson    * this method.
13378c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson    *
13478c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson    * @return Description of the current platform
13578c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson    */
13678c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson   protected String describePlatform() {
13778c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson      return "Java " + System.getProperty("java.specification.version") + " ("
13878c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson         + System.getProperty("java.vm.vendor") + " " + System.getProperty("java.vm.name") + " "
13978c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson         + System.getProperty("java.vm.version") + " " + System.getProperty("java.runtime.version")
14078c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson         + ")";
14178c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson   }
14278c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson
14378c496fe0fac4c89993109340aec80d1afa3141fIan Parkinson}
144