doordash-oss / swiftui-preview-snapshots

Apache License 2.0
154 stars 7 forks source link

Feature Request: Custom Snapshot Directory Support #9

Closed mackoj closed 5 months ago

mackoj commented 5 months ago

Hi @jflan-dd,

Description:

The library currently lacks the ability to specify a custom snapshot directory. This feature would be incredibly useful, particularly in scenarios where tests are distributed across various folders, as it allows for centralizing all snapshots into a designated directory at the root of the tests folder.

Proposed Solution:

Introducing an endpoint within the swift-snapshot-testing library, such as verifySnapshot, would enable users to customize the snapshot directory. By providing this capability, users could seamlessly integrate the library into their projects while maintaining organizational consistency.

Request:

Could the API be extended to incorporate the verifySnapshot functionality alongside or instead of assertSnapshot?

Solution

For the moment I added this to my project. This code will allow me using custom snapshot directory but in order to make it work. I need a .snapshotName(prefix:) to be public.

import PreviewSnapshots
import SnapshotTesting
import SwiftUI
import XCTest

// MARK: - PreviewSnapshots Customisation
extension PreviewSnapshots {
  public func assertSnapshots<Format>(
    as snapshotting: Snapshotting<AnyView, Format>,
    named name: String? = nil,
    record recording: Bool = false,
    snapshotDirectory: String? = nil,
    file: StaticString = #file,
    testName: String = #function,
    line: UInt = #line
  ) {
    for configuration in configurations {
      customAssertSnapshot(
        matching: configure(configuration.state),
        as: snapshotting,
        named: configuration.snapshotName(prefix: name),
        record: recording,
        snapshotDirectory: snapshotDirectory,
        file: file,
        testName: testName,
        line: line
      )
    }
  }
}

extension PreviewSnapshots.Configuration {
    /// Construct a snapshot name based on the configuration name and an optional prefix.
    func snapshotName(prefix: String?) -> String {
        guard let prefix = prefix else { return name }
        return "\(prefix)-\(name)"
    }
}

// MARK: - SnapshotTesting Customisation
public func customAssertSnapshot<Value, Format>(
  matching value: @autoclosure () throws -> Value,
  as snapshotting: Snapshotting<Value, Format>,
  named name: String? = nil,
  record recording: Bool = false,
  snapshotDirectory: String? = nil,
  timeout: TimeInterval = 5,
  file: StaticString = #file,
  testName: String = #function,
  line: UInt = #line
) {
  let failure = verifySnapshot(
    matching: try value(),
    as: snapshotting,
    named: name,
    record: recording,
    snapshotDirectory: snapshotDirectory,
    timeout: timeout,
    file: file,
    testName: testName
  )
  guard let message = failure else { return }
  XCTFail(message, file: file, line: line)
}

Thank you!

mackoj commented 5 months ago

The only missing part is https://github.com/doordash-oss/swiftui-preview-snapshots/pull/8.

jflan-dd commented 5 months ago

There was good discussion in the linked PR. In the end the current plan is to not add specific snapshot directory support since in the upstream swift-snapshot-testing consumers also have to manually use/wrap verifySnapshot in order to use custom directories, and the for loop over the configurations is pretty trivial to write.

https://github.com/doordash-oss/swiftui-preview-snapshots/pull/8#issuecomment-1934671492