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

hazendaz / httpunit / 344

07 Jun 2025 08:48PM UTC coverage: 80.528%. Remained the same
344

push

github

hazendaz
Fix list usage and empty collection

3216 of 4105 branches covered (78.34%)

Branch coverage included in aggregate %.

1 of 2 new or added lines in 1 file covered. (50.0%)

8252 of 10136 relevant lines covered (81.41%)

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.io.UnsupportedEncodingException;
34
import java.text.SimpleDateFormat;
35
import java.util.ArrayList;
36
import java.util.Collection;
37
import java.util.Collections;
38
import java.util.Date;
39
import java.util.Enumeration;
40
import java.util.Hashtable;
41
import java.util.Iterator;
42
import java.util.List;
43
import java.util.Locale;
44
import java.util.Map;
45
import java.util.TimeZone;
46
import java.util.Vector;
47

48
class ServletUnitHttpResponse implements HttpServletResponse {
1✔
49

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

416
    // ---------------------------------------------- package methods --------------------------------------------------
417

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

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

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

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

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

471
        return values == null ? null : (String) values.get(0);
1✔
472
    }
473

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

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

507
    }
508

509
    // --------------------------------------- methods added to ServletRequest in Servlet API 2.4
510
    // ----------------------------
511

512
    @Override
513
    public void setCharacterEncoding(String string) {
514
        _encoding = string;
×
515
    }
×
516

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

525
    // ------------------------------------------- private members ------------------------------------
526

527
    private String _contentType = "text/plain";
1✔
528

529
    private String _encoding;
530

531
    private PrintWriter _writer;
532

533
    private ServletOutputStream _servletStream;
534

535
    private ByteArrayOutputStream _outputStream;
536

537
    private int _status = SC_OK;
1✔
538

539
    private String _statusMessage = "OK";
1✔
540

541
    private final Hashtable _headers = new Hashtable<>();
1✔
542

543
    private boolean _headersComplete;
544

545
    private Vector _cookies = new Vector<>();
1✔
546

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

559
    private void addCookieHeader() {
560
        if (_cookies.isEmpty()) {
1✔
561
            return;
1✔
562
        }
563

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

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

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

598
    @Override
599
    public String getHeader(String name) {
600
        return (String) _headers.get(name.toUpperCase());
×
601
    }
602

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

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

627
    @Override
628
    public void setContentLengthLong(long len) {
629
        setLongHeader("Content-Length", len);
×
630
    }
×
631

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

640
}
641

642
class ServletUnitOutputStream extends ServletOutputStream {
643

644
    ServletUnitOutputStream(ByteArrayOutputStream stream) {
1✔
645
        _stream = stream;
1✔
646
    }
1✔
647

648
    @Override
649
    public void write(int aByte) throws IOException {
650
        _stream.write(aByte);
1✔
651
    }
1✔
652

653
    private ByteArrayOutputStream _stream;
654

655
    @Override
656
    public boolean isReady() {
657
        return false;
×
658
    }
659

660
    @Override
661
    public void setWriteListener(WriteListener writeListener) {
662
        // Do nothing
663
    }
×
664
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc