Skip to content

Commit b50f0bd

Browse files
Copilotvinniefalco
andcommitted
Add iosfwd includes and create comprehensive tests
Co-authored-by: vinniefalco <1503976+vinniefalco@users.noreply.github.com>
1 parent 110ad09 commit b50f0bd

3 files changed

Lines changed: 209 additions & 0 deletions

File tree

include/boost/http_proto/request_base.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
#include <boost/http_proto/detail/config.hpp>
1515
#include <boost/http_proto/message_base.hpp>
1616

17+
#include <iosfwd>
18+
1719
namespace boost {
1820
namespace http_proto {
1921

include/boost/http_proto/response_base.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
#include <boost/http_proto/message_base.hpp>
1717
#include <boost/http_proto/status.hpp>
1818

19+
#include <iosfwd>
20+
1921
namespace boost {
2022
namespace http_proto {
2123

test/unit/ostream.cpp

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
//
2+
// Copyright (c) 2025 GitHub Copilot
3+
//
4+
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5+
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6+
//
7+
// Official repository: https://github.com/cppalliance/http_proto
8+
//
9+
10+
// Test that header file is self-contained.
11+
#include <boost/http_proto/fields.hpp>
12+
#include <boost/http_proto/fields_base.hpp>
13+
#include <boost/http_proto/request.hpp>
14+
#include <boost/http_proto/request_base.hpp>
15+
#include <boost/http_proto/response.hpp>
16+
#include <boost/http_proto/response_base.hpp>
17+
18+
#include "test_suite.hpp"
19+
20+
#include <sstream>
21+
22+
namespace boost {
23+
namespace http_proto {
24+
25+
struct ostream_test
26+
{
27+
void
28+
testFields()
29+
{
30+
// Test fields
31+
{
32+
fields f;
33+
f.set(field::host, "example.com");
34+
f.set(field::content_type, "text/html");
35+
36+
std::stringstream ss;
37+
ss << f;
38+
39+
std::string result = ss.str();
40+
41+
// Should not contain CRLF
42+
BOOST_TEST(result.find("\r\n") == std::string::npos);
43+
44+
// Should contain LF
45+
BOOST_TEST(result.find("\n") != std::string::npos);
46+
47+
// Should not end with newline (no trailing CRLF)
48+
BOOST_TEST(!result.empty() && result.back() != '\n');
49+
50+
// Should contain the field names and values
51+
BOOST_TEST(result.find("Host: example.com") != std::string::npos);
52+
BOOST_TEST(result.find("Content-Type: text/html") != std::string::npos);
53+
}
54+
55+
// Test fields_base
56+
{
57+
fields f;
58+
f.set(field::server, "test-server");
59+
60+
std::stringstream ss;
61+
ss << static_cast<const fields_base&>(f);
62+
63+
std::string result = ss.str();
64+
65+
// Should not contain CRLF
66+
BOOST_TEST(result.find("\r\n") == std::string::npos);
67+
68+
// Should contain LF
69+
BOOST_TEST(result.find("\n") != std::string::npos);
70+
71+
// Should not end with newline
72+
BOOST_TEST(!result.empty() && result.back() != '\n');
73+
}
74+
}
75+
76+
void
77+
testRequest()
78+
{
79+
// Test request
80+
{
81+
request req(method::get, "/");
82+
req.set(field::host, "example.com");
83+
req.set(field::user_agent, "test-agent");
84+
85+
std::stringstream ss;
86+
ss << req;
87+
88+
std::string result = ss.str();
89+
90+
// Should not contain CRLF
91+
BOOST_TEST(result.find("\r\n") == std::string::npos);
92+
93+
// Should contain LF
94+
BOOST_TEST(result.find("\n") != std::string::npos);
95+
96+
// Should not end with newline
97+
BOOST_TEST(!result.empty() && result.back() != '\n');
98+
99+
// Should start with request line
100+
BOOST_TEST(result.find("GET / HTTP/1.1") == 0);
101+
102+
// Should contain headers
103+
BOOST_TEST(result.find("Host: example.com") != std::string::npos);
104+
BOOST_TEST(result.find("User-Agent: test-agent") != std::string::npos);
105+
}
106+
107+
// Test request_base
108+
{
109+
request req(method::post, "/data");
110+
111+
std::stringstream ss;
112+
ss << static_cast<const request_base&>(req);
113+
114+
std::string result = ss.str();
115+
116+
// Should not contain CRLF
117+
BOOST_TEST(result.find("\r\n") == std::string::npos);
118+
119+
// Should start with request line
120+
BOOST_TEST(result.find("POST /data HTTP/1.1") == 0);
121+
}
122+
}
123+
124+
void
125+
testResponse()
126+
{
127+
// Test response
128+
{
129+
response res(status::ok);
130+
res.set(field::server, "test-server");
131+
res.set(field::content_type, "text/plain");
132+
133+
std::stringstream ss;
134+
ss << res;
135+
136+
std::string result = ss.str();
137+
138+
// Should not contain CRLF
139+
BOOST_TEST(result.find("\r\n") == std::string::npos);
140+
141+
// Should contain LF
142+
BOOST_TEST(result.find("\n") != std::string::npos);
143+
144+
// Should not end with newline
145+
BOOST_TEST(!result.empty() && result.back() != '\n');
146+
147+
// Should start with status line
148+
BOOST_TEST(result.find("HTTP/1.1 200 OK") == 0);
149+
150+
// Should contain headers
151+
BOOST_TEST(result.find("Server: test-server") != std::string::npos);
152+
BOOST_TEST(result.find("Content-Type: text/plain") != std::string::npos);
153+
}
154+
155+
// Test response_base
156+
{
157+
response res(status::not_found);
158+
159+
std::stringstream ss;
160+
ss << static_cast<const response_base&>(res);
161+
162+
std::string result = ss.str();
163+
164+
// Should not contain CRLF
165+
BOOST_TEST(result.find("\r\n") == std::string::npos);
166+
167+
// Should start with status line
168+
BOOST_TEST(result.find("HTTP/1.1 404 Not Found") == 0);
169+
}
170+
}
171+
172+
void
173+
testEmptyMessages()
174+
{
175+
// Test empty fields
176+
{
177+
fields f;
178+
179+
std::stringstream ss;
180+
ss << f;
181+
182+
std::string result = ss.str();
183+
184+
// Empty fields should produce empty output (no trailing CRLF)
185+
BOOST_TEST(result.empty());
186+
}
187+
}
188+
189+
void
190+
run()
191+
{
192+
testFields();
193+
testRequest();
194+
testResponse();
195+
testEmptyMessages();
196+
}
197+
};
198+
199+
TEST_SUITE(
200+
ostream_test,
201+
"boost.http_proto.ostream"
202+
);
203+
204+
} // http_proto
205+
} // boost

0 commit comments

Comments
 (0)