Skip to content

Commit 2e0c0fe

Browse files
committed
[test] OutputRawSpan tests
1 parent 51eebe1 commit 2e0c0fe

File tree

1 file changed

+155
-0
lines changed

1 file changed

+155
-0
lines changed
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
//===--- OutputRawSpanTests.swift -----------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2025 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
// RUN: %target-run-stdlib-swift
14+
15+
// REQUIRES: executable_test
16+
17+
import StdlibUnittest
18+
19+
var suite = TestSuite("OutputRawSpan Tests")
20+
defer { runAllTests() }
21+
22+
@available(SwiftStdlib 6.2, *)
23+
struct Allocation: ~Copyable {
24+
let allocation: UnsafeMutableRawBufferPointer
25+
var byteCount: Int? = nil
26+
27+
init(byteCount: Int = 1) {
28+
precondition(byteCount >= 0)
29+
allocation = .allocate(byteCount: byteCount, alignment: 16)
30+
}
31+
32+
var isEmpty: Bool { (byteCount ?? 0) == 0 }
33+
34+
mutating func initialize<E>(
35+
_ body: (inout OutputRawSpan) throws(E) -> Void
36+
) throws(E) {
37+
if byteCount != nil { fatalError() }
38+
var outputBuffer = OutputRawSpan(buffer: allocation, initializedCount: 0)
39+
do {
40+
try body(&outputBuffer)
41+
let initialized = outputBuffer.finalize(for: allocation)
42+
byteCount = initialized
43+
}
44+
catch {
45+
outputBuffer.removeAll()
46+
let initialized = outputBuffer.finalize(for: allocation)
47+
assert(initialized == 0)
48+
throw error
49+
}
50+
}
51+
52+
borrowing func withSpan<E, R: ~Copyable>(
53+
_ body: (borrowing RawSpan) throws(E) -> R
54+
) throws(E) -> R {
55+
try body(RawSpan(_unsafeBytes: allocation[0..<(byteCount ?? 0)]))
56+
}
57+
58+
deinit {
59+
allocation.deallocate()
60+
}
61+
}
62+
63+
enum MyTestError: Error { case error }
64+
65+
suite.test("Create OutputRawSpan")
66+
.require(.stdlib_6_2).code {
67+
guard #available(SwiftStdlib 6.2, *) else { return }
68+
69+
let c = 48
70+
let allocation = UnsafeMutableRawBufferPointer.allocate(byteCount: c, alignment: 16)
71+
defer { allocation.deallocate() }
72+
73+
let ob = unsafe OutputRawSpan(buffer: allocation, initializedCount: 0)
74+
let initialized = ob.finalize(for: allocation)
75+
expectEqual(initialized, 0)
76+
}
77+
78+
suite.test("deinit without relinquishing memory")
79+
.require(.stdlib_6_2).code {
80+
guard #available(SwiftStdlib 6.2, *) else { return }
81+
82+
let c = 48
83+
let allocation = UnsafeMutableRawBufferPointer.allocate(byteCount: c, alignment: 16)
84+
defer { allocation.deallocate() }
85+
86+
var ob = unsafe OutputRawSpan(buffer: allocation, initializedCount: 0)
87+
// OutputRawSpan(buffer: Slice(base: allocation, bounds: 0..<c))
88+
ob.append(repeating: 65, count: 12, as: UInt8.self)
89+
expectEqual(ob.byteCount, 12)
90+
_ = ob
91+
}
92+
93+
suite.test("append single elements")
94+
.require(.stdlib_6_2).code {
95+
guard #available(SwiftStdlib 6.2, *) else { return }
96+
97+
var a = Allocation(byteCount: 48)
98+
let c = 10
99+
a.initialize {
100+
for i in 0...c {
101+
$0.append(UInt8(i))
102+
}
103+
let oops = $0.removeLast()
104+
expectEqual(Int(oops), c)
105+
}
106+
expectNotNil(a.byteCount)
107+
expectEqual(a.byteCount, c)
108+
a.withSpan {
109+
expectEqual($0.byteCount, c)
110+
for o in $0.byteOffsets {
111+
expectEqual(Int($0.unsafeLoad(fromByteOffset: o, as: UInt8.self)), o)
112+
}
113+
}
114+
}
115+
116+
suite.test("initialize buffer with repeated elements")
117+
.require(.stdlib_6_2).code {
118+
guard #available(SwiftStdlib 6.2, *) else { return }
119+
120+
var a = Allocation(byteCount: 48)
121+
let c = UInt8(10)
122+
a.initialize {
123+
$0.append(repeating: c, count: Int(c), as: UInt8.self)
124+
let oops = $0.removeLast()
125+
expectEqual(oops, c)
126+
expectEqual($0.byteCount, Int(c-1))
127+
}
128+
a.withSpan {
129+
expectEqual($0.byteCount, Int(c-1))
130+
for o in $0.byteOffsets {
131+
expectEqual($0.unsafeLoad(fromByteOffset: o, as: UInt8.self), c)
132+
}
133+
}
134+
}
135+
136+
suite.test("deinitialize buffer")
137+
.require(.stdlib_6_2).code {
138+
guard #available(SwiftStdlib 6.2, *) else { return }
139+
140+
var a = Allocation(byteCount: 48)
141+
do {
142+
try a.initialize {
143+
$0.append(0)
144+
$0.append(1)
145+
expectTrue($0.byteCount > 0)
146+
throw MyTestError.error
147+
}
148+
}
149+
catch MyTestError.error {
150+
expectEqual(a.isEmpty, true)
151+
}
152+
catch {
153+
expectTrue(false)
154+
}
155+
}

0 commit comments

Comments
 (0)