diff --git a/Sources/SnapshotTesting/Snapshotting/UIView.swift b/Sources/SnapshotTesting/Snapshotting/UIView.swift index d2ed6e0f5..cb50fa649 100644 --- a/Sources/SnapshotTesting/Snapshotting/UIView.swift +++ b/Sources/SnapshotTesting/Snapshotting/UIView.swift @@ -34,6 +34,43 @@ extension Snapshotting where Value == UIView, Format == UIImage { ) } } + + /// A snapshot strategy for comparing views based on pixel equality. + /// + /// - Parameters: + /// - config: A set of device configuration settings. + /// - precision: The percentage of pixels that must match. + /// - perceptualPrecision: The percentage a pixel must match the source pixel to be considered a match. [98-99% mimics the precision of the human eye.](http://zschuessler.github.io/DeltaE/learn/#toc-defining-delta-e) + /// - targetSize: The size that you prefer for the view. To obtain a view that is as small as possible, specify the constant [layoutFittingCompressedSize](https://developer.apple.com/documentation/uikit/uiview/1622568-layoutfittingcompressedsize). To obtain a view that is as large as possible, specify the constant [layoutFittingExpandedSize](https://developer.apple.com/documentation/uikit/uiview/1622532-layoutfittingexpandedsize). + /// - horizontalFittingPriority: The priority for horizontal constraints. Specify [fittingSizeLevel](https://developer.apple.com/documentation/uikit/uilayoutpriority/1622248-fittingsizelevel) to get a width that is as close as possible to the width value of `targetSize`. + /// - verticalFittingPriority: The priority for vertical constraints. Specify [fittingSizeLevel](https://developer.apple.com/documentation/uikit/uilayoutpriority/1622248-fittingsizelevel) to get a height that is as close as possible to the height value of `targetSize`. + /// - traits: A trait collection override. + public static func image( + drawHierarchyInKeyWindow: Bool = false, + precision: Float = 1, + perceptualPrecision: Float = 1, + targetSize: CGSize, + horizontalFittingPriority: UILayoutPriority, + verticalFittingPriority: UILayoutPriority, + traits: UITraitCollection = .init() + ) + -> Snapshotting { + + return SimplySnapshotting.image(precision: precision, perceptualPrecision: perceptualPrecision, scale: traits.displayScale).asyncPullback { view in + let size = view.systemLayoutSizeFitting( + targetSize, + withHorizontalFittingPriority: horizontalFittingPriority, + verticalFittingPriority: verticalFittingPriority + ) + return snapshotView( + config: .init(safeArea: .zero, size: size, traits: .init()), + drawHierarchyInKeyWindow: drawHierarchyInKeyWindow, + traits: traits, + view: view, + viewController: .init() + ) + } + } } extension Snapshotting where Value == UIView, Format == String { diff --git a/Tests/SnapshotTestingTests/SnapshotTestingTests.swift b/Tests/SnapshotTestingTests/SnapshotTestingTests.swift index 570f24240..1172ead8e 100644 --- a/Tests/SnapshotTestingTests/SnapshotTestingTests.swift +++ b/Tests/SnapshotTestingTests/SnapshotTestingTests.swift @@ -853,6 +853,23 @@ final class SnapshotTestingTests: XCTestCase { assertSnapshot(matching: view, as: .recursiveDescription) #endif } + + func testSystemLayoutFittingWithView() { + #if os(iOS) + let label = UILabel() + label.text = "What's the point?" + label.numberOfLines = .zero + + assertSnapshot( + matching: label, + as: .image( + targetSize: CGSize(width: 50, height: UIView.layoutFittingExpandedSize.height), + horizontalFittingPriority: .required, + verticalFittingPriority: .fittingSizeLevel + ) + ) + #endif + } func testUIViewControllerLifeCycle() { #if os(iOS) diff --git a/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testSystemLayoutFittingWithView.1.png b/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testSystemLayoutFittingWithView.1.png new file mode 100644 index 000000000..301923f2a Binary files /dev/null and b/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testSystemLayoutFittingWithView.1.png differ