#if canImport(UIKit) import UIKit import Nimble @available(iOS 13.4, *) public func haveTheDefaultPointerInteraction() -> Nimble.Predicate { return Nimble.Predicate { actual -> PredicateResult in let message = ExpectationMessage.expectedActualValueTo("have the default pointer interaction") guard let view = try actual.evaluate() else { return PredicateResult(status: .fail, message: message.appendedBeNilHint()) } if let button = view as? UIButton { return hasDefaultPointerInteraction(button: button) } let pointerInteractions = view.interactions.compactMap { $0 as? UIPointerInteraction } // there should be one and only one pointer interaction here. guard let interaction = pointerInteractions.first, pointerInteractions.count == 1 else { return PredicateResult(status: .doesNotMatch, message: message) } // I mean, sure, it's possible to test that the delegate's responses returns the expected default values. // But that's work I don't care to do, and, honestly, if you're going to THAT much effort just for the default behavior // Then you did something wrong and your test SHOULD fail. return PredicateResult(bool: interaction.delegate == nil, message: message) } } @available(iOS 13.4, *) private func hasDefaultPointerInteraction(button: UIButton) -> PredicateResult { let message = ExpectationMessage.expectedActualValueTo("have the default pointer interaction") let pointerInteractions = button.interactions.compactMap { $0 as? UIPointerInteraction } // there should be one and only one pointer interaction here. guard pointerInteractions.count == 1 else { // isPointerInteractionEnabled will add it's own UIPointerInteraction. This is still distinct from you the developer adding your own pointer interaction. return PredicateResult(status: .doesNotMatch, message: message.appended(details: "On buttons, it's easier to set `isPointerInteractionEnabled` to true. Use that for the default pointer interaction.")) } // I mean, sure, it's possible to test that the pointerStyleProvider's responses returns the expected default values. // But that's work I don't care to do, and, honestly, if you're going to THAT much effort just for the default behavior // Then you did something wrong and your test SHOULD fail. return PredicateResult(bool: button.isPointerInteractionEnabled == true && button.pointerStyleProvider == nil, message: message) } #endif