|
import Foundation |
|
|
|
struct DeviceToken { |
|
enum Failure: Error { |
|
case invalidHexString |
|
} |
|
var data: Data |
|
var hexString: String { |
|
let result = data.map { String(format: "%02x", $0) }.joined().uppercased() |
|
return result |
|
} |
|
|
|
init(data: Data) { |
|
self.data = data |
|
} |
|
|
|
init(hexString: String) throws { |
|
if hexString.count % 2 != 0 { |
|
throw Failure.invalidHexString |
|
} |
|
let length = 2 |
|
let end = hexString.count/length |
|
let range = 0..<end |
|
let transformHex: (Int) -> String = { |
|
String(hexString.dropFirst($0 * length).prefix(length)) |
|
} |
|
let transformByte: (String) throws -> UInt8 = { |
|
guard let value = UInt8($0, radix: 16) else { |
|
throw Failure.invalidHexString |
|
} |
|
return value |
|
} |
|
let bytes = try range.map(transformHex).map(transformByte) |
|
let data = Data(bytes) |
|
self.data = data |
|
} |
|
} |
|
|
|
/** TESTING **/ |
|
|
|
import XCTest |
|
|
|
public class TestObserver: NSObject, XCTestObservation { |
|
|
|
public static func observe() { |
|
let observer = TestObserver() |
|
XCTestObservationCenter.shared.addTestObserver(observer) |
|
} |
|
|
|
public func testCase(_ testCase: XCTestCase, didFailWithDescription description: String, inFile filePath: String?, atLine lineNumber: Int) { |
|
print("🚫 \(description) line:\(lineNumber)") |
|
} |
|
|
|
public func testCaseDidFinish(_ testCase: XCTestCase) { |
|
if testCase.testRun?.hasSucceeded == true { |
|
print("✅ \(testCase)") |
|
} |
|
} |
|
|
|
} |
|
|
|
class DeviceTokenTests : XCTestCase { |
|
|
|
func testEmptyHexString() { |
|
guard let deviceToken = try? DeviceToken(hexString: "") else { |
|
XCTFail() |
|
return |
|
} |
|
XCTAssertEqual(deviceToken.hexString, "") |
|
XCTAssertEqual(Array(deviceToken.data), []) |
|
} |
|
|
|
func testMaxHexString() { |
|
guard let deviceToken = try? DeviceToken(hexString: "FF") else { |
|
XCTFail() |
|
return |
|
} |
|
XCTAssertEqual(deviceToken.hexString, "FF") |
|
XCTAssertEqual(Array(deviceToken.data), [255]) |
|
} |
|
|
|
func testVariousHexStringValues() { |
|
guard let deviceToken = try? DeviceToken(hexString: "FF0110") else { |
|
XCTFail() |
|
return |
|
} |
|
XCTAssertEqual(deviceToken.hexString, "FF0110") |
|
XCTAssertEqual(Array(deviceToken.data), [255, 1, 16]) |
|
} |
|
|
|
func testEmptyData() { |
|
let deviceToken = DeviceToken(data: Data([])) |
|
XCTAssertEqual(deviceToken.hexString, "") |
|
XCTAssertEqual(Array(deviceToken.data), []) |
|
} |
|
|
|
func testMaxData() { |
|
let deviceToken = DeviceToken(data: Data([255])) |
|
XCTAssertEqual(deviceToken.hexString, "FF") |
|
XCTAssertEqual(Array(deviceToken.data), [255]) |
|
} |
|
|
|
func testVariousDataValues() { |
|
let deviceToken = DeviceToken(data: Data([255, 1, 16])) |
|
XCTAssertEqual(deviceToken.hexString, "FF0110") |
|
XCTAssertEqual(Array(deviceToken.data), [255, 1, 16]) |
|
} |
|
|
|
func testInvalidHexStringValues() { |
|
XCTAssertThrowsError(try DeviceToken(hexString: "FF1")) |
|
XCTAssertThrowsError(try DeviceToken(hexString: "FF0g")) |
|
} |
|
} |
|
|
|
TestObserver.observe() |
|
DeviceTokenTests.defaultTestSuite.run() |