Merge pull request #1195 from johnno1962e/master
diff --git a/Foundation/HTTPCookieStorage.swift b/Foundation/HTTPCookieStorage.swift
index 2e9e080..045b69d 100644
--- a/Foundation/HTTPCookieStorage.swift
+++ b/Foundation/HTTPCookieStorage.swift
@@ -49,7 +49,7 @@
let bundlePath = Bundle.main.bundlePath
var bundleName = bundlePath.components(separatedBy: "/").last!
if let range = bundleName.range(of: ".", options: String.CompareOptions.backwards, range: nil, locale: nil) {
- bundleName = bundleName.substring(to: range.lowerBound)
+ bundleName = String(bundleName[..<range.lowerBound])
}
let cookieFolderPath = _CFXDGCreateDataHomePath()._swiftObject + "/" + bundleName
cookieFilePath = filePath(path: cookieFolderPath, fileName: "/.cookies." + cookieStorageName, bundleName: bundleName)
diff --git a/Foundation/JSONSerialization.swift b/Foundation/JSONSerialization.swift
index a7b011f..f74932d 100644
--- a/Foundation/JSONSerialization.swift
+++ b/Foundation/JSONSerialization.swift
@@ -62,8 +62,9 @@
return true
}
- // object is Swift.String, NSNull, Int, Bool, or UInt
- if obj is String || obj is NSNull || obj is Int || obj is Bool || obj is UInt {
+ if obj is String || obj is NSNull || obj is Int || obj is Bool || obj is UInt ||
+ obj is Int8 || obj is Int16 || obj is Int32 || obj is Int64 ||
+ obj is UInt8 || obj is UInt16 || obj is UInt32 || obj is UInt64 {
return true
}
@@ -76,6 +77,10 @@
return number.isFinite
}
+ if let number = obj as? Decimal {
+ return number.isFinite
+ }
+
// object is Swift.Array
if let array = obj as? [Any?] {
for element in array {
@@ -99,8 +104,13 @@
// object is NSNumber and is not NaN or infinity
// For better performance, this (most expensive) test should be last.
if let number = _SwiftValue.store(obj) as? NSNumber {
- let invalid = number.doubleValue.isInfinite || number.doubleValue.isNaN
- return !invalid
+ if CFNumberIsFloatType(number._cfObject) {
+ let dv = number.doubleValue
+ let invalid = dv.isInfinite || dv.isNaN
+ return !invalid
+ } else {
+ return true
+ }
}
// invalid object
@@ -285,9 +295,7 @@
//MARK: - JSONSerializer
private struct JSONWriter {
-
- private let maxUIntLength = String(describing: UInt.max).count
- private let maxIntLength = String(describing: Int.max).count
+
var indent = 0
let pretty: Bool
let sortedKeys: Bool
@@ -320,13 +328,37 @@
case let boolValue as Bool:
serializeBool(boolValue)
case let num as Int:
- try serializeInt(value: num)
+ serializeInteger(value: num)
+ case let num as Int8:
+ serializeInteger(value: num)
+ case let num as Int16:
+ serializeInteger(value: num)
+ case let num as Int32:
+ serializeInteger(value: num)
+ case let num as Int64:
+ serializeInteger(value: num)
case let num as UInt:
- try serializeUInt(value: num)
+ serializeInteger(value: num)
+ case let num as UInt8:
+ serializeInteger(value: num)
+ case let num as UInt16:
+ serializeInteger(value: num)
+ case let num as UInt32:
+ serializeInteger(value: num)
+ case let num as UInt64:
+ serializeInteger(value: num)
case let array as Array<Any?>:
try serializeArray(array)
case let dict as Dictionary<AnyHashable, Any?>:
try serializeDictionary(dict)
+ case let num as Float:
+ try serializeNumber(NSNumber(value: num))
+ case let num as Double:
+ try serializeNumber(NSNumber(value: num))
+ case let num as Decimal:
+ writer(num.description)
+ case let num as NSDecimalNumber:
+ writer(num.description)
case is NSNull:
try serializeNull()
case _ where _SwiftValue.store(obj) is NSNumber:
@@ -336,92 +368,33 @@
}
}
- private func serializeUInt(value: UInt) throws {
- if value == 0 {
- writer("0")
- return
- }
- var array: [UInt] = []
- var stringResult = ""
- //Maximum length of an UInt
- array.reserveCapacity(maxUIntLength)
- stringResult.reserveCapacity(maxUIntLength)
- var number = value
-
- while number != 0 {
- array.append(number % 10)
+ private func serializeInteger<T: UnsignedInteger>(value: T, isNegative: Bool = false) {
+ let maxIntLength = 22 // 20 digits in UInt64 + optional sign + trailing '\0'
+ let asciiZero: CChar = 0x30 // ASCII '0' == 0x30
+ let asciiMinus: CChar = 0x2d // ASCII '-' == 0x2d
+
+ var number = UInt64(value)
+ var buffer = Array<CChar>(repeating: 0, count: maxIntLength)
+ var pos = maxIntLength - 1
+
+ repeat {
+ pos -= 1
+ buffer[pos] = asciiZero + CChar(number % 10)
number /= 10
+ } while number != 0
+
+ if isNegative {
+ pos -= 1
+ buffer[pos] = asciiMinus
}
-
- /*
- Step backwards through the array and append the values to the string. This way the values are appended in the correct order.
- */
- var counter = array.count
- while counter > 0 {
- counter -= 1
- let digit: UInt = array[counter]
- switch digit {
- case 0: stringResult.append("0")
- case 1: stringResult.append("1")
- case 2: stringResult.append("2")
- case 3: stringResult.append("3")
- case 4: stringResult.append("4")
- case 5: stringResult.append("5")
- case 6: stringResult.append("6")
- case 7: stringResult.append("7")
- case 8: stringResult.append("8")
- case 9: stringResult.append("9")
- default: fatalError()
- }
- }
-
- writer(stringResult)
+ let output = String(cString: Array(buffer.suffix(from: pos)))
+ writer(output)
}
-
- private func serializeInt(value: Int) throws {
- if value == 0 {
- writer("0")
- return
- }
- var array: [Int] = []
- var stringResult = ""
- array.reserveCapacity(maxIntLength)
- //Account for a negative sign
- stringResult.reserveCapacity(maxIntLength + 1)
- var number = value
-
- while number != 0 {
- array.append(number % 10)
- number /= 10
- }
- //If negative add minus sign before adding any values
- if value < 0 {
- stringResult.append("-")
- }
- /*
- Step backwards through the array and append the values to the string. This way the values are appended in the correct order.
- */
- var counter = array.count
- while counter > 0 {
- counter -= 1
- let digit = array[counter]
- switch digit {
- case 0: stringResult.append("0")
- case 1, -1: stringResult.append("1")
- case 2, -2: stringResult.append("2")
- case 3, -3: stringResult.append("3")
- case 4, -4: stringResult.append("4")
- case 5, -5: stringResult.append("5")
- case 6, -6: stringResult.append("6")
- case 7, -7: stringResult.append("7")
- case 8, -8: stringResult.append("8")
- case 9, -9: stringResult.append("9")
- default: fatalError()
- }
- }
- writer(stringResult)
+
+ private func serializeInteger<T: SignedInteger>(value: T) {
+ serializeInteger(value: UInt64(value.magnitude), isNegative: value < 0)
}
-
+
func serializeString(_ str: String) throws {
writer("\"")
for scalar in str.unicodeScalars {
@@ -462,15 +435,30 @@
}
mutating func serializeNumber(_ num: NSNumber) throws {
- if num.doubleValue.isInfinite || num.doubleValue.isNaN {
- throw NSError(domain: NSCocoaErrorDomain, code: CocoaError.propertyListReadCorrupt.rawValue, userInfo: ["NSDebugDescription" : "Number cannot be infinity or NaN"])
- }
-
- switch num._cfTypeID {
- case CFBooleanGetTypeID():
- serializeBool(num.boolValue)
- default:
- writer(_serializationString(for: num))
+ if CFNumberIsFloatType(num._cfObject) {
+ let dv = num.doubleValue
+ if !dv.isFinite {
+ let value: String
+ if dv.isNaN {
+ value = "NaN"
+ } else if dv.isInfinite {
+ value = "infinite"
+ } else {
+ value = String(dv)
+ }
+
+ throw NSError(domain: NSCocoaErrorDomain, code: CocoaError.propertyListReadCorrupt.rawValue, userInfo: ["NSDebugDescription" : "Invalid number value (\(value)) in JSON write"])
+ }
+
+ let string = CFNumberFormatterCreateStringWithNumber(nil, _numberformatter, num._cfObject)._swiftObject
+ writer(string)
+ } else {
+ switch num._cfTypeID {
+ case CFBooleanGetTypeID():
+ serializeBool(num.boolValue)
+ default:
+ writer(num.stringValue)
+ }
}
}
@@ -578,13 +566,6 @@
}
}
- //[SR-2151] https://bugs.swift.org/browse/SR-2151
- private mutating func _serializationString(for number: NSNumber) -> String {
- if !CFNumberIsFloatType(number._cfObject) {
- return number.stringValue
- }
- return CFNumberFormatterCreateStringWithNumber(nil, _numberformatter, number._cfObject)._swiftObject
- }
}
//MARK: - JSONDeserializer
diff --git a/TestFoundation/HTTPServer.swift b/TestFoundation/HTTPServer.swift
index 14823d5..f52b771 100644
--- a/TestFoundation/HTTPServer.swift
+++ b/TestFoundation/HTTPServer.swift
@@ -37,6 +37,12 @@
static let EMPTY = ""
}
+extension UInt16 {
+ public init(networkByteOrder input: UInt16) {
+ self.init(bigEndian: input)
+ }
+}
+
class _TCPSocket {
private var listenSocket: Int32!
@@ -57,12 +63,15 @@
return r
}
- init(port: UInt16) throws {
+ public private(set) var port: UInt16
+
+ init(port: UInt16?) throws {
#if os(Linux)
let SOCKSTREAM = Int32(SOCK_STREAM.rawValue)
#else
let SOCKSTREAM = SOCK_STREAM
#endif
+ self.port = port ?? 0
listenSocket = try attempt("socket", valid: isNotNegative, socket(AF_INET, SOCKSTREAM, Int32(IPPROTO_TCP)))
var on: Int = 1
_ = try attempt("setsockopt", valid: isZero, setsockopt(listenSocket, SOL_SOCKET, SO_REUSEADDR, &on, socklen_t(MemoryLayout<Int>.size)))
@@ -72,16 +81,26 @@
let addr = UnsafePointer<sockaddr>($0)
_ = try attempt("bind", valid: isZero, bind(listenSocket, addr, socklen_t(MemoryLayout<sockaddr>.size)))
})
+
+ var actualSA = sockaddr_in()
+ withUnsafeMutablePointer(to: &actualSA) { ptr in
+ ptr.withMemoryRebound(to: sockaddr.self, capacity: 1) { (ptr: UnsafeMutablePointer<sockaddr>) in
+ var len = socklen_t(MemoryLayout<sockaddr>.size)
+ getsockname(listenSocket, ptr, &len)
+ }
+ }
+
+ self.port = UInt16(networkByteOrder: actualSA.sin_port)
}
- private func createSockaddr(_ port: UInt16) -> sockaddr_in {
+ private func createSockaddr(_ port: UInt16?) -> sockaddr_in {
// Listen on the loopback address so that OSX doesnt pop up a dialog
// asking to accept incoming connections if the firewall is enabled.
let addr = UInt32(INADDR_LOOPBACK).bigEndian
#if os(Linux)
- return sockaddr_in(sin_family: sa_family_t(AF_INET), sin_port: htons(port), sin_addr: in_addr(s_addr: addr), sin_zero: (0,0,0,0,0,0,0,0))
+ return sockaddr_in(sin_family: sa_family_t(AF_INET), sin_port: htons(port ?? 0), sin_addr: in_addr(s_addr: addr), sin_zero: (0,0,0,0,0,0,0,0))
#else
- return sockaddr_in(sin_len: 0, sin_family: sa_family_t(AF_INET), sin_port: CFSwapInt16HostToBig(port), sin_addr: in_addr(s_addr: addr), sin_zero: (0,0,0,0,0,0,0,0))
+ return sockaddr_in(sin_len: 0, sin_family: sa_family_t(AF_INET), sin_port: CFSwapInt16HostToBig(port ?? 0), sin_addr: in_addr(s_addr: addr), sin_zero: (0,0,0,0,0,0,0,0))
#endif
}
@@ -135,20 +154,27 @@
}
func shutdown() {
- close(connectionSocket)
+ if let connectionSocket = self.connectionSocket {
+ close(connectionSocket)
+ }
close(listenSocket)
}
}
class _HTTPServer {
- let socket: _TCPSocket
+ let socket: _TCPSocket
+ var port: UInt16 {
+ get {
+ return self.socket.port
+ }
+ }
- init(port: UInt16) throws {
+ init(port: UInt16?) throws {
socket = try _TCPSocket(port: port)
}
- public class func create(port: UInt16) throws -> _HTTPServer {
+ public class func create(port: UInt16?) throws -> _HTTPServer {
return try _HTTPServer(port: port)
}
@@ -161,7 +187,7 @@
}
public func request() throws -> _HTTPRequest {
- return _HTTPRequest(request: try socket.readData())
+ return try _HTTPRequest(request: socket.readData())
}
public func respond(with response: _HTTPResponse, startDelay: TimeInterval? = nil, sendDelay: TimeInterval? = nil, bodyChunks: Int? = nil) throws {
@@ -309,8 +335,13 @@
let startDelay: TimeInterval?
let sendDelay: TimeInterval?
let bodyChunks: Int?
+ var port: UInt16 {
+ get {
+ return self.httpServer.port
+ }
+ }
- public init (port: UInt16, startDelay: TimeInterval? = nil, sendDelay: TimeInterval? = nil, bodyChunks: Int? = nil) throws {
+ public init (port: UInt16?, startDelay: TimeInterval? = nil, sendDelay: TimeInterval? = nil, bodyChunks: Int? = nil) throws {
httpServer = try _HTTPServer.create(port: port)
self.startDelay = startDelay
self.sendDelay = sendDelay
@@ -406,23 +437,28 @@
}
class LoopbackServerTest : XCTestCase {
- static var serverPort: Int = -1
+ private static let staticSyncQ = DispatchQueue(label: "org.swift.TestFoundation.HTTPServer.StaticSyncQ")
+
+ private static var _serverPort: Int = -1
+ static var serverPort: Int {
+ get {
+ return staticSyncQ.sync { _serverPort }
+ }
+ set {
+ staticSyncQ.sync { _serverPort = newValue }
+ }
+ }
override class func setUp() {
super.setUp()
func runServer(with condition: ServerSemaphore, startDelay: TimeInterval? = nil, sendDelay: TimeInterval? = nil, bodyChunks: Int? = nil) throws {
- let start = 21961
- for port in start...(start+100) { //we must find at least one port to bind
- do {
- serverPort = port
- let test = try TestURLSessionServer(port: UInt16(port), startDelay: startDelay, sendDelay: sendDelay, bodyChunks: bodyChunks)
- try test.start(started: condition)
- try test.readAndRespond()
- test.stop()
- } catch let e as ServerError {
- if e.operation == "bind" { continue }
- throw e
- }
+ while true {
+ let test = try TestURLSessionServer(port: nil, startDelay: startDelay, sendDelay: sendDelay, bodyChunks: bodyChunks)
+ serverPort = Int(test.port)
+ try test.start(started: condition)
+ try test.readAndRespond()
+ serverPort = -2
+ test.stop()
}
}
diff --git a/TestFoundation/TestHTTPCookieStorage.swift b/TestFoundation/TestHTTPCookieStorage.swift
index bea3391..472e34a 100644
--- a/TestFoundation/TestHTTPCookieStorage.swift
+++ b/TestFoundation/TestHTTPCookieStorage.swift
@@ -230,7 +230,7 @@
let bundlePath = Bundle.main.bundlePath
var bundleName = "/" + bundlePath.components(separatedBy: "/").last!
if let range = bundleName.range(of: ".", options: String.CompareOptions.backwards, range: nil, locale: nil) {
- bundleName = bundleName.substring(to: range.lowerBound)
+ bundleName = String(bundleName[..<range.lowerBound])
}
if let xdg_data_home = getenv("XDG_DATA_HOME") {
destPath = String(utf8String: xdg_data_home)! + bundleName + "/.cookies.shared"
@@ -251,7 +251,7 @@
let exeName = "/xdgTestHelper/xdgTestHelper"
#endif
- task.launchPath = bundlePath.substring(to: pathIndex!) + exeName
+ task.launchPath = bundlePath[..<pathIndex!] + exeName
var environment = ProcessInfo.processInfo.environment
let testPath = NSHomeDirectory() + "/TestXDG"
environment["XDG_DATA_HOME"] = testPath
diff --git a/TestFoundation/TestJSONEncoder.swift b/TestFoundation/TestJSONEncoder.swift
index 6444296..842eb52 100644
--- a/TestFoundation/TestJSONEncoder.swift
+++ b/TestFoundation/TestJSONEncoder.swift
@@ -405,23 +405,13 @@
// UInt and Int
func test_codingOfUIntMinMax() {
- let encoder = JSONEncoder()
-
struct MyValue: Codable {
- let intMin:Int = Int.min
- let intMax:Int = Int.max
- let uintMin:UInt = UInt.min
- let uintMax:UInt = UInt.max
+ let int64Min = Int64.min
+ let int64Max = Int64.max
+ let uint64Min = UInt64.min
+ let uint64Max = UInt64.max
}
- let myValue = MyValue()
- let myDictI: [String:Any] = ["intMin": myValue.intMin, "intMax": myValue.intMax]
- let myDictU: [String:Any] = ["uintMin": myValue.uintMin, "uintMax": myValue.uintMax]
- let myDict1: [String:Any] = ["intMin": myValue.intMin]
- let myDict2: [String:Any] = ["intMax": myValue.intMax]
- let myDict3: [String:Any] = ["uintMin": myValue.uintMin]
- let myDict4: [String:Any] = ["uintMax": myValue.uintMax]
-
func compareJSON(_ s1: String, _ s2: String) {
let ss1 = s1.trimmingCharacters(in: CharacterSet(charactersIn: "{}")).split(separator: Character(",")).sorted()
let ss2 = s2.trimmingCharacters(in: CharacterSet(charactersIn: "{}")).split(separator: Character(",")).sorted()
@@ -429,40 +419,16 @@
}
do {
+ let encoder = JSONEncoder()
+ let myValue = MyValue()
let result = try encoder.encode(myValue)
let r = String(data: result, encoding: .utf8) ?? "nil"
- compareJSON(r, "{\"uintMin\":0,\"uintMax\":18446744073709551615,\"intMin\":-9223372036854775808,\"intMax\":9223372036854775807}")
-
- let resultI = try JSONSerialization.data(withJSONObject: myDictI)
- let rI = String(data: resultI, encoding: .utf8) ?? "nil"
- compareJSON(rI, "{\"intMin\":-9223372036854775808,\"intMax\":9223372036854775807}")
-
- let resultU = try JSONSerialization.data(withJSONObject: myDictU)
- let rU = String(data: resultU, encoding: .utf8) ?? "nil"
- compareJSON(rU, "{\"uintMax\":18446744073709551615,\"uintMin\":0}")
-
- let result1 = try JSONSerialization.data(withJSONObject: myDict1)
- let r1 = String(data: result1, encoding: .utf8) ?? "nil"
- XCTAssertEqual(r1, "{\"intMin\":-9223372036854775808}")
-
- let result2 = try JSONSerialization.data(withJSONObject: myDict2)
- let r2 = String(data: result2, encoding: .utf8) ?? "nil"
- XCTAssertEqual(r2, "{\"intMax\":9223372036854775807}")
-
- let result3 = try JSONSerialization.data(withJSONObject: myDict3)
- let r3 = String(data: result3, encoding: .utf8) ?? "nil"
- XCTAssertEqual(r3, "{\"uintMin\":0}")
-
- let result4 = try JSONSerialization.data(withJSONObject: myDict4)
- let r4 = String(data: result4, encoding: .utf8) ?? "nil"
- XCTAssertEqual(r4, "{\"uintMax\":18446744073709551615}")
+ compareJSON(r, "{\"uint64Min\":0,\"uint64Max\":18446744073709551615,\"int64Min\":-9223372036854775808,\"int64Max\":9223372036854775807}")
} catch {
XCTFail(String(describing: error))
}
}
-
-
// MARK: - Helper Functions
private var _jsonEmptyDictionary: Data {
return "{}".data(using: .utf8)!
diff --git a/TestFoundation/TestJSONSerialization.swift b/TestFoundation/TestJSONSerialization.swift
index 61e23c1..a07eba4 100644
--- a/TestFoundation/TestJSONSerialization.swift
+++ b/TestFoundation/TestJSONSerialization.swift
@@ -829,6 +829,7 @@
return [
("test_isValidJSONObjectTrue", test_isValidJSONObjectTrue),
("test_isValidJSONObjectFalse", test_isValidJSONObjectFalse),
+ ("test_validNumericJSONObjects", test_validNumericJSONObjects)
]
}
@@ -924,6 +925,36 @@
}
}
+ func test_validNumericJSONObjects() {
+ // All of the numeric types supported by JSONSerialization
+ XCTAssertTrue(JSONSerialization.isValidJSONObject([nil, NSNull()]))
+ XCTAssertTrue(JSONSerialization.isValidJSONObject([true, false]))
+ XCTAssertTrue(JSONSerialization.isValidJSONObject([Int.min, Int8.min, Int16.min, Int32.min, Int64.min]))
+ XCTAssertTrue(JSONSerialization.isValidJSONObject([UInt.min, UInt8.min, UInt16.min, UInt32.min, UInt64.min]))
+ XCTAssertTrue(JSONSerialization.isValidJSONObject([Float.leastNonzeroMagnitude, Double.leastNonzeroMagnitude]))
+
+ XCTAssertTrue(JSONSerialization.isValidJSONObject([NSNumber(value: true), NSNumber(value: Float.greatestFiniteMagnitude), NSNumber(value: Double.greatestFiniteMagnitude)]))
+ XCTAssertTrue(JSONSerialization.isValidJSONObject([NSNumber(value: Int.max), NSNumber(value: Int8.max), NSNumber(value: Int16.max), NSNumber(value: Int32.max), NSNumber(value: Int64.max)]))
+ XCTAssertTrue(JSONSerialization.isValidJSONObject([NSNumber(value: UInt.max), NSNumber(value: UInt8.max), NSNumber(value: UInt16.max), NSNumber(value: UInt32.max), NSNumber(value: UInt64.max)]))
+ XCTAssertTrue(JSONSerialization.isValidJSONObject([NSDecimalNumber(booleanLiteral: true), NSDecimalNumber(decimal: Decimal.greatestFiniteMagnitude), NSDecimalNumber(floatLiteral: Double.greatestFiniteMagnitude), NSDecimalNumber(integerLiteral: Int.min)]))
+ XCTAssertTrue(JSONSerialization.isValidJSONObject([Decimal(123), Decimal(Double.leastNonzeroMagnitude)]))
+
+ XCTAssertFalse(JSONSerialization.isValidJSONObject(Float.nan))
+ XCTAssertFalse(JSONSerialization.isValidJSONObject(Float.infinity))
+ XCTAssertFalse(JSONSerialization.isValidJSONObject(-Float.infinity))
+ XCTAssertFalse(JSONSerialization.isValidJSONObject(NSNumber(value: Float.nan)))
+ XCTAssertFalse(JSONSerialization.isValidJSONObject(NSNumber(value: Float.infinity)))
+ XCTAssertFalse(JSONSerialization.isValidJSONObject(NSNumber(value: -Float.infinity)))
+
+ XCTAssertFalse(JSONSerialization.isValidJSONObject(Double.nan))
+ XCTAssertFalse(JSONSerialization.isValidJSONObject(Double.infinity))
+ XCTAssertFalse(JSONSerialization.isValidJSONObject(-Double.infinity))
+ XCTAssertFalse(JSONSerialization.isValidJSONObject(NSNumber(value: Double.nan)))
+ XCTAssertFalse(JSONSerialization.isValidJSONObject(NSNumber(value: Double.infinity)))
+ XCTAssertFalse(JSONSerialization.isValidJSONObject(NSNumber(value: -Double.infinity)))
+
+ XCTAssertFalse(JSONSerialization.isValidJSONObject(NSDecimalNumber(decimal: Decimal(floatLiteral: Double.nan))))
+ }
}
// MARK: - serializationTests
@@ -941,6 +972,14 @@
("test_serialize_IntMin", test_serialize_IntMin),
("test_serialize_UIntMax", test_serialize_UIntMax),
("test_serialize_UIntMin", test_serialize_UIntMin),
+ ("test_serialize_8BitSizes", test_serialize_8BitSizes),
+ ("test_serialize_16BitSizes", test_serialize_16BitSizes),
+ ("test_serialize_32BitSizes", test_serialize_32BitSizes),
+ ("test_serialize_64BitSizes", test_serialize_64BitSizes),
+ ("test_serialize_Float", test_serialize_Float),
+ ("test_serialize_Double", test_serialize_Double),
+ ("test_serialize_Decimal", test_serialize_Decimal),
+ ("test_serialize_NSDecimalNumber", test_serialize_NSDecimalNumber),
("test_serialize_stringEscaping", test_serialize_stringEscaping),
("test_jsonReadingOffTheEndOfBuffers", test_jsonReadingOffTheEndOfBuffers),
("test_jsonObjectToOutputStreamBuffer", test_jsonObjectToOutputStreamBuffer),
@@ -1172,7 +1211,80 @@
let json: [Any] = [UInt.min]
XCTAssertEqual(try trySerialize(json), "[\(UInt.min)]")
}
-
+
+ func test_serialize_8BitSizes() {
+ let json1 = [Int8.min, Int8(-1), Int8(0), Int8(1), Int8.max]
+ XCTAssertEqual(try trySerialize(json1), "[-128,-1,0,1,127]")
+ let json2 = [UInt8.min, UInt8(0), UInt8(1), UInt8.max]
+ XCTAssertEqual(try trySerialize(json2), "[0,0,1,255]")
+ }
+
+ func test_serialize_16BitSizes() {
+ let json1 = [Int16.min, Int16(-1), Int16(0), Int16(1), Int16.max]
+ XCTAssertEqual(try trySerialize(json1), "[-32768,-1,0,1,32767]")
+ let json2 = [UInt16.min, UInt16(0), UInt16(1), UInt16.max]
+ XCTAssertEqual(try trySerialize(json2), "[0,0,1,65535]")
+ }
+
+ func test_serialize_32BitSizes() {
+ let json1 = [Int32.min, Int32(-1), Int32(0), Int32(1), Int32.max]
+ XCTAssertEqual(try trySerialize(json1), "[-2147483648,-1,0,1,2147483647]")
+ let json2 = [UInt32.min, UInt32(0), UInt32(1), UInt32.max]
+ XCTAssertEqual(try trySerialize(json2), "[0,0,1,4294967295]")
+ }
+
+ func test_serialize_64BitSizes() {
+ let json1 = [Int64.min, Int64(-1), Int64(0), Int64(1), Int64.max]
+ XCTAssertEqual(try trySerialize(json1), "[-9223372036854775808,-1,0,1,9223372036854775807]")
+ let json2 = [UInt64.min, UInt64(0), UInt64(1), UInt64.max]
+ XCTAssertEqual(try trySerialize(json2), "[0,0,1,18446744073709551615]")
+ }
+
+ func test_serialize_Float() {
+ XCTAssertEqual(try trySerialize([-Float.leastNonzeroMagnitude, Float.leastNonzeroMagnitude]), "[-0,0]")
+ XCTAssertEqual(try trySerialize([-Float.greatestFiniteMagnitude]), "[-340282346638529000000000000000000000000]")
+ XCTAssertEqual(try trySerialize([Float.greatestFiniteMagnitude]), "[340282346638529000000000000000000000000]")
+ XCTAssertEqual(try trySerialize([Float(-1), Float.leastNonzeroMagnitude, Float(1)]), "[-1,0,1]")
+ }
+
+ func test_serialize_Double() {
+ XCTAssertEqual(try trySerialize([-Double.leastNonzeroMagnitude, Double.leastNonzeroMagnitude]), "[-0,0]")
+ XCTAssertEqual(try trySerialize([-Double.leastNormalMagnitude, Double.leastNormalMagnitude]), "[-0,0]")
+ XCTAssertEqual(try trySerialize([-Double.greatestFiniteMagnitude]), "[-179769313486232000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000]")
+ XCTAssertEqual(try trySerialize([Double.greatestFiniteMagnitude]), "[179769313486232000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000]")
+ XCTAssertEqual(try trySerialize([Double(-1.0), Double(1.0)]), "[-1,1]")
+ }
+
+ func test_serialize_Decimal() {
+ XCTAssertEqual(try trySerialize([-Decimal.leastFiniteMagnitude]), "[3402823669209384634633746074317682114550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000]")
+ XCTAssertEqual(try trySerialize([Decimal.leastFiniteMagnitude]), "[-3402823669209384634633746074317682114550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000]")
+ XCTAssertEqual(try trySerialize([-Decimal.leastNonzeroMagnitude]), "[-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001]")
+ XCTAssertEqual(try trySerialize([Decimal.leastNonzeroMagnitude]), "[0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001]")
+ XCTAssertEqual(try trySerialize([-Decimal.greatestFiniteMagnitude]), "[-3402823669209384634633746074317682114550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000]")
+ XCTAssertEqual(try trySerialize([Decimal.greatestFiniteMagnitude]), "[3402823669209384634633746074317682114550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000]")
+ XCTAssertEqual(try trySerialize([Decimal(Int8.min), Decimal(Int8(0)), Decimal(Int8.max)]), "[-128,0,127]")
+ XCTAssertEqual(try trySerialize([Decimal(string: "-0.0"), Decimal(string: "0.000"), Decimal(string: "1.0000")]), "[0,0,1]")
+ }
+
+ func test_serialize_NSDecimalNumber() {
+ let dn0: [Any] = [NSDecimalNumber(floatLiteral: -Double.leastNonzeroMagnitude)]
+ let dn1: [Any] = [NSDecimalNumber(floatLiteral: Double.leastNonzeroMagnitude)]
+ let dn2: [Any] = [NSDecimalNumber(floatLiteral: -Double.leastNormalMagnitude)]
+ let dn3: [Any] = [NSDecimalNumber(floatLiteral: Double.leastNormalMagnitude)]
+ let dn4: [Any] = [NSDecimalNumber(floatLiteral: -Double.greatestFiniteMagnitude)]
+ let dn5: [Any] = [NSDecimalNumber(floatLiteral: Double.greatestFiniteMagnitude)]
+
+ XCTAssertEqual(try trySerialize(dn0), "[-0.00000000000000000000000000000000000000000000000000000000000000000004940656458412464128]")
+ XCTAssertEqual(try trySerialize(dn1), "[0.00000000000000000000000000000000000000000000000000000000000000000004940656458412464128]")
+ XCTAssertEqual(try trySerialize(dn2), "[-0.0000000000000000000000000000000000000000000000000002225073858507201792]")
+ XCTAssertEqual(try trySerialize(dn3), "[0.0000000000000000000000000000000000000000000000000002225073858507201792]")
+ XCTAssertEqual(try trySerialize(dn4), "[-17976931348623167488000000000000000000000000000000000]")
+ XCTAssertEqual(try trySerialize(dn5), "[17976931348623167488000000000000000000000000000000000]")
+ XCTAssertEqual(try trySerialize([NSDecimalNumber(string: "0.0001"), NSDecimalNumber(string: "0.00"), NSDecimalNumber(string: "-0.0")]), "[0.0001,0,0]")
+ XCTAssertEqual(try trySerialize([NSDecimalNumber(integerLiteral: Int(Int16.min)), NSDecimalNumber(integerLiteral: 0), NSDecimalNumber(integerLiteral: Int(Int16.max))]), "[-32768,0,32767]")
+ XCTAssertEqual(try trySerialize([NSDecimalNumber(booleanLiteral: true), NSDecimalNumber(booleanLiteral: false)]), "[1,0]")
+ }
+
func test_serialize_stringEscaping() {
var json = ["foo"]
XCTAssertEqual(try trySerialize(json), "[\"foo\"]")
diff --git a/TestFoundation/TestOperationQueue.swift b/TestFoundation/TestOperationQueue.swift
index f60f17b..02f95c4 100644
--- a/TestFoundation/TestOperationQueue.swift
+++ b/TestFoundation/TestOperationQueue.swift
@@ -175,12 +175,17 @@
override internal(set) var isExecuting: Bool {
get {
- return _executing
+ lock.lock()
+ let wasExecuting = _executing
+ lock.unlock()
+ return wasExecuting
}
set {
- if _executing != newValue {
+ if isExecuting != newValue {
willChangeValue(forKey: "isExecuting")
+ lock.lock()
_executing = newValue
+ lock.unlock()
didChangeValue(forKey: "isExecuting")
}
}
@@ -188,12 +193,17 @@
override internal(set) var isFinished: Bool {
get {
- return _finished
+ lock.lock()
+ let wasFinished = _finished
+ lock.unlock()
+ return wasFinished
}
set {
- if _finished != newValue {
+ if isFinished != newValue {
willChangeValue(forKey: "isFinished")
+ lock.lock()
_finished = newValue
+ lock.unlock()
didChangeValue(forKey: "isFinished")
}
}
@@ -213,10 +223,8 @@
queue.async {
sleep(1)
- self.lock.lock()
self.isExecuting = false
self.isFinished = true
- self.lock.unlock()
}
}
diff --git a/TestFoundation/TestProcess.swift b/TestFoundation/TestProcess.swift
index 163dc31..922c607 100644
--- a/TestFoundation/TestProcess.swift
+++ b/TestFoundation/TestProcess.swift
@@ -334,7 +334,7 @@
guard let range = line.range(of: "=") else {
throw Error.InvalidEnvironmentVariable(line)
}
- result[line.substring(to: range.lowerBound)] = line.substring(from: range.upperBound)
+ result[String(line[..<range.lowerBound])] = String(line[range.upperBound...])
}
return result
}
diff --git a/TestFoundation/TestURLSession.swift b/TestFoundation/TestURLSession.swift
index 68339fc..c941f1c 100644
--- a/TestFoundation/TestURLSession.swift
+++ b/TestFoundation/TestURLSession.swift
@@ -36,7 +36,7 @@
("test_verifyHttpAdditionalHeaders", test_verifyHttpAdditionalHeaders),
("test_timeoutInterval", test_timeoutInterval),
("test_httpRedirection", test_httpRedirection),
- ("test_httpRedirectionTimeout", test_httpRedirectionTimeout),
+ //("test_httpRedirectionTimeout", test_httpRedirectionTimeout), /* temporarily disabled (https://bugs.swift.org/browse/SR-5751) */
("test_http0_9SimpleResponses", test_http0_9SimpleResponses),
("test_outOfRangeButCorrectlyFormattedHTTPCode", test_outOfRangeButCorrectlyFormattedHTTPCode),
("test_missingContentLengthButStillABody", test_missingContentLengthButStillABody),
@@ -313,6 +313,8 @@
waitForExpectations(timeout: 12)
}
+ /*
+ // temporarily disabled (https://bugs.swift.org/browse/SR-5751)
func test_httpRedirectionTimeout() {
let urlString = "http://127.0.0.1:\(TestURLSession.serverPort)/UnitedStates"
var req = URLRequest(url: URL(string: urlString)!)
@@ -325,11 +327,14 @@
if let e = error as? URLError {
XCTAssertEqual(e.code, .timedOut, "Unexpected error code")
return
+ } else {
+ XCTFail("test unexpectedly succeeded (response=\(response.debugDescription))")
}
}
task.resume()
waitForExpectations(timeout: 12)
}
+ */
func test_http0_9SimpleResponses() {
for brokenCity in ["Pompeii", "Sodom"] {
diff --git a/TestFoundation/TestXMLParser.swift b/TestFoundation/TestXMLParser.swift
index 84e5782..b08f0b3 100644
--- a/TestFoundation/TestXMLParser.swift
+++ b/TestFoundation/TestXMLParser.swift
@@ -86,10 +86,10 @@
return xmlUnderTest
}
if let open = encoding.range(of: "(") {
- encoding = encoding.substring(from: open.upperBound)
+ encoding = String(encoding[open.upperBound...])
}
if let close = encoding.range(of: ")") {
- encoding = encoding.substring(to: close.lowerBound)
+ encoding = String(encoding[..<close.lowerBound])
}
return "<?xml version='1.0' encoding='\(encoding.uppercased())' standalone='no'?>\n\(xmlUnderTest)\n"
}