<commit_before>/*
 * Copyright 2015-2016 the original author or authors.
 *
 * All rights reserved. This program and the accompanying materials are
 * made available under the terms of the Eclipse Public License v1.0 which
 * accompanies this distribution and is available at
 *
 * http://www.eclipse.org/legal/epl-v10.html
 */

package org.junit.platform.runner;

import static java.util.Arrays.stream;
import static java.util.stream.Collectors.toList;
import static org.junit.platform.commons.meta.API.Usage.Maintained;
import static org.junit.platform.engine.discovery.ClassFilter.includeClassNamePattern;
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
import static org.junit.platform.launcher.EngineFilter.excludeEngines;
import static org.junit.platform.launcher.EngineFilter.includeEngines;
import static org.junit.platform.launcher.TagFilter.excludeTags;
import static org.junit.platform.launcher.TagFilter.includeTags;
import static org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder.request;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.function.Function;

import org.junit.platform.commons.meta.API;
import org.junit.platform.commons.util.Preconditions;
import org.junit.platform.engine.DiscoverySelector;
import org.junit.platform.engine.discovery.DiscoverySelectors;
import org.junit.platform.launcher.Launcher;
import org.junit.platform.launcher.LauncherDiscoveryRequest;
import org.junit.platform.launcher.TestIdentifier;
import org.junit.platform.launcher.TestPlan;
import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder;
import org.junit.platform.launcher.core.LauncherFactory;
import org.junit.runner.Description;
import org.junit.runner.Runner;
import org.junit.runner.manipulation.Filter;
import org.junit.runner.manipulation.Filterable;
import org.junit.runner.manipulation.NoTestsRemainException;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.model.InitializationError;

/**
 * JUnit 4 based {@link Runner} which runs tests on the JUnit Platform in a
 * JUnit 4 environment.
 *
 * <p>Annotating a class with {@code @RunWith(JUnitPlatform.class)} allows it
 * to be run with IDEs and build systems that support JUnit 4 but do not yet
 * support the JUnit Platform directly.
 *
 * <p>Consult the various annotations in this package for configuration options.
 *
 * <p>If you do not use any configuration annotations from this package, you
 * can simply use this runner on a test class whose programming model is
 * supported on the JUnit Platform &mdash; for example, a JUnit Jupiter test class.
 * Note, however, that any test class run with this runner must be {@code public}
 * in order to be picked up by IDEs and build tools.
 *
 * @since 1.0
 * @see SelectPackages
 * @see SelectClasses
 * @see IncludeClassNamePattern
 * @see IncludeTags
 * @see ExcludeTags
 * @see IncludeEngines
 * @see ExcludeEngines
 */
@API(Maintained)
public class JUnitPlatform extends Runner implements Filterable {

	private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[0];
	private static final String[] EMPTY_STRING_ARRAY = new String[0];
	private static final String EMPTY_STRING = "";

	private final Class<?> testClass;
	private final Launcher launcher;

	private LauncherDiscoveryRequest discoveryRequest;
	private JUnitPlatformTestTree testTree;

	public JUnitPlatform(Class<?> testClass) throws InitializationError {
		this(testClass, LauncherFactory.create());
	}

	// For testing only
	JUnitPlatform(Class<?> testClass, Launcher launcher) throws InitializationError {
		this.launcher = launcher;
		this.testClass = testClass;
		this.discoveryRequest = createDiscoveryRequest();
		this.testTree = generateTestTree();
	}

	@Override
	public Description getDescription() {
		return this.testTree.getSuiteDescription();
	}

	@Override
	public void run(RunNotifier notifier) {
		JUnitPlatformRunnerListener listener = new JUnitPlatformRunnerListener(this.testTree, notifier);
		this.launcher.registerTestExecutionListeners(listener);
		this.launcher.execute(this.discoveryRequest);
	}

	private JUnitPlatformTestTree generateTestTree() {
		Preconditions.notNull(this.discoveryRequest, "DiscoveryRequest must not be null");
		TestPlan plan = this.launcher.discover(this.discoveryRequest);
		return new JUnitPlatformTestTree(plan, testClass);
	}

	private LauncherDiscoveryRequest createDiscoveryRequest() {
		List<DiscoverySelector> selectors = getSelectorsFromAnnotations();

		// Allows to simply add @RunWith(JUnitPlatform.class) to any test case
		if (selectors.isEmpty()) {
			selectors.add(selectClass(this.testClass));
		}

		LauncherDiscoveryRequestBuilder requestBuilder = request().selectors(selectors);
		addFiltersFromAnnotations(requestBuilder);
		return requestBuilder.build();
	}

