| 1 | package com.reallifedeveloper.tools.test.fitnesse; | |
| 2 | ||
| 3 | import java.text.DateFormat; | |
| 4 | import java.text.ParseException; | |
| 5 | import java.text.SimpleDateFormat; | |
| 6 | import java.util.Date; | |
| 7 | ||
| 8 | import org.checkerframework.checker.nullness.qual.Nullable; | |
| 9 | import org.slf4j.Logger; | |
| 10 | import org.slf4j.LoggerFactory; | |
| 11 | import org.springframework.context.ApplicationContext; | |
| 12 | import org.springframework.context.support.ClassPathXmlApplicationContext; | |
| 13 | import org.springframework.context.support.GenericApplicationContext; | |
| 14 | ||
| 15 | /** | |
| 16 | * Base class for all FitNesse fixtures. | |
| 17 | * | |
| 18 | * @author RealLifeDeveloper | |
| 19 | */ | |
| 20 | public class BaseFitNesseFixture { | |
| 21 | ||
| 22 | /** | |
| 23 | * The date format used by {@link #parseDate(String)} ({@value #DATE_FORMAT}). | |
| 24 | */ | |
| 25 | public static final String DATE_FORMAT = "yyyy-MM-dd"; | |
| 26 | ||
| 27 | private static final ThreadLocal<ApplicationContext> APPLICATION_CONTEXT = ThreadLocal | |
| 28 | .withInitial(() -> new GenericApplicationContext()); | |
| 29 | ||
| 30 | private final Logger logger = LoggerFactory.getLogger(getClass()); | |
| 31 | ||
| 32 | private @Nullable String comment; | |
| 33 | ||
| 34 | /** | |
| 35 | * Creates a new {@code BaseFitNesseFixture} object using the given Spring application context. The application context is associated | |
| 36 | * with the current thread, so this fixture instance is assumed to be used by a single thread. | |
| 37 | * | |
| 38 | * @param applicationContext the Spring application context to use, must not be {@code null} | |
| 39 | */ | |
| 40 | public BaseFitNesseFixture(ApplicationContext applicationContext) { | |
| 41 |
1
1. <init> : negated conditional → KILLED |
if (applicationContext == null) { |
| 42 | throw new IllegalArgumentException("applicationContext must not be null"); | |
| 43 | } | |
| 44 |
1
1. <init> : removed call to java/lang/ThreadLocal::set → KILLED |
APPLICATION_CONTEXT.set(applicationContext); |
| 45 | } | |
| 46 | ||
| 47 | /** | |
| 48 | * Creates a new {@code BaseFitNesseFixture} object reading the Spring application context from the given classpath resource, which | |
| 49 | * should be a Spring XML configuration file. | |
| 50 | * | |
| 51 | * @param springConfigurationResourceName name of the classpath resource containing Spring XML configuration, must not be {@code null} | |
| 52 | */ | |
| 53 | public BaseFitNesseFixture(String springConfigurationResourceName) { | |
| 54 | this(initApplicationContext(springConfigurationResourceName)); | |
| 55 | } | |
| 56 | ||
| 57 | private static ApplicationContext initApplicationContext(String springConfigurationResourceName) { | |
| 58 |
1
1. initApplicationContext : negated conditional → KILLED |
if (springConfigurationResourceName == null) { |
| 59 | throw new IllegalArgumentException("springConfigurationResourceName must not be null"); | |
| 60 | } | |
| 61 |
1
1. initApplicationContext : replaced return value with null for com/reallifedeveloper/tools/test/fitnesse/BaseFitNesseFixture::initApplicationContext → KILLED |
return new ClassPathXmlApplicationContext(springConfigurationResourceName); |
| 62 | } | |
| 63 | ||
| 64 | /** | |
| 65 | * A comment that is useful as documentation in most FitNesse tests. | |
| 66 | * <p> | |
| 67 | * Any FitNesse test that uses this base class can add the column "Comment", which in most cases is not used by the test, but is useful | |
| 68 | * as documentation of the test case. | |
| 69 | * | |
| 70 | * @return the comment that was written for the test case | |
| 71 | */ | |
| 72 | public @Nullable String getComment() { | |
| 73 |
1
1. getComment : replaced return value with "" for com/reallifedeveloper/tools/test/fitnesse/BaseFitNesseFixture::getComment → KILLED |
return comment; |
| 74 | } | |
| 75 | ||
| 76 | /** | |
| 77 | * Specifies a comment for the current test case. | |
| 78 | * | |
| 79 | * @param comment the comment that belongs to the test case | |
| 80 | */ | |
| 81 | public void setComment(String comment) { | |
| 82 | this.comment = comment; | |
| 83 | } | |
| 84 | ||
| 85 | /** | |
| 86 | * Gives the Spring {@code ApplicationContext} associated with this thread. | |
| 87 | * <p> | |
| 88 | * This method never returns {@code null}; if it is not possible to create an {@code ApplicationContext}, an exception is thrown. | |
| 89 | * <p> | |
| 90 | * Note that the {@code ApplicationContext} is managed statically, so if a class already has loaded a context using this method, and | |
| 91 | * another class is later used that wants to use a different configuration, no reload will happen automatically. In this case, you can | |
| 92 | * use the method {@link #resetApplicationContext()} to reset the context and force a reload. | |
| 93 | * | |
| 94 | * @return the Spring {@code ApplicationContext}, never {@code null} | |
| 95 | */ | |
| 96 | protected ApplicationContext getApplicationContext() { | |
| 97 |
1
1. getApplicationContext : replaced return value with null for com/reallifedeveloper/tools/test/fitnesse/BaseFitNesseFixture::getApplicationContext → RUN_ERROR |
return APPLICATION_CONTEXT.get(); |
| 98 | } | |
| 99 | ||
| 100 | /** | |
| 101 | * Sets the Spring {@code ApplicationContext} to {@code null}. This can be used to force a reload of the context the next time the | |
| 102 | * method {@link #getApplicationContext()} is called. | |
| 103 | */ | |
| 104 | public static void resetApplicationContext() { | |
| 105 | // applicationContext = null; | |
| 106 | } | |
| 107 | ||
| 108 | /** | |
| 109 | * Looks up a Spring bean of a given class in the {@code ApplicationContext}. This method never returns {@code null}; if the bean does | |
| 110 | * not exist, an exception is thrown. | |
| 111 | * | |
| 112 | * @param <T> the type of the Spring bean | |
| 113 | * @param beanClass the class of the Spring bean | |
| 114 | * | |
| 115 | * @return the Spring bean, never {@code null} | |
| 116 | */ | |
| 117 | protected <T> T getBean(Class<T> beanClass) { | |
| 118 |
1
1. getBean : replaced return value with null for com/reallifedeveloper/tools/test/fitnesse/BaseFitNesseFixture::getBean → KILLED |
return getApplicationContext().getBean(beanClass); |
| 119 | } | |
| 120 | ||
| 121 | /** | |
| 122 | * Gives an {@code org.slf4j.Logger} that can be used by the concrete fixture classes for logging. | |
| 123 | * | |
| 124 | * @return an {@code org.slf4j.Logger} | |
| 125 | */ | |
| 126 | protected Logger logger() { | |
| 127 |
1
1. logger : replaced return value with null for com/reallifedeveloper/tools/test/fitnesse/BaseFitNesseFixture::logger → KILLED |
return logger; |
| 128 | } | |
| 129 | ||
| 130 | /** | |
| 131 | * Parses a date string on the form {@value #DATE_FORMAT} and returns the corresponding {@code java.util.Date} object. | |
| 132 | * | |
| 133 | * @param date the date string to parse, should be on the form {@value #DATE_FORMAT} | |
| 134 | * | |
| 135 | * @return the {@code java.util.Date} corresponding to {@code date} | |
| 136 | * | |
| 137 | * @throws IllegalArgumentException if {@code date} cannot be parsed | |
| 138 | */ | |
| 139 | protected Date parseDate(String date) { | |
| 140 | DateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT); | |
| 141 | try { | |
| 142 |
1
1. parseDate : replaced return value with null for com/reallifedeveloper/tools/test/fitnesse/BaseFitNesseFixture::parseDate → KILLED |
return dateFormat.parse(date); |
| 143 | } catch (ParseException e) { | |
| 144 | throw new IllegalArgumentException("Unparseable date: " + date, e); | |
| 145 | } | |
| 146 | } | |
| 147 | ||
| 148 | /** | |
| 149 | * A null-safe toString method. | |
| 150 | * | |
| 151 | * @param o the object to be converted to string, can be {@code null} | |
| 152 | * | |
| 153 | * @return {@code null} if {@code o} is {@code null}, otherwise {@code o.toString()} | |
| 154 | */ | |
| 155 | protected @Nullable String toString(Object o) { | |
| 156 |
2
1. toString : replaced return value with "" for com/reallifedeveloper/tools/test/fitnesse/BaseFitNesseFixture::toString → KILLED 2. toString : negated conditional → KILLED |
return o == null ? null : o.toString(); |
| 157 | } | |
| 158 | ||
| 159 | /** | |
| 160 | * Make finalize method final to avoid "Finalizer attacks" and corresponding SpotBugs warning (CT_CONSTRUCTOR_THROW). | |
| 161 | * | |
| 162 | * @see <a href="https://wiki.sei.cmu.edu/confluence/display/java/OBJ11-J.+Be+wary+of+letting+constructors+throw+exceptions"> | |
| 163 | * Explanation of finalizer attack</a> | |
| 164 | */ | |
| 165 | @Override | |
| 166 | @SuppressWarnings({ "deprecation", "removal", "Finalize", "checkstyle:NoFinalizer", "PMD.EmptyFinalizer" }) | |
| 167 | protected final void finalize() throws Throwable { | |
| 168 | // Do nothing | |
| 169 | } | |
| 170 | } | |
Mutations | ||
| 41 |
1.1 |
|
| 44 |
1.1 |
|
| 58 |
1.1 |
|
| 61 |
1.1 |
|
| 73 |
1.1 |
|
| 97 |
1.1 |
|
| 118 |
1.1 |
|
| 127 |
1.1 |
|
| 142 |
1.1 |
|
| 156 |
1.1 2.2 |