Skip to content

Commit 30ffba9

Browse files
committed
fix tests in Linux
1 parent 4a70fda commit 30ffba9

File tree

6 files changed

+112
-50
lines changed

6 files changed

+112
-50
lines changed

Sources/Storage/MultipartFormData.swift

Lines changed: 48 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -419,8 +419,17 @@ class MultipartFormData {
419419
var buffer = [UInt8](repeating: 0, count: streamBufferSize)
420420
let bytesRead = inputStream.read(&buffer, maxLength: streamBufferSize)
421421

422-
if let error = inputStream.streamError {
423-
throw MultipartFormDataError.inputStreamReadFailed(error: error)
422+
if bytesRead < 0 {
423+
if let error = inputStream.streamError {
424+
throw MultipartFormDataError.inputStreamReadFailed(error: error)
425+
} else {
426+
throw MultipartFormDataError.inputStreamReadFailed(
427+
error: MultipartFormDataError.UnexpectedInputStreamLength(
428+
bytesExpected: bodyPart.bodyContentLength,
429+
bytesRead: UInt64(encoded.count)
430+
)
431+
)
432+
}
424433
}
425434

426435
if bytesRead > 0 {
@@ -474,9 +483,17 @@ class MultipartFormData {
474483
let bufferSize = min(streamBufferSize, Int(bytesLeftToRead))
475484
var buffer = [UInt8](repeating: 0, count: bufferSize)
476485
let bytesRead = inputStream.read(&buffer, maxLength: bufferSize)
477-
478-
if let streamError = inputStream.streamError {
479-
throw MultipartFormDataError.inputStreamReadFailed(error: streamError)
486+
if bytesRead < 0 {
487+
if let streamError = inputStream.streamError {
488+
throw MultipartFormDataError.inputStreamReadFailed(error: streamError)
489+
} else {
490+
throw MultipartFormDataError.inputStreamReadFailed(
491+
error: MultipartFormDataError.UnexpectedInputStreamLength(
492+
bytesExpected: bodyPart.bodyContentLength,
493+
bytesRead: bodyPart.bodyContentLength - bytesLeftToRead
494+
)
495+
)
496+
}
480497
}
481498

482499
if bytesRead > 0 {
@@ -514,8 +531,17 @@ class MultipartFormData {
514531
while bytesToWrite > 0, outputStream.hasSpaceAvailable {
515532
let bytesWritten = outputStream.write(buffer, maxLength: bytesToWrite)
516533

517-
if let error = outputStream.streamError {
518-
throw MultipartFormDataError.outputStreamWriteFailed(error: error)
534+
if bytesWritten < 0 {
535+
if let error = outputStream.streamError {
536+
throw MultipartFormDataError.outputStreamWriteFailed(error: error)
537+
} else {
538+
throw MultipartFormDataError.outputStreamWriteFailed(
539+
error: MultipartFormDataError.UnexpectedInputStreamLength(
540+
bytesExpected: UInt64(buffer.count),
541+
bytesRead: UInt64(buffer.count - bytesToWrite)
542+
)
543+
)
544+
}
519545
}
520546

521547
bytesToWrite -= bytesWritten
@@ -650,10 +676,10 @@ enum MultipartFormDataError: Error {
650676

651677
var underlyingError: (any Error)? {
652678
switch self {
653-
case let .bodyPartFileNotReachableWithError(_, error),
654-
let .bodyPartFileSizeQueryFailedWithError(_, error),
655-
let .inputStreamReadFailed(error),
656-
let .outputStreamWriteFailed(error):
679+
case .bodyPartFileNotReachableWithError(_, let error),
680+
.bodyPartFileSizeQueryFailedWithError(_, let error),
681+
.inputStreamReadFailed(let error),
682+
.outputStreamWriteFailed(let error):
657683
error
658684

659685
case .bodyPartURLInvalid,
@@ -671,17 +697,17 @@ enum MultipartFormDataError: Error {
671697

672698
var url: URL? {
673699
switch self {
674-
case let .bodyPartURLInvalid(url),
675-
let .bodyPartFilenameInvalid(url),
676-
let .bodyPartFileNotReachable(url),
677-
let .bodyPartFileNotReachableWithError(url, _),
678-
let .bodyPartFileIsDirectory(url),
679-
let .bodyPartFileSizeNotAvailable(url),
680-
let .bodyPartFileSizeQueryFailedWithError(url, _),
681-
let .bodyPartInputStreamCreationFailed(url),
682-
let .outputStreamFileAlreadyExists(url),
683-
let .outputStreamURLInvalid(url),
684-
let .outputStreamCreationFailed(url):
700+
case .bodyPartURLInvalid(let url),
701+
.bodyPartFilenameInvalid(let url),
702+
.bodyPartFileNotReachable(let url),
703+
.bodyPartFileNotReachableWithError(let url, _),
704+
.bodyPartFileIsDirectory(let url),
705+
.bodyPartFileSizeNotAvailable(let url),
706+
.bodyPartFileSizeQueryFailedWithError(let url, _),
707+
.bodyPartInputStreamCreationFailed(let url),
708+
.outputStreamFileAlreadyExists(let url),
709+
.outputStreamURLInvalid(let url),
710+
.outputStreamCreationFailed(let url):
685711
url
686712

687713
case .inputStreamReadFailed, .outputStreamWriteFailed:

Tests/HelpersTests/HTTPErrorTests.swift

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ import Foundation
99
import Helpers
1010
import XCTest
1111

12+
#if canImport(FoundationNetworking)
13+
import FoundationNetworking
14+
#endif
15+
1216
final class HTTPErrorTests: XCTestCase {
1317

1418
func testInitialization() {
@@ -19,9 +23,9 @@ final class HTTPErrorTests: XCTestCase {
1923
httpVersion: "1.1",
2024
headerFields: ["Content-Type": "application/json"]
2125
)!
22-
26+
2327
let error = HTTPError(data: data, response: response)
24-
28+
2529
XCTAssertEqual(error.data, data)
2630
XCTAssertEqual(error.response, response)
2731
}
@@ -34,9 +38,9 @@ final class HTTPErrorTests: XCTestCase {
3438
httpVersion: "1.1",
3539
headerFields: nil
3640
)!
37-
41+
3842
let error = HTTPError(data: data, response: response)
39-
43+
4044
XCTAssertEqual(
4145
error.errorDescription,
4246
"Status Code: 400 Body: Bad Request: Invalid parameters"
@@ -51,9 +55,9 @@ final class HTTPErrorTests: XCTestCase {
5155
httpVersion: "1.1",
5256
headerFields: nil
5357
)!
54-
58+
5559
let error = HTTPError(data: data, response: response)
56-
60+
5761
XCTAssertEqual(error.errorDescription, "Status Code: 404 Body: ")
5862
}
5963

@@ -67,29 +71,29 @@ final class HTTPErrorTests: XCTestCase {
6771
httpVersion: "1.1",
6872
headerFields: nil
6973
)!
70-
74+
7175
let error = HTTPError(data: data, response: response)
72-
76+
7377
XCTAssertEqual(error.errorDescription, "Status Code: 500")
7478
}
7579

7680
func testLocalizedErrorDescription_WithJSONData() {
7781
let jsonString = """
78-
{
79-
"error": "Validation failed",
80-
"details": "Email format is invalid"
81-
}
82-
"""
82+
{
83+
"error": "Validation failed",
84+
"details": "Email format is invalid"
85+
}
86+
"""
8387
let data = Data(jsonString.utf8)
8488
let response = HTTPURLResponse(
8589
url: URL(string: "https://example.com")!,
8690
statusCode: 422,
8791
httpVersion: "1.1",
8892
headerFields: ["Content-Type": "application/json"]
8993
)!
90-
94+
9195
let error = HTTPError(data: data, response: response)
92-
96+
9397
XCTAssertEqual(
9498
error.errorDescription,
9599
"Status Code: 422 Body: \(jsonString)"
@@ -105,9 +109,9 @@ final class HTTPErrorTests: XCTestCase {
105109
httpVersion: "1.1",
106110
headerFields: nil
107111
)!
108-
112+
109113
let error = HTTPError(data: data, response: response)
110-
114+
111115
XCTAssertEqual(
112116
error.errorDescription,
113117
"Status Code: 400 Body: \(message)"
@@ -123,16 +127,15 @@ final class HTTPErrorTests: XCTestCase {
123127
httpVersion: "1.1",
124128
headerFields: nil
125129
)!
126-
130+
127131
let error = HTTPError(data: data, response: response)
128-
132+
129133
XCTAssertEqual(
130134
error.errorDescription,
131135
"Status Code: 413 Body: \(largeMessage)"
132136
)
133137
}
134138

135-
136139
func testProperties() {
137140
let data = Data("test error".utf8)
138141
let response = HTTPURLResponse(
@@ -141,13 +144,13 @@ final class HTTPErrorTests: XCTestCase {
141144
httpVersion: "1.1",
142145
headerFields: ["Content-Type": "application/json"]
143146
)!
144-
147+
145148
let error = HTTPError(data: data, response: response)
146-
149+
147150
// Test that properties are correctly set
148151
XCTAssertEqual(error.data, data)
149152
XCTAssertEqual(error.response, response)
150153
XCTAssertEqual(error.response.statusCode, 400)
151154
XCTAssertEqual(error.response.url, URL(string: "https://example.com")!)
152155
}
153-
}
156+
}

Tests/HelpersTests/LoggerInterceptorTests.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,15 @@
55
// Created by Coverage Tests
66
//
77

8+
import Foundation
9+
import HTTPTypes
810
import XCTest
11+
912
@testable import Helpers
10-
import HTTPTypes
13+
14+
#if canImport(FoundationNetworking)
15+
import FoundationNetworking
16+
#endif
1117

1218
final class LoggerInterceptorTests: XCTestCase {
1319

@@ -69,7 +75,7 @@ final class LoggerInterceptorTests: XCTestCase {
6975
}
7076

7177
// Verify request was logged
72-
XCTAssertEqual(logger.verboseLogs.count, 2) // Request and response
78+
XCTAssertEqual(logger.verboseLogs.count, 2) // Request and response
7379
XCTAssertTrue(logger.verboseLogs[0].contains("Request:"))
7480
XCTAssertTrue(logger.verboseLogs[0].contains("/users"))
7581
}

Tests/RealtimeTests/PushV2Tests.swift

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,15 @@
66
//
77

88
import ConcurrencyExtras
9+
import Foundation
910
import XCTest
1011

1112
@testable import Realtime
1213

14+
#if canImport(FoundationNetworking)
15+
import FoundationNetworking
16+
#endif
17+
1318
final class PushV2Tests: XCTestCase {
1419

1520
func testPushStatusValues() {
@@ -334,6 +339,12 @@ private final class MockRealtimeClient: RealtimeClientProtocol, @unchecked Senda
334339

335340
private struct MockHTTPClient: HTTPClientType {
336341
func send(_ request: HTTPRequest) async throws -> HTTPResponse {
337-
return HTTPResponse(data: Data(), response: HTTPURLResponse())
342+
let urlResponse = HTTPURLResponse(
343+
url: URL(string: "https://example.com")!,
344+
statusCode: 200,
345+
httpVersion: nil,
346+
headerFields: nil
347+
)!
348+
return HTTPResponse(data: Data(), response: urlResponse)
338349
}
339350
}

Tests/StorageTests/StorageBucketAPITests.swift

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ final class StorageBucketAPITests: XCTestCase {
7777
]
7878

7979
for (input, expect, description) in urlTestCases {
80-
XCTContext.runActivity(named: "should \(description) if useNewHostname is true") { _ in
80+
runActivity(named: "should \(description) if useNewHostname is true") {
8181
let storage = SupabaseStorageClient(
8282
configuration: StorageClientConfiguration(
8383
url: URL(string: input)!,
@@ -88,7 +88,7 @@ final class StorageBucketAPITests: XCTestCase {
8888
XCTAssertEqual(storage.configuration.url.absoluteString, expect)
8989
}
9090

91-
XCTContext.runActivity(named: "should not modify host if useNewHostname is false") { _ in
91+
runActivity(named: "should not modify host if useNewHostname is false") {
9292
let storage = SupabaseStorageClient(
9393
configuration: StorageClientConfiguration(
9494
url: URL(string: input)!,
@@ -101,6 +101,16 @@ final class StorageBucketAPITests: XCTestCase {
101101
}
102102
}
103103

104+
private func runActivity(named name: String, body: () -> Void) {
105+
#if os(Linux)
106+
body()
107+
#else
108+
XCTContext.runActivity(named: name) { _ in
109+
body()
110+
}
111+
#endif
112+
}
113+
104114
func testGetBucket() async throws {
105115
Mock(
106116
url: url.appendingPathComponent("bucket/bucket123"),

scripts/run-on-linux.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/bin/bash
2+
3+
SWIFT_VERSION="latest"
4+
5+
# Spin Swift Docker container
6+
docker run -it --rm -v $(pwd):/app -w /app "swift:$SWIFT_VERSION" bash

0 commit comments

Comments
 (0)