	private void addFiltersFromAnnotations(LauncherDiscoveryRequestBuilder requestBuilder) {
		addIncludeClassNamePatternFilter(requestBuilder);

		addIncludedTagsFilter(requestBuilder);
		addExcludedTagsFilter(requestBuilder);

		addIncludedEnginesFilter(requestBuilder);
		addExcludedEnginesFilter(requestBuilder);
	}

	private List<DiscoverySelector> getSelectorsFromAnnotations() {
		List<DiscoverySelector> selectors = new ArrayList<>();

		selectors.addAll(transform(getSelectedClasses(), DiscoverySelectors::selectClass));
		selectors.addAll(transform(getSelectedPackageNames(), DiscoverySelectors::selectPackage));

		return selectors;
	}

	private <T> List<DiscoverySelector> transform(T[] sourceElements, Function<T, DiscoverySelector> transformer) {
		return stream(sourceElements).map(transformer).collect(toList());
	}

	private void addIncludeClassNamePatternFilter(LauncherDiscoveryRequestBuilder requestBuilder) {
		String pattern = getIncludeClassNamePattern();
		if (!pattern.isEmpty()) {
			requestBuilder.filters(includeClassNamePattern(pattern));
		}
	}

	private void addIncludedTagsFilter(LauncherDiscoveryRequestBuilder requestBuilder) {
		String[] includedTags = getIncludedTags();
		if (includedTags.length > 0) {
			requestBuilder.filters(includeTags(includedTags));
		}
	}

	private void addExcludedTagsFilter(LauncherDiscoveryRequestBuilder requestBuilder) {
		String[] excludedTags = getExcludedTags();
		if (excludedTags.length > 0) {
			requestBuilder.filters(excludeTags(excludedTags));
		}
	}

	private void addIncludedEnginesFilter(LauncherDiscoveryRequestBuilder requestBuilder) {
		String[] engineIds = getIncludedEngineIds();
		if (engineIds.length > 0) {
			requestBuilder.filters(includeEngines(engineIds));
		}
	}

	private void addExcludedEnginesFilter(LauncherDiscoveryRequestBuilder requestBuilder) {
		String[] engineIds = getExcludedEngineIds();
		if (engineIds.length > 0) {
			requestBuilder.filters(excludeEngines(engineIds));
		}
	}

	private Class<?>[] getSelectedClasses() {
		return getValueFromAnnotation(SelectClasses.class, SelectClasses::value, EMPTY_CLASS_ARRAY);
	}

	private String[] getSelectedPackageNames() {
		return getValueFromAnnotation(SelectPackages.class, SelectPackages::value, EMPTY_STRING_ARRAY);
	}

	private String[] getIncludedTags() {
		return getValueFromAnnotation(IncludeTags.class, IncludeTags::value, EMPTY_STRING_ARRAY);
	}

	private String[] getExcludedTags() {
		return getValueFromAnnotation(ExcludeTags.class, ExcludeTags::value, EMPTY_STRING_ARRAY);
	}

	private String[] getIncludedEngineIds() {
		return getValueFromAnnotation(IncludeEngines.class, IncludeEngines::value, EMPTY_STRING_ARRAY);
	}

	private String[] getExcludedEngineIds() {
		return getValueFromAnnotation(ExcludeEngines.class, ExcludeEngines::value, EMPTY_STRING_ARRAY);
	}

	private String getIncludeClassNamePattern() {
		return getValueFromAnnotation(IncludeClassNamePattern.class, IncludeClassNamePattern::value,
			EMPTY_STRING).trim();
	}

	private <A extends Annotation, V> V getValueFromAnnotation(Class<A> annotationClass, Function<A, V> extractor,
			V defaultValue) {
		A annotation = this.testClass.getAnnotation(annotationClass);
		return (annotation != null ? extractor.apply(annotation) : defaultValue);
	}

	@Override
	public void filter(Filter filter) throws NoTestsRemainException {
		Set<TestIdentifier> filteredIdentifiers = testTree.getFilteredLeaves(filter);
		if (filteredIdentifiers.isEmpty()) {
			throw new NoTestsRemainException();
		}
		this.discoveryRequest = createDiscoveryRequestForUniqueIds(filteredIdentifiers);
		this.testTree = generateTestTree();
	}

	private LauncherDiscoveryRequest createDiscoveryRequestForUniqueIds(Set<TestIdentifier> testIdentifiers) {
		// @formatter:off
		List<DiscoverySelector> selectors = testIdentifiers.stream()
				.map(TestIdentifier::getUniqueId)
				.map(DiscoverySelectors::selectUniqueId)
				.collect(toList());
		// @formatter:on
		return request().selectors(selectors).build();
	}

}
<commit_msg>Link to @UseTechnicalNames from JUnitPlatform runner Javadoc<commit_after>/*
 * Copyright 2015-2016 the original author or authors.
 *
 * All rights reserved. This program and the accompanying materials are
 * made available under the terms of the Eclipse Public License v1.0 which
 * accompanies this distribution and is available at
 *
 * http://www.eclipse.org/legal/epl-v10.html
 */

