@@ -2,11 +2,130 @@ import XCTest
22@testable import GradientFlow
33
44final class GradientFlowTests : XCTestCase {
5- func testExample( ) throws {
6- // XCTest Documentation
7- // https://developer.apple.com/documentation/xctest
85
9- // Defining Test Cases and Test Methods
10- // https://developer.apple.com/documentation/xctest/defining_test_cases_and_test_methods
6+ // MARK: - GradientFlow Entry Point
7+
8+ @MainActor
9+ func test_createLabel_returnsGradientTextLabel( ) {
10+ let label = GradientFlow . createLabel ( )
11+ XCTAssertNotNil ( label)
12+ XCTAssertTrue ( type ( of: label) == GradientTextLabel . self)
13+ }
14+
15+ @MainActor
16+ func test_createAnimatedLabel_setsTextColorsAndAnimationFlag( ) {
17+ let colors = GradientFlow . ColorPresets. purpleDream
18+
19+ let label = GradientFlow . createAnimatedLabel ( text: " Hello " , colors: colors)
20+
21+ XCTAssertEqual ( label. text, " Hello " )
22+ XCTAssertEqual ( label. colors. count, colors. count)
23+ XCTAssertEqual ( label. colors, colors)
24+ XCTAssertTrue ( label. isAnimated)
25+ }
26+
27+ // MARK: - Fluent API (Chaining)
28+
29+ @MainActor
30+ func test_fluentAPI_setsProperties( ) {
31+ let label = GradientTextLabel . create ( )
32+ . setText ( " Rainbow! " )
33+ . setFontSize ( 32 )
34+ . setFontWeight ( . semibold)
35+ . setGradientDirection ( . topToBottom)
36+ . setAnimated ( false )
37+ . setAnimationDirection ( . bottomToTop)
38+ . setAnimationDuration ( 2.5 )
39+
40+ XCTAssertEqual ( label. text, " Rainbow! " )
41+ XCTAssertEqual ( label. fontSize, 32 )
42+ XCTAssertEqual ( label. fontWeight, . semibold)
43+ XCTAssertEqual ( label. gradientDirection, . topToBottom)
44+ XCTAssertFalse ( label. isAnimated)
45+ XCTAssertEqual ( label. animationDirection, . bottomToTop)
46+ XCTAssertEqual ( label. animationDuration, 2.5 , accuracy: 0.0001 )
47+ }
48+
49+ // MARK: - Presets
50+
51+ @MainActor
52+ func test_setColorPreset_appliesColors( ) {
53+ let preset = GradientFlow . ColorPresets. rainbow
54+
55+ let label = GradientTextLabel . create ( )
56+ . setColorPreset ( preset)
57+
58+ XCTAssertEqual ( label. colors, preset)
59+ }
60+
61+ // MARK: - AnimationDirection
62+
63+ func test_animationDirection_keyPath_isCorrect( ) {
64+ XCTAssertEqual ( AnimationDirection . leftToRight. keyPath, " x " )
65+ XCTAssertEqual ( AnimationDirection . rightToLeft. keyPath, " x " )
66+ XCTAssertEqual ( AnimationDirection . topToBottom. keyPath, " y " )
67+ XCTAssertEqual ( AnimationDirection . bottomToTop. keyPath, " y " )
68+ }
69+
70+ // MARK: - Gradient Layer / Mask Wiring
71+
72+ @MainActor
73+ func test_layoutSubviews_setsMaskAndGradientFrame( ) {
74+ let label = GradientTextLabel ( )
75+ label. frame = CGRect ( x: 0 , y: 0 , width: 120 , height: 40 )
76+
77+ // Trigger a layout pass so layoutSubviews() runs.
78+ label. layoutIfNeeded ( )
79+
80+ // The view should have a mask layer (CATextLayer) applied.
81+ XCTAssertNotNil ( label. layer. mask)
82+
83+ // The gradient layer frame should be non-zero after layout.
84+ XCTAssertGreaterThan ( label. gradientLayer. frame. width, 0 )
85+ XCTAssertGreaterThan ( label. gradientLayer. frame. height, 0 )
86+ }
87+
88+ @MainActor
89+ func test_whenAnimatedTrue_animationIsAddedToGradientLayer( ) {
90+ let label = GradientTextLabel ( )
91+ label. frame = CGRect ( x: 0 , y: 0 , width: 120 , height: 40 )
92+ label. isAnimated = true
93+
94+ // layoutSubviews() should start the animation when isAnimated is true.
95+ label. layoutIfNeeded ( )
96+
97+ // Verify the animation is registered on the gradient layer.
98+ let keys = label. gradientLayer. animationKeys ( ) ?? [ ]
99+ XCTAssertTrue ( keys. contains ( " gradientAnimation " ) )
100+ }
101+
102+ @MainActor
103+ func test_whenAnimatedFalse_animationIsRemovedFromGradientLayer( ) {
104+ let label = GradientTextLabel ( )
105+ label. frame = CGRect ( x: 0 , y: 0 , width: 120 , height: 40 )
106+ label. isAnimated = true
107+ label. layoutIfNeeded ( )
108+
109+ // Turning off animation should remove it from the gradient layer.
110+ label. isAnimated = false
111+
112+ let keys = label. gradientLayer. animationKeys ( ) ?? [ ]
113+ XCTAssertFalse ( keys. contains ( " gradientAnimation " ) )
114+ }
115+
116+ // MARK: - Gradient Direction Start/End Points
117+
118+ @MainActor
119+ func test_gradientDirection_updatesStartEndPoints( ) {
120+ let label = GradientTextLabel ( )
121+ label. frame = CGRect ( x: 0 , y: 0 , width: 100 , height: 30 )
122+
123+ label. gradientDirection = . leftToRight
124+ XCTAssertEqual ( label. gradientLayer. startPoint, CGPoint ( x: 0 , y: 0.5 ) )
125+ XCTAssertEqual ( label. gradientLayer. endPoint, CGPoint ( x: 1 , y: 0.5 ) )
126+
127+ label. gradientDirection = . topToBottom
128+ XCTAssertEqual ( label. gradientLayer. startPoint, CGPoint ( x: 0.5 , y: 0 ) )
129+ XCTAssertEqual ( label. gradientLayer. endPoint, CGPoint ( x: 0.5 , y: 1 ) )
11130 }
12131}
0 commit comments