Skip to content

Commit 77d4723

Browse files
authored
Merge pull request #9 from ecunha-ta/add_swiftview_heic
Adds SwiftUIView HEIC support
2 parents 57d730e + c71b0f1 commit 77d4723

8 files changed

+165
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
//
2+
// SwiftUIView.swift
3+
//
4+
// Created by Emanuel Cunha on 20/05/2023
5+
//
6+
7+
#if canImport(SwiftUI)
8+
import Foundation
9+
import SwiftUI
10+
@testable import SnapshotTesting
11+
12+
#if os(iOS) || os(tvOS)
13+
@available(iOS 13.0, tvOS 13.0, *)
14+
public extension Snapshotting where Value: SwiftUI.View, Format == UIImage {
15+
16+
/// A snapshot strategy for comparing views based on pixel equality.
17+
static var imageHEIC: Snapshotting {
18+
return .imageHEIC()
19+
}
20+
21+
/// A snapshot strategy for comparing SwiftUI Views based on pixel equality.
22+
///
23+
/// - Parameters:
24+
/// - drawHierarchyInKeyWindow: Utilize the simulator's key window in order to render `UIAppearance` and `UIVisualEffect`s. This option requires a host application for your tests and will _not_ work for framework test targets.
25+
/// - precision: The percentage of pixels that must match.
26+
/// - 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)
27+
/// - layout: A view layout override.
28+
/// - traits: A trait collection override.
29+
/// - compressionQuality: The desired compression quality to use when writing to an image destination.
30+
static func imageHEIC(
31+
drawHierarchyInKeyWindow: Bool = false,
32+
precision: Float = 1,
33+
perceptualPrecision: Float = 1,
34+
layout: SwiftUISnapshotLayout = .sizeThatFits,
35+
traits: UITraitCollection = .init(),
36+
compressionQuality: CompressionQuality = .lossless
37+
) -> Snapshotting {
38+
let config: ViewImageConfig
39+
40+
switch layout {
41+
#if os(iOS) || os(tvOS)
42+
case let .device(config: deviceConfig):
43+
config = deviceConfig
44+
#endif
45+
case .sizeThatFits:
46+
config = .init(safeArea: .zero, size: nil, traits: traits)
47+
case let .fixed(width: width, height: height):
48+
let size = CGSize(width: width, height: height)
49+
config = .init(safeArea: .zero, size: size, traits: traits)
50+
}
51+
52+
return SimplySnapshotting.imageHEIC(
53+
precision: precision,
54+
perceptualPrecision: perceptualPrecision,
55+
scale: traits.displayScale,
56+
compressionQuality: compressionQuality
57+
).asyncPullback { view in
58+
var config = config
59+
60+
let controller: UIViewController
61+
62+
if config.size != nil {
63+
controller = UIHostingController.init(
64+
rootView: view
65+
)
66+
} else {
67+
let hostingController = UIHostingController.init(rootView: view)
68+
69+
let maxSize = CGSize(width: 0.0, height: 0.0)
70+
config.size = hostingController.sizeThatFits(in: maxSize)
71+
72+
controller = hostingController
73+
}
74+
75+
return snapshotView(
76+
config: config.size.map { .init(safeArea: config.safeArea, size: $0, traits: config.traits) } ?? config,
77+
drawHierarchyInKeyWindow: false,
78+
traits: traits,
79+
view: controller.view,
80+
viewController: controller
81+
)
82+
}
83+
}
84+
}
85+
#endif
86+
#endif

Tests/SnapshotTestingHEICTests/SnapshotTestingHEICTests.swift

+56
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Use iPhone 8 for tests
22
import XCTest
33
import SnapshotTesting
4+
import SwiftUI
5+
46
@testable import SnapshotTestingHEIC
57

68
final class SnapshotTestingHEICTests: XCTestCase {
@@ -19,6 +21,7 @@ final class SnapshotTestingHEICTests: XCTestCase {
1921
super.tearDown()
2022
}
2123

24+
// // ViewController Tests
2225
func test_without_HEIC() {
2326
assertSnapshot(matching: sut, as: .image(on: .iPadPro12_9))
2427
}
@@ -42,6 +45,59 @@ final class SnapshotTestingHEICTests: XCTestCase {
4245
assertSnapshot(matching: sut, as: .imageHEIC(on: .iPadPro12_9,
4346
compressionQuality: 0.75))
4447
}
48+
49+
// SwiftUI Tests
50+
51+
func test_swiftui_without_HEIC() {
52+
let view: some SwiftUI.View = SwiftUIView_Previews.previews
53+
54+
assertSnapshot(matching: view,
55+
as: .imageHEIC(layout: .device(config: .iPadPro12_9)))
56+
}
57+
58+
func test_swiftui_HEIC_compressionQuality_lossless() {
59+
let view: some SwiftUI.View = SwiftUIView_Previews.previews
60+
61+
assertSnapshot(matching: view,
62+
as: .imageHEIC(
63+
layout: .device(config: .iPadPro12_9),
64+
compressionQuality: .lossless
65+
)
66+
)
67+
}
68+
69+
func test_swiftui_HEIC_compressionQuality_medium() {
70+
let view: some SwiftUI.View = SwiftUIView_Previews.previews
71+
72+
assertSnapshot(matching: view,
73+
as: .imageHEIC(
74+
layout: .device(config: .iPadPro12_9),
75+
compressionQuality: .medium
76+
)
77+
)
78+
}
79+
80+
func test_swiftui_HEIC_compressionQuality_maximum() {
81+
let view: some SwiftUI.View = SwiftUIView_Previews.previews
82+
83+
assertSnapshot(matching: view,
84+
as: .imageHEIC(
85+
layout: .device(config: .iPadPro12_9),
86+
compressionQuality: .maximum
87+
)
88+
)
89+
}
90+
91+
func test_swiftui_HEIC_compressionQuality_custom() {
92+
let view: some SwiftUI.View = SwiftUIView_Previews.previews
93+
94+
assertSnapshot(matching: view,
95+
as: .imageHEIC(
96+
layout: .device(config: .iPadPro12_9),
97+
compressionQuality: 0.75
98+
)
99+
)
100+
}
45101
#endif
46102

47103

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//
2+
// SwiftUIView.swift
3+
//
4+
//
5+
// Created by Emanuel Cunha on 19/05/2023.
6+
//
7+
8+
#if os(iOS) || os(tvOS)
9+
import SwiftUI
10+
11+
struct SwiftUIView: View {
12+
var body: some View {
13+
Text("Test SnapshotTestingHEIC SwiftUI")
14+
.font(.system(size: 64))
15+
}
16+
}
17+
18+
struct SwiftUIView_Previews: PreviewProvider {
19+
static var previews: some View {
20+
SwiftUIView()
21+
}
22+
}
23+
#endif

0 commit comments

Comments
 (0)