Fix #667 Make no ack an enum case

This commit is contained in:
Erik 2017-05-05 22:35:39 -04:00
parent 58f51d07a2
commit 23c76417d2
No known key found for this signature in database
GPG Key ID: 4930B7C5FBC1A69D
2 changed files with 41 additions and 11 deletions

View File

@ -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)
}
}

View File

@ -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<SocketAck>(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])
}
}
}