1 /*
   2  * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 import java.util.function.Consumer;
  25 import java.util.Collection;
  26 import java.util.LinkedList;
  27 import java.util.List;
  28 
  29 /**
  30  * A master superclass for all selection/resolution tests.  Contains a
  31  * couple of standard definitions that make writing these tests
  32  * easier.
  33  */
  34 public abstract class SelectionResolutionTest {
  35 
  36     /**
  37      * A unified output function, to ensure that all output goes to
  38      * the right string (System.err).
  39      *
  40      * @param str The line to print.
  41      */
  42     protected void println(final String str) {
  43         System.err.println(str);
  44     }
  45 
  46     /**
  47      * A test group is a generator for a set of tests that should
  48      * share common characteristics.  The Simple class provides a
  49      * default implementation that should work for most purposes.
  50      */
  51     public static interface TestGroup {
  52         /**
  53          * Given an action that runs a given test case, generate and
  54          * run all cases in this test group.
  55          */
  56         public void runCases(Consumer<SelectionResolutionTestCase> runner);
  57 
  58         /**
  59          * The basic implementation of TestGroup.  Produces one case
  60          * for every possible combination of cases from each of its
  61          * templates, by running them in order on an empty
  62          * SelectionResolutionTestCase.Builder.  This should be good
  63          * enough for writing most tests.
  64          */
  65         public static class Simple implements TestGroup {
  66             private final Template[] templates;
  67             private final SelectionResolutionTestCase.Builder initBuilder;
  68 
  69             public Simple(final SelectionResolutionTestCase.Builder initBuilder,
  70                           final Template... templates) {
  71                 this.templates = templates;
  72                 this.initBuilder = initBuilder;
  73             }
  74 
  75             @Override
  76             public void runCases(final Consumer<SelectionResolutionTestCase> runner) {
  77                 Consumer<SelectionResolutionTestCase.Builder> curr = (builder) -> {
  78                     runner.accept(builder.build());
  79                 };
  80 
  81                 for(int i = templates.length - 1; i >= 0; i--) {
  82                     final Consumer<SelectionResolutionTestCase.Builder> next = curr;
  83                     final Template template = templates[i];
  84                     curr = (builder) -> {
  85                         template.runCases(next, builder);
  86                     };
  87                 }
  88 
  89                 curr.accept(initBuilder);
  90             }
  91         }
  92     }
  93 
  94     private final List<String> errs = new LinkedList<String>();
  95 
  96     private final Collection<TestGroup> testGroups;
  97 
  98     private int testcount = 0;
  99 
 100     /**
 101      * Create a test from a set of test groups.  Most actual tests can
 102      * just define the test groups and pass them into this
 103      * constructor, then call run.
 104      */
 105     protected SelectionResolutionTest(final Collection<TestGroup> testGroups) {
 106         this.testGroups = testGroups;
 107     }
 108 
 109     /**
 110      * Run all the tests, report errors if they happen.
 111      */
 112     protected void run() {
 113         testGroups.stream().forEach(
 114                 (group) -> {
 115                     group.runCases((final SelectionResolutionTestCase testcase) -> {
 116                             testcount++;
 117                             final String err = testcase.run();
 118 
 119                             if (err != null) {
 120                                 errs.add(err);
 121                             }
 122                         });
 123                 });
 124 
 125         println("Ran " + testcount + " cases");
 126 
 127         if(!errs.isEmpty()) {
 128             println("Errors occurred in test:");
 129             for(final String err : errs) {
 130                 println(err);
 131             }
 132             throw new RuntimeException("Errors occurred in test");
 133         } else {
 134             println("All test cases succeeded");
 135         }
 136     }
 137 }