├── .dockerignore ├── .editorconfig ├── .github ├── CODE_OF_CONDUCT.md ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── question.md ├── kaleidoscope-diff.png ├── snapshot-test-1.png ├── snapshot-test.png └── workflows │ ├── ci.yml │ ├── format.yml │ └── release.yml ├── .gitignore ├── .spi.yml ├── CONTRIBUTING.md ├── LICENSE ├── Makefile ├── Package.resolved ├── Package.swift ├── Package@swift-6.0.swift ├── README.md ├── Sources ├── InlineSnapshotTesting │ ├── AssertInlineSnapshot.swift │ ├── Documentation.docc │ │ └── InlineSnapshotTesting.md │ └── Exports.swift ├── SnapshotTesting │ ├── AssertSnapshot.swift │ ├── Async.swift │ ├── Common │ │ ├── Internal.swift │ │ ├── PlistEncoder.swift │ │ ├── String+SpecialCharacters.swift │ │ ├── View.swift │ │ └── XCTAttachment.swift │ ├── Diff.swift │ ├── Diffing.swift │ ├── Documentation.docc │ │ ├── Articles │ │ │ ├── CustomStrategies.md │ │ │ ├── IntegratingWithTestFrameworks.md │ │ │ └── MigrationGuides │ │ │ │ ├── MigratingTo1.17.md │ │ │ │ └── MigrationGuides.md │ │ ├── Extensions │ │ │ ├── AssertSnapshot.md │ │ │ ├── Deprecations │ │ │ │ ├── SnapshotTestingDeprecations.md │ │ │ │ ├── diffTool-property-deprecation.md │ │ │ │ └── isRecording-property-deprecation.md │ │ │ ├── SnapshotsTrait.md │ │ │ ├── Snapshotting.md │ │ │ └── WithSnapshotTesting.md │ │ └── SnapshotTesting.md │ ├── Extensions │ │ └── Wait.swift │ ├── Internal │ │ ├── Deprecations.swift │ │ └── RecordIssue.swift │ ├── SnapshotTestingConfiguration.swift │ ├── SnapshotsTestTrait.swift │ ├── Snapshotting.swift │ └── Snapshotting │ │ ├── Any.swift │ │ ├── CALayer.swift │ │ ├── CGPath.swift │ │ ├── CaseIterable.swift │ │ ├── Data.swift │ │ ├── Encodable.swift │ │ ├── NSBezierPath.swift │ │ ├── NSImage.swift │ │ ├── NSView.swift │ │ ├── NSViewController.swift │ │ ├── SceneKit.swift │ │ ├── SpriteKit.swift │ │ ├── String.swift │ │ ├── SwiftUIView.swift │ │ ├── UIBezierPath.swift │ │ ├── UIImage.swift │ │ ├── UIView.swift │ │ ├── UIViewController.swift │ │ └── URLRequest.swift └── SnapshotTestingCustomDump │ └── CustomDump.swift └── Tests ├── InlineSnapshotTestingTests ├── AssertInlineSnapshotSwiftTests.swift ├── CustomDumpTests.swift ├── InlineSnapshotTesting.xctestplan ├── InlineSnapshotTestingTests.swift └── Internal │ ├── BaseSuite.swift │ └── BaseTestCase.swift └── SnapshotTestingTests ├── AssertSnapshotSwiftTests.swift ├── DeprecationTests.swift ├── Internal ├── BaseSuite.swift ├── BaseTestCase.swift └── TestHelpers.swift ├── RecordTests.swift ├── SnapshotTestingTests.swift ├── SnapshotsTraitTests.swift ├── SwiftTestingTests.swift ├── WaitTests.swift ├── WithSnapshotTestingTests.swift ├── __Fixtures__ ├── earth.png ├── pointfree.html └── testImagePrecision.reference.png └── __Snapshots__ ├── AssertSnapshotSwiftTests ├── dump.1.txt └── dump.2.txt ├── SnapshotTestingTests ├── testAny.1.txt ├── testAnyAsJson.1.json ├── testAnySnapshotStringConvertible.character.txt ├── testAnySnapshotStringConvertible.data.txt ├── testAnySnapshotStringConvertible.date.txt ├── testAnySnapshotStringConvertible.nsobject.txt ├── testAnySnapshotStringConvertible.string.txt ├── testAnySnapshotStringConvertible.substring.txt ├── testAnySnapshotStringConvertible.url.txt ├── testAssertMultipleSnapshot.1.png ├── testAssertMultipleSnapshot.2.png ├── testAssertMultipleSnapshot.iPad-image.png ├── testAssertMultipleSnapshot.iPhoneSE-image.png ├── testAutolayout.1.png ├── testCALayer.1.png ├── testCALayerWithGradient.1.png ├── testCGPath.iOS.png ├── testCGPath.iOS.txt ├── testCGPath.macOS.png ├── testCGPath.macOS.txt ├── testCGPath.tvOS.png ├── testCGPath.tvOS.txt ├── testCaseIterable.1.csv ├── testCollectionViewsWithMultipleScreenSizes.ipad.png ├── testCollectionViewsWithMultipleScreenSizes.iphone8.png ├── testCollectionViewsWithMultipleScreenSizes.iphoneMax.png ├── testCollectionViewsWithMultipleScreenSizes.iphoneSe.png ├── testData.1 ├── testDeterministicDictionaryAndSetSnapshots.1.txt ├── testEmbeddedWebView.ios.png ├── testEncodable.1.json ├── testEncodable.2.plist ├── testImagePrecision.exact.png ├── testImagePrecision.perceptual.png ├── testMixedViews.ios.png ├── testMixedViews.macos.png ├── testMultipleSnapshots.1.txt ├── testMultipleSnapshots.2.txt ├── testNSBezierPath.macOS.png ├── testNSBezierPath.macOS.txt ├── testNSView.1.png ├── testNSView.2.txt ├── testNSViewWithLayer.1.png ├── testNSViewWithLayer.2.txt ├── testNamedAssertion.named.txt ├── testPrecision.ios.png ├── testPrecision.macos.png ├── testPrecision.tvos.png ├── testRecursion.1.txt ├── testRecursion.2.txt ├── testSCNView.ios.png ├── testSCNView.macos.png ├── testSCNView.tvos.png ├── testSKView.ios.png ├── testSKView.macos.png ├── testSKView.tvos.png ├── testSwiftUIView_iOS.1.png ├── testSwiftUIView_iOS.device.png ├── testSwiftUIView_iOS.fixed.png ├── testSwiftUIView_iOS.size-that-fits.png ├── testSwiftUIView_tvOS.1.png ├── testSwiftUIView_tvOS.device.png ├── testSwiftUIView_tvOS.fixed.png ├── testSwiftUIView_tvOS.size-that-fits.png ├── testTableViewController.1.png ├── testTraits.ipad-10-2-33-split-portrait.png ├── testTraits.ipad-10-2-50-split-landscape.png ├── testTraits.ipad-10-2-66-split-landscape.png ├── testTraits.ipad-10-2-66-split-portrait.png ├── testTraits.ipad-10-2-alternative.png ├── testTraits.ipad-10-2-split-landscape.png ├── testTraits.ipad-10-2.png ├── testTraits.ipad-10-2.txt ├── testTraits.ipad-9-7-33-split-landscape.png ├── testTraits.ipad-9-7-33-split-portrait.png ├── testTraits.ipad-9-7-50-split-landscape.png ├── testTraits.ipad-9-7-66-split-landscape.png ├── testTraits.ipad-9-7-66-split-portrait.png ├── testTraits.ipad-9-7-alternative.png ├── testTraits.ipad-9-7.png ├── testTraits.ipad-9-7.txt ├── testTraits.ipad-mini-33-split-landscape.png ├── testTraits.ipad-mini-33-split-portrait.png ├── testTraits.ipad-mini-50-split-landscape.png ├── testTraits.ipad-mini-66-split-landscape.png ├── testTraits.ipad-mini-66-split-portrait.png ├── testTraits.ipad-mini-alternative.png ├── testTraits.ipad-mini.png ├── testTraits.ipad-mini.txt ├── testTraits.ipad-pro-10-5-alternative.png ├── testTraits.ipad-pro-10-5.png ├── testTraits.ipad-pro-10-5.txt ├── testTraits.ipad-pro-10inch-33-split-landscape.png ├── testTraits.ipad-pro-10inch-33-split-portrait.png ├── testTraits.ipad-pro-10inch-50-split-landscape.png ├── testTraits.ipad-pro-10inch-66-split-landscape.png ├── testTraits.ipad-pro-10inch-66-split-portrait.png ├── testTraits.ipad-pro-11-alternative.png ├── testTraits.ipad-pro-11.png ├── testTraits.ipad-pro-11.txt ├── testTraits.ipad-pro-11inch-33-split-landscape.png ├── testTraits.ipad-pro-11inch-33-split-portrait.png ├── testTraits.ipad-pro-11inch-50-split-landscape.png ├── testTraits.ipad-pro-11inch-66-split-landscape.png ├── testTraits.ipad-pro-11inch-66-split-portrait.png ├── testTraits.ipad-pro-12-9-alternative.png ├── testTraits.ipad-pro-12-9.png ├── testTraits.ipad-pro-12-9.txt ├── testTraits.ipad-pro-12inch-33-split-landscape.png ├── testTraits.ipad-pro-12inch-33-split-portrait.png ├── testTraits.ipad-pro-12inch-50-split-landscape.png ├── testTraits.ipad-pro-12inch-66-split-landscape.png ├── testTraits.ipad-pro-12inch-66-split-portrait.png ├── testTraits.iphone-8-alternative.png ├── testTraits.iphone-8-plus-alternative.png ├── testTraits.iphone-8-plus.png ├── testTraits.iphone-8-plus.txt ├── testTraits.iphone-8.png ├── testTraits.iphone-8.txt ├── testTraits.iphone-se-accessibility-extra-extra-extra-large.png ├── testTraits.iphone-se-accessibility-extra-extra-large.png ├── testTraits.iphone-se-accessibility-extra-large.png ├── testTraits.iphone-se-accessibility-large.png ├── testTraits.iphone-se-accessibility-medium.png ├── testTraits.iphone-se-alternative.png ├── testTraits.iphone-se-extra-extra-extra-large.png ├── testTraits.iphone-se-extra-extra-large.png ├── testTraits.iphone-se-extra-large.png ├── testTraits.iphone-se-extra-small.png ├── testTraits.iphone-se-large.png ├── testTraits.iphone-se-medium.png ├── testTraits.iphone-se-small.png ├── testTraits.iphone-se.png ├── testTraits.iphone-se.txt ├── testTraits.iphone-x-alternative.png ├── testTraits.iphone-x.png ├── testTraits.iphone-x.txt ├── testTraits.iphone-xr-alternative.png ├── testTraits.iphone-xr.png ├── testTraits.iphone-xr.txt ├── testTraits.iphone-xs-max-alternative.png ├── testTraits.iphone-xs-max.png ├── testTraits.iphone-xs-max.txt ├── testTraits.tv.png ├── testTraits.tv4k.png ├── testTraitsEmbeddedInTabNavigation.ipad-10-2-alternative.png ├── testTraitsEmbeddedInTabNavigation.ipad-10-2.png ├── testTraitsEmbeddedInTabNavigation.ipad-9-7-alternative.png ├── testTraitsEmbeddedInTabNavigation.ipad-9-7.png ├── testTraitsEmbeddedInTabNavigation.ipad-mini-alternative.png ├── testTraitsEmbeddedInTabNavigation.ipad-mini.png ├── testTraitsEmbeddedInTabNavigation.ipad-pro-10-5-alternative.png ├── testTraitsEmbeddedInTabNavigation.ipad-pro-10-5.png ├── testTraitsEmbeddedInTabNavigation.ipad-pro-11-alternative.png ├── testTraitsEmbeddedInTabNavigation.ipad-pro-11.png ├── testTraitsEmbeddedInTabNavigation.ipad-pro-12-9-alternative.png ├── testTraitsEmbeddedInTabNavigation.ipad-pro-12-9.png ├── testTraitsEmbeddedInTabNavigation.iphone-8-alternative.png ├── testTraitsEmbeddedInTabNavigation.iphone-8-plus-alternative.png ├── testTraitsEmbeddedInTabNavigation.iphone-8-plus.png ├── testTraitsEmbeddedInTabNavigation.iphone-8.png ├── testTraitsEmbeddedInTabNavigation.iphone-se-alternative.png ├── testTraitsEmbeddedInTabNavigation.iphone-se.png ├── testTraitsEmbeddedInTabNavigation.iphone-x-alternative.png ├── testTraitsEmbeddedInTabNavigation.iphone-x.png ├── testTraitsEmbeddedInTabNavigation.iphone-xr-alternative.png ├── testTraitsEmbeddedInTabNavigation.iphone-xr.png ├── testTraitsEmbeddedInTabNavigation.iphone-xs-max-alternative.png ├── testTraitsEmbeddedInTabNavigation.iphone-xs-max.png ├── testTraitsWithView.label-accessibility-extra-extra-extra-large.png ├── testTraitsWithView.label-accessibility-extra-extra-large.png ├── testTraitsWithView.label-accessibility-extra-large.png ├── testTraitsWithView.label-accessibility-large.png ├── testTraitsWithView.label-accessibility-medium.png ├── testTraitsWithView.label-extra-extra-extra-large.png ├── testTraitsWithView.label-extra-extra-large.png ├── testTraitsWithView.label-extra-large.png ├── testTraitsWithView.label-extra-small.png ├── testTraitsWithView.label-large.png ├── testTraitsWithView.label-medium.png ├── testTraitsWithView.label-small.png ├── testTraitsWithViewController.label-accessibility-extra-extra-extra-large.txt ├── testTraitsWithViewController.label-accessibility-extra-extra-large.txt ├── testTraitsWithViewController.label-accessibility-extra-large.txt ├── testTraitsWithViewController.label-accessibility-large.txt ├── testTraitsWithViewController.label-accessibility-medium.txt ├── testTraitsWithViewController.label-extra-extra-extra-large.txt ├── testTraitsWithViewController.label-extra-extra-large.txt ├── testTraitsWithViewController.label-extra-large.txt ├── testTraitsWithViewController.label-extra-small.txt ├── testTraitsWithViewController.label-large.txt ├── testTraitsWithViewController.label-medium.txt ├── testTraitsWithViewController.label-small.txt ├── testUIBezierPath.iOS.png ├── testUIBezierPath.iOS.txt ├── testUIBezierPath.tvOS.png ├── testUIBezierPath.tvOS.txt ├── testUIView.1.png ├── testUIView.2.txt ├── testUIViewControllerLifeCycle.1.png ├── testUIViewControllerLifeCycle.2.png ├── testURLRequest.get-curl.txt ├── testURLRequest.get-with-query-curl.txt ├── testURLRequest.get-with-query.txt ├── testURLRequest.get.txt ├── testURLRequest.head-curl.txt ├── testURLRequest.head.txt ├── testURLRequest.post-curl.txt ├── testURLRequest.post-json.txt ├── testURLRequest.post-with-json-curl.txt ├── testURLRequest.post-with-json.txt ├── testURLRequest.post.txt ├── testViewAgainstEmptyImage.notEmptyImage.png ├── testViewControllerHierarchy.1.txt ├── testViewWithZeroHeightOrWidth.noHeight.png ├── testViewWithZeroHeightOrWidth.noWidth-noHeight.png ├── testViewWithZeroHeightOrWidth.noWidth.png ├── testWebView.ios.png ├── testWebView.macos.png ├── testWebViewWithCancellingNavigationDelegate.ios.png ├── testWebViewWithCancellingNavigationDelegate.macos.png ├── testWebViewWithManipulatingNavigationDelegate.ios.png └── testWebViewWithManipulatingNavigationDelegate.macos.png ├── SwiftTestingTests ├── testSnapshot.1.txt ├── testSnapshot.snap.txt └── testSnapshotFailure.1.txt └── WaitTests └── testWait.1.txt /.dockerignore: -------------------------------------------------------------------------------- 1 | .git/ 2 | .build/ 3 | !.build/checkouts/ 4 | !.build/repositories/ 5 | !.build/workspace-state.json 6 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | indent_style = space 7 | indent_size = 2 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | -------------------------------------------------------------------------------- /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, caste, color, religion, or sexual 10 | identity and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the overall 26 | community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or advances of 31 | any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email address, 35 | without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | . 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series of 86 | actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or permanent 93 | ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within the 113 | community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.1, available at 119 | [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. 120 | 121 | Community Impact Guidelines were inspired by 122 | [Mozilla's code of conduct enforcement ladder][Mozilla CoC]. 123 | 124 | For answers to common questions about this code of conduct, see the FAQ at 125 | [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at 126 | [https://www.contributor-covenant.org/translations][translations]. 127 | 128 | [homepage]: https://www.contributor-covenant.org 129 | [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html 130 | [Mozilla CoC]: https://github.com/mozilla/diversity 131 | [FAQ]: https://www.contributor-covenant.org/faq 132 | [translations]: https://www.contributor-covenant.org/translations 133 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | Give a clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Zip up a project that reproduces the behavior and attach it by dragging it here. 15 | 16 | ```swift 17 | // And/or enter code that reproduces the behavior here. 18 | 19 | ``` 20 | 21 | **Expected behavior** 22 | Give a clear and concise description of what you expected to happen. 23 | 24 | **Screenshots** 25 | If applicable, add screenshots to help explain your problem. 26 | 27 | **Environment** 28 | - swift-snapshot-testing version [e.g. 1.9.0] 29 | - Xcode [e.g. 13.2] 30 | - Swift [e.g. 5.5] 31 | - OS: [e.g. iOS 15] 32 | 33 | **Additional context** 34 | Add any more context about the problem here. 35 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Question 3 | about: Have a question about SnapshotTesting? 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | SnapshotTesting uses GitHub issues for bugs. For more general discussion and help, please use [GitHub Discussions](https://github.com/pointfreeco/swift-snapshot-testing/discussions). 11 | -------------------------------------------------------------------------------- /.github/kaleidoscope-diff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/.github/kaleidoscope-diff.png -------------------------------------------------------------------------------- /.github/snapshot-test-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/.github/snapshot-test-1.png -------------------------------------------------------------------------------- /.github/snapshot-test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/.github/snapshot-test.png -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - "*" 10 | 11 | jobs: 12 | macos: 13 | strategy: 14 | matrix: 15 | xcode: 16 | - 15.4 17 | - '16.1' 18 | 19 | name: macOS 20 | runs-on: macos-14 21 | steps: 22 | - uses: actions/checkout@v3 23 | - name: Select Xcode ${{ matrix.xcode }} 24 | run: sudo xcode-select -s /Applications/Xcode_${{ matrix.xcode }}.app 25 | - name: Run tests 26 | run: make test-swift 27 | 28 | ubuntu: 29 | strategy: 30 | matrix: 31 | swift: 32 | - '5.9' 33 | 34 | container: swift:${{ matrix.swift }} 35 | name: Linux (Swift ${{ matrix.swift }}) 36 | runs-on: ubuntu-latest 37 | steps: 38 | - uses: actions/checkout@v4 39 | - run: swift test 40 | 41 | # windows: 42 | # strategy: 43 | # matrix: 44 | # swift: 45 | # - "5.9.1" 46 | 47 | # name: Windows (Swift ${{ matrix.swift }}) 48 | # runs-on: windows-latest 49 | 50 | # steps: 51 | # - uses: compnerd/gha-setup-swift@main 52 | # with: 53 | # branch: swift-${{ matrix.swift }}-release 54 | # tag: ${{ matrix.swift }}-RELEASE 55 | 56 | # - name: Set git to use LF 57 | # run: | 58 | # git config --global core.autocrlf false 59 | # git config --global core.eol lf 60 | 61 | # - uses: actions/checkout@v4 62 | # - run: swift build 63 | # - run: swift test 64 | 65 | android: 66 | strategy: 67 | matrix: 68 | swift: 69 | - "6.0.2" 70 | name: Android 71 | runs-on: ubuntu-latest 72 | steps: 73 | - uses: actions/checkout@v4 74 | - uses: skiptools/swift-android-action@v2 75 | with: 76 | swift-version: ${{ matrix.swift }} 77 | copy-files: ${GITHUB_WORKSPACE}/Tests/SnapshotTestingTests/__Snapshots__ 78 | -------------------------------------------------------------------------------- /.github/workflows/format.yml: -------------------------------------------------------------------------------- 1 | name: Format 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | concurrency: 9 | group: format-${{ github.ref }} 10 | cancel-in-progress: true 11 | 12 | jobs: 13 | swift_format: 14 | name: swift-format 15 | runs-on: macos-13 16 | steps: 17 | - uses: actions/checkout@v3 18 | - name: Xcode Select 19 | run: sudo xcode-select -s /Applications/Xcode_14.3.1.app 20 | - name: Install 21 | run: brew install swift-format 22 | - name: Format 23 | run: make format 24 | - uses: stefanzweifel/git-auto-commit-action@v4 25 | with: 26 | commit_message: Run swift-format 27 | branch: 'main' 28 | env: 29 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 30 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | on: 3 | release: 4 | types: [published] 5 | workflow_dispatch: 6 | jobs: 7 | project-channel: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Dump Github context 11 | env: 12 | GITHUB_CONTEXT: ${{ toJSON(github) }} 13 | run: echo "$GITHUB_CONTEXT" 14 | - name: Slack Notification on SUCCESS 15 | if: success() 16 | uses: tokorom/action-slack-incoming-webhook@main 17 | env: 18 | INCOMING_WEBHOOK_URL: ${{ secrets.SLACK_PROJECT_CHANNEL_WEBHOOK_URL }} 19 | with: 20 | text: swift-snapshot-testing ${{ github.event.release.tag_name }} has been released. 21 | blocks: | 22 | [ 23 | { 24 | "type": "header", 25 | "text": { 26 | "type": "plain_text", 27 | "text": "swift-snapshot-testing ${{ github.event.release.tag_name}}" 28 | } 29 | }, 30 | { 31 | "type": "section", 32 | "text": { 33 | "type": "mrkdwn", 34 | "text": ${{ toJSON(github.event.release.body) }} 35 | } 36 | }, 37 | { 38 | "type": "section", 39 | "text": { 40 | "type": "mrkdwn", 41 | "text": "${{ github.event.release.html_url }}" 42 | } 43 | } 44 | ] 45 | 46 | releases-channel: 47 | runs-on: ubuntu-latest 48 | steps: 49 | - name: Dump Github context 50 | env: 51 | GITHUB_CONTEXT: ${{ toJSON(github) }} 52 | run: echo "$GITHUB_CONTEXT" 53 | - name: Slack Notification on SUCCESS 54 | if: success() 55 | uses: tokorom/action-slack-incoming-webhook@main 56 | env: 57 | INCOMING_WEBHOOK_URL: ${{ secrets.SLACK_RELEASES_WEBHOOK_URL }} 58 | with: 59 | text: swift-snapshot-testing ${{ github.event.release.tag_name }} has been released. 60 | blocks: | 61 | [ 62 | { 63 | "type": "header", 64 | "text": { 65 | "type": "plain_text", 66 | "text": "swift-snapshot-testing ${{ github.event.release.tag_name}}" 67 | } 68 | }, 69 | { 70 | "type": "section", 71 | "text": { 72 | "type": "mrkdwn", 73 | "text": ${{ toJSON(github.event.release.body) }} 74 | } 75 | }, 76 | { 77 | "type": "section", 78 | "text": { 79 | "type": "mrkdwn", 80 | "text": "${{ github.event.release.html_url }}" 81 | } 82 | } 83 | ] 84 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | *.dSYM.zip 29 | *.dSYM 30 | 31 | ## Playgrounds 32 | timeline.xctimeline 33 | playground.xcworkspace 34 | 35 | # Swift Package Manager 36 | # 37 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 38 | # Packages/ 39 | # Package.pins 40 | .build/ 41 | .swiftpm 42 | 43 | # CocoaPods 44 | # 45 | # We recommend against adding the Pods directory to your .gitignore. However 46 | # you should judge for yourself, the pros and cons are mentioned at: 47 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 48 | # 49 | # Pods/ 50 | 51 | # Carthage 52 | # 53 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 54 | # Carthage/Checkouts 55 | 56 | Carthage/Build 57 | 58 | # fastlane 59 | # 60 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 61 | # screenshots whenever they are needed. 62 | # For more information about the recommended setup visit: 63 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 64 | 65 | fastlane/report.xml 66 | fastlane/Preview.html 67 | fastlane/screenshots 68 | fastlane/test_output 69 | 70 | .DS_Store 71 | -------------------------------------------------------------------------------- /.spi.yml: -------------------------------------------------------------------------------- 1 | # This is manifest file for the Swift Package Index for it to auto-generate and 2 | # host DocC documentation. 3 | # 4 | # For reference see https://swiftpackageindex.com/swiftpackageindex/spimanifest/documentation/spimanifest/commonusecases#Host-DocC-documentation-in-the-Swift-Package-Index 5 | 6 | version: 1 7 | builder: 8 | configs: 9 | - documentation_targets: 10 | # First item in the list is the "landing" (default) target 11 | - SnapshotTesting 12 | - InlineSnapshotTesting 13 | - platform: watchos 14 | scheme: InlineSnapshotTesting 15 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | ## Code of Conduct 4 | 5 | This project and everyone participating in it is governed by its [Code of Conduct](.github/CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to support@pointfree.co. 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Point-Free, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | test-linux: 2 | docker run \ 3 | --rm \ 4 | -v "$(PWD):$(PWD)" \ 5 | -w "$(PWD)" \ 6 | swift:5.7-focal \ 7 | bash -c 'swift test' 8 | 9 | test-macos: 10 | set -o pipefail && \ 11 | xcodebuild test \ 12 | -scheme SnapshotTesting \ 13 | -destination platform="macOS" \ 14 | 15 | test-ios: 16 | set -o pipefail && \ 17 | xcodebuild test \ 18 | -scheme SnapshotTesting \ 19 | -destination platform="iOS Simulator,name=iPhone 11 Pro Max,OS=13.3" 20 | 21 | test-swift: 22 | swift test 23 | 24 | test-tvos: 25 | set -o pipefail && \ 26 | xcodebuild test \ 27 | -scheme SnapshotTesting \ 28 | -destination platform="tvOS Simulator,name=Apple TV 4K,OS=13.3" 29 | 30 | format: 31 | swift format \ 32 | --ignore-unparsable-files \ 33 | --in-place \ 34 | --recursive \ 35 | ./Package.swift ./Sources ./Tests 36 | 37 | test-all: test-linux test-macos test-ios 38 | -------------------------------------------------------------------------------- /Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "pins" : [ 3 | { 4 | "identity" : "swift-custom-dump", 5 | "kind" : "remoteSourceControl", 6 | "location" : "https://github.com/pointfreeco/swift-custom-dump", 7 | "state" : { 8 | "revision" : "82645ec760917961cfa08c9c0c7104a57a0fa4b1", 9 | "version" : "1.3.3" 10 | } 11 | }, 12 | { 13 | "identity" : "swift-syntax", 14 | "kind" : "remoteSourceControl", 15 | "location" : "https://github.com/swiftlang/swift-syntax", 16 | "state" : { 17 | "revision" : "0687f71944021d616d34d922343dcef086855920", 18 | "version" : "600.0.1" 19 | } 20 | }, 21 | { 22 | "identity" : "xctest-dynamic-overlay", 23 | "kind" : "remoteSourceControl", 24 | "location" : "https://github.com/pointfreeco/xctest-dynamic-overlay", 25 | "state" : { 26 | "revision" : "a3f634d1a409c7979cabc0a71b3f26ffa9fc8af1", 27 | "version" : "1.4.3" 28 | } 29 | } 30 | ], 31 | "version" : 2 32 | } 33 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.9 2 | 3 | import PackageDescription 4 | 5 | let package = Package( 6 | name: "swift-snapshot-testing", 7 | platforms: [ 8 | .iOS(.v13), 9 | .macOS(.v10_15), 10 | .tvOS(.v13), 11 | .watchOS(.v6), 12 | ], 13 | products: [ 14 | .library( 15 | name: "SnapshotTesting", 16 | targets: ["SnapshotTesting"] 17 | ), 18 | .library( 19 | name: "InlineSnapshotTesting", 20 | targets: ["InlineSnapshotTesting"] 21 | ), 22 | .library( 23 | name: "SnapshotTestingCustomDump", 24 | targets: ["SnapshotTestingCustomDump"] 25 | ), 26 | ], 27 | dependencies: [ 28 | .package(url: "https://github.com/pointfreeco/swift-custom-dump", from: "1.3.3"), 29 | .package(url: "https://github.com/swiftlang/swift-syntax", "509.0.0"..<"602.0.0"), 30 | ], 31 | targets: [ 32 | .target( 33 | name: "SnapshotTesting" 34 | ), 35 | .testTarget( 36 | name: "SnapshotTestingTests", 37 | dependencies: [ 38 | "SnapshotTesting" 39 | ], 40 | exclude: [ 41 | "__Fixtures__", 42 | "__Snapshots__", 43 | ] 44 | ), 45 | .target( 46 | name: "InlineSnapshotTesting", 47 | dependencies: [ 48 | "SnapshotTesting", 49 | "SnapshotTestingCustomDump", 50 | .product(name: "SwiftParser", package: "swift-syntax"), 51 | .product(name: "SwiftSyntax", package: "swift-syntax"), 52 | .product(name: "SwiftSyntaxBuilder", package: "swift-syntax"), 53 | ] 54 | ), 55 | .testTarget( 56 | name: "InlineSnapshotTestingTests", 57 | dependencies: [ 58 | "InlineSnapshotTesting" 59 | ] 60 | ), 61 | .target( 62 | name: "SnapshotTestingCustomDump", 63 | dependencies: [ 64 | "SnapshotTesting", 65 | .product(name: "CustomDump", package: "swift-custom-dump"), 66 | ] 67 | ), 68 | ] 69 | ) 70 | -------------------------------------------------------------------------------- /Package@swift-6.0.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:6.0 2 | 3 | import PackageDescription 4 | 5 | let package = Package( 6 | name: "swift-snapshot-testing", 7 | platforms: [ 8 | .iOS(.v13), 9 | .macOS(.v10_15), 10 | .tvOS(.v13), 11 | .watchOS(.v6), 12 | ], 13 | products: [ 14 | .library( 15 | name: "SnapshotTesting", 16 | targets: ["SnapshotTesting"] 17 | ), 18 | .library( 19 | name: "InlineSnapshotTesting", 20 | targets: ["InlineSnapshotTesting"] 21 | ), 22 | .library( 23 | name: "SnapshotTestingCustomDump", 24 | targets: ["SnapshotTestingCustomDump"] 25 | ), 26 | ], 27 | dependencies: [ 28 | .package(url: "https://github.com/pointfreeco/swift-custom-dump", from: "1.3.3"), 29 | .package(url: "https://github.com/swiftlang/swift-syntax", "509.0.0"..<"602.0.0"), 30 | ], 31 | targets: [ 32 | .target( 33 | name: "SnapshotTesting" 34 | ), 35 | .testTarget( 36 | name: "SnapshotTestingTests", 37 | dependencies: [ 38 | "SnapshotTesting" 39 | ], 40 | exclude: [ 41 | "__Fixtures__", 42 | "__Snapshots__", 43 | ] 44 | ), 45 | .target( 46 | name: "InlineSnapshotTesting", 47 | dependencies: [ 48 | "SnapshotTesting", 49 | "SnapshotTestingCustomDump", 50 | .product(name: "SwiftParser", package: "swift-syntax"), 51 | .product(name: "SwiftSyntax", package: "swift-syntax"), 52 | .product(name: "SwiftSyntaxBuilder", package: "swift-syntax"), 53 | ] 54 | ), 55 | .testTarget( 56 | name: "InlineSnapshotTestingTests", 57 | dependencies: [ 58 | "InlineSnapshotTesting" 59 | ] 60 | ), 61 | .target( 62 | name: "SnapshotTestingCustomDump", 63 | dependencies: [ 64 | "SnapshotTesting", 65 | .product(name: "CustomDump", package: "swift-custom-dump"), 66 | ] 67 | ), 68 | ], 69 | swiftLanguageModes: [.v5] 70 | ) 71 | -------------------------------------------------------------------------------- /Sources/InlineSnapshotTesting/Documentation.docc/InlineSnapshotTesting.md: -------------------------------------------------------------------------------- 1 | # ``InlineSnapshotTesting`` 2 | 3 | Powerfully convenient snapshot testing. 4 | 5 | ## Overview 6 | 7 | [Snapshot Testing][swift-snapshot-testing] writes the snapshots it generates directly to disk 8 | alongside the test files. This makes for compact test cases with single line assertions... 9 | 10 | ```swift 11 | assertSnapshot(of: value, as: .json) 12 | ``` 13 | 14 | ...but can make verification more cumbersome: one must find the corresponding file in order to 15 | verify that it matches their expectation. In this case, if the above assertion is the second one in 16 | a `testMySnapshot()` method in a `MySnapshotTests.swift` file, the snapshot will be found at: 17 | 18 | ```sh 19 | $ cat __Snapshots__/MySnapshotTests/testMySnapshot.2.json 20 | { 21 | "id": 42, 22 | "name": "Blob" 23 | } 24 | ``` 25 | 26 | Inline Snapshot Testing offers an alternative approach by writing string snapshots directly into 27 | the test file. This makes it easy to verify a snapshot test at any time, since the value and 28 | snapshot sit next to each other in the assertion. One can `import InlineSnapshotTesting` and rewrite 29 | the above assertion as: 30 | 31 | ```swift 32 | assertInlineSnapshot(of: value, as: .json) 33 | ``` 34 | 35 | And when the test is run, it will automatically insert the snapshot as a trailing closure to be used 36 | by future test runs, and fail: 37 | 38 | ```swift 39 | assertInlineSnapshot(of: value, as: .json) { // ❌ 40 | """ 41 | { 42 | "id": 42, 43 | "name": "Blob" 44 | } 45 | """ 46 | } 47 | ``` 48 | 49 | ``` 50 | ❌ failed - Automatically recorded a new snapshot. 51 | 52 | Re-run "testMySnapshot" to test against the newly-recorded snapshot. 53 | ``` 54 | 55 | > Warning: When a snapshot is written into a test file, the undo history of the test file in Xcode 56 | > will be lost. Be careful to avoid losing work, and commit often to version control. 57 | > 58 | > We would love for this to be fixed. Please [file feedback][apple-feedback] with Apple to improve 59 | > things, or if you have an idea of how we can improve things from the library, please 60 | > [start a discussion][discussions] or [open a pull request][pull-requests]. 61 | 62 | [apple-feedback]: https://www.apple.com/feedback/ 63 | [discussions]: https://github.com/pointfreeco/swift-composable-architecture/discussions 64 | [pull-requests]: https://github.com/pointfreeco/swift-composable-architecture/pulls 65 | [swift-snapshot-testing]: https://github.com/pointfreeco/swift-snapshot-testing 66 | 67 | ## Topics 68 | 69 | ### Essentials 70 | 71 | - ``assertInlineSnapshot(of:as:message:record:timeout:syntaxDescriptor:matches:file:function:line:column:)`` 72 | 73 | ### Writing a custom helper 74 | 75 | - ``InlineSnapshotSyntaxDescriptor`` 76 | -------------------------------------------------------------------------------- /Sources/InlineSnapshotTesting/Exports.swift: -------------------------------------------------------------------------------- 1 | @_exported import SnapshotTesting 2 | -------------------------------------------------------------------------------- /Sources/SnapshotTesting/Async.swift: -------------------------------------------------------------------------------- 1 | /// A wrapper around an asynchronous operation. 2 | /// 3 | /// Snapshot strategies may utilize this type to create snapshots in an asynchronous fashion. 4 | /// 5 | /// For example, WebKit's `WKWebView` offers a callback-based API for taking image snapshots 6 | /// (`takeSnapshot`). `Async` allows us to build a value that can pass its callback along to the 7 | /// scope in which the image has been created. 8 | /// 9 | /// ```swift 10 | /// Async { callback in 11 | /// webView.takeSnapshot(with: nil) { image, error in 12 | /// callback(image!) 13 | /// } 14 | /// } 15 | /// ``` 16 | public struct Async { 17 | public let run: (@escaping (Value) -> Void) -> Void 18 | 19 | /// Creates an asynchronous operation. 20 | /// 21 | /// - Parameters: 22 | /// - run: A function that, when called, can hand a value to a callback. 23 | public init(run: @escaping (_ callback: @escaping (Value) -> Void) -> Void) { 24 | self.run = run 25 | } 26 | 27 | /// Wraps a pure value in an asynchronous operation. 28 | /// 29 | /// - Parameter value: A value to be wrapped in an asynchronous operation. 30 | public init(value: Value) { 31 | self.init { callback in callback(value) } 32 | } 33 | 34 | /// Transforms an `Async` into an `Async` with a function `(Value) -> NewValue`. 35 | /// 36 | /// - Parameter transform: A transformation to apply to the value wrapped by the async value. 37 | public func map(_ transform: @escaping (Value) -> NewValue) -> Async { 38 | .init { callback in 39 | self.run { value in callback(transform(value)) } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Sources/SnapshotTesting/Common/Internal.swift: -------------------------------------------------------------------------------- 1 | #if os(macOS) 2 | import Cocoa 3 | typealias Image = NSImage 4 | typealias ImageView = NSImageView 5 | typealias View = NSView 6 | #elseif os(iOS) || os(tvOS) 7 | import UIKit 8 | typealias Image = UIImage 9 | typealias ImageView = UIImageView 10 | typealias View = UIView 11 | #endif 12 | -------------------------------------------------------------------------------- /Sources/SnapshotTesting/Common/String+SpecialCharacters.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | extension String { 4 | 5 | /// Checks whether the string has escaped special character literals or not. 6 | /// 7 | /// This method won't detect an unescaped special character. 8 | /// For example, this method will return true for "\\n" or #"\n"#, but false for "\n" 9 | /// 10 | /// The following are the special character literals that this methods looks for: 11 | /// The escaped special characters \0 (null character), \\ (backslash), 12 | /// \t (horizontal tab), \n (line feed), \r (carriage return), 13 | /// \" (double quotation mark) and \' (single quotation mark), 14 | /// An arbitrary Unicode scalar value, written as \u{n}, 15 | /// where n is a 1–8 digit hexadecimal number (Unicode is discussed in Unicode below) 16 | /// The character sequence "# 17 | /// 18 | /// - Returns: True if the string has any special character literals, false otherwise. 19 | func hasEscapedSpecialCharactersLiteral() -> Bool { 20 | let multilineLiteralAndNumberSign = ##""" 21 | """# 22 | """## 23 | let patterns = [ 24 | // Matches \u{n} where n is a 1–8 digit hexadecimal number 25 | try? NSRegularExpression(pattern: #"\\u\{[a-fA-f0-9]{1,8}\}"#, options: .init()), 26 | try? NSRegularExpression(pattern: #"\0"#, options: .ignoreMetacharacters), 27 | try? NSRegularExpression(pattern: #"\\"#, options: .ignoreMetacharacters), 28 | try? NSRegularExpression(pattern: #"\t"#, options: .ignoreMetacharacters), 29 | try? NSRegularExpression(pattern: #"\n"#, options: .ignoreMetacharacters), 30 | try? NSRegularExpression(pattern: #"\r"#, options: .ignoreMetacharacters), 31 | try? NSRegularExpression(pattern: #"\""#, options: .ignoreMetacharacters), 32 | try? NSRegularExpression(pattern: #"\'"#, options: .ignoreMetacharacters), 33 | try? NSRegularExpression( 34 | pattern: multilineLiteralAndNumberSign, options: .ignoreMetacharacters), 35 | ] 36 | let matches = patterns.compactMap { 37 | $0?.firstMatch( 38 | in: self, options: .init(), range: NSRange.init(location: 0, length: self.count)) 39 | } 40 | return matches.count > 0 41 | } 42 | 43 | /// This method calculates how many number signs (#) we need to add around a string 44 | /// literal to properly escape its content. 45 | /// 46 | /// Multiple # are needed when the literal contains "#, "##, "### ... 47 | /// 48 | /// - Returns: The number of "number signs(#)" needed around a string literal. 49 | /// When there is no "#, ... return 1 50 | func numberOfNumberSignsNeeded() -> Int { 51 | let pattern = try! NSRegularExpression(pattern: ##""#{1,}"##, options: .init()) 52 | 53 | let matches = pattern.matches( 54 | in: self, options: .init(), range: NSRange.init(location: 0, length: self.count)) 55 | 56 | // If we have "## then the length of the match is 3, 57 | // which is also the number of "number signs (#)" we need to add 58 | // before and after the string literal 59 | return matches.map { $0.range.length }.max() ?? 1 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Sources/SnapshotTesting/Common/XCTAttachment.swift: -------------------------------------------------------------------------------- 1 | #if os(Linux) || os(Android) || os(Windows) 2 | import Foundation 3 | 4 | public struct XCTAttachment { 5 | public init(data: Data) {} 6 | public init(data: Data, uniformTypeIdentifier: String) {} 7 | } 8 | #endif 9 | -------------------------------------------------------------------------------- /Sources/SnapshotTesting/Diff.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | struct Difference { 4 | enum Which { 5 | case first 6 | case second 7 | case both 8 | } 9 | 10 | let elements: [A] 11 | let which: Which 12 | } 13 | 14 | func diff(_ fst: [A], _ snd: [A]) -> [Difference] { 15 | var idxsOf = [A: [Int]]() 16 | fst.enumerated().forEach { idxsOf[$1, default: []].append($0) } 17 | 18 | let sub = snd.enumerated().reduce((overlap: [Int: Int](), fst: 0, snd: 0, len: 0)) { 19 | sub, sndPair in 20 | (idxsOf[sndPair.element] ?? []) 21 | .reduce((overlap: [Int: Int](), fst: sub.fst, snd: sub.snd, len: sub.len)) { 22 | innerSub, fstIdx in 23 | 24 | var newOverlap = innerSub.overlap 25 | newOverlap[fstIdx] = (sub.overlap[fstIdx - 1] ?? 0) + 1 26 | 27 | if let newLen = newOverlap[fstIdx], newLen > sub.len { 28 | return (newOverlap, fstIdx - newLen + 1, sndPair.offset - newLen + 1, newLen) 29 | } 30 | return (newOverlap, innerSub.fst, innerSub.snd, innerSub.len) 31 | } 32 | } 33 | let (_, fstIdx, sndIdx, len) = sub 34 | 35 | if len == 0 { 36 | let fstDiff = fst.isEmpty ? [] : [Difference(elements: fst, which: .first)] 37 | let sndDiff = snd.isEmpty ? [] : [Difference(elements: snd, which: .second)] 38 | return fstDiff + sndDiff 39 | } else { 40 | let fstDiff = diff(Array(fst.prefix(upTo: fstIdx)), Array(snd.prefix(upTo: sndIdx))) 41 | let midDiff = [Difference(elements: Array(fst.suffix(from: fstIdx).prefix(len)), which: .both)] 42 | let lstDiff = diff(Array(fst.suffix(from: fstIdx + len)), Array(snd.suffix(from: sndIdx + len))) 43 | return fstDiff + midDiff + lstDiff 44 | } 45 | } 46 | 47 | let minus = "−" 48 | let plus = "+" 49 | private let figureSpace = "\u{2007}" 50 | 51 | struct Hunk { 52 | let fstIdx: Int 53 | let fstLen: Int 54 | let sndIdx: Int 55 | let sndLen: Int 56 | let lines: [String] 57 | 58 | var patchMark: String { 59 | let fstMark = "\(minus)\(fstIdx + 1),\(fstLen)" 60 | let sndMark = "\(plus)\(sndIdx + 1),\(sndLen)" 61 | return "@@ \(fstMark) \(sndMark) @@" 62 | } 63 | 64 | // Semigroup 65 | 66 | static func + (lhs: Hunk, rhs: Hunk) -> Hunk { 67 | return Hunk( 68 | fstIdx: lhs.fstIdx + rhs.fstIdx, 69 | fstLen: lhs.fstLen + rhs.fstLen, 70 | sndIdx: lhs.sndIdx + rhs.sndIdx, 71 | sndLen: lhs.sndLen + rhs.sndLen, 72 | lines: lhs.lines + rhs.lines 73 | ) 74 | } 75 | 76 | // Monoid 77 | 78 | init(fstIdx: Int = 0, fstLen: Int = 0, sndIdx: Int = 0, sndLen: Int = 0, lines: [String] = []) { 79 | self.fstIdx = fstIdx 80 | self.fstLen = fstLen 81 | self.sndIdx = sndIdx 82 | self.sndLen = sndLen 83 | self.lines = lines 84 | } 85 | 86 | init(idx: Int = 0, len: Int = 0, lines: [String] = []) { 87 | self.init(fstIdx: idx, fstLen: len, sndIdx: idx, sndLen: len, lines: lines) 88 | } 89 | } 90 | 91 | func chunk(diff diffs: [Difference], context ctx: Int = 4) -> [Hunk] { 92 | func prepending(_ prefix: String) -> (String) -> String { 93 | return { prefix + $0 + ($0.hasSuffix(" ") ? "¬" : "") } 94 | } 95 | let changed: (Hunk) -> Bool = { 96 | $0.lines.contains(where: { $0.hasPrefix(minus) || $0.hasPrefix(plus) }) 97 | } 98 | 99 | let (hunk, hunks) = 100 | diffs 101 | .reduce((current: Hunk(), hunks: [Hunk]())) { cursor, diff in 102 | let (current, hunks) = cursor 103 | let len = diff.elements.count 104 | 105 | switch diff.which { 106 | case .both where len > ctx * 2: 107 | let hunk = 108 | current + Hunk(len: ctx, lines: diff.elements.prefix(ctx).map(prepending(figureSpace))) 109 | let next = Hunk( 110 | fstIdx: current.fstIdx + current.fstLen + len - ctx, 111 | fstLen: ctx, 112 | sndIdx: current.sndIdx + current.sndLen + len - ctx, 113 | sndLen: ctx, 114 | lines: (diff.elements.suffix(ctx) as ArraySlice).map(prepending(figureSpace)) 115 | ) 116 | return (next, changed(hunk) ? hunks + [hunk] : hunks) 117 | case .both where current.lines.isEmpty: 118 | let lines = (diff.elements.suffix(ctx) as ArraySlice).map(prepending(figureSpace)) 119 | let count = lines.count 120 | return (current + Hunk(idx: len - count, len: count, lines: lines), hunks) 121 | case .both: 122 | return (current + Hunk(len: len, lines: diff.elements.map(prepending(figureSpace))), hunks) 123 | case .first: 124 | return (current + Hunk(fstLen: len, lines: diff.elements.map(prepending(minus))), hunks) 125 | case .second: 126 | return (current + Hunk(sndLen: len, lines: diff.elements.map(prepending(plus))), hunks) 127 | } 128 | } 129 | 130 | return changed(hunk) ? hunks + [hunk] : hunks 131 | } 132 | -------------------------------------------------------------------------------- /Sources/SnapshotTesting/Diffing.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import XCTest 3 | 4 | /// The ability to compare `Value`s and convert them to and from `Data`. 5 | public struct Diffing { 6 | /// Converts a value _to_ data. 7 | public var toData: (Value) -> Data 8 | 9 | /// Produces a value _from_ data. 10 | public var fromData: (Data) -> Value 11 | 12 | /// Compares two values. If the values do not match, returns a failure message and artifacts 13 | /// describing the failure. 14 | public var diff: (Value, Value) -> (String, [XCTAttachment])? 15 | 16 | /// Creates a new `Diffing` on `Value`. 17 | /// 18 | /// - Parameters: 19 | /// - toData: A function used to convert a value _to_ data. 20 | /// - fromData: A function used to produce a value _from_ data. 21 | /// - diff: A function used to compare two values. If the values do not match, returns a failure 22 | public init( 23 | toData: @escaping (_ value: Value) -> Data, 24 | fromData: @escaping (_ data: Data) -> Value, 25 | diff: @escaping (_ lhs: Value, _ rhs: Value) -> (String, [XCTAttachment])? 26 | ) { 27 | self.toData = toData 28 | self.fromData = fromData 29 | self.diff = diff 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Sources/SnapshotTesting/Documentation.docc/Articles/CustomStrategies.md: -------------------------------------------------------------------------------- 1 | # Defining custom snapshot strategies 2 | 3 | While SnapshotTesting comes with a wide variety of snapshot strategies, it can also be extended with 4 | custom, user-defined strategies using the ``SnapshotTesting/Snapshotting`` and 5 | ``SnapshotTesting/Diffing`` types. 6 | 7 | ## Snapshotting 8 | 9 | The ``SnapshotTesting/Snapshotting`` type represents the ability to transform a snapshottable value 10 | (like a view or data structure) into a diffable format (like an image or text). 11 | 12 | ### Transforming existing strategies 13 | 14 | Existing strategies can be transformed to work with new types using the `pullback` method. 15 | 16 | For example, given the following `image` strategy on `UIView`: 17 | 18 | ``` swift 19 | Snapshotting.image 20 | ``` 21 | 22 | We can define an `image` strategy on `UIViewController` using the `pullback` method: 23 | 24 | ``` swift 25 | extension Snapshotting where Value == UIViewController, Format == UIImage { 26 | public static let image: Snapshotting = Snapshotting 27 | .image 28 | .pullback { viewController in viewController.view } 29 | } 30 | ``` 31 | 32 | Pullback takes a transform function from the new strategy's value to the existing strategy's value, 33 | in this case `(UIViewController) -> UIView`. 34 | 35 | ### Creating brand new strategies 36 | 37 | Most strategies can be built from existing ones, but if you've defined your own 38 | ``SnapshotTesting/Diffing`` strategy, you may need to create a base ``SnapshotTesting/Snapshotting`` 39 | value alongside it. 40 | 41 | ### Asynchronous Strategies 42 | 43 | Some types need to be snapshot in an asynchronous fashion. ``SnapshotTesting/Snapshotting`` offers 44 | two APIs for building asynchronous strategies by utilizing a built-in ``Async`` type. 45 | 46 | #### Async pullbacks 47 | 48 | Alongside ``Snapshotting/pullback(_:)`` there is ``Snapshotting/asyncPullback(_:)``, which takes a 49 | transform function `(NewStrategyValue) -> Async`. 50 | 51 | For example, WebKit's `WKWebView` offers a callback-based API for taking image snapshots, where the 52 | image is passed asynchronously to the callback block. While `pullback` would require the `UIImage` 53 | to be returned from the transform function, `asyncPullback` and `Async` allow us to pass the `image` 54 | a value that can pass its callback along to the scope in which the image has been created. 55 | 56 | ``` swift 57 | extension Snapshotting where Value == WKWebView, Format == UIImage { 58 | public static let image: Snapshotting = Snapshotting 59 | .image 60 | .asyncPullback { webView in 61 | Async { callback in 62 | webView.takeSnapshot(with: nil) { image, error in 63 | callback(image!) 64 | } 65 | } 66 | } 67 | } 68 | ``` 69 | 70 | #### Async initialization 71 | 72 | `Snapshotting` defines an alternate initializer to describe snapshotting values in an asynchronous 73 | fashion. 74 | 75 | For example, were we to define a strategy for `WKWebView` _without_ 76 | ``Snapshotting/asyncPullback(_:)``: 77 | 78 | ``` swift 79 | extension Snapshotting where Value == WKWebView, Format == UIImage { 80 | public static let image = Snapshotting( 81 | pathExtension: "png", 82 | diffing: .image, 83 | asyncSnapshot: { webView in 84 | Async { callback in 85 | webView.takeSnapshot(with: nil) { image, error in 86 | callback(image!) 87 | } 88 | } 89 | } 90 | ) 91 | } 92 | ``` 93 | 94 | ## Diffing 95 | 96 | The ``SnapshotTesting/Diffing`` type represents the ability to compare `Value`s and convert them to 97 | and from `Data`. 98 | -------------------------------------------------------------------------------- /Sources/SnapshotTesting/Documentation.docc/Articles/IntegratingWithTestFrameworks.md: -------------------------------------------------------------------------------- 1 | # Integrating with test frameworks 2 | 3 | Learn how to use snapshot testing in the two main testing frameworks: Xcode's XCTest and Swift's 4 | native testing framework. 5 | 6 | ## Overview 7 | 8 | The Apple ecosystem currently has two primary testing frameworks, and unfortunately they are not 9 | compatible with each other. There is the XCTest framework, which is a private framework provided 10 | by Apple and heavily integrated into Xcode. And now there is Swift Testing, an open source testing 11 | framework built in Swift that is capable of integrating into a variety of environments. 12 | 13 | These two frameworks are not compatible in the sense that an assertion made in one framework 14 | from a test in the other framework will not trigger a test failure. So, if you are writing a test 15 | with the new `@Test` macro style, and you use a test helper that ultimately calls `XCTFail` under 16 | the hood, that will not bubble up to an actual test failure when tests are run. And similarly, if 17 | you have a test case inheriting from `XCTestCase` that ultimiately invokes the new style `#expect` 18 | macro, that too will not actually trigger a test failure. 19 | 20 | However, these details have all been hidden away in the SnapshotTesting library. You can simply 21 | use ``assertSnapshot(of:as:named:record:timeout:file:testName:line:)`` in either an `XCTestCase` 22 | subclass _or_ `@Test`, and it will dynamically detect what context it is running in and trigger 23 | the correct test failure: 24 | 25 | ```swift 26 | @Test 27 | func testFeature() { 28 | assertSnapshot(of: MyView(), as: .image) // ✅ 29 | } 30 | 31 | class FeatureTests: XCTestCase { 32 | func testFeature() { 33 | assertSnapshot(of: MyView(), as: .image) // ✅ 34 | } 35 | } 36 | ``` 37 | 38 | ### Configuring snapshots 39 | 40 | For the most part, asserting on snapshots works the same whether you are using XCTest or Swift 41 | Testing. There is one major difference, and that is how snapshot configuration works. There are 42 | two major ways snapshots can be configured: ``SnapshotTestingConfiguration/diffTool-swift.property`` 43 | and ``SnapshotTestingConfiguration/record-swift.property``. 44 | 45 | The `diffTool` property allows you to customize how a command is printed to the test failure 46 | message that allows you to quickly open a diff of two files, such as 47 | [Kaleidoscope](http://kaleidoscope.app). The `record` property allows you to change the mode of 48 | assertion so that new snapshots are generated and saved to disk. 49 | 50 | These properties can be overridden for a scope of an operation using the 51 | ``withSnapshotTesting(record:diffTool:operation:)-2kuyr`` function. In a Swift Testing context 52 | you can apply the ``Testing/Trait/snapshots`` trait to either a single test or an entire suite: 53 | 54 | ```swift 55 | import SnapshotTesting 56 | 57 | @Suite(.snapshots(record: .failed, diffTool: .ksdiff)) 58 | struct FeatureTests { 59 | … 60 | } 61 | ``` 62 | 63 | This will override the `diffTool` and `record` properties for each test in the suite. 64 | 65 | In an XCTest context, the simplest way to do this is to override the `invokeTest` method on 66 | `XCTestCase` and wrap it in `withSnapshotTesting`: 67 | 68 | ```swift 69 | class FeatureTests: XCTestCase { 70 | override func invokeTest() { 71 | withSnapshotTesting(record: .failed, diffTool: .ksdiff) { 72 | super.invokeTest() 73 | } 74 | } 75 | } 76 | ``` 77 | 78 | This will override the `diffTool` and `record` properties for each test function. 79 | 80 | ### UI Testing 81 | 82 | Xcode's UI testing tools are currently incompatible with Swift Testing. Simply adding 83 | `import Testing` to any UI test target file will cause a compilation error saying that "Testing" 84 | cannot be found. This complicates using SnapshotTesting in UI test targets because it needs to 85 | import Testing in order to provide the test helpers mentioned above. 86 | 87 | The way in which Xcode disallows importing Testing in UI test targets is via the presence of a 88 | special Swift flag: 89 | 90 | ``` 91 | -module_alias Testing=_Testing_Unavailable 92 | ``` 93 | 94 | This is done so that people do not expect `#expect` and other Testing tools to work in UI test 95 | targets. If you want to use SnapshotTesting in a UI test target, we recommend that you remove 96 | this flag: 97 | 98 | * Open your project's settings and navigate to the settings for your UI testing target. 99 | * Search for "Other Swift flags" in the "Build Settings" tab. 100 | * Delete the `$(inherited)` flag. 101 | 102 | Now you can `import SnapshotTesting` in UI test targets _and_ make use of `assertSnapshot`. But 103 | do remember that you _cannot_ use `#expect` or any of the other tools from Swift Testing. 104 | -------------------------------------------------------------------------------- /Sources/SnapshotTesting/Documentation.docc/Articles/MigrationGuides/MigrationGuides.md: -------------------------------------------------------------------------------- 1 | # Migration guides 2 | 3 | Learn how to upgrade your application to the newest version of this library. 4 | 5 | ## Overview 6 | 7 | This library is under constant development, and we are always looking for ways to simplify the 8 | library, and make it more powerful. As such, we often need to deprecate certain APIs in favor of 9 | newer ones. We recommend people update their code as quickly as possible to the newest APIs, and 10 | these guides contain tips to do so. 11 | 12 | > Important: Before following any particular migration guide be sure you have followed all the 13 | > preceding migration guides. 14 | 15 | ### Guides 16 | 17 | - 18 | -------------------------------------------------------------------------------- /Sources/SnapshotTesting/Documentation.docc/Extensions/AssertSnapshot.md: -------------------------------------------------------------------------------- 1 | # ``SnapshotTesting/assertSnapshot(of:as:named:record:timeout:file:testName:line:)`` 2 | 3 | ## Topics 4 | 5 | ### Multiple snapshots 6 | 7 | - ``assertSnapshots(of:as:record:timeout:file:testName:line:)-6mdbp`` 8 | - ``assertSnapshots(of:as:record:timeout:file:testName:line:)-6c4fe`` 9 | 10 | ### Custom assertions 11 | 12 | - ``verifySnapshot(of:as:named:record:snapshotDirectory:timeout:file:testName:line:)`` 13 | 14 | ### Deprecations 15 | 16 | - ``assertSnapshot(matching:as:named:record:timeout:file:testName:line:)`` 17 | - ``assertSnapshots(matching:as:record:timeout:file:testName:line:)-4fz7d`` 18 | - ``assertSnapshots(matching:as:record:timeout:file:testName:line:)-wq4j`` 19 | - ``verifySnapshot(matching:as:named:record:snapshotDirectory:timeout:file:testName:line:)`` 20 | -------------------------------------------------------------------------------- /Sources/SnapshotTesting/Documentation.docc/Extensions/Deprecations/SnapshotTestingDeprecations.md: -------------------------------------------------------------------------------- 1 | # Deprecations 2 | 3 | ## Topics 4 | 5 | ### Assert helpers 6 | 7 | - ``assertSnapshots(matching:as:record:timeout:file:testName:line:)-4fz7d`` 8 | - ``assertSnapshots(matching:as:record:timeout:file:testName:line:)-wq4j`` 9 | 10 | ### Configuration 11 | 12 | - ``isRecording`` 13 | - ``diffTool`` 14 | 15 | ### Supporting types 16 | 17 | - ``SnapshotTestCase`` 18 | -------------------------------------------------------------------------------- /Sources/SnapshotTesting/Documentation.docc/Extensions/Deprecations/diffTool-property-deprecation.md: -------------------------------------------------------------------------------- 1 | # ``SnapshotTesting/diffTool`` 2 | 3 | @DeprecationSummary { 4 | Use ``withSnapshotTesting(record:diffTool:operation:)-2kuyr`` to customize the diff tool, instead. 5 | See for more information. 6 | } 7 | -------------------------------------------------------------------------------- /Sources/SnapshotTesting/Documentation.docc/Extensions/Deprecations/isRecording-property-deprecation.md: -------------------------------------------------------------------------------- 1 | # ``SnapshotTesting/isRecording`` 2 | 3 | @DeprecationSummary { 4 | Use ``withSnapshotTesting(record:diffTool:operation:)-2kuyr`` to customize the record mode, 5 | instead. See for more information. 6 | } 7 | -------------------------------------------------------------------------------- /Sources/SnapshotTesting/Documentation.docc/Extensions/SnapshotsTrait.md: -------------------------------------------------------------------------------- 1 | # ``SnapshotTesting/Testing/Trait/snapshots(diffTool:record:)`` 2 | 3 | ### Configuration 4 | 5 | - ``Testing/Trait/snapshots(_:)`` 6 | -------------------------------------------------------------------------------- /Sources/SnapshotTesting/Documentation.docc/Extensions/Snapshotting.md: -------------------------------------------------------------------------------- 1 | # ``SnapshotTesting/Snapshotting`` 2 | 3 | ## Topics 4 | 5 | ### Strategies 6 | 7 | - ``curl`` 8 | - ``data`` 9 | - ``description`` 10 | - ``dump`` 11 | - ``elementsDescription-20h0f`` 12 | - ``elementsDescription-90719`` 13 | - ``elementsDescription(numberFormatter:)-1g0wq`` 14 | - ``elementsDescription(numberFormatter:)-8g5ik`` 15 | - ``func(into:)`` 16 | - ``image-34drn`` 17 | - ``image-4k9c6`` 18 | - ``image-4nvp5`` 19 | - ``image-5ftbk`` 20 | - ``image-8eey6`` 21 | - ``image-8ng2q`` 22 | - ``image(precision:perceptualPrecision:)-2gh0i`` 23 | - ``image(precision:perceptualPrecision:)-2x9v4`` 24 | - ``image(precision:perceptualPrecision:)-4o0qz`` 25 | - ``image(precision:perceptualPrecision:size:)-1sccj`` 26 | - ``image(precision:perceptualPrecision:size:)-20l7o`` 27 | - ``image(precision:perceptualPrecision:size:)-7hqxj`` 28 | - ``image(precision:perceptualPrecision:size:)-ba2u`` 29 | - ``image(precision:perceptualPrecision:drawingMode:)`` 30 | - ``json-745rx`` 31 | - ``json-9cu20`` 32 | - ``json(_:)`` 33 | - ``lines`` 34 | - ``plist`` 35 | - ``plist(_:)`` 36 | - ``raw`` 37 | - ``raw(pretty:)`` 38 | - ``recursiveDescription-227s4`` 39 | - ``recursiveDescription-7anah`` 40 | 41 | ### Defining a strategy 42 | 43 | - ``init(pathExtension:diffing:snapshot:)`` 44 | - ``init(pathExtension:diffing:asyncSnapshot:)`` 45 | - ``init(pathExtension:diffing:)`` 46 | 47 | ### Transforming strategies 48 | 49 | - ``pullback(_:)`` 50 | - ``asyncPullback(_:)`` 51 | - ``wait(for:on:)`` 52 | 53 | ### Properties 54 | 55 | - ``snapshot`` 56 | - ``diffing`` 57 | - ``pathExtension`` 58 | 59 | ### Supporting types 60 | 61 | - ``AnySnapshotStringConvertible`` 62 | - ``SimplySnapshotting`` 63 | - ``SwiftUISnapshotLayout`` 64 | -------------------------------------------------------------------------------- /Sources/SnapshotTesting/Documentation.docc/Extensions/WithSnapshotTesting.md: -------------------------------------------------------------------------------- 1 | # ``SnapshotTesting/withSnapshotTesting(record:diffTool:operation:)-2kuyr`` 2 | 3 | ## Topics 4 | 5 | ### Overloads 6 | 7 | - ``withSnapshotTesting(record:diffTool:operation:)-6bsqw`` 8 | -------------------------------------------------------------------------------- /Sources/SnapshotTesting/Documentation.docc/SnapshotTesting.md: -------------------------------------------------------------------------------- 1 | # ``SnapshotTesting`` 2 | 3 | Powerfully flexible snapshot testing. 4 | 5 | ## Topics 6 | 7 | ### Essentials 8 | 9 | - ``assertSnapshot(of:as:named:record:timeout:file:testName:line:)`` 10 | - 11 | - 12 | 13 | ### Strategies 14 | 15 | - 16 | - ``Snapshotting`` 17 | - ``Diffing`` 18 | - ``Async`` 19 | 20 | ### Configuration 21 | 22 | - ``Testing/Trait/snapshots(diffTool:record:)`` 23 | - ``withSnapshotTesting(record:diffTool:operation:)-2kuyr`` 24 | - ``SnapshotTestingConfiguration`` 25 | 26 | ### Deprecations 27 | 28 | - 29 | -------------------------------------------------------------------------------- /Sources/SnapshotTesting/Extensions/Wait.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import XCTest 3 | 4 | extension Snapshotting { 5 | /// Transforms an existing snapshot strategy into one that waits for some amount of time before 6 | /// taking the snapshot. This can be useful for waiting for animations to complete or for UIKit 7 | /// events to finish (_i.e._ waiting for a `UINavigationController` to push a child onto the 8 | /// stack). 9 | /// 10 | /// - Parameters: 11 | /// - duration: The amount of time to wait before taking the snapshot. 12 | /// - strategy: The snapshot to invoke after the specified amount of time has passed. 13 | public static func wait( 14 | for duration: TimeInterval, 15 | on strategy: Self 16 | ) -> Self { 17 | Self( 18 | pathExtension: strategy.pathExtension, 19 | diffing: strategy.diffing, 20 | asyncSnapshot: { value in 21 | Async { callback in 22 | let expectation = XCTestExpectation(description: "Wait") 23 | DispatchQueue.main.asyncAfter(deadline: .now() + duration) { 24 | expectation.fulfill() 25 | } 26 | _ = XCTWaiter.wait(for: [expectation], timeout: duration + 1) 27 | strategy.snapshot(value).run(callback) 28 | } 29 | }) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Sources/SnapshotTesting/Internal/RecordIssue.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | #if canImport(Testing) 4 | import Testing 5 | #endif 6 | 7 | var isSwiftTesting: Bool { 8 | #if canImport(Testing) 9 | return Test.current != nil 10 | #else 11 | return false 12 | #endif 13 | } 14 | 15 | @_spi(Internals) 16 | public func recordIssue( 17 | _ message: @autoclosure () -> String, 18 | fileID: StaticString, 19 | filePath: StaticString, 20 | line: UInt, 21 | column: UInt 22 | ) { 23 | #if canImport(Testing) 24 | if Test.current != nil { 25 | Issue.record( 26 | Comment(rawValue: message()), 27 | sourceLocation: SourceLocation( 28 | fileID: fileID.description, 29 | filePath: filePath.description, 30 | line: Int(line), 31 | column: Int(column) 32 | ) 33 | ) 34 | } else { 35 | XCTFail(message(), file: filePath, line: line) 36 | } 37 | #else 38 | XCTFail(message(), file: filePath, line: line) 39 | #endif 40 | } 41 | -------------------------------------------------------------------------------- /Sources/SnapshotTesting/SnapshotsTestTrait.swift: -------------------------------------------------------------------------------- 1 | #if canImport(Testing) 2 | import Testing 3 | 4 | /// A type representing the configuration of snapshot testing. 5 | public struct _SnapshotsTestTrait: SuiteTrait, TestTrait { 6 | public let isRecursive = true 7 | let configuration: SnapshotTestingConfiguration 8 | } 9 | 10 | extension Trait where Self == _SnapshotsTestTrait { 11 | /// Configure snapshot testing in a suite or test. 12 | public static var snapshots: Self { 13 | snapshots() 14 | } 15 | 16 | /// Configure snapshot testing in a suite or test. 17 | /// 18 | /// - Parameters: 19 | /// - record: The record mode of the test. 20 | /// - diffTool: The diff tool to use in failure messages. 21 | public static func snapshots( 22 | record: SnapshotTestingConfiguration.Record? = nil, 23 | diffTool: SnapshotTestingConfiguration.DiffTool? = nil 24 | ) -> Self { 25 | _SnapshotsTestTrait( 26 | configuration: SnapshotTestingConfiguration( 27 | record: record, 28 | diffTool: diffTool 29 | ) 30 | ) 31 | } 32 | 33 | /// Configure snapshot testing in a suite or test. 34 | /// 35 | /// - Parameter configuration: The configuration to use. 36 | public static func snapshots( 37 | _ configuration: SnapshotTestingConfiguration 38 | ) -> Self { 39 | _SnapshotsTestTrait(configuration: configuration) 40 | } 41 | } 42 | 43 | #if compiler(>=6.1) 44 | extension _SnapshotsTestTrait: TestScoping { 45 | public func provideScope( 46 | for test: Test, 47 | testCase: Test.Case?, 48 | performing function: () async throws -> Void 49 | ) async throws { 50 | try await withSnapshotTesting( 51 | record: configuration.record, 52 | diffTool: configuration.diffTool 53 | ) { 54 | try await File.$counter.withValue(File.Counter()) { 55 | try await function() 56 | } 57 | } 58 | } 59 | } 60 | #endif 61 | #endif 62 | -------------------------------------------------------------------------------- /Sources/SnapshotTesting/Snapshotting.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import XCTest 3 | 4 | /// A type representing the ability to transform a snapshottable value into a diffable format (like 5 | /// text or an image) for snapshot testing. 6 | public struct Snapshotting { 7 | /// The path extension applied to references saved to disk. 8 | public var pathExtension: String? 9 | 10 | /// How the snapshot format is diffed and converted to and from data. 11 | public var diffing: Diffing 12 | 13 | /// How a value is transformed into a diffable snapshot format. 14 | public var snapshot: (Value) -> Async 15 | 16 | /// Creates a snapshot strategy. 17 | /// 18 | /// - Parameters: 19 | /// - pathExtension: The path extension applied to references saved to disk. 20 | /// - diffing: How to diff and convert the snapshot format to and from data. 21 | /// - asyncSnapshot: An asynchronous transform function from a value into a diffable snapshot 22 | /// format. 23 | public init( 24 | pathExtension: String?, 25 | diffing: Diffing, 26 | asyncSnapshot: @escaping (_ value: Value) -> Async 27 | ) { 28 | self.pathExtension = pathExtension 29 | self.diffing = diffing 30 | self.snapshot = asyncSnapshot 31 | } 32 | 33 | /// Creates a snapshot strategy. 34 | /// 35 | /// - Parameters: 36 | /// - pathExtension: The path extension applied to references saved to disk. 37 | /// - diffing: How to diff and convert the snapshot format to and from data. 38 | /// - snapshot: A transform function from a value into a diffable snapshot format. 39 | public init( 40 | pathExtension: String?, 41 | diffing: Diffing, 42 | snapshot: @escaping (_ value: Value) -> Format 43 | ) { 44 | self.init(pathExtension: pathExtension, diffing: diffing) { 45 | Async(value: snapshot($0)) 46 | } 47 | } 48 | 49 | /// Transforms a strategy on `Value`s into a strategy on `NewValue`s through a function 50 | /// `(NewValue) -> Value`. 51 | /// 52 | /// This is the most important operation for transforming existing strategies into new strategies. 53 | /// It allows you to transform a `Snapshotting` into a 54 | /// `Snapshotting` by pulling it back along a function `(NewValue) -> Value`. 55 | /// Notice that the function must go in the direction `(NewValue) -> Value` even though we are 56 | /// transforming in the other direction 57 | /// `(Snapshotting) -> Snapshotting`. 58 | /// 59 | /// A simple example of this is to `pullback` the snapshot strategy on `UIView`s to work on 60 | /// `UIViewController`s: 61 | /// 62 | /// ```swift 63 | /// let strategy = Snapshotting.image.pullback { (vc: UIViewController) in 64 | /// vc.view 65 | /// } 66 | /// ``` 67 | /// 68 | /// Here we took the strategy that snapshots `UIView`s as `UIImage`s and pulled it back to work on 69 | /// `UIViewController`s by using the function `(UIViewController) -> UIView` that simply plucks 70 | /// the view out of the controller. 71 | /// 72 | /// Nearly every snapshot strategy provided in this library is a pullback of some base strategy, 73 | /// which shows just how important this operation is. 74 | /// 75 | /// - Parameters: 76 | /// - transform: A transform function from `NewValue` into `Value`. 77 | public func pullback(_ transform: @escaping (_ otherValue: NewValue) -> Value) 78 | -> Snapshotting 79 | { 80 | self.asyncPullback { newValue in Async(value: transform(newValue)) } 81 | } 82 | 83 | /// Transforms a strategy on `Value`s into a strategy on `NewValue`s through a function 84 | /// `(NewValue) -> Async`. 85 | /// 86 | /// See the documentation of `pullback` for a full description of how pullbacks works. This 87 | /// operation differs from `pullback` in that it allows you to use a transformation 88 | /// `(NewValue) -> Async`, which is necessary when your transformation needs to perform 89 | /// some asynchronous work. 90 | /// 91 | /// - Parameters: 92 | /// - transform: A transform function from `NewValue` into `Async`. 93 | public func asyncPullback( 94 | _ transform: @escaping (_ otherValue: NewValue) -> Async 95 | ) -> Snapshotting { 96 | Snapshotting( 97 | pathExtension: self.pathExtension, 98 | diffing: self.diffing 99 | ) { newValue in 100 | .init { callback in 101 | transform(newValue).run { value in 102 | self.snapshot(value).run { snapshot in 103 | callback(snapshot) 104 | } 105 | } 106 | } 107 | } 108 | } 109 | } 110 | 111 | /// A snapshot strategy where the type being snapshot is also a diffable type. 112 | public typealias SimplySnapshotting = Snapshotting 113 | 114 | extension Snapshotting where Value == Format { 115 | public init(pathExtension: String?, diffing: Diffing) { 116 | self.init( 117 | pathExtension: pathExtension, 118 | diffing: diffing, 119 | snapshot: { $0 } 120 | ) 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /Sources/SnapshotTesting/Snapshotting/CALayer.swift: -------------------------------------------------------------------------------- 1 | #if os(macOS) 2 | import AppKit 3 | import Cocoa 4 | import QuartzCore 5 | 6 | extension Snapshotting where Value == CALayer, Format == NSImage { 7 | /// A snapshot strategy for comparing layers based on pixel equality. 8 | /// 9 | /// ``` swift 10 | /// // Match reference perfectly. 11 | /// assertSnapshot(of: layer, as: .image) 12 | /// 13 | /// // Allow for a 1% pixel difference. 14 | /// assertSnapshot(of: layer, as: .image(precision: 0.99)) 15 | /// ``` 16 | public static var image: Snapshotting { 17 | return .image(precision: 1) 18 | } 19 | 20 | /// A snapshot strategy for comparing layers based on pixel equality. 21 | /// 22 | /// - Parameters: 23 | /// - precision: The percentage of pixels that must match. 24 | /// - perceptualPrecision: The percentage a pixel must match the source pixel to be considered a 25 | /// match. 98-99% mimics 26 | /// [the precision](http://zschuessler.github.io/DeltaE/learn/#toc-defining-delta-e) of the 27 | /// human eye. 28 | public static func image(precision: Float, perceptualPrecision: Float = 1) -> Snapshotting { 29 | return SimplySnapshotting.image( 30 | precision: precision, perceptualPrecision: perceptualPrecision 31 | ).pullback { layer in 32 | let image = NSImage(size: layer.bounds.size) 33 | image.lockFocus() 34 | let context = NSGraphicsContext.current!.cgContext 35 | layer.setNeedsLayout() 36 | layer.layoutIfNeeded() 37 | layer.render(in: context) 38 | image.unlockFocus() 39 | return image 40 | } 41 | } 42 | } 43 | #elseif os(iOS) || os(tvOS) 44 | import UIKit 45 | 46 | extension Snapshotting where Value == CALayer, Format == UIImage { 47 | /// A snapshot strategy for comparing layers based on pixel equality. 48 | public static var image: Snapshotting { 49 | return .image() 50 | } 51 | 52 | /// A snapshot strategy for comparing layers based on pixel equality. 53 | /// 54 | /// - Parameters: 55 | /// - precision: The percentage of pixels that must match. 56 | /// - perceptualPrecision: The percentage a pixel must match the source pixel to be considered a 57 | /// match. 98-99% mimics 58 | /// [the precision](http://zschuessler.github.io/DeltaE/learn/#toc-defining-delta-e) of the 59 | /// human eye. 60 | /// - traits: A trait collection override. 61 | public static func image( 62 | precision: Float = 1, perceptualPrecision: Float = 1, traits: UITraitCollection = .init() 63 | ) 64 | -> Snapshotting 65 | { 66 | return SimplySnapshotting.image( 67 | precision: precision, perceptualPrecision: perceptualPrecision, scale: traits.displayScale 68 | ).pullback { layer in 69 | renderer(bounds: layer.bounds, for: traits).image { ctx in 70 | layer.setNeedsLayout() 71 | layer.layoutIfNeeded() 72 | layer.render(in: ctx.cgContext) 73 | } 74 | } 75 | } 76 | } 77 | #endif 78 | -------------------------------------------------------------------------------- /Sources/SnapshotTesting/Snapshotting/CaseIterable.swift: -------------------------------------------------------------------------------- 1 | extension Snapshotting where Value: CaseIterable, Format == String { 2 | /// A strategy for snapshotting the output for every input of a function. The format of the 3 | /// snapshot is a comma-separated value (CSV) file that shows the mapping of inputs to outputs. 4 | /// 5 | /// - Parameter witness: A snapshotting value on the output of the function to be snapshot. 6 | /// - Returns: A snapshot strategy on functions `(Value) -> A` that feeds every possible input 7 | /// into the function and records the output into a CSV file. 8 | /// 9 | /// ```swift 10 | /// enum Direction: String, CaseIterable { 11 | /// case up, down, left, right 12 | /// var rotatedLeft: Direction { 13 | /// switch self { 14 | /// case .up: return .left 15 | /// case .down: return .right 16 | /// case .left: return .down 17 | /// case .right: return .up 18 | /// } 19 | /// } 20 | /// } 21 | /// 22 | /// assertSnapshot( 23 | /// of: \Direction.rotatedLeft, 24 | /// as: .func(into: .description) 25 | /// ) 26 | /// ``` 27 | /// 28 | /// Records: 29 | /// 30 | /// ```csv 31 | /// "up","left" 32 | /// "down","right" 33 | /// "left","down" 34 | /// "right","up" 35 | /// ``` 36 | public static func `func`(into witness: Snapshotting) -> Snapshotting< 37 | (Value) -> A, Format 38 | > { 39 | var snapshotting = Snapshotting.lines.asyncPullback { (f: (Value) -> A) in 40 | Value.allCases.map { input in 41 | witness.snapshot(f(input)) 42 | .map { (input, $0) } 43 | } 44 | .sequence() 45 | .map { rows in 46 | rows.map { "\"\($0)\",\"\($1)\"" } 47 | .joined(separator: "\n") 48 | } 49 | } 50 | 51 | snapshotting.pathExtension = "csv" 52 | 53 | return snapshotting 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Sources/SnapshotTesting/Snapshotting/Data.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import XCTest 3 | 4 | extension Snapshotting where Value == Data, Format == Data { 5 | /// A snapshot strategy for comparing bare binary data. 6 | public static var data: Snapshotting { 7 | return .init( 8 | pathExtension: nil, 9 | diffing: .init(toData: { $0 }, fromData: { $0 }) { old, new in 10 | guard old != new else { return nil } 11 | let message = 12 | old.count == new.count 13 | ? "Expected data to match" 14 | : "Expected \(new) to match \(old)" 15 | return (message, []) 16 | } 17 | ) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Sources/SnapshotTesting/Snapshotting/Encodable.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | extension Snapshotting where Value: Encodable, Format == String { 4 | /// A snapshot strategy for comparing encodable structures based on their JSON representation. 5 | /// 6 | /// ```swift 7 | /// assertSnapshot(of: user, as: .json) 8 | /// ``` 9 | /// 10 | /// Records: 11 | /// 12 | /// ```json 13 | /// { 14 | /// "bio" : "Blobbed around the world.", 15 | /// "id" : 1, 16 | /// "name" : "Blobby" 17 | /// } 18 | /// ``` 19 | @available(iOS 11.0, macOS 10.13, tvOS 11.0, watchOS 4.0, *) 20 | public static var json: Snapshotting { 21 | let encoder = JSONEncoder() 22 | encoder.outputFormatting = [.prettyPrinted, .sortedKeys] 23 | return .json(encoder) 24 | } 25 | 26 | /// A snapshot strategy for comparing encodable structures based on their JSON representation. 27 | /// 28 | /// - Parameter encoder: A JSON encoder. 29 | public static func json(_ encoder: JSONEncoder) -> Snapshotting { 30 | var snapshotting = SimplySnapshotting.lines.pullback { (encodable: Value) in 31 | try! String(decoding: encoder.encode(encodable), as: UTF8.self) 32 | } 33 | snapshotting.pathExtension = "json" 34 | return snapshotting 35 | } 36 | 37 | /// A snapshot strategy for comparing encodable structures based on their property list 38 | /// representation. 39 | /// 40 | /// ```swift 41 | /// assertSnapshot(of: user, as: .plist) 42 | /// ``` 43 | /// 44 | /// Records: 45 | /// 46 | /// ```xml 47 | /// 48 | /// 50 | /// 51 | /// 52 | /// bio 53 | /// Blobbed around the world. 54 | /// id 55 | /// 1 56 | /// name 57 | /// Blobby 58 | /// 59 | /// 60 | /// ``` 61 | public static var plist: Snapshotting { 62 | let encoder = PropertyListEncoder() 63 | encoder.outputFormat = .xml 64 | return .plist(encoder) 65 | } 66 | 67 | /// A snapshot strategy for comparing encodable structures based on their property list 68 | /// representation. 69 | /// 70 | /// - Parameter encoder: A property list encoder. 71 | public static func plist(_ encoder: PropertyListEncoder) -> Snapshotting { 72 | var snapshotting = SimplySnapshotting.lines.pullback { (encodable: Value) in 73 | try! String(decoding: encoder.encode(encodable), as: UTF8.self) 74 | } 75 | snapshotting.pathExtension = "plist" 76 | return snapshotting 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /Sources/SnapshotTesting/Snapshotting/NSBezierPath.swift: -------------------------------------------------------------------------------- 1 | #if os(macOS) 2 | import AppKit 3 | import Cocoa 4 | 5 | extension Snapshotting where Value == NSBezierPath, Format == NSImage { 6 | /// A snapshot strategy for comparing bezier paths based on pixel equality. 7 | public static var image: Snapshotting { 8 | return .image() 9 | } 10 | 11 | /// A snapshot strategy for comparing bezier paths based on pixel equality. 12 | /// 13 | ///``` swift 14 | /// // Match reference perfectly. 15 | /// assertSnapshot(of: path, as: .image) 16 | /// 17 | /// // Allow for a 1% pixel difference. 18 | /// assertSnapshot(of: path, as: .image(precision: 0.99)) 19 | /// ``` 20 | /// 21 | /// - Parameters: 22 | /// - precision: The percentage of pixels that must match. 23 | /// - perceptualPrecision: The percentage a pixel must match the source pixel to be considered a 24 | /// match. 98-99% mimics 25 | /// [the precision](http://zschuessler.github.io/DeltaE/learn/#toc-defining-delta-e) of the 26 | /// human eye. 27 | public static func image(precision: Float = 1, perceptualPrecision: Float = 1) -> Snapshotting { 28 | return SimplySnapshotting.image( 29 | precision: precision, perceptualPrecision: perceptualPrecision 30 | ).pullback { path in 31 | // Move path info frame: 32 | let bounds = path.bounds 33 | let transform = AffineTransform(translationByX: -bounds.origin.x, byY: -bounds.origin.y) 34 | path.transform(using: transform) 35 | 36 | let image = NSImage(size: path.bounds.size) 37 | image.lockFocus() 38 | path.fill() 39 | image.unlockFocus() 40 | return image 41 | } 42 | } 43 | } 44 | 45 | extension Snapshotting where Value == NSBezierPath, Format == String { 46 | /// A snapshot strategy for comparing bezier paths based on pixel equality. 47 | @available(macOS 11.0, *) 48 | @available(iOS 11.0, *) 49 | public static var elementsDescription: Snapshotting { 50 | return .elementsDescription(numberFormatter: defaultNumberFormatter) 51 | } 52 | 53 | /// A snapshot strategy for comparing bezier paths based on pixel equality. 54 | /// 55 | /// - Parameter numberFormatter: The number formatter used for formatting points. 56 | @available(macOS 11.0, *) 57 | @available(iOS 11.0, *) 58 | public static func elementsDescription(numberFormatter: NumberFormatter) -> Snapshotting { 59 | let namesByType: [NSBezierPath.ElementType: String] = [ 60 | .moveTo: "MoveTo", 61 | .lineTo: "LineTo", 62 | .curveTo: "CurveTo", 63 | .closePath: "Close", 64 | ] 65 | 66 | let numberOfPointsByType: [NSBezierPath.ElementType: Int] = [ 67 | .moveTo: 1, 68 | .lineTo: 1, 69 | .curveTo: 3, 70 | .closePath: 0, 71 | ] 72 | 73 | return SimplySnapshotting.lines.pullback { path in 74 | var string: String = "" 75 | 76 | var elementPoints = [CGPoint](repeating: .zero, count: 3) 77 | for elementIndex in 0.. Note: Snapshots must be compared on the same OS as the device that originally took the 14 | /// > reference to avoid discrepancies between images. 15 | /// 16 | /// - Parameters: 17 | /// - precision: The percentage of pixels that must match. 18 | /// - perceptualPrecision: The percentage a pixel must match the source pixel to be considered a 19 | /// match. 98-99% mimics 20 | /// [the precision](http://zschuessler.github.io/DeltaE/learn/#toc-defining-delta-e) of the 21 | /// human eye. 22 | /// - size: A view size override. 23 | public static func image( 24 | precision: Float = 1, perceptualPrecision: Float = 1, size: CGSize? = nil 25 | ) -> Snapshotting { 26 | return SimplySnapshotting.image( 27 | precision: precision, perceptualPrecision: perceptualPrecision 28 | ).asyncPullback { view in 29 | let initialSize = view.frame.size 30 | if let size = size { view.frame.size = size } 31 | guard view.frame.width > 0, view.frame.height > 0 else { 32 | fatalError("View not renderable to image at size \(view.frame.size)") 33 | } 34 | return view.snapshot 35 | ?? Async { callback in 36 | addImagesForRenderedViews(view).sequence().run { views in 37 | let bitmapRep = view.bitmapImageRepForCachingDisplay(in: view.bounds)! 38 | view.cacheDisplay(in: view.bounds, to: bitmapRep) 39 | let image = NSImage(size: view.bounds.size) 40 | image.addRepresentation(bitmapRep) 41 | callback(image) 42 | views.forEach { $0.removeFromSuperview() } 43 | view.frame.size = initialSize 44 | } 45 | } 46 | } 47 | } 48 | } 49 | 50 | extension Snapshotting where Value == NSView, Format == String { 51 | /// A snapshot strategy for comparing views based on a recursive description of their properties 52 | /// and hierarchies. 53 | /// 54 | /// ``` swift 55 | /// assertSnapshot(of: view, as: .recursiveDescription) 56 | /// ``` 57 | /// 58 | /// Records: 59 | /// 60 | /// ``` 61 | /// [ AF LU ] h=--- v=--- NSButton "Push Me" f=(0,0,77,32) b=(-) 62 | /// [ A LU ] h=--- v=--- NSButtonBezelView f=(0,0,77,32) b=(-) 63 | /// [ AF LU ] h=--- v=--- NSButtonTextField "Push Me" f=(10,6,57,16) b=(-) 64 | /// ``` 65 | public static var recursiveDescription: Snapshotting { 66 | return SimplySnapshotting.lines.pullback { view in 67 | return purgePointers( 68 | view.perform(Selector(("_subtreeDescription"))).retain().takeUnretainedValue() 69 | as! String 70 | ) 71 | } 72 | } 73 | } 74 | #endif 75 | -------------------------------------------------------------------------------- /Sources/SnapshotTesting/Snapshotting/NSViewController.swift: -------------------------------------------------------------------------------- 1 | #if os(macOS) 2 | import AppKit 3 | import Cocoa 4 | 5 | extension Snapshotting where Value == NSViewController, Format == NSImage { 6 | /// A snapshot strategy for comparing view controller views based on pixel equality. 7 | public static var image: Snapshotting { 8 | return .image() 9 | } 10 | 11 | /// A snapshot strategy for comparing view controller views based on pixel equality. 12 | /// 13 | /// - Parameters: 14 | /// - precision: The percentage of pixels that must match. 15 | /// - perceptualPrecision: The percentage a pixel must match the source pixel to be considered a 16 | /// match. 98-99% mimics 17 | /// [the precision](http://zschuessler.github.io/DeltaE/learn/#toc-defining-delta-e) of the 18 | /// human eye. 19 | /// - size: A view size override. 20 | public static func image( 21 | precision: Float = 1, perceptualPrecision: Float = 1, size: CGSize? = nil 22 | ) -> Snapshotting { 23 | return Snapshotting.image( 24 | precision: precision, perceptualPrecision: perceptualPrecision, size: size 25 | ).pullback { $0.view } 26 | } 27 | } 28 | 29 | extension Snapshotting where Value == NSViewController, Format == String { 30 | /// A snapshot strategy for comparing view controller views based on a recursive description of 31 | /// their properties and hierarchies. 32 | public static var recursiveDescription: Snapshotting { 33 | return Snapshotting.recursiveDescription.pullback { $0.view } 34 | } 35 | } 36 | #endif 37 | -------------------------------------------------------------------------------- /Sources/SnapshotTesting/Snapshotting/SceneKit.swift: -------------------------------------------------------------------------------- 1 | #if os(iOS) || os(macOS) || os(tvOS) 2 | import SceneKit 3 | #if os(macOS) 4 | import Cocoa 5 | #elseif os(iOS) || os(tvOS) 6 | import UIKit 7 | #endif 8 | 9 | #if os(macOS) 10 | extension Snapshotting where Value == SCNScene, Format == NSImage { 11 | /// A snapshot strategy for comparing SceneKit scenes based on pixel equality. 12 | /// 13 | /// - Parameters: 14 | /// - precision: The percentage of pixels that must match. 15 | /// - perceptualPrecision: The percentage a pixel must match the source pixel to be considered a 16 | /// match. 98-99% mimics 17 | /// [the precision](http://zschuessler.github.io/DeltaE/learn/#toc-defining-delta-e) of the 18 | /// human eye. 19 | /// - size: The size of the scene. 20 | public static func image(precision: Float = 1, perceptualPrecision: Float = 1, size: CGSize) 21 | -> Snapshotting 22 | { 23 | return .scnScene(precision: precision, perceptualPrecision: perceptualPrecision, size: size) 24 | } 25 | } 26 | #elseif os(iOS) || os(tvOS) 27 | extension Snapshotting where Value == SCNScene, Format == UIImage { 28 | /// A snapshot strategy for comparing SceneKit scenes based on pixel equality. 29 | /// 30 | /// - Parameters: 31 | /// - precision: The percentage of pixels that must match. 32 | /// - perceptualPrecision: The percentage a pixel must match the source pixel to be considered a 33 | /// match. 98-99% mimics 34 | /// [the precision](http://zschuessler.github.io/DeltaE/learn/#toc-defining-delta-e) of the 35 | /// human eye. 36 | /// - size: The size of the scene. 37 | public static func image(precision: Float = 1, perceptualPrecision: Float = 1, size: CGSize) 38 | -> Snapshotting 39 | { 40 | return .scnScene(precision: precision, perceptualPrecision: perceptualPrecision, size: size) 41 | } 42 | } 43 | #endif 44 | 45 | extension Snapshotting where Value == SCNScene, Format == Image { 46 | fileprivate static func scnScene(precision: Float, perceptualPrecision: Float, size: CGSize) 47 | -> Snapshotting 48 | { 49 | return Snapshotting.image( 50 | precision: precision, perceptualPrecision: perceptualPrecision 51 | ).pullback { scene in 52 | let view = SCNView(frame: .init(x: 0, y: 0, width: size.width, height: size.height)) 53 | view.scene = scene 54 | return view 55 | } 56 | } 57 | } 58 | #endif 59 | -------------------------------------------------------------------------------- /Sources/SnapshotTesting/Snapshotting/SpriteKit.swift: -------------------------------------------------------------------------------- 1 | #if os(iOS) || os(macOS) || os(tvOS) 2 | import SpriteKit 3 | #if os(macOS) 4 | import Cocoa 5 | #elseif os(iOS) || os(tvOS) 6 | import UIKit 7 | #endif 8 | 9 | #if os(macOS) 10 | extension Snapshotting where Value == SKScene, Format == NSImage { 11 | /// A snapshot strategy for comparing SpriteKit scenes based on pixel equality. 12 | /// 13 | /// - Parameters: 14 | /// - precision: The percentage of pixels that must match. 15 | /// - perceptualPrecision: The percentage a pixel must match the source pixel to be considered a 16 | /// match. 98-99% mimics 17 | /// [the precision](http://zschuessler.github.io/DeltaE/learn/#toc-defining-delta-e) of the 18 | /// human eye. 19 | /// - size: The size of the scene. 20 | public static func image(precision: Float = 1, perceptualPrecision: Float = 1, size: CGSize) 21 | -> Snapshotting 22 | { 23 | return .skScene(precision: precision, perceptualPrecision: perceptualPrecision, size: size) 24 | } 25 | } 26 | #elseif os(iOS) || os(tvOS) 27 | extension Snapshotting where Value == SKScene, Format == UIImage { 28 | /// A snapshot strategy for comparing SpriteKit scenes based on pixel equality. 29 | /// 30 | /// - Parameters: 31 | /// - precision: The percentage of pixels that must match. 32 | /// - perceptualPrecision: The percentage a pixel must match the source pixel to be considered a 33 | /// match. 98-99% mimics 34 | /// [the precision](http://zschuessler.github.io/DeltaE/learn/#toc-defining-delta-e) of the 35 | /// human eye. 36 | /// - size: The size of the scene. 37 | public static func image(precision: Float = 1, perceptualPrecision: Float = 1, size: CGSize) 38 | -> Snapshotting 39 | { 40 | return .skScene(precision: precision, perceptualPrecision: perceptualPrecision, size: size) 41 | } 42 | } 43 | #endif 44 | 45 | extension Snapshotting where Value == SKScene, Format == Image { 46 | fileprivate static func skScene(precision: Float, perceptualPrecision: Float, size: CGSize) 47 | -> Snapshotting 48 | { 49 | return Snapshotting.image( 50 | precision: precision, perceptualPrecision: perceptualPrecision 51 | ).pullback { scene in 52 | let view = SKView(frame: .init(x: 0, y: 0, width: size.width, height: size.height)) 53 | view.presentScene(scene) 54 | return view 55 | } 56 | } 57 | } 58 | #endif 59 | -------------------------------------------------------------------------------- /Sources/SnapshotTesting/Snapshotting/String.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import XCTest 3 | 4 | extension Snapshotting where Value == String, Format == String { 5 | /// A snapshot strategy for comparing strings based on equality. 6 | public static let lines = Snapshotting(pathExtension: "txt", diffing: .lines) 7 | } 8 | 9 | extension Diffing where Value == String { 10 | /// A line-diffing strategy for UTF-8 text. 11 | public static let lines = Diffing( 12 | toData: { Data($0.utf8) }, 13 | fromData: { String(decoding: $0, as: UTF8.self) } 14 | ) { old, new in 15 | guard old != new else { return nil } 16 | let hunks = chunk( 17 | diff: SnapshotTesting.diff( 18 | old.split(separator: "\n", omittingEmptySubsequences: false).map(String.init), 19 | new.split(separator: "\n", omittingEmptySubsequences: false).map(String.init) 20 | )) 21 | let failure = 22 | hunks 23 | .flatMap { [$0.patchMark] + $0.lines } 24 | .joined(separator: "\n") 25 | let attachment = XCTAttachment( 26 | data: Data(failure.utf8), uniformTypeIdentifier: "public.patch-file") 27 | return (failure, [attachment]) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Sources/SnapshotTesting/Snapshotting/SwiftUIView.swift: -------------------------------------------------------------------------------- 1 | #if canImport(SwiftUI) 2 | import Foundation 3 | import SwiftUI 4 | 5 | /// The size constraint for a snapshot (similar to `PreviewLayout`). 6 | public enum SwiftUISnapshotLayout { 7 | #if os(iOS) || os(tvOS) 8 | /// Center the view in a device container described by`config`. 9 | case device(config: ViewImageConfig) 10 | #endif 11 | /// Center the view in a fixed size container. 12 | case fixed(width: CGFloat, height: CGFloat) 13 | /// Fit the view to the ideal size that fits its content. 14 | case sizeThatFits 15 | } 16 | 17 | #if os(iOS) || os(tvOS) 18 | @available(iOS 13.0, tvOS 13.0, *) 19 | extension Snapshotting where Value: SwiftUI.View, Format == UIImage { 20 | 21 | /// A snapshot strategy for comparing SwiftUI Views based on pixel equality. 22 | public static var image: Snapshotting { 23 | return .image() 24 | } 25 | 26 | /// A snapshot strategy for comparing SwiftUI Views based on pixel equality. 27 | /// 28 | /// - Parameters: 29 | /// - drawHierarchyInKeyWindow: Utilize the simulator's key window in order to render 30 | /// `UIAppearance` and `UIVisualEffect`s. This option requires a host application for your 31 | /// tests and will _not_ work for framework test targets. 32 | /// - precision: The percentage of pixels that must match. 33 | /// - perceptualPrecision: The percentage a pixel must match the source pixel to be considered a 34 | /// match. 98-99% mimics 35 | /// [the precision](http://zschuessler.github.io/DeltaE/learn/#toc-defining-delta-e) of the 36 | /// human eye. 37 | /// - layout: A view layout override. 38 | /// - traits: A trait collection override. 39 | public static func image( 40 | drawHierarchyInKeyWindow: Bool = false, 41 | precision: Float = 1, 42 | perceptualPrecision: Float = 1, 43 | layout: SwiftUISnapshotLayout = .sizeThatFits, 44 | traits: UITraitCollection = .init() 45 | ) 46 | -> Snapshotting 47 | { 48 | let config: ViewImageConfig 49 | 50 | switch layout { 51 | #if os(iOS) || os(tvOS) 52 | case let .device(config: deviceConfig): 53 | config = deviceConfig 54 | #endif 55 | case .sizeThatFits: 56 | config = .init(safeArea: .zero, size: nil, traits: traits) 57 | case let .fixed(width: width, height: height): 58 | let size = CGSize(width: width, height: height) 59 | config = .init(safeArea: .zero, size: size, traits: traits) 60 | } 61 | 62 | return SimplySnapshotting.image( 63 | precision: precision, perceptualPrecision: perceptualPrecision, scale: traits.displayScale 64 | ).asyncPullback { view in 65 | var config = config 66 | 67 | let controller: UIViewController 68 | 69 | if config.size != nil { 70 | controller = UIHostingController.init( 71 | rootView: view 72 | ) 73 | } else { 74 | let hostingController = UIHostingController.init(rootView: view) 75 | 76 | let maxSize = CGSize(width: 0.0, height: 0.0) 77 | config.size = hostingController.sizeThatFits(in: maxSize) 78 | 79 | controller = hostingController 80 | } 81 | 82 | return snapshotView( 83 | config: config, 84 | drawHierarchyInKeyWindow: drawHierarchyInKeyWindow, 85 | traits: traits, 86 | view: controller.view, 87 | viewController: controller 88 | ) 89 | } 90 | } 91 | } 92 | #endif 93 | #endif 94 | -------------------------------------------------------------------------------- /Sources/SnapshotTesting/Snapshotting/UIBezierPath.swift: -------------------------------------------------------------------------------- 1 | #if os(iOS) || os(tvOS) 2 | import UIKit 3 | 4 | extension Snapshotting where Value == UIBezierPath, Format == UIImage { 5 | /// A snapshot strategy for comparing bezier paths based on pixel equality. 6 | public static var image: Snapshotting { 7 | return .image() 8 | } 9 | 10 | /// A snapshot strategy for comparing bezier paths based on pixel equality. 11 | /// 12 | /// - Parameters: 13 | /// - precision: The percentage of pixels that must match. 14 | /// - perceptualPrecision: The percentage a pixel must match the source pixel to be considered a 15 | /// match. 98-99% mimics 16 | /// [the precision](http://zschuessler.github.io/DeltaE/learn/#toc-defining-delta-e) of the 17 | /// human eye. 18 | /// - scale: The scale to use when loading the reference image from disk. 19 | public static func image( 20 | precision: Float = 1, perceptualPrecision: Float = 1, scale: CGFloat = 1 21 | ) -> Snapshotting { 22 | return SimplySnapshotting.image( 23 | precision: precision, perceptualPrecision: perceptualPrecision, scale: scale 24 | ).pullback { path in 25 | let bounds = path.bounds 26 | let format: UIGraphicsImageRendererFormat 27 | if #available(iOS 11.0, tvOS 11.0, *) { 28 | format = UIGraphicsImageRendererFormat.preferred() 29 | } else { 30 | format = UIGraphicsImageRendererFormat.default() 31 | } 32 | format.scale = scale 33 | return UIGraphicsImageRenderer(bounds: bounds, format: format).image { ctx in 34 | path.fill() 35 | } 36 | } 37 | } 38 | } 39 | 40 | @available(iOS 11.0, tvOS 11.0, *) 41 | extension Snapshotting where Value == UIBezierPath, Format == String { 42 | /// A snapshot strategy for comparing bezier paths based on pixel equality. 43 | public static var elementsDescription: Snapshotting { 44 | Snapshotting.elementsDescription.pullback { path in path.cgPath } 45 | } 46 | 47 | /// A snapshot strategy for comparing bezier paths based on pixel equality. 48 | /// 49 | /// - Parameter numberFormatter: The number formatter used for formatting points. 50 | public static func elementsDescription(numberFormatter: NumberFormatter) -> Snapshotting { 51 | Snapshotting.elementsDescription( 52 | numberFormatter: numberFormatter 53 | ).pullback { path in path.cgPath } 54 | } 55 | } 56 | #endif 57 | -------------------------------------------------------------------------------- /Sources/SnapshotTesting/Snapshotting/UIView.swift: -------------------------------------------------------------------------------- 1 | #if os(iOS) || os(tvOS) 2 | import UIKit 3 | 4 | extension Snapshotting where Value == UIView, Format == UIImage { 5 | /// A snapshot strategy for comparing views based on pixel equality. 6 | public static var image: Snapshotting { 7 | return .image() 8 | } 9 | 10 | /// A snapshot strategy for comparing views based on pixel equality. 11 | /// 12 | /// - Parameters: 13 | /// - drawHierarchyInKeyWindow: Utilize the simulator's key window in order to render 14 | /// `UIAppearance` and `UIVisualEffect`s. This option requires a host application for your 15 | /// tests and will _not_ work for framework test targets. 16 | /// - precision: The percentage of pixels that must match. 17 | /// - perceptualPrecision: The percentage a pixel must match the source pixel to be considered a 18 | /// match. 98-99% mimics 19 | /// [the precision](http://zschuessler.github.io/DeltaE/learn/#toc-defining-delta-e) of the 20 | /// human eye. 21 | /// - size: A view size override. 22 | /// - traits: A trait collection override. 23 | public static func image( 24 | drawHierarchyInKeyWindow: Bool = false, 25 | precision: Float = 1, 26 | perceptualPrecision: Float = 1, 27 | size: CGSize? = nil, 28 | traits: UITraitCollection = .init() 29 | ) 30 | -> Snapshotting 31 | { 32 | 33 | return SimplySnapshotting.image( 34 | precision: precision, perceptualPrecision: perceptualPrecision, scale: traits.displayScale 35 | ).asyncPullback { view in 36 | snapshotView( 37 | config: .init(safeArea: .zero, size: size ?? view.frame.size, traits: .init()), 38 | drawHierarchyInKeyWindow: drawHierarchyInKeyWindow, 39 | traits: traits, 40 | view: view, 41 | viewController: .init() 42 | ) 43 | } 44 | } 45 | } 46 | 47 | extension Snapshotting where Value == UIView, Format == String { 48 | /// A snapshot strategy for comparing views based on a recursive description of their properties 49 | /// and hierarchies. 50 | /// 51 | /// ``` swift 52 | /// s// Layout on the current device. 53 | /// assertSnapshot(of: view, as: .recursiveDescription) 54 | /// 55 | /// // Layout with a certain size. 56 | /// assertSnapshot(of: view, as: .recursiveDescription(size: .init(width: 22, height: 22))) 57 | /// 58 | /// // Layout with a certain trait collection. 59 | /// assertSnapshot(of: view, as: .recursiveDescription(traits: .init(horizontalSizeClass: .regular))) 60 | /// ``` 61 | /// 62 | /// Records: 63 | /// 64 | /// ``` 65 | /// > 66 | /// | > 67 | /// ``` 68 | public static var recursiveDescription: Snapshotting { 69 | return Snapshotting.recursiveDescription() 70 | } 71 | 72 | /// A snapshot strategy for comparing views based on a recursive description of their properties 73 | /// and hierarchies. 74 | public static func recursiveDescription( 75 | size: CGSize? = nil, 76 | traits: UITraitCollection = .init() 77 | ) 78 | -> Snapshotting 79 | { 80 | return SimplySnapshotting.lines.pullback { view in 81 | let dispose = prepareView( 82 | config: .init(safeArea: .zero, size: size ?? view.frame.size, traits: traits), 83 | drawHierarchyInKeyWindow: false, 84 | traits: .init(), 85 | view: view, 86 | viewController: .init() 87 | ) 88 | defer { dispose() } 89 | return purgePointers( 90 | view.perform(Selector(("recursiveDescription"))).retain().takeUnretainedValue() 91 | as! String 92 | ) 93 | } 94 | } 95 | } 96 | #endif 97 | -------------------------------------------------------------------------------- /Sources/SnapshotTesting/Snapshotting/URLRequest.swift: -------------------------------------------------------------------------------- 1 | #if !os(WASI) 2 | import Foundation 3 | 4 | #if canImport(FoundationNetworking) 5 | import FoundationNetworking 6 | #endif 7 | 8 | extension Snapshotting where Value == URLRequest, Format == String { 9 | /// A snapshot strategy for comparing requests based on raw equality. 10 | /// 11 | /// ``` swift 12 | /// assertSnapshot(of: request, as: .raw) 13 | /// ``` 14 | /// 15 | /// Records: 16 | /// 17 | /// ``` 18 | /// POST http://localhost:8080/account 19 | /// Cookie: pf_session={"userId":"1"} 20 | /// 21 | /// email=blob%40pointfree.co&name=Blob 22 | /// ``` 23 | public static let raw = Snapshotting.raw(pretty: false) 24 | 25 | /// A snapshot strategy for comparing requests based on raw equality. 26 | /// 27 | /// - Parameter pretty: Attempts to pretty print the body of the request (supports JSON). 28 | public static func raw(pretty: Bool) -> Snapshotting { 29 | return SimplySnapshotting.lines.pullback { (request: URLRequest) in 30 | let method = 31 | "\(request.httpMethod ?? "GET") \(request.url?.sortingQueryItems()?.absoluteString ?? "(null)")" 32 | 33 | let headers = (request.allHTTPHeaderFields ?? [:]) 34 | .map { key, value in "\(key): \(value)" } 35 | .sorted() 36 | 37 | let body: [String] 38 | do { 39 | if pretty, #available(iOS 11.0, macOS 10.13, tvOS 11.0, watchOS 4.0, *) { 40 | body = 41 | try request.httpBody 42 | .map { try JSONSerialization.jsonObject(with: $0, options: []) } 43 | .map { 44 | try JSONSerialization.data( 45 | withJSONObject: $0, options: [.prettyPrinted, .sortedKeys]) 46 | } 47 | .map { ["\n\(String(decoding: $0, as: UTF8.self))"] } 48 | ?? [] 49 | } else { 50 | throw NSError(domain: "co.pointfree.Never", code: 1, userInfo: nil) 51 | } 52 | } catch { 53 | body = 54 | request.httpBody 55 | .map { ["\n\(String(decoding: $0, as: UTF8.self))"] } 56 | ?? [] 57 | } 58 | 59 | return ([method] + headers + body).joined(separator: "\n") 60 | } 61 | } 62 | 63 | /// A snapshot strategy for comparing requests based on a cURL representation. 64 | /// 65 | // ``` swift 66 | // assertSnapshot(of: request, as: .curl) 67 | // ``` 68 | // 69 | // Records: 70 | // 71 | // ``` 72 | // curl \ 73 | // --request POST \ 74 | // --header "Accept: text/html" \ 75 | // --data 'pricing[billing]=monthly&pricing[lane]=individual' \ 76 | // "https://www.pointfree.co/subscribe" 77 | // ``` 78 | public static let curl = SimplySnapshotting.lines.pullback { (request: URLRequest) in 79 | 80 | var components = ["curl"] 81 | 82 | // HTTP Method 83 | let httpMethod = request.httpMethod! 84 | switch httpMethod { 85 | case "GET": break 86 | case "HEAD": components.append("--head") 87 | default: components.append("--request \(httpMethod)") 88 | } 89 | 90 | // Headers 91 | if let headers = request.allHTTPHeaderFields { 92 | for field in headers.keys.sorted() where field != "Cookie" { 93 | let escapedValue = headers[field]!.replacingOccurrences(of: "\"", with: "\\\"") 94 | components.append("--header \"\(field): \(escapedValue)\"") 95 | } 96 | } 97 | 98 | // Body 99 | if let httpBodyData = request.httpBody, 100 | let httpBody = String(data: httpBodyData, encoding: .utf8) 101 | { 102 | var escapedBody = httpBody.replacingOccurrences(of: "\\\"", with: "\\\\\"") 103 | escapedBody = escapedBody.replacingOccurrences(of: "\"", with: "\\\"") 104 | 105 | components.append("--data \"\(escapedBody)\"") 106 | } 107 | 108 | // Cookies 109 | if let cookie = request.allHTTPHeaderFields?["Cookie"] { 110 | let escapedValue = cookie.replacingOccurrences(of: "\"", with: "\\\"") 111 | components.append("--cookie \"\(escapedValue)\"") 112 | } 113 | 114 | // URL 115 | components.append("\"\(request.url!.sortingQueryItems()!.absoluteString)\"") 116 | 117 | return components.joined(separator: " \\\n\t") 118 | } 119 | } 120 | 121 | extension URL { 122 | fileprivate func sortingQueryItems() -> URL? { 123 | var components = URLComponents(url: self, resolvingAgainstBaseURL: false) 124 | let sortedQueryItems = components?.queryItems?.sorted { $0.name < $1.name } 125 | components?.queryItems = sortedQueryItems 126 | 127 | return components?.url 128 | } 129 | } 130 | #endif 131 | -------------------------------------------------------------------------------- /Sources/SnapshotTestingCustomDump/CustomDump.swift: -------------------------------------------------------------------------------- 1 | import CustomDump 2 | import SnapshotTesting 3 | 4 | extension Snapshotting where Format == String { 5 | /// A snapshot strategy for comparing any structure based on a 6 | /// [custom dump](https://github.com/pointfreeco/swift-custom-dump). 7 | /// 8 | /// ```swift 9 | /// assertSnapshot(of: user, as: .customDump) 10 | /// ``` 11 | /// 12 | /// Records: 13 | /// 14 | /// ``` 15 | /// User( 16 | /// bio: "Blobbed around the world.", 17 | /// id: 1, 18 | /// name: "Blobby" 19 | /// ) 20 | /// ``` 21 | public static var customDump: Snapshotting { 22 | SimplySnapshotting.lines.pullback(String.init(customDumping:)) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Tests/InlineSnapshotTestingTests/CustomDumpTests.swift: -------------------------------------------------------------------------------- 1 | #if canImport(Testing) 2 | import Testing 3 | import InlineSnapshotTesting 4 | import SnapshotTestingCustomDump 5 | 6 | extension BaseSuite { 7 | struct CustomDumpSnapshotTests { 8 | @Test func basics() { 9 | struct User { let id: Int, name: String, bio: String } 10 | let user = User(id: 1, name: "Blobby", bio: "Blobbed around the world.") 11 | assertInlineSnapshot(of: user, as: .customDump) { 12 | """ 13 | BaseSuite.CustomDumpSnapshotTests.User( 14 | id: 1, 15 | name: "Blobby", 16 | bio: "Blobbed around the world." 17 | ) 18 | """ 19 | } 20 | } 21 | } 22 | } 23 | #endif 24 | -------------------------------------------------------------------------------- /Tests/InlineSnapshotTestingTests/InlineSnapshotTesting.xctestplan: -------------------------------------------------------------------------------- 1 | { 2 | "configurations" : [ 3 | { 4 | "id" : "54C128DD-A06E-4F40-83B2-00CB6C7027E8", 5 | "name" : "Configuration 1", 6 | "options" : { 7 | 8 | } 9 | } 10 | ], 11 | "defaultOptions" : { 12 | 13 | }, 14 | "testTargets" : [ 15 | { 16 | "target" : { 17 | "containerPath" : "container:", 18 | "identifier" : "InlineSnapshotTestingTests", 19 | "name" : "InlineSnapshotTestingTests" 20 | } 21 | } 22 | ], 23 | "version" : 1 24 | } 25 | -------------------------------------------------------------------------------- /Tests/InlineSnapshotTestingTests/Internal/BaseSuite.swift: -------------------------------------------------------------------------------- 1 | #if canImport(Testing) 2 | import Testing 3 | import SnapshotTesting 4 | 5 | @Suite(.snapshots(record: .failed, diffTool: .ksdiff)) 6 | struct BaseSuite { 7 | } 8 | #endif 9 | -------------------------------------------------------------------------------- /Tests/InlineSnapshotTestingTests/Internal/BaseTestCase.swift: -------------------------------------------------------------------------------- 1 | import SnapshotTesting 2 | import XCTest 3 | 4 | class BaseTestCase: XCTestCase { 5 | override func invokeTest() { 6 | withSnapshotTesting( 7 | record: .failed, 8 | diffTool: .ksdiff 9 | ) { 10 | super.invokeTest() 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/AssertSnapshotSwiftTests.swift: -------------------------------------------------------------------------------- 1 | #if canImport(Testing) 2 | import Testing 3 | import Foundation 4 | import SnapshotTesting 5 | 6 | extension BaseSuite { 7 | struct AssertSnapshotTests { 8 | @Test(.snapshots(record: .missing)) func dump() { 9 | struct User { let id: Int, name: String, bio: String } 10 | let user = User(id: 1, name: "Blobby", bio: "Blobbed around the world.") 11 | assertSnapshot(of: user, as: .dump) 12 | } 13 | } 14 | 15 | @MainActor 16 | struct MainActorTests { 17 | @Test func dump() { 18 | struct User { let id: Int, name: String, bio: String } 19 | let user = User(id: 1, name: "Blobby", bio: "Blobbed around the world.") 20 | assertSnapshot(of: user, as: .dump) 21 | } 22 | } 23 | } 24 | #endif 25 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/DeprecationTests.swift: -------------------------------------------------------------------------------- 1 | import SnapshotTesting 2 | import XCTest 3 | 4 | final class DeprecationTests: XCTestCase { 5 | @available(*, deprecated) 6 | func testIsRecordingProxy() { 7 | SnapshotTesting.record = true 8 | XCTAssertEqual(isRecording, true) 9 | 10 | SnapshotTesting.record = false 11 | XCTAssertEqual(isRecording, false) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/Internal/BaseSuite.swift: -------------------------------------------------------------------------------- 1 | #if canImport(Testing) 2 | import Testing 3 | import SnapshotTesting 4 | 5 | @Suite(.snapshots(record: .failed, diffTool: .ksdiff)) 6 | struct BaseSuite { 7 | } 8 | #endif 9 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/Internal/BaseTestCase.swift: -------------------------------------------------------------------------------- 1 | import SnapshotTesting 2 | import XCTest 3 | 4 | class BaseTestCase: XCTestCase { 5 | override func invokeTest() { 6 | withSnapshotTesting( 7 | record: .failed, 8 | diffTool: .ksdiff 9 | ) { 10 | super.invokeTest() 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/Internal/TestHelpers.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | @testable import SnapshotTesting 4 | 5 | #if os(iOS) 6 | let platform = "ios" 7 | #elseif os(tvOS) 8 | let platform = "tvos" 9 | #elseif os(macOS) 10 | let platform = "macos" 11 | extension NSTextField { 12 | var text: String { 13 | get { return self.stringValue } 14 | set { self.stringValue = newValue } 15 | } 16 | } 17 | #endif 18 | 19 | #if os(macOS) || os(iOS) || os(tvOS) 20 | extension CGPath { 21 | /// Creates an approximation of a heart at a 45º angle with a circle above, using all available element types: 22 | static var heart: CGPath { 23 | let scale: CGFloat = 30.0 24 | let path = CGMutablePath() 25 | 26 | path.move(to: CGPoint(x: 0.0 * scale, y: 0.0 * scale)) 27 | path.addLine(to: CGPoint(x: 0.0 * scale, y: 2.0 * scale)) 28 | path.addQuadCurve( 29 | to: CGPoint(x: 1.0 * scale, y: 3.0 * scale), 30 | control: CGPoint(x: 0.125 * scale, y: 2.875 * scale) 31 | ) 32 | path.addQuadCurve( 33 | to: CGPoint(x: 2.0 * scale, y: 2.0 * scale), 34 | control: CGPoint(x: 1.875 * scale, y: 2.875 * scale) 35 | ) 36 | path.addCurve( 37 | to: CGPoint(x: 3.0 * scale, y: 1.0 * scale), 38 | control1: CGPoint(x: 2.5 * scale, y: 2.0 * scale), 39 | control2: CGPoint(x: 3.0 * scale, y: 1.5 * scale) 40 | ) 41 | path.addCurve( 42 | to: CGPoint(x: 2.0 * scale, y: 0.0 * scale), 43 | control1: CGPoint(x: 3.0 * scale, y: 0.5 * scale), 44 | control2: CGPoint(x: 2.5 * scale, y: 0.0 * scale) 45 | ) 46 | path.addLine(to: CGPoint(x: 0.0 * scale, y: 0.0 * scale)) 47 | path.closeSubpath() 48 | 49 | path.addEllipse( 50 | in: CGRect( 51 | origin: CGPoint(x: 2.0 * scale, y: 2.0 * scale), 52 | size: CGSize(width: scale, height: scale) 53 | )) 54 | 55 | return path 56 | } 57 | } 58 | #endif 59 | 60 | #if os(iOS) || os(tvOS) 61 | extension UIBezierPath { 62 | /// Creates an approximation of a heart at a 45º angle with a circle above, using all available element types: 63 | static var heart: UIBezierPath { 64 | UIBezierPath(cgPath: .heart) 65 | } 66 | } 67 | #endif 68 | 69 | #if os(macOS) 70 | extension NSBezierPath { 71 | /// Creates an approximation of a heart at a 45º angle with a circle above, using all available element types: 72 | static var heart: NSBezierPath { 73 | let scale: CGFloat = 30.0 74 | let path = NSBezierPath() 75 | 76 | path.move(to: CGPoint(x: 0.0 * scale, y: 0.0 * scale)) 77 | path.line(to: CGPoint(x: 0.0 * scale, y: 2.0 * scale)) 78 | path.curve( 79 | to: CGPoint(x: 1.0 * scale, y: 3.0 * scale), 80 | controlPoint1: CGPoint(x: 0.0 * scale, y: 2.5 * scale), 81 | controlPoint2: CGPoint(x: 0.5 * scale, y: 3.0 * scale) 82 | ) 83 | path.curve( 84 | to: CGPoint(x: 2.0 * scale, y: 2.0 * scale), 85 | controlPoint1: CGPoint(x: 1.5 * scale, y: 3.0 * scale), 86 | controlPoint2: CGPoint(x: 2.0 * scale, y: 2.5 * scale) 87 | ) 88 | path.curve( 89 | to: CGPoint(x: 3.0 * scale, y: 1.0 * scale), 90 | controlPoint1: CGPoint(x: 2.5 * scale, y: 2.0 * scale), 91 | controlPoint2: CGPoint(x: 3.0 * scale, y: 1.5 * scale) 92 | ) 93 | path.curve( 94 | to: CGPoint(x: 2.0 * scale, y: 0.0 * scale), 95 | controlPoint1: CGPoint(x: 3.0 * scale, y: 0.5 * scale), 96 | controlPoint2: CGPoint(x: 2.5 * scale, y: 0.0 * scale) 97 | ) 98 | path.line(to: CGPoint(x: 0.0 * scale, y: 0.0 * scale)) 99 | path.close() 100 | 101 | path.appendOval( 102 | in: CGRect( 103 | origin: CGPoint(x: 2.0 * scale, y: 2.0 * scale), 104 | size: CGSize(width: scale, height: scale) 105 | )) 106 | 107 | return path 108 | } 109 | } 110 | #endif 111 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/SnapshotsTraitTests.swift: -------------------------------------------------------------------------------- 1 | #if compiler(>=6) && canImport(Testing) 2 | import Testing 3 | @_spi(Internals) import SnapshotTesting 4 | 5 | extension BaseSuite { 6 | struct SnapshotsTraitTests { 7 | @Test(.snapshots(diffTool: "ksdiff")) 8 | func testDiffTool() { 9 | #expect( 10 | _diffTool(currentFilePath: "old.png", failedFilePath: "new.png") 11 | == "ksdiff old.png new.png" 12 | ) 13 | } 14 | 15 | @Suite(.snapshots(diffTool: "ksdiff")) 16 | struct OverrideDiffTool { 17 | @Test(.snapshots(diffTool: "difftool")) 18 | func testDiffToolOverride() { 19 | #expect( 20 | _diffTool(currentFilePath: "old.png", failedFilePath: "new.png") 21 | == "difftool old.png new.png" 22 | ) 23 | } 24 | 25 | @Suite(.snapshots(record: .all)) 26 | struct OverrideRecord { 27 | @Test 28 | func config() { 29 | #expect( 30 | _diffTool(currentFilePath: "old.png", failedFilePath: "new.png") 31 | == "ksdiff old.png new.png" 32 | ) 33 | #expect(_record == .all) 34 | } 35 | 36 | @Suite(.snapshots(record: .failed, diffTool: "diff")) 37 | struct OverrideDiffToolAndRecord { 38 | @Test 39 | func config() { 40 | #expect( 41 | _diffTool(currentFilePath: "old.png", failedFilePath: "new.png") 42 | == "diff old.png new.png" 43 | ) 44 | #expect(_record == .failed) 45 | } 46 | } 47 | } 48 | } 49 | } 50 | } 51 | #endif 52 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/SwiftTestingTests.swift: -------------------------------------------------------------------------------- 1 | #if compiler(>=6) && canImport(Testing) 2 | import Testing 3 | import SnapshotTesting 4 | 5 | extension BaseSuite { 6 | @Suite(.serialized, .snapshots(record: .missing)) 7 | struct SwiftTestingTests { 8 | @Test func testSnapshot() { 9 | assertSnapshot(of: ["Hello", "World"], as: .dump, named: "snap") 10 | withKnownIssue { 11 | assertSnapshot(of: ["Goodbye", "World"], as: .dump, named: "snap") 12 | } matching: { issue in 13 | issue.description.hasSuffix( 14 | """ 15 | @@ −1,4 +1,4 @@ 16 |  ▿ 2 elements 17 | − - "Hello" 18 | + - "Goodbye" 19 |   - "World" 20 | """) 21 | } 22 | } 23 | } 24 | } 25 | #endif 26 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/WaitTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | @testable import SnapshotTesting 4 | 5 | class WaitTests: BaseTestCase { 6 | func testWait() { 7 | var value = "Hello" 8 | DispatchQueue.main.asyncAfter(deadline: .now() + 1) { 9 | value = "Goodbye" 10 | } 11 | 12 | let strategy = Snapshotting.lines.pullback { (_: Void) in 13 | value 14 | } 15 | 16 | assertSnapshot(of: (), as: .wait(for: 1.5, on: strategy)) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/WithSnapshotTestingTests.swift: -------------------------------------------------------------------------------- 1 | @_spi(Internals) @testable import SnapshotTesting 2 | import XCTest 3 | 4 | class WithSnapshotTestingTests: XCTestCase { 5 | func testNesting() { 6 | withSnapshotTesting(record: .all) { 7 | XCTAssertEqual( 8 | SnapshotTestingConfiguration.current? 9 | .diffTool?(currentFilePath: "old.png", failedFilePath: "new.png"), 10 | """ 11 | @− 12 | "file://old.png" 13 | @+ 14 | "file://new.png" 15 | 16 | To configure output for a custom diff tool, use 'withSnapshotTesting'. For example: 17 | 18 | withSnapshotTesting(diffTool: .ksdiff) { 19 | // ... 20 | } 21 | """ 22 | ) 23 | XCTAssertEqual(SnapshotTestingConfiguration.current?.record, .all) 24 | withSnapshotTesting(diffTool: "ksdiff") { 25 | XCTAssertEqual( 26 | SnapshotTestingConfiguration.current? 27 | .diffTool?(currentFilePath: "old.png", failedFilePath: "new.png"), 28 | "ksdiff old.png new.png" 29 | ) 30 | XCTAssertEqual(SnapshotTestingConfiguration.current?.record, .all) 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Fixtures__/earth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Fixtures__/earth.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Fixtures__/testImagePrecision.reference.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Fixtures__/testImagePrecision.reference.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/AssertSnapshotSwiftTests/dump.1.txt: -------------------------------------------------------------------------------- 1 | ▿ User 2 | - bio: "Blobbed around the world." 3 | - id: 1 4 | - name: "Blobby" 5 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/AssertSnapshotSwiftTests/dump.2.txt: -------------------------------------------------------------------------------- 1 | ▿ User 2 | - bio: "Blobbed around the world." 3 | - id: 1 4 | - name: "Blobby" 5 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testAny.1.txt: -------------------------------------------------------------------------------- 1 | ▿ User 2 | - bio: "Blobbed around the world." 3 | - id: 1 4 | - name: "Blobby" 5 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testAnyAsJson.1.json: -------------------------------------------------------------------------------- 1 | { 2 | "bio" : "Blobbed around the world.", 3 | "id" : 1, 4 | "name" : "Blobby" 5 | } -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testAnySnapshotStringConvertible.character.txt: -------------------------------------------------------------------------------- 1 | - "a" 2 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testAnySnapshotStringConvertible.data.txt: -------------------------------------------------------------------------------- 1 | - 13 bytes 2 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testAnySnapshotStringConvertible.date.txt: -------------------------------------------------------------------------------- 1 | - 2001-01-01T00:00:00Z 2 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testAnySnapshotStringConvertible.nsobject.txt: -------------------------------------------------------------------------------- 1 | - 2 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testAnySnapshotStringConvertible.string.txt: -------------------------------------------------------------------------------- 1 | - "Hello, world!" 2 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testAnySnapshotStringConvertible.substring.txt: -------------------------------------------------------------------------------- 1 | - "Hello" 2 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testAnySnapshotStringConvertible.url.txt: -------------------------------------------------------------------------------- 1 | - https://www.pointfree.co 2 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testAssertMultipleSnapshot.1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testAssertMultipleSnapshot.1.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testAssertMultipleSnapshot.2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testAssertMultipleSnapshot.2.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testAssertMultipleSnapshot.iPad-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testAssertMultipleSnapshot.iPad-image.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testAssertMultipleSnapshot.iPhoneSE-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testAssertMultipleSnapshot.iPhoneSE-image.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testAutolayout.1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testAutolayout.1.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testCALayer.1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testCALayer.1.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testCALayerWithGradient.1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testCALayerWithGradient.1.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testCGPath.iOS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testCGPath.iOS.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testCGPath.iOS.txt: -------------------------------------------------------------------------------- 1 | MoveTo (0.0, 0.0) 2 | LineTo (0.0, 60.0) 3 | QuadCurveTo (3.75, 86.25) (30.0, 90.0) 4 | QuadCurveTo (56.25, 86.25) (60.0, 60.0) 5 | CurveTo (75.0, 60.0) (90.0, 45.0) (90.0, 30.0) 6 | CurveTo (90.0, 15.0) (75.0, 0.0) (60.0, 0.0) 7 | LineTo (0.0, 0.0) 8 | Close 9 | 10 | MoveTo (90.0, 75.0) 11 | CurveTo (90.0, 83.284) (83.284, 90.0) (75.0, 90.0) 12 | CurveTo (66.716, 90.0) (60.0, 83.284) (60.0, 75.0) 13 | CurveTo (60.0, 66.716) (66.716, 60.0) (75.0, 60.0) 14 | CurveTo (83.284, 60.0) (90.0, 66.716) (90.0, 75.0) 15 | Close 16 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testCGPath.macOS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testCGPath.macOS.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testCGPath.macOS.txt: -------------------------------------------------------------------------------- 1 | MoveTo (0.0, 0.0) 2 | LineTo (0.0, 60.0) 3 | QuadCurveTo (3.75, 86.25) (30.0, 90.0) 4 | QuadCurveTo (56.25, 86.25) (60.0, 60.0) 5 | CurveTo (75.0, 60.0) (90.0, 45.0) (90.0, 30.0) 6 | CurveTo (90.0, 15.0) (75.0, 0.0) (60.0, 0.0) 7 | LineTo (0.0, 0.0) 8 | Close 9 | 10 | MoveTo (90.0, 75.0) 11 | CurveTo (90.0, 83.284) (83.284, 90.0) (75.0, 90.0) 12 | CurveTo (66.716, 90.0) (60.0, 83.284) (60.0, 75.0) 13 | CurveTo (60.0, 66.716) (66.716, 60.0) (75.0, 60.0) 14 | CurveTo (83.284, 60.0) (90.0, 66.716) (90.0, 75.0) 15 | Close 16 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testCGPath.tvOS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testCGPath.tvOS.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testCGPath.tvOS.txt: -------------------------------------------------------------------------------- 1 | MoveTo (0.0, 0.0) 2 | LineTo (0.0, 60.0) 3 | QuadCurveTo (3.75, 86.25) (30.0, 90.0) 4 | QuadCurveTo (56.25, 86.25) (60.0, 60.0) 5 | CurveTo (75.0, 60.0) (90.0, 45.0) (90.0, 30.0) 6 | CurveTo (90.0, 15.0) (75.0, 0.0) (60.0, 0.0) 7 | LineTo (0.0, 0.0) 8 | Close 9 | 10 | MoveTo (90.0, 75.0) 11 | CurveTo (90.0, 83.284) (83.284, 90.0) (75.0, 90.0) 12 | CurveTo (66.716, 90.0) (60.0, 83.284) (60.0, 75.0) 13 | CurveTo (60.0, 66.716) (66.716, 60.0) (75.0, 60.0) 14 | CurveTo (83.284, 60.0) (90.0, 66.716) (90.0, 75.0) 15 | Close 16 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testCaseIterable.1.csv: -------------------------------------------------------------------------------- 1 | "up","left" 2 | "down","right" 3 | "left","down" 4 | "right","up" -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testCollectionViewsWithMultipleScreenSizes.ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testCollectionViewsWithMultipleScreenSizes.ipad.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testCollectionViewsWithMultipleScreenSizes.iphone8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testCollectionViewsWithMultipleScreenSizes.iphone8.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testCollectionViewsWithMultipleScreenSizes.iphoneMax.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testCollectionViewsWithMultipleScreenSizes.iphoneMax.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testCollectionViewsWithMultipleScreenSizes.iphoneSe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testCollectionViewsWithMultipleScreenSizes.iphoneSe.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testData.1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testData.1 -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testDeterministicDictionaryAndSetSnapshots.1.txt: -------------------------------------------------------------------------------- 1 | ▿ DictionarySetContainer 2 | ▿ dict: 3 key/value pairs 3 | ▿ (2 elements) 4 | - key: "a" 5 | - value: 1 6 | ▿ (2 elements) 7 | - key: "b" 8 | - value: 2 9 | ▿ (2 elements) 10 | - key: "c" 11 | - value: 3 12 | ▿ set: 2 members 13 | ▿ Person 14 | - name: "Brandon" 15 | ▿ Person 16 | - name: "Stephen" 17 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testEmbeddedWebView.ios.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testEmbeddedWebView.ios.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testEncodable.1.json: -------------------------------------------------------------------------------- 1 | { 2 | "bio" : "Blobbed around the world.", 3 | "id" : 1, 4 | "name" : "Blobby" 5 | } -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testEncodable.2.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | bio 6 | Blobbed around the world. 7 | id 8 | 1 9 | name 10 | Blobby 11 | 12 | 13 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testImagePrecision.exact.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testImagePrecision.exact.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testImagePrecision.perceptual.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testImagePrecision.perceptual.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testMixedViews.ios.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testMixedViews.ios.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testMixedViews.macos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testMixedViews.macos.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testMultipleSnapshots.1.txt: -------------------------------------------------------------------------------- 1 | ▿ 1 element 2 | - 1 3 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testMultipleSnapshots.2.txt: -------------------------------------------------------------------------------- 1 | ▿ 2 elements 2 | - 1 3 | - 2 4 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testNSBezierPath.macOS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testNSBezierPath.macOS.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testNSBezierPath.macOS.txt: -------------------------------------------------------------------------------- 1 | MoveTo (0.0, 0.0) 2 | LineTo (0.0, 60.0) 3 | CurveTo (0.0, 75.0) (15.0, 90.0) (30.0, 90.0) 4 | CurveTo (45.0, 90.0) (60.0, 75.0) (60.0, 60.0) 5 | CurveTo (75.0, 60.0) (90.0, 45.0) (90.0, 30.0) 6 | CurveTo (90.0, 15.0) (75.0, 0.0) (60.0, 0.0) 7 | LineTo (0.0, 0.0) 8 | Close 9 | 10 | MoveTo (85.607, 64.393) 11 | CurveTo (91.464, 70.251) (91.464, 79.749) (85.607, 85.607) 12 | CurveTo (79.749, 91.464) (70.251, 91.464) (64.393, 85.607) 13 | CurveTo (58.536, 79.749) (58.536, 70.251) (64.393, 64.393) 14 | CurveTo (70.251, 58.536) (79.749, 58.536) (85.607, 64.393) 15 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testNSView.1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testNSView.1.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testNSView.2.txt: -------------------------------------------------------------------------------- 1 | [ AF ! wLU ] h=--- v=--- NSButton "Push Me" f=(0,0,87,32) b=(-) => 2 | [ A ! wLU ] h=--- v=--- NSButtonBezelView f=(0,0,87,32) b=(-) => 3 | [ AF ! wLU ] h=--- v=--- NSButtonTextField "Push Me" f=(11,6,65,16) b=(-) => 4 | A=autoresizesSubviews, C=canDrawConcurrently, D=needsDisplay, F=flipped, G=gstate, H=hidden (h=by ancestor), L=needsLayout (l=child needsLayout), U=needsUpdateConstraints (u=child needsUpdateConstraints), O=opaque, P=preservesContentDuringLiveResize, S=scaled/rotated, W=wantsLayer (w=ancestor wantsLayer), V=needsVibrancy (v=allowsVibrancy), #=has surface 5 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testNSViewWithLayer.1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testNSViewWithLayer.1.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testNSViewWithLayer.2.txt: -------------------------------------------------------------------------------- 1 | [ A ! W U ] h=--- v=--- NSView f=(0,0,10,10) b=(-) => 2 | A=autoresizesSubviews, C=canDrawConcurrently, D=needsDisplay, F=flipped, G=gstate, H=hidden (h=by ancestor), L=needsLayout (l=child needsLayout), U=needsUpdateConstraints (u=child needsUpdateConstraints), O=opaque, P=preservesContentDuringLiveResize, S=scaled/rotated, W=wantsLayer (w=ancestor wantsLayer), V=needsVibrancy (v=allowsVibrancy), #=has surface 3 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testNamedAssertion.named.txt: -------------------------------------------------------------------------------- 1 | ▿ User 2 | - bio: "Blobbed around the world." 3 | - id: 1 4 | - name: "Blobby" 5 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testPrecision.ios.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testPrecision.ios.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testPrecision.macos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testPrecision.macos.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testPrecision.tvos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testPrecision.tvos.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testRecursion.1.txt: -------------------------------------------------------------------------------- 1 | ▿ Father 2 | ▿ child: Optional 3 | ▿ some: Child 4 | ▿ father (circular reference detected) 5 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testRecursion.2.txt: -------------------------------------------------------------------------------- 1 | ▿ Child 2 | ▿ father: Father 3 | ▿ child: Optional 4 | ▿ some (circular reference detected) 5 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testSCNView.ios.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testSCNView.ios.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testSCNView.macos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testSCNView.macos.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testSCNView.tvos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testSCNView.tvos.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testSKView.ios.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testSKView.ios.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testSKView.macos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testSKView.macos.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testSKView.tvos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testSKView.tvos.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testSwiftUIView_iOS.1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testSwiftUIView_iOS.1.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testSwiftUIView_iOS.device.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testSwiftUIView_iOS.device.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testSwiftUIView_iOS.fixed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testSwiftUIView_iOS.fixed.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testSwiftUIView_iOS.size-that-fits.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testSwiftUIView_iOS.size-that-fits.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testSwiftUIView_tvOS.1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testSwiftUIView_tvOS.1.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testSwiftUIView_tvOS.device.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testSwiftUIView_tvOS.device.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testSwiftUIView_tvOS.fixed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testSwiftUIView_tvOS.fixed.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testSwiftUIView_tvOS.size-that-fits.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testSwiftUIView_tvOS.size-that-fits.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTableViewController.1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTableViewController.1.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-10-2-33-split-portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-10-2-33-split-portrait.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-10-2-50-split-landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-10-2-50-split-landscape.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-10-2-66-split-landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-10-2-66-split-landscape.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-10-2-66-split-portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-10-2-66-split-portrait.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-10-2-alternative.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-10-2-alternative.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-10-2-split-landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-10-2-split-landscape.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-10-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-10-2.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-10-2.txt: -------------------------------------------------------------------------------- 1 | > 2 | | > 3 | | > 4 | | > 5 | | > -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-9-7-33-split-landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-9-7-33-split-landscape.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-9-7-33-split-portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-9-7-33-split-portrait.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-9-7-50-split-landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-9-7-50-split-landscape.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-9-7-66-split-landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-9-7-66-split-landscape.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-9-7-66-split-portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-9-7-66-split-portrait.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-9-7-alternative.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-9-7-alternative.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-9-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-9-7.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-9-7.txt: -------------------------------------------------------------------------------- 1 | > 2 | | > 3 | | > 4 | | > 5 | | > -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-mini-33-split-landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-mini-33-split-landscape.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-mini-33-split-portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-mini-33-split-portrait.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-mini-50-split-landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-mini-50-split-landscape.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-mini-66-split-landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-mini-66-split-landscape.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-mini-66-split-portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-mini-66-split-portrait.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-mini-alternative.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-mini-alternative.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-mini.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-mini.txt: -------------------------------------------------------------------------------- 1 | > 2 | | > 3 | | > 4 | | > 5 | | > -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-10-5-alternative.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-10-5-alternative.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-10-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-10-5.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-10-5.txt: -------------------------------------------------------------------------------- 1 | > 2 | | > 3 | | > 4 | | > 5 | | > -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-10inch-33-split-landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-10inch-33-split-landscape.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-10inch-33-split-portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-10inch-33-split-portrait.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-10inch-50-split-landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-10inch-50-split-landscape.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-10inch-66-split-landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-10inch-66-split-landscape.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-10inch-66-split-portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-10inch-66-split-portrait.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-11-alternative.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-11-alternative.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-11.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-11.txt: -------------------------------------------------------------------------------- 1 | > 2 | | > 3 | | > 4 | | > 5 | | > -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-11inch-33-split-landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-11inch-33-split-landscape.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-11inch-33-split-portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-11inch-33-split-portrait.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-11inch-50-split-landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-11inch-50-split-landscape.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-11inch-66-split-landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-11inch-66-split-landscape.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-11inch-66-split-portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-11inch-66-split-portrait.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-12-9-alternative.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-12-9-alternative.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-12-9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-12-9.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-12-9.txt: -------------------------------------------------------------------------------- 1 | > 2 | | > 3 | | > 4 | | > 5 | | > -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-12inch-33-split-landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-12inch-33-split-landscape.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-12inch-33-split-portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-12inch-33-split-portrait.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-12inch-50-split-landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-12inch-50-split-landscape.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-12inch-66-split-landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-12inch-66-split-landscape.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-12inch-66-split-portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.ipad-pro-12inch-66-split-portrait.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-8-alternative.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-8-alternative.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-8-plus-alternative.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-8-plus-alternative.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-8-plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-8-plus.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-8-plus.txt: -------------------------------------------------------------------------------- 1 | > 2 | | > 3 | | > 4 | | > 5 | | > -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-8.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-8.txt: -------------------------------------------------------------------------------- 1 | > 2 | | > 3 | | > 4 | | > 5 | | > -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-se-accessibility-extra-extra-extra-large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-se-accessibility-extra-extra-extra-large.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-se-accessibility-extra-extra-large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-se-accessibility-extra-extra-large.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-se-accessibility-extra-large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-se-accessibility-extra-large.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-se-accessibility-large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-se-accessibility-large.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-se-accessibility-medium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-se-accessibility-medium.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-se-alternative.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-se-alternative.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-se-extra-extra-extra-large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-se-extra-extra-extra-large.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-se-extra-extra-large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-se-extra-extra-large.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-se-extra-large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-se-extra-large.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-se-extra-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-se-extra-small.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-se-large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-se-large.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-se-medium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-se-medium.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-se-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-se-small.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-se.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-se.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-se.txt: -------------------------------------------------------------------------------- 1 | > 2 | | > 3 | | > 4 | | > 5 | | > -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-x-alternative.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-x-alternative.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-x.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-x.txt: -------------------------------------------------------------------------------- 1 | > 2 | | > 3 | | > 4 | | > 5 | | > -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-xr-alternative.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-xr-alternative.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-xr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-xr.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-xr.txt: -------------------------------------------------------------------------------- 1 | > 2 | | > 3 | | > 4 | | > 5 | | > -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-xs-max-alternative.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-xs-max-alternative.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-xs-max.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-xs-max.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.iphone-xs-max.txt: -------------------------------------------------------------------------------- 1 | > 2 | | > 3 | | > 4 | | > 5 | | > -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.tv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.tv.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.tv4k.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraits.tv4k.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.ipad-10-2-alternative.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.ipad-10-2-alternative.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.ipad-10-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.ipad-10-2.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.ipad-9-7-alternative.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.ipad-9-7-alternative.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.ipad-9-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.ipad-9-7.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.ipad-mini-alternative.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.ipad-mini-alternative.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.ipad-mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.ipad-mini.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.ipad-pro-10-5-alternative.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.ipad-pro-10-5-alternative.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.ipad-pro-10-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.ipad-pro-10-5.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.ipad-pro-11-alternative.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.ipad-pro-11-alternative.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.ipad-pro-11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.ipad-pro-11.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.ipad-pro-12-9-alternative.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.ipad-pro-12-9-alternative.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.ipad-pro-12-9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.ipad-pro-12-9.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.iphone-8-alternative.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.iphone-8-alternative.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.iphone-8-plus-alternative.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.iphone-8-plus-alternative.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.iphone-8-plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.iphone-8-plus.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.iphone-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.iphone-8.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.iphone-se-alternative.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.iphone-se-alternative.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.iphone-se.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.iphone-se.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.iphone-x-alternative.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.iphone-x-alternative.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.iphone-x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.iphone-x.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.iphone-xr-alternative.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.iphone-xr-alternative.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.iphone-xr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.iphone-xr.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.iphone-xs-max-alternative.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.iphone-xs-max-alternative.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.iphone-xs-max.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsEmbeddedInTabNavigation.iphone-xs-max.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsWithView.label-accessibility-extra-extra-extra-large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsWithView.label-accessibility-extra-extra-extra-large.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsWithView.label-accessibility-extra-extra-large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsWithView.label-accessibility-extra-extra-large.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsWithView.label-accessibility-extra-large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsWithView.label-accessibility-extra-large.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsWithView.label-accessibility-large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsWithView.label-accessibility-large.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsWithView.label-accessibility-medium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsWithView.label-accessibility-medium.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsWithView.label-extra-extra-extra-large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsWithView.label-extra-extra-extra-large.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsWithView.label-extra-extra-large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsWithView.label-extra-extra-large.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsWithView.label-extra-large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsWithView.label-extra-large.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsWithView.label-extra-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsWithView.label-extra-small.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsWithView.label-large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsWithView.label-large.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsWithView.label-medium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsWithView.label-medium.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsWithView.label-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsWithView.label-small.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsWithViewController.label-accessibility-extra-extra-extra-large.txt: -------------------------------------------------------------------------------- 1 | > 2 | | > -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsWithViewController.label-accessibility-extra-extra-large.txt: -------------------------------------------------------------------------------- 1 | > 2 | | > -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsWithViewController.label-accessibility-extra-large.txt: -------------------------------------------------------------------------------- 1 | > 2 | | > -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsWithViewController.label-accessibility-large.txt: -------------------------------------------------------------------------------- 1 | > 2 | | > -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsWithViewController.label-accessibility-medium.txt: -------------------------------------------------------------------------------- 1 | > 2 | | > -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsWithViewController.label-extra-extra-extra-large.txt: -------------------------------------------------------------------------------- 1 | > 2 | | > -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsWithViewController.label-extra-extra-large.txt: -------------------------------------------------------------------------------- 1 | > 2 | | > -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsWithViewController.label-extra-large.txt: -------------------------------------------------------------------------------- 1 | > 2 | | > -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsWithViewController.label-extra-small.txt: -------------------------------------------------------------------------------- 1 | > 2 | | > -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsWithViewController.label-large.txt: -------------------------------------------------------------------------------- 1 | > 2 | | > -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsWithViewController.label-medium.txt: -------------------------------------------------------------------------------- 1 | > 2 | | > -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testTraitsWithViewController.label-small.txt: -------------------------------------------------------------------------------- 1 | > 2 | | > -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testUIBezierPath.iOS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testUIBezierPath.iOS.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testUIBezierPath.iOS.txt: -------------------------------------------------------------------------------- 1 | MoveTo (0.0, 0.0) 2 | LineTo (0.0, 60.0) 3 | QuadCurveTo (3.75, 86.25) (30.0, 90.0) 4 | QuadCurveTo (56.25, 86.25) (60.0, 60.0) 5 | CurveTo (75.0, 60.0) (90.0, 45.0) (90.0, 30.0) 6 | CurveTo (90.0, 15.0) (75.0, 0.0) (60.0, 0.0) 7 | LineTo (0.0, 0.0) 8 | Close 9 | 10 | MoveTo (90.0, 75.0) 11 | CurveTo (90.0, 83.284) (83.284, 90.0) (75.0, 90.0) 12 | CurveTo (66.716, 90.0) (60.0, 83.284) (60.0, 75.0) 13 | CurveTo (60.0, 66.716) (66.716, 60.0) (75.0, 60.0) 14 | CurveTo (83.284, 60.0) (90.0, 66.716) (90.0, 75.0) 15 | Close 16 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testUIBezierPath.tvOS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testUIBezierPath.tvOS.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testUIBezierPath.tvOS.txt: -------------------------------------------------------------------------------- 1 | MoveTo (0.0, 0.0) 2 | LineTo (0.0, 60.0) 3 | QuadCurveTo (3.75, 86.25) (30.0, 90.0) 4 | QuadCurveTo (56.25, 86.25) (60.0, 60.0) 5 | CurveTo (75.0, 60.0) (90.0, 45.0) (90.0, 30.0) 6 | CurveTo (90.0, 15.0) (75.0, 0.0) (60.0, 0.0) 7 | LineTo (0.0, 0.0) 8 | Close 9 | 10 | MoveTo (90.0, 75.0) 11 | CurveTo (90.0, 83.284) (83.284, 90.0) (75.0, 90.0) 12 | CurveTo (66.716, 90.0) (60.0, 83.284) (60.0, 75.0) 13 | CurveTo (60.0, 66.716) (66.716, 60.0) (75.0, 60.0) 14 | CurveTo (83.284, 60.0) (90.0, 66.716) (90.0, 75.0) 15 | Close 16 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testUIView.1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testUIView.1.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testUIView.2.txt: -------------------------------------------------------------------------------- 1 | > 2 | | > -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testUIViewControllerLifeCycle.1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testUIViewControllerLifeCycle.1.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testUIViewControllerLifeCycle.2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testUIViewControllerLifeCycle.2.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testURLRequest.get-curl.txt: -------------------------------------------------------------------------------- 1 | curl \ 2 | --header "Accept: text/html" \ 3 | --header "Content-Type: application/json" \ 4 | --cookie "pf_session={}" \ 5 | "https://www.pointfree.co/" -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testURLRequest.get-with-query-curl.txt: -------------------------------------------------------------------------------- 1 | curl \ 2 | --header "Accept: text/html" \ 3 | --header "Content-Type: application/json" \ 4 | --cookie "pf_session={}" \ 5 | "https://www.pointfree.co?key_1=value_1&key_2=value_2&key_3=value_3" -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testURLRequest.get-with-query.txt: -------------------------------------------------------------------------------- 1 | GET https://www.pointfree.co?key_1=value_1&key_2=value_2&key_3=value_3 2 | Accept: text/html 3 | Content-Type: application/json 4 | Cookie: pf_session={} -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testURLRequest.get.txt: -------------------------------------------------------------------------------- 1 | GET https://www.pointfree.co/ 2 | Accept: text/html 3 | Content-Type: application/json 4 | Cookie: pf_session={} -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testURLRequest.head-curl.txt: -------------------------------------------------------------------------------- 1 | curl \ 2 | --head \ 3 | --cookie "pf_session={}" \ 4 | "https://www.pointfree.co/" -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testURLRequest.head.txt: -------------------------------------------------------------------------------- 1 | HEAD https://www.pointfree.co/ 2 | Cookie: pf_session={} -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testURLRequest.post-curl.txt: -------------------------------------------------------------------------------- 1 | curl \ 2 | --request POST \ 3 | --header "Accept: text/html" \ 4 | --data "pricing[billing]=monthly&pricing[lane]=individual" \ 5 | --cookie "pf_session={\"user_id\":\"0\"}" \ 6 | "https://www.pointfree.co/subscribe" -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testURLRequest.post-json.txt: -------------------------------------------------------------------------------- 1 | POST https://www.pointfree.co/subscribe 2 | Accept: application/json 3 | Cookie: pf_session={"user_id":"0"} 4 | 5 | { 6 | "pricing" : { 7 | "billing" : "monthly", 8 | "lane" : "individual" 9 | } 10 | } -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testURLRequest.post-with-json-curl.txt: -------------------------------------------------------------------------------- 1 | curl \ 2 | --request POST \ 3 | --header "Accept: application/json" \ 4 | --header "Content-Type: application/json" \ 5 | --data "{\"name\":\"tammy134235345235\", \"salary\":0, \"age\":\"tammy133\"}" \ 6 | "http://dummy.restapiexample.com/api/v1/create" -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testURLRequest.post-with-json.txt: -------------------------------------------------------------------------------- 1 | POST http://dummy.restapiexample.com/api/v1/create 2 | Accept: application/json 3 | Content-Type: application/json 4 | 5 | {"name":"tammy134235345235", "salary":0, "age":"tammy133"} -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testURLRequest.post.txt: -------------------------------------------------------------------------------- 1 | POST https://www.pointfree.co/subscribe 2 | Accept: text/html 3 | Cookie: pf_session={"user_id":"0"} 4 | 5 | pricing[billing]=monthly&pricing[lane]=individual -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testViewAgainstEmptyImage.notEmptyImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testViewAgainstEmptyImage.notEmptyImage.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testViewControllerHierarchy.1.txt: -------------------------------------------------------------------------------- 1 | , state: appeared, view: 2 | | , state: appeared, view: 3 | | | , state: appeared, view: <_UIPageViewControllerContentView> 4 | | | | , state: appeared, view: 5 | | , state: disappeared, view: not in the window 6 | | | , state: disappeared, view: (view not loaded) 7 | | , state: disappeared, view: not in the window 8 | | | , state: disappeared, view: (view not loaded) 9 | | , state: disappeared, view: not in the window 10 | | | , state: disappeared, view: (view not loaded) 11 | | , state: disappeared, view: not in the window 12 | | | , state: disappeared, view: (view not loaded) -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testViewWithZeroHeightOrWidth.noHeight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testViewWithZeroHeightOrWidth.noHeight.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testViewWithZeroHeightOrWidth.noWidth-noHeight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testViewWithZeroHeightOrWidth.noWidth-noHeight.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testViewWithZeroHeightOrWidth.noWidth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testViewWithZeroHeightOrWidth.noWidth.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testWebView.ios.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testWebView.ios.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testWebView.macos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testWebView.macos.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testWebViewWithCancellingNavigationDelegate.ios.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testWebViewWithCancellingNavigationDelegate.ios.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testWebViewWithCancellingNavigationDelegate.macos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testWebViewWithCancellingNavigationDelegate.macos.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testWebViewWithManipulatingNavigationDelegate.ios.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testWebViewWithManipulatingNavigationDelegate.ios.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testWebViewWithManipulatingNavigationDelegate.macos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointfreeco/swift-snapshot-testing/b198a568ad24c5a22995c5ff0ecf9667634e860e/Tests/SnapshotTestingTests/__Snapshots__/SnapshotTestingTests/testWebViewWithManipulatingNavigationDelegate.macos.png -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SwiftTestingTests/testSnapshot.1.txt: -------------------------------------------------------------------------------- 1 | ▿ 2 elements 2 | - "Hello" 3 | - "World" 4 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SwiftTestingTests/testSnapshot.snap.txt: -------------------------------------------------------------------------------- 1 | ▿ 2 elements 2 | - "Hello" 3 | - "World" 4 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/SwiftTestingTests/testSnapshotFailure.1.txt: -------------------------------------------------------------------------------- 1 | ▿ 2 elements 2 | - "Hello" 3 | - "World" 4 | -------------------------------------------------------------------------------- /Tests/SnapshotTestingTests/__Snapshots__/WaitTests/testWait.1.txt: -------------------------------------------------------------------------------- 1 | Goodbye --------------------------------------------------------------------------------