package org.junit.platform.runner;

import static java.util.Arrays.stream;
import static java.util.stream.Collectors.toList;
import static org.junit.platform.commons.meta.API.Usage.Maintained;
import static org.junit.platform.engine.discovery.ClassFilter.includeClassNamePattern;
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
import static org.junit.platform.launcher.EngineFilter.excludeEngines;
import static org.junit.platform.launcher.EngineFilter.includeEngines;
import static org.junit.platform.launcher.TagFilter.excludeTags;
import static org.junit.platform.launcher.TagFilter.includeTags;
import static org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder.request;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.function.Function;

import org.junit.platform.commons.meta.API;
import org.junit.platform.commons.util.Preconditions;
import org.junit.platform.engine.DiscoverySelector;
import org.junit.platform.engine.discovery.DiscoverySelectors;
import org.junit.platform.launcher.Launcher;
import org.junit.platform.launcher.LauncherDiscoveryRequest;
import org.junit.platform.launcher.TestIdentifier;
import org.junit.platform.launcher.TestPlan;
import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder;
import org.junit.platform.launcher.core.LauncherFactory;
import org.junit.runner.Description;
import org.junit.runner.Runner;
import org.junit.runner.manipulation.Filter;
import org.junit.runner.manipulation.Filterable;
import org.junit.runner.manipulation.NoTestsRemainException;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.model.InitializationError;

/**
 * JUnit 4 based {@link Runner} which runs tests on the JUnit Platform in a
 * JUnit 4 environment.
 *
 * <p>Annotating a class with {@code @RunWith(JUnitPlatform.class)} allows it
 * to be run with IDEs and build systems that support JUnit 4 but do not yet
 * support the JUnit Platform directly.
 *
 * <p>Consult the various annotations in this package for configuration options.
 *
 * <p>If you do not use any configuration annotations from this package, you
 * can simply use this runner on a test class whose programming model is
 * supported on the JUnit Platform &mdash; for example, a JUnit Jupiter test class.
 * Note, however, that any test class run with this runner must be {@code public}
 * in order to be picked up by IDEs and build tools.
 *
 * @since 1.0
 * @see SelectPackages
 * @see SelectClasses
 * @see IncludeClassNamePattern
 * @see IncludeTags
 * @see ExcludeTags
 * @see IncludeEngines
 * @see ExcludeEngines
 * @see UseTechnicalNames
 */
@API(Maintained)
public class JUnitPlatform extends Runner implements Filterable {

	private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[0];
	private static final String[] EMPTY_STRING_ARRAY = new String[0];
	private static final String EMPTY_STRING = "";

	private final Class<?> testClass;
	private final Launcher launcher;

	private LauncherDiscoveryRequest discoveryRequest;
	private JUnitPlatformTestTree testTree;

	public JUnitPlatform(Class<?> testClass) throws InitializationError {
		this(testClass, LauncherFactory.create());
	}

	// For testing only
	JUnitPlatform(Class<?> testClass, Launcher launcher) throws InitializationError {
		this.launcher = launcher;
		this.testClass = testClass;
		this.discoveryRequest = createDiscoveryRequest();
		this.testTree = generateTestTree();
	}

	@Override
	public Description getDescription() {
		return this.testTree.getSuiteDescription();
	}

	@Override
	public void run(RunNotifier notifier) {
		JUnitPlatformRunnerListener listener = new JUnitPlatformRunnerListener(this.testTree, notifier);
		this.launcher.registerTestExecutionListeners(listener);
		this.launcher.execute(this.discoveryRequest);
	}

	private JUnitPlatformTestTree generateTestTree() {
		Preconditions.notNull(this.discoveryRequest, "DiscoveryRequest must not be null");
		TestPlan plan = this.launcher.discover(this.discoveryRequest);
		return new JUnitPlatformTestTree(plan, testClass);
	}

	private LauncherDiscoveryRequest createDiscoveryRequest() {
		List<DiscoverySelector> selectors = getSelectorsFromAnnotations();

		// Allows to simply add @RunWith(JUnitPlatform.class) to any test case
		if (selectors.isEmpty()) {
			selectors.add(selectClass(this.testClass));
		}

		LauncherDiscoveryRequestBuilder requestBuilder = request().selectors(selectors);
		addFiltersFromAnnotations(requestBuilder);
		return requestBuilder.build();
	}

	private void addFiltersFromAnnotations(LauncherDiscoveryRequestBuilder requestBuilder) {
		addIncludeClassNamePatternFilter(requestBuilder);

		addIncludedTagsFilter(requestBuilder);
		addExcludedTagsFilter(requestBuilder);

		addIncludedEnginesFilter(requestBuilder);
		addExcludedEnginesFilter(requestBuilder);
	}

