A fast, safe, and efficient CBOR serialization library for Swift on any platform.
swiftpackageindex.com/thecoolwinter/CBOR/1.1.1/documentation/cbor
atproto
swift
cbor
1//
2// ScannerTests.swift
3// CBOR
4//
5// Created by Khan Winter on 8/24/25.
6//
7
8#if canImport(FoundationEssentials)
9import FoundationEssentials
10#else
11import Foundation
12#endif
13import Testing
14@testable import CBOR
15
16@Suite
17struct ScannerTests {
18 @Test(arguments: [(24, 1), (25, 2), (26, 4), (27, 8)])
19 func int(argument: UInt8, byteCount: Int) throws {
20 let data = Data([argument] + Array(repeating: UInt8.zero, count: byteCount))
21 try data.withUnsafeBytes {
22 let data = $0[...]
23
24 let scanner = CBORScanner(data: DataReader(data: data))
25 let results = try scanner.scan()
26 let map = results.contents()
27 #expect(map == [Int(MajorType.uint.bits | argument), 1, byteCount])
28
29 #expect(results.load(at: 0).type == .uint)
30 #expect(results.load(at: 0).argument == argument)
31 #expect(results.load(at: 0).count == byteCount)
32 }
33 }
34
35 @Test(arguments: [(24, 1), (25, 2), (26, 4), (27, 8)])
36 func intInvalidSize(argument: UInt8, maxSize: Int) {
37 for count in 0..<maxSize {
38 let data = Array(repeating: UInt8.zero, count: count)
39 Data([argument] + data).withUnsafeBytes {
40 let data = $0[...]
41 #expect(throws: ScanError.self) {
42 try CBORScanner(data: DataReader(data: data)).scan()
43 }
44 }
45 }
46 }
47
48 @Test(arguments: [(24, 1), (25, 2), (26, 4), (27, 8)])
49 func nint(argument: UInt8, byteCount: Int) throws {
50 let data = Data([MajorType.nint.bits | argument] + Array(repeating: UInt8.zero, count: byteCount))
51 try data.withUnsafeBytes {
52 let data = $0[...]
53 let scanner = CBORScanner(data: DataReader(data: data))
54 let results = try scanner.scan()
55 let map = results.contents()
56 #expect(map == [Int(MajorType.nint.bits | argument), 1, byteCount])
57 }
58 }
59
60 @Test(arguments: [(24, 1), (25, 2), (26, 4), (27, 8)])
61 func nintInvalidSize(argument: UInt8, maxSize: Int) {
62 for count in 0..<maxSize {
63 let data = Data([MajorType.nint.bits | argument] + Array(repeating: UInt8.zero, count: count))
64 data.withUnsafeBytes {
65 let data = $0[...]
66 #expect(throws: ScanError.self) {
67 try CBORScanner(data: DataReader(data: data)).scan()
68 }
69 }
70 }
71 }
72
73 @Test(arguments: [
74 ("BFFF", [MajorType.map.intValue, 0, 0, 0, 2]), // Empty, indeterminate map
75 ( // Nested, empty, indeterminate map: { "": {} }
76 "BF60BFFFFF",
77 [MajorType.map.intValue, 2, 8, 0, 5, MajorType.string.intValue, 2, 0, MajorType.map.intValue, 0, 0, 2, 2]
78 )
79 ])
80 func indeterminateMap(data: String, expectedMap: [Int]) throws {
81 let data = data.asHexData()
82 try data.withUnsafeBytes {
83 let data = $0[...]
84 let options = DecodingOptions(rejectIndeterminateLengths: false)
85 let scanner = CBORScanner(data: DataReader(data: data), options: options)
86 let results = try scanner.scan()
87 let map = results.contents()
88 #expect(map == expectedMap)
89 }
90 }
91
92 @Test(arguments: [
93 ("A0", [MajorType.map.intValue, 0, 0, 1, 0]), // Empty map
94 ( // { "": 1, "": 2 }
95 "A260016002",
96 [
97 MajorType.map.intValue, 4, 12, 1, 4,
98 MajorType.string.intValue, 2, 0,
99 (MajorType.uint.intValue | 1), 3, 0,
100 MajorType.string.intValue, 4, 0,
101 (MajorType.uint.intValue | 2), 5, 0]
102 )
103 ])
104 func map(data: String, expectedMap: [Int]) throws {
105 let data = data.asHexData()
106 try data.withUnsafeBytes {
107 let data = $0[...]
108 let scanner = CBORScanner(data: DataReader(data: data))
109 let results = try scanner.scan()
110 let map = results.contents()
111 #expect(map == expectedMap)
112 }
113 }
114
115 @Test
116 func indeterminateNestedArray() throws {
117 let expectedMap = [128, 2, 22, 0, 10, 128, 2, 6, 1, 4, 2, 3, 0, 3, 4, 0, 128, 2, 6, 5, 4, 4, 7, 0, 5, 8, 0]
118 let data = "9F9F0203FF9F0405FFFF".asHexData()
119 try data.withUnsafeBytes {
120 let data = $0[...]
121 let options = DecodingOptions(rejectIndeterminateLengths: false)
122 let scanner = CBORScanner(data: DataReader(data: data), options: options)
123 let results = try scanner.scan()
124 let map = results.contents()
125 #expect(map == expectedMap)
126 }
127 }
128}