Files
RestKit/Tests/Application/UI/RKTableControllerTest.m
2012-07-11 18:53:46 -04:00

2362 lines
138 KiB
Objective-C

//
// RKTableControllerTest.m
// RestKit
//
// Created by Blake Watters on 8/3/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
#import "RKTestEnvironment.h"
#import "RKTableController.h"
#import "RKTableSection.h"
#import "RKTestUser.h"
#import "RKMappableObject.h"
#import "RKAbstractTableController_Internals.h"
#import "RKTableControllerTestDelegate.h"
// Expose the object loader delegate for testing purposes...
@interface RKTableController () <RKObjectLoaderDelegate>
- (void)animationDidStopAddingSwipeView:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context;
@end
@interface RKTableControllerTestTableViewController : UITableViewController
@end
@implementation RKTableControllerTestTableViewController
@end
@interface RKTableControllerTestViewController : UIViewController
@end
@implementation RKTableControllerTestViewController
@end
@interface RKTestUserTableViewCell : UITableViewCell
@end
@implementation RKTestUserTableViewCell
@end
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@interface RKTableControllerTest : RKTestCase
@end
@implementation RKTableControllerTest
- (void)setUp
{
[RKTestFactory setUp];
}
- (void)tearDown
{
[RKTestFactory tearDown];
}
- (void)testInitializeWithATableViewController
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
assertThat(viewController.tableView, is(notNilValue()));
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
assertThat(tableController.viewController, is(equalTo(viewController)));
assertThat(tableController.tableView, is(equalTo(viewController.tableView)));
}
- (void)testInitializeWithATableViewAndViewController
{
UITableView *tableView = [UITableView new];
RKTableControllerTestViewController *viewController = [RKTableControllerTestViewController new];
RKTableController *tableController = [RKTableController tableControllerWithTableView:tableView forViewController:viewController];
assertThat(tableController.viewController, is(equalTo(viewController)));
assertThat(tableController.tableView, is(equalTo(tableView)));
}
- (void)testInitializesToUnloadedState
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
assertThatBool([tableController isLoaded], is(equalToBool(NO)));
}
- (void)testAlwaysHaveAtLeastOneSection
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
assertThat(viewController.tableView, is(notNilValue()));
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
assertThatInt(tableController.sectionCount, is(equalToInt(1)));
}
- (void)testDisconnectFromTheTableViewOnDealloc
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
assertThatInt(tableController.sectionCount, is(equalToInt(1)));
[pool drain];
assertThat(viewController.tableView.delegate, is(nilValue()));
assertThat(viewController.tableView.dataSource, is(nilValue()));
}
- (void)testNotDisconnectFromTheTableViewIfDelegateOrDataSourceAreNotSelf
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [[RKTableController alloc] initWithTableView:viewController.tableView viewController:viewController];
viewController.tableView.delegate = viewController;
viewController.tableView.dataSource = viewController;
assertThatInt(tableController.sectionCount, is(equalToInt(1)));
[tableController release];
assertThat(viewController.tableView.delegate, isNot(nilValue()));
assertThat(viewController.tableView.dataSource, isNot(nilValue()));
}
#pragma mark - Section Management
- (void)testAddASection
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
RKTableSection *section = [RKTableSection section];
[tableController addSection:section];
assertThatInt([tableController.sections count], is(equalToInt(2)));
}
- (void)testConnectTheSectionToTheTableModelOnAdd
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
RKTableSection *section = [RKTableSection section];
[tableController addSection:section];
assertThat(section.tableController, is(equalTo(tableController)));
}
- (void)testConnectTheSectionToTheCellMappingsOfTheTableModelWhenNil
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
RKTableSection *section = [RKTableSection section];
assertThat(section.cellMappings, is(nilValue()));
[tableController addSection:section];
assertThat(section.cellMappings, is(equalTo(tableController.cellMappings)));
}
- (void)testNotConnectTheSectionToTheCellMappingsOfTheTableModelWhenNonNil
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
RKTableSection *section = [RKTableSection section];
section.cellMappings = [NSMutableDictionary dictionary];
[tableController addSection:section];
assertThatBool(section.cellMappings == tableController.cellMappings, is(equalToBool(NO)));
}
- (void)testCountTheSections
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
RKTableSection *section = [RKTableSection section];
[tableController addSection:section];
assertThatInt(tableController.sectionCount, is(equalToInt(2)));
}
- (void)testRemoveASection
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
RKTableSection *section = [RKTableSection section];
[tableController addSection:section];
assertThatInt(tableController.sectionCount, is(equalToInt(2)));
[tableController removeSection:section];
assertThatInt(tableController.sectionCount, is(equalToInt(1)));
}
- (void)testNotLetRemoveTheLastSection
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
RKTableSection *section = [RKTableSection section];
[tableController addSection:section];
assertThatInt(tableController.sectionCount, is(equalToInt(2)));
[tableController removeSection:section];
}
- (void)testInsertASectionAtATestificIndex
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
RKTableSection *referenceSection = [RKTableSection section];
[tableController addSection:[RKTableSection section]];
[tableController addSection:[RKTableSection section]];
[tableController addSection:[RKTableSection section]];
[tableController addSection:[RKTableSection section]];
[tableController insertSection:referenceSection atIndex:2];
assertThatInt(tableController.sectionCount, is(equalToInt(6)));
assertThat([tableController.sections objectAtIndex:2], is(equalTo(referenceSection)));
}
- (void)testRemoveASectionByIndex
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
RKTableSection *section = [RKTableSection section];
[tableController addSection:section];
assertThatInt(tableController.sectionCount, is(equalToInt(2)));
[tableController removeSectionAtIndex:1];
assertThatInt(tableController.sectionCount, is(equalToInt(1)));
}
- (void)testRaiseAnExceptionWhenAttemptingToRemoveTheLastSection
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
NSException *exception = nil;
@try {
[tableController removeSectionAtIndex:0];
}
@catch (NSException *e) {
exception = e;
}
@finally {
assertThat(exception, isNot(nilValue()));
}
}
- (void)testReturnTheSectionAtAGivenIndex
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
RKTableSection *referenceSection = [RKTableSection section];
[tableController addSection:[RKTableSection section]];
[tableController addSection:[RKTableSection section]];
[tableController addSection:[RKTableSection section]];
[tableController addSection:[RKTableSection section]];
[tableController insertSection:referenceSection atIndex:2];
assertThatInt(tableController.sectionCount, is(equalToInt(6)));
assertThat([tableController sectionAtIndex:2], is(equalTo(referenceSection)));
}
- (void)testRemoveAllSections
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
[tableController addSection:[RKTableSection section]];
[tableController addSection:[RKTableSection section]];
[tableController addSection:[RKTableSection section]];
[tableController addSection:[RKTableSection section]];
assertThatInt(tableController.sectionCount, is(equalToInt(5)));
[tableController removeAllSections];
assertThatInt(tableController.sectionCount, is(equalToInt(1)));
}
- (void)testReturnASectionByHeaderTitle
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
[tableController addSection:[RKTableSection section]];
[tableController addSection:[RKTableSection section]];
RKTableSection *titledSection = [RKTableSection section];
titledSection.headerTitle = @"Testing";
[tableController addSection:titledSection];
[tableController addSection:[RKTableSection section]];
assertThat([tableController sectionWithHeaderTitle:@"Testing"], is(equalTo(titledSection)));
}
- (void)testNotifyTheTableViewOnSectionInsertion
{
RKTableControllerTestViewController *viewController = [RKTableControllerTestViewController new];
id mockTableView = [OCMockObject niceMockForClass:[UITableView class]];
RKTableController *tableController = [RKTableController tableControllerWithTableView:mockTableView forViewController:viewController];
[[mockTableView expect] insertSections:[NSIndexSet indexSetWithIndex:1] withRowAnimation:tableController.defaultRowAnimation];
[tableController addSection:[RKTableSection section]];
[mockTableView verify];
}
- (void)testNotifyTheTableViewOnSectionRemoval
{
RKTableControllerTestViewController *viewController = [RKTableControllerTestViewController new];
id mockTableView = [OCMockObject niceMockForClass:[UITableView class]];
RKTableController *tableController = [RKTableController tableControllerWithTableView:mockTableView forViewController:viewController];
[[mockTableView expect] insertSections:[NSIndexSet indexSetWithIndex:1] withRowAnimation:tableController.defaultRowAnimation];
[[mockTableView expect] deleteSections:[NSIndexSet indexSetWithIndex:1] withRowAnimation:tableController.defaultRowAnimation];
RKTableSection *section = [RKTableSection section];
[tableController addSection:section];
[tableController removeSection:section];
[mockTableView verify];
}
- (void)testNotifyTheTableOfSectionRemovalAndReaddWhenRemovingAllSections
{
RKTableControllerTestViewController *viewController = [RKTableControllerTestViewController new];
id mockTableView = [OCMockObject niceMockForClass:[UITableView class]];
RKTableController *tableController = [RKTableController tableControllerWithTableView:mockTableView forViewController:viewController];
[[mockTableView expect] deleteSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:tableController.defaultRowAnimation];
[[mockTableView expect] deleteSections:[NSIndexSet indexSetWithIndex:1] withRowAnimation:tableController.defaultRowAnimation];
[[mockTableView expect] insertSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:tableController.defaultRowAnimation];
RKTableSection *section = [RKTableSection section];
[tableController addSection:section];
[tableController removeAllSections];
[mockTableView verify];
}
#pragma mark - UITableViewDataSource Tests
- (void)testRaiseAnExceptionIfSentAMessageWithATableViewItIsNotBoundTo
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
NSException *exception = nil;
@try {
[tableController numberOfSectionsInTableView:[UITableView new]];
}
@catch (NSException *e) {
exception = e;
}
@finally {
assertThat(exception, is(notNilValue()));
}
}
- (void)testReturnTheNumberOfSectionsInTableView
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
assertThatInt([tableController numberOfSectionsInTableView:viewController.tableView], is(equalToInt(1)));
[tableController addSection:[RKTableSection section]];
assertThatInt([tableController numberOfSectionsInTableView:viewController.tableView], is(equalToInt(2)));
}
- (void)testReturnTheNumberOfRowsInSectionInTableView
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
assertThatInt([tableController tableView:viewController.tableView numberOfRowsInSection:0], is(equalToInt(0)));
NSArray *objects = [NSArray arrayWithObject:@"one"];
[tableController loadObjects:objects];
assertThatInt([tableController tableView:viewController.tableView numberOfRowsInSection:0], is(equalToInt(1)));
}
- (void)testReturnTheHeaderTitleForSection
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
RKTableSection *section = [RKTableSection section];
[tableController addSection:section];
assertThat([tableController tableView:viewController.tableView titleForHeaderInSection:1], is(nilValue()));
section.headerTitle = @"RestKit!";
assertThat([tableController tableView:viewController.tableView titleForHeaderInSection:1], is(equalTo(@"RestKit!")));
}
- (void)testReturnTheTitleForFooterInSection
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
RKTableSection *section = [RKTableSection section];
[tableController addSection:section];
assertThat([tableController tableView:viewController.tableView titleForFooterInSection:1], is(nilValue()));
section.footerTitle = @"RestKit!";
assertThat([tableController tableView:viewController.tableView titleForFooterInSection:1], is(equalTo(@"RestKit!")));
}
- (void)testReturnTheNumberOfRowsAcrossAllSections
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
RKTableSection *section = [RKTableSection section];
id sectionMock = [OCMockObject partialMockForObject:section];
NSUInteger rowCount = 5;
[[[sectionMock stub] andReturnValue:OCMOCK_VALUE(rowCount)] rowCount];
[tableController addSection:section];
assertThatInt(tableController.rowCount, is(equalToInt(5)));
}
- (void)testReturnTheTableViewCellForRowAtIndexPath
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
RKTableItem *item = [RKTableItem tableItemWithText:@"Test!" detailText:@"Details!" image:nil];
[tableController loadTableItems:[NSArray arrayWithObject:item] inSection:0 withMapping:[RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *cellMapping) {
// Detail text label won't appear with default style...
cellMapping.style = UITableViewCellStyleValue1;
[cellMapping addDefaultMappings];
}]];
UITableViewCell *cell = [tableController tableView:tableController.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
assertThat(cell.textLabel.text, is(equalTo(@"Test!")));
assertThat(cell.detailTextLabel.text, is(equalTo(@"Details!")));
}
#pragma mark - Table Cell Mapping
- (void)testInitializeCellMappings
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
assertThat(tableController.cellMappings, is(notNilValue()));
}
- (void)testRegisterMappingsForObjectsToTableViewCell
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
assertThat([tableController.cellMappings cellMappingForClass:[RKTestUser class]], is(nilValue()));
[tableController mapObjectsWithClass:[RKTestUser class] toTableCellsWithMapping:[RKTableViewCellMapping cellMapping]];
RKObjectMapping *mapping = [tableController.cellMappings cellMappingForClass:[RKTestUser class]];
assertThat(mapping, isNot(nilValue()));
assertThatBool([mapping.objectClass isSubclassOfClass:[UITableViewCell class]], is(equalToBool(YES)));
}
- (void)testDefaultTheReuseIdentifierToTheNameOfTheObjectClass
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
assertThat([tableController.cellMappings cellMappingForClass:[RKTestUser class]], is(nilValue()));
RKTableViewCellMapping *cellMapping = [RKTableViewCellMapping cellMapping];
[tableController mapObjectsWithClass:[RKTestUser class] toTableCellsWithMapping:cellMapping];
assertThat(cellMapping.reuseIdentifier, is(equalTo(@"UITableViewCell")));
}
- (void)testDefaultTheReuseIdentifierToTheNameOfTheObjectClassWhenCreatingMappingWithBlockSyntax
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
assertThat([tableController.cellMappings cellMappingForClass:[RKTestUser class]], is(nilValue()));
RKTableViewCellMapping *cellMapping = [RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *cellMapping) {
cellMapping.cellClass = [RKTestUserTableViewCell class];
}];
[tableController mapObjectsWithClass:[RKTestUser class] toTableCellsWithMapping:cellMapping];
assertThat(cellMapping.reuseIdentifier, is(equalTo(@"RKTestUserTableViewCell")));
}
- (void)testReturnTheObjectForARowAtIndexPath
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
RKTestUser *user = [RKTestUser user];
[tableController loadObjects:[NSArray arrayWithObject:user]];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
assertThatBool(user == [tableController objectForRowAtIndexPath:indexPath], is(equalToBool(YES)));
}
- (void)testReturnTheCellMappingForTheRowAtIndexPath
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
RKTableViewCellMapping *cellMapping = [RKTableViewCellMapping cellMapping];
[tableController mapObjectsWithClass:[RKTestUser class] toTableCellsWithMapping:cellMapping];
[tableController loadObjects:[NSArray arrayWithObject:[RKTestUser user]]];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
assertThat([tableController cellMappingForObjectAtIndexPath:indexPath], is(equalTo(cellMapping)));
}
- (void)testChangeTheReuseIdentifierWhenMutatedWithinTheBlockInitializer
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
assertThat([tableController.cellMappings cellMappingForClass:[RKTestUser class]], is(nilValue()));
[tableController mapObjectsWithClass:[RKTestUser class] toTableCellsWithMapping:[RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *cellMapping) {
cellMapping.cellClass = [RKTestUserTableViewCell class];
cellMapping.reuseIdentifier = @"RKTestUserOverride";
}]];
RKTableViewCellMapping *userCellMapping = [tableController.cellMappings cellMappingForClass:[RKTestUser class]];
assertThat(userCellMapping, isNot(nilValue()));
assertThat(userCellMapping.reuseIdentifier, is(equalTo(@"RKTestUserOverride")));
}
#pragma mark - Static Object Loading
- (void)testLoadAnArrayOfObjects
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
NSArray *objects = [NSArray arrayWithObject:@"one"];
assertThat([tableController sectionAtIndex:0].objects, is(empty()));
[tableController loadObjects:objects];
assertThat([tableController sectionAtIndex:0].objects, is(equalTo(objects)));
}
- (void)testLoadAnArrayOfObjectsToTheTestifiedSection
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
[tableController addSection:[RKTableSection section]];
NSArray *objects = [NSArray arrayWithObject:@"one"];
assertThat([tableController sectionAtIndex:1].objects, is(empty()));
[tableController loadObjects:objects inSection:1];
assertThat([tableController sectionAtIndex:1].objects, is(equalTo(objects)));
}
- (void)testLoadAnArrayOfTableItems
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
NSArray *tableItems = [RKTableItem tableItemsFromStrings:@"One", @"Two", @"Three", nil];
[tableController loadTableItems:tableItems];
assertThatBool([tableController isLoaded], is(equalToBool(YES)));
assertThatInt(tableController.rowCount, is(equalToInt(3)));
UITableViewCell *cellOne = [tableController tableView:tableController.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
UITableViewCell *cellTwo = [tableController tableView:tableController.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]];
UITableViewCell *cellThree = [tableController tableView:tableController.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:2 inSection:0]];
assertThat(cellOne.textLabel.text, is(equalTo(@"One")));
assertThat(cellTwo.textLabel.text, is(equalTo(@"Two")));
assertThat(cellThree.textLabel.text, is(equalTo(@"Three")));
}
- (void)testAllowYouToTriggerAnEmptyLoad
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
assertThatBool([tableController isLoaded], is(equalToBool(NO)));
[tableController loadEmpty];
assertThatBool([tableController isLoaded], is(equalToBool(YES)));
assertThatBool([tableController isEmpty], is(equalToBool(YES)));
}
#pragma mark - Network Load
- (void)testLoadCollectionOfObjectsAndMapThemIntoTableViewCells
{
RKObjectManager *objectManager = [RKTestFactory objectManager];
objectManager.client.cachePolicy = RKRequestCachePolicyNone;
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.objectManager = objectManager;
[tableController mapObjectsWithClass:[RKTestUser class] toTableCellsWithMapping:[RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *mapping) {
mapping.cellClass = [RKTestUserTableViewCell class];
[mapping mapKeyPath:@"name" toAttribute:@"textLabel.text"];
[mapping mapKeyPath:@"nickName" toAttribute:@"detailTextLabel.text"];
}]];
RKTableControllerTestDelegate *delegate = [RKTableControllerTestDelegate tableControllerDelegate];
delegate.timeout = 10;
tableController.delegate = delegate;
[tableController loadTableFromResourcePath:@"/JSON/users.json" usingBlock:^(RKObjectLoader *objectLoader) {
objectLoader.objectMapping = [RKObjectMapping mappingForClass:[RKTestUser class] usingBlock:^(RKObjectMapping *mapping) {
[mapping mapAttributes:@"name", nil];
}];
}];
[delegate waitForLoad];
assertThatBool([tableController isLoaded], is(equalToBool(YES)));
assertThatInt(tableController.rowCount, is(equalToInt(3)));
}
- (void)testSetTheModelToTheLoadedStateIfObjectsAreLoadedSuccessfully
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
assertThatBool([tableController isLoaded], is(equalToBool(NO)));
NSArray *objects = [NSArray arrayWithObject:[RKTestUser new]];
id mockLoader = [OCMockObject mockForClass:[RKObjectLoader class]];
[tableController objectLoader:mockLoader didLoadObjects:objects];
assertThatBool([tableController isLoading], is(equalToBool(NO)));
assertThatBool([tableController isLoaded], is(equalToBool(YES)));
}
- (void)testSetTheModelToErrorStateIfTheObjectLoaderFailsWithAnError
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
id mockObjectLoader = [OCMockObject niceMockForClass:[RKObjectLoader class]];
NSError *error = [NSError errorWithDomain:@"Test" code:0 userInfo:nil];
[tableController objectLoader:mockObjectLoader didFailWithError:error];
assertThatBool([tableController isLoading], is(equalToBool(NO)));
assertThatBool([tableController isLoaded], is(equalToBool(YES)));
assertThatBool([tableController isError], is(equalToBool(YES)));
assertThatBool([tableController isEmpty], is(equalToBool(YES)));
}
- (void)testErrorIsClearedAfterSubsequentLoad
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
id mockObjectLoader = [OCMockObject niceMockForClass:[RKObjectLoader class]];
NSError *error = [NSError errorWithDomain:@"Test" code:0 userInfo:nil];
[tableController objectLoader:mockObjectLoader didFailWithError:error];
assertThatBool([tableController isLoading], is(equalToBool(NO)));
assertThatBool([tableController isLoaded], is(equalToBool(YES)));
assertThatBool([tableController isError], is(equalToBool(YES)));
assertThatBool([tableController isEmpty], is(equalToBool(YES)));
[tableController objectLoader:mockObjectLoader didLoadObjects:[NSArray array]];
assertThatBool([tableController isError], is(equalToBool(NO)));
assertThat(tableController.error, is(nilValue()));
}
- (void)testDisplayOfErrorImageTakesPresendenceOverEmpty
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
UIImage *imageForEmpty = [RKTestFixture imageWithContentsOfFixture:@"blake.png"];
UIImage *imageForError = [imageForEmpty copy];
tableController.imageForEmpty = imageForEmpty;
tableController.imageForError = imageForError;
id mockObjectLoader = [OCMockObject niceMockForClass:[RKObjectLoader class]];
NSError *error = [NSError errorWithDomain:@"Test" code:0 userInfo:nil];
[tableController objectLoader:mockObjectLoader didFailWithError:error];
assertThatBool([tableController isLoading], is(equalToBool(NO)));
assertThatBool([tableController isLoaded], is(equalToBool(YES)));
assertThatBool([tableController isError], is(equalToBool(YES)));
assertThatBool([tableController isEmpty], is(equalToBool(YES)));
UIImage *overlayImage = [tableController overlayImage];
assertThat(overlayImage, isNot(nilValue()));
assertThat(overlayImage, is(equalTo(imageForError)));
}
- (void)testBitwiseLoadingTransition
{
RKTableControllerState oldState = RKTableControllerStateNotYetLoaded;
RKTableControllerState newState = RKTableControllerStateLoading;
BOOL loadingTransitioned = ((oldState ^ newState) & RKTableControllerStateLoading);
assertThatBool(loadingTransitioned, is(equalToBool(YES)));
oldState = RKTableControllerStateOffline | RKTableControllerStateEmpty;
newState = RKTableControllerStateOffline | RKTableControllerStateEmpty | RKTableControllerStateLoading;
loadingTransitioned = ((oldState ^ newState) & RKTableControllerStateLoading);
assertThatBool(loadingTransitioned, is(equalToBool(YES)));
oldState = RKTableControllerStateNormal;
newState = RKTableControllerStateLoading;
loadingTransitioned = ((oldState ^ newState) & RKTableControllerStateLoading);
assertThatBool(loadingTransitioned, is(equalToBool(YES)));
oldState = RKTableControllerStateOffline | RKTableControllerStateEmpty | RKTableControllerStateLoading;
newState = RKTableControllerStateOffline | RKTableControllerStateLoading;
loadingTransitioned = ((oldState ^ newState) & RKTableControllerStateLoading);
assertThatBool(loadingTransitioned, is(equalToBool(NO)));
oldState = RKTableControllerStateNotYetLoaded;
newState = RKTableControllerStateOffline;
loadingTransitioned = ((oldState ^ newState) & RKTableControllerStateLoading);
assertThatBool(loadingTransitioned, is(equalToBool(NO)));
}
- (void)testSetTheModelToAnEmptyStateIfTheObjectLoaderReturnsAnEmptyCollection
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
assertThatBool([tableController isLoaded], is(equalToBool(NO)));
NSArray *objects = [NSArray array];
id mockLoader = [OCMockObject mockForClass:[RKObjectLoader class]];
[tableController objectLoader:mockLoader didLoadObjects:objects];
assertThatBool([tableController isLoading], is(equalToBool(NO)));
assertThatBool([tableController isEmpty], is(equalToBool(YES)));
}
- (void)testSetTheModelToALoadedStateEvenIfTheObjectLoaderReturnsAnEmptyCollection
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
assertThatBool([tableController isLoaded], is(equalToBool(NO)));
NSArray *objects = [NSArray array];
id mockLoader = [OCMockObject mockForClass:[RKObjectLoader class]];
[tableController objectLoader:mockLoader didLoadObjects:objects];
assertThatBool([tableController isLoading], is(equalToBool(NO)));
assertThatBool([tableController isEmpty], is(equalToBool(YES)));
assertThatBool([tableController isLoaded], is(equalToBool(YES)));
}
- (void)testEnterTheLoadingStateWhenTheRequestStartsLoading
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
assertThatBool([tableController isLoaded], is(equalToBool(NO)));
assertThatBool([tableController isLoading], is(equalToBool(NO)));
id mockLoader = [OCMockObject mockForClass:[RKObjectLoader class]];
[tableController requestDidStartLoad:mockLoader];
assertThatBool([tableController isLoading], is(equalToBool(YES)));
}
- (void)testExitTheLoadingStateWhenTheRequestFinishesLoading
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
assertThatBool([tableController isLoaded], is(equalToBool(NO)));
assertThatBool([tableController isLoading], is(equalToBool(NO)));
id mockLoader = [OCMockObject niceMockForClass:[RKObjectLoader class]];
[tableController requestDidStartLoad:mockLoader];
assertThatBool([tableController isLoading], is(equalToBool(YES)));
[tableController objectLoaderDidFinishLoading:mockLoader];
assertThatBool([tableController isLoading], is(equalToBool(NO)));
}
- (void)testClearTheLoadingStateWhenARequestIsCancelled
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
assertThatBool([tableController isLoaded], is(equalToBool(NO)));
assertThatBool([tableController isLoading], is(equalToBool(NO)));
id mockLoader = [OCMockObject mockForClass:[RKObjectLoader class]];
[tableController requestDidStartLoad:mockLoader];
assertThatBool([tableController isLoading], is(equalToBool(YES)));
[tableController requestDidCancelLoad:mockLoader];
assertThatBool([tableController isLoading], is(equalToBool(NO)));
}
- (void)testClearTheLoadingStateWhenARequestTimesOut
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
assertThatBool([tableController isLoaded], is(equalToBool(NO)));
assertThatBool([tableController isLoading], is(equalToBool(NO)));
id mockLoader = [OCMockObject mockForClass:[RKObjectLoader class]];
[tableController requestDidStartLoad:mockLoader];
assertThatBool([tableController isLoading], is(equalToBool(YES)));
[tableController requestDidTimeout:mockLoader];
assertThatBool([tableController isLoading], is(equalToBool(NO)));
}
- (void)testDoSomethingWhenTheRequestLoadsAnUnexpectedResponse
{
RKLogCritical(@"PENDING - Undefined Behavior!!!");
}
- (void)testLoadCollectionOfObjectsAndMapThemIntoSections
{
RKObjectManager *objectManager = [RKTestFactory objectManager];
objectManager.client.cachePolicy = RKRequestCachePolicyNone;
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.objectManager = objectManager;
[tableController mapObjectsWithClass:[RKTestUser class] toTableCellsWithMapping:[RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *mapping) {
mapping.cellClass = [RKTestUserTableViewCell class];
[mapping mapKeyPath:@"name" toAttribute:@"textLabel.text"];
[mapping mapKeyPath:@"nickName" toAttribute:@"detailTextLabel.text"];
}]];
tableController.sectionNameKeyPath = @"name";
RKTableControllerTestDelegate *delegate = [RKTableControllerTestDelegate tableControllerDelegate];
delegate.timeout = 10;
tableController.delegate = delegate;
[tableController loadTableFromResourcePath:@"/JSON/users.json" usingBlock:^(RKObjectLoader *objectLoader) {
objectLoader.objectMapping = [RKObjectMapping mappingForClass:[RKTestUser class] usingBlock:^(RKObjectMapping *mapping) {
[mapping mapAttributes:@"name", nil];
}];
}];
[delegate waitForLoad];
assertThatBool([tableController isLoaded], is(equalToBool(YES)));
assertThatInt(tableController.sectionCount, is(equalToInt(3)));
assertThatInt(tableController.rowCount, is(equalToInt(3)));
}
- (void)testLoadingACollectionOfObjectsIntoSectionsAndThenLoadingAnEmptyCollectionChangesTableToEmpty
{
RKObjectManager *objectManager = [RKTestFactory objectManager];
objectManager.client.cachePolicy = RKRequestCachePolicyNone;
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.objectManager = objectManager;
[tableController mapObjectsWithClass:[RKTestUser class] toTableCellsWithMapping:[RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *mapping) {
mapping.cellClass = [RKTestUserTableViewCell class];
[mapping mapKeyPath:@"name" toAttribute:@"textLabel.text"];
[mapping mapKeyPath:@"nickName" toAttribute:@"detailTextLabel.text"];
}]];
tableController.sectionNameKeyPath = @"name";
RKTableControllerTestDelegate *delegate = [RKTableControllerTestDelegate tableControllerDelegate];
delegate.timeout = 10;
tableController.delegate = delegate;
[tableController loadTableFromResourcePath:@"/JSON/users.json" usingBlock:^(RKObjectLoader *objectLoader) {
objectLoader.objectMapping = [RKObjectMapping mappingForClass:[RKTestUser class] usingBlock:^(RKObjectMapping *mapping) {
[mapping mapAttributes:@"name", nil];
}];
}];
[delegate waitForLoad];
assertThatBool([tableController isLoaded], is(equalToBool(YES)));
assertThatInt(tableController.sectionCount, is(equalToInt(3)));
assertThatInt(tableController.rowCount, is(equalToInt(3)));
delegate = [RKTableControllerTestDelegate tableControllerDelegate];
delegate.timeout = 10;
tableController.delegate = delegate;
[tableController loadTableFromResourcePath:@"/204" usingBlock:^(RKObjectLoader *objectLoader) {
objectLoader.objectMapping = [RKObjectMapping mappingForClass:[RKTestUser class] usingBlock:^(RKObjectMapping *mapping) {
[mapping mapAttributes:@"name", nil];
}];
}];
[delegate waitForLoad];
assertThatBool([tableController isLoaded], is(equalToBool(YES)));
assertThatBool([tableController isEmpty], is(equalToBool(YES)));
}
#pragma mark - RKTableViewDelegate Tests
- (void)testNotifyTheDelegateWhenLoadingStarts
{
RKObjectManager *objectManager = [RKTestFactory objectManager];
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.objectManager = objectManager;
[tableController mapObjectsWithClass:[RKTestUser class] toTableCellsWithMapping:[RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *mapping) {
mapping.cellClass = [RKTestUserTableViewCell class];
[mapping mapKeyPath:@"name" toAttribute:@"textLabel.text"];
[mapping mapKeyPath:@"nickName" toAttribute:@"detailTextLabel.text"];
}]];
id mockDelegate = [OCMockObject partialMockForObject:[RKTableControllerTestDelegate new]];
[[[mockDelegate expect] andForwardToRealObject] tableControllerDidStartLoad:tableController];
tableController.delegate = mockDelegate;
[tableController loadTableFromResourcePath:@"/JSON/users.json" usingBlock:^(RKObjectLoader *objectLoader) {
objectLoader.objectMapping = [RKObjectMapping mappingForClass:[RKTestUser class] usingBlock:^(RKObjectMapping *mapping) {
[mapping mapAttributes:@"name", nil];
}];
}];
[mockDelegate waitForLoad];
STAssertNoThrow([mockDelegate verify], nil);
}
- (void)testNotifyTheDelegateWhenLoadingFinishes
{
RKObjectManager *objectManager = [RKTestFactory objectManager];
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.objectManager = objectManager;
[tableController mapObjectsWithClass:[RKTestUser class] toTableCellsWithMapping:[RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *mapping) {
mapping.cellClass = [RKTestUserTableViewCell class];
[mapping mapKeyPath:@"name" toAttribute:@"textLabel.text"];
[mapping mapKeyPath:@"nickName" toAttribute:@"detailTextLabel.text"];
}]];
RKTableControllerTestDelegate *delegate = [RKTableControllerTestDelegate new];
id mockDelegate = [OCMockObject partialMockForObject:delegate];
[[[mockDelegate expect] andForwardToRealObject] tableControllerDidFinishLoad:tableController];
tableController.delegate = mockDelegate;
[tableController loadTableFromResourcePath:@"/JSON/users.json" usingBlock:^(RKObjectLoader *objectLoader) {
objectLoader.objectMapping = [RKObjectMapping mappingForClass:[RKTestUser class] usingBlock:^(RKObjectMapping *mapping) {
[mapping mapAttributes:@"name", nil];
}];
}];
[mockDelegate waitForLoad];
STAssertNoThrow([mockDelegate verify], nil);
}
- (void)testNotifyTheDelegateOnDidFinalizeLoad
{
RKObjectManager *objectManager = [RKTestFactory objectManager];
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.objectManager = objectManager;
[tableController mapObjectsWithClass:[RKTestUser class] toTableCellsWithMapping:[RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *mapping) {
mapping.cellClass = [RKTestUserTableViewCell class];
[mapping mapKeyPath:@"name" toAttribute:@"textLabel.text"];
[mapping mapKeyPath:@"nickName" toAttribute:@"detailTextLabel.text"];
}]];
RKTableControllerTestDelegate *delegate = [RKTableControllerTestDelegate new];
id mockDelegate = [OCMockObject partialMockForObject:delegate];
[[mockDelegate expect] tableControllerDidFinalizeLoad:tableController];
tableController.delegate = mockDelegate;
[tableController loadTableFromResourcePath:@"/JSON/users.json" usingBlock:^(RKObjectLoader *objectLoader) {
objectLoader.objectMapping = [RKObjectMapping mappingForClass:[RKTestUser class] usingBlock:^(RKObjectMapping *mapping) {
[mapping mapAttributes:@"name", nil];
}];
}];
[mockDelegate waitForLoad];
STAssertNoThrow([mockDelegate verify], nil);
}
- (void)testNotifyTheDelegateWhenAnErrorOccurs
{
RKObjectManager *objectManager = [RKTestFactory objectManager];
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.objectManager = objectManager;
[tableController mapObjectsWithClass:[RKTestUser class] toTableCellsWithMapping:[RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *mapping) {
mapping.cellClass = [RKTestUserTableViewCell class];
[mapping mapKeyPath:@"name" toAttribute:@"textLabel.text"];
[mapping mapKeyPath:@"nickName" toAttribute:@"detailTextLabel.text"];
}]];
RKTableControllerTestDelegate *delegate = [RKTableControllerTestDelegate new];
id mockDelegate = [OCMockObject partialMockForObject:delegate];
[[[mockDelegate expect] andForwardToRealObject] tableController:tableController didFailLoadWithError:OCMOCK_ANY];
tableController.delegate = mockDelegate;
[tableController loadTableFromResourcePath:@"/fail" usingBlock:^(RKObjectLoader *objectLoader) {
objectLoader.objectMapping = [RKObjectMapping mappingForClass:[RKTestUser class] usingBlock:^(RKObjectMapping *mapping) {
[mapping mapAttributes:@"name", nil];
}];
}];
[mockDelegate waitForLoad];
STAssertNoThrow([mockDelegate verify], nil);
}
- (void)testNotifyTheDelegateWhenAnEmptyCollectionIsLoaded
{
RKObjectManager *objectManager = [RKTestFactory objectManager];
objectManager.client.cachePolicy = RKRequestCachePolicyNone;
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.objectManager = objectManager;
[tableController mapObjectsWithClass:[RKTestUser class] toTableCellsWithMapping:[RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *mapping) {
mapping.cellClass = [RKTestUserTableViewCell class];
[mapping mapKeyPath:@"name" toAttribute:@"textLabel.text"];
[mapping mapKeyPath:@"nickName" toAttribute:@"detailTextLabel.text"];
}]];
RKTableControllerTestDelegate *delegate = [RKTableControllerTestDelegate new];
delegate.timeout = 5;
id mockDelegate = [OCMockObject partialMockForObject:delegate];
[[[mockDelegate expect] andForwardToRealObject] tableControllerDidBecomeEmpty:tableController];
tableController.delegate = mockDelegate;
[tableController loadTableFromResourcePath:@"/empty/array" usingBlock:^(RKObjectLoader *objectLoader) {
objectLoader.objectMapping = [RKObjectMapping mappingForClass:[RKTestUser class] usingBlock:^(RKObjectMapping *mapping) {
[mapping mapAttributes:@"name", nil];
}];
}];
[mockDelegate waitForLoad];
STAssertNoThrow([mockDelegate verify], nil);
}
- (void)testNotifyTheDelegateWhenModelWillLoadWithObjectLoader
{
RKObjectManager *objectManager = [RKTestFactory objectManager];
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.objectManager = objectManager;
[tableController mapObjectsWithClass:[RKTestUser class] toTableCellsWithMapping:[RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *mapping) {
mapping.cellClass = [RKTestUserTableViewCell class];
[mapping mapKeyPath:@"name" toAttribute:@"textLabel.text"];
[mapping mapKeyPath:@"nickName" toAttribute:@"detailTextLabel.text"];
}]];
RKTableControllerTestDelegate *delegate = [RKTableControllerTestDelegate new];
id mockDelegate = [OCMockObject partialMockForObject:delegate];
[[[mockDelegate expect] andForwardToRealObject] tableController:tableController willLoadTableWithObjectLoader:OCMOCK_ANY];
tableController.delegate = mockDelegate;
[tableController loadTableFromResourcePath:@"/empty/array" usingBlock:^(RKObjectLoader *objectLoader) {
objectLoader.objectMapping = [RKObjectMapping mappingForClass:[RKTestUser class] usingBlock:^(RKObjectMapping *mapping) {
[mapping mapAttributes:@"name", nil];
}];
}];
[mockDelegate waitForLoad];
STAssertNoThrow([mockDelegate verify], nil);
}
- (void)testNotifyTheDelegateWhenModelDidLoadWithObjectLoader
{
RKObjectManager *objectManager = [RKTestFactory objectManager];
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.objectManager = objectManager;
[tableController mapObjectsWithClass:[RKTestUser class] toTableCellsWithMapping:[RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *mapping) {
mapping.cellClass = [RKTestUserTableViewCell class];
[mapping mapKeyPath:@"name" toAttribute:@"textLabel.text"];
[mapping mapKeyPath:@"nickName" toAttribute:@"detailTextLabel.text"];
}]];
RKTableControllerTestDelegate *delegate = [RKTableControllerTestDelegate new];
id mockDelegate = [OCMockObject partialMockForObject:delegate];
[[[mockDelegate expect] andForwardToRealObject] tableController:tableController didLoadTableWithObjectLoader:OCMOCK_ANY];
tableController.delegate = mockDelegate;
[tableController loadTableFromResourcePath:@"/empty/array" usingBlock:^(RKObjectLoader *objectLoader) {
objectLoader.objectMapping = [RKObjectMapping mappingForClass:[RKTestUser class] usingBlock:^(RKObjectMapping *mapping) {
[mapping mapAttributes:@"name", nil];
}];
}];
[mockDelegate waitForLoad];
STAssertNoThrow([mockDelegate verify], nil);
}
- (void)testNotifyTheDelegateWhenModelDidCancelLoad
{
RKObjectManager *objectManager = [RKTestFactory objectManager];
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.objectManager = objectManager;
[tableController mapObjectsWithClass:[RKTestUser class] toTableCellsWithMapping:[RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *mapping) {
mapping.cellClass = [RKTestUserTableViewCell class];
[mapping mapKeyPath:@"name" toAttribute:@"textLabel.text"];
[mapping mapKeyPath:@"nickName" toAttribute:@"detailTextLabel.text"];
}]];
RKTableControllerTestDelegate *delegate = [RKTableControllerTestDelegate new];
id mockDelegate = [OCMockObject partialMockForObject:delegate];
[[[mockDelegate expect] andForwardToRealObject] tableControllerDidCancelLoad:tableController];
tableController.delegate = mockDelegate;
[tableController loadTableFromResourcePath:@"/empty/array" usingBlock:^(RKObjectLoader *objectLoader) {
objectLoader.objectMapping = [RKObjectMapping mappingForClass:[RKTestUser class] usingBlock:^(RKObjectMapping *mapping) {
[mapping mapAttributes:@"name", nil];
}];
}];
[tableController cancelLoad];
STAssertNoThrow([mockDelegate verify], nil);
}
- (void)testNotifyTheDelegateWhenDidEndEditingARow
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
RKTableItem *tableItem = [RKTableItem tableItem];
RKTableControllerTestDelegate *delegate = [RKTableControllerTestDelegate new];
id mockDelegate = [OCMockObject partialMockForObject:delegate];
[[[mockDelegate expect] andForwardToRealObject] tableController:tableController
didEndEditing:OCMOCK_ANY
atIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
tableController.delegate = mockDelegate;
[tableController loadTableItems:[NSArray arrayWithObject:tableItem]];
[tableController tableView:tableController.tableView didEndEditingRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
STAssertNoThrow([mockDelegate verify], nil);
}
- (void)testNotifyTheDelegateWhenWillBeginEditingARow
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
RKTableItem *tableItem = [RKTableItem tableItem];
RKTableControllerTestDelegate *delegate = [RKTableControllerTestDelegate new];
id mockDelegate = [OCMockObject partialMockForObject:delegate];
[[[mockDelegate expect] andForwardToRealObject] tableController:tableController
willBeginEditing:OCMOCK_ANY
atIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
tableController.delegate = mockDelegate;
[tableController loadTableItems:[NSArray arrayWithObject:tableItem]];
[tableController tableView:tableController.tableView willBeginEditingRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
STAssertNoThrow([mockDelegate verify], nil);
}
- (void)testNotifyTheDelegateWhenAnObjectIsInserted
{
NSArray *objects = [NSArray arrayWithObject:@"first object"];
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
RKTableControllerTestDelegate *delegate = [RKTableControllerTestDelegate new];
id mockDelegate = [OCMockObject partialMockForObject:delegate];
[[[mockDelegate expect] andForwardToRealObject] tableController:tableController
didInsertObject:@"first object"
atIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
[[[mockDelegate expect] andForwardToRealObject] tableController:tableController
didInsertObject:@"new object"
atIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]];
tableController.delegate = mockDelegate;
[tableController loadObjects:objects];
assertThat([tableController objectForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]],
is(equalTo(@"first object")));
[[tableController.sections objectAtIndex:0] insertObject:@"new object" atIndex:1];
assertThat([[tableController.sections objectAtIndex:0] objectAtIndex:0], is(equalTo(@"first object")));
assertThat([[tableController.sections objectAtIndex:0] objectAtIndex:1], is(equalTo(@"new object")));
STAssertNoThrow([mockDelegate verify], nil);
}
- (void)testNotifyTheDelegateWhenAnObjectIsUpdated
{
NSArray *objects = [NSArray arrayWithObjects:@"first object", @"second object", nil];
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
RKTableControllerTestDelegate *delegate = [RKTableControllerTestDelegate new];
id mockDelegate = [OCMockObject partialMockForObject:delegate];
[[[mockDelegate expect] andForwardToRealObject] tableController:tableController
didInsertObject:@"first object"
atIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
[[[mockDelegate expect] andForwardToRealObject] tableController:tableController
didInsertObject:@"second object"
atIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]];
[[[mockDelegate expect] andForwardToRealObject] tableController:tableController
didUpdateObject:@"new second object"
atIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]];
tableController.delegate = mockDelegate;
[tableController loadObjects:objects];
assertThat([[tableController.sections objectAtIndex:0] objectAtIndex:0], is(equalTo(@"first object")));
assertThat([[tableController.sections objectAtIndex:0] objectAtIndex:1], is(equalTo(@"second object")));
[[tableController.sections objectAtIndex:0] replaceObjectAtIndex:1 withObject:@"new second object"];
assertThat([[tableController.sections objectAtIndex:0] objectAtIndex:1], is(equalTo(@"new second object")));
STAssertNoThrow([mockDelegate verify], nil);
}
- (void)testNotifyTheDelegateWhenAnObjectIsDeleted
{
NSArray *objects = [NSArray arrayWithObjects:@"first object", @"second object", nil];
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
RKTableControllerTestDelegate *delegate = [RKTableControllerTestDelegate new];
id mockDelegate = [OCMockObject partialMockForObject:delegate];
[[[mockDelegate expect] andForwardToRealObject] tableController:tableController
didInsertObject:@"first object"
atIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
[[[mockDelegate expect] andForwardToRealObject] tableController:tableController
didInsertObject:@"second object"
atIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]];
[[[mockDelegate expect] andForwardToRealObject] tableController:tableController
didDeleteObject:@"second object"
atIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]];
tableController.delegate = mockDelegate;
[tableController loadObjects:objects];
assertThat([[tableController.sections objectAtIndex:0] objectAtIndex:0], is(equalTo(@"first object")));
assertThat([[tableController.sections objectAtIndex:0] objectAtIndex:1], is(equalTo(@"second object")));
[[tableController.sections objectAtIndex:0] removeObjectAtIndex:1];
assertThat([[tableController.sections objectAtIndex:0] objectAtIndex:0], is(equalTo(@"first object")));
STAssertNoThrow([mockDelegate verify], nil);
}
- (void)testNotifyTheDelegateWhenObjectsAreLoadedInASection
{
RKObjectManager *objectManager = [RKTestFactory objectManager];
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.objectManager = objectManager;
[tableController mapObjectsWithClass:[RKTestUser class] toTableCellsWithMapping:[RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *mapping) {
mapping.cellClass = [RKTestUserTableViewCell class];
[mapping mapKeyPath:@"name" toAttribute:@"textLabel.text"];
[mapping mapKeyPath:@"nickName" toAttribute:@"detailTextLabel.text"];
}]];
RKTableControllerTestDelegate *delegate = [RKTableControllerTestDelegate new];
id mockDelegate = [OCMockObject partialMockForObject:delegate];
[[mockDelegate expect] tableController:tableController didLoadObjects:OCMOCK_ANY inSection:OCMOCK_ANY];
tableController.delegate = mockDelegate;
[tableController loadTableFromResourcePath:@"/JSON/users.json" usingBlock:^(RKObjectLoader *objectLoader) {
objectLoader.objectMapping = [RKObjectMapping mappingForClass:[RKTestUser class] usingBlock:^(RKObjectMapping *mapping) {
[mapping mapAttributes:@"name", nil];
}];
}];
[mockDelegate waitForLoad];
STAssertNoThrow([mockDelegate verify], nil);
}
- (void)testDelegateIsNotifiedOfWillDisplayCellForObjectAtIndexPath
{
RKObjectManager *objectManager = [RKTestFactory objectManager];
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.objectManager = objectManager;
[tableController mapObjectsWithClass:[RKTestUser class] toTableCellsWithMapping:[RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *mapping) {
mapping.cellClass = [RKTestUserTableViewCell class];
[mapping mapKeyPath:@"name" toAttribute:@"textLabel.text"];
}]];
RKTableControllerTestDelegate *delegate = [RKTableControllerTestDelegate new];
id mockDelegate = [OCMockObject partialMockForObject:delegate];
[[[mockDelegate expect] andForwardToRealObject] tableController:tableController willLoadTableWithObjectLoader:OCMOCK_ANY];
tableController.delegate = mockDelegate;
[tableController loadTableFromResourcePath:@"/JSON/users.json" usingBlock:^(RKObjectLoader *objectLoader) {
objectLoader.objectMapping = [RKObjectMapping mappingForClass:[RKTestUser class] usingBlock:^(RKObjectMapping *mapping) {
[mapping mapAttributes:@"name", nil];
}];
}];
[[mockDelegate expect] tableController:tableController willDisplayCell:OCMOCK_ANY forObject:OCMOCK_ANY atIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
[[mockDelegate expect] tableController:tableController willDisplayCell:OCMOCK_ANY forObject:OCMOCK_ANY atIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]];
[[mockDelegate expect] tableController:tableController willDisplayCell:OCMOCK_ANY forObject:OCMOCK_ANY atIndexPath:[NSIndexPath indexPathForRow:2 inSection:0]];
[[[UIApplication sharedApplication].windows objectAtIndex:0] setRootViewController:viewController];
[mockDelegate waitForLoad];
STAssertNoThrow([mockDelegate verify], nil);
}
- (void)testDelegateIsNotifiedOfDidSelectRowForObjectAtIndexPath
{
RKObjectManager *objectManager = [RKTestFactory objectManager];
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.objectManager = objectManager;
[tableController mapObjectsWithClass:[RKTestUser class] toTableCellsWithMapping:[RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *mapping) {
mapping.cellClass = [RKTestUserTableViewCell class];
[mapping mapKeyPath:@"name" toAttribute:@"textLabel.text"];
}]];
RKTableControllerTestDelegate *delegate = [RKTableControllerTestDelegate new];
id mockDelegate = [OCMockObject partialMockForObject:delegate];
[[[mockDelegate expect] andForwardToRealObject] tableController:tableController willLoadTableWithObjectLoader:OCMOCK_ANY];
tableController.delegate = mockDelegate;
[tableController loadTableFromResourcePath:@"/JSON/users.json" usingBlock:^(RKObjectLoader *objectLoader) {
objectLoader.objectMapping = [RKObjectMapping mappingForClass:[RKTestUser class] usingBlock:^(RKObjectMapping *mapping) {
[mapping mapAttributes:@"name", nil];
}];
}];
[[mockDelegate expect] tableController:tableController didSelectCell:OCMOCK_ANY forObject:OCMOCK_ANY atIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
[[[UIApplication sharedApplication].windows objectAtIndex:0] setRootViewController:viewController];
[mockDelegate waitForLoad];
[tableController tableView:tableController.tableView didSelectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
STAssertNoThrow([mockDelegate verify], nil);
}
#pragma mark - Notifications
- (void)testPostANotificationWhenLoadingStarts
{
RKObjectManager *objectManager = [RKTestFactory objectManager];
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.objectManager = objectManager;
[tableController mapObjectsWithClass:[RKTestUser class] toTableCellsWithMapping:[RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *mapping) {
mapping.cellClass = [RKTestUserTableViewCell class];
[mapping mapKeyPath:@"name" toAttribute:@"textLabel.text"];
[mapping mapKeyPath:@"nickName" toAttribute:@"detailTextLabel.text"];
}]];
id observerMock = [OCMockObject observerMock];
[[NSNotificationCenter defaultCenter] addMockObserver:observerMock name:RKTableControllerDidStartLoadNotification object:tableController];
[[observerMock expect] notificationWithName:RKTableControllerDidStartLoadNotification object:tableController];
RKTableControllerTestDelegate *delegate = [RKTableControllerTestDelegate new];
tableController.delegate = delegate;
[tableController loadTableFromResourcePath:@"/JSON/users.json" usingBlock:^(RKObjectLoader *objectLoader) {
objectLoader.objectMapping = [RKObjectMapping mappingForClass:[RKTestUser class] usingBlock:^(RKObjectMapping *mapping) {
[mapping mapAttributes:@"name", nil];
}];
}];
[delegate waitForLoad];
[observerMock verify];
}
- (void)testPostANotificationWhenLoadingFinishes
{
RKObjectManager *objectManager = [RKTestFactory objectManager];
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.objectManager = objectManager;
[tableController mapObjectsWithClass:[RKTestUser class] toTableCellsWithMapping:[RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *mapping) {
mapping.cellClass = [RKTestUserTableViewCell class];
[mapping mapKeyPath:@"name" toAttribute:@"textLabel.text"];
[mapping mapKeyPath:@"nickName" toAttribute:@"detailTextLabel.text"];
}]];
id observerMock = [OCMockObject observerMock];
[[NSNotificationCenter defaultCenter] addMockObserver:observerMock name:RKTableControllerDidFinishLoadNotification object:tableController];
[[observerMock expect] notificationWithName:RKTableControllerDidFinishLoadNotification object:tableController];
RKTableControllerTestDelegate *delegate = [RKTableControllerTestDelegate new];
tableController.delegate = delegate;
[tableController loadTableFromResourcePath:@"/JSON/users.json" usingBlock:^(RKObjectLoader *objectLoader) {
objectLoader.objectMapping = [RKObjectMapping mappingForClass:[RKTestUser class] usingBlock:^(RKObjectMapping *mapping) {
[mapping mapAttributes:@"name", nil];
}];
}];
[delegate waitForLoad];
[observerMock verify];
}
- (void)testPostANotificationWhenObjectsAreLoaded
{
RKObjectManager *objectManager = [RKTestFactory objectManager];
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.objectManager = objectManager;
[tableController mapObjectsWithClass:[RKTestUser class] toTableCellsWithMapping:[RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *mapping) {
mapping.cellClass = [RKTestUserTableViewCell class];
[mapping mapKeyPath:@"name" toAttribute:@"textLabel.text"];
[mapping mapKeyPath:@"nickName" toAttribute:@"detailTextLabel.text"];
}]];
id observerMock = [OCMockObject observerMock];
[[NSNotificationCenter defaultCenter] addMockObserver:observerMock name:RKTableControllerDidLoadObjectsNotification object:tableController];
[[observerMock expect] notificationWithName:RKTableControllerDidLoadObjectsNotification object:tableController];
RKTableControllerTestDelegate *delegate = [RKTableControllerTestDelegate new];
tableController.delegate = delegate;
[tableController loadTableFromResourcePath:@"/JSON/users.json" usingBlock:^(RKObjectLoader *objectLoader) {
objectLoader.objectMapping = [RKObjectMapping mappingForClass:[RKTestUser class] usingBlock:^(RKObjectMapping *mapping) {
[mapping mapAttributes:@"name", nil];
}];
}];
[delegate waitForLoad];
[observerMock verify];
}
- (void)testPostANotificationWhenAnErrorOccurs
{
RKObjectManager *objectManager = [RKTestFactory objectManager];
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.objectManager = objectManager;
[tableController mapObjectsWithClass:[RKTestUser class] toTableCellsWithMapping:[RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *mapping) {
mapping.cellClass = [RKTestUserTableViewCell class];
[mapping mapKeyPath:@"name" toAttribute:@"textLabel.text"];
[mapping mapKeyPath:@"nickName" toAttribute:@"detailTextLabel.text"];
}]];
id observerMock = [OCMockObject observerMock];
[[NSNotificationCenter defaultCenter] addMockObserver:observerMock name:RKTableControllerDidLoadErrorNotification object:tableController];
[[observerMock expect] notificationWithName:RKTableControllerDidLoadErrorNotification object:tableController userInfo:OCMOCK_ANY];
RKTableControllerTestDelegate *delegate = [RKTableControllerTestDelegate new];
tableController.delegate = delegate;
[tableController loadTableFromResourcePath:@"/fail" usingBlock:^(RKObjectLoader *objectLoader) {
objectLoader.objectMapping = [RKObjectMapping mappingForClass:[RKTestUser class] usingBlock:^(RKObjectMapping *mapping) {
[mapping mapAttributes:@"name", nil];
}];
}];
[delegate waitForLoad];
[observerMock verify];
}
- (void)testPostANotificationWhenAnEmptyCollectionIsLoaded
{
RKObjectManager *objectManager = [RKTestFactory objectManager];
objectManager.client.cachePolicy = RKRequestCachePolicyNone;
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.objectManager = objectManager;
[tableController mapObjectsWithClass:[RKTestUser class] toTableCellsWithMapping:[RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *mapping) {
mapping.cellClass = [RKTestUserTableViewCell class];
[mapping mapKeyPath:@"name" toAttribute:@"textLabel.text"];
[mapping mapKeyPath:@"nickName" toAttribute:@"detailTextLabel.text"];
}]];
id observerMock = [OCMockObject observerMock];
[[NSNotificationCenter defaultCenter] addMockObserver:observerMock name:RKTableControllerDidLoadEmptyNotification object:tableController];
[[observerMock expect] notificationWithName:RKTableControllerDidLoadEmptyNotification object:tableController];
RKTableControllerTestDelegate *delegate = [RKTableControllerTestDelegate new];
tableController.delegate = delegate;
[tableController loadTableFromResourcePath:@"/empty/array" usingBlock:^(RKObjectLoader *objectLoader) {
objectLoader.objectMapping = [RKObjectMapping mappingForClass:[RKTestUser class] usingBlock:^(RKObjectMapping *mapping) {
[mapping mapAttributes:@"name", nil];
}];
}];
[delegate waitForLoad];
[observerMock verify];
}
#pragma mark - State Transitions
- (void)testInitializesToNotYetLoadedState
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
assertThatBool(tableController.state == RKTableControllerStateNotYetLoaded, is(equalToBool(YES)));
}
- (void)testInitialLoadSetsStateToLoading
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
assertThatBool([tableController isLoaded], is(equalToBool(NO)));
assertThatBool([tableController isLoading], is(equalToBool(NO)));
id mockLoader = [OCMockObject mockForClass:[RKObjectLoader class]];
[tableController requestDidStartLoad:mockLoader];
assertThatBool([tableController isLoading], is(equalToBool(YES)));
assertThatBool([tableController isLoaded], is(equalToBool(NO)));
}
- (void)testSuccessfulLoadSetsStateToNormal
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
assertThatBool([tableController isLoaded], is(equalToBool(NO)));
assertThatBool([tableController isLoading], is(equalToBool(NO)));
id mockLoader = [OCMockObject mockForClass:[RKObjectLoader class]];
[tableController objectLoader:mockLoader didLoadObjects:[NSArray arrayWithObject:@"test"]];
assertThatBool([tableController isLoading], is(equalToBool(NO)));
assertThatBool([tableController isLoaded], is(equalToBool(YES)));
assertThatInteger(tableController.state, is(equalToInteger(RKTableControllerStateNormal)));
}
- (void)testErrorLoadsSetsStateToError
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
assertThatBool([tableController isLoaded], is(equalToBool(NO)));
assertThatBool([tableController isLoading], is(equalToBool(NO)));
id mockLoader = [OCMockObject mockForClass:[RKObjectLoader class]];
NSError *error = [NSError errorWithDomain:@"Test" code:1234 userInfo:nil];
[tableController objectLoader:mockLoader didFailWithError:error];
assertThatBool([tableController isLoaded], is(equalToBool(YES)));
assertThatBool([tableController isError], is(equalToBool(YES)));
assertThatBool([tableController isEmpty], is(equalToBool(YES)));
}
- (void)testSecondaryLoadAfterErrorSetsStateToErrorAndLoading
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
assertThatBool([tableController isLoaded], is(equalToBool(NO)));
assertThatBool([tableController isLoading], is(equalToBool(NO)));
id mockLoader = [OCMockObject mockForClass:[RKObjectLoader class]];
NSError *error = [NSError errorWithDomain:@"Test" code:1234 userInfo:nil];
[tableController objectLoader:mockLoader didFailWithError:error];
assertThatBool([tableController isLoaded], is(equalToBool(YES)));
assertThatBool([tableController isError], is(equalToBool(YES)));
assertThatBool([tableController isEmpty], is(equalToBool(YES)));
[tableController requestDidStartLoad:mockLoader];
assertThatBool([tableController isLoading], is(equalToBool(YES)));
assertThatBool([tableController isError], is(equalToBool(YES)));
}
- (void)testEmptyLoadSetsStateToEmpty
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
[tableController loadEmpty];
assertThatBool([tableController isEmpty], is(equalToBool(YES)));
}
- (void)testSecondaryLoadAfterEmptySetsStateToEmptyAndLoading
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
[tableController loadEmpty];
assertThatBool([tableController isEmpty], is(equalToBool(YES)));
assertThatBool([tableController isLoading], is(equalToBool(NO)));
id mockLoader = [OCMockObject mockForClass:[RKObjectLoader class]];
[tableController requestDidStartLoad:mockLoader];
assertThatBool([tableController isLoading], is(equalToBool(YES)));
assertThatBool([tableController isEmpty], is(equalToBool(YES)));
}
- (void)testTransitionToOfflineAfterLoadSetsStateToOfflineAndLoaded
{
RKObjectManager *objectManager = [RKTestFactory objectManager];
id mockManager = [OCMockObject partialMockForObject:objectManager];
BOOL isOnline = YES;
[[[mockManager stub] andReturnValue:OCMOCK_VALUE(isOnline)] isOnline];
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.objectManager = mockManager;
[tableController loadEmpty];
assertThatBool([tableController isEmpty], is(equalToBool(YES)));
assertThatBool([tableController isLoading], is(equalToBool(NO)));
assertThatBool([tableController isOffline], is(equalToBool(NO)));
id mockLoader = [OCMockObject mockForClass:[RKObjectLoader class]];
[tableController requestDidStartLoad:mockLoader];
assertThatBool([tableController isLoading], is(equalToBool(YES)));
assertThatBool([tableController isEmpty], is(equalToBool(YES)));
isOnline = NO;
id mockManager2 = [OCMockObject partialMockForObject:objectManager];
[[[mockManager2 stub] andReturnValue:OCMOCK_VALUE(isOnline)] isOnline];
tableController.objectManager = mockManager2;
[[NSNotificationCenter defaultCenter] postNotificationName:RKObjectManagerDidBecomeOfflineNotification object:tableController.objectManager];
assertThatBool(tableController.isOffline, is(equalToBool(YES)));
}
#pragma mark - State Views
- (void)testPermitYouToOverlayAnImageOnTheTable
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
UIImage *image = [RKTestFixture imageWithContentsOfFixture:@"blake.png"];
[tableController showImageInOverlay:image];
UIImageView *imageView = tableController.stateOverlayImageView;
assertThat(imageView, isNot(nilValue()));
assertThat(imageView.image, is(equalTo(image)));
}
- (void)testPermitYouToRemoveAnImageOverlayFromTheTable
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
UIImage *image = [RKTestFixture imageWithContentsOfFixture:@"blake.png"];
[tableController showImageInOverlay:image];
assertThat([tableController.tableView.superview subviews], isNot(empty()));
[tableController removeImageOverlay];
assertThat([tableController.tableView.superview subviews], is(nilValue()));
}
- (void)testTriggerDisplayOfTheErrorViewOnTransitionToErrorState
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
UIImage *image = [RKTestFixture imageWithContentsOfFixture:@"blake.png"];
tableController.imageForError = image;
id mockError = [OCMockObject mockForClass:[NSError class]];
[tableController objectLoader:nil didFailWithError:mockError];
assertThatBool([tableController isError], is(equalToBool(YES)));
UIImageView *imageView = tableController.stateOverlayImageView;
assertThat(imageView, isNot(nilValue()));
assertThat(imageView.image, is(equalTo(image)));
}
- (void)testTriggerHidingOfTheErrorViewOnTransitionOutOfTheErrorState
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
UIImage *image = [RKTestFixture imageWithContentsOfFixture:@"blake.png"];
tableController.imageForError = image;
id mockError = [OCMockObject niceMockForClass:[NSError class]];
[tableController objectLoader:nil didFailWithError:mockError];
assertThatBool([tableController isError], is(equalToBool(YES)));
UIImageView *imageView = tableController.stateOverlayImageView;
assertThat(imageView, isNot(nilValue()));
assertThat(imageView.image, is(equalTo(image)));
[tableController loadTableItems:[NSArray arrayWithObject:[RKTableItem tableItem]]];
assertThat(tableController.error, is(nilValue()));
assertThat(tableController.stateOverlayImageView.image, is(nilValue()));
}
- (void)testTriggerDisplayOfTheEmptyViewOnTransitionToEmptyState
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
UIImage *image = [RKTestFixture imageWithContentsOfFixture:@"blake.png"];
tableController.imageForEmpty = image;
[tableController loadEmpty];
assertThatBool([tableController isEmpty], is(equalToBool(YES)));
UIImageView *imageView = tableController.stateOverlayImageView;
assertThat(imageView, isNot(nilValue()));
assertThat(imageView.image, is(equalTo(image)));
}
- (void)testTriggerHidingOfTheEmptyViewOnTransitionOutOfTheEmptyState
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
UIImage *image = [RKTestFixture imageWithContentsOfFixture:@"blake.png"];
tableController.imageForEmpty = image;
[tableController loadEmpty];
assertThatBool([tableController isEmpty], is(equalToBool(YES)));
UIImageView *imageView = tableController.stateOverlayImageView;
assertThat(imageView, isNot(nilValue()));
assertThat(imageView.image, is(equalTo(image)));
[tableController loadTableItems:[NSArray arrayWithObject:[RKTableItem tableItem]]];
assertThat(tableController.stateOverlayImageView.image, is(nilValue()));
}
- (void)testTriggerDisplayOfTheLoadingViewOnTransitionToTheLoadingState
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
tableController.loadingView = spinner;
[tableController setValue:[NSNumber numberWithBool:YES] forKey:@"loading"];
UIView *view = [tableController.tableOverlayView.subviews lastObject];
assertThatBool(view == spinner, is(equalToBool(YES)));
}
- (void)testTriggerHidingOfTheLoadingViewOnTransitionOutOfTheLoadingState
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
tableController.loadingView = spinner;
[tableController setValue:[NSNumber numberWithBool:YES] forKey:@"loading"];
UIView *loadingView = [tableController.tableOverlayView.subviews lastObject];
assertThatBool(loadingView == spinner, is(equalToBool(YES)));
[tableController setValue:[NSNumber numberWithBool:NO] forKey:@"loading"];
loadingView = [tableController.tableOverlayView.subviews lastObject];
assertThat(loadingView, is(nilValue()));
}
#pragma mark - Header, Footer, and Empty Rows
- (void)testShowHeaderRows
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
[tableController addHeaderRowForItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
tableItem.text = @"Header";
tableItem.cellMapping = [RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *cellMapping) {
[cellMapping addDefaultMappings];
}];
}]];
NSArray *tableItems = [RKTableItem tableItemsFromStrings:@"One", @"Two", @"Three", nil];
[tableController loadTableItems:tableItems];
assertThatBool([tableController isLoaded], is(equalToBool(YES)));
assertThatInt(tableController.rowCount, is(equalToInt(4)));
UITableViewCell *cellOne = [tableController tableView:tableController.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
UITableViewCell *cellTwo = [tableController tableView:tableController.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]];
UITableViewCell *cellThree = [tableController tableView:tableController.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:2 inSection:0]];
UITableViewCell *cellFour = [tableController tableView:tableController.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:3 inSection:0]];
assertThat(cellOne.textLabel.text, is(equalTo(@"Header")));
assertThat(cellTwo.textLabel.text, is(equalTo(@"One")));
assertThat(cellThree.textLabel.text, is(equalTo(@"Two")));
assertThat(cellFour.textLabel.text, is(equalTo(@"Three")));
[tableController tableView:tableController.tableView willDisplayCell:cellOne forRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
[tableController tableView:tableController.tableView willDisplayCell:cellTwo forRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]];
[tableController tableView:tableController.tableView willDisplayCell:cellThree forRowAtIndexPath:[NSIndexPath indexPathForRow:2 inSection:0]];
[tableController tableView:tableController.tableView willDisplayCell:cellFour forRowAtIndexPath:[NSIndexPath indexPathForRow:3 inSection:0]];
assertThatBool(cellOne.hidden, is(equalToBool(NO)));
assertThatBool(cellTwo.hidden, is(equalToBool(NO)));
assertThatBool(cellThree.hidden, is(equalToBool(NO)));
assertThatBool(cellFour.hidden, is(equalToBool(NO)));
}
- (void)testShowFooterRows
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
[tableController addFooterRowForItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
tableItem.text = @"Footer";
tableItem.cellMapping = [RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *cellMapping) {
[cellMapping addDefaultMappings];
}];
}]];
NSArray *tableItems = [RKTableItem tableItemsFromStrings:@"One", @"Two", @"Three", nil];
[tableController loadTableItems:tableItems];
assertThatBool([tableController isLoaded], is(equalToBool(YES)));
assertThatInt(tableController.rowCount, is(equalToInt(4)));
UITableViewCell *cellOne = [tableController tableView:tableController.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
UITableViewCell *cellTwo = [tableController tableView:tableController.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]];
UITableViewCell *cellThree = [tableController tableView:tableController.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:2 inSection:0]];
UITableViewCell *cellFour = [tableController tableView:tableController.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:3 inSection:0]];
assertThat(cellOne.textLabel.text, is(equalTo(@"One")));
assertThat(cellTwo.textLabel.text, is(equalTo(@"Two")));
assertThat(cellThree.textLabel.text, is(equalTo(@"Three")));
assertThat(cellFour.textLabel.text, is(equalTo(@"Footer")));
[tableController tableView:tableController.tableView willDisplayCell:cellOne forRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
[tableController tableView:tableController.tableView willDisplayCell:cellTwo forRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]];
[tableController tableView:tableController.tableView willDisplayCell:cellThree forRowAtIndexPath:[NSIndexPath indexPathForRow:2 inSection:0]];
[tableController tableView:tableController.tableView willDisplayCell:cellFour forRowAtIndexPath:[NSIndexPath indexPathForRow:3 inSection:0]];
assertThatBool(cellOne.hidden, is(equalToBool(NO)));
assertThatBool(cellTwo.hidden, is(equalToBool(NO)));
assertThatBool(cellThree.hidden, is(equalToBool(NO)));
assertThatBool(cellFour.hidden, is(equalToBool(NO)));
}
- (void)testHideHeaderRowsWhenEmptyWhenPropertyIsNotSet
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
[tableController addHeaderRowForItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
tableItem.text = @"Header";
tableItem.cellMapping = [RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *cellMapping) {
[cellMapping addDefaultMappings];
}];
}]];
tableController.showsHeaderRowsWhenEmpty = NO;
[tableController loadEmpty];
assertThatBool([tableController isLoaded], is(equalToBool(YES)));
assertThatInt(tableController.rowCount, is(equalToInt(1)));
assertThatBool([tableController isEmpty], is(equalToBool(YES)));
UITableViewCell *cellOne = [tableController tableView:tableController.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
assertThat(cellOne.textLabel.text, is(equalTo(@"Header")));
[tableController tableView:tableController.tableView willDisplayCell:cellOne forRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
assertThatBool(cellOne.hidden, is(equalToBool(YES)));
}
- (void)testHideFooterRowsWhenEmptyWhenPropertyIsNotSet
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
[tableController addFooterRowForItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
tableItem.text = @"Footer";
tableItem.cellMapping = [RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *cellMapping) {
[cellMapping addDefaultMappings];
}];
}]];
tableController.showsFooterRowsWhenEmpty = NO;
[tableController loadEmpty];
assertThatBool([tableController isLoaded], is(equalToBool(YES)));
assertThatInt(tableController.rowCount, is(equalToInt(1)));
assertThatBool([tableController isEmpty], is(equalToBool(YES)));
UITableViewCell *cellOne = [tableController tableView:tableController.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
assertThat(cellOne.textLabel.text, is(equalTo(@"Footer")));
[tableController tableView:tableController.tableView willDisplayCell:cellOne forRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
assertThatBool(cellOne.hidden, is(equalToBool(YES)));
}
- (void)testRemoveHeaderAndFooterCountsWhenDeterminingIsEmpty
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
[tableController addHeaderRowForItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
tableItem.text = @"Header";
tableItem.cellMapping = [RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *cellMapping) {
[cellMapping addDefaultMappings];
}];
}]];
[tableController addFooterRowForItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
tableItem.text = @"Footer";
tableItem.cellMapping = [RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *cellMapping) {
[cellMapping addDefaultMappings];
}];
}]];
[tableController setEmptyItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
tableItem.text = @"Empty";
tableItem.cellMapping = [RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *cellMapping) {
[cellMapping addDefaultMappings];
}];
}]];
tableController.showsFooterRowsWhenEmpty = NO;
tableController.showsHeaderRowsWhenEmpty = NO;
[tableController loadEmpty];
assertThatBool([tableController isLoaded], is(equalToBool(YES)));
assertThatInt(tableController.rowCount, is(equalToInt(3)));
assertThatBool([tableController isEmpty], is(equalToBool(YES)));
}
- (void)testNotShowTheEmptyItemWhenTheTableIsNotEmpty
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
[tableController addHeaderRowForItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
tableItem.text = @"Header";
tableItem.cellMapping = [RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *cellMapping) {
[cellMapping addDefaultMappings];
}];
}]];
[tableController addFooterRowForItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
tableItem.text = @"Footer";
tableItem.cellMapping = [RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *cellMapping) {
[cellMapping addDefaultMappings];
}];
}]];
[tableController setEmptyItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
tableItem.text = @"Empty";
tableItem.cellMapping = [RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *cellMapping) {
[cellMapping addDefaultMappings];
}];
}]];
NSArray *tableItems = [RKTableItem tableItemsFromStrings:@"One", @"Two", @"Three", nil];
[tableController loadTableItems:tableItems];
assertThatBool([tableController isLoaded], is(equalToBool(YES)));
assertThatInt(tableController.rowCount, is(equalToInt(6)));
UITableViewCell *cellOne = [tableController tableView:tableController.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
UITableViewCell *cellTwo = [tableController tableView:tableController.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]];
UITableViewCell *cellThree = [tableController tableView:tableController.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:2 inSection:0]];
UITableViewCell *cellFour = [tableController tableView:tableController.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:3 inSection:0]];
UITableViewCell *cellFive = [tableController tableView:tableController.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:4 inSection:0]];
UITableViewCell *cellSix = [tableController tableView:tableController.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:5 inSection:0]];
assertThat(cellOne.textLabel.text, is(equalTo(@"Empty")));
assertThat(cellTwo.textLabel.text, is(equalTo(@"Header")));
assertThat(cellThree.textLabel.text, is(equalTo(@"One")));
assertThat(cellFour.textLabel.text, is(equalTo(@"Two")));
assertThat(cellFive.textLabel.text, is(equalTo(@"Three")));
assertThat(cellSix.textLabel.text, is(equalTo(@"Footer")));
[tableController tableView:tableController.tableView willDisplayCell:cellOne forRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
[tableController tableView:tableController.tableView willDisplayCell:cellTwo forRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]];
[tableController tableView:tableController.tableView willDisplayCell:cellThree forRowAtIndexPath:[NSIndexPath indexPathForRow:2 inSection:0]];
[tableController tableView:tableController.tableView willDisplayCell:cellFour forRowAtIndexPath:[NSIndexPath indexPathForRow:3 inSection:0]];
[tableController tableView:tableController.tableView willDisplayCell:cellFive forRowAtIndexPath:[NSIndexPath indexPathForRow:4 inSection:0]];
[tableController tableView:tableController.tableView willDisplayCell:cellSix forRowAtIndexPath:[NSIndexPath indexPathForRow:5 inSection:0]];
assertThatBool(cellOne.hidden, is(equalToBool(YES)));
assertThatBool(cellTwo.hidden, is(equalToBool(NO)));
assertThatBool(cellThree.hidden, is(equalToBool(NO)));
assertThatBool(cellFour.hidden, is(equalToBool(NO)));
assertThatBool(cellFive.hidden, is(equalToBool(NO)));
assertThatBool(cellSix.hidden, is(equalToBool(NO)));
}
- (void)testShowTheEmptyItemWhenTheTableIsEmpty
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
[tableController addHeaderRowForItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
tableItem.text = @"Header";
tableItem.cellMapping = [RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *cellMapping) {
[cellMapping addDefaultMappings];
}];
}]];
[tableController addFooterRowForItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
tableItem.text = @"Footer";
tableItem.cellMapping = [RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *cellMapping) {
[cellMapping addDefaultMappings];
}];
}]];
[tableController setEmptyItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
tableItem.text = @"Empty";
tableItem.cellMapping = [RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *cellMapping) {
[cellMapping addDefaultMappings];
}];
}]];
tableController.showsHeaderRowsWhenEmpty = NO;
tableController.showsFooterRowsWhenEmpty = NO;
[tableController loadEmpty];
assertThatBool([tableController isLoaded], is(equalToBool(YES)));
assertThatInt(tableController.rowCount, is(equalToInt(3)));
assertThatBool([tableController isEmpty], is(equalToBool(YES)));
UITableViewCell *cellOne = [tableController tableView:tableController.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
UITableViewCell *cellTwo = [tableController tableView:tableController.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]];
UITableViewCell *cellThree = [tableController tableView:tableController.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:2 inSection:0]];
assertThat(cellOne.textLabel.text, is(equalTo(@"Empty")));
assertThat(cellTwo.textLabel.text, is(equalTo(@"Header")));
assertThat(cellThree.textLabel.text, is(equalTo(@"Footer")));
[tableController tableView:tableController.tableView willDisplayCell:cellOne forRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
[tableController tableView:tableController.tableView willDisplayCell:cellTwo forRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]];
[tableController tableView:tableController.tableView willDisplayCell:cellThree forRowAtIndexPath:[NSIndexPath indexPathForRow:2 inSection:0]];
assertThatBool(cellOne.hidden, is(equalToBool(NO)));
assertThatBool(cellTwo.hidden, is(equalToBool(YES)));
assertThatBool(cellThree.hidden, is(equalToBool(YES)));
}
- (void)testShowTheEmptyItemPlusHeadersAndFootersWhenTheTableIsEmpty
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
[tableController addHeaderRowForItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
tableItem.text = @"Header";
tableItem.cellMapping = [RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *cellMapping) {
[cellMapping addDefaultMappings];
}];
}]];
[tableController addFooterRowForItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
tableItem.text = @"Footer";
tableItem.cellMapping = [RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *cellMapping) {
[cellMapping addDefaultMappings];
}];
}]];
[tableController setEmptyItem:[RKTableItem tableItemUsingBlock:^(RKTableItem *tableItem) {
tableItem.text = @"Empty";
tableItem.cellMapping = [RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *cellMapping) {
[cellMapping addDefaultMappings];
}];
}]];
tableController.showsHeaderRowsWhenEmpty = YES;
tableController.showsFooterRowsWhenEmpty = YES;
[tableController loadEmpty];
assertThatBool([tableController isLoaded], is(equalToBool(YES)));
assertThatInt(tableController.rowCount, is(equalToInt(3)));
assertThatBool([tableController isEmpty], is(equalToBool(YES)));
UITableViewCell *cellOne = [tableController tableView:tableController.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
UITableViewCell *cellTwo = [tableController tableView:tableController.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]];
UITableViewCell *cellThree = [tableController tableView:tableController.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:2 inSection:0]];
assertThat(cellOne.textLabel.text, is(equalTo(@"Empty")));
assertThat(cellTwo.textLabel.text, is(equalTo(@"Header")));
assertThat(cellThree.textLabel.text, is(equalTo(@"Footer")));
[tableController tableView:tableController.tableView willDisplayCell:cellOne forRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
[tableController tableView:tableController.tableView willDisplayCell:cellTwo forRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]];
[tableController tableView:tableController.tableView willDisplayCell:cellThree forRowAtIndexPath:[NSIndexPath indexPathForRow:2 inSection:0]];
assertThatBool(cellOne.hidden, is(equalToBool(NO)));
assertThatBool(cellTwo.hidden, is(equalToBool(NO)));
assertThatBool(cellThree.hidden, is(equalToBool(NO)));
}
#pragma mark - UITableViewDelegate Tests
- (void)testInvokeTheOnSelectCellForObjectAtIndexPathBlockHandler
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
RKTableItem *tableItem = [RKTableItem tableItem];
__block BOOL dispatched = NO;
[tableController loadTableItems:[NSArray arrayWithObject:tableItem] withMapping:[RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *cellMapping) {
cellMapping.onSelectCellForObjectAtIndexPath = ^(UITableViewCell *cell, id object, NSIndexPath *indexPath) {
dispatched = YES;
};
}]];
[tableController tableView:tableController.tableView didSelectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
assertThatBool(dispatched, is(equalToBool(YES)));
}
- (void)testInvokeTheOnCellWillAppearForObjectAtIndexPathBlockHandler
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
RKTableItem *tableItem = [RKTableItem tableItem];
__block BOOL dispatched = NO;
[tableController loadTableItems:[NSArray arrayWithObject:tableItem] withMapping:[RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *cellMapping) {
cellMapping.onCellWillAppearForObjectAtIndexPath = ^(UITableViewCell *cell, id object, NSIndexPath *indexPath) {
dispatched = YES;
};
}]];
id mockCell = [OCMockObject niceMockForClass:[UITableViewCell class]];
[tableController tableView:tableController.tableView willDisplayCell:mockCell forRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
assertThatBool(dispatched, is(equalToBool(YES)));
}
- (void)testOptionallyHideHeaderRowsWhenTheyAppearAndTheTableIsEmpty
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.showsHeaderRowsWhenEmpty = NO;
RKTableItem *tableItem = [RKTableItem tableItem];
[tableController addHeaderRowForItem:tableItem];
[tableController loadEmpty];
id mockCell = [OCMockObject niceMockForClass:[UITableViewCell class]];
[[mockCell expect] setHidden:YES];
[tableController tableView:tableController.tableView willDisplayCell:mockCell forRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
[mockCell verify];
}
- (void)testOptionallyHideFooterRowsWhenTheyAppearAndTheTableIsEmpty
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.showsFooterRowsWhenEmpty = NO;
RKTableItem *tableItem = [RKTableItem tableItem];
[tableController addFooterRowForItem:tableItem];
[tableController loadEmpty];
id mockCell = [OCMockObject niceMockForClass:[UITableViewCell class]];
[[mockCell expect] setHidden:YES];
[tableController tableView:tableController.tableView willDisplayCell:mockCell forRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
[mockCell verify];
}
- (void)testInvokeABlockCallbackWhenTheCellAccessoryButtonIsTapped
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
RKTableItem *tableItem = [RKTableItem tableItem];
__block BOOL dispatched = NO;
RKTableViewCellMapping *mapping = [RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *cellMapping) {
cellMapping.onTapAccessoryButtonForObjectAtIndexPath = ^(UITableViewCell *cell, id object, NSIndexPath *indexPath) {
dispatched = YES;
};
}];
[tableController loadTableItems:[NSArray arrayWithObject:tableItem] withMapping:mapping];
[tableController tableView:tableController.tableView accessoryButtonTappedForRowWithIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
assertThatBool(dispatched, is(equalToBool(YES)));
}
- (void)testInvokeABlockCallbackWhenTheDeleteConfirmationButtonTitleIsDetermined
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
RKTableItem *tableItem = [RKTableItem tableItem];
NSString *deleteTitle = @"Delete Me";
RKTableViewCellMapping *mapping = [RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *cellMapping) {
cellMapping.titleForDeleteButtonForObjectAtIndexPath = ^ NSString*(UITableViewCell *cell, id object, NSIndexPath *indexPath) {
return deleteTitle;
};
}];
[tableController loadTableItems:[NSArray arrayWithObject:tableItem] withMapping:mapping];
NSString *delegateTitle = [tableController tableView:tableController.tableView
titleForDeleteConfirmationButtonForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
assertThat(delegateTitle, is(equalTo(deleteTitle)));
}
- (void)testInvokeABlockCallbackWhenCellEditingStyleIsDetermined
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.canEditRows = YES;
RKTableItem *tableItem = [RKTableItem tableItem];
RKTableViewCellMapping *mapping = [RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *cellMapping) {
cellMapping.editingStyleForObjectAtIndexPath = ^ UITableViewCellEditingStyle(UITableViewCell *cell, id object, NSIndexPath *indexPath) {
return UITableViewCellEditingStyleInsert;
};
}];
[tableController loadTableItems:[NSArray arrayWithObject:tableItem] withMapping:mapping];
UITableViewCellEditingStyle delegateStyle = [tableController tableView:tableController.tableView
editingStyleForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
assertThatInt(delegateStyle, is(equalToInt(UITableViewCellEditingStyleInsert)));
}
- (void)testInvokeABlockCallbackWhenACellIsMoved
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.canMoveRows = YES;
RKTableItem *tableItem = [RKTableItem tableItem];
NSIndexPath *moveToIndexPath = [NSIndexPath indexPathForRow:2 inSection:0];
[tableController loadTableItems:[NSArray arrayWithObject:tableItem] withMapping:[RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *cellMapping) {
cellMapping.targetIndexPathForMove = ^ NSIndexPath*(UITableViewCell *cell, id object, NSIndexPath *sourceIndexPath, NSIndexPath *destinationIndexPath) {
return moveToIndexPath;
};
}]];
NSIndexPath *delegateIndexPath = [tableController tableView:tableController.tableView
targetIndexPathForMoveFromRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] toProposedIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]];
assertThat(delegateIndexPath, is(equalTo(moveToIndexPath)));
}
#pragma mark Variable Height Rows
- (void)testReturnTheRowHeightConfiguredOnTheTableViewWhenVariableHeightRowsIsDisabled
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.variableHeightRows = NO;
tableController.tableView.rowHeight = 55;
RKTableItem *tableItem = [RKTableItem tableItem];
[tableController loadTableItems:[NSArray arrayWithObject:tableItem] withMapping:[RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *cellMapping) {
cellMapping.rowHeight = 200;
}]];
CGFloat height = [tableController tableView:tableController.tableView heightForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
assertThatFloat(height, is(equalToFloat(55)));
}
- (void)testReturnTheHeightFromTheTableCellMappingWhenVariableHeightRowsAreEnabled
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.variableHeightRows = YES;
tableController.tableView.rowHeight = 55;
RKTableItem *tableItem = [RKTableItem tableItem];
[tableController loadTableItems:[NSArray arrayWithObject:tableItem] withMapping:[RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *cellMapping) {
cellMapping.rowHeight = 200;
}]];
CGFloat height = [tableController tableView:tableController.tableView heightForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
assertThatFloat(height, is(equalToFloat(200)));
}
- (void)testInvokeAnBlockCallbackToDetermineTheCellHeightWhenVariableHeightRowsAreEnabled
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.variableHeightRows = YES;
tableController.tableView.rowHeight = 55;
RKTableItem *tableItem = [RKTableItem tableItem];
[tableController loadTableItems:[NSArray arrayWithObject:tableItem] withMapping:[RKTableViewCellMapping cellMappingUsingBlock:^(RKTableViewCellMapping *cellMapping) {
cellMapping.rowHeight = 200;
cellMapping.heightOfCellForObjectAtIndexPath = ^ CGFloat(id object, NSIndexPath *indexPath) { return 150; };
}]];
CGFloat height = [tableController tableView:tableController.tableView heightForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
assertThatFloat(height, is(equalToFloat(150)));
}
#pragma mark - Editing
- (void)testAllowEditingWhenTheCanEditRowsPropertyIsSet
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.canEditRows = YES;
RKTableItem *tableItem = [RKTableItem tableItem];
[tableController loadTableItems:[NSArray arrayWithObject:tableItem]];
BOOL delegateCanEdit = [tableController tableView:tableController.tableView
canEditRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
assertThatBool(delegateCanEdit, is(equalToBool(YES)));
}
- (void)testCommitADeletionWhenTheCanEditRowsPropertyIsSet
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.canEditRows = YES;
[tableController loadObjects:[NSArray arrayWithObjects:@"First Object", @"Second Object", nil]];
assertThatInt([tableController rowCount], is(equalToInt(2)));
BOOL delegateCanEdit = [tableController tableView:tableController.tableView
canEditRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
assertThatBool(delegateCanEdit, is(equalToBool(YES)));
[tableController tableView:tableController.tableView
commitEditingStyle:UITableViewCellEditingStyleDelete
forRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]];
assertThatInt([tableController rowCount], is(equalToInt(1)));
assertThat([tableController objectForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]],
is(equalTo(@"First Object")));
}
- (void)testNotCommitADeletionWhenTheCanEditRowsPropertyIsNotSet
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
[tableController loadObjects:[NSArray arrayWithObjects:@"First Object", @"Second Object", nil]];
assertThatInt([tableController rowCount], is(equalToInt(2)));
BOOL delegateCanEdit = [tableController tableView:tableController.tableView
canEditRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
assertThatBool(delegateCanEdit, is(equalToBool(NO)));
[tableController tableView:tableController.tableView
commitEditingStyle:UITableViewCellEditingStyleDelete
forRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]];
assertThatInt([tableController rowCount], is(equalToInt(2)));
assertThat([tableController objectForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]],
is(equalTo(@"First Object")));
assertThat([tableController objectForRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]],
is(equalTo(@"Second Object")));
}
- (void)testDoNothingToCommitAnInsertionWhenTheCanEditRowsPropertyIsSet
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.canEditRows = YES;
[tableController loadObjects:[NSArray arrayWithObjects:@"First Object", @"Second Object", nil]];
assertThatInt([tableController rowCount], is(equalToInt(2)));
BOOL delegateCanEdit = [tableController tableView:tableController.tableView
canEditRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
assertThatBool(delegateCanEdit, is(equalToBool(YES)));
[tableController tableView:tableController.tableView
commitEditingStyle:UITableViewCellEditingStyleInsert
forRowAtIndexPath:[NSIndexPath indexPathForRow:2 inSection:0]];
assertThatInt([tableController rowCount], is(equalToInt(2)));
assertThat([tableController objectForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]],
is(equalTo(@"First Object")));
assertThat([tableController objectForRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]],
is(equalTo(@"Second Object")));
}
- (void)testAllowMovingWhenTheCanMoveRowsPropertyIsSet
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.canMoveRows = YES;
RKTableItem *tableItem = [RKTableItem tableItem];
[tableController loadTableItems:[NSArray arrayWithObject:tableItem]];
BOOL delegateCanMove = [tableController tableView:tableController.tableView
canMoveRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
assertThatBool(delegateCanMove, is(equalToBool(YES)));
}
- (void)testMoveARowWithinASectionWhenTheCanMoveRowsPropertyIsSet
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.canMoveRows = YES;
[tableController loadObjects:[NSArray arrayWithObjects:@"First Object", @"Second Object", nil]];
assertThatInt([tableController rowCount], is(equalToInt(2)));
BOOL delegateCanMove = [tableController tableView:tableController.tableView
canMoveRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
assertThatBool(delegateCanMove, is(equalToBool(YES)));
[tableController tableView:tableController.tableView
moveRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]
toIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]];
assertThatInt([tableController rowCount], is(equalToInt(2)));
assertThat([tableController objectForRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]],
is(equalTo(@"First Object")));
assertThat([tableController objectForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]],
is(equalTo(@"Second Object")));
}
- (void)testMoveARowAcrossSectionsWhenTheCanMoveRowsPropertyIsSet
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.canMoveRows = YES;
[tableController loadObjects:[NSArray arrayWithObjects:@"First Object", @"Second Object", nil]];
assertThatInt([tableController rowCount], is(equalToInt(2)));
assertThatInt([tableController sectionCount], is(equalToInt(1)));
BOOL delegateCanMove = [tableController tableView:tableController.tableView
canMoveRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
assertThatBool(delegateCanMove, is(equalToBool(YES)));
[tableController tableView:tableController.tableView
moveRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]
toIndexPath:[NSIndexPath indexPathForRow:0 inSection:1]];
assertThatInt([tableController rowCount], is(equalToInt(2)));
assertThatInt([tableController sectionCount], is(equalToInt(2)));
assertThat([tableController objectForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:1]],
is(equalTo(@"First Object")));
assertThat([tableController objectForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]],
is(equalTo(@"Second Object")));
}
- (void)testNotMoveARowWhenTheCanMoveRowsPropertyIsNotSet
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
[tableController loadObjects:[NSArray arrayWithObjects:@"First Object", @"Second Object", nil]];
assertThatInt([tableController rowCount], is(equalToInt(2)));
BOOL delegateCanMove = [tableController tableView:tableController.tableView
canMoveRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
assertThatBool(delegateCanMove, is(equalToBool(NO)));
[tableController tableView:tableController.tableView
moveRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]
toIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]];
assertThatInt([tableController rowCount], is(equalToInt(2)));
assertThat([tableController objectForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]],
is(equalTo(@"First Object")));
assertThat([tableController objectForRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]],
is(equalTo(@"Second Object")));
}
#pragma mark - Reachability Integration
- (void)testTransitionToTheOnlineStateWhenAReachabilityNoticeIsReceived
{
RKObjectManager *objectManager = [RKTestFactory objectManager];
id mockManager = [OCMockObject partialMockForObject:objectManager];
BOOL online = YES;
[[[mockManager stub] andReturnValue:OCMOCK_VALUE(online)] isOnline];
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.objectManager = objectManager;
[[NSNotificationCenter defaultCenter] postNotificationName:RKObjectManagerDidBecomeOnlineNotification object:objectManager];
assertThatBool(tableController.isOnline, is(equalToBool(YES)));
}
- (void)testTransitionToTheOfflineStateWhenAReachabilityNoticeIsReceived
{
RKObjectManager *objectManager = [RKTestFactory objectManager];
id mockManager = [OCMockObject partialMockForObject:objectManager];
BOOL online = NO;
[[[mockManager stub] andReturnValue:OCMOCK_VALUE(online)] isOnline];
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.objectManager = objectManager;
[[NSNotificationCenter defaultCenter] postNotificationName:RKObjectManagerDidBecomeOfflineNotification object:objectManager];
assertThatBool(tableController.isOnline, is(equalToBool(NO)));
}
- (void)testNotifyTheDelegateOnTransitionToOffline
{
RKObjectManager *objectManager = [RKTestFactory objectManager];
id mockManager = [OCMockObject partialMockForObject:objectManager];
[mockManager setExpectationOrderMatters:YES];
RKObjectManagerNetworkStatus networkStatus = RKObjectManagerNetworkStatusOnline;
[[[mockManager stub] andReturnValue:OCMOCK_VALUE(networkStatus)] networkStatus];
BOOL online = YES; // Initial online state for table
[[[mockManager expect] andReturnValue:OCMOCK_VALUE(online)] isOnline];
online = NO; // After the notification is posted
[[[mockManager expect] andReturnValue:OCMOCK_VALUE(online)] isOnline];
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
id mockDelegate = [OCMockObject mockForProtocol:@protocol(RKTableControllerDelegate)];
[[mockDelegate expect] tableControllerDidBecomeOffline:tableController];
tableController.delegate = mockDelegate;
[[NSNotificationCenter defaultCenter] postNotificationName:RKObjectManagerDidBecomeOfflineNotification object:objectManager];
STAssertNoThrow([mockDelegate verify], nil);
}
- (void)testPostANotificationOnTransitionToOffline
{
RKObjectManager *objectManager = [RKTestFactory objectManager];
id mockManager = [OCMockObject partialMockForObject:objectManager];
[mockManager setExpectationOrderMatters:YES];
RKObjectManagerNetworkStatus networkStatus = RKObjectManagerNetworkStatusOnline;
[[[mockManager stub] andReturnValue:OCMOCK_VALUE(networkStatus)] networkStatus];
BOOL online = YES; // Initial online state for table
[[[mockManager expect] andReturnValue:OCMOCK_VALUE(online)] isOnline];
online = NO; // After the notification is posted
[[[mockManager expect] andReturnValue:OCMOCK_VALUE(online)] isOnline];
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
id observerMock = [OCMockObject observerMock];
[[NSNotificationCenter defaultCenter] addMockObserver:observerMock name:RKTableControllerDidBecomeOffline object:tableController];
[[observerMock expect] notificationWithName:RKTableControllerDidBecomeOffline object:tableController];
[[NSNotificationCenter defaultCenter] postNotificationName:RKObjectManagerDidBecomeOfflineNotification object:objectManager];
[observerMock verify];
}
- (void)testNotifyTheDelegateOnTransitionToOnline
{
RKObjectManager *objectManager = [RKTestFactory objectManager];
id mockManager = [OCMockObject partialMockForObject:objectManager];
BOOL online = NO;
[[[mockManager expect] andReturnValue:OCMOCK_VALUE(online)] isOnline];
online = YES;
[[[mockManager stub] andReturnValue:OCMOCK_VALUE(online)] isOnline];
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
[RKObjectManager setSharedManager:nil]; // Don't want the controller to initialize with the sharedManager...
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.objectManager = objectManager;
id mockDelegate = [OCMockObject mockForProtocol:@protocol(RKTableControllerDelegate)];
[[mockDelegate expect] tableControllerDidBecomeOnline:tableController];
tableController.delegate = mockDelegate;
[[NSNotificationCenter defaultCenter] postNotificationName:RKObjectManagerDidBecomeOnlineNotification object:objectManager];
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.3]];
STAssertNoThrow([mockDelegate verify], nil);
}
- (void)testPostANotificationOnTransitionToOnline
{
RKObjectManager *objectManager = [RKTestFactory objectManager];
id mockManager = [OCMockObject partialMockForObject:objectManager];
BOOL online = NO;
[[[mockManager expect] andReturnValue:OCMOCK_VALUE(online)] isOnline];
online = YES;
[[[mockManager stub] andReturnValue:OCMOCK_VALUE(online)] isOnline];
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
[RKObjectManager setSharedManager:nil]; // Don't want the controller to initialize with the sharedManager...
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.objectManager = objectManager;
id observerMock = [OCMockObject observerMock];
[[NSNotificationCenter defaultCenter] addMockObserver:observerMock name:RKTableControllerDidBecomeOnline object:tableController];
[[observerMock expect] notificationWithName:RKTableControllerDidBecomeOnline object:tableController];
[[NSNotificationCenter defaultCenter] postNotificationName:RKObjectManagerDidBecomeOnlineNotification object:objectManager];
[observerMock verify];
}
- (void)testShowTheOfflineImageOnTransitionToOffline
{
RKObjectManager *objectManager = [RKTestFactory objectManager];
id mockManager = [OCMockObject partialMockForObject:objectManager];
[mockManager setExpectationOrderMatters:YES];
RKObjectManagerNetworkStatus networkStatus = RKObjectManagerNetworkStatusOnline;
[[[mockManager stub] andReturnValue:OCMOCK_VALUE(networkStatus)] networkStatus];
BOOL online = YES; // Initial online state for table
[[[mockManager expect] andReturnValue:OCMOCK_VALUE(online)] isOnline];
online = NO; // After the notification is posted
[[[mockManager expect] andReturnValue:OCMOCK_VALUE(online)] isOnline];
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
UIImage *image = [RKTestFixture imageWithContentsOfFixture:@"blake.png"];
tableController.imageForOffline = image;
[[NSNotificationCenter defaultCenter] postNotificationName:RKObjectManagerDidBecomeOfflineNotification object:objectManager];
assertThatBool(tableController.isOnline, is(equalToBool(NO)));
UIImageView *imageView = tableController.stateOverlayImageView;
assertThat(imageView, isNot(nilValue()));
assertThat(imageView.image, is(equalTo(image)));
}
- (void)testRemoveTheOfflineImageOnTransitionToOnlineFromOffline
{
RKObjectManager *objectManager = [RKTestFactory objectManager];
id mockManager = [OCMockObject partialMockForObject:objectManager];
[mockManager setExpectationOrderMatters:YES];
RKObjectManagerNetworkStatus networkStatus = RKObjectManagerNetworkStatusOnline;
[[[mockManager stub] andReturnValue:OCMOCK_VALUE(networkStatus)] networkStatus];
BOOL online = YES; // Initial online state for table
[[[mockManager expect] andReturnValue:OCMOCK_VALUE(online)] isOnline];
online = NO; // After the notification is posted
[[[mockManager expect] andReturnValue:OCMOCK_VALUE(online)] isOnline];
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
[tableController loadEmpty]; // Load to change the isLoaded state
UIImage *image = [RKTestFixture imageWithContentsOfFixture:@"blake.png"];
tableController.imageForOffline = image;
[[NSNotificationCenter defaultCenter] postNotificationName:RKObjectManagerDidBecomeOfflineNotification object:objectManager];
assertThatBool(tableController.isOnline, is(equalToBool(NO)));
UIImageView *imageView = tableController.stateOverlayImageView;
assertThat(imageView, isNot(nilValue()));
assertThat(imageView.image, is(equalTo(image)));
online = YES;
[[[mockManager expect] andReturnValue:OCMOCK_VALUE(online)] isOnline];
[[NSNotificationCenter defaultCenter] postNotificationName:RKObjectManagerDidBecomeOnlineNotification object:objectManager];
assertThatBool(tableController.isOnline, is(equalToBool(YES)));
imageView = tableController.stateOverlayImageView;
assertThat(imageView.image, is(nilValue()));
}
#pragma mark - Swipe Menus
- (void)testAllowSwipeMenusWhenTheSwipeViewsEnabledPropertyIsSet
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.cellSwipeViewsEnabled = YES;
RKTableItem *tableItem = [RKTableItem tableItem];
[tableController loadTableItems:[NSArray arrayWithObject:tableItem]];
assertThatBool(tableController.canEditRows, is(equalToBool(NO)));
assertThatBool(tableController.cellSwipeViewsEnabled, is(equalToBool(YES)));
}
- (void)testNotAllowEditingWhenTheSwipeViewsEnabledPropertyIsSet
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.cellSwipeViewsEnabled = YES;
RKTableItem *tableItem = [RKTableItem tableItem];
[tableController loadTableItems:[NSArray arrayWithObject:tableItem]];
BOOL delegateCanEdit = [tableController tableView:tableController.tableView
canEditRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
assertThatBool(delegateCanEdit, is(equalToBool(NO)));
}
- (void)testRaiseAnExceptionWhenEnablingSwipeViewsWhenTheCanEditRowsPropertyIsSet
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.canEditRows = YES;
NSException *exception = nil;
@try {
tableController.cellSwipeViewsEnabled = YES;
}
@catch (NSException *e) {
exception = e;
}
@finally {
assertThat(exception, isNot(nilValue()));
}
}
- (void)testCallTheDelegateBeforeShowingTheSwipeView
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.cellSwipeViewsEnabled = YES;
RKTableItem *tableItem = [RKTableItem tableItem];
RKTableControllerTestDelegate *delegate = [RKTableControllerTestDelegate new];
id mockDelegate = [OCMockObject partialMockForObject:delegate];
[[[mockDelegate expect] andForwardToRealObject] tableController:tableController
willAddSwipeView:OCMOCK_ANY
toCell:OCMOCK_ANY
forObject:OCMOCK_ANY];
tableController.delegate = mockDelegate;
[tableController loadTableItems:[NSArray arrayWithObject:tableItem]];
[tableController addSwipeViewTo:[RKTestUserTableViewCell new]
withObject:@"object"
direction:UISwipeGestureRecognizerDirectionRight];
STAssertNoThrow([mockDelegate verify], nil);
}
- (void)testCallTheDelegateBeforeHidingTheSwipeView
{
RKTableControllerTestTableViewController *viewController = [RKTableControllerTestTableViewController new];
RKTableController *tableController = [RKTableController tableControllerForTableViewController:viewController];
tableController.cellSwipeViewsEnabled = YES;
RKTableItem *tableItem = [RKTableItem tableItem];
RKTableControllerTestDelegate *delegate = [RKTableControllerTestDelegate new];
id mockDelegate = [OCMockObject partialMockForObject:delegate];
[[[mockDelegate expect] andForwardToRealObject] tableController:tableController
willAddSwipeView:OCMOCK_ANY
toCell:OCMOCK_ANY
forObject:OCMOCK_ANY];
[[[mockDelegate expect] andForwardToRealObject] tableController:tableController
willRemoveSwipeView:OCMOCK_ANY
fromCell:OCMOCK_ANY
forObject:OCMOCK_ANY];
tableController.delegate = mockDelegate;
[tableController loadTableItems:[NSArray arrayWithObject:tableItem]];
[tableController addSwipeViewTo:[RKTestUserTableViewCell new]
withObject:@"object"
direction:UISwipeGestureRecognizerDirectionRight];
[tableController animationDidStopAddingSwipeView:nil
finished:nil
context:nil];
[tableController removeSwipeView:YES];
STAssertNoThrow([mockDelegate verify], nil);
}
@end