Use errors in parsing method

This commit is contained in:
Erik Little 2017-08-18 11:04:06 -04:00
parent 079c8e4e4c
commit afbf2cfc40
No known key found for this signature in database
GPG Key ID: 4930B7C5FBC1A69D
3 changed files with 96 additions and 98 deletions

View File

@ -153,14 +153,11 @@ class SocketBasicPacketTest: XCTestCase {
let socket = SocketIOClient(socketURL: URL(string: "http://localhost/")!) let socket = SocketIOClient(socketURL: URL(string: "http://localhost/")!)
socket.setTestable() socket.setTestable()
if case let .right(packet) = socket.parseString(engineString) { var packet = try! socket.parseString(engineString)
var packet = packet
XCTAssertEqual(packet.event, "test") XCTAssertEqual(packet.event, "test")
_ = packet.addData(data) _ = packet.addData(data)
_ = packet.addData(data2) _ = packet.addData(data2)
XCTAssertEqual(packet.args[0] as? String, "~~0") XCTAssertEqual(packet.args[0] as? String, "~~0")
} else {
XCTFail()
}
} }
} }

View File

@ -107,11 +107,11 @@ class SocketParserTest: XCTestCase {
func testInvalidInput() { func testInvalidInput() {
let message = "8" let message = "8"
switch testSocket.parseString(message) { do {
case .left(_): let _ = try testSocket.parseString(message)
return XCTFail()
case .right(_): } catch {
XCTFail("Created packet when shouldn't have")
} }
} }
@ -125,24 +125,21 @@ class SocketParserTest: XCTestCase {
func validateParseResult(_ message: String) { func validateParseResult(_ message: String) {
let validValues = SocketParserTest.packetTypes[message]! let validValues = SocketParserTest.packetTypes[message]!
let packet = testSocket.parseString(message) let packet = try! testSocket.parseString(message)
let type = String(message.characters.prefix(1)) let type = String(message.characters.prefix(1))
if case let .right(packet) = packet {
XCTAssertEqual(packet.type, SocketPacket.PacketType(rawValue: Int(type) ?? -1)!) XCTAssertEqual(packet.type, SocketPacket.PacketType(rawValue: Int(type) ?? -1)!)
XCTAssertEqual(packet.nsp, validValues.0) XCTAssertEqual(packet.nsp, validValues.0)
XCTAssertTrue((packet.data as NSArray).isEqual(to: validValues.1), "\(packet.data)") XCTAssertTrue((packet.data as NSArray).isEqual(to: validValues.1), "\(packet.data)")
XCTAssertTrue((packet.binary as NSArray).isEqual(to: validValues.2), "\(packet.binary)") XCTAssertTrue((packet.binary as NSArray).isEqual(to: validValues.2), "\(packet.binary)")
XCTAssertEqual(packet.id, validValues.3) XCTAssertEqual(packet.id, validValues.3)
} else {
XCTFail()
}
} }
func testParsePerformance() { func testParsePerformance() {
let keys = Array(SocketParserTest.packetTypes.keys) let keys = Array(SocketParserTest.packetTypes.keys)
measure { measure {
for item in keys.enumerated() { for item in keys.enumerated() {
_ = self.testSocket.parseString(item.element) _ = try! self.testSocket.parseString(item.element)
} }
} }
} }

View File

@ -27,6 +27,12 @@ protocol SocketParsable {
func parseSocketMessage(_ message: String) func parseSocketMessage(_ message: String)
} }
enum SocketParsableError : Error {
case invalidDataArray
case invalidPacket
case invalidPacketType
}
extension SocketParsable where Self: SocketIOClientSpec { extension SocketParsable where Self: SocketIOClientSpec {
private func isCorrectNamespace(_ nsp: String) -> Bool { private func isCorrectNamespace(_ nsp: String) -> Bool {
return nsp == self.nsp return nsp == self.nsp
@ -62,15 +68,15 @@ extension SocketParsable where Self: SocketIOClientSpec {
} }
/// Parses a messsage from the engine. Returning either a string error or a complete SocketPacket /// Parses a messsage from the engine. Returning either a string error or a complete SocketPacket
func parseString(_ message: String) -> Either<String, SocketPacket> { func parseString(_ message: String) throws -> SocketPacket {
var reader = SocketStringReader(message: message) var reader = SocketStringReader(message: message)
guard let type = Int(reader.read(count: 1)).flatMap({ SocketPacket.PacketType(rawValue: $0) }) else { guard let type = Int(reader.read(count: 1)).flatMap({ SocketPacket.PacketType(rawValue: $0) }) else {
return .left("Invalid packet type") throw SocketParsableError.invalidPacketType
} }
if !reader.hasNext { if !reader.hasNext {
return .right(SocketPacket(type: type, nsp: "/")) return SocketPacket(type: type, nsp: "/")
} }
var namespace = "/" var namespace = "/"
@ -80,7 +86,7 @@ extension SocketParsable where Self: SocketIOClientSpec {
if let holders = Int(reader.readUntilOccurence(of: "-")) { if let holders = Int(reader.readUntilOccurence(of: "-")) {
placeholders = holders placeholders = holders
} else { } else {
return .left("Invalid packet") throw SocketParsableError.invalidPacket
} }
} }
@ -89,7 +95,7 @@ extension SocketParsable where Self: SocketIOClientSpec {
} }
if !reader.hasNext { if !reader.hasNext {
return .right(SocketPacket(type: type, nsp: namespace, placeholders: placeholders)) return SocketPacket(type: type, nsp: namespace, placeholders: placeholders)
} }
var idString = "" var idString = ""
@ -113,21 +119,17 @@ extension SocketParsable where Self: SocketIOClientSpec {
dataArray = "[" + dataArray + "]" dataArray = "[" + dataArray + "]"
} }
switch parseData(dataArray) { let data = try parseData(dataArray)
case let .left(err):
return .left(err) return SocketPacket(type: type, data: data, id: Int(idString) ?? -1, nsp: namespace, placeholders: placeholders)
case let .right(data):
return .right(SocketPacket(type: type, data: data, id: Int(idString) ?? -1,
nsp: namespace, placeholders: placeholders))
}
} }
// Parses data for events // Parses data for events
private func parseData(_ data: String) -> Either<String, [Any]> { private func parseData(_ data: String) throws -> [Any] {
do { do {
return .right(try data.toArray()) return try data.toArray()
} catch { } catch {
return .left("Error parsing data for packet") throw SocketParsableError.invalidDataArray
} }
} }
@ -137,12 +139,14 @@ extension SocketParsable where Self: SocketIOClientSpec {
DefaultSocketLogger.Logger.log("Parsing %@", type: "SocketParser", args: message) DefaultSocketLogger.Logger.log("Parsing %@", type: "SocketParser", args: message)
switch parseString(message) { do {
case let .left(err): let packet = try parseString(message)
DefaultSocketLogger.Logger.error("\(err): %@", type: "SocketParser", args: message)
case let .right(pack): DefaultSocketLogger.Logger.log("Decoded packet as: %@", type: "SocketParser", args: packet.description)
DefaultSocketLogger.Logger.log("Decoded packet as: %@", type: "SocketParser", args: pack.description)
handlePacket(pack) handlePacket(packet)
} catch {
DefaultSocketLogger.Logger.error("\(error): %@", type: "SocketParser", args: message)
} }
} }