/*******************************************************************************
* Copyright (c) 2012 BMW Car IT and others.
* 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.jnario.lib.tests;
import static com.google.common.collect.Lists.newArrayList;
import static org.hamcrest.core.Is.is;
import static org.jnario.lib.tests.ExampleGroupRunnerTest.ExampleWithNestedCustomRunner.CustomRunner.HAS_RUN;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.experimental.results.PrintableResult.testResult;
import static org.junit.experimental.results.ResultMatchers.hasFailureContaining;
import static org.junit.experimental.results.ResultMatchers.isSuccessful;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.hamcrest.Matcher;
import org.jnario.runner.Contains;
import org.jnario.runner.ExampleGroupRunner;
import org.jnario.runner.Extension;
import org.jnario.runner.NameProvider;
import org.jnario.runner.Named;
import org.jnario.runner.Order;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.internal.matchers.TypeSafeMatcher;
import org.junit.runner.Description;
import org.junit.runner.JUnitCore;
import org.junit.runner.RunWith;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.model.InitializationError;
/**
* @author Sebastian Benz - Initial contribution and API
*/
@SuppressWarnings({"unchecked", "restriction"})
public class ExampleGroupRunnerTest {
@RunWith(ExampleGroupRunner.class)
@Named("Example1 Name")
public static class Example {
@BeforeClass
public static void beforeClass(){
run("Example#beforeClass");
}
@Before
public void before(){
run("Example#before");
}
@Test
@Order(1)
@Named("Test 1")
public void first() throws Exception {
run("Example#first");
}
@Test
@Order(2)
@Named("Test 2")
public void second() throws Exception {
run("Example#second");
}
@After
public void after(){
run("Example#after");
}
@AfterClass
public static void afterClass(){
run("Example#afterClass");
}
}
@RunWith(ExampleGroupRunner.class)
@Named("Example2 Name")
public static class ExampleWithContext {
@Named("Context Name")
public static class SubExample{
@Test
@Order(3)
@Named("Test 2")
public void firstSubTest() throws Exception {
run("SubExample#firstSubTest");
}
@Test
@Order(4)
@Named("Test 3")
public void secondSubTest() throws Exception {
run("SubExample#secondSubTest");
}
}
@Test
@Named("Test 1")
public void firstTest() throws Exception {
run("ExampleWithContext#firstTest");
}
}
@RunWith(ExampleGroupRunner.class)
@Named("Example3 Name")
@Contains({Example.class, ExampleWithContext.class})
public static class ParentExample {
@Test
@Named("Parent Test 1")
public void first() throws Exception {
run("ParentExample#first");
}
}
@RunWith(ExampleGroupRunner.class)
public static class ExampleWithoutAnnotation {
@Test
public void test() throws Exception {
run("ExampleWithoutAnnotation#test");
}
}
public static class ExampleExtension{
@BeforeClass
public static void beforeClass(){
}
}
@RunWith(ExampleGroupRunner.class)
public static class ExampleWithExtension {
@Extension public static Example extensionExample = new Example();
@Test
@Order(1)
public void test1() throws Exception {
run("ExampleWithExtension#test1");
}
@Test
@Order(2)
public void test2() throws Exception {
run("ExampleWithExtension#test2");
}
}
@RunWith(ExampleGroupRunner.class)
public static class ExampleWithUninitializedExtension{
@Extension public Example uninitialized;
@Test
public void aTest() throws Exception {
}
}
@RunWith(ExampleGroupRunner.class)
public static class ExampleWithNestedCustomRunner{
public static class CustomRunner extends ExampleGroupRunner{
public static boolean HAS_RUN = false;
public CustomRunner(Class<?> testClass, NameProvider nameProvider, Set<Method> setups)
throws InitializationError {
super(testClass, nameProvider, setups);
}
@Override
public void run(RunNotifier notifier) {
HAS_RUN = true;
super.run(notifier);
}
}
@RunWith(CustomRunner.class)
public static class SubExample{
@Test
public void aTest() throws Exception {
}
}
}
private static List<String> executedTests = newArrayList();
@Before
public void clearExecutedTests(){
executedTests.clear();
}
@Test
public void shouldUseDefaultNameWithoutAnnotation() throws InitializationError {
assertThat(describe(ExampleWithoutAnnotation.class), is(desc(ExampleWithoutAnnotation.class.getName())));
}
@Test
public void shouldNameTestsAfterNamedAnnotation() throws Exception {
assertThat(describe(Example.class), is(
desc("Example1 Name",
desc("Test 1"),
desc("Test 2")
)));
}
@Test
public void shouldNestContextWithinTestClass() throws Exception {
assertThat(describe(ExampleWithContext.class), is(
desc("Example2 Name",
desc("Context Name",
desc("Test 2"),
desc("Test 3")
),
desc("Test 1")
)));
}
@Test
public void shouldNestContainedClassesWithinTestClass() throws Exception {
assertThat(describe(ParentExample.class), is(
desc("Example3 Name",
desc("Example1 Name",
desc("Test 1"),
desc("Test 2")
),
desc("Example2 Name",
desc("Context Name",
desc("Test 2"),
desc("Test 3")
),
desc("Test 1")
))));
}
@Test
public void shouldExecuteAllTests() throws Exception {
List<String> expected = newArrayList(
"Example#first",
"Example#second",
"SubExample#firstSubTest",
"SubExample#secondSubTest",
"ExampleWithContext#firstTest",
"ParentExample#first"
);
new JUnitCore().run(ParentExample.class);
for (String test : expected) {
Assert.assertTrue(executedTests.contains(test));
}
}
@Test
public void shouldExecuteAllSetupAndTearDownMethods() throws Exception {
List<String> expected = newArrayList(
"Example#beforeClass",
"Example#before",
"Example#first",
"Example#after",
"Example#before",
"Example#second",
"Example#after",
"Example#afterClass"
);
new JUnitCore().run(Example.class);
assertEquals(expected, executedTests);
}
@Test
public void shouldExecuteSetupAndTeardownMethodsInExtensions() throws Exception {
List<String> expected = newArrayList(
"Example#beforeClass",
"Example#before",
"ExampleWithExtension#test1",
"Example#after",
"Example#before",
"ExampleWithExtension#test2",
"Example#after",
"Example#afterClass"
);
new JUnitCore().run(ExampleWithExtension.class);
assertEquals(expected, executedTests);
}
@RunWith(ExampleGroupRunner.class)
public static class ExampleWithRule{
@Rule public TestRule testRule = new TestRule();
@Test
public void test() throws Exception{
}
}
@Test
public void shouldObeyRules(){
assertThat(testResult(ExampleWithRule.class), is(isSuccessful()));
assertTrue(TestRule.isExecuted());
}
@Test
public void throwsIllegalStateExceptionIfExceptionIsNotInitialized() throws Exception {
assertThat(testResult(ExampleWithUninitializedExtension.class), hasFailureContaining("uninitialized is not initialized"));
}
@Test
public void shouldUseNestedRunners() throws Exception {
new JUnitCore().run(ExampleWithNestedCustomRunner.class);
assertTrue(HAS_RUN);
// clean up
HAS_RUN = false;
}
private Description describe(Class<?> klass) throws InitializationError {
ExampleGroupRunner xspecRunner = new ExampleGroupRunner(klass);
Description description = xspecRunner.getDescription();
return description;
}
private Matcher<Description> desc(final String displayName, final Matcher<Description>... childrenMatchers) {
return new TypeSafeMatcher<Description>() {
public void describeTo(org.hamcrest.Description description) {
description.appendText(displayName);
}
@Override
public boolean matchesSafely(Description item) {
String name = getTestName(item);
if(!displayName.equals(name)){
return false;
}
for(int i = 0; i < childrenMatchers.length; i++){
Matcher<Description> matcher = childrenMatchers[i];
Description description = item.getChildren().get(i);
if(!matcher.matches(description)){
return false;
}
}
return true;
}
private String getTestName(Description desc) {
return desc.getDisplayName().split("\\(")[0];
}
};
}
public static void run(String testName){
executedTests.add(testName);
}
}