Skip to content

Commit 34b59dd

Browse files
committed
Add AnimationTests
1 parent 25fc047 commit 34b59dd

File tree

4 files changed

+97
-33
lines changed

4 files changed

+97
-33
lines changed

Example/OpenSwiftUIUITests/Graphic/Color/ColorAnimationExampleUITests.swift

Lines changed: 0 additions & 33 deletions
This file was deleted.

Example/OpenSwiftUIUITests/Graphic/Color/ColorUITests.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,26 @@ struct ColorUITests {
5757
testName: "hsb_\(name)"
5858
)
5959
}
60+
61+
@Test
62+
func colorAnimation() {
63+
struct ContentView: View {
64+
@State private var showRed = false
65+
var body: some View {
66+
VStack {
67+
Color(platformColor: showRed ? .red : .blue)
68+
.frame(width: showRed ? 50 : 100, height: showRed ? 50 : 100)
69+
}
70+
.animation(.easeInOut(duration: 1), value: showRed)
71+
.onAppear {
72+
showRed.toggle()
73+
}
74+
}
75+
}
76+
let model = AnimationTestModel(duration: 1, count: 10)
77+
openSwiftUIAssertAnimationSnapshot(
78+
of: ContentView(),
79+
model: model,
80+
)
81+
}
6082
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//
2+
// AnimationDebugController.swift
3+
// OpenSwiftUIUITests
4+
5+
import Foundation
6+
7+
struct AnimationTestModel: Hashable {
8+
var intervals: [Double]
9+
10+
init(intervals: [Double]) {
11+
self.intervals = intervals
12+
}
13+
14+
init(times: [Double]) {
15+
intervals = zip(times.dropFirst(), times).map { $0 - $1 }
16+
}
17+
18+
init(duration: Double, count: Int) {
19+
intervals = Array(repeating: duration / Double(count), count: count)
20+
}
21+
}
22+
23+
final class AnimationDebugController<V>: UIHostingController<V> where V: View {
24+
init(_ view: V) {
25+
super.init(rootView: view)
26+
}
27+
28+
@MainActor
29+
required init?(coder: NSCoder) {
30+
fatalError("init(coder:) has not been implemented")
31+
}
32+
33+
func advance(interval: Double) {
34+
(view as! _UIHostingView<V>)._renderForTest(interval: interval)
35+
}
36+
37+
func advanceAsync(interval: Double) -> Bool {
38+
(view as! _UIHostingView<V>)._renderAsyncForTest(interval: interval)
39+
}
40+
}

Example/OpenSwiftUIUITests/UITests/SnapshotTesting+Testing.swift

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,3 +155,38 @@ private func openSwiftUIAssertSnapshot<Value, Format>(
155155
)
156156
)
157157
}
158+
159+
// MARK: - Animation
160+
161+
func openSwiftUIAssertAnimationSnapshot<V: View>(
162+
of value: @autoclosure () -> V,
163+
model: AnimationTestModel,
164+
perceptualPrecision: Float = 1,
165+
size: CGSize = defaultSize,
166+
record recording: Bool? = shouldRecord,
167+
timeout: TimeInterval = 5,
168+
fileID: StaticString = #fileID,
169+
file filePath: StaticString = #filePath,
170+
testName: String = #function,
171+
line: UInt = #line,
172+
column: UInt = #column
173+
) {
174+
let vc = AnimationDebugController(value())
175+
// Flush the neccessary onAppear etc. stuff
176+
vc.advance(interval: .zero)
177+
model.intervals.enumerated().forEach { (index, interval) in
178+
vc.advance(interval: interval)
179+
openSwiftUIAssertSnapshot(
180+
of: vc,
181+
as: .image(perceptualPrecision: perceptualPrecision, size: size),
182+
named: "\(index + 1)_\(model.intervals.count).\(Int(size.width))x\(Int(size.height))",
183+
record: recording,
184+
timeout: timeout,
185+
fileID: fileID,
186+
file: filePath,
187+
testName: testName,
188+
line: line,
189+
column: column
190+
)
191+
}
192+
}

0 commit comments

Comments
 (0)