• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

hazendaz / httpunit / #155

20 Aug 2024 11:42PM UTC coverage: 80.622% (+0.004%) from 80.618%
#155

push

github

hazendaz
[ci] format the code

3231 of 4119 branches covered (78.44%)

Branch coverage included in aggregate %.

68 of 80 new or added lines in 21 files covered. (85.0%)

4 existing lines in 4 files now uncovered.

8285 of 10165 relevant lines covered (81.51%)

0.82 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.86
/src/main/java/com/meterware/servletunit/JUnitServlet.java
1
/*
2
 * MIT License
3
 *
4
 * Copyright 2011-2024 Russell Gold
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
7
 * documentation files (the "Software"), to deal in the Software without restriction, including without limitation
8
 * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
9
 * to permit persons to whom the Software is furnished to do so, subject to the following conditions:
10
 *
11
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions
12
 * of the Software.
13
 *
14
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
15
 * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
17
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
18
 * DEALINGS IN THE SOFTWARE.
19
 */
20
package com.meterware.servletunit;
21

22
import jakarta.servlet.ServletException;
23
import jakarta.servlet.http.HttpServlet;
24
import jakarta.servlet.http.HttpServletRequest;
25
import jakarta.servlet.http.HttpServletResponse;
26

27
import java.io.IOException;
28
import java.io.PrintWriter;
29
import java.util.Enumeration;
30

31
import junit.framework.AssertionFailedError;
32
import junit.framework.Test;
33
import junit.framework.TestFailure;
34
import junit.framework.TestResult;
35
import junit.runner.BaseTestRunner;
36

37
/**
38
 * A servlet which can run unit tests inside a servlet context. It may be extended to provide InvocationContext-access
39
 * to such tests if a container-specific implementation of InvocationContextFactory is provided. Combined with
40
 * ServletTestCase, this would permit in-container tests of servlets in a fashion similar to that supported by
41
 * ServletUnit.
42
 *
43
 * @author <a href="mailto:russgold@httpunit.org">Russell Gold</a>
44
 **/
45
public class JUnitServlet extends HttpServlet {
46

47
    private static final long serialVersionUID = 1L;
48

49
    public JUnitServlet() {
×
50
    }
×
51

52
    protected JUnitServlet(InvocationContextFactory factory) {
1✔
53
        _factory = factory;
1✔
54
    }
1✔
55

56
    @Override
57
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
58
            throws ServletException, IOException {
59
        ResultsFormatter formatter = getResultsFormatter(request.getParameter("format"));
1✔
60
        response.setContentType(formatter.getContentType());
1✔
61
        final String testName = request.getParameter("test");
1✔
62
        if (testName == null || testName.length() == 0) {
1!
63
            reportCannotRunTest(response.getWriter(), "No test class specified");
1✔
64
        } else {
65
            ServletTestRunner runner = new ServletTestRunner(response.getWriter(), formatter);
1✔
66
            runner.runTestSuite(testName);
1✔
67
        }
68
        response.getWriter().close();
1✔
69
    }
1✔
70

71
    private ResultsFormatter getResultsFormatter(String formatterName) {
72
        if ("text".equalsIgnoreCase(formatterName)) {
1✔
73
            return new TextResultsFormatter();
1✔
74
        }
75
        if ("xml".equalsIgnoreCase(formatterName)) {
1✔
76
            return new XMLResultsFormatter();
1✔
77
        }
78
        return new HTMLResultsFormatter();
1✔
79
    }
80

81
    private InvocationContextFactory _factory;
82

83
    private void reportCannotRunTest(PrintWriter writer, final String errorMessage) {
84
        writer.print("<html><head><title>Cannot run test</title></head><body>" + errorMessage + "</body></html>");
1✔
85
    }
1✔
86

87
    class ServletTestRunner extends BaseTestRunner {
88
        private PrintWriter _writer;
89
        private ResultsFormatter _formatter;
90

91
        public ServletTestRunner(PrintWriter writer, ResultsFormatter formatter) {
1✔
92
            ServletTestCase.setInvocationContextFactory(_factory);
1✔
93
            _writer = writer;
1✔
94
            _formatter = formatter;
1✔
95
        }
1✔
96

97
        void runTestSuite(String testClassName) {
98
            Test suite = getTest(testClassName);
1✔
99

100
            if (suite != null) {
1✔
101
                TestResult testResult = new TestResult();
1✔
102
                testResult.addListener(this);
1✔
103
                long startTime = System.currentTimeMillis();
1✔
104
                suite.run(testResult);
1✔
105
                long endTime = System.currentTimeMillis();
1✔
106
                _formatter.displayResults(_writer, testClassName, elapsedTimeAsString(endTime - startTime), testResult);
1✔
107
            }
108
        }
1✔
109

110
        @Override
111
        public void addError(Test test, Throwable throwable) {
112
        }
1✔
113

114
        @Override
115
        public void addFailure(Test test, AssertionFailedError error) {
116
        }
1✔
117

118
        @Override
119
        public void endTest(Test test) {
120
        }
1✔
121

122
        @Override
123
        protected void runFailed(String s) {
124
            reportCannotRunTest(_writer, s);
1✔
125
        }
1✔
126

127
        @Override
128
        public void startTest(Test test) {
129
        }
1✔
130

131
        @Override
132
        public void testStarted(String s) {
133
        }
×
134

135
        @Override
136
        public void testEnded(String s) {
137
        }
×
138

139
        @Override
140
        public void testFailed(int i, Test test, Throwable throwable) {
141
        }
×
142

143
    }
144

145
    static abstract class ResultsFormatter {
1✔
146

147
        private static final char LF = 10;
148
        private static final char CR = 13;
149

150
        abstract String getContentType();
151

152
        void displayResults(PrintWriter writer, String testClassName, String elapsedTimeString, TestResult testResult) {
153
            displayHeader(writer, testClassName, testResult, elapsedTimeString);
1✔
154
            displayResults(writer, testResult);
1✔
155
            displayFooter(writer);
1✔
156
        }
1✔
157

158
        protected abstract void displayHeader(PrintWriter writer, String testClassName, TestResult testResult,
159
                String elapsedTimeString);
160

161
        protected abstract void displayResults(PrintWriter writer, TestResult testResult);
162

163
        protected abstract void displayFooter(PrintWriter writer);
164

165
        protected String sgmlEscape(String s) {
166
            if (s == null) {
1!
167
                return "NULL";
×
168
            }
169
            StringBuilder result = new StringBuilder(s.length());
1✔
170
            char[] chars = s.toCharArray();
1✔
171
            for (int i = 0; i < chars.length; i++) {
1✔
172
                switch (chars[i]) {
1!
173
                    case '&':
NEW
174
                        result.append("&amp;");
×
UNCOV
175
                        break;
×
176
                    case '<':
177
                        result.append("&lt;");
1✔
178
                        break;
1✔
179
                    case '>':
180
                        result.append("&gt;");
1✔
181
                        break;
1✔
182
                    case LF:
183
                        if (i > 0 && chars[i - 1] == CR) {
1!
NEW
184
                            result.append(chars[i]);
×
NEW
185
                            break;
×
186
                        }
187
                    case CR:
188
                        result.append(getLineBreak());
1✔
189
                    default:
190
                        result.append(chars[i]);
1✔
191
                }
192
            }
193
            return result.toString();
1✔
194
        }
195

196
        protected String getLineBreak() {
197
            return "<br>";
1✔
198
        }
199
    }
200

201
    abstract static class DisplayedResultsFormatter extends ResultsFormatter {
1✔
202

203
        @Override
204
        protected void displayHeader(PrintWriter writer, String testClassName, TestResult testResult,
205
                String elapsedTimeString) {
206
            displayHeader(writer, testClassName, getFormatted(testResult.runCount(), "test"), elapsedTimeString,
1✔
207
                    testResult.wasSuccessful() ? "OK" : "Problems Occurred");
1✔
208
        }
1✔
209

210
        @Override
211
        protected void displayResults(PrintWriter writer, TestResult testResult) {
212
            if (!testResult.wasSuccessful()) {
1✔
213
                displayProblems(writer, "failure", testResult.failureCount(), testResult.failures());
1✔
214
                displayProblems(writer, "error", testResult.errorCount(), testResult.errors());
1✔
215
            }
216
        }
1✔
217

218
        protected abstract void displayHeader(PrintWriter writer, String testClassName, String testCountText,
219
                String elapsedTimeString, String resultString);
220

221
        protected abstract void displayProblemTitle(PrintWriter writer, String title);
222

223
        protected abstract void displayProblemDetailHeader(PrintWriter writer, int i, String testName);
224

225
        protected abstract void displayProblemDetailFooter(PrintWriter writer);
226

227
        protected abstract void displayProblemDetail(PrintWriter writer, String message);
228

229
        private void displayProblems(PrintWriter writer, String kind, int count, Enumeration enumeration) {
230
            if (count != 0) {
1✔
231
                displayProblemTitle(writer, getFormatted(count, kind));
1✔
232
                Enumeration e = enumeration;
1✔
233
                for (int i = 1; e.hasMoreElements(); i++) {
1✔
234
                    TestFailure failure = (TestFailure) e.nextElement();
1✔
235
                    displayProblemDetailHeader(writer, i, failure.failedTest().toString());
1✔
236
                    if (failure.thrownException() instanceof AssertionFailedError) {
1✔
237
                        displayProblemDetail(writer, failure.thrownException().getMessage());
1✔
238
                    } else {
239
                        displayProblemDetail(writer, BaseTestRunner.getFilteredTrace(failure.thrownException()));
1✔
240
                    }
241
                    displayProblemDetailFooter(writer);
1✔
242
                }
243
            }
244
        }
1✔
245

246
        private String getFormatted(int count, String name) {
247
            return count + " " + name + (count == 1 ? "" : "s");
1✔
248
        }
249

250
    }
251

252
    static class TextResultsFormatter extends DisplayedResultsFormatter {
1✔
253

254
        @Override
255
        String getContentType() {
256
            return "text/plain";
1✔
257
        }
258

259
        @Override
260
        protected void displayHeader(PrintWriter writer, String testClassName, String testCountText,
261
                String elapsedTimeString, String resultString) {
262
            writer.println(testClassName + " (" + testCountText + "): " + resultString);
1✔
263
        }
1✔
264

265
        @Override
266
        protected void displayFooter(PrintWriter writer) {
267
        }
1✔
268

269
        @Override
270
        protected void displayProblemTitle(PrintWriter writer, String title) {
271
            writer.println();
1✔
272
            writer.println(title + ':');
1✔
273
        }
1✔
274

275
        @Override
276
        protected void displayProblemDetailHeader(PrintWriter writer, int i, String testName) {
277
            writer.println(i + ". " + testName + ":");
1✔
278
        }
1✔
279

280
        @Override
281
        protected void displayProblemDetailFooter(PrintWriter writer) {
282
            writer.println();
1✔
283
        }
1✔
284

285
        @Override
286
        protected void displayProblemDetail(PrintWriter writer, String message) {
287
            writer.println(message);
1✔
288
        }
1✔
289
    }
290

291
    static class HTMLResultsFormatter extends DisplayedResultsFormatter {
1✔
292

293
        @Override
294
        String getContentType() {
295
            return "text/html";
1✔
296
        }
297

298
        @Override
299
        protected void displayHeader(PrintWriter writer, String testClassName, String testCountText,
300
                String elapsedTimeString, String resultString) {
301
            writer.println("<html><head><title>Test Suite: " + testClassName + "</title>");
1✔
302
            writer.println("<style type='text/css'>");
1✔
303
            writer.println("<!--");
1✔
304
            writer.println("  td.detail { font-size:smaller; vertical-align: top }");
1✔
305
            writer.println("  -->");
1✔
306
            writer.println("</style></head><body>");
1✔
307
            writer.println("<table id='results' border='1'><tr>");
1✔
308
            writer.println("<td>" + testCountText + "</td>");
1✔
309
            writer.println("<td>Time: " + elapsedTimeString + "</td>");
1✔
310
            writer.println("<td>" + resultString + "</td></tr>");
1✔
311
        }
1✔
312

313
        @Override
314
        protected void displayFooter(PrintWriter writer) {
315
            writer.println("</table>");
1✔
316
            writer.println("</body></html>");
1✔
317
        }
1✔
318

319
        @Override
320
        protected void displayProblemTitle(PrintWriter writer, String title) {
321
            writer.println("<tr><td colspan=3>" + title + "</td></tr>");
1✔
322
        }
1✔
323

324
        @Override
325
        protected void displayProblemDetailHeader(PrintWriter writer, int i, String testName) {
326
            writer.println("<tr><td class='detail' align='right'>" + i + "</td>");
1✔
327
            writer.println("<td class='detail'>" + testName + "</td><td class='detail'>");
1✔
328
        }
1✔
329

330
        @Override
331
        protected void displayProblemDetailFooter(PrintWriter writer) {
332
            writer.println("</td></tr>");
1✔
333
        }
1✔
334

335
        @Override
336
        protected void displayProblemDetail(PrintWriter writer, String message) {
337
            writer.println(sgmlEscape(message));
1✔
338
        }
1✔
339

340
    }
341

342
    static class XMLResultsFormatter extends ResultsFormatter {
1✔
343

344
        @Override
345
        String getContentType() {
346
            return "text/xml;charset=UTF-8";
1✔
347
        }
348

349
        @Override
350
        protected void displayHeader(PrintWriter writer, String testClassName, TestResult testResult,
351
                String elapsedTimeString) {
352
            writer.println("<?xml version='1.0' encoding='UTF-8' ?>\n" + "<testsuite name=" + asAttribute(testClassName)
1✔
353
                    + " tests=" + asAttribute(testResult.runCount()) + " failures="
1✔
354
                    + asAttribute(testResult.failureCount()) + " errors=" + asAttribute(testResult.errorCount())
1✔
355
                    + " time=" + asAttribute(elapsedTimeString) + ">");
1✔
356
        }
1✔
357

358
        private String asAttribute(int value) {
359
            return '"' + Integer.toString(value) + '"';
1✔
360
        }
361

362
        private String asAttribute(String value) {
363
            return '"' + sgmlEscape(value) + '"';
1✔
364
        }
365

366
        @Override
367
        protected void displayFooter(PrintWriter writer) {
368
            writer.println("</testsuite>");
1✔
369
        }
1✔
370

371
        @Override
372
        protected void displayResults(PrintWriter writer, TestResult testResult) {
373
            displayResults(writer, "failure", testResult.failures());
1✔
374
            displayResults(writer, "error", testResult.errors());
1✔
375
        }
1✔
376

377
        private void displayResults(PrintWriter writer, String failureNodeName, Enumeration resultsEnumeration) {
378
            for (Enumeration e = resultsEnumeration; e.hasMoreElements();) {
1✔
379
                TestFailure failure = (TestFailure) e.nextElement();
1✔
380
                writer.println("  <testcase name=" + asAttribute(failure.failedTest().toString()) + ">");
1✔
381
                writer.print("    <" + failureNodeName + " type="
1✔
382
                        + asAttribute(failure.thrownException().getClass().getName()) + " message="
1✔
383
                        + asAttribute(failure.exceptionMessage()));
1✔
384
                if (!displayException()) {
1!
385
                    writer.println("/>");
×
386
                } else {
387
                    writer.println(">");
1✔
388
                    writer.print(sgmlEscape(BaseTestRunner.getFilteredTrace(failure.thrownException())));
1✔
389
                    writer.println("    </" + failureNodeName + ">");
1✔
390
                }
391
                writer.println("  </testcase>");
1✔
392
            }
1✔
393
        }
1✔
394

395
        private boolean displayException() {
396
            return true;
1✔
397
        }
398

399
        @Override
400
        protected String getLineBreak() {
401
            return "";
1✔
402
        }
403
    }
404

405
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc