From 23c76417d206b865e13b3e76297b9cf308d521f2 Mon Sep 17 00:00:00 2001 From: Erik Date: Fri, 5 May 2017 22:35:39 -0400 Subject: [PATCH] Fix #667 Make no ack an enum case --- SocketIO-MacTests/SocketAckManagerTest.swift | 31 ++++++++++++++++++-- Source/SocketAckManager.swift | 21 ++++++++----- 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/SocketIO-MacTests/SocketAckManagerTest.swift b/SocketIO-MacTests/SocketAckManagerTest.swift index 764ad34..455c5b9 100644 --- a/SocketIO-MacTests/SocketAckManagerTest.swift +++ b/SocketIO-MacTests/SocketAckManagerTest.swift @@ -9,18 +9,43 @@ import XCTest @testable import SocketIO -class SocketAckManagerTest: XCTestCase { +class SocketAckManagerTest : XCTestCase { var ackManager = SocketAckManager() func testAddAcks() { - let callbackExpection = self.expectation(description: "callbackExpection") + let callbackExpection = expectation(description: "callbackExpection") let itemsArray = ["Hi", "ho"] + func callback(_ items: [Any]) { callbackExpection.fulfill() } + ackManager.addAck(1, callback: callback) ackManager.executeAck(1, with: itemsArray, onQueue: DispatchQueue.main) - + waitForExpectations(timeout: 3.0, handler: nil) } + + func testManagerTimeoutAck() { + let callbackExpection = expectation(description: "Manager should timeout ack with noAck status") + let itemsArray = ["Hi", "ho"] + + func callback(_ items: [Any]) { + XCTAssertEqual(items.count, 1, "Timed out ack should have one value") + guard let timeoutReason = items[0] as? String else { + XCTFail("Timeout reason should be a string") + + return + } + + XCTAssertEqual(timeoutReason, SocketAckStatus.noAck.rawValue) + + callbackExpection.fulfill() + } + + ackManager.addAck(1, callback: callback) + ackManager.timeoutAck(1, onQueue: DispatchQueue.main) + + waitForExpectations(timeout: 0.2, handler: nil) + } } diff --git a/Source/SocketAckManager.swift b/Source/SocketAckManager.swift index eea183b..b5d4cdc 100644 --- a/Source/SocketAckManager.swift +++ b/Source/SocketAckManager.swift @@ -22,19 +22,24 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +import Dispatch import Foundation +public enum SocketAckStatus : String { + case noAck = "NO ACK" +} + private struct SocketAck : Hashable { let ack: Int var callback: AckCallback! var hashValue: Int { return ack.hashValue } - + init(ack: Int) { self.ack = ack } - + init(ack: Int, callback: @escaping AckCallback) { self.ack = ack self.callback = callback @@ -52,28 +57,28 @@ private func ==(lhs: SocketAck, rhs: SocketAck) -> Bool { struct SocketAckManager { private var acks = Set(minimumCapacity: 1) private let ackSemaphore = DispatchSemaphore(value: 1) - + mutating func addAck(_ ack: Int, callback: @escaping AckCallback) { acks.insert(SocketAck(ack: ack, callback: callback)) } - + /// Should be called on handle queue mutating func executeAck(_ ack: Int, with items: [Any], onQueue: DispatchQueue) { ackSemaphore.wait() defer { ackSemaphore.signal() } let ack = acks.remove(SocketAck(ack: ack)) - + onQueue.async() { ack?.callback(items) } } - + /// Should be called on handle queue mutating func timeoutAck(_ ack: Int, onQueue: DispatchQueue) { ackSemaphore.wait() defer { ackSemaphore.signal() } let ack = acks.remove(SocketAck(ack: ack)) - + onQueue.async() { - ack?.callback?(["NO ACK"]) + ack?.callback?([SocketAckStatus.noAck.rawValue]) } } }