### CocoaPods Installation for Quick and Nimble Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Quick/README.md Instructions for installing the Quick and Nimble testing frameworks using CocoaPods by adding them to your project's Podfile. This example assumes a Swift project using frameworks. ```ruby # Podfile use_frameworks! target "MyApp" do # Normal libraries abstract_target 'Tests' do inherit! :search_paths target "MyAppTests" target "MyAppUITests" pod 'Quick' pod 'Nimble' end end ``` -------------------------------- ### Quick Spec Example Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Quick/README.md A basic example of a QuickSpec class demonstrating describe, context, and it blocks for writing behavior-driven tests in Swift. It uses Nimble for assertions. ```swift import Quick import Nimble class TableOfContentsSpec: QuickSpec { override func spec() { describe("the 'Documentation' directory") { it("has everything you need to get started") { let sections = Directory("Documentation").sections expect(sections).to(contain("Organized Tests with Quick Examples and Example Groups")) expect(sections).to(contain("Installing Quick")) } context("if it doesn't have what you're looking for") { it("needs to be updated") { let you = You(awesome: true) expect{you.submittedAnIssue}.toEventually(beTruthy()) } } } } } ``` -------------------------------- ### Install Nimble via CocoaPods Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Instructions for adding Nimble to your project's Podfile to utilize it for testing macOS, iOS, or tvOS applications. Requires enabling Swift support with `use_frameworks!`. ```ruby platform :ios, '8.0' source 'https://github.com/CocoaPods/Specs.git' # Whatever pods you need for your app go here target 'YOUR_APP_NAME_HERE_Tests', :exclusive => true do use_frameworks! pod 'Nimble' end ``` -------------------------------- ### Swift/XML: Configure AsyncDefaults with XCTest Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Provides instructions and code examples for configuring Nimble's AsyncDefaults using XCTest by implementing XCTestObserver and setting NSPrincipalClass in Info.plist. ```xml NSPrincipalClass MyTests.TestSetup ``` ```swift // TestSetup.swift import XCTest import Nimble @objc class TestSetup: NSObject { override init() { XCTestObservationCenter.shared.register(AsyncConfigurationTestObserver()) } } class AsyncConfigurationTestObserver: NSObject, XCTestObserver { func testBundleWillStart(_ testBundle: Bundle) { Nimble.AsyncDefaults.timeout = .seconds(5) Nimble.AsyncDefaults.pollInterval = .milliseconds(100) } } ``` -------------------------------- ### Writing Custom Nimble Matchers Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Provides an example of how to create a custom Nimble matcher in Swift. It illustrates the structure of a matcher function, returning a `Predicate` closure, and handling `PredicateResult` for success and failure reporting. ```Swift public func equal(expectedValue: T?) -> Predicate { return Predicate { (actualExpression: Expression) throws -> PredicateResult in let msg = ExpectationMessage.expectedActualValueTo("equal <\(expectedValue)>") if let actualValue = try actualExpression.evaluate() { return PredicateResult( bool: actualValue == expectedValue!, message: msg ) } else { return PredicateResult( status: .fail, message: msg.appendedBeNilHint() ) } } } ``` -------------------------------- ### Swift Predicate: Custom Failure Messages (equal) Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Demonstrates customizing failure messages using Predicate.define. This example shows how to create an 'equal' predicate with a custom message format. ```Swift public func equal(_ expectedValue: T?) -> Predicate { return Predicate.define("equal <\(stringify(expectedValue))>") { actualExpression, msg in let actualValue = try actualExpression.evaluate() let matches = actualValue == expectedValue && expectedValue != nil if expectedValue == nil || actualValue == nil { if expectedValue == nil && actualValue != nil { return PredicateResult( status: .fail, message: msg.appendedBeNilHint() ) } return PredicateResult(status: .fail, message: msg) } return PredicateResult(bool: matches, message: msg) } } ``` -------------------------------- ### Install AttributeKit with Swift Package Manager (Package.swift) Source: https://github.com/hainayanda/attributekit/blob/main/README.md This code demonstrates how to declare AttributeKit as a dependency in your project's Package.swift file and how to import it into your target modules. ```swift dependencies: [ .package(url: "https://github.com/hainayanda/AttributeKit.git", .upToNextMajor(from: "1.0.1")) ] .target( name: "MyModule", dependencies: ["AttributeKit"] ``` -------------------------------- ### Install AttributeKit with CocoaPods Source: https://github.com/hainayanda/attributekit/blob/main/README.md This snippet shows how to add AttributeKit as a dependency to your project using CocoaPods. Ensure you have CocoaPods installed and run 'pod install' in your project's directory. ```ruby pod 'AttributeKit', '~> 1.0.1' ``` -------------------------------- ### Install AttributeKit with Swift Package Manager (Xcode) Source: https://github.com/hainayanda/attributekit/blob/main/README.md Instructions for adding AttributeKit to your project via Xcode's Swift Package Manager integration. This involves adding the repository URL and specifying the version rules. ```swift File > Swift Package > Add Package Dependency URL: Rules: Version, Up to Next Major, 1.0.1 ``` -------------------------------- ### Ordered Collection Matchers (Swift) Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Checks if elements appear at the beginning or end of an ordered collection in Swift. `beginWith` verifies the start, and `endWith` verifies the end. Both can accept multiple arguments. ```Swift expect(actual).to(beginWith(expected...)) expect(actual).to(endWith(expected...)) ``` -------------------------------- ### Ordered Collection Matchers (Objective-C) Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Checks if elements appear at the beginning or end of an ordered collection in Objective-C. `beginWith` verifies the start, and `endWith` verifies the end. Both currently support only a single argument. ```Objective-C expect(actual).to(beginWith(expected)); expect(actual).to(endWith(expected)); ``` -------------------------------- ### Swift beginWith Matcher and Objective-C Integration Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Provides the Swift implementation for a `beginWith` matcher and its Objective-C wrapper using NMBPredicate, demonstrating how to create custom matchers for sequences. ```Swift public func beginWith(_ startingElement: S.Element) -> Predicate where S.Element: Equatable { return Predicate.simple("begin with <\(startingElement)>") { actualExpression in guard let actualValue = try actualExpression.evaluate() else { return .fail } var actualGenerator = actualValue.makeIterator() return PredicateStatus(bool: actualGenerator.next() == startingElement) } } ``` ```Swift extension NMBPredicate { @objc public class func beginWithMatcher(_ expected: Any) -> NMBPredicate { return NMBPredicate { actualExpression in let actual = try actualExpression.evaluate() let expr = actualExpression.cast { $0 as? NMBOrderedCollection } return try beginWith(expected).satisfies(expr).toObjectiveC() } } } ``` -------------------------------- ### Swift: Configure AsyncDefaults with Quick Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Shows how to set custom AsyncDefaults for timeout and poll interval by creating a QuickConfiguration subclass in Swift. ```swift import Quick import Nimble class AsyncConfiguration: QuickConfiguration { override class func configure(_ configuration: QCKConfiguration) { Nimble.AsyncDefaults.timeout = .seconds(5) Nimble.AsyncDefaults.pollInterval = .milliseconds(100) } } ``` -------------------------------- ### Basic Nimble Expectations Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Demonstrates fundamental Nimble matchers for various data types and conditions, including equality, approximate equality, comparisons, substring containment, and truthiness checks. It also shows how to test asynchronous operations using `toEventually`. ```Swift expect(1 + 1).to(equal(2)) expect(1.2).to(beCloseTo(1.1, within: 0.1)) expect(3) > 2 expect("seahorse").to(contain("sea")) expect(["Atlantic", "Pacific"]).toNot(contain("Mississippi")) expect(ocean.isClean).toEventually(beTruthy()) ``` -------------------------------- ### Objective-C: Using Nimble Expectations Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Demonstrates how to use Nimble's expect function with Objective-C objects and various data types, including boxing primitives and using expectAction for exceptions. ```objective-c // Objective-C @import Nimble; expect(@(1 + 1)).to(equal(@2)); expect(@"Hello world").to(contain(@"world")); // Boxed as NSNumber * expect(2).to(equal(2)); expect(1.2).to(beLessThan(2.0)); expect(true).to(beTruthy()); // Boxed as NSString * expect(@"Hello world").to(equal(@"Hello world")); // Boxed as NSRange expect(NSMakeRange(1, 10)).to(equal(NSMakeRange(1, 10))); // Objective-C expectAction(^{ [exception raise]; }).to(raiseException()); ``` -------------------------------- ### Objective-C Integration with NMBPredicate Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Shows how to expose Swift matchers to Objective-C by extending NMBPredicate. It includes creating a class method for the matcher and a C function for easier syntax. ```Swift // Swift extension NMBPredicate { @objc public class func beNilMatcher() -> NMBPredicate { return NMBPredicate { actualExpression in return try beNil().satisfies(actualExpression).toObjectiveC() } } } ``` ```Objective-C // Objective-C expect(actual).to([NMBPredicate beNilMatcher]()); ``` ```Objective-C // Objective-C FOUNDATION_EXPORT NMBPredicate *beNil() { return [NMBPredicate beNilMatcher]; } ``` -------------------------------- ### Using waitUntil in Objective-C Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Explains how to use `waitUntil` in Objective-C to manage asynchronous operations, signaling completion via a block. ```Objective-C waitUntil(^(void (^done)(void)){ [ocean goFishWithHandler:^(BOOL success){ expect(success).to(beTrue()); done(); }]; }); ``` -------------------------------- ### Testing Value Persistence with toAlways and toNever Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Illustrates using `toAlways` and `toNever` to test if a value consistently matches or never matches a condition throughout a timeout period. ```Swift ocean.add("dolphins") expect(ocean).toAlways(contain("dolphins")) expect(ocean).toNever(contain("hares")) ``` -------------------------------- ### Nimble Post-Build Script for XCTest Support Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md A post-build script action for Xcode schemes to remove the Swift XCTest support library, preventing it from being unnecessarily copied into the application when using Nimble standalone. ```shell rm "${SWIFT_STDLIB_TOOL_DESTINATION_DIR}/libswiftXCTest.dylib" ``` -------------------------------- ### XCTest Assertions vs. Nimble Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Compares the syntax of traditional XCTest assertions with Nimble's more expressive syntax for checking equality. It highlights how Nimble can make test code more readable. ```Swift // Swift XCTAssertEqual(1 + 1, 2, "expected one plus one to equal two") ``` ```Swift // Swift expect(1 + 1).to(equal(2)) ``` -------------------------------- ### Testing Value Persistence with toAlways and toNever in Objective-C Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Demonstrates using `toAlways` and `toNever` in Objective-C to check if a value consistently matches or never matches a condition over time. ```Objective-C [ocean add:@"dolphins"] expect(ocean).toAlways(contain(@"dolphins")) expect(ocean).toNever(contain(@"hares")) ``` -------------------------------- ### Customizing Timeout and Poll Interval Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Explains how to customize the timeout duration and poll interval for `toEventually` expectations to handle slower asynchronous updates. ```Swift // Waits three seconds for ocean to contain "starfish": expect(ocean).toEventually(contain("starfish"), timeout: .seconds(3)) // Evaluate someValue every 0.2 seconds repeatedly until it equals 100, or fails if it timeouts after 5.5 seconds. expect(someValue).toEventually(equal(100), timeout: .milliseconds(5500), pollInterval: .milliseconds(200)) ``` -------------------------------- ### Testing C Primitives in Objective-C Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Shows how to test primitive C values in Objective-C by wrapping them in an object literal when using Nimble. ```Objective-C expect(@(1 + 1)).to(equal(@2)); ``` -------------------------------- ### Basic Expectations (Objective-C) Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Express expectations using the `expect(...).to` syntax for equality checks in Objective-C. This is the fundamental way to assert expected outcomes in Nimble. ```Objective-C @import Nimble; expect(seagull.squawk).to(equal(@"Squee!")); ``` -------------------------------- ### XCTest Assertions in Objective-C Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Shows the standard XCTest assertion syntax used in Objective-C for verifying equality, including a custom failure message. ```Objective-C // Objective-C XCTAssertEqual(1 + 1, 2, @"expected one plus one to equal two"); ``` -------------------------------- ### Basic Expectations Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Express expectations using the `expect(...).to` syntax for equality checks. This is the fundamental way to assert expected outcomes in Nimble. ```Swift import Nimble expect(seagull.squawk).to(equal("Squee!")) ``` -------------------------------- ### waitUntil with Timeout in Objective-C Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Demonstrates setting a timeout for `waitUntil` in Objective-C, ensuring asynchronous tasks complete within the specified time. ```Objective-C waitUntilTimeout(10, ^(void (^done)(void)){ [ocean goFishWithHandler:^(BOOL success){ expect(success).to(beTrue()); done(); }]; }); ``` -------------------------------- ### Using waitUntil for Asynchronous Operations Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Demonstrates the `waitUntil` function for handling asynchronous operations where a callback signals completion. It ensures the test waits until the operation is done. ```Swift waitUntil { done in ocean.goFish { success in expect(success).to(beTrue()) done() } } ``` -------------------------------- ### Async/Await Support in Nimble Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Explains how Nimble supports awaiting asynchronous functions. The async function is awaited before being passed to the matcher, allowing synchronous matcher code. ```Swift await expect(await aFunctionReturning1()).to(equal(1)) ``` -------------------------------- ### Swift Predicate: haveDescription Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Creates a Predicate that checks if an actual value, conforming to Printable, has a specific description. It leverages Swift generics for type constraints. ```Swift public func haveDescription(description: String) -> Predicate { return Predicate.simple("have description") { actual in return PredicateStatus(bool: actual.evaluate().description == description) } } ``` -------------------------------- ### Custom Validation with Nimble Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Demonstrates how to use Nimble's `expect` and `succeed()` for custom validation logic within closures. It shows how to check for specific enum cases and assert success or failure. ```Swift expect { guard case .enumCaseWithAssociatedValueThatIDontCareAbout = actual else { return .failed(reason: "wrong enum case") } return .succeeded }.to(succeed()) expect { guard case .enumCaseWithAssociatedValueThatIDontCareAbout = actual else { return .failed(reason: "wrong enum case") } return .succeeded }.notTo(succeed()) ``` -------------------------------- ### Objective-C Exception Handling Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Tests if Objective-C code raises an exception, optionally checking the exception's name, reason, or custom conditions via a block. ```Objective-C // Passes if 'actual', when evaluated, raises an exception: expect(actual).to(raiseException()) // Passes if 'actual' raises an exception with the given name expect(actual).to(raiseException().named(name)) // Passes if 'actual' raises an exception with the given name and reason: expect(actual).to(raiseException().named(name).reason(reason)) // Passes if 'actual' raises an exception and it passes expectations defined in the given block: // (in this case, if name begins with "a r") expect(actual).to(raiseException().satisfyingBlock(^(NSException *exception) { expect(exception.name).to(beginWith(@"a r")); })); ``` -------------------------------- ### Testing C Primitives with Nimble Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Demonstrates how to test primitive C values using Nimble in Swift. For Objective-C, primitive C values need to be wrapped in an object literal. ```Swift let actual: CInt = 1 let expectedValue: CInt = 1 expect(actual).to(equal(expectedValue)) ``` ```Swift expect(1 as CInt).to(equal(1)) ``` -------------------------------- ### waitUntil with Timeout Parameter Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Shows how to specify a timeout for the `waitUntil` function, ensuring the asynchronous operation completes within a given duration. ```Swift waitUntil(timeout: .seconds(10)) { done in ocean.goFish { success in expect(success).to(beTrue()) done() } } ``` -------------------------------- ### Comparison Matchers Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Asserts that a value is less than, less than or equal to, greater than, or greater than or equal to another value. Requires the compared values to implement the `Comparable` protocol. ```Swift expect(actual).to(beLessThan(expected)) expect(actual) < expected expect(actual).to(beLessThanOrEqualTo(expected)) expect(actual) <= expected expect(actual).to(beGreaterThan(expected)) expect(actual) > expected expect(actual).to(beGreaterThanOrEqualTo(expected)) expect(actual) >= expected ``` ```Objective-C expect(actual).to(beLessThan(expected)); expect(actual).to(beLessThanOrEqualTo(expected)); expect(actual).to(beGreaterThan(expected)); expect(actual).to(beGreaterThanOrEqualTo(expected)); ``` -------------------------------- ### Swift Exception Handling Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Tests if a code block raises an exception, optionally checking the exception's name, reason, or custom conditions via a closure. ```Swift // Passes if 'actual', when evaluated, raises an exception: expect(actual).to(raiseException()) // Passes if 'actual' raises an exception with the given name: expect(actual).to(raiseException(named: name)) // Passes if 'actual' raises an exception with the given name and reason: expect(actual).to(raiseException(named: name, reason: reason)) // Passes if 'actual' raises an exception which passes expectations defined in the given closure: // (in this case, if the exception's name begins with "a r") expect { exception.raise() }.to(raiseException { (exception: NSException) in expect(exception.name).to(beginWith("a r")) }) ``` -------------------------------- ### Custom Failure Messages Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Add custom text to failure messages using the `description` argument in Swift or `toWithDescription` in Objective-C to provide more context when a test fails. ```Swift expect(1 + 1).to(equal(3), description: "Make sure libKindergartenMath is loaded") ``` -------------------------------- ### String Matchers (Objective-C) Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Provides matchers for string manipulation in Objective-C. `contain` checks for substrings, `beginWith` and `endWith` check prefixes and suffixes, `beEmpty` checks for an empty string, and `match` checks against a regular expression. ```Objective-C expect(actual).to(contain(expected)); expect(actual).to(beginWith(prefix)); expect(actual).to(endWith(suffix)); expect(actual).to(beEmpty()); expect(actual).to(match(expected)) ``` -------------------------------- ### Customizing Timeout in Objective-C Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Shows how to set a custom timeout for `toEventually` expectations in Objective-C using the `withTimeout` modifier. ```Objective-C // Waits three seconds for ocean to contain "starfish": expect(ocean).withTimeout(3).toEventually(contain(@"starfish")); ``` -------------------------------- ### Notification Posting Matchers Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Asserts that a closure posts notifications to the default or a specified notification center. Supports matching specific notifications or notifications with specific names. ```Swift let testNotification = Notification(name: Notification.Name("Foo"), object: nil) // Passes if the closure in expect { ... } posts a notification to the default // notification center. expect { NotificationCenter.default.post(testNotification) }.to(postNotifications(equal([testNotification]))) // Passes if the closure in expect { ... } posts a notification to a given // notification center let notificationCenter = NotificationCenter() expect { notificationCenter.post(testNotification) }.to(postNotifications(equal([testNotification]), from: notificationCenter)) // Passes if the closure in expect { ... } posts a notification with the provided names to a given // notification center. Make sure to use this when running tests on Catalina, // using DistributedNotificationCenter as there is currently no way // of observing notifications without providing specific names. let distributedNotificationCenter = DistributedNotificationCenter() expect { distributedNotificationCenter.post(testNotification) }.toEventually(postDistributedNotifications(equal([testNotification]), from: distributedNotificationCenter, names: [testNotification.name])) ``` -------------------------------- ### Custom Failure Messages (Objective-C) Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Add custom text to failure messages using the `description` argument in Swift or `toWithDescription` in Objective-C to provide more context when a test fails. ```Objective-C @import Nimble; expect(@(1+1)).toWithDescription(equal(@3), @"Make sure libKindergartenMath is loaded"); ``` -------------------------------- ### String Matchers (Swift) Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Provides matchers for string manipulation in Swift. `contain` checks for substrings, `beginWith` and `endWith` check prefixes and suffixes, `beEmpty` checks for an empty string, and `match` checks against a regular expression. ```Swift expect(actual).to(contain(substring)) expect(actual).to(beginWith(prefix)) expect(actual).to(endWith(suffix)) expect(actual).to(beEmpty()) expect(actual).to(match(expected)) ``` -------------------------------- ### Polling Expectations with toEventually Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Demonstrates using `toEventually` to make expectations on values updated asynchronously. The expectation passes if the condition is met within the timeout period. ```Swift DispatchQueue.main.async { ocean.add("dolphins") ocean.add("whales") } expect(ocean).toEventually(contain("dolphins", "whales")) ``` -------------------------------- ### Handling nil in Objective-C Matchers Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Explains the importance of handling nil values in Objective-C matchers, noting that most matchers do not match nil by default. It highlights the `beNil()` matcher for explicit nil expectations. ```Objective-C // Objective-C expect(nil).to(equal(nil)); // fails expect(nil).to(beNil()); // passes ``` -------------------------------- ### Collection Matchers Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Asserts that all elements in a collection satisfy a given condition or matcher. For Swift, the collection must conform to `Sequence`. For Objective-C, it must implement `NSFastEnumeration`. ```Swift // Providing a custom function: expect([1, 2, 3, 4]).to(allPass { $0 < 5 }) // Composing the expectation with another matcher: expect([1, 2, 3, 4]).to(allPass(beLessThan(5))) ``` ```Objective-C // Objective-C expect(@[@1, @2, @3, @4]).to(allPass(beLessThan(@5))); ``` -------------------------------- ### Swift Predicate: beNil Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Creates a Predicate that checks if an actual value is nil. It uses lazy evaluation and supports nilable actual expressions. ```Swift public func beNil() -> Predicate { // Predicate.simpleNilable(..) automatically generates ExpectationMessage for // us based on the string we provide to it. Also, the 'Nilable' postfix indicates // that this Predicate supports matching against nil actualExpressions, instead of // always resulting in a PredicateStatus.fail result -- which is true for // Predicate.simple(..) return Predicate.simpleNilable("be nil") { actualExpression in let actualValue = try actualExpression.evaluate() return PredicateStatus(bool: actualValue == nil) } } ``` -------------------------------- ### Testing for Raised Exceptions Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Test if a block of code raises an exception using `to(raiseException())`. You can specify the exception's name, reason, and user info for more precise testing. ```Swift let exception = NSException( name: NSInternalInconsistencyException, reason: "Not enough fish in the sea.", userInfo: ["something": "is fishy"]) expect { exception.raise() }.to(raiseException()) expect { exception.raise() }.to(raiseException(named: NSInternalInconsistencyException)) expect { exception.raise() }.to(raiseException( named: NSInternalInconsistencyException, reason: "Not enough fish in the sea")) expect { exception.raise() }.to(raiseException( named: NSInternalInconsistencyException, reason: "Not enough fish in the sea", userInfo: ["something": "is fishy"])) expect { exception.raise() }.to(raiseException().satisfyingBlock { exception in expect(exception.name).to(beginWith(NSInternalInconsistencyException)) }) ``` -------------------------------- ### Swift: Set Global Timeout and Poll Interval Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Demonstrates how to increase the global timeout to 5 seconds and slow the polling interval to 0.1 seconds using Nimble's AsyncDefaults in Swift. ```swift // Swift // Increase the global timeout to 5 seconds: Nimble.AsyncDefaults.timeout = .seconds(5) // Slow the polling interval to 0.1 seconds: Nimble.AsyncDefaults.pollInterval = .milliseconds(100) ``` -------------------------------- ### Nimble ExpectationMessage Enum Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Illustrates the `ExpectationMessage` enum in Nimble, used for constructing error messages in matchers. It includes cases for standard messages and free-form error reporting. ```Swift public indirect enum ExpectationMessage { // Emits standard error message: // eg - "expected to , got " case expectedActualValueTo(/* message: */ String) // Allows any free-form message // eg - "" case fail(/* message: */ String) // ... } ``` -------------------------------- ### Objective-C Identity Checking with beIdenticalTo Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Checks if two Objective-C objects have the same pointer address. ```Objective-C // Passes if 'actual' has the same pointer address as 'expected': expect(actual).to(beIdenticalTo(expected)); // Passes if 'actual' does not have the same pointer address as 'expected': expect(actual).toNot(beIdenticalTo(expected)); ``` -------------------------------- ### Swift Appending Messages Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Demonstrates how to append messages to existing failure messages in Swift. `appended(message:)` adds inline messages, while `appended(details:)` adds multi-line details for test logs. ```Swift // produces "expected to be true, got (use beFalse() for inverse)" // appended message do show up inline in Xcode. .expectedActualValueTo("be true").appended(message: " (use beFalse() for inverse)") ``` ```Swift // produces "expected to be true, got \n\nuse beFalse() for inverse\nor use beNil()" // details do not show inline in Xcode, but do show up in test logs. .expectedActualValueTo("be true").appended(details: "use beFalse() for inverse\nor use beNil()") ``` -------------------------------- ### Operator Overloads (Swift) Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Utilize overloaded operators like `!=` for equivalence and `>` for comparisons in Swift for more concise expectation syntax. ```Swift // Passes if squawk does not equal "Hi!": expect(seagull.squawk) != "Hi!" // Passes if 10 is greater than 2: expect(10) > 2 ``` -------------------------------- ### Polling Expectations with toEventually in Objective-C Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Shows how to use `toEventually` in Objective-C for asynchronously updated values. The expectation passes if the condition is met within the timeout period. ```Objective-C dispatch_async(dispatch_get_main_queue(), ^{ [ocean add:@"dolphins"]; [ocean add:@"whales"]; }); expect(ocean).toEventually(contain(@"dolphins", @"whales")); ``` -------------------------------- ### Swift Equivalence Checking with equal Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Checks if two values are equivalent. Requires values to be Equatable, Comparable, or NSObject subclasses. Fails for nil values. ```Swift // Passes if 'actual' is equivalent to 'expected': expect(actual).to(equal(expected)) expect(actual) == expected // Passes if 'actual' is not equivalent to 'expected': expect(actual).toNot(equal(expected)) expect(actual) != expected ``` -------------------------------- ### Swift Assertions Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Tests if a code block throws an assertion, such as `fatalError()` or a failed precondition. It also shows how to assert that a specific error is NOT thrown. ```Swift // Passes if 'somethingThatThrows()' throws an assertion, // such as by calling 'fatalError()' or if a precondition fails: expect { try somethingThatThrows() }.to(throwAssertion()) expect { () -> Void in fatalError() }.to(throwAssertion()) expect { precondition(false) }.to(throwAssertion()) // Passes if throwing an NSError is not equal to throwing an assertion: expect { throw NSError(domain: "test", code: 0, userInfo: nil) }.toNot(throwAssertion()) // Passes if the code after the precondition check is not run: var reachedPoint1 = false var reachedPoint2 = false expect { reachedPoint1 = true precondition(false, "condition message") reachedPoint2 = true }.to(throwAssertion()) expect(reachedPoint1) == true expect(reachedPoint2) == false ``` -------------------------------- ### Objective-C Equivalence Checking with equal Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Checks if two Objective-C values are equivalent. Requires values to be Equatable, Comparable, or NSObject subclasses. Fails for nil values. ```Objective-C // Passes if 'actual' is equivalent to 'expected': expect(actual).to(equal(expected)) // Passes if 'actual' is not equivalent to 'expected': expect(actual).toNot(equal(expected)) ``` -------------------------------- ### Swift Type Checking with beAKindOf Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Checks if an object is an instance of a given class or conforms to a protocol. Supports inheritance hierarchies. ```Swift protocol SomeProtocol{} class SomeClassConformingToProtocol: SomeProtocol{} struct SomeStructConformingToProtocol: SomeProtocol{} // The following tests pass expect(1).to(beAKindOf(Int.self)) expect("turtle").to(beAKindOf(String.self)) let classObject = SomeClassConformingToProtocol() expect(classObject).to(beAKindOf(SomeProtocol.self)) expect(classObject).to(beAKindOf(SomeClassConformingToProtocol.self)) expect(classObject).toNot(beAKindOf(SomeStructConformingToProtocol.self)) let structObject = SomeStructConformingToProtocol() expect(structObject).to(beAKindOf(SomeProtocol.self)) expect(structObject).to(beAKindOf(SomeStructConformingToProtocol.self)) expect(structObject).toNot(beAKindOf(SomeClassConformingToProtocol.self)) ``` -------------------------------- ### Testing for Raised Exceptions (Objective-C) Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Test if a block of code raises an exception using `to(raiseException())` with `expectAction`. You can specify the exception's name, reason, and user info for more precise testing. ```Objective-C NSException *exception = [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Not enough fish in the sea." userInfo:nil]; expectAction(^{ [exception raise]; }).to(raiseException()); expectAction(^{ [exception raise]; }).to(raiseException().named(NSInternalInconsistencyException)); expectAction(^{ [exception raise]; }).to(raiseException(). named(NSInternalInconsistencyException). reason(@"Not enough fish in the sea")); expectAction(^{ [exception raise]; }).to(raiseException(). named(NSInternalInconsistencyException). reason(@"Not enough fish in the sea"). userInfo(@{@"something": @"is fishy"})); expectAction(exception.raise()).to(raiseException().satisfyingBlock(^(NSException *exception) { expect(exception.name).to(beginWith(NSInternalInconsistencyException)); })); ``` -------------------------------- ### Custom Nimble Assertion Handler Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Demonstrates how to create a custom assertion handler for Nimble when used outside of XCTest. This involves defining a class that conforms to the `AssertionHandler` protocol and assigning an instance to the global `NimbleAssertionHandler` variable. ```swift class MyAssertionHandler : AssertionHandler { func assert(assertion: Bool, message: FailureMessage, location: SourceLocation) { if (!assertion) { print("Expectation failed: (message.stringValue)") } } } ``` ```swift // Somewhere before you use any assertions NimbleAssertionHandler = MyAssertionHandler() ``` -------------------------------- ### Swift ExpectationMessage Enum Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Defines various ways to construct failure messages for predicates in Swift, including standard error messages, custom messages, and messages with specific actual values. ```Swift public indirect enum ExpectationMessage { // Emits standard error message: // eg - "expected to , got " case expectedActualValueTo(/* message: */ String) // Allows any free-form message // eg - "" case fail(/* message: */ String) // Emits standard error message with a custom actual value instead of the default. // eg - "expected to , got " case expectedCustomValueTo(/* message: */ String, /* actual: */ String) // Emits standard error message without mentioning the actual value // eg - "expected to " case expectedTo(/* message: */ String) // ... } ``` -------------------------------- ### Collection Count Matchers Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Asserts that a collection has a specific number of elements. For Swift, the collection must conform to `Collection`. For Objective-C, it must be an instance of `NSArray`, `NSDictionary`, `NSSet`, or `NSHashTable`. ```Swift // Passes if 'actual' contains the 'expected' number of elements: expect(actual).to(haveCount(expected)) // Passes if 'actual' does _not_ contain the 'expected' number of elements: expect(actual).notTo(haveCount(expected)) ``` ```Objective-C // Passes if 'actual' contains the 'expected' number of elements: expect(actual).to(haveCount(expected)) // Passes if 'actual' does _not_ contain the 'expected' number of elements: expect(actual).notTo(haveCount(expected)) ``` -------------------------------- ### Collection Membership Matchers (Swift) Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Tests for collection membership and emptiness in Swift. `contain` checks if all expected values are present, `beEmpty` checks if the collection is empty. `contain` can take multiple arguments. ```Swift expect(actual).to(contain(expected...)) expect(actual).to(beEmpty()) ``` ```Swift expect(["whale", "dolphin", "starfish"]).to(contain("dolphin", "starfish")) ``` -------------------------------- ### Floating Point Comparison with beCloseTo Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Asserts that two floating-point numbers are close to each other within a specified delta. This is useful due to potential inaccuracies in floating-point representation. Supports array comparisons as well. ```Swift expect(actual).to(beCloseTo(expected, within: delta)) expect(actual) ≈ expected expect(actual) ≈ (expected, delta) expect(actual) ≈ expected ± delta expect(actual) == expected ± delta expect([0.0, 2.0]) ≈ [0.0001, 2.0001] expect([0.0, 2.0]).to(beCloseTo([0.1, 2.1], within: 0.1)) ``` ```Objective-C expect(actual).to(beCloseTo(expected).within(delta)); ``` -------------------------------- ### Collection Membership Matchers (Objective-C) Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Tests for collection membership and emptiness in Objective-C. `contain` checks if an expected value is present, `beEmpty` checks if the collection is empty. `contain` currently only supports a single argument. ```Objective-C expect(actual).to(contain(expected)); expect(actual).to(beEmpty()); ``` ```Objective-C expect(@[@"whale", @"dolphin", @"starfish"]).to(contain(@"dolphin")); expect(@[@"whale", @"dolphin", @"starfish"]).to(contain(@"starfish")); ``` -------------------------------- ### Objective-C: Disabling Nimble Shorthand Syntax Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Explains how to disable Nimble's shorthand syntax in Objective-C by defining NIMBLE_DISABLE_SHORT_SYNTAX to avoid conflicts with custom functions. ```objective-c #define NIMBLE_DISABLE_SHORT_SYNTAX 1 @import Nimble; NMB_expect(^{ return seagull.squawk; }, __FILE__, __LINE__).to(NMB_equal(@"Squee!")); ``` -------------------------------- ### Objective-C Type Checking with beAKindOf Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Checks if an Objective-C object is an instance of a given class. Supports inheritance. ```Objective-C // The following tests pass NSMutableArray *array = [NSMutableArray array]; expect(array).to(beAKindOf([NSArray class])); expect(@1).toNot(beAKindOf([NSNull class])); ``` -------------------------------- ### Swift Error Handling Source: https://github.com/hainayanda/attributekit/blob/main/Example/Pods/Nimble/README.md Tests if a code block throws an `Error`. It supports checking for errors within a specific domain, a particular enum case, or a specific error type. ```Swift // Passes if 'somethingThatThrows()' throws an 'Error': expect { try somethingThatThrows() }.to(throwError()) // Passes if 'somethingThatThrows()' throws an error within a particular domain: expect { try somethingThatThrows() }.to(throwError { (error: Error) in expect(error._domain).to(equal(NSCocoaErrorDomain)) }) // Passes if 'somethingThatThrows()' throws a particular error enum case: expect { try somethingThatThrows() }.to(throwError(NSCocoaError.PropertyListReadCorruptError)) // Passes if 'somethingThatThrows()' throws an error of a particular type: expect { try somethingThatThrows() }.to(throwError(errorType: NimbleError.self)) ```