Skip to content

Commit 7ee2295

Browse files
committed
test: swiftui preferredcontentsize
1 parent c1bf3c8 commit 7ee2295

File tree

1 file changed

+123
-0
lines changed

1 file changed

+123
-0
lines changed
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
#if canImport(UIKit)
2+
3+
import SwiftUI
4+
import Workflow
5+
import WorkflowSwiftUI
6+
import XCTest
7+
8+
final class PreferredContentSizeTests: XCTestCase {
9+
func test_preferredContentSize() {
10+
let maxWidth: CGFloat = 50
11+
let maxHeight: CGFloat = 50
12+
13+
func assertPreferredContentSize(in axes: Axis.Set) {
14+
let screen = TestScreen(model: .constant(state: State(axes: axes)))
15+
let viewController = screen.buildViewController(in: .empty)
16+
viewController.view.frame = CGRect(x: 0, y: 0, width: maxWidth, height: maxHeight)
17+
viewController.view.layoutIfNeeded()
18+
19+
func assertContentSize(
20+
_ contentSize: CGSize,
21+
expected: CGSize? = nil,
22+
file: StaticString = #filePath,
23+
line: UInt = #line
24+
) {
25+
let state = State(width: contentSize.width, height: contentSize.height, axes: axes)
26+
let screen = TestScreen(model: .constant(state: state))
27+
screen.update(viewController: viewController, with: .empty)
28+
29+
viewController.view.layoutIfNeeded()
30+
let pcs = viewController.preferredContentSize
31+
32+
XCTAssertEqual(
33+
pcs,
34+
expected ?? contentSize,
35+
"Axes: \(axes.testDescription)",
36+
file: file,
37+
line: line
38+
)
39+
}
40+
41+
assertContentSize(CGSize(width: 20, height: 20))
42+
assertContentSize(CGSize(width: 40, height: 20))
43+
assertContentSize(CGSize(width: 20, height: 40))
44+
assertContentSize(
45+
CGSize(width: 100, height: 100),
46+
expected: CGSize(
47+
width: axes.contains(.horizontal) ? maxWidth : 100,
48+
height: axes.contains(.vertical) ? maxHeight : 100
49+
)
50+
)
51+
}
52+
53+
assertPreferredContentSize(in: [])
54+
assertPreferredContentSize(in: .horizontal)
55+
assertPreferredContentSize(in: .vertical)
56+
assertPreferredContentSize(in: [.horizontal, .vertical])
57+
}
58+
}
59+
60+
extension Axis.Set {
61+
var testDescription: String {
62+
switch self {
63+
case .horizontal: "[horizontal]"
64+
case .vertical: "[vertical]"
65+
case [.horizontal, .vertical]: "[horizontal, vertical]"
66+
default: "[]"
67+
}
68+
}
69+
}
70+
71+
@ObservableState
72+
private struct State {
73+
var width: CGFloat = 0
74+
var height: CGFloat = 0
75+
var axes: Axis.Set = []
76+
}
77+
78+
private struct TestWorkflow: Workflow {
79+
typealias Rendering = StateAccessor<State>
80+
81+
func makeInitialState() -> State {
82+
State()
83+
}
84+
85+
func render(state: State, context: RenderContext<TestWorkflow>) -> Rendering {
86+
context.makeStateAccessor(state: state)
87+
}
88+
}
89+
90+
private struct TestScreen: ObservableScreen {
91+
typealias Model = StateAccessor<State>
92+
93+
var model: Model
94+
95+
var sizingOptions: SwiftUIScreenSizingOptions = .preferredContentSize
96+
97+
@ViewBuilder
98+
static func makeView(store: Store<Model>) -> some View {
99+
TestView(store: store)
100+
}
101+
}
102+
103+
private struct TestView: View {
104+
var store: Store<StateAccessor<State>>
105+
106+
var body: some View {
107+
WithPerceptionTracking {
108+
if store.axes.isEmpty {
109+
box
110+
} else {
111+
ScrollView(store.axes) {
112+
box
113+
}
114+
}
115+
}
116+
}
117+
118+
var box: some View {
119+
Color.red.frame(width: store.width, height: store.height)
120+
}
121+
}
122+
123+
#endif

0 commit comments

Comments
 (0)