Skip to content

Commit 53de385

Browse files
committed
Update the test case testAnimatedImageBinding to correctly unit test the AniamtedImage's @binding update, this time it works
1 parent 4345bd4 commit 53de385

File tree

1 file changed

+53
-24
lines changed

1 file changed

+53
-24
lines changed

Tests/AnimatedImageTests.swift

Lines changed: 53 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,23 @@ extension View {
2020
}
2121
}
2222

23+
extension AnimatedImage {
24+
struct WrapperView: View & Inspectable {
25+
var name: String
26+
var bundle: Bundle?
27+
@State var isAnimating: Bool
28+
29+
var onViewUpdate: (Self, PlatformView, AnimatedImage.Context) -> Void
30+
31+
var body: some View {
32+
AnimatedImage(name: name, bundle: bundle, isAnimating: $isAnimating)
33+
.onViewUpdate { view, context in
34+
self.onViewUpdate(self, view, context)
35+
}
36+
}
37+
}
38+
}
39+
2340
class AnimatedImageTests: XCTestCase {
2441

2542
override func setUp() {
@@ -89,38 +106,50 @@ class AnimatedImageTests: XCTestCase {
89106

90107
func testAnimatedImageBinding() throws {
91108
let expectation = self.expectation(description: "AnimatedImage binding control")
92-
let binding = Binding<Bool>(wrappedValue: true)
93-
var context: AnimatedImage.Context?
94-
let imageView = AnimatedImage(name: "TestLoopCount.gif", bundle: TestUtils.testImageBundle(), isAnimating: binding)
95-
.onViewCreate { _, c in
96-
context = c
97-
}
98-
let introspectView = imageView.introspectAnimatedImage { animatedImageView in
109+
var viewUpdateCount = 0
110+
// Use wrapper to make the @Binding works
111+
let wrapperView = AnimatedImage.WrapperView(name: "TestLoopCount.gif", bundle: TestUtils.testImageBundle(), isAnimating: true) { wrapperView, view, context in
112+
viewUpdateCount += 1
113+
guard let animatedImageView = view as? SDAnimatedImageView else {
114+
XCTFail("AnimatedImage's view should be SDAnimatedImageView")
115+
return
116+
}
99117
if let animatedImage = animatedImageView.image as? SDAnimatedImage {
100118
XCTAssertEqual(animatedImage.animatedImageLoopCount, 1)
101119
XCTAssertEqual(animatedImage.animatedImageFrameCount, 2)
102120
} else {
103-
XCTFail("SDAnimatedImageView.image invalid")
121+
XCTFail("AnimatedImage's image should be SDAnimatedImage")
104122
}
105-
#if os(iOS) || os(tvOS)
106-
XCTAssertTrue(animatedImageView.isAnimating)
123+
// View update times before stable from SwiftUI, different behavior for AppKit/UIKit
124+
#if os(macOS)
125+
let stableViewUpdateCount = 1
107126
#else
108-
XCTAssertTrue(animatedImageView.animates)
127+
let stableViewUpdateCount = 2
109128
#endif
110-
binding.wrappedValue = false
111-
XCTAssertFalse(binding.wrappedValue)
112-
XCTAssertFalse(imageView.isAnimating)
113-
// Currently ViewInspector's @Binding value update does not trigger `UIViewRepresentable.updateUIView`, mock here
114-
imageView.updateView(animatedImageView.superview as! AnimatedImageViewWrapper, context: context!)
115-
#if os(iOS) || os(tvOS)
116-
XCTAssertFalse(animatedImageView.isAnimating)
117-
#else
118-
XCTAssertFalse(animatedImageView.animates)
119-
#endif
120-
expectation.fulfill()
129+
switch viewUpdateCount {
130+
case stableViewUpdateCount:
131+
// #1 SwiftUI's own updateUIView call
132+
#if os(iOS) || os(tvOS)
133+
XCTAssertTrue(animatedImageView.isAnimating)
134+
#else
135+
XCTAssertTrue(animatedImageView.animates)
136+
#endif
137+
DispatchQueue.main.async {
138+
wrapperView.isAnimating = false
139+
}
140+
case stableViewUpdateCount + 1:
141+
// #3 AnimatedImage's isAnimating @Binding trigger update (from above)
142+
#if os(iOS) || os(tvOS)
143+
XCTAssertFalse(animatedImageView.isAnimating)
144+
#else
145+
XCTAssertFalse(animatedImageView.animates)
146+
#endif
147+
expectation.fulfill()
148+
default: break
149+
// do not care
150+
}
121151
}
122-
_ = try introspectView.inspect(AnimatedImage.self)
123-
ViewHosting.host(view: introspectView)
152+
ViewHosting.host(view: wrapperView)
124153
self.waitForExpectations(timeout: 5, handler: nil)
125154
}
126155

0 commit comments

Comments
 (0)