diff --git a/Sources/OpenSwiftUICore/Shape/ShapeStyle/ContentStyle.swift b/Sources/OpenSwiftUICore/Shape/ShapeStyle/ContentStyle.swift index dbbf392e0..3781f6f18 100644 --- a/Sources/OpenSwiftUICore/Shape/ShapeStyle/ContentStyle.swift +++ b/Sources/OpenSwiftUICore/Shape/ShapeStyle/ContentStyle.swift @@ -2,7 +2,7 @@ // ContentStyle.swift // OpenSwiftUICore // -// Audited for 6.0.87 +// Audited for 6.5.4 // Status: Complete // ID: BE30CA4BBA5F98638AD9D34F1557FB4D (SwiftUICore) @@ -286,17 +286,15 @@ extension ContentStyle.ID: ColorProvider { } package init?(level: Int) { - self.init(rawValue: Int8(level & 0xFF)) + guard (0..<5).contains(level) else { + return nil + } + self.init(rawValue: Int8(level)) } package init(truncatingLevel level: Int) { - switch level { - case 0: self = .primary - case 1: self = .secondary - case 2: self = .tertiary - case 3: self = .quaternary - default: self = .quinary - } + let rawValue = Int8(truncatingIfNeeded: min(level, 4)) + self = Self(rawValue: rawValue)! } } @@ -345,7 +343,7 @@ public struct HierarchicalShapeStyleModifier: ShapeStyle where Base: Shape } public func _apply(to shape: inout _ShapeStyle_Shape) { - if let primaryStyle = primaryStyle(in: shape.environment) { + if let primaryStyle = base.primaryStyle(in: shape.environment) { primaryStyle.offset(by: level)._apply(to: &shape) } else { base.offset(by: level)._apply(to: &shape) diff --git a/Tests/OpenSwiftUICoreTests/Shape/ShapeStyle/ContentStyleTests.swift b/Tests/OpenSwiftUICoreTests/Shape/ShapeStyle/ContentStyleTests.swift new file mode 100644 index 000000000..a5dd294aa --- /dev/null +++ b/Tests/OpenSwiftUICoreTests/Shape/ShapeStyle/ContentStyleTests.swift @@ -0,0 +1,43 @@ +// +// ContentStyleTests.swift +// OpenSwiftUICoreTests + +import OpenSwiftUICore +import OpenSwiftUITestsSupport +import Testing + +@Suite(.tags(.aigc)) +struct ContentStyleTests { + @Test(arguments: [ + (0, ContentStyle.ID.primary), + (1, .secondary), + (2, .tertiary), + (3, .quaternary), + (4, .quinary), + ]) + func levelSelectsStyle(level: Int, expected: ContentStyle.ID) { + #expect(ContentStyle.ID(level: level) == expected) + } + + @Test(arguments: [Int.min, -256, -1, 5, 127, 128, 255, 256, 260, Int.max]) + func invalidLevelReturnsNil(level: Int) { + #expect(ContentStyle.ID(level: level) == nil) + } + + @Test(arguments: [ + (0, ContentStyle.ID.primary), + (1, .secondary), + (2, .tertiary), + (3, .quaternary), + (4, .quinary), + (5, .quinary), + (256, .quinary), + (Int.max, .quinary), + (-256, .primary), + (-255, .secondary), + (-252, .quinary), + ]) + func truncatingLevelSelectsStyle(level: Int, expected: ContentStyle.ID) { + #expect(ContentStyle.ID(truncatingLevel: level) == expected) + } +} diff --git a/Tests/OpenSwiftUICoreTests/Shape/ShapeStyle/HierarchicalShapeStyleTests.swift b/Tests/OpenSwiftUICoreTests/Shape/ShapeStyle/HierarchicalShapeStyleTests.swift new file mode 100644 index 000000000..6c5a8fb08 --- /dev/null +++ b/Tests/OpenSwiftUICoreTests/Shape/ShapeStyle/HierarchicalShapeStyleTests.swift @@ -0,0 +1,46 @@ +// +// HierarchicalShapeStyleTests.swift +// OpenSwiftUICoreTests + +@testable import OpenSwiftUICore +import OpenSwiftUITestsSupport +import Testing + +@Suite(.tags(.aigc)) +struct HierarchicalShapeStyleTests { + @Test + func secondaryColorUsesBaseColor() { + var environment = EnvironmentValues() + environment.setTestSystemColorDefinition() + var shape = _ShapeStyle_Shape( + operation: .fallbackColor(level: 0), + environment: environment + ) + + Color.red.secondary._apply(to: &shape) + + guard case let .color(color) = shape.result else { + Issue.record("Expected secondary fallback color") + return + } + #expect(color == .red.opacity(0.75)) + } + + @Test + func nestedStyleUsesPrimaryBaseColor() { + var environment = EnvironmentValues() + environment.setTestSystemColorDefinition() + var shape = _ShapeStyle_Shape( + operation: .fallbackColor(level: 0), + environment: environment + ) + + Color.red.tertiary.secondary._apply(to: &shape) + + guard case let .color(color) = shape.result else { + Issue.record("Expected secondary fallback color") + return + } + #expect(color == .red.opacity(0.75)) + } +}