	private List<DiscoverySelector> getSelectorsFromAnnotations() {
		List<DiscoverySelector> selectors = new ArrayList<>();

		selectors.addAll(transform(getSelectedClasses(), DiscoverySelectors::selectClass));
		selectors.addAll(transform(getSelectedPackageNames(), DiscoverySelectors::selectPackage));

		return selectors;
	}

	private <T> List<DiscoverySelector> transform(T[] sourceElements, Function<T, DiscoverySelector> transformer) {
		return stream(sourceElements).map(transformer).collect(toList());
	}

	private void addIncludeClassNamePatternFilter(LauncherDiscoveryRequestBuilder requestBuilder) {
		String pattern = getIncludeClassNamePattern();
		if (!pattern.isEmpty()) {
			requestBuilder.filters(includeClassNamePattern(pattern));
		}
	}

	private void addIncludedTagsFilter(LauncherDiscoveryRequestBuilder requestBuilder) {
		String[] includedTags = getIncludedTags();
		if (includedTags.length > 0) {
			requestBuilder.filters(includeTags(includedTags));
		}
	}

	private void addExcludedTagsFilter(LauncherDiscoveryRequestBuilder requestBuilder) {
		String[] excludedTags = getExcludedTags();
		if (excludedTags.length > 0) {
			requestBuilder.filters(excludeTags(excludedTags));
		}
	}

	private void addIncludedEnginesFilter(LauncherDiscoveryRequestBuilder requestBuilder) {
		String[] engineIds = getIncludedEngineIds();
		if (engineIds.length > 0) {
			requestBuilder.filters(includeEngines(engineIds));
		}
	}

	private void addExcludedEnginesFilter(LauncherDiscoveryRequestBuilder requestBuilder) {
		String[] engineIds = getExcludedEngineIds();
		if (engineIds.length > 0) {
			requestBuilder.filters(excludeEngines(engineIds));
		}
	}

	private Class<?>[] getSelectedClasses() {
		return getValueFromAnnotation(SelectClasses.class, SelectClasses::value, EMPTY_CLASS_ARRAY);
	}

	private String[] getSelectedPackageNames() {
		return getValueFromAnnotation(SelectPackages.class, SelectPackages::value, EMPTY_STRING_ARRAY);
	}

	private String[] getIncludedTags() {
		return getValueFromAnnotation(IncludeTags.class, IncludeTags::value, EMPTY_STRING_ARRAY);
	}

	private String[] getExcludedTags() {
		return getValueFromAnnotation(ExcludeTags.class, ExcludeTags::value, EMPTY_STRING_ARRAY);
	}

	private String[] getIncludedEngineIds() {
		return getValueFromAnnotation(IncludeEngines.class, IncludeEngines::value, EMPTY_STRING_ARRAY);
	}

	private String[] getExcludedEngineIds() {
		return getValueFromAnnotation(ExcludeEngines.class, ExcludeEngines::value, EMPTY_STRING_ARRAY);
	}

	private String getIncludeClassNamePattern() {
		return getValueFromAnnotation(IncludeClassNamePattern.class, IncludeClassNamePattern::value,
			EMPTY_STRING).trim();
	}

	private <A extends Annotation, V> V getValueFromAnnotation(Class<A> annotationClass, Function<A, V> extractor,
			V defaultValue) {
		A annotation = this.testClass.getAnnotation(annotationClass);
		return (annotation != null ? extractor.apply(annotation) : defaultValue);
	}

	@Override
	public void filter(Filter filter) throws NoTestsRemainException {
		Set<TestIdentifier> filteredIdentifiers = testTree.getFilteredLeaves(filter);
		if (filteredIdentifiers.isEmpty()) {
			throw new NoTestsRemainException();
		}
		this.discoveryRequest = createDiscoveryRequestForUniqueIds(filteredIdentifiers);
		this.testTree = generateTestTree();
	}

	private LauncherDiscoveryRequest createDiscoveryRequestForUniqueIds(Set<TestIdentifier> testIdentifiers) {
		// @formatter:off
		List<DiscoverySelector> selectors = testIdentifiers.stream()
				.map(TestIdentifier::getUniqueId)
				.map(DiscoverySelectors::selectUniqueId)
				.collect(toList());
		// @formatter:on
		return request().selectors(selectors).build();
	}

}

{'fraction_non_alphanumeric': 0.09370988446726572, 'fraction_numerical': 0.0025673940949935813, 'mean_word_length': 6.352482560525236, 'pattern_counts': {'":': 0, '<': 47, '<?xml version=': 0, '>': 55, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6650830', 'n_tokens_mistral': 5348, 'n_tokens_neox': 4972, 'n_words': 1130}