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

ar.com.dgarcia.javaspec.api.JavaSpec Maven / Gradle / Ivy

The newest version!
package ar.com.dgarcia.javaspec.api;

import ar.com.dgarcia.javaspec.api.contexts.TestContext;
import ar.com.dgarcia.javaspec.api.exceptions.FailingRunnable;
import ar.com.dgarcia.javaspec.api.exceptions.SpecException;
import ar.com.dgarcia.javaspec.api.variable.Let;
import ar.com.dgarcia.javaspec.impl.model.SpecTree;
import ar.com.dgarcia.javaspec.impl.modes.DefinitionMode;
import ar.com.dgarcia.javaspec.impl.modes.ExecutionMode;
import ar.com.dgarcia.javaspec.impl.modes.InitialMode;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.function.Consumer;

/**
 * This class is the extension point to add testing expressiveness with Java Specs.
* The method idiom is copied from: http://jasmine.github.io/2.0/introduction.html.
* Created by kfgodel on 12/07/14. */ public abstract class JavaSpec implements JavaSpecApi { private ExecutionMode currentMode = InitialMode.create(); /** * Starting method to define the specs.
* This method must be extended by subclasses and define any spec as calls to describe() and it() */ public abstract void define(); /** * Uses the user definition of this spec class (contained in the define() method) to create * the nodes in the given tree.
* * @param specTree The tree that will represent this spec */ public void populate(SpecTree specTree) { DefinitionMode definitionMode = DefinitionMode.create(specTree, getContextTypeFromSubclassDeclaration()); this.currentMode = definitionMode; this.define(); // Switch to execution mode to prepare for test to be run this.currentMode = definitionMode.changeToRunning(); } /** * Using reflection gets the concrete type used to parameterize this class.
* That parameter is going to be proxied later and made available to the user * @return The concrete test context subtype or an exception if pre-conditions are not met */ public Class getContextTypeFromSubclassDeclaration() { Class subClass = getClass(); if (!(subClass.getSuperclass().equals(JavaSpec.class))) { throw new SpecException("A java spec class[" + subClass + "] must inherit directly from " + JavaSpec.class); } Type generifiedJavaSpec = subClass.getGenericSuperclass(); if (!(generifiedJavaSpec instanceof ParameterizedType)) { throw new SpecException("JavaSpec superclass must be generified with a type of TestContext. For example JavaSpec"); } Type contextType = ((ParameterizedType) generifiedJavaSpec).getActualTypeArguments()[0]; return getClassInstanceFromArgument(contextType); } /** * Tries toget the raw class instance that represents the interface defining the test context * @param contextType The type that is found on the spec declaration * @return The class instance that represents the test context interface */ private Class getClassInstanceFromArgument(Type contextType) throws SpecException { if (contextType instanceof ParameterizedType) { // It's another generic type, it may be a class based context ParameterizedType parameterizedArgument = (ParameterizedType) contextType; Type rawType = parameterizedArgument.getRawType(); if (!(rawType instanceof Class)) { throw new SpecException("JavaSpec parameterization can't reference a generic type: " + rawType); } return (Class) rawType; } if (!(contextType instanceof Class)) { throw new SpecException("JavaSpec generic parameter can't be a type wildcard: " + contextType); } return (Class) contextType; } // ************************************************** // Any API call delegate it to the api to build the meta tree for the spec description // or execute running test behavior // ************************************************** @Override public T context() { return currentMode.context(); } @Override public Let localLet(String variableName) { return currentMode.localLet(variableName); } @Override public void xdescribe(String aGroupName, Runnable aGroupDefinition) { currentMode.xdescribe(aGroupName, aGroupDefinition); } @Override public void xdescribe(Class aGroupName, Runnable aGroupDefinition) { currentMode.xdescribe(aGroupName, aGroupDefinition); } @Override public void describe(Class aClass, Runnable aGroupDefinition) { currentMode.describe(aClass, aGroupDefinition); } @Override public void describe(String aGroupName, Runnable aGroupDefinition) { currentMode.describe(aGroupName, aGroupDefinition); } @Override public void xit(String testName, Runnable aTestCode) { currentMode.xit(testName, aTestCode); } @Override public void xit(String testName) { currentMode.xit(testName); } @Override public void it(String testName, Runnable aTestCode) { currentMode.it(testName, aTestCode); } @Override public void afterEach(Runnable aCodeBlock) { currentMode.afterEach(aCodeBlock); } @Override public void beforeEach(Runnable aCodeBlock) { currentMode.beforeEach(aCodeBlock); } @Override public void itThrows(Class expectedExceptionType, String testNameSuffix, FailingRunnable aTestCode, Consumer exceptionAssertions) throws SpecException { currentMode.itThrows(expectedExceptionType, testNameSuffix, aTestCode, exceptionAssertions); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy