001/** 002 * The MIT License (MIT) 003 * 004 * Copyright (c) 2017 tools4j.org (Marco Terzer) 005 * 006 * Permission is hereby granted, free of charge, to any person obtaining a copy 007 * of this software and associated documentation files (the "Software"), to deal 008 * in the Software without restriction, including without limitation the rights 009 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 010 * copies of the Software, and to permit persons to whom the Software is 011 * furnished to do so, subject to the following conditions: 012 * 013 * The above copyright notice and this permission notice shall be included in all 014 * copies or substantial portions of the Software. 015 * 016 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 017 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 018 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 019 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 020 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 021 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 022 * SOFTWARE. 023 */ 024package org.tools4j.spockito; 025 026import org.junit.Test; 027import org.junit.runners.model.FrameworkMethod; 028import org.junit.runners.model.InitializationError; 029 030import java.util.ArrayList; 031import java.util.List; 032import java.util.Objects; 033 034/** 035 * A runner for the situation where a test method is to be run multiple times with all the rows of an unroll table. 036 * This case applies if the {@link org.tools4j.spockito.Spockito.Unroll} annotation is present at test method level. 037 */ 038public class SingleTestMultiRowRunner extends AbstractSpockitoTestRunner { 039 040 private final FrameworkMethod testMethod; 041 private final ValueConverter methodValueConverter; 042 043 public SingleTestMultiRowRunner(final Class<?> clazz, 044 final FrameworkMethod testMethod, 045 final ValueConverter methodValueConverter) throws InitializationError { 046 super(clazz); 047 this.testMethod = Objects.requireNonNull(testMethod); 048 this.methodValueConverter = Objects.requireNonNull(methodValueConverter); 049 validate(); 050 } 051 052 @Override 053 protected String getName() { 054 return testMethod.getName(); 055 } 056 057 @Override 058 protected String testName(final FrameworkMethod method) { 059 if (method instanceof UnrolledTestMethod) { 060 return method.getName() + Spockito.getName(method.getMethod(), ((UnrolledTestMethod)method).getTableRow()); 061 } 062 return super.testName(method); 063 } 064 065 @Override 066 protected List<FrameworkMethod> computeTestMethods() { 067 final List<FrameworkMethod> testMethods = new ArrayList<>(); 068 final Spockito.Unroll unroll = testMethod.getAnnotation(Spockito.Unroll.class); 069 if (unroll == null) { 070 testMethods.add(testMethod); 071 } else { 072 final Table table = Table.parse(unroll.value()); 073 testMethods.addAll(unroll(table)); 074 } 075 return testMethods; 076 } 077 078 private List<UnrolledTestMethod> unroll(final Table table) { 079 final List<UnrolledTestMethod> unrolled = new ArrayList<>(table.getRowCount()); 080 for (final TableRow row : table) { 081 final UnrolledTestMethod unrolledTestMethod = new UnrolledTestMethod(testMethod.getMethod(), row, methodValueConverter); 082 unrolled.add(unrolledTestMethod); 083 } 084 return unrolled; 085 } 086 087 protected void validate() throws InitializationError { 088 final List<Throwable> errors = new ArrayList<>(); 089 try { 090 super.collectInitializationErrors(errors); 091 } catch (final Exception e) { 092 errors.add(e); 093 } 094 if (!errors.isEmpty()) { 095 throw new InitializationError(testMethod + ": " + errors.get(0)); 096 } 097 } 098 099 @Override 100 protected void validateTestMethods(final List<Throwable> errors) { 101 final List<FrameworkMethod> methods = getTestClass().getAnnotatedMethods(Test.class); 102 for (final FrameworkMethod method : methods) { 103 final Spockito.Unroll unroll = method.getAnnotation(Spockito.Unroll.class); 104 if (unroll == null) { 105 method.validatePublicVoidNoArg(false, errors); 106 } else { 107 method.validatePublicVoid(false, errors); 108 method.validateNoTypeParametersOnArgs(errors); 109 } 110 } 111 } 112 113}