All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.nordstrom.automation.junit.AtomicTest Maven / Gradle / Ivy

There is a newer version: 17.1.1
Show newest version
package com.nordstrom.automation.junit;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.experimental.theories.Theory;
import org.junit.runner.Description;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.TestClass;

/**
 * This class represents an atomic JUnit test, which is composed of a core {@link Test @Test} method and
 * the configuration methods that run with it ({@link Before @Before}, {@link org.junit.After @After},
 * {@link org.junit.BeforeClass @BeforeClass}, and {@link AfterClass @AfterClass}).
 */
@Ignore
@SuppressWarnings("all")
public class AtomicTest {
    private final Object runner;
    private final Description description;
    private final FrameworkMethod identity;
    private final List particles;
    private Throwable thrown;
    
    private static final Pattern PARAM = Pattern.compile("[(\\[]");
    private static final List> TEST_TYPES = Arrays.asList(Test.class, Theory.class);
    
    public AtomicTest(Description description) {
        this.runner = Run.getThreadRunner();
        this.description = description;
        this.particles = getParticles(runner, description);
        this.identity = particles.isEmpty() ? null : particles.get(0);
    }

    /**
     * Get the runner for this atomic test.
     * 
     * @return {@code BlockJUnit4ClassRunner} object
     */
    public Object getRunner() {
        return runner;
    }

    /**
     * Get the description for this atomic test.
     * 
     * @return {@link Description} object
     */
    public Description getDescription() {
        return description;
    }

    /**
     * Get the "identity" method for this atomic test - the core {@link Test @Test} method.
     * 
     * @return core method associated with this atomic test (may be {@code null})
     */
    public FrameworkMethod getIdentity() {
        return identity;
    }
    
    /**
     * Get the "particle" methods of which this atomic test is composed.
     * 
     * @return list of methods that compose this atomic test (may be empty)
     */
    public List getParticles() {
        return particles;
    }

    /**
     * Determine if this atomic test includes configuration methods.
     * 
     * @return {@code true} if this atomic test includes configuration; otherwise {@code false}
     */
    public boolean hasConfiguration() {
        return (particles.size() > 1);
    }
    
    /**
     * Set the exception for this atomic test.
     * 
     * @param thrown exception for this atomic test
     */
    void setThrowable(Throwable thrown) {
        this.thrown = thrown;
    }
    
    /**
     * Get the exception for this atomic test.
     * 
     * @return exception for this atomic test; {@code null} if test finished normally
     */
    public Throwable getThrowable() {
        return thrown;
    }
    
    /**
     * Determine if this atomic test includes the specified method.
     * 
     * @param method method object
     * @return {@code true} if this atomic test includes the specified method; otherwise {@code false}
     */
    public boolean includes(FrameworkMethod method) {
        return particles.contains(method);
    }
    
    /**
     * Determine if this atomic test represents a "theory" method permutation.
     * 
     * @return {@code true} if this atomic test represents a permutation; otherwise {@code false}
     */
    public boolean isTheory() {
        return isTheory(description);
    }
    
    /**
     * Determine if the specified description represents a "theory" method permutation.
     * 
     * @param description JUnit method description
     * @return {@code true} if the specified description represents a permutation; otherwise {@code false}
     */
    public static boolean isTheory(Description description) {
        return DescribeChild.isPermutation(description);
    }
    
    /**
     * Determine if this atomic test represents a test method.
     * 
     * @return {@code true} if this atomic test represents a test method; otherwise {@code false} 
     */
    public boolean isTest() {
        return isTest(description);
    }
    
    /**
     * Determine if the specified description represents a test method.
     * 
     * @param description JUnit description object
     * @return {@code true} if description represents a test method; otherwise {@code false} 
     */
    public static boolean isTest(Description description) {
        return (getTestAnnotation(description) != null);
    }
    
    /**
     * Get the annotation that marks the specified description as a test method.
     * 
     * @param description JUnit description object
     * @return if description represents a test method, the {@link Test} or {@link Theory} annotation;
     * otherwise {@code null}
     */
    public static Annotation getTestAnnotation(Description description) {
        for (Annotation annotation : description.getAnnotations()) {
            if (TEST_TYPES.contains(annotation.annotationType())) return annotation;
        }
        return null;
    }
    
    /**
     * {@inheritDoc}
     */
    @Override
    public String toString() {
        return description.toString();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null) return false;
        if ( ! (o instanceof AtomicTest)) return false;
        AtomicTest that = (AtomicTest) o;
        return Objects.equals(runner, that.runner) &&
                Objects.equals(identity, that.identity);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public int hashCode() {
        return description.hashCode();
    }
    
    /**
     * Get the "particle" method for this atomic test.
     * 
     * @param runner JUnit test runner
     * @param description JUnit method description
     * @return list of "particle" methods (may be empty)
     */
    private List getParticles(Object runner, Description description) {
        List particles = new ArrayList<>();
        if (isTest(description)) {
            TestClass testClass = LifecycleHooks.getTestClassOf(runner);
            
            String methodName = description.getMethodName();
            Matcher matcher = PARAM.matcher(methodName);
            if (matcher.find()) {
                methodName = methodName.substring(0, matcher.start());
            }
            
            FrameworkMethod identity = null;
            for (FrameworkMethod method : testClass.getAnnotatedMethods()) {
                if (method.getName().equals(methodName)) {
                    identity = method;
                    break;
                }
            }
            
            if (identity != null) {
                particles.add(identity);
                particles.addAll(testClass.getAnnotatedMethods(Before.class));
                particles.addAll(testClass.getAnnotatedMethods(After.class));
            } else {
                throw new IllegalStateException("Identity method not found");
            }
        }
        
        return particles;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy