Skip to content

Commit d318e4d

Browse files
committed
reorganize tests
1 parent e3731dc commit d318e4d

File tree

3 files changed

+365
-328
lines changed

3 files changed

+365
-328
lines changed
Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
//===----------------------------------------------------------------------===//
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+
import Testing
13+
14+
#if FOUNDATION_FRAMEWORK
15+
@testable import Foundation
16+
#else
17+
@testable import FoundationEssentials
18+
#endif // FOUNDATION_FRAMEWORK
19+
20+
/// Unit tests for propagation of type-safe metadata in ProgressManager tree.
21+
#if FOUNDATION_FRAMEWORK
22+
/// Unit tests for interop methods that support building Progress trees with both Progress and ProgressManager
23+
@Suite("Progress Manager Interop") struct ProgressManagerInteropTests {
24+
func doSomethingWithProgress() async -> Progress {
25+
let p = Progress(totalUnitCount: 2)
26+
return p
27+
}
28+
29+
func doSomethingWithReporter(subprogress: consuming Subprogress?) async {
30+
let manager = subprogress?.start(totalCount: 4)
31+
manager?.complete(count: 2)
32+
manager?.complete(count: 2)
33+
}
34+
35+
@Test func interopProgressParentProgressManagerChild() async throws {
36+
// Initialize a Progress Parent
37+
let overall = Progress.discreteProgress(totalUnitCount: 10)
38+
39+
// Add Progress as Child
40+
let p1 = await doSomethingWithProgress()
41+
overall.addChild(p1, withPendingUnitCount: 5)
42+
43+
let _ = await Task.detached {
44+
p1.completedUnitCount = 1
45+
try? await Task.sleep(nanoseconds: 10000)
46+
p1.completedUnitCount = 2
47+
}.value
48+
49+
// Check if ProgressManager values propagate to Progress parent
50+
#expect(overall.fractionCompleted == 0.5)
51+
#expect(overall.completedUnitCount == 5)
52+
53+
// Add ProgressManager as Child
54+
let p2 = overall.makeChild(withPendingUnitCount: 5)
55+
await doSomethingWithReporter(subprogress: p2)
56+
57+
// Check if Progress values propagate to Progress parent
58+
#expect(overall.fractionCompleted == 1.0)
59+
#expect(overall.completedUnitCount == 10)
60+
}
61+
62+
@Test func interopProgressParentProgressReporterChildWithEmptyProgress() async throws {
63+
// Initialize a Progress parent
64+
let overall = Progress.discreteProgress(totalUnitCount: 10)
65+
66+
// Add Progress as Child
67+
let p1 = await doSomethingWithProgress()
68+
overall.addChild(p1, withPendingUnitCount: 5)
69+
70+
let _ = await Task.detached {
71+
p1.completedUnitCount = 1
72+
try? await Task.sleep(nanoseconds: 10000)
73+
p1.completedUnitCount = 2
74+
}.value
75+
76+
// Check if ProgressManager values propagate to Progress parent
77+
#expect(overall.fractionCompleted == 0.5)
78+
#expect(overall.completedUnitCount == 5)
79+
80+
// Add ProgressReporter as Child
81+
let p2 = ProgressManager(totalCount: 10)
82+
let p2Reporter = p2.reporter
83+
overall.addChild(p2Reporter, withPendingUnitCount: 5)
84+
85+
p2.complete(count: 10)
86+
87+
// Check if Progress values propagate to Progress parent
88+
#expect(overall.fractionCompleted == 1.0)
89+
#expect(overall.completedUnitCount == 10)
90+
}
91+
92+
@Test func interopProgressParentProgressReporterChildWithExistingProgress() async throws {
93+
// Initialize a Progress parent
94+
let overall = Progress.discreteProgress(totalUnitCount: 10)
95+
96+
// Add Progress as Child
97+
let p1 = await doSomethingWithProgress()
98+
overall.addChild(p1, withPendingUnitCount: 5)
99+
100+
let _ = await Task.detached {
101+
p1.completedUnitCount = 1
102+
try? await Task.sleep(nanoseconds: 10000)
103+
p1.completedUnitCount = 2
104+
}.value
105+
106+
// Check if ProgressManager values propagate to Progress parent
107+
#expect(overall.fractionCompleted == 0.5)
108+
#expect(overall.completedUnitCount == 5)
109+
110+
// Add ProgressReporter with CompletedCount 3 as Child
111+
let p2 = ProgressManager(totalCount: 10)
112+
p2.complete(count: 3)
113+
let p2Reporter = p2.reporter
114+
overall.addChild(p2Reporter, withPendingUnitCount: 5)
115+
116+
p2.complete(count: 7)
117+
118+
// Check if Progress values propagate to Progress parent
119+
#expect(overall.fractionCompleted == 1.0)
120+
#expect(overall.completedUnitCount == 10)
121+
}
122+
123+
@Test func interopProgressManagerParentProgressChild() async throws {
124+
// Initialize ProgressManager parent
125+
let overallManager = ProgressManager(totalCount: 10)
126+
127+
// Add ProgressManager as Child
128+
await doSomethingWithReporter(subprogress: overallManager.subprogress(assigningCount: 5))
129+
130+
// Check if ProgressManager values propagate to ProgressManager parent
131+
#expect(overallManager.fractionCompleted == 0.5)
132+
#expect(overallManager.completedCount == 5)
133+
134+
// Interop: Add Progress as Child
135+
let p2 = await doSomethingWithProgress()
136+
overallManager.subprogress(assigningCount: 5, to: p2)
137+
138+
let _ = await Task.detached {
139+
p2.completedUnitCount = 1
140+
try? await Task.sleep(nanoseconds: 10000)
141+
p2.completedUnitCount = 2
142+
}.value
143+
144+
// Check if Progress values propagate to ProgressRerpoter parent
145+
#expect(overallManager.completedCount == 10)
146+
#expect(overallManager.totalCount == 10)
147+
#expect(overallManager.fractionCompleted == 1.0)
148+
}
149+
150+
func getProgressWithTotalCountInitialized() -> Progress {
151+
return Progress(totalUnitCount: 5)
152+
}
153+
154+
func receiveProgress(progress: consuming Subprogress) {
155+
let _ = progress.start(totalCount: 5)
156+
}
157+
158+
@Test func interopProgressManagerParentProgressChildConsistency() async throws {
159+
let overallReporter = ProgressManager(totalCount: nil)
160+
let child = overallReporter.subprogress(assigningCount: 5)
161+
receiveProgress(progress: child)
162+
#expect(overallReporter.totalCount == nil)
163+
164+
let overallReporter2 = ProgressManager(totalCount: nil)
165+
let interopChild = getProgressWithTotalCountInitialized()
166+
overallReporter2.subprogress(assigningCount: 5, to: interopChild)
167+
#expect(overallReporter2.totalCount == nil)
168+
}
169+
170+
@Test func interopProgressParentProgressManagerChildConsistency() async throws {
171+
let overallProgress = Progress()
172+
let child = Progress(totalUnitCount: 5)
173+
overallProgress.addChild(child, withPendingUnitCount: 5)
174+
#expect(overallProgress.totalUnitCount == 0)
175+
176+
let overallProgress2 = Progress()
177+
let interopChild = overallProgress2.makeChild(withPendingUnitCount: 5)
178+
receiveProgress(progress: interopChild)
179+
#expect(overallProgress2.totalUnitCount == 0)
180+
}
181+
182+
#if FOUNDATION_EXIT_TESTS
183+
@Test func indirectParticipationOfProgressInAcyclicGraph() async throws {
184+
await #expect(processExitsWith: .failure) {
185+
let manager = ProgressManager(totalCount: 2)
186+
187+
let parentManager1 = ProgressManager(totalCount: 1)
188+
parentManager1.assign(count: 1, to: manager.reporter)
189+
190+
let parentManager2 = ProgressManager(totalCount: 1)
191+
parentManager2.assign(count: 1, to: manager.reporter)
192+
193+
let progress = Progress.discreteProgress(totalUnitCount: 4)
194+
manager.subprogress(assigningCount: 1, to: progress)
195+
196+
progress.completedUnitCount = 2
197+
#expect(progress.fractionCompleted == 0.5)
198+
#expect(manager.fractionCompleted == 0.25)
199+
#expect(parentManager1.fractionCompleted == 0.25)
200+
#expect(parentManager2.fractionCompleted == 0.25)
201+
202+
progress.addChild(parentManager1.reporter, withPendingUnitCount: 1)
203+
}
204+
}
205+
#endif
206+
}
207+
#endif

0 commit comments

Comments
 (0)