-
Notifications
You must be signed in to change notification settings - Fork 240
/
Copy pathAnimatedImageTests.swift
186 lines (173 loc) · 7.61 KB
/
AnimatedImageTests.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
import XCTest
import SwiftUI
import ViewInspector
@testable import SDWebImageSwiftUI
extension AnimatedImage : Inspectable {}
extension AnimatedImage {
struct WrapperView: View & Inspectable {
var name: String
var bundle: Bundle?
@State var isAnimating: Bool
var onViewUpdate: (Self, PlatformView, AnimatedImage.Context) -> Void
var body: some View {
AnimatedImage(name: name, bundle: bundle, isAnimating: $isAnimating)
.onViewUpdate { view, context in
self.onViewUpdate(self, view, context)
}
}
}
}
class AnimatedImageTests: XCTestCase {
override func setUp() {
super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}
func testAnimatedImageWithName() throws {
let expectation = self.expectation(description: "AnimatedImage name initializer")
let imageName = "TestImage.gif"
let imageView = AnimatedImage(name: imageName, bundle: TestUtils.testImageBundle())
ViewHosting.host(view: imageView)
let animatedImageView = try imageView.inspect().actualView().platformView().wrapped
if let animatedImage = animatedImageView.image as? SDAnimatedImage {
XCTAssertEqual(animatedImage.animatedImageLoopCount, 0)
XCTAssertEqual(animatedImage.animatedImageFrameCount, 5)
} else {
XCTFail("SDAnimatedImageView.image invalid")
}
expectation.fulfill()
self.waitForExpectations(timeout: 5, handler: nil)
ViewHosting.expel()
}
func testAnimatedImageWithData() throws {
let expectation = self.expectation(description: "AnimatedImage data initializer")
let imageData = try XCTUnwrap(TestUtils.testImageData(name: "TestLoopCount.gif"))
let imageView = AnimatedImage(data: imageData)
ViewHosting.host(view: imageView)
let animatedImageView = try imageView.inspect().actualView().platformView().wrapped
if let animatedImage = animatedImageView.image as? SDAnimatedImage {
XCTAssertEqual(animatedImage.animatedImageLoopCount, 1)
XCTAssertEqual(animatedImage.animatedImageFrameCount, 2)
} else {
XCTFail("SDAnimatedImageView.image invalid")
}
expectation.fulfill()
self.waitForExpectations(timeout: 5, handler: nil)
ViewHosting.expel()
}
func testAnimatedImageWithURL() throws {
let expectation = self.expectation(description: "AnimatedImage url initializer")
let imageUrl = URL(string: "https://raw.githubusercontent.com/liyong03/YLGIFImage/master/YLGIFImageDemo/YLGIFImageDemo/joy.gif")
let imageView = AnimatedImage(url: imageUrl)
.onSuccess { image, data, cacheType in
XCTAssertNotNil(image)
if let animatedImage = image as? SDAnimatedImage {
XCTAssertEqual(animatedImage.animatedImageLoopCount, 0)
XCTAssertEqual(animatedImage.animatedImageFrameCount, 389)
} else {
XCTFail("SDAnimatedImageView.image invalid")
}
expectation.fulfill()
}.onFailure { error in
XCTFail(error.localizedDescription)
}
ViewHosting.host(view: imageView)
let animatedImageView = try imageView.inspect().actualView().platformView().wrapped
XCTAssertEqual(animatedImageView.sd_imageURL, imageUrl)
self.waitForExpectations(timeout: 10, handler: nil)
ViewHosting.expel()
}
func testAnimatedImageBinding() throws {
let expectation = self.expectation(description: "AnimatedImage binding control")
var isStopped = false
// Use wrapper to make the @Binding works
let wrapperView = AnimatedImage.WrapperView(name: "TestImageAnimated.apng", bundle: TestUtils.testImageBundle(), isAnimating: true) { wrapperView, view, context in
guard let animatedImageView = view as? SDAnimatedImageView else {
XCTFail("AnimatedImage's view should be SDAnimatedImageView")
return
}
if let animatedImage = animatedImageView.image as? SDAnimatedImage {
XCTAssertEqual(animatedImage.animatedImageLoopCount, 0)
XCTAssertEqual(animatedImage.animatedImageFrameCount, 101)
} else {
XCTFail("AnimatedImage's image should be SDAnimatedImage")
}
// Wait 1 second for SwiftUI's own `updateUIView` callback finished.
// It's suck that the actual callback behavior is different on different iOS version or Simulator version, so I can assume which is the last callback using the callback count.
if !isStopped {
// # SwiftUI's own updateUIView call
// Ignore in Travis-CI because of macOS 10.14's bug behavior on iPhone Simulator
// #if os(iOS) || os(tvOS)
// XCTAssertTrue(animatedImageView.isAnimating)
// #else
// XCTAssertTrue(animatedImageView.animates)
// #endif
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
if !isStopped {
isStopped = true
wrapperView.isAnimating = false
} else {
// Extra `updateUIView` from SwiftUI, ignore
}
}
} else {
// # AnimatedImage's isAnimating @Binding trigger update (from above)
#if os(iOS) || os(tvOS)
XCTAssertFalse(animatedImageView.isAnimating)
#else
XCTAssertFalse(animatedImageView.animates)
#endif
expectation.fulfill()
}
}
ViewHosting.host(view: wrapperView)
self.waitForExpectations(timeout: 5, handler: nil)
ViewHosting.expel()
}
func testAnimatedImageModifier() throws {
let expectation = self.expectation(description: "WebImage modifier")
let imageUrl = URL(string: "https://assets.sbnation.com/assets/2512203/dogflops.gif")
let imageView = AnimatedImage(url: imageUrl, options: [.progressiveLoad], context: [.imageScaleFactor: 1]) {
Circle()
}
let introspectView = imageView
.onSuccess { _, _, _ in
expectation.fulfill()
}
.onFailure { _ in
XCTFail()
}
.onProgress { _, _ in
}
.onViewCreate { view, context in
XCTAssert(view.isKind(of: SDAnimatedImageView.self))
context.coordinator.userInfo = ["foo" : "bar"]
}
.onViewUpdate { view, context in
XCTAssert(view.isKind(of: SDAnimatedImageView.self))
XCTAssertEqual(context.coordinator.userInfo?["foo"] as? String, "bar")
}
.indicator(.activity)
// Image
.resizable()
.renderingMode(.original)
.interpolation(.high)
.antialiased(true)
// Animation
.runLoopMode(.common)
.customLoopCount(1)
.maxBufferSize(0)
.pausable(true)
.purgeable(true)
.playbackRate(1)
.transition(.fade)
.animation(.easeInOut)
_ = try introspectView.inspect()
ViewHosting.host(view: introspectView)
self.waitForExpectations(timeout: 10, handler: nil)
ViewHosting.expel()
}
}