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

hazendaz / httpunit / 636

05 Dec 2025 03:27AM UTC coverage: 80.509%. Remained the same
636

push

github

hazendaz
Cleanup more old since tags

you guessed it, at this point going to jautodoc the rest so the warnings on builds go away ;)

3213 of 4105 branches covered (78.27%)

Branch coverage included in aggregate %.

8249 of 10132 relevant lines covered (81.42%)

0.81 hits per line

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

73.13
/src/main/java/com/meterware/servletunit/ServletUnitHttpResponse.java
1
/*
2
 * MIT License
3
 *
4
 * Copyright 2011-2025 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 com.meterware.httpunit.HttpUnitUtils;
23

24
import jakarta.servlet.ServletOutputStream;
25
import jakarta.servlet.WriteListener;
26
import jakarta.servlet.http.Cookie;
27
import jakarta.servlet.http.HttpServletResponse;
28

29
import java.io.ByteArrayOutputStream;
30
import java.io.IOException;
31
import java.io.OutputStreamWriter;
32
import java.io.PrintWriter;
33
import java.nio.charset.Charset;
34
import java.nio.charset.StandardCharsets;
35
import java.text.SimpleDateFormat;
36
import java.util.ArrayList;
37
import java.util.Collection;
38
import java.util.Collections;
39
import java.util.Date;
40
import java.util.Enumeration;
41
import java.util.Hashtable;
42
import java.util.Iterator;
43
import java.util.List;
44
import java.util.Locale;
45
import java.util.Map;
46
import java.util.TimeZone;
47
import java.util.Vector;
48

49
class ServletUnitHttpResponse implements HttpServletResponse {
1✔
50

51
    // rfc1123-date is "Sun, 06 Nov 1994 08:49:37 GMT"
52
    private static final String RFC1123_DATE_SPEC = "EEE, dd MMM yyyy HH:mm:ss z";
53
    private boolean _committed;
54
    private Locale _locale = Locale.getDefault();
1✔
55

56
    private static final Hashtable ENCODING_MAP = new Hashtable<>();
1✔
57

58
    /**
59
     * Adds the specified cookie to the response. It can be called multiple times to set more than one cookie.
60
     */
61
    @Override
62
    public void addCookie(Cookie cookie) {
63
        _cookies.addElement(cookie);
1✔
64
    }
1✔
65

66
    /**
67
     * Checks whether the response message header has a field with the specified name.
68
     */
69
    @Override
70
    public boolean containsHeader(String name) {
71
        return _headers.containsKey(name.toUpperCase());
1✔
72
    }
73

74
    /**
75
     * Encodes the specified URL by including the session ID in it, or, if encoding is not needed, returns the URL
76
     * unchanged. The implementation of this method should include the logic to determine whether the session ID needs
77
     * to be encoded in the URL. For example, if the browser supports cookies, or session tracking is turned off, URL
78
     * encoding is unnecessary.
79
     **/
80
    @Override
81
    public String encodeURL(String url) {
82
        return url;
×
83
    }
84

85
    /**
86
     * Encodes the specified URL for use in the <code>sendRedirect</code> method or, if encoding is not needed, returns
87
     * the URL unchanged. The implementation of this method should include the logic to determine whether the session ID
88
     * needs to be encoded in the URL. Because the rules for making this determination differ from those used to decide
89
     * whether to encode a normal link, this method is seperate from the <code>encodeUrl</code> method.
90
     **/
91
    @Override
92
    public String encodeRedirectURL(String url) {
93
        return url;
×
94
    }
95

96
    /**
97
     * Sends a temporary redirect response to the client using the specified redirect location URL. The URL must be
98
     * absolute (for example, <code><em>https://hostname/path/file.html</em></code>). Relative URLs are not permitted
99
     * here.
100
     */
101
    @Override
102
    public void sendRedirect(String location) throws IOException {
103
        setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
1✔
104
        setHeader("Location", location);
1✔
105
    }
1✔
106

107
    /**
108
     * Sends an error response to the client using the specified status code and descriptive message. If setStatus has
109
     * previously been called, it is reset to the error status code. The message is sent as the body of an HTML page,
110
     * which is returned to the user to describe the problem. The page is sent with a default HTML header; the message
111
     * is enclosed in simple body tags (&lt;body&gt;&lt;/body&gt;).
112
     **/
113
    @Override
114
    public void sendError(int sc) throws IOException {
115
        sendError(sc, "");
×
116
    }
×
117

118
    /**
119
     * Sends an error response to the client using the specified status code and descriptive message. If setStatus has
120
     * previously been called, it is reset to the error status code. The message is sent as the body of an HTML page,
121
     * which is returned to the user to describe the problem. The page is sent with a default HTML header; the message
122
     * is enclosed in simple body tags (&lt;body&gt;&lt;/body&gt;).
123
     **/
124
    @Override
125
    public void sendError(int sc, String msg) throws IOException {
126
        setStatus(sc);
×
127
        _statusMessage = msg;
×
128

129
        _writer = null;
×
130
        _servletStream = null;
×
131

132
        setContentType("text/html");
×
133
        getWriter().println("<html><head><title>" + msg + "</title></head><body>" + msg + "</body></html>");
×
134
    }
×
135

136
    /**
137
     * Sets the status code for this response. This method is used to set the return status code when there is no error
138
     * (for example, for the status codes SC_OK or SC_MOVED_TEMPORARILY). If there is an error, the
139
     * <code>sendError</code> method should be used instead.
140
     **/
141
    @Override
142
    public void setStatus(int sc) {
143
        _status = sc;
1✔
144
    }
1✔
145

146
    /**
147
     * Adds a field to the response header with the given name and value. If the field had already been set, the new
148
     * value overwrites the previous one. The <code>containsHeader</code> method can be used to test for the presence of
149
     * a header before setting its value.
150
     **/
151
    @Override
152
    public void setHeader(String name, String value) {
153
        ArrayList values = new ArrayList<>();
1✔
154
        values.add(value);
1✔
155
        synchronized (_headers) {
1✔
156
            _headers.put(name.toUpperCase(), values);
1✔
157
        }
1✔
158
    }
1✔
159

160
    /**
161
     * Adds a field to the response header with the given name and integer value. If the field had already been set, the
162
     * new value overwrites the previous one. The <code>containsHeader</code> method can be used to test for the
163
     * presence of a header before setting its value.
164
     **/
165
    @Override
166
    public void setIntHeader(String name, int value) {
167
        setHeader(name, asHeaderValue(value));
1✔
168
    }
1✔
169

170
    /**
171
     * Adds a field to the response header with the given name and integer value. If the field had already been set, the
172
     * new value overwrites the previous one. The <code>containsHeader</code> method can be used to test for the
173
     * presence of a header before setting its value.
174
     **/
175
    public void setLongHeader(String name, long value) {
176
        setHeader(name, asHeaderLongValue(value));
×
177
    }
×
178

179
    private String asHeaderValue(int value) {
180
        return Integer.toString(value);
1✔
181
    }
182

183
    private String asHeaderLongValue(long value) {
184
        return Long.toString(value);
×
185
    }
186

187
    /**
188
     * Adds a field to the response header with the given name and date-valued field. The date is specified in terms of
189
     * milliseconds since the epoch. If the date field had already been set, the new value overwrites the previous one.
190
     * The <code>containsHeader</code> method can be used to test for the presence of a header before setting its value.
191
     **/
192
    @Override
193
    public void setDateHeader(String name, long date) {
194
        setHeader(name, asDateHeaderValue(date));
1✔
195
    }
1✔
196

197
    private String asDateHeaderValue(long date) {
198
        Date value = new Date(date);
1✔
199
        SimpleDateFormat formatter = new SimpleDateFormat(RFC1123_DATE_SPEC, Locale.US);
1✔
200
        formatter.setTimeZone(TimeZone.getTimeZone("Greenwich Mean Time"));
1✔
201
        return formatter.format(value);
1✔
202
    }
203

204
    /**
205
     * Returns the name of the character set encoding used for the MIME body sent by this response.
206
     **/
207
    @Override
208
    public String getCharacterEncoding() {
209
        return _encoding == null ? StandardCharsets.ISO_8859_1.name() : _encoding;
1✔
210
    }
211

212
    /**
213
     * Sets the content type of the response the server sends to the client. The content type may include the type of
214
     * character encoding used, for example, <code>text/html; charset=ISO-8859-4</code>.
215
     * <p>
216
     * You can only use this method once, and you should call it before you obtain a <code>PrintWriter</code> or
217
     * {@link ServletOutputStream} object to return a response.
218
     **/
219
    @Override
220
    public void setContentType(String type) {
221
        String[] typeAndEncoding = HttpUnitUtils.parseContentTypeHeader(type);
1✔
222

223
        _contentType = typeAndEncoding[0];
1✔
224
        if (typeAndEncoding[1] != null) {
1✔
225
            _encoding = typeAndEncoding[1];
1✔
226
        }
227
    }
1✔
228

229
    /**
230
     * Returns a {@link ServletOutputStream} suitable for writing binary data in the response. The servlet engine does
231
     * not encode the binary data.
232
     *
233
     * @exception IllegalStateException
234
     *                if you have already called the <code>getWriter</code> method
235
     **/
236
    @Override
237
    public ServletOutputStream getOutputStream() throws IOException {
238
        if (_writer != null) {
1✔
239
            throw new IllegalStateException("Tried to create output stream; writer already exists");
1✔
240
        }
241
        if (_servletStream == null) {
1✔
242
            _outputStream = new ByteArrayOutputStream();
1✔
243
            _servletStream = new ServletUnitOutputStream(_outputStream);
1✔
244
        }
245
        return _servletStream;
1✔
246
    }
247

248
    /**
249
     * Returns a <code>PrintWriter</code> object that you can use to send character text to the client. The character
250
     * encoding used is the one specified in the <code>charset=</code> property of the {@link #setContentType} method,
251
     * which you must call <i>before</i> you call this method.
252
     * <p>
253
     * If necessary, the MIME type of the response is modified to reflect the character encoding used.
254
     * <p>
255
     * You cannot use this method if you have already called {@link #getOutputStream} for this
256
     * <code>ServletResponse</code> object.
257
     *
258
     * @exception IllegalStateException
259
     *                if the <code>getOutputStream</code> method has already been called for this response object; in
260
     *                that case, you can't use this method
261
     **/
262
    @Override
263
    public PrintWriter getWriter() {
264
        if (_servletStream != null) {
1✔
265
            throw new IllegalStateException("Tried to create writer; output stream already exists");
1✔
266
        }
267
        if (_writer == null) {
1✔
268
            _outputStream = new ByteArrayOutputStream();
1✔
269
            _writer = new PrintWriter(new OutputStreamWriter(_outputStream, Charset.forName(getCharacterEncoding())));
1✔
270
        }
271
        return _writer;
1✔
272
    }
273

274
    /**
275
     * Sets the length of the content the server returns to the client. In HTTP servlets, this method sets the HTTP
276
     * Content-Length header.
277
     **/
278
    @Override
279
    public void setContentLength(int len) {
280
        setIntHeader("Content-Length", len);
1✔
281
    }
1✔
282

283
    // ------------------------------- the following methods are new in JSDK 2.2 ----------------------
284

285
    /**
286
     * Adds a response header with the given name and value. This method allows response headers to have multiple
287
     * values.
288
     **/
289
    @Override
290
    public void addHeader(String name, String value) {
291
        synchronized (_headers) {
1✔
292
            String key = name.toUpperCase();
1✔
293
            List values = (ArrayList) _headers.get(key);
1✔
294
            if (values == null) {
1✔
295
                values = new ArrayList<>();
1✔
296
                _headers.put(key, values);
1✔
297
            }
298
            values.add(value);
1✔
299
        }
1✔
300
    }
1✔
301

302
    /**
303
     * Adds a response header with the given name and value. This method allows response headers to have multiple
304
     * values.
305
     **/
306
    @Override
307
    public void addIntHeader(String name, int value) {
308
        addHeader(name, asHeaderValue(value));
1✔
309
    }
1✔
310

311
    /**
312
     * Adds a response header with the given name and value. This method allows response headers to have multiple
313
     * values.
314
     **/
315
    @Override
316
    public void addDateHeader(String name, long value) {
317
        addHeader(name, asDateHeaderValue(value));
1✔
318
    }
1✔
319

320
    /**
321
     * Sets the preferred buffer size for the body of the response. The servlet container will use a buffer at least as
322
     * large as the size requested. The actual buffer size used can be found using getBufferSize.
323
     **/
324
    @Override
325
    public void setBufferSize(int size) {
326
        if (getContents().length != 0) {
1✔
327
            throw new IllegalStateException("May not set buffer size after data is written");
1✔
328
        }
329
    }
1✔
330

331
    /**
332
     * Returns the actual buffer size used for the response. If no buffering is used, this method returns 0.
333
     **/
334
    @Override
335
    public int getBufferSize() {
336
        return 0;
×
337
    }
338

339
    /**
340
     * Returns a boolean indicating if the response has been committed. A committed response has already had its status
341
     * code and headers written.
342
     **/
343
    @Override
344
    public boolean isCommitted() {
345
        return _committed;
1✔
346
    }
347

348
    /**
349
     * Forces any content in the buffer to be written to the client. A call to this method automatically commits the
350
     * response, meaning the status code and headers will be written.
351
     **/
352
    @Override
353
    public void flushBuffer() throws IOException {
354
        _committed = true;
1✔
355
    }
1✔
356

357
    /**
358
     * Clears any data that exists in the buffer as well as the status code and headers. If the response has been
359
     * committed, this method throws an IllegalStateException.
360
     **/
361
    @Override
362
    public void reset() {
363
        resetBuffer();
1✔
364
        _headers.clear();
1✔
365
        _headersComplete = false;
1✔
366
        _status = SC_OK;
1✔
367
    }
1✔
368

369
    /**
370
     * Sets the locale of the response, setting the headers (including the Content-Type's charset) as appropriate. This
371
     * method should be called before a call to getWriter(). By default, the response locale is the default locale for
372
     * the server.
373
     **/
374
    @Override
375
    public void setLocale(Locale locale) {
376
        _locale = locale;
1✔
377
        if (_encoding == null) {
1!
378
            for (Iterator it = ENCODING_MAP.entrySet().iterator(); it.hasNext();) {
1!
379
                Map.Entry entry = (Map.Entry) it.next();
1✔
380
                String locales = (String) entry.getValue();
1✔
381
                if (locales.indexOf(locale.getLanguage()) >= 0 || locales.indexOf(locale.toString()) >= 0) {
1!
382
                    _encoding = (String) entry.getKey();
1✔
383
                    return;
1✔
384
                }
385
            }
1✔
386
        }
387
    }
×
388

389
    /**
390
     * Returns the locale assigned to the response.
391
     **/
392
    @Override
393
    public Locale getLocale() {
394
        return _locale;
1✔
395
    }
396

397
    // ----------------------------- methods added to ServletResponse in JSDK 2.3 --------------------------------------
398

399
    /**
400
     * Clears the content of the underlying buffer in the response without clearing headers or status code. If the
401
     * response has been committed, this method throws an IllegalStateException.
402
     */
403
    @Override
404
    public void resetBuffer() {
405
        if (_committed) {
1✔
406
            throw new IllegalStateException("May not resetBuffer after response is committed");
1✔
407
        }
408
        _outputStream = null;
1✔
409
        _servletStream = null;
1✔
410
        _writer = null;
1✔
411
    }
1✔
412

413
    // ---------------------------------------------- package methods --------------------------------------------------
414

415
    /**
416
     * Returns the contents of this response.
417
     **/
418
    byte[] getContents() {
419
        if (_outputStream == null) {
1✔
420
            return new byte[0];
1✔
421
        }
422
        if (_writer != null) {
1✔
423
            _writer.flush();
1✔
424
        }
425
        return _outputStream.toByteArray();
1✔
426
    }
427

428
    /**
429
     * Returns the status of this response.
430
     **/
431
    @Override
432
    public int getStatus() {
433
        return _status;
1✔
434
    }
435

436
    /**
437
     * Returns the message associated with this response's status.
438
     **/
439
    String getMessage() {
440
        return _statusMessage;
×
441
    }
442

443
    public String[] getHeaderFieldNames() {
444
        if (!_headersComplete) {
×
445
            completeHeaders();
×
446
        }
447
        Vector names = new Vector<>();
×
448
        for (Enumeration e = _headers.keys(); e.hasMoreElements();) {
×
449
            names.addElement(e.nextElement());
×
450
        }
451
        String[] result = new String[names.size()];
×
452
        names.copyInto(result);
×
453
        return result;
×
454
    }
455

456
    /**
457
     * Returns the headers defined for this response.
458
     *
459
     * @param name
460
     *            - the name of the field to get
461
     **/
462
    String getHeaderFieldDirect(String name) {
463
        ArrayList values;
464
        synchronized (_headers) {
1✔
465
            values = (ArrayList) _headers.get(name.toUpperCase());
1✔
466
        }
1✔
467

468
        return values == null ? null : (String) values.get(0);
1✔
469
    }
470

471
    /**
472
     * Returns the headers defined for this response.
473
     *
474
     * @param name
475
     **/
476
    String getHeaderField(String name) {
477
        if (!_headersComplete) {
1✔
478
            completeHeaders();
1✔
479
        }
480
        return getHeaderFieldDirect(name);
1✔
481
    }
482

483
    /**
484
     * Return an array of all the header values associated with the specified header name, or an zero-length array if
485
     * there are no such header values.
486
     *
487
     * @param name
488
     *            Header name to look up
489
     */
490
    public String[] getHeaderFields(String name) {
491
        if (!_headersComplete) {
1✔
492
            completeHeaders();
1✔
493
        }
494
        ArrayList values;
495
        synchronized (_headers) {
1✔
496
            values = (ArrayList) _headers.get(name.toUpperCase());
1✔
497
        }
1✔
498
        if (values == null) {
1✔
499
            return new String[0];
1✔
500
        }
501
        String[] results = new String[values.size()];
1✔
502
        return (String[]) values.toArray(results);
1✔
503

504
    }
505

506
    // --------------------------------------- methods added to ServletRequest in Servlet API 2.4
507
    // ----------------------------
508

509
    @Override
510
    public void setCharacterEncoding(String string) {
511
        _encoding = string;
×
512
    }
×
513

514
    /**
515
     * Returns the content type defined for this response.
516
     **/
517
    @Override
518
    public String getContentType() {
519
        return _contentType;
×
520
    }
521

522
    // ------------------------------------------- private members ------------------------------------
523

524
    private String _contentType = "text/plain";
1✔
525

526
    private String _encoding;
527

528
    private PrintWriter _writer;
529

530
    private ServletOutputStream _servletStream;
531

532
    private ByteArrayOutputStream _outputStream;
533

534
    private int _status = SC_OK;
1✔
535

536
    private String _statusMessage = "OK";
1✔
537

538
    private final Hashtable _headers = new Hashtable<>();
1✔
539

540
    private boolean _headersComplete;
541

542
    private Vector _cookies = new Vector<>();
1✔
543

544
    private void completeHeaders() {
545
        if (_headersComplete) {
1!
546
            return;
×
547
        }
548
        addCookieHeader();
1✔
549
        // BR 3301056 ServletUnit handling Content-Type incorrectly
550
        if (getHeaderFieldDirect("Content-Type") == null) {
1✔
551
            setHeader("Content-Type", _contentType + "; charset=" + getCharacterEncoding());
1✔
552
        }
553
        _headersComplete = true;
1✔
554
    }
1✔
555

556
    private void addCookieHeader() {
557
        if (_cookies.isEmpty()) {
1✔
558
            return;
1✔
559
        }
560

561
        StringBuilder sb = new StringBuilder();
1✔
562
        for (Enumeration e = _cookies.elements(); e.hasMoreElements();) {
1✔
563
            Cookie cookie = (Cookie) e.nextElement();
1✔
564
            sb.append(cookie.getName()).append('=').append(cookie.getValue());
1✔
565
            if (cookie.getPath() != null) {
1!
566
                sb.append(";path=").append(cookie.getPath());
1✔
567
            }
568
            if (cookie.getDomain() != null) {
1!
569
                sb.append(";domain=").append(cookie.getDomain());
×
570
            }
571
            if (e.hasMoreElements()) {
1!
572
                sb.append(',');
×
573
            }
574
        }
1✔
575
        setHeader("Set-Cookie", sb.toString());
1✔
576
    }
1✔
577

578
    static {
579
        ENCODING_MAP.put("ISO-8859-1", "ca da de en es fi fr is it nl no pt sv ");
1✔
580
        ENCODING_MAP.put("ISO-8859-2", "cs hr hu pl ro sh sk sl sq ");
1✔
581
        ENCODING_MAP.put("ISO-8859-4", "et lt lv ");
1✔
582
        ENCODING_MAP.put("ISO-8859-5", "be bg mk ru sr uk ");
1✔
583
        ENCODING_MAP.put("ISO-8859-6", "ar ");
1✔
584
        ENCODING_MAP.put("ISO-8859-7", "el ");
1✔
585
        ENCODING_MAP.put("ISO-8859-8", "iw he ");
1✔
586
        ENCODING_MAP.put("ISO-8859-9", "tr ");
1✔
587

588
        ENCODING_MAP.put("Shift_JIS", "ja ");
1✔
589
        ENCODING_MAP.put("EUC-KR", "ko ");
1✔
590
        ENCODING_MAP.put("TIS-620", "th ");
1✔
591
        ENCODING_MAP.put("GB2312", "zh ");
1✔
592
        ENCODING_MAP.put("Big5", "zh_TW zh_HK ");
1✔
593
    }
1✔
594

595
    @Override
596
    public String getHeader(String name) {
597
        return (String) _headers.get(name.toUpperCase());
×
598
    }
599

600
    @Override
601
    public Collection<String> getHeaders(String name) {
602
        List values;
603
        synchronized (_headers) {
×
604
            values = (ArrayList) _headers.get(name.toUpperCase());
×
605
        }
×
606
        if (values == null) {
×
607
            return Collections.emptyList();
×
608
        }
609
        return values;
×
610
    }
611

612
    @Override
613
    public Collection<String> getHeaderNames() {
614
        if (!_headersComplete) {
×
615
            completeHeaders();
×
616
        }
617
        Vector names = new Vector<>();
×
618
        for (Enumeration e = _headers.keys(); e.hasMoreElements();) {
×
619
            names.addElement(e.nextElement());
×
620
        }
621
        return names;
×
622
    }
623

624
    @Override
625
    public void setContentLengthLong(long len) {
626
        setLongHeader("Content-Length", len);
×
627
    }
×
628

629
    public void sendRedirect(String location, int sc, boolean clearBuffer) throws IOException {
630
        setStatus(sc);
×
631
        setHeader("Location", location);
×
632
        if (clearBuffer) {
×
633
            resetBuffer();
×
634
        }
635
    }
×
636

637
}
638

639
class ServletUnitOutputStream extends ServletOutputStream {
640

641
    ServletUnitOutputStream(ByteArrayOutputStream stream) {
1✔
642
        _stream = stream;
1✔
643
    }
1✔
644

645
    @Override
646
    public void write(int aByte) throws IOException {
647
        _stream.write(aByte);
1✔
648
    }
1✔
649

650
    private ByteArrayOutputStream _stream;
651

652
    @Override
653
    public boolean isReady() {
654
        return false;
×
655
    }
656

657
    @Override
658
    public void setWriteListener(WriteListener writeListener) {
659
        // Do nothing
660
    }
×
661
}
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