test(ios): cover settings host/port parsing
parent
6bf1e6fa06
commit
dbd3865e3b
|
|
@ -0,0 +1,40 @@
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
struct SettingsHostPort: Equatable {
|
||||||
|
var host: String
|
||||||
|
var port: Int
|
||||||
|
}
|
||||||
|
|
||||||
|
enum SettingsNetworkingHelpers {
|
||||||
|
static func parseHostPort(from address: String) -> SettingsHostPort? {
|
||||||
|
let trimmed = address.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
|
guard !trimmed.isEmpty else { return nil }
|
||||||
|
|
||||||
|
if trimmed.hasPrefix("["),
|
||||||
|
let close = trimmed.firstIndex(of: "]"),
|
||||||
|
close < trimmed.endIndex
|
||||||
|
{
|
||||||
|
let host = String(trimmed[trimmed.index(after: trimmed.startIndex)..<close])
|
||||||
|
let portStart = trimmed.index(after: close)
|
||||||
|
guard portStart < trimmed.endIndex, trimmed[portStart] == ":" else { return nil }
|
||||||
|
let portString = String(trimmed[trimmed.index(after: portStart)...])
|
||||||
|
guard let port = Int(portString) else { return nil }
|
||||||
|
return SettingsHostPort(host: host, port: port)
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let colon = trimmed.lastIndex(of: ":") else { return nil }
|
||||||
|
let host = String(trimmed[..<colon])
|
||||||
|
let portString = String(trimmed[trimmed.index(after: colon)...])
|
||||||
|
guard !host.isEmpty, let port = Int(portString) else { return nil }
|
||||||
|
return SettingsHostPort(host: host, port: port)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func httpURLString(host: String?, port: Int?, fallback: String) -> String {
|
||||||
|
if let host, let port {
|
||||||
|
let needsBrackets = host.contains(":") && !host.hasPrefix("[") && !host.hasSuffix("]")
|
||||||
|
let hostPart = needsBrackets ? "[\(host)]" : host
|
||||||
|
return "http://\(hostPart):\(port)"
|
||||||
|
}
|
||||||
|
return "http://\(fallback)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -400,40 +400,11 @@ struct SettingsTab: View {
|
||||||
return en0 ?? fallback
|
return en0 ?? fallback
|
||||||
}
|
}
|
||||||
|
|
||||||
private struct HostPort: Equatable {
|
private static func parseHostPort(from address: String) -> SettingsHostPort? {
|
||||||
var host: String
|
SettingsNetworkingHelpers.parseHostPort(from: address)
|
||||||
var port: Int
|
|
||||||
}
|
|
||||||
|
|
||||||
private static func parseHostPort(from address: String) -> HostPort? {
|
|
||||||
let trimmed = address.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
||||||
guard !trimmed.isEmpty else { return nil }
|
|
||||||
|
|
||||||
if trimmed.hasPrefix("["),
|
|
||||||
let close = trimmed.firstIndex(of: "]"),
|
|
||||||
close < trimmed.endIndex
|
|
||||||
{
|
|
||||||
let host = String(trimmed[trimmed.index(after: trimmed.startIndex)..<close])
|
|
||||||
let portStart = trimmed.index(after: close)
|
|
||||||
guard portStart < trimmed.endIndex, trimmed[portStart] == ":" else { return nil }
|
|
||||||
let portString = String(trimmed[trimmed.index(after: portStart)...])
|
|
||||||
guard let port = Int(portString) else { return nil }
|
|
||||||
return HostPort(host: host, port: port)
|
|
||||||
}
|
|
||||||
|
|
||||||
guard let colon = trimmed.lastIndex(of: ":") else { return nil }
|
|
||||||
let host = String(trimmed[..<colon])
|
|
||||||
let portString = String(trimmed[trimmed.index(after: colon)...])
|
|
||||||
guard !host.isEmpty, let port = Int(portString) else { return nil }
|
|
||||||
return HostPort(host: host, port: port)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func httpURLString(host: String?, port: Int?, fallback: String) -> String {
|
private static func httpURLString(host: String?, port: Int?, fallback: String) -> String {
|
||||||
if let host, let port {
|
SettingsNetworkingHelpers.httpURLString(host: host, port: port, fallback: fallback)
|
||||||
let needsBrackets = host.contains(":") && !host.hasPrefix("[") && !host.hasSuffix("]")
|
|
||||||
let hostPart = needsBrackets ? "[\(host)]" : host
|
|
||||||
return "http://\(hostPart):\(port)"
|
|
||||||
}
|
|
||||||
return "http://\(fallback)"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
import Testing
|
||||||
|
@testable import Clawdis
|
||||||
|
|
||||||
|
@Suite struct SettingsNetworkingHelpersTests {
|
||||||
|
@Test func parseHostPortParsesIPv4() {
|
||||||
|
#expect(SettingsNetworkingHelpers.parseHostPort(from: "127.0.0.1:8080") == .init(host: "127.0.0.1", port: 8080))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test func parseHostPortParsesHostnameAndTrims() {
|
||||||
|
#expect(SettingsNetworkingHelpers.parseHostPort(from: " example.com:80 \n") == .init(host: "example.com", port: 80))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test func parseHostPortParsesBracketedIPv6() {
|
||||||
|
#expect(
|
||||||
|
SettingsNetworkingHelpers.parseHostPort(from: "[2001:db8::1]:443") ==
|
||||||
|
.init(host: "2001:db8::1", port: 443))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test func parseHostPortRejectsMissingPort() {
|
||||||
|
#expect(SettingsNetworkingHelpers.parseHostPort(from: "example.com") == nil)
|
||||||
|
#expect(SettingsNetworkingHelpers.parseHostPort(from: "[2001:db8::1]") == nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test func parseHostPortRejectsInvalidPort() {
|
||||||
|
#expect(SettingsNetworkingHelpers.parseHostPort(from: "example.com:lol") == nil)
|
||||||
|
#expect(SettingsNetworkingHelpers.parseHostPort(from: "[2001:db8::1]:lol") == nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test func httpURLStringFormatsIPv4AndPort() {
|
||||||
|
#expect(SettingsNetworkingHelpers.httpURLString(host: "127.0.0.1", port: 8080, fallback: "fallback") == "http://127.0.0.1:8080")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test func httpURLStringBracketsIPv6() {
|
||||||
|
#expect(SettingsNetworkingHelpers.httpURLString(host: "2001:db8::1", port: 8080, fallback: "fallback") == "http://[2001:db8::1]:8080")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test func httpURLStringLeavesAlreadyBracketedIPv6() {
|
||||||
|
#expect(SettingsNetworkingHelpers.httpURLString(host: "[2001:db8::1]", port: 8080, fallback: "fallback") == "http://[2001:db8::1]:8080")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test func httpURLStringFallsBackWhenMissingHostOrPort() {
|
||||||
|
#expect(SettingsNetworkingHelpers.httpURLString(host: nil, port: 80, fallback: "x") == "http://x")
|
||||||
|
#expect(SettingsNetworkingHelpers.httpURLString(host: "example.com", port: nil, fallback: "y") == "http://y")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
Reference in New Issue