Scott90/SDCAlertView — pull request #8 by lukestringer90 (2013-12-01 20:43:27+00:00)
Title: Block property alternatives for SDCAlertViewDelegate

# API Additions
I've added a number of block properties to `SDCAlertView` to act as callback alternatives to the `SDCAlertViewDelegate` protocol methods. Namely:

- `void (^clickedButtonBlock)(NSInteger buttonIndex);` for `alertView:clickedButtonAtIndex:`
- `BOOL (^shouldDismissBlock)(NSInteger buttonIndex)` for `alertView:shouldDismissWithButtonIndex:`
- `void (^willDismissBlock)(NSInteger buttonIndex;` for `alertView:willDismissWithButtonIndex:`
- `void (^didDismissBlock)(NSInteger buttonIndex` for `alertView:didDismissWithButtonIndex:`

If set these blocks will be called at the same time as the regular delegate method.

# Tests
I've added unit tests for each of these 4 new properties to make sure they work correctly as alternatives to the delegate methods. In order to facilitate testing I've had to make a few changes to the internals of the `SDCAlertView` (the public API remains unchanged).

## `SDCAlertView+Buttons`

The `buttonTitles` and `firstOtherButtonIndex` properties have been refactored into a category along with the `tappedButtonAtIndex:` and `numberOfButtons` methods. This is necessary so we can call the `tappedButtonAtIndex :` method in our test cases to simulate the alert view buttons [being tapped programatically](https://github.com/lukestringer90/SDCAlertView/blob/blocks/SDCAlertViewTests/SDCAlertViewTests.m#L49).

As adding properties to a class via an separate category (i.e. not as a private class extension) isn't supported at compile time, the `buttonTitles ` and `firstOtherButtonIndex ` properties are setup at runtime using [this method](http://www.davidhamrick.com/2012/02/12/Adding-Properties-to-an-Objective-C-Category.html). This works fine but looks a little weird if you haven't seen it before.

## `SDCAlertView+SDCAlertViewController`

The `alertViewController` property has been refactored into a separate category. This allows a different SDCAlertViewController instance to be injected and used by the SDCAlertView instance being tested.

This is necessary as when an SDCAlertView is dismissed the `dismissAlert:animated:completion:` method of SDCAlertViewController is called. The completion block passed to this method is called until all the UI computation has finished, but when we are running unit tests there will be know UI computation to finish, so the completion block will never be called.

We [inject a mock SDCAlertViewController](https://github.com/lukestringer90/SDCAlertView/blob/blocks/SDCAlertViewTests/SDCAlertViewTests.m#L128) instance into the `alertViewController ` property of SDCAlertView that will automatically call the completion block, allowing us to test that the `didDismissBlock ` block.

---

Happy to discuss more, let me know what you think.