1/* 2 * Copyright (c) 2016, 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 24package selectionresolution; 25 26import java.util.function.Consumer; 27import java.util.Collection; 28import java.util.LinkedList; 29import java.util.List; 30 31/** 32 * A master superclass for all selection/resolution tests. Contains a 33 * couple of standard definitions that make writing these tests 34 * easier. 35 */ 36public abstract class SelectionResolutionTest { 37 38 /** 39 * A unified output function, to ensure that all output goes to 40 * the right string (System.err). 41 * 42 * @param str The line to print. 43 */ 44 protected void println(final String str) { 45 System.err.println(str); 46 } 47 48 /** 49 * A test group is a generator for a set of tests that should 50 * share common characteristics. The Simple class provides a 51 * default implementation that should work for most purposes. 52 */ 53 public static interface TestGroup { 54 /** 55 * Given an action that runs a given test case, generate and 56 * run all cases in this test group. 57 */ 58 public void runCases(Consumer<SelectionResolutionTestCase> runner); 59 60 /** 61 * The basic implementation of TestGroup. Produces one case 62 * for every possible combination of cases from each of its 63 * templates, by running them in order on an empty 64 * SelectionResolutionTestCase.Builder. This should be good 65 * enough for writing most tests. 66 */ 67 public static class Simple implements TestGroup { 68 private final Template[] templates; 69 private final SelectionResolutionTestCase.Builder initBuilder; 70 71 public Simple(final SelectionResolutionTestCase.Builder initBuilder, 72 final Template... templates) { 73 this.templates = templates; 74 this.initBuilder = initBuilder; 75 } 76 77 @Override 78 public void runCases(final Consumer<SelectionResolutionTestCase> runner) { 79 Consumer<SelectionResolutionTestCase.Builder> curr = (builder) -> { 80 runner.accept(builder.build()); 81 }; 82 83 for(int i = templates.length - 1; i >= 0; i--) { 84 final Consumer<SelectionResolutionTestCase.Builder> next = curr; 85 final Template template = templates[i]; 86 curr = (builder) -> { 87 template.runCases(next, builder); 88 }; 89 } 90 91 curr.accept(initBuilder); 92 } 93 } 94 } 95 96 private final List<String> errs = new LinkedList<String>(); 97 98 private final Collection<TestGroup> testGroups; 99 100 private int testcount = 0; 101 102 /** 103 * Create a test from a set of test groups. Most actual tests can 104 * just define the test groups and pass them into this 105 * constructor, then call run. 106 */ 107 protected SelectionResolutionTest(final Collection<TestGroup> testGroups) { 108 this.testGroups = testGroups; 109 } 110 111 /** 112 * Run all the tests, report errors if they happen. 113 */ 114 protected void run() { 115 testGroups.stream().forEach( 116 (group) -> { 117 group.runCases((final SelectionResolutionTestCase testcase) -> { 118 testcount++; 119 final String err = testcase.run(); 120 121 if (err != null) { 122 errs.add(err); 123 } 124 }); 125 }); 126 127 println("Ran " + testcount + " cases"); 128 129 if(!errs.isEmpty()) { 130 println("Errors occurred in test:"); 131 for(final String err : errs) { 132 println(err); 133 } 134 throw new RuntimeException("Errors occurred in test"); 135 } else { 136 println("All test cases succeeded"); 137 } 138 } 139} 140