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

codeigniter4 / CodeIgniter4 / 20693067785

04 Jan 2026 12:42PM UTC coverage: 85.499% (+0.001%) from 85.498%
20693067785

Pull #9862

github

web-flow
Merge 130f47a80 into 2226f8935
Pull Request #9862: feat: make DebugToolbar smarter about detecting binary/streamed responses

29 of 34 new or added lines in 2 files covered. (85.29%)

58 existing lines in 4 files now uncovered.

21839 of 25543 relevant lines covered (85.5%)

203.91 hits per line

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

79.17
/system/Test/Utilities/NativeHeadersStack.php
1
<?php
2

3
declare(strict_types=1);
4

5
/**
6
 * This file is part of CodeIgniter 4 framework.
7
 *
8
 * (c) CodeIgniter Foundation <admin@codeigniter.com>
9
 *
10
 * For the full copyright and license information, please view
11
 * the LICENSE file that was distributed with this source code.
12
 */
13

14
namespace CodeIgniter\Test\Utilities;
15

16
/**
17
 * Class NativeHeadersStack
18
 *
19
 * A utility class for simulating native PHP header handling in unit tests.
20
 * It allows the inspection, manipulation, and mocking of HTTP headers without
21
 * affecting the actual HTTP output.
22
 *
23
 * @internal This class is for testing purposes only.
24
 */
25
final class NativeHeadersStack
26
{
27
    private static bool $headersSent = false;
28

29
    /**
30
     * @var array<string, list<string>>
31
     */
32
    private static array $headers = [];
33

34
    private static ?int $responseCode = null;
35

36
    /**
37
     * Resets the state of the class to its default values.
38
     */
39
    public static function reset(): void
40
    {
41
        self::$headersSent  = false;
6✔
42
        self::$headers      = [];
6✔
43
        self::$responseCode = null;
6✔
44
    }
45

46
    /**
47
     * Sets the state of whether headers have been sent.
48
     */
49
    public static function setHeadersSent(bool $sent): void
50
    {
51
        self::$headersSent = $sent;
1✔
52
    }
53

54
    /**
55
     * Simulates PHP's native `headers_sent()` function.
56
     */
57
    public static function headersSent(): bool
58
    {
59
        return self::$headersSent;
8✔
60
    }
61

62
    /**
63
     * Sets a header by name, replacing or appending it.
64
     * This is the main method for header manipulation.
65
     *
66
     * @param string   $header       The header string (e.g., 'Content-Type: application/json').
67
     * @param bool     $replace      Whether to replace a previous similar header.
68
     * @param int|null $responseCode Forces the HTTP response code to the specified value.
69
     */
70
    public static function set(string $header, bool $replace = true, ?int $responseCode = null): void
71
    {
72
        if (str_contains($header, ':')) {
3✔
73
            [$name, $value] = explode(':', $header, 2);
3✔
74
            $name           = trim($name);
3✔
75
            $value          = trim($value);
3✔
76

77
            if ($replace || ! isset(self::$headers[strtolower($name)])) {
3✔
78
                self::$headers[strtolower($name)] = [];
3✔
79
            }
80
            self::$headers[strtolower($name)][] = "{$name}: {$value}";
3✔
81
        } else {
82
            // Handle non-key-value headers like "HTTP/1.1 404 Not Found"
NEW
83
            self::$headers['status'][] = $header;
×
84
        }
85

86
        if ($responseCode !== null) {
3✔
NEW
87
            self::$responseCode = $responseCode;
×
88
        }
89
    }
90

91
    /**
92
     * Pushes a header to the stack without replacing existing ones.
93
     */
94
    public static function push(string $header): void
95
    {
NEW
96
        self::set($header, false);
×
97
    }
98

99
    /**
100
     * A convenience method to push multiple headers at once.
101
     *
102
     * @param list<string> $headers An array of headers to push onto the stack.
103
     */
104
    public static function pushMany(array $headers): void
105
    {
106
        foreach ($headers as $header) {
1✔
107
            // Default to not replacing for multiple adds
108
            self::set($header, false);
1✔
109
        }
110
    }
111

112
    /**
113
     * Simulates PHP's `headers_list()` function.
114
     *
115
     * @return list<string> The list of simulated headers.
116
     */
117
    public static function listHeaders(): array
118
    {
119
        $list = [];
5✔
120

121
        foreach (self::$headers as $values) {
5✔
122
            $list = array_merge($list, $values);
3✔
123
        }
124

125
        return $list;
5✔
126
    }
127

128
    /**
129
     * Checks if a header with the given name exists in the stack (case-insensitive).
130
     *
131
     * @param string $name The header name to search for (e.g., 'Content-Type').
132
     */
133
    public static function hasHeader(string $name): bool
134
    {
NEW
135
        return isset(self::$headers[strtolower($name)]);
×
136
    }
137

138
    /**
139
     * Simulates PHP's `http_response_code()` function.
140
     *
141
     * @return int|null The stored response code, or null if not set.
142
     */
143
    public static function getResponseCode(): ?int
144
    {
NEW
145
        return self::$responseCode;
×
146
    }
147
}
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