Viewing is open to everyone. Downloading and starring need a GitHub sign-in. Sign in with GitHub

CKeyScanKitTests.swift

v0.1.0-build.85 Latest Commit ede38f5

Size
5.4 KB
Lines
108
Language
swift
SHA-256
e1bbcc6f6441…
View on GitHub

Sign in with GitHub to download. Each download is recorded with your GitHub username.

1import CKeyScanKit
2import CoreGraphics
3import CoreVideo
4import XCTest
5
6/// The scan-only product: no renderer and no telemetry are linked here.
7final class CKeyPayloadTests: XCTestCase {
8 func testTextDetection() {
9 XCTAssertEqual(CKeyPayload.text(from: Data("hello\r\nworld\t!".utf8)), "hello\r\nworld\t!")
10 XCTAssertNil(CKeyPayload.text(from: Data([0xff, 0xfe])), "invalid UTF-8")
11 XCTAssertNil(CKeyPayload.text(from: Data([0x41, 0x00, 0x42])), "NUL is a control character")
12 XCTAssertNil(CKeyPayload.text(from: Data([0x41, 0x1b])), "ESC is a control character")
13 XCTAssertNil(CKeyPayload.text(from: Data()))
14 XCTAssertEqual(CKeyPayload.hex(Data([0x00, 0xab, 0x10])), "00ab10")
15 }
16
17 func testAllowlistedForms() {
18 XCTAssertEqual(CKeyPayload.classify(" https://citeory.com/tour \n"), .web(URL(string: "https://citeory.com/tour")!))
19 XCTAssertEqual(CKeyPayload.classify("HTTP://example.com"), .web(URL(string: "HTTP://example.com")!))
20 XCTAssertEqual(CKeyPayload.classify("mailto:hello@citeory.com?subject=Hi"),
21 .email(URL(string: "mailto:hello@citeory.com?subject=Hi")!, address: "hello@citeory.com"))
22 XCTAssertEqual(CKeyPayload.classify("tel:+1 (555) 123-4567"),
23 .call(URL(string: "tel:+15551234567")!, number: "+15551234567"))
24 if case .message(_, let number)? = CKeyPayload.classify("sms:+15551234567?body=Hi") {
25 XCTAssertEqual(number, "+15551234567")
26 } else {
27 XCTFail("sms")
28 }
29 if case .geo(let lat, let lon, let label, let url)? = CKeyPayload.classify("geo:37.33490,-122.00900?q=Apple%20Park") {
30 XCTAssertEqual(lat, 37.3349, accuracy: 1e-9)
31 XCTAssertEqual(lon, -122.009, accuracy: 1e-9)
32 XCTAssertEqual(label, "Apple Park")
33 XCTAssertEqual(url.host, "maps.apple.com")
34 } else {
35 XCTFail("geo")
36 }
37 if case .address(let address, let url)? = CKeyPayload.classify("address:1 Infinite Loop\n\nCupertino, CA 95014") {
38 XCTAssertEqual(address, "1 Infinite Loop, Cupertino, CA 95014")
39 XCTAssertTrue(url.absoluteString.contains("address="))
40 } else {
41 XCTFail("address")
42 }
43 let card = "BEGIN:VCARD\r\nVERSION:3.0\r\nFN:Ada Lovelace\r\nEND:VCARD"
44 XCTAssertEqual(CKeyPayload.classify(card), .contact(vCard: card, name: "Ada Lovelace"))
45 }
46
47 func testRejectedForms() {
48 for text in ["javascript:alert(1)", "data:text/html,hi", "file:///etc/passwd", "intent://x",
49 "myapp://open", "mailto:nobody", "tel:12", "sms:", "geo:91,0", "geo:0,181", "geo:abc",
50 "address: \n ", "https://", "plain words", "BEGIN:VCARD\nFN:x"] {
51 XCTAssertNil(CKeyPayload.classify(text), text)
52 }
53 }
54}
55
56final class CKeyDecoderTests: XCTestCase {
57 func testBlankFramesDoNotDecode() throws {
58 let white = [UInt8](repeating: 255, count: 320 * 240)
59 white.withUnsafeBufferPointer { buffer in
60 XCTAssertNil(CKeyDecoder.decode(gray: buffer.baseAddress!, width: 320, height: 240, stride: 320))
61 }
62 var pixelBuffer: CVPixelBuffer?
63 XCTAssertEqual(CVPixelBufferCreate(nil, 64, 64, kCVPixelFormatType_OneComponent8, nil, &pixelBuffer),
64 kCVReturnSuccess)
65 XCTAssertNil(CKeyDecoder.decode(pixelBuffer: try XCTUnwrap(pixelBuffer)))
66 }
67
68 func testInvalidGeometryIsRejected() {
69 let gray = [UInt8](repeating: 0, count: 16)
70 gray.withUnsafeBufferPointer { buffer in
71 XCTAssertNil(CKeyDecoder.decode(gray: buffer.baseAddress!, width: 4, height: 4, stride: 2))
72 }
73 }
74
75 func testResultMetadata() {
76 let result = CKeyResult(bytes: Data("hi".utf8), profile: .scalable, version: 3, layout: .print)
77 XCTAssertEqual(result.text, "hi")
78 XCTAssertEqual(result.telemetryProfileCode, 1)
79 XCTAssertEqual(result.profileDescription, "Profile 0.1 · print · v3")
80 XCTAssertEqual(CKeyResult(bytes: Data(count: 16), profile: .locator).telemetryProfileCode, 2)
81 XCTAssertFalse(CKeyCoreInfo.softwareVersion.isEmpty)
82 XCTAssertGreaterThanOrEqual(CKeyCoreInfo.abiVersion, 4)
83 }
84}
85
86final class CKeyPayloadEdgeCaseTests: XCTestCase {
87 func testPhoneParametersAreNeverDialled() {
88 guard case .call(let url, let number)? = CKeyPayload.classify("tel:+15550100;ext=7") else { return XCTFail("tel") }
89 XCTAssertEqual(number, "+15550100")
90 XCTAssertEqual(url.absoluteString, "tel:+15550100")
91 guard case .message(_, let sms)? = CKeyPayload.classify("sms:+15550100?body=Hi") else { return XCTFail("sms") }
92 XCTAssertEqual(sms, "+15550100")
93 }
94
95 func testFormatCharactersAreText() {
96 // Family emoji (ZWJ sequence), a soft hyphen and a BOM are text, not binary.
97 let text = "👨‍👩‍👧 co\u{00AD}operate \u{FEFF}hello"
98 XCTAssertEqual(CKeyPayload.text(from: Data(text.utf8)), text)
99 XCTAssertNil(CKeyPayload.text(from: Data([0x41, 0x07, 0x42]))) // BEL is a control character
100 XCTAssertNil(CKeyPayload.text(from: Data("a\u{0085}b".utf8))) // C1 control
101 }
102
103 func testVCardMustBeComplete() {
104 XCTAssertNotNil(CKeyPayload.classify("BEGIN:VCARD\nVERSION:4.0\nFN:Ada\nEND:VCARD"))
105 XCTAssertNil(CKeyPayload.classify("BEGIN:VCARD\nFN:Ada\nEND:VCARD trailing words"))
106 XCTAssertNil(CKeyPayload.classify("BEGIN:VCARDS and more END:VCARD"))
107 }
108}