Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue736 unit testing w prop files take2 #742

Open
wants to merge 22 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Large refactor
  • Loading branch information
ee-usgs committed Nov 1, 2022
commit 0f8797f9ae34622dd4e7be429a67012bbda2dddb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.yarnandtail.andhow.junit5;

import org.junit.jupiter.api.extension.ExtendWith;
import org.yarnandtail.andhow.junit5.ext.ConfigFromFileBeforeAllTestsExt;

import java.lang.annotation.*;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Target({ TYPE, ANNOTATION_TYPE })
@Retention(RUNTIME)
@ExtendWith(ConfigFromFileBeforeAllTestsExt.class)
public @interface ConfigFromFileBeforeAllTests {
String filePath();
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
package org.yarnandtail.andhow.junit5;

import org.junit.jupiter.api.extension.ExtendWith;
import org.yarnandtail.andhow.junit5.ext.ConfigFromFileExt;
import org.yarnandtail.andhow.junit5.ext.ConfigFromFileBeforeEachTestExt;

import java.lang.annotation.*;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Target({ TYPE, METHOD, ANNOTATION_TYPE })
@Target({ TYPE, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Inherited
@ExtendWith(ConfigFromFileExt.class)
public @interface ConfigFromFile {
@ExtendWith(ConfigFromFileBeforeEachTestExt.class)
public @interface ConfigFromFileBeforeEachTest {
String filePath();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.yarnandtail.andhow.junit5;

import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.yarnandtail.andhow.junit5.ext.ConfigFromFileBaseExt;
import org.yarnandtail.andhow.junit5.ext.ConfigFromFileBeforeThisTestExt;

import java.lang.annotation.*;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Target({ METHOD, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Inherited
@ExtendWith(ConfigFromFileBeforeThisTestExt.class)
public @interface ConfigFromFileBeforeThisTest {
String filePath();
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,21 @@
import org.junit.jupiter.api.extension.*;
import org.yarnandtail.andhow.*;
import org.yarnandtail.andhow.api.StandardLoader;
import org.yarnandtail.andhow.junit5.ConfigFromFile;
import org.yarnandtail.andhow.load.std.*;
import org.yarnandtail.andhow.testutil.AndHowTestUtils;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Optional;
import java.util.function.UnaryOperator;

public class ConfigFromFileExt extends ExtensionBase
implements BeforeAllCallback, AfterAllCallback, BeforeEachCallback, AfterEachCallback {
/**
* Implementation of an ExtensionBase that configures AndHow from a single properties
* file. It is the base class to be used in one of three modes:
* <li>BeforeAll/AfterAll Registered on a test class</li>
* <li>BeforeEach/AfterEach Registered on a test class to apply to all methods</li>
* <li>BeforeEach/AfterEach Registered on a test method to apply to a single test</li>
* Mixing purposes (i.e. a single instance registered for use for more than one mode)
* can result in confused state.
*/
public abstract class ConfigFromFileBaseExt extends ExtensionBase {

/** The complete path to a properties file on the classpath */
private String _classpathFile;
Expand All @@ -25,50 +29,34 @@ public class ConfigFromFileExt extends ExtensionBase
* New instance - validation of the classpathFile is deferred until use.
* @param classpathFile Complete path to a properties file on the classpath
*/
public ConfigFromFileExt(String classpathFile) {
public ConfigFromFileBaseExt(String classpathFile) {
if (classpathFile == null) {
throw new IllegalArgumentException("The classpath properties file path cannot be null.");
}
_classpathFile = classpathFile;
}

public ConfigFromFileExt() {
// Empty constructor used when the @ConfigFromFile annotation is used.
// In that case, the classpathFile is found via the annotation filePath property.
}
/**
* Empty constructor used when the \@ConfigFromFile annotation is used.
*
* When the empty construct is used, the classpathFile is found via the
* \@ConfigFromFile annotation filePath property.
*/
public ConfigFromFileBaseExt() { }

/**
* When this Extension is being used in association w/ an annotation, this returns
* that class.
* @return
*/
protected abstract String getAnnotationFilePath(ExtensionContext context);

// Would this be confused, called for BeforeAll and BeforeEach, etc, if there
// were both class and test annotations on a test? How would that be kept straight?
// Might need to split up these
protected String getClasspathFile(ExtensionContext context) {
if (_classpathFile == null) {
Class<?> clazz = context.getRequiredTestClass();
Optional<Method> method = context.getTestMethod();

ConfigFromFile cff;

if (method.isPresent()) {
cff = method.get().getAnnotation(ConfigFromFile.class);

if (cff == null) {
throw new IllegalStateException("Expected the @ConfigFromFile annotation on the '" +
method.get().getName() + "' method.");
}

} else {

cff = clazz.getAnnotation(ConfigFromFile.class);

if (cff == null) {
throw new IllegalStateException("Expected the @ConfigFromFile annotation on class '" +
clazz.getName() + "'.");
}

}

_classpathFile = cff.filePath();
_classpathFile = getAnnotationFilePath(context);
}

System.out.println("CFF: filePath = " + _classpathFile);
return _classpathFile;
}

Expand Down Expand Up @@ -96,7 +84,6 @@ protected String getClasspathFile(ExtensionContext context) {
* @param context Passed by JUnit prior to any test in the class
* @throws Exception
*/
@Override
public void beforeAll(ExtensionContext context) throws Exception {

// remove current core and keep to be later restored
Expand All @@ -113,9 +100,9 @@ public void beforeAll(ExtensionContext context) throws Exception {
CONFIG_KEY,
AndHowTestUtils.setAndHowInProcessConfig(_config));

System.out.println("CFF: beforeAll: filePath = " + fullPath);
}

@Override
public void afterAll(ExtensionContext context) throws Exception {
Object core = getPerTestClassStore(context).remove(CORE_KEY, AndHowTestUtils.getAndHowCoreClass());
AndHowTestUtils.setAndHowCore(core);
Expand All @@ -131,7 +118,6 @@ public void afterAll(ExtensionContext context) throws Exception {
* @param context
* @throws Exception
*/
@Override
public void beforeEach(ExtensionContext context) throws Exception {
getPerTestMethodStore(context).put(CORE_KEY, AndHowTestUtils.setAndHowCore(null));

Expand All @@ -145,14 +131,15 @@ public void beforeEach(ExtensionContext context) throws Exception {
getPerTestMethodStore(context).put(
CONFIG_KEY,
AndHowTestUtils.setAndHowInProcessConfig(_config));

System.out.println("CFF: beforeEach: filePath = " + fullPath);
}

/**
* Restore the state of AndHow to what it was before this test.
* @param context
* @throws Exception
*/
@Override
public void afterEach(ExtensionContext context) throws Exception {
Object core = getPerTestMethodStore(context).remove(CORE_KEY, AndHowTestUtils.getAndHowCoreClass());
AndHowTestUtils.setAndHowCore(core);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package org.yarnandtail.andhow.junit5.ext;

import org.junit.jupiter.api.extension.*;
import org.yarnandtail.andhow.junit5.ConfigFromFileBeforeAllTests;

public class ConfigFromFileBeforeAllTestsExt extends ConfigFromFileBaseExt
implements BeforeAllCallback, AfterAllCallback {

/**
* Empty constructor used when the \@ConfigFromFileBeforeThisTest annotation is used.
*
* When the empty construct is used, the classpathFile is found via the
* \@ConfigFromFile annotation filePath property.
*/
public ConfigFromFileBeforeAllTestsExt() {
super();
}

/**
* New instance - validation of the classpathFile is deferred until use.
* @param classpathFile Complete path to a properties file on the classpath
*/
public ConfigFromFileBeforeAllTestsExt(String classpathFile) {
super(classpathFile);
}

@Override
protected String getAnnotationFilePath(ExtensionContext context) {
if (context.getElement().isPresent()) {
ConfigFromFileBeforeAllTests cff = context.getElement().get().getAnnotation(ConfigFromFileBeforeAllTests.class);
return cff.filePath();
} else {
throw new IllegalStateException("Expected the @ConfigFromFileBeforeAllTests annotation on the '" +
context.getRequiredTestMethod() + "' test method.");
}
}

@Override
public void beforeAll(final ExtensionContext context) throws Exception {
super.beforeAll(context);
}

@Override
public void afterAll(final ExtensionContext context) throws Exception {
super.afterAll(context);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package org.yarnandtail.andhow.junit5.ext;

import org.junit.jupiter.api.extension.*;
import org.yarnandtail.andhow.junit5.ConfigFromFileBeforeEachTest;

public class ConfigFromFileBeforeEachTestExt extends ConfigFromFileBaseExt
implements BeforeEachCallback, AfterEachCallback {

/**
* Empty constructor used when the \@ConfigFromFileBeforeThisTest annotation is used.
*
* When the empty construct is used, the classpathFile is found via the
* \@ConfigFromFile annotation filePath property.
*/
public ConfigFromFileBeforeEachTestExt() {
super();
}

/**
* New instance - validation of the classpathFile is deferred until use.
* @param classpathFile Complete path to a properties file on the classpath
*/
public ConfigFromFileBeforeEachTestExt(String classpathFile) {
super(classpathFile);
}

@Override
protected String getAnnotationFilePath(ExtensionContext context) {
if (context.getElement().isPresent()) {
ConfigFromFileBeforeEachTest cff = context.getElement().get().getAnnotation(ConfigFromFileBeforeEachTest.class);
return cff.filePath();
} else {
throw new IllegalStateException("Expected the @ConfigFromFileBeforeEachTest annotation on the '" +
context.getRequiredTestMethod() + "' test method.");
}
}

@Override
public void beforeEach(final ExtensionContext context) throws Exception {
super.beforeEach(context);
}

@Override
public void afterEach(final ExtensionContext context) throws Exception {
super.afterEach(context);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package org.yarnandtail.andhow.junit5.ext;

import org.junit.jupiter.api.extension.*;
import org.yarnandtail.andhow.junit5.ConfigFromFileBeforeThisTest;

public class ConfigFromFileBeforeThisTestExt extends ConfigFromFileBaseExt
implements BeforeEachCallback, AfterEachCallback {

/**
* Empty constructor used when the \@ConfigFromFileBeforeThisTest annotation is used.
*
* When the empty construct is used, the classpathFile is found via the
* \@ConfigFromFile annotation filePath property.
*/
public ConfigFromFileBeforeThisTestExt() {
super();
}

/**
* New instance - validation of the classpathFile is deferred until use.
* @param classpathFile Complete path to a properties file on the classpath
*/
public ConfigFromFileBeforeThisTestExt(String classpathFile) {
super(classpathFile);
}

@Override
protected String getAnnotationFilePath(ExtensionContext context) {
if (context.getElement().isPresent()) {
ConfigFromFileBeforeThisTest cff = context.getElement().get().getAnnotation(ConfigFromFileBeforeThisTest.class);
return cff.filePath();
} else {
throw new IllegalStateException("Expected the @ConfigFromFileBeforeThisTest annotation on the '" +
context.getRequiredTestMethod() + "' test method.");
}
}

@Override
public void beforeEach(final ExtensionContext context) throws Exception {
super.beforeEach(context);
}

@Override
public void afterEach(final ExtensionContext context) throws Exception {
super.afterEach(context);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import org.junit.jupiter.api.*;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.mockito.*;
import org.yarnandtail.andhow.junit5.ext.ConfigFromFileExt;
import org.yarnandtail.andhow.junit5.ext.ConfigFromFileBaseExt;
import org.yarnandtail.andhow.testutil.AndHowTestUtils;

import static org.junit.jupiter.api.Assertions.*;
Expand All @@ -13,7 +13,7 @@
* so the only way to refer to such is a class is to also be in the default
* package, thus this test class.
*/
class ConfigFromFileExtDefaultPackageTest {
class ConfigFromFileBaseExtDefaultPackageTest {

Object andHowCoreCreatedDuringTest;

Expand Down Expand Up @@ -58,7 +58,7 @@ void tearDown() {

@Test
public void expandPathShouldExpandRelativePaths() {
ConfigFromFileExtSimple ext = new ConfigFromFileExtSimple();
ConfigFromFileBaseExtSimple ext = new ConfigFromFileBaseExtSimple();

assertEquals("/myFile.props",
ext.expandPath("myFile.props", extensionContext));
Expand All @@ -71,7 +71,7 @@ public void expandPathShouldExpandRelativePaths() {

@Test
public void expandPathShouldNotExpandAbsPaths() {
ConfigFromFileExtSimple ext = new ConfigFromFileExtSimple();
ConfigFromFileBaseExtSimple ext = new ConfigFromFileBaseExtSimple();

assertEquals("/myFile.props",
ext.expandPath("/myFile.props", extensionContext));
Expand All @@ -89,11 +89,15 @@ public void expandPathShouldNotExpandAbsPaths() {
}

/* Simple subclass to test protected methods */
public static class ConfigFromFileExtSimple extends ConfigFromFileExt {
public ConfigFromFileExtSimple() {
public static class ConfigFromFileBaseExtSimple extends ConfigFromFileBaseExt {
public ConfigFromFileBaseExtSimple() {
super("");
}

public String getAnnotationFilePath(ExtensionContext context) {
return "";
}

public String expandPath(String classpath, ExtensionContext context) {
return super.expandPath(classpath, context);
}
Expand Down
Loading