Skip to content

Commit 6335a6d

Browse files
committed
Test animation stamping and emission
1 parent 0538d79 commit 6335a6d

1 file changed

Lines changed: 53 additions & 0 deletions

File tree

AndroidSwiftUICore/Tests/AndroidSwiftUICoreTests/EvaluatorTests.swift

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,3 +249,56 @@ struct GraphicsTests {
249249
#expect(node.props["vertical"] == .string("bottom"))
250250
}
251251
}
252+
253+
// MARK: - Animation
254+
255+
@Suite("Animation")
256+
struct AnimationTests {
257+
258+
@Test("A withAnimation write stamps the next tree's root, once")
259+
func withAnimationStampsRoot() {
260+
struct Screen: View {
261+
@State var on = false
262+
var body: some View { Text("x").opacity(on ? 1 : 0) }
263+
}
264+
let host = ViewHost(Screen())
265+
var node = host.evaluate()
266+
#expect(node.props["animationCurve"] == nil)
267+
// find the opacity toggle by writing through a registered callback:
268+
// simplest is to mutate via withAnimation around a state write driven
269+
// by re-linking — use onTapGesture to reach the state.
270+
struct Tappable: View {
271+
@State var on = false
272+
var body: some View {
273+
Text("x").opacity(on ? 1 : 0).onTapGesture { withAnimation(.easeIn(duration: 0.2)) { on.toggle() } }
274+
}
275+
}
276+
let tapHost = ViewHost(Tappable())
277+
node = tapHost.evaluate()
278+
guard case .int(let id)? = node.modifiers.first(where: { $0.kind == "onTapGesture" })?.args["action"] else {
279+
Issue.record("missing tap id"); return
280+
}
281+
tapHost.callbacks.invokeVoid(Int64(id))
282+
node = tapHost.evaluate()
283+
#expect(node.props["animationCurve"] == .string("easeIn"))
284+
#expect(node.props["animationDurationMs"] == .double(200))
285+
// a subsequent plain write does not animate
286+
node = tapHost.evaluate()
287+
#expect(node.props["animationCurve"] == nil)
288+
}
289+
290+
@Test("withAnimation returns its body's value and restores the transaction")
291+
func withAnimationScoping() {
292+
let result = withAnimation(.linear(duration: 1)) { 41 + 1 }
293+
#expect(result == 42)
294+
#expect(Transaction._current == nil)
295+
}
296+
297+
@Test(".animation emits curve, duration, and value token")
298+
func implicitAnimation() {
299+
let node = ViewHost(Text("x").animation(.spring(), value: 3)).evaluate()
300+
let anim = node.modifiers.first { $0.kind == "animation" }
301+
#expect(anim?.args["curve"] == .string("spring"))
302+
#expect(anim?.args["token"] == .string("3"))
303+
}
304+
}

0 commit comments

Comments
 (0)