/*
 * 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.launcher.core;

import static org.junit.jupiter.api.Assertions.assertAll;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectMethod;
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectPackage;
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectUniqueId;
import static org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder.request;

import java.lang.reflect.Method;

import org.junit.jupiter.api.Test;
import org.junit.platform.engine.DiscoverySelector;
import org.junit.platform.engine.EngineDiscoveryRequest;
import org.junit.platform.engine.UniqueId;
import org.junit.platform.engine.discovery.ClassSelector;
import org.junit.platform.engine.discovery.DiscoverySelectors;
import org.junit.platform.engine.discovery.MethodSelector;
import org.junit.platform.engine.discovery.PackageSelector;
import org.junit.platform.engine.discovery.UniqueIdSelector;

/**
 * Unit tests for {@link DefaultDiscoveryRequest}.
 *
 * @since 1.0
 */
public class DiscoveryRequestTests {

	private static final Method fullyQualifiedMethod = fullyQualifiedMethod();

	private static final String fullyQualifiedMethodName = fullyQualifiedMethodName();

	@Test
	void selectMethodByFullyQualifiedName() throws Exception {
		MethodSelector selector = selectMethod(fullyQualifiedMethodName);
		assertEquals(fullyQualifiedMethod, selector.getJavaMethod());
	}

	@Test
	@SuppressWarnings("deprecation")
	void selectNameWithPackageName() {
		DiscoverySelector selector = DiscoverySelectors.selectName("org.junit.platform");
		assertEquals(PackageSelector.class, selector.getClass());
	}

	@Test
	@SuppressWarnings("deprecation")
	void selectNameWithClassName() {
		DiscoverySelector selector = DiscoverySelectors.selectName(getClass().getName());
		assertEquals(ClassSelector.class, selector.getClass());
	}

	@Test
	@SuppressWarnings("deprecation")
	void selectNameWithMethodName() throws Exception {
		DiscoverySelector selector = DiscoverySelectors.selectName(fullyQualifiedMethodName);
		assertEquals(MethodSelector.class, selector.getClass());
	}

	@Test
	void buildDiscoveryRequest() {
		// @formatter:off
		EngineDiscoveryRequest spec = request().selectors(
			selectUniqueId(UniqueId.forEngine("fooEngine")),
			selectPackage("org.junit.platform"),
			selectClass(getClass()),
			selectMethod(fullyQualifiedMethodName)
		).build();

		assertAll(
			() -> assertEquals(1, spec.getSelectorsByType(UniqueIdSelector.class).size()),
			() -> assertEquals(1, spec.getSelectorsByType(PackageSelector.class).size()),
			() -> assertEquals(1, spec.getSelectorsByType(ClassSelector.class).size()),
			() -> assertEquals(1, spec.getSelectorsByType(MethodSelector.class).size())
		);
		// @formatter:on
	}

	private static String fullyQualifiedMethodName() {
		return DiscoveryRequestTests.class.getName() + "#" + fullyQualifiedMethod().getName();
	}

	private static Method fullyQualifiedMethod() {
		try {
			return DiscoveryRequestTests.class.getDeclaredMethod("myTest");
		}
		catch (Exception ex) {
			throw new IllegalStateException(ex);
		}
	}

	void myTest() {
	}

}

@@ -1738,36 +1738,19 @@
 edName()
- throws Exception
  %7B%0A
+
 %09%09Method
@@ -1801,32 +1801,32 @@
 iedMethodName);%0A
-
 %09%09assertEquals(f
@@ -1869,32 +1869,348 @@
 aMethod());%0A%09%7D%0A%0A
+%09@Test%0A%09void selectMethodWithParametersByMethodReference() throws Exception %7B%0A%09%09Method method = getClass().getDeclaredMethod(%22myTest%22, String.class);%0A%09%09MethodSelector selector = selectMethod(getClass(), method);%0A%09%09assertEquals(method, selector.getJavaMethod());%0A%09%09assertEquals(method, selector.getJavaMethod());%0A%09%7D%0A%0A
 %09@Test%0A%09@Suppres
@@ -2712,33 +2712,16 @@
 odName()
- throws Exception
  %7B%0A%09%09Dis
@@ -3882,10 +3882,42 @@
 ) %7B%0A%09%7D%0A%0A
+%09void myTest(String info) %7B%0A%09%7D%0A%0A
 %7D%0A

Introduce test for selectMethod() via method reference