<commit_before>import Quick
import Nimble
import UIKit
import FBSnapshotTestCase

func allContentSizeCategories() -> [UIContentSizeCategory] {
    return [
        UIContentSizeCategoryExtraSmall, UIContentSizeCategorySmall, UIContentSizeCategoryMedium,
        UIContentSizeCategoryLarge, UIContentSizeCategoryExtraLarge, UIContentSizeCategoryExtraExtraLarge,
        UIContentSizeCategoryExtraExtraExtraLarge, UIContentSizeCategoryAccessibilityMedium,
        UIContentSizeCategoryAccessibilityLarge, UIContentSizeCategoryAccessibilityExtraLarge,
        UIContentSizeCategoryAccessibilityExtraExtraLarge, UIContentSizeCategoryAccessibilityExtraExtraExtraLarge
    ]
}

func shortCategoryName(category: UIContentSizeCategory) -> String {
    return category.stringByReplacingOccurrencesOfString("UICTContentSizeCategory", withString: "")
}

func combineMatchers<T>(matchers: [MatcherFunc<T>], ignoreFailures: Bool = false, deferred: (() -> Void)? = nil) -> MatcherFunc<T> {
    return MatcherFunc { actualExpression, failureMessage in
        defer {
            deferred?()
        }

        return try matchers.reduce(true) { acc, matcher -> Bool in
            guard acc || ignoreFailures else { return false }

            let result = try matcher.matches(actualExpression, failureMessage: failureMessage)
            return result && acc
        }
    }
}

public func haveValidDynamicTypeSnapshot(named name: String? = nil, usesDrawRect: Bool = false, tolerance: CGFloat? = nil, sizes: [UIContentSizeCategory] = allContentSizeCategories(), isDeviceAgnostic: Bool = false) -> MatcherFunc<Snapshotable> {
    let mock = NBSMockedApplication()

    let matchers: [MatcherFunc<Snapshotable>] = sizes.map { category in
        let sanitizedName = _sanitizedTestName(name)
        let nameWithCategory = "\(sanitizedName)_\(shortCategoryName(category))"

        return MatcherFunc { actualExpression, failureMessage in
            mock.mockPrefferedContentSizeCategory(category as String)

            let matcher: MatcherFunc<Snapshotable>
            if isDeviceAgnostic {
                matcher = haveValidDeviceAgnosticSnapshot(named: nameWithCategory, usesDrawRect: usesDrawRect, tolerance: tolerance)
            } else {
                matcher = haveValidSnapshot(named: nameWithCategory, usesDrawRect: usesDrawRect, tolerance: tolerance)
            }

            return try matcher.matches(actualExpression, failureMessage: failureMessage)
        }
    }

    return combineMatchers(matchers) {
        mock.stopMockingPrefferedContentSizeCategory()
    }
}

public func recordDynamicTypeSnapshot(named name: String? = nil, usesDrawRect: Bool = false, sizes: [UIContentSizeCategory] = allContentSizeCategories(), isDeviceAgnostic: Bool = false) -> MatcherFunc<Snapshotable> {
    let mock = NBSMockedApplication()

    let matchers: [MatcherFunc<Snapshotable>] = sizes.map { category in
        let sanitizedName = _sanitizedTestName(name)
        let nameWithCategory = "\(sanitizedName)_\(shortCategoryName(category))"

        return MatcherFunc { actualExpression, failureMessage in
            mock.mockPrefferedContentSizeCategory(category as String)

            let matcher: MatcherFunc<Snapshotable>
            if isDeviceAgnostic {
                matcher = recordDeviceAgnosticSnapshot(named: nameWithCategory, usesDrawRect: usesDrawRect)<commit_msg>Adding support to Swift 3<commit_after>import Quick
import Nimble
import UIKit
import FBSnapshotTestCase

func allContentSizeCategories() -> [UIContentSizeCategory] {
    #if swift(>=3.0)
        return [
            .extraSmall, .small, .medium,
            .large, .extraLarge, .extraExtraLarge,
            .extraExtraExtraLarge, .accessibilityMedium,
            .accessibilityLarge, .accessibilityExtraLarge,
            .accessibilityExtraExtraLarge, .accessibilityExtraExtraExtraLarge
        ]
    #else
        return [
            UIContentSizeCategoryExtraSmall, UIContentSizeCategorySmall, UIContentSizeCategoryMedium,
            UIContentSizeCategoryLarge, UIContentSizeCategoryExtraLarge, UIContentSizeCategoryExtraExtraLarge,
            UIContentSizeCategoryExtraExtraExtraLarge, UIContentSizeCategoryAccessibilityMedium,
            UIContentSizeCategoryAccessibilityLarge, UIContentSizeCategoryAccessibilityExtraLarge,
            UIContentSizeCategoryAccessibilityExtraExtraLarge, UIContentSizeCategoryAccessibilityExtraExtraExtraLarge
        ]
    #endif
}

func shortCategoryName(_ category: UIContentSizeCategory) -> String {
    #if swift(>=3.0)
        return category.rawValue.replacingOccurrences(of: "UICTContentSizeCategory", with: "")
    #else
        return category.stringByReplacingOccurrencesOfString("UICTContentSizeCategory", withString: "")
    #endif
}

func combineMatchers<T>(_ matchers: [MatcherFunc<T>], ignoreFailures: Bool = false, deferred: (() -> Void)? = nil) -> MatcherFunc<T> {
    return MatcherFunc { actualExpression, failureMessage in
        defer {
            deferred?()
        }

        return try matchers.reduce(true) { acc, matcher -> Bool in
            guard acc || ignoreFailures else { return false }

            let result = try matcher.matches(actualExpression, failureMessage: failureMessage)
            return result && acc
        }
    }
}

public func haveValidDynamicTypeSnapshot(named name: String? = nil, usesDrawRect: Bool = false, tolerance: CGFloat? = nil, sizes: [UIContentSizeCategory] = allContentSizeCategories(), isDeviceAgnostic: Bool = false) -> MatcherFunc<Snapshotable> {
    let mock = NBSMockedApplication()

    let matchers: [MatcherFunc<Snapshotable>] = sizes.map { category in
        let sanitizedName = _sanitizedTestName(name)
        let nameWithCategory = "\(sanitizedName)_\(shortCategoryName(category))"

        return MatcherFunc { actualExpression, failureMessage in
            #if swift(>=3.0)
                mock.mockPrefferedContentSizeCategory(category)
            #else
                mock.mockPrefferedContentSizeCategory(category as String)
            #endif

            let matcher: MatcherFunc<Snapshotable>
            if isDeviceAgnostic {
                matcher = haveValidDeviceAgnosticSnapshot(named: nameWithCategory, usesDrawRect: usesDrawRect, tolerance: tolerance)
            } else {
                matcher = haveValidSnapshot(named: nameWithCategory, usesDrawRect: usesDrawRect, tolerance: tolerance)
            }

            return try matcher.matches(actualExpression, failureMessage: failureMessage)
        }
    }

    return combineMatchers(matchers) {
        mock.stopMockingPrefferedContentSizeCategory()
    }
}

public func recordDynamicTypeSnapshot(named name: String? = nil, usesDrawRect: Bool = false, sizes: [UIContentSizeCategory] = allContentSizeCategories(), isDeviceAgnostic: Bool = false) -> MatcherFunc<Snapshotable> {
    let mock = NBSMockedApplication()

    let matchers: [MatcherFunc<Snapshotable>] = sizes.map { category in
        let sanitizedName = _sanitizedTestName(name)
        let nameWithCategory = "\(sanitizedName)_\(shortCategoryName(category))"

        return MatcherFunc { actualExpression, failureMessage in
            #if swift(>=3.0)
                mock.mockPrefferedContentSizeCategory(category)
            #else
                mock.mockPrefferedContentSizeCategory(category as String)
            #endif

            let matcher: MatcherFunc<Snapshotable>
            if isDeviceAgnostic {
                matcher = recordDeviceAgnosticSnapshot(named: nameWithCategory, usesDrawRect: usesDrawRect)
{'fraction_non_alphanumeric': 0.07691291132549227, 'fraction_numerical': 0.0011893749174045195, 'mean_word_length': 3.5290245362058648, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3129349', 'n_tokens_mistral': 1999, 'n_tokens_neox': 1941, 'n_words': 418}