@@ -974,3 +974,104 @@ extension ProgressManager.Properties {
974974 #expect( manager. summary ( of: ProgressManager . Properties. TotalPixelCount. self) == [ 42 , 26 , 24 ] )
975975 }
976976}
977+
978+ extension ProgressManager . Properties {
979+ var viralIndeterminate : ViralIndeterminate . Type { ViralIndeterminate . self }
980+ struct ViralIndeterminate : Sendable , ProgressManager . Property {
981+ typealias Value = Int
982+
983+ typealias Summary = Int
984+
985+ static var key : String { " MyApp.ViralIndeterminate " }
986+
987+ static var defaultValue : Int { 1 }
988+
989+ static var defaultSummary : Int { 1 }
990+
991+ static func reduce( into summary: inout Int , value: Int ) {
992+ summary = min ( summary, value)
993+ }
994+
995+ static func merge( _ summary1: Int , _ summary2: Int ) -> Int {
996+ min ( summary1, summary2)
997+ }
998+
999+ static func finalSummary( _ parentSummary: Int , _ childSummary: Int ) -> Int {
1000+ min ( parentSummary, childSummary)
1001+ }
1002+ }
1003+ }
1004+
1005+
1006+ @Suite ( " Progress Manager Viral Indeterminate Property " , . tags( . progressManager) ) struct ProgressManagerViralIndeterminateProperties {
1007+ // Tests the use of additional property to virally propagate property from leaf to root
1008+ func doSomething( subprogress: consuming Subprogress ) async {
1009+ let manager = subprogress. start ( totalCount: 3 )
1010+
1011+ manager. withProperties { properties in
1012+ properties. completedCount += 1
1013+ properties. viralIndeterminate = 0
1014+
1015+ properties. completedCount += 1
1016+
1017+ properties. completedCount += 1
1018+ }
1019+
1020+ #expect( manager. fractionCompleted == 1.0 )
1021+ #expect( manager. summary ( of: ProgressManager . Properties. ViralIndeterminate. self) == 0 )
1022+ }
1023+
1024+ func doSomethingTwoLevels( subprogress: consuming Subprogress ) async {
1025+ let manager = subprogress. start ( totalCount: 2 )
1026+
1027+ manager. withProperties { properties in
1028+ properties. completedCount = 1
1029+ properties. viralIndeterminate = 1
1030+ }
1031+
1032+ await doSomething ( subprogress: manager. subprogress ( assigningCount: 1 ) )
1033+
1034+ #expect( manager. fractionCompleted == 1.0 )
1035+ #expect( manager. summary ( of: ProgressManager . Properties. ViralIndeterminate. self) == 0 )
1036+ }
1037+
1038+ @Test func discreteManager( ) async throws {
1039+ let manager = ProgressManager ( totalCount: 1 )
1040+
1041+ manager. withProperties { properties in
1042+ properties. completedCount = 1
1043+ properties. viralIndeterminate = 1
1044+ }
1045+
1046+ #expect( manager. fractionCompleted == 1.0 )
1047+ #expect( manager. summary ( of: ProgressManager . Properties. ViralIndeterminate. self) == 1 )
1048+ }
1049+
1050+ @Test func twoLevelManager( ) async throws {
1051+ let manager = ProgressManager ( totalCount: 2 )
1052+
1053+ manager. withProperties { properties in
1054+ properties. completedCount = 1
1055+ properties. viralIndeterminate = 1
1056+ }
1057+
1058+ await doSomething ( subprogress: manager. subprogress ( assigningCount: 1 ) )
1059+
1060+ #expect( manager. fractionCompleted == 1.0 )
1061+ #expect( manager. summary ( of: ProgressManager . Properties. ViralIndeterminate. self) == 0 )
1062+ }
1063+
1064+ @Test func threeLevelManager( ) async throws {
1065+ let manager = ProgressManager ( totalCount: 2 )
1066+
1067+ manager. withProperties { properties in
1068+ properties. completedCount = 1
1069+ properties. viralIndeterminate = 1
1070+ }
1071+
1072+ await doSomethingTwoLevels ( subprogress: manager. subprogress ( assigningCount: 1 ) )
1073+
1074+ #expect( manager. fractionCompleted == 1.0 )
1075+ #expect( manager. summary ( of: ProgressManager . Properties. ViralIndeterminate. self) == 0 )
1076+ }
1077+ }
0 commit comments