BaseFitNesseFixture.java

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
Location : <init>
Killed by : com.reallifedeveloper.tools.test.fitnesse.FitNesseFixtureTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.tools.test.fitnesse.FitNesseFixtureTest]/[method:testLogger()]
negated conditional → KILLED

44

1.1
Location : <init>
Killed by : com.reallifedeveloper.tools.test.fitnesse.FitNesseFixtureTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.tools.test.fitnesse.FitNesseFixtureTest]/[method:getNonExistingBean()]
removed call to java/lang/ThreadLocal::set → KILLED

58

1.1
Location : initApplicationContext
Killed by : com.reallifedeveloper.tools.test.fitnesse.FitNesseFixtureTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.tools.test.fitnesse.FitNesseFixtureTest]/[method:testLogger()]
negated conditional → KILLED

61

1.1
Location : initApplicationContext
Killed by : com.reallifedeveloper.tools.test.fitnesse.FitNesseFixtureTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.tools.test.fitnesse.FitNesseFixtureTest]/[method:testLogger()]
replaced return value with null for com/reallifedeveloper/tools/test/fitnesse/BaseFitNesseFixture::initApplicationContext → KILLED

73

1.1
Location : getComment
Killed by : com.reallifedeveloper.tools.test.fitnesse.FitNesseFixtureTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.tools.test.fitnesse.FitNesseFixtureTest]/[method:comment()]
replaced return value with "" for com/reallifedeveloper/tools/test/fitnesse/BaseFitNesseFixture::getComment → KILLED

97

1.1
Location : getApplicationContext
Killed by : none
replaced return value with null for com/reallifedeveloper/tools/test/fitnesse/BaseFitNesseFixture::getApplicationContext → RUN_ERROR

118

1.1
Location : getBean
Killed by : com.reallifedeveloper.tools.test.fitnesse.FitNesseFixtureTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.tools.test.fitnesse.FitNesseFixtureTest]/[method:getExistingBean()]
replaced return value with null for com/reallifedeveloper/tools/test/fitnesse/BaseFitNesseFixture::getBean → KILLED

127

1.1
Location : logger
Killed by : com.reallifedeveloper.tools.test.fitnesse.FitNesseFixtureTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.tools.test.fitnesse.FitNesseFixtureTest]/[method:testLogger()]
replaced return value with null for com/reallifedeveloper/tools/test/fitnesse/BaseFitNesseFixture::logger → KILLED

142

1.1
Location : parseDate
Killed by : com.reallifedeveloper.tools.test.fitnesse.FitNesseFixtureTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.tools.test.fitnesse.FitNesseFixtureTest]/[method:parseCorrectDate()]
replaced return value with null for com/reallifedeveloper/tools/test/fitnesse/BaseFitNesseFixture::parseDate → KILLED

156

1.1
Location : toString
Killed by : com.reallifedeveloper.tools.test.fitnesse.FitNesseFixtureTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.tools.test.fitnesse.FitNesseFixtureTest]/[method:testToStringNull()]
replaced return value with "" for com/reallifedeveloper/tools/test/fitnesse/BaseFitNesseFixture::toString → KILLED

2.2
Location : toString
Killed by : com.reallifedeveloper.tools.test.fitnesse.FitNesseFixtureTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.tools.test.fitnesse.FitNesseFixtureTest]/[method:testToStringNull()]
negated conditional → KILLED

Active mutators

Tests examined


Report generated by PIT 1.20.2