@@ -10,244 +10,19 @@ import Foundation
1010#if canImport(FoundationNetworking)
1111import FoundationNetworking
1212#endif
13- import XCTest
13+ import Testing
1414@testable import HTTP
1515
16- final class HTTPTests : XCTestCase {
17-
18- func testVersion( ) {
19- XCTAssertEqual ( HTTPVersion . v1. rawValue, " HTTP/1.0 " )
20- XCTAssertEqual ( HTTPVersion ( rawValue: " HTTP/1.0 " ) , . v1)
21- XCTAssertEqual ( HTTPVersion . v1_1. rawValue, " HTTP/1.1 " )
22- XCTAssertEqual ( HTTPVersion ( rawValue: " HTTP/1.1 " ) , . v1_1)
23- XCTAssertEqual ( HTTPVersion . v2. rawValue, " HTTP/2.0 " )
24- XCTAssertEqual ( HTTPVersion ( rawValue: " HTTP/2.0 " ) , . v2)
25- }
26-
27- func testRequestMessage( ) {
28-
29- do {
30- // GET /ping HTTP/1.1
31- // Host: localhost:8456
32- // Accept: */*
33- // Accept-Language: en-US,en;q=0.9
34- // Connection: keep-alive
35- // Accept-Encoding: gzip, deflate
36- // User-Agent: xctest/21250 CFNetwork/1398 Darwin/22.1.0
37-
38- let data = Data ( [
39- 71 , 69 , 84 , 32 , 47 , 112 , 105 , 110 , 103 , 32 , 72 , 84 , 84 , 80 , 47 , 49 , 46 , 49 ,
40- 13 , 10 ,
41- 72 , 111 , 115 , 116 , 58 , 32 , 108 , 111 , 99 , 97 , 108 , 104 , 111 , 115 , 116 , 58 , 56 , 52 , 53 , 54 ,
42- 13 , 10 ,
43- 65 , 99 , 99 , 101 , 112 , 116 , 58 , 32 , 42 , 47 , 42 ,
44- 13 , 10 ,
45- 65 , 99 , 99 , 101 , 112 , 116 , 45 , 76 , 97 , 110 , 103 , 117 , 97 , 103 , 101 , 58 , 32 , 101 , 110 , 45 , 85 , 83 , 44 , 101 , 110 , 59 , 113 , 61 , 48 , 46 , 57 ,
46- 13 , 10 ,
47- 67 , 111 , 110 , 110 , 101 , 99 , 116 , 105 , 111 , 110 , 58 , 32 , 107 , 101 , 101 , 112 , 45 , 97 , 108 , 105 , 118 , 101 ,
48- 13 , 10 ,
49- 65 , 99 , 99 , 101 , 112 , 116 , 45 , 69 , 110 , 99 , 111 , 100 , 105 , 110 , 103 , 58 , 32 , 103 , 122 , 105 , 112 , 44 , 32 , 100 , 101 , 102 , 108 , 97 , 116 , 101 ,
50- 13 , 10 ,
51- 85 , 115 , 101 , 114 , 45 , 65 , 103 , 101 , 110 , 116 , 58 , 32 , 120 , 99 , 116 , 101 , 115 , 116 , 47 , 50 , 49 , 50 , 53 , 48 , 32 , 67 , 70 , 78 , 101 , 116 , 119 , 111 , 114 , 107 , 47 , 49 , 51 , 57 , 56 , 32 , 68 , 97 , 114 , 119 , 105 , 110 , 47 , 50 , 50 , 46 , 49 , 46 , 48 ,
52- 13 , 10 ,
53- 13 , 10
54- ] )
55-
56- guard let message = HTTPRequest ( data: data) else {
57- XCTFail ( )
58- return
59- }
60-
61- XCTAssertNil ( message. headers [ . contentLength] )
62- XCTAssertEqual ( message. headers [ . userAgent] , " xctest/21250 CFNetwork/1398 Darwin/22.1.0 " )
63- XCTAssertEqual ( message. headers. count, 6 )
64- XCTAssertEqual ( message. uri, " /ping " )
65- XCTAssertEqual ( HTTPRequest ( data: message. data) , message)
66- }
67- }
68-
69- func testResponseMessage( ) {
70-
71- do {
72- let string = """
73- HTTP/1.1 200 OK \r
74- Date: Sun, 10 Oct 2010 23:26:07 GMT \r
75- Server: Apache/2.2.8 (Ubuntu) mod_ssl/2.2.8 OpenSSL/0.9.8g \r
76- Last-Modified: Sun, 26 Sep 2010 22:04:35 GMT \r
77- ETag: " 45b6-834-49130cc1182c0 " \r
78- Accept-Ranges: bytes \r
79- Content-Length: 12 \r
80- Connection: close \r
81- Content-Type: text/html \r
82- \r
83- Hello world!
84- """
85-
86- guard let message = HTTPMessage ( data: Data ( string. utf8) ) else {
87- XCTFail ( )
88- return
89- }
90-
91- XCTAssertEqual ( message. body, Data ( " Hello world! " . utf8) )
92- XCTAssertEqual ( message. headers [ . date] , " Sun, 10 Oct 2010 23:26:07 GMT " )
93- XCTAssertEqual ( message. headers [ . contentType] , " text/html " )
94- XCTAssertEqual ( message. headers. count, 8 )
95- XCTAssertEqual ( message. head, . response( . init( version: . v1_1, code: . ok) ) )
96- XCTAssertEqual ( HTTPMessage ( data: message. data) , message)
97- }
98- }
99-
100- func testRequestHeader( ) {
101- let string = #"GET /logo.gif HTTP/1.1"#
102- guard let header = HTTPMessage . Header. Request ( rawValue: string) else {
103- XCTFail ( )
104- return
105- }
106- XCTAssertEqual ( header. method, . get)
107- XCTAssertEqual ( header. uri, " /logo.gif " )
108- XCTAssertEqual ( header. version, . v1_1)
109- XCTAssertEqual ( HTTPMessage . Header ( rawValue: string) , . request( header) )
110- }
111-
112- func testResponseHeader( ) {
113- let string = #"HTTP/1.1 200 OK"#
114- guard let header = HTTPMessage . Header. Response ( rawValue: string) else {
115- XCTFail ( )
116- return
117- }
118- XCTAssertEqual ( header. version, . v1_1)
119- XCTAssertEqual ( header. code, . ok)
120- XCTAssertEqual ( header. status, header. code. reasonPhrase)
121- XCTAssertEqual ( HTTPMessage . Header ( rawValue: string) , . response( header) )
122- }
123-
124- func testServerPingPong( ) async throws {
125- let port = UInt16 . random ( in: 8080 ..< 9000 )
126- var server : HTTPServer ? = try await HTTPServer ( configuration: . init( port: port) , response: { ( address, request) in
127- if request. uri == " /ping " , request. method == . get {
128- return . init( code: . ok, body: Data ( " pong " . utf8) )
129- } else {
130- return . init( code: 404 )
131- }
132- } )
133- assert ( server != nil )
134- let client = URLSession ( configuration: . ephemeral)
135- let serverURL = URL ( string: " http://localhost: \( port) " ) !
136-
137- let ( pongData, pongResponse) = try await client. data ( for: URLRequest ( url: serverURL. appendingPathComponent ( " ping " ) ) )
138- XCTAssertEqual ( ( pongResponse as! HTTPURLResponse ) . statusCode, 200 )
139- XCTAssertEqual ( String ( data: pongData, encoding: . utf8) , " pong " )
140-
141- //
142- server = nil
143- try await Task . sleep ( nanoseconds: 100_000 )
144- }
145-
146- func testServerGetBlob( ) async throws {
147- let port = UInt16 . random ( in: 8080 ..< 9000 )
148- let blob = Data ( repeating: . random( in: . min ... . max) , count: 1024 * . random( in: 1 ... 10 ) )
149- print ( " Blob: " , blob. count)
150- var server : HTTPServer ? = try await HTTPServer ( configuration: . init( port: port) , response: { ( address, request) in
151- if request. uri == " /blob " , request. method == . get {
152- return request. body. isEmpty ? . init( code: . ok, body: blob) : . init( code: . badRequest)
153- } else {
154- return . init( code: 404 )
155- }
156- } )
157- assert ( server != nil )
158- let client = URLSession ( configuration: . ephemeral)
159- let serverURL = URL ( string: " http://localhost: \( port) " ) !
160-
161- let ( data, urlResponse) = try await client. data ( for: URLRequest ( url: serverURL. appendingPathComponent ( " blob " ) ) )
162- XCTAssertEqual ( ( urlResponse as! HTTPURLResponse ) . statusCode, 200 )
163- XCTAssertEqual ( data, blob)
164-
165- //
166- server = nil
167- try await Task . sleep ( nanoseconds: 100_000 )
168- }
169-
170- func testServerPostBlob( ) async throws {
171- let port = UInt16 . random ( in: 8080 ..< 9000 )
172- let blob = Data ( repeating: . random( in: . min ... . max) , count: 1024 * . random( in: 1 ... 10 ) )
173- print ( " Blob: " , blob. count)
174- var server : HTTPServer ? = try await HTTPServer ( configuration: . init( port: port) , response: { ( address, request) in
175- if request. uri == " /blob " , request. method == . post {
176- XCTAssertEqual ( request. headers [ . contentLength] , blob. count. description)
177- XCTAssertEqual ( request. body. count, blob. count)
178- XCTAssertEqual ( request. body, blob)
179- return . init( code: request. body == blob ? . ok : . badRequest)
180- } else {
181- return . init( code: 404 )
182- }
183- } )
184- assert ( server != nil )
185- let client = URLSession ( configuration: . ephemeral)
186- let serverURL = URL ( string: " http://localhost: \( port) " ) !
187-
188- var request = URLRequest ( url: serverURL. appendingPathComponent ( " blob " ) )
189- request. httpMethod = HTTPMethod . post. rawValue
190- request. httpBody = blob
191- let ( data, urlResponse) = try await client. data ( for: request)
192- XCTAssertEqual ( ( urlResponse as! HTTPURLResponse ) . statusCode, 200 )
193- XCTAssert ( data. isEmpty)
194-
195- //
196- server = nil
197- try await Task . sleep ( nanoseconds: 100_000 )
198- }
199-
200- func testServerGetLargeBlob( ) async throws {
201- let port = UInt16 . random ( in: 8080 ..< 9000 )
202- let blob = Data ( repeating: . random( in: . min ... . max) , count: 1024 * 1024 * . random( in: 2 ... 4 ) )
203- print ( " Blob: " , blob. count)
204- var server : HTTPServer ? = try await HTTPServer ( configuration: . init( port: port) , response: { ( address, request) in
205- if request. uri == " /blob " , request. method == . get {
206- return request. body. isEmpty ? . init( code: . ok, body: blob) : . init( code: . badRequest)
207- } else {
208- return . init( code: 404 )
209- }
210- } )
211- assert ( server != nil )
212- let client = URLSession ( configuration: . ephemeral)
213- let serverURL = URL ( string: " http://localhost: \( port) " ) !
214-
215- let ( data, urlResponse) = try await client. data ( for: URLRequest ( url: serverURL. appendingPathComponent ( " blob " ) ) )
216- XCTAssertEqual ( ( urlResponse as! HTTPURLResponse ) . statusCode, 200 )
217- XCTAssertEqual ( data, blob)
218-
219- //
220- server = nil
221- try await Task . sleep ( nanoseconds: 100_000 )
222- }
223-
224- func testServerPostLargeBlob( ) async throws {
225- let port = UInt16 . random ( in: 8080 ..< 9000 )
226- let blob = Data ( repeating: . random( in: . min ... . max) , count: 1024 * 1024 * . random( in: 2 ... 4 ) )
227- print ( " Blob: " , blob. count)
228- var server : HTTPServer ? = try await HTTPServer ( configuration: . init( port: port) , response: { ( address, request) in
229- if request. uri == " /blob " , request. method == . post {
230- XCTAssertEqual ( request. headers [ . contentLength] , blob. count. description)
231- XCTAssertEqual ( request. body. count, blob. count)
232- XCTAssertEqual ( request. body, blob)
233- return . init( code: request. body == blob ? . ok : . badRequest)
234- } else {
235- return . init( code: 404 )
236- }
237- } )
238- assert ( server != nil )
239- let client = URLSession ( configuration: . ephemeral)
240- let serverURL = URL ( string: " http://localhost: \( port) " ) !
241-
242- var request = URLRequest ( url: serverURL. appendingPathComponent ( " blob " ) )
243- request. httpMethod = HTTPMethod . post. rawValue
244- request. httpBody = blob
245- let ( data, urlResponse) = try await client. data ( for: request)
246- XCTAssertEqual ( ( urlResponse as! HTTPURLResponse ) . statusCode, 200 )
247- XCTAssert ( data. isEmpty)
248-
249- //
250- server = nil
251- try await Task . sleep ( nanoseconds: 100_000 )
16+ @Suite
17+ struct HTTPTests {
18+
19+ @Test
20+ func version( ) {
21+ #expect( HTTPVersion . v1. rawValue == " HTTP/1.0 " )
22+ #expect( HTTPVersion ( rawValue: " HTTP/1.0 " ) == . v1)
23+ #expect( HTTPVersion . v1_1. rawValue == " HTTP/1.1 " )
24+ #expect( HTTPVersion ( rawValue: " HTTP/1.1 " ) == . v1_1)
25+ #expect( HTTPVersion . v2. rawValue == " HTTP/2.0 " )
26+ #expect( HTTPVersion ( rawValue: " HTTP/2.0 " ) == . v2)
25227 }
25328}
0 commit comments