1/* 2 * Copyright (C) 2016 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 17package android.icu.junit; 18 19import android.icu.dev.test.TestFmwk; 20import java.io.PrintWriter; 21import java.io.StringWriter; 22import java.util.regex.Matcher; 23import java.util.regex.Pattern; 24import junit.framework.AssertionFailedError; 25import org.junit.runner.Description; 26 27/** 28 * Represents a test within a {@link TestFmwk} class. 29 */ 30final class IcuFrameworkTest implements Comparable<IcuFrameworkTest> { 31 32 private static final String[] EMPTY_ARGS = new String[0]; 33 34 private static final Pattern EXTRACT_ERROR_INFO = Pattern.compile( 35 "^[A-Za-z0-9_]+ \\{(\n.*)\n\\}.*", Pattern.DOTALL); 36 37 /** 38 * The {@link TestFmwk} instance on which the tests will be run. 39 */ 40 private final TestFmwk testFmwk; 41 42 private final TestFmwk.Target target; 43 44 /** 45 * The name of the individual target to run. 46 */ 47 private final String methodName; 48 49 IcuFrameworkTest(TestFmwk testFmwk, TestFmwk.Target target, String methodName) { 50 this.testFmwk = testFmwk; 51 this.target = target; 52 this.methodName = methodName; 53 } 54 55 public String getMethodName() { 56 return methodName; 57 } 58 59 /** 60 * Runs the target. 61 */ 62 public void run() { 63 test_for_TestFmwk_Run(); 64 } 65 66 /** 67 * A special method to avoid the TestFmwk from throwing an InternalError when an error occurs 68 * during execution of the test but outside the actual test method, e.g. in a 69 * {@link TestFmwk#validate()} method. See http://bugs.icu-project.org/trac/ticket/12183 70 * 71 * <p>DO NOT CHANGE THE NAME 72 */ 73 private void test_for_TestFmwk_Run() { 74 StringWriter stringWriter = new StringWriter(); 75 PrintWriter log = new PrintWriter(stringWriter); 76 77 TestFmwk.TestParams localParams = TestFmwk.TestParams.create(EMPTY_ARGS, log); 78 if (localParams == null) { 79 throw new IllegalStateException("Could not create params"); 80 } 81 82 // We don't want an error summary as we are only running one test. 83 localParams.errorSummary = null; 84 85 try { 86 // Make sure that the TestFmwk is initialized with the correct parameters. This method 87 // is being called solely for its side effect of updating the TestFmwk.params field. 88 testFmwk.resolveTarget(localParams); 89 90 // Run the target. 91 target.run(); 92 } catch (Exception e) { 93 // Output the exception to the log and make sure it is treated as an error. 94 e.printStackTrace(log); 95 localParams.errorCount++; 96 } 97 98 // Treat warnings as errors. 99 int errorCount = localParams.errorCount + localParams.warnCount; 100 101 // Ensure that all data is written to the StringWriter. 102 log.flush(); 103 104 // Treat warnings as errors. 105 String information = stringWriter.toString(); 106 if (errorCount != 0) { 107 // Remove unnecessary formatting. 108 Matcher matcher = EXTRACT_ERROR_INFO.matcher(information); 109 if (matcher.matches()) { 110 information = matcher.group(1)/*.replace("\n ", "\n")*/; 111 } 112 113 // Also append the logs to the console output. 114 String output = "Failure: " + getDescription() + ", due to " 115 + errorCount + " error(s)\n" + information; 116 117 throw new AssertionFailedError(output); 118 } 119 } 120 121 /** 122 * Get the JUnit {@link Description} 123 */ 124 public Description getDescription() { 125 // Get a description for the specific method within the class. 126 return Description.createTestDescription(testFmwk.getClass(), methodName); 127 } 128 129 @Override 130 public int compareTo(IcuFrameworkTest o) { 131 return methodName.compareTo(o.methodName); 132 } 133} 134