Skip to content

Commit de0d998

Browse files
committed
added execution test of async actor prop accesses
1 parent e4076b6 commit de0d998

File tree

1 file changed

+173
-0
lines changed

1 file changed

+173
-0
lines changed
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
// RUN: %target-run-simple-swift(-parse-as-library -Xfrontend -enable-experimental-concurrency %import-libdispatch) | %FileCheck %s
2+
3+
// REQUIRES: executable_test
4+
// REQUIRES: concurrency
5+
// REQUIRES: libdispatch
6+
7+
@propertyWrapper
8+
struct SuccessTracker {
9+
private var _stored: Bool
10+
private var numReads : Int = 0 // an unchecked statistic to exercise mutating get
11+
init(initially: Bool) {
12+
self._stored = initially
13+
}
14+
15+
var wrappedValue: Bool {
16+
mutating get {
17+
numReads += 1
18+
return _stored
19+
}
20+
set { _stored = newValue }
21+
}
22+
}
23+
24+
func writeToBool(_ b : inout Bool, _ val : Bool) {
25+
b = val
26+
}
27+
28+
actor List<T : ConcurrentValue> {
29+
var head : T
30+
var tail : List<T>?
31+
32+
lazy var hasTail : Bool = (tail != nil)
33+
34+
var computedTail : List<T>? {
35+
get { tail }
36+
}
37+
38+
subscript(_ offset : Int) -> T? {
39+
// since we don't have async subscripts, we just return nil for non-zero inputs! :)
40+
if offset != 0 {
41+
return nil
42+
}
43+
44+
return head
45+
}
46+
47+
/// this silly property is here just for testing wrapped-property access
48+
@SuccessTracker(initially: true) var success : Bool
49+
func setSuccess(_ b : Bool) { writeToBool(&success, b) }
50+
51+
init(_ value : T) {
52+
self.head = value
53+
self.tail = nil
54+
}
55+
56+
init(_ value : T, _ tail : List<T>) {
57+
self.head = value
58+
self.tail = tail
59+
}
60+
61+
func last() async -> T {
62+
switch tail {
63+
case .none:
64+
return head
65+
case .some(let tl):
66+
if await tl.hasTail {
67+
return await tl.last()
68+
}
69+
return await tl.head
70+
}
71+
}
72+
73+
static func tabulate(_ n : Int, _ f : (Int) -> T) -> List<T> {
74+
if n == 0 {
75+
return List<T>(f(n))
76+
}
77+
return List<T>(f(n), tabulate(n-1, f))
78+
}
79+
80+
static func foldr<R>(_ f : (T, R) -> R, _ start : R, _ lst : List<T>) async -> R {
81+
switch await lst.tail {
82+
case .none:
83+
return f(await lst.head, start)
84+
case .some(let tl):
85+
return f(await lst.head, await foldr(f, start, tl))
86+
}
87+
}
88+
}
89+
90+
91+
actor Tester {
92+
/// returns true iff success
93+
func doListTest() async -> Bool {
94+
let n = 4 // if you change this, you'll have to update other stuff too
95+
96+
let ints = List<Int>.tabulate(n, { $0 })
97+
98+
let last1 = await ints.tail!.computedTail!.tail!.tail![0]
99+
let last2 = await ints.last()
100+
101+
guard last1 == last2 else {
102+
print("fail 1")
103+
return false
104+
}
105+
106+
107+
let expected = (n * (n + 1)) / 2
108+
let sum = await List<Int>.foldr({ $0 + $1 }, 0, ints)
109+
110+
guard sum == expected else {
111+
print("fail 2")
112+
return false
113+
}
114+
115+
// CHECK: done list test
116+
// CHECK-NOT: fail
117+
print("done list test")
118+
return true
119+
}
120+
121+
func doPropertyWrapperTest() async -> Bool {
122+
let actor = List<String>("blah")
123+
124+
await actor.setSuccess(false)
125+
guard await actor.success == false else {
126+
print("fail 3")
127+
return false
128+
}
129+
130+
await actor.setSuccess(true)
131+
guard await actor.success == true else {
132+
print("fail 4")
133+
return false
134+
}
135+
136+
// CHECK: done property wrapper test
137+
// CHECK-NOT: fail
138+
print("done property wrapper test")
139+
return true
140+
}
141+
}
142+
143+
@globalActor
144+
struct SillyActor {
145+
actor _Impl {}
146+
static let shared = _Impl()
147+
}
148+
149+
@SillyActor
150+
var test : Tester = Tester()
151+
152+
@SillyActor
153+
var expectedResult : Bool {
154+
get { true }
155+
set {}
156+
}
157+
158+
@main struct RunIt {
159+
static func main() async {
160+
let success = await expectedResult
161+
162+
guard await test.doListTest() == success else {
163+
fatalError("fail list test")
164+
}
165+
166+
guard await test.doPropertyWrapperTest() == success else {
167+
fatalError("fail property wrapper test")
168+
}
169+
170+
// CHECK: done all testing
171+
print("done all testing")
172+
}
173+
}

0 commit comments

Comments
 (0)