Skip to content

Commit

Permalink
Support visionOS
Browse files Browse the repository at this point in the history
  • Loading branch information
mihai8804858 committed Jul 18, 2024
1 parent c097f95 commit 472017f
Show file tree
Hide file tree
Showing 181 changed files with 408 additions and 244 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ jobs:
strategy:
matrix:
xcode:
- "14.3.1"
- "15.3"

name: macOS 13 (Xcode ${{ matrix.xcode }})
runs-on: macos-13
name: macOS 14 (Xcode ${{ matrix.xcode }})
runs-on: macos-14
steps:
- uses: actions/checkout@v3
- name: Select Xcode ${{ matrix.xcode }}
Expand All @@ -28,7 +28,7 @@ jobs:
strategy:
matrix:
swift:
- "5.7"
- "5.9.1"

name: Ubuntu (Swift ${{ matrix.swift }})
runs-on: ubuntu-20.04
Expand Down
12 changes: 9 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ test-ios:
set -o pipefail && \
xcodebuild test \
-scheme SnapshotTesting \
-destination platform="iOS Simulator,name=iPhone 11 Pro Max,OS=13.3"
-destination platform="iOS Simulator,name=iPhone 15 Pro Max,OS=17.4"

test-swift:
swift test
Expand All @@ -25,7 +25,13 @@ test-tvos:
set -o pipefail && \
xcodebuild test \
-scheme SnapshotTesting \
-destination platform="tvOS Simulator,name=Apple TV 4K,OS=13.3"
-destination platform="tvOS Simulator,name=Apple TV 4K,OS=17.4"

test-visionos:
set -o pipefail && \
xcodebuild test \
-scheme SnapshotTesting \
-destination platform="visionOS Simulator,name=Apple Vision Pro,OS=1.1"

format:
swift format \
Expand All @@ -34,4 +40,4 @@ format:
--recursive \
./Package.swift ./Sources ./Tests

test-all: test-linux test-macos test-ios
test-all: test-linux test-macos test-ios test-visionos
3 changes: 2 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version:5.7
// swift-tools-version:5.9

import PackageDescription

Expand All @@ -9,6 +9,7 @@ let package = Package(
.macOS(.v10_15),
.tvOS(.v13),
.watchOS(.v6),
.visionOS(.v1),
],
products: [
.library(
Expand Down
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,7 @@ targets: [
collections from a single simulator.
- **First-class Xcode support.** Image differences are captured as XCTest attachments. Text
differences are rendered in inline error messages.
- **Supports any platform that supports Swift.** Write snapshot tests for iOS, Linux, macOS, and
tvOS.
- **Supports any platform that supports Swift.** Write snapshot tests for iOS, Linux, macOS, tvOS and visionOS.
- **SceneKit, SpriteKit, and WebKit support.** Most snapshot testing libraries don't support these
view subclasses.
- **`Codable` support**. Snapshot encodable data structures into their JSON and property list
Expand Down
2 changes: 1 addition & 1 deletion Sources/SnapshotTesting/AssertSnapshot.swift
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ public func verifySnapshot<Value, Format>(
let data = try Data(contentsOf: snapshotFileUrl)
let reference = snapshotting.diffing.fromData(data)

#if os(iOS) || os(tvOS)
#if os(iOS) || os(tvOS) || os(visionOS)
// If the image generation fails for the diffable part and the reference was empty, use the reference
if let localDiff = diffable as? UIImage,
let refImage = reference as? UIImage,
Expand Down
2 changes: 1 addition & 1 deletion Sources/SnapshotTesting/Common/Internal.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
typealias Image = NSImage
typealias ImageView = NSImageView
typealias View = NSView
#elseif os(iOS) || os(tvOS)
#elseif os(iOS) || os(tvOS) || os(visionOS)
import UIKit
typealias Image = UIImage
typealias ImageView = UIImageView
Expand Down
57 changes: 42 additions & 15 deletions Sources/SnapshotTesting/Common/View.swift
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
#if os(iOS) || os(macOS) || os(tvOS)
#if os(iOS) || os(macOS) || os(tvOS) || os(visionOS)
#if os(macOS)
import Cocoa
#endif
import SceneKit
import SpriteKit
#if os(iOS) || os(tvOS)
#if os(iOS) || os(tvOS) || os(visionOS)
import UIKit
#endif
#if os(iOS) || os(macOS)
#if os(iOS) || os(macOS) || os(visionOS)
import WebKit
#endif

#if os(iOS) || os(tvOS)
#if os(iOS) || os(tvOS) || os(visionOS)
public struct ViewImageConfig: Sendable {
public enum Orientation {
case landscape
Expand Down Expand Up @@ -499,6 +499,12 @@
size: .init(width: 3840, height: 2160),
traits: .init()
)
#elseif os(visionOS)
public static let visionPro = ViewImageConfig(
safeArea: .zero,
size: .init(width: 2700, height: 1360),
traits: .init()
)
#endif
}

Expand Down Expand Up @@ -804,6 +810,21 @@
)
#elseif os(tvOS)
// TODO
#elseif os(visionOS)
public static let visionPro = UITraitCollection(
traitsFrom: [
.init(userInterfaceIdiom: .vision),
.init(horizontalSizeClass: .regular),
.init(verticalSizeClass: .regular),
.init(displayScale: 2.0),
.init(userInterfaceStyle: .dark),
.init(layoutDirection: .leftToRight),
.init(forceTouchCapability: .unavailable),
.init(preferredContentSizeCategory: .large),
.init(accessibilityContrast: .normal),
.init(userInterfaceLevel: .base),
]
)
#endif
}
#endif
Expand All @@ -819,7 +840,7 @@
imageView.frame = view.frame
#if os(macOS)
view.superview?.addSubview(imageView, positioned: .above, relativeTo: view)
#elseif os(iOS) || os(tvOS)
#elseif os(iOS) || os(tvOS) || os(visionOS)
view.superview?.insertSubview(imageView, aboveSubview: view)
#endif
callback(imageView)
Expand Down Expand Up @@ -850,26 +871,26 @@
let cgImage = inWindow { skView.texture(from: skView.scene!)!.cgImage() }
#if os(macOS)
let image = Image(cgImage: cgImage, size: skView.bounds.size)
#elseif os(iOS) || os(tvOS)
#elseif os(iOS) || os(tvOS) || os(visionOS)
let image = Image(cgImage: cgImage)
#endif
return Async(value: image)
} else {
fatalError("Taking SKView snapshots requires macOS 10.11 or greater")
}
}
#if os(iOS) || os(macOS)
#if os(iOS) || os(macOS) || os(visionOS)
if let wkWebView = self as? WKWebView {
return Async<Image> { callback in
let work = {
if #available(iOS 11.0, macOS 10.13, *) {
if #available(iOS 11.0, macOS 10.13, visionOS 1.0, *) {
inWindow {
guard wkWebView.frame.width != 0, wkWebView.frame.height != 0 else {
callback(Image())
return
}
let configuration = WKSnapshotConfiguration()
if #available(iOS 13, macOS 10.15, *) {
if #available(iOS 13, macOS 10.15, visionOS 1.0, *) {
configuration.afterScreenUpdates = false
}
wkWebView.takeSnapshot(with: configuration) { image, _ in
Expand All @@ -879,6 +900,8 @@
} else {
#if os(iOS)
fatalError("Taking WKWebView snapshots requires iOS 11.0 or greater")
#elseif os(visionOS)
fatalError("Taking WKWebView snapshots requires visionOS 1.0 or greater")
#elseif os(macOS)
fatalError("Taking WKWebView snapshots requires macOS 10.13 or greater")
#endif
Expand All @@ -903,7 +926,7 @@
#endif
return nil
}
#if os(iOS) || os(tvOS)
#if os(iOS) || os(tvOS) || os(visionOS)
func asImage() -> Image {
let renderer = UIGraphicsImageRenderer(bounds: bounds)
return renderer.image { rendererContext in
Expand All @@ -913,7 +936,7 @@
#endif
}

#if os(iOS) || os(tvOS)
#if os(iOS) || os(tvOS) || os(visionOS)
extension UIApplication {
static var sharedIfAvailable: UIApplication? {
let sharedSelector = NSSelectorFromString("sharedApplication")
Expand Down Expand Up @@ -1011,7 +1034,7 @@

func renderer(bounds: CGRect, for traits: UITraitCollection) -> UIGraphicsImageRenderer {
let renderer: UIGraphicsImageRenderer
if #available(iOS 11.0, tvOS 11.0, *) {
if #available(iOS 11.0, tvOS 11.0, visionOS 1.0, *) {
renderer = UIGraphicsImageRenderer(bounds: bounds, format: .init(for: traits))
} else {
renderer = UIGraphicsImageRenderer(bounds: bounds)
Expand Down Expand Up @@ -1076,10 +1099,14 @@

private func getKeyWindow() -> UIWindow? {
var window: UIWindow?
if #available(iOS 13.0, *) {
if #available(iOS 13.0, visionOS 1.0, *) {
window = UIApplication.sharedIfAvailable?.windows.first { $0.isKeyWindow }
} else {
window = UIApplication.sharedIfAvailable?.keyWindow
#if os(visionOS)
window = UIApplication.sharedIfAvailable?.windows.first { $0.isKeyWindow }
#else
window = UIApplication.sharedIfAvailable?.keyWindow
#endif
}
return window
}
Expand Down Expand Up @@ -1112,7 +1139,7 @@
fatalError("init(coder:) has not been implemented")
}

@available(iOS 11.0, *)
@available(iOS 11.0, visionOS 1.0, *)
override var safeAreaInsets: UIEdgeInsets {
#if os(iOS)
let removeTopInset =
Expand Down
2 changes: 1 addition & 1 deletion Sources/SnapshotTesting/Snapshotting/Any.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ extension Snapshotting where Format == String {
}
}

@available(macOS 10.13, watchOS 4.0, tvOS 11.0, *)
@available(macOS 10.13, watchOS 4.0, tvOS 11.0, iOS 11.0, visionOS 1.0, *)
extension Snapshotting where Format == String {
/// A snapshot strategy for comparing any structure based on their JSON representation.
public static var json: Snapshotting {
Expand Down
2 changes: 1 addition & 1 deletion Sources/SnapshotTesting/Snapshotting/CALayer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
}
}
}
#elseif os(iOS) || os(tvOS)
#elseif os(iOS) || os(tvOS) || os(visionOS)
import UIKit

extension Snapshotting where Value == CALayer, Format == UIImage {
Expand Down
8 changes: 4 additions & 4 deletions Sources/SnapshotTesting/Snapshotting/CGPath.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
}
}
}
#elseif os(iOS) || os(tvOS)
#elseif os(iOS) || os(tvOS) || os(visionOS)
import UIKit

extension Snapshotting where Value == CGPath, Format == UIImage {
Expand All @@ -75,7 +75,7 @@
).pullback { path in
let bounds = path.boundingBoxOfPath
let format: UIGraphicsImageRendererFormat
if #available(iOS 11.0, tvOS 11.0, *) {
if #available(iOS 11.0, tvOS 11.0, visionOS 1.0, *) {
format = UIGraphicsImageRendererFormat.preferred()
} else {
format = UIGraphicsImageRendererFormat.default()
Expand All @@ -91,8 +91,8 @@
}
#endif

#if os(macOS) || os(iOS) || os(tvOS)
@available(iOS 11.0, OSX 10.13, tvOS 11.0, *)
#if os(macOS) || os(iOS) || os(tvOS) || os(visionOS)
@available(iOS 11.0, OSX 10.13, tvOS 11.0, visionOS 1.0, *)
extension Snapshotting where Value == CGPath, Format == String {
/// A snapshot strategy for comparing bezier paths based on element descriptions.
public static var elementsDescription: Snapshotting {
Expand Down
2 changes: 1 addition & 1 deletion Sources/SnapshotTesting/Snapshotting/Encodable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ extension Snapshotting where Value: Encodable, Format == String {
/// "name" : "Blobby"
/// }
/// ```
@available(iOS 11.0, macOS 10.13, tvOS 11.0, watchOS 4.0, *)
@available(iOS 11.0, macOS 10.13, tvOS 11.0, watchOS 4.0, visionOS 1.0, *)
public static var json: Snapshotting {
let encoder = JSONEncoder()
encoder.outputFormatting = [.prettyPrinted, .sortedKeys]
Expand Down
6 changes: 3 additions & 3 deletions Sources/SnapshotTesting/Snapshotting/SceneKit.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#if os(iOS) || os(macOS) || os(tvOS)
#if os(iOS) || os(macOS) || os(tvOS) || os(visionOS)
import SceneKit
#if os(macOS)
import Cocoa
#elseif os(iOS) || os(tvOS)
#elseif os(iOS) || os(tvOS) || os(visionOS)
import UIKit
#endif

Expand All @@ -23,7 +23,7 @@
return .scnScene(precision: precision, perceptualPrecision: perceptualPrecision, size: size)
}
}
#elseif os(iOS) || os(tvOS)
#elseif os(iOS) || os(tvOS) || os(visionOS)
extension Snapshotting where Value == SCNScene, Format == UIImage {
/// A snapshot strategy for comparing SceneKit scenes based on pixel equality.
///
Expand Down
6 changes: 3 additions & 3 deletions Sources/SnapshotTesting/Snapshotting/SpriteKit.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#if os(iOS) || os(macOS) || os(tvOS)
#if os(iOS) || os(macOS) || os(tvOS) || os(visionOS)
import SpriteKit
#if os(macOS)
import Cocoa
#elseif os(iOS) || os(tvOS)
#elseif os(iOS) || os(tvOS) || os(visionOS)
import UIKit
#endif

Expand All @@ -23,7 +23,7 @@
return .skScene(precision: precision, perceptualPrecision: perceptualPrecision, size: size)
}
}
#elseif os(iOS) || os(tvOS)
#elseif os(iOS) || os(tvOS) || os(visionOS)
extension Snapshotting where Value == SKScene, Format == UIImage {
/// A snapshot strategy for comparing SpriteKit scenes based on pixel equality.
///
Expand Down
8 changes: 4 additions & 4 deletions Sources/SnapshotTesting/Snapshotting/SwiftUIView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

/// The size constraint for a snapshot (similar to `PreviewLayout`).
public enum SwiftUISnapshotLayout {
#if os(iOS) || os(tvOS)
#if os(iOS) || os(tvOS) || os(visionOS)
/// Center the view in a device container described by`config`.
case device(config: ViewImageConfig)
#endif
Expand All @@ -14,8 +14,8 @@
case sizeThatFits
}

#if os(iOS) || os(tvOS)
@available(iOS 13.0, tvOS 13.0, *)
#if os(iOS) || os(tvOS) || os(visionOS)
@available(iOS 13.0, tvOS 13.0, visionOS 1.0, *)
extension Snapshotting where Value: SwiftUI.View, Format == UIImage {

/// A snapshot strategy for comparing SwiftUI Views based on pixel equality.
Expand Down Expand Up @@ -48,7 +48,7 @@
let config: ViewImageConfig

switch layout {
#if os(iOS) || os(tvOS)
#if os(iOS) || os(tvOS) || os(visionOS)
case let .device(config: deviceConfig):
config = deviceConfig
#endif
Expand Down
Loading

0 comments on commit 472017f

Please sign in to comment.