1 /******************************************************************************* 2 * Copyright (c) 2014 Moritz Eysholdt and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * Moritz Eysholdt <moritz.eysholdt@itemis.de> - initial API and implementation 13 *******************************************************************************/ 14 package org.eclipse.jdt.internal.junit4.runner; 15 16 import java.util.HashSet; 17 import java.util.Set; 18 19 import org.junit.runner.Description; 20 import org.junit.runner.Runner; 21 import org.junit.runner.manipulation.Filter; 22 import org.junit.runner.manipulation.NoTestsRemainException; 23 24 /** 25 * This filter keeps all matched {@link Description}s in a tree, including the children and 26 * container of the matched Description. 27 * 28 * It is allowed to match more than one Description. 29 */ 30 public class SubForestFilter extends Filter { 31 32 private Set<Description> fIncluded= null; 33 34 private final DescriptionMatcher fMatcher; 35 SubForestFilter(DescriptionMatcher matcher)36 public SubForestFilter(DescriptionMatcher matcher) { 37 fMatcher= matcher; 38 } 39 40 @Override apply(Object child)41 public void apply(Object child) throws NoTestsRemainException { 42 if (child instanceof Runner && fIncluded == null) { 43 fIncluded= new HashSet<Description>(); 44 collectIncludedDescriptions(((Runner)child).getDescription()); 45 if (fIncluded.isEmpty()) 46 throw new NoTestsRemainException(); 47 } 48 super.apply(child); 49 } 50 collectIncludedDescriptions(Description description)51 private boolean collectIncludedDescriptions(Description description) { 52 if (fMatcher.matches(description)) { 53 includeWithChildren(description); 54 return true; 55 } 56 boolean hasIncludedChild= false; 57 for (Description child : description.getChildren()) { 58 hasIncludedChild|= collectIncludedDescriptions(child); 59 } 60 if (hasIncludedChild) { 61 this.fIncluded.add(description); 62 } 63 return hasIncludedChild; 64 } 65 66 @Override describe()67 public String describe() { 68 return fMatcher.toString(); 69 } 70 getIncludedDescriptions()71 public Set<Description> getIncludedDescriptions() { 72 return fIncluded; 73 } 74 includeWithChildren(Description description)75 private void includeWithChildren(Description description) { 76 fIncluded.add(description); 77 for (Description child : description.getChildren()) { 78 includeWithChildren(child); 79 } 80 } 81 82 @Override shouldRun(Description description)83 public boolean shouldRun(Description description) { 84 return fIncluded.contains(description); 85 } 86 87 } 88