@@ -21,12 +21,13 @@ import Testing
2121 return p
2222 }
2323
24- func doSomethingWithReporter ( subprogress: consuming Subprogress ? ) async {
24+ func doSomething ( subprogress: consuming Subprogress ? ) async {
2525 let manager = subprogress? . start ( totalCount: 4 )
2626 manager? . complete ( count: 2 )
2727 manager? . complete ( count: 2 )
2828 }
2929
30+ // MARK: Progress - Subprogress Interop
3031 @Test func interopProgressParentProgressManagerChild( ) async throws {
3132 // Initialize a Progress Parent
3233 let overall = Progress . discreteProgress ( totalUnitCount: 10 )
@@ -47,14 +48,75 @@ import Testing
4748
4849 // Add ProgressManager as Child
4950 let p2 = overall. makeChild ( withPendingUnitCount: 5 )
50- await doSomethingWithReporter ( subprogress: p2)
51+ await doSomething ( subprogress: p2)
5152
5253 // Check if ProgressManager values propagate to Progress parent
5354 #expect( overall. fractionCompleted == 1.0 )
5455 #expect( overall. completedUnitCount == 10 )
5556 }
5657
57- @Test func interopProgressParentProgressReporterChildWithEmptyProgress( ) async throws {
58+ @Test func interopProgressParentProgressManagerGrandchild( ) async throws {
59+ // Structure: Progress with two Progress children, one of the children has a ProgressManager child
60+ let overall = Progress . discreteProgress ( totalUnitCount: 10 )
61+
62+ let p1 = await doSomethingWithProgress ( )
63+ overall. addChild ( p1, withPendingUnitCount: 5 )
64+
65+ let _ = await Task . detached {
66+ p1. completedUnitCount = 1
67+ try ? await Task . sleep ( nanoseconds: 10000 )
68+ p1. completedUnitCount = 2
69+ } . value
70+
71+ #expect( overall. fractionCompleted == 0.5 )
72+ #expect( overall. completedUnitCount == 5 )
73+
74+ let p2 = Progress ( totalUnitCount: 1 , parent: overall, pendingUnitCount: 5 )
75+
76+ await doSomething ( subprogress: p2. makeChild ( withPendingUnitCount: 1 ) )
77+
78+ // Check if ProgressManager values propagate to Progress parent
79+ #expect( overall. fractionCompleted == 1.0 )
80+ #expect( overall. completedUnitCount == 10 )
81+ }
82+
83+ @Test func interopProgressParentProgressManagerGrandchildAndProgressGrandchild( ) async throws {
84+ // Structure: Progress with two Progress children, one of the children has a ProgressManager child and a Progress child
85+ let overall = Progress . discreteProgress ( totalUnitCount: 10 )
86+
87+ let p1 = await doSomethingWithProgress ( )
88+ overall. addChild ( p1, withPendingUnitCount: 5 )
89+
90+ let _ = await Task . detached {
91+ p1. completedUnitCount = 1
92+ try ? await Task . sleep ( nanoseconds: 10000 )
93+ p1. completedUnitCount = 2
94+ } . value
95+
96+ #expect( overall. fractionCompleted == 0.5 )
97+ #expect( overall. completedUnitCount == 5 )
98+
99+ let p2 = Progress ( totalUnitCount: 18 )
100+ overall. addChild ( p2, withPendingUnitCount: 5 )
101+
102+ let p3 = await doSomethingWithProgress ( )
103+ p2. addChild ( p3, withPendingUnitCount: 9 )
104+
105+ let _ = await Task . detached {
106+ p3. completedUnitCount = 1
107+ try ? await Task . sleep ( nanoseconds: 10000 )
108+ p3. completedUnitCount = 2
109+ } . value
110+
111+ await doSomething ( subprogress: p2. makeChild ( withPendingUnitCount: 9 ) )
112+
113+ // Check if ProgressManager values propagate to Progress parent
114+ #expect( overall. fractionCompleted == 1.0 )
115+ #expect( overall. completedUnitCount == 10 )
116+ }
117+
118+ // MARK: Progress - ProgressReporter Interop
119+ @Test func interopProgressParentProgressReporterChild( ) async throws {
58120 // Initialize a Progress parent
59121 let overall = Progress . discreteProgress ( totalUnitCount: 10 )
60122
@@ -84,7 +146,7 @@ import Testing
84146 #expect( overall. completedUnitCount == 10 )
85147 }
86148
87- @Test func interopProgressParentProgressReporterChildWithExistingProgress ( ) async throws {
149+ @Test func interopProgressParentProgressReporterChildWithNonZeroFractionCompleted ( ) async throws {
88150 // Initialize a Progress parent
89151 let overall = Progress . discreteProgress ( totalUnitCount: 10 )
90152
@@ -115,12 +177,51 @@ import Testing
115177 #expect( overall. completedUnitCount == 10 )
116178 }
117179
180+ @Test func interopProgressParentProgressReporterGrandchild( ) async throws {
181+ // Initialize a Progress parent
182+ let overall = Progress . discreteProgress ( totalUnitCount: 10 )
183+
184+ // Add Progress as Child
185+ let p1 = await doSomethingWithProgress ( )
186+ overall. addChild ( p1, withPendingUnitCount: 5 )
187+
188+ let _ = await Task . detached {
189+ p1. completedUnitCount = 1
190+ try ? await Task . sleep ( nanoseconds: 10000 )
191+ p1. completedUnitCount = 2
192+ } . value
193+
194+ // Check if ProgressManager values propagate to Progress parent
195+ #expect( overall. fractionCompleted == 0.5 )
196+ #expect( overall. completedUnitCount == 5 )
197+
198+ let p2 = await doSomethingWithProgress ( )
199+ overall. addChild ( p2, withPendingUnitCount: 5 )
200+
201+ p2. completedUnitCount = 1
202+
203+ #expect( overall. fractionCompleted == 0.75 )
204+ #expect( overall. completedUnitCount == 5 )
205+
206+ // Add ProgressReporter as Child
207+ let p3 = ProgressManager ( totalCount: 10 )
208+ let p3Reporter = p3. reporter
209+ p2. addChild ( p3Reporter, withPendingUnitCount: 1 )
210+
211+ p3. complete ( count: 10 )
212+
213+ // Check if Progress values propagate to Progress parent
214+ #expect( overall. fractionCompleted == 1.0 )
215+ #expect( overall. completedUnitCount == 10 )
216+ }
217+
218+ // MARK: ProgressManager - Progress Interop
118219 @Test func interopProgressManagerParentProgressChild( ) async throws {
119220 // Initialize ProgressManager parent
120221 let overallManager = ProgressManager ( totalCount: 10 )
121222
122223 // Add ProgressManager as Child
123- await doSomethingWithReporter ( subprogress: overallManager. subprogress ( assigningCount: 5 ) )
224+ await doSomething ( subprogress: overallManager. subprogress ( assigningCount: 5 ) )
124225
125226 // Check if ProgressManager values propagate to ProgressManager parent
126227 #expect( overallManager. fractionCompleted == 0.5 )
@@ -142,6 +243,34 @@ import Testing
142243 #expect( overallManager. fractionCompleted == 1.0 )
143244 }
144245
246+ @Test func interopProgressManagerParentProgressGrandchild( ) async throws {
247+ // Initialize ProgressManager parent
248+ let overallManager = ProgressManager ( totalCount: 10 )
249+
250+ // Add ProgressManager as Child
251+ await doSomething ( subprogress: overallManager. subprogress ( assigningCount: 5 ) )
252+
253+ #expect( overallManager. fractionCompleted == 0.5 )
254+ #expect( overallManager. completedCount == 5 )
255+
256+ let p2 = overallManager. subprogress ( assigningCount: 5 ) . start ( totalCount: 3 )
257+ p2. complete ( count: 1 )
258+
259+
260+ let p3 = await doSomethingWithProgress ( )
261+ p2. subprogress ( assigningCount: 2 , to: p3)
262+
263+ let _ = await Task . detached {
264+ p3. completedUnitCount = 1
265+ try ? await Task . sleep ( nanoseconds: 10000 )
266+ p3. completedUnitCount = 2
267+ } . value
268+
269+ // Check if Progress values propagate to ProgressRerpoter parent
270+ #expect( overallManager. completedCount == 10 )
271+ #expect( overallManager. fractionCompleted == 1.0 )
272+ }
273+
145274 func getProgressWithTotalCountInitialized( ) -> Progress {
146275 return Progress ( totalUnitCount: 5 )
147276 }
@@ -150,6 +279,7 @@ import Testing
150279 let _ = progress. start ( totalCount: 5 )
151280 }
152281
282+ // MARK: Behavior Consistency Tests
153283 @Test func interopProgressManagerParentProgressChildConsistency( ) async throws {
154284 let overallReporter = ProgressManager ( totalCount: nil )
155285 let child = overallReporter. subprogress ( assigningCount: 5 )
0 commit comments