Skip to content
This repository has been archived by the owner on Feb 2, 2023. It is now read-only.

IGListKit Support II: Electric Boogaloo #2942

Merged
merged 12 commits into from
Jan 30, 2017
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ before_install:
install: echo "<3"
env:
- MODE=tests
- MODE=tests_listkit
- MODE=examples-pt1
- MODE=examples-pt2
- MODE=examples-pt3
Expand Down
394 changes: 394 additions & 0 deletions ASDKListKit/ASDKListKit.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions ASDKListKit/ASDKListKit.xcworkspace/contents.xcworkspacedata

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions ASDKListKit/ASDKListKitTests/ASListKitTestAdapterDataSource.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// ASListKitTestAdapterDataSource.h
// AsyncDisplayKit
//
// Created by Adlai Holler on 12/25/16.
// Copyright © 2016 Facebook. All rights reserved.
//

#import <IGListKit/IGListKit.h>

@interface ASListKitTestAdapterDataSource : NSObject <IGListAdapterDataSource>

// array of numbers which is then passed to -[IGListTestSection setItems:]
@property (nonatomic, strong) NSArray <NSNumber *> *objects;

@end
27 changes: 27 additions & 0 deletions ASDKListKit/ASDKListKitTests/ASListKitTestAdapterDataSource.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//
// ASListKitTestAdapterDataSource.m
// AsyncDisplayKit
//
// Created by Adlai Holler on 12/25/16.
// Copyright © 2016 Facebook. All rights reserved.
//

#import "ASListKitTestAdapterDataSource.h"
#import "ASListTestSection.h"

@implementation ASListKitTestAdapterDataSource

- (NSArray *)objectsForListAdapter:(IGListAdapter *)listAdapter {
return self.objects;
}

- (IGListSectionController <IGListSectionType> *)listAdapter:(IGListAdapter *)listAdapter sectionControllerForObject:(id)object {
ASListTestSection *section = [[ASListTestSection alloc] init];
return section;
}

- (nullable UIView *)emptyViewForListAdapter:(IGListAdapter *)listAdapter {
return nil;
}

@end
107 changes: 107 additions & 0 deletions ASDKListKit/ASDKListKitTests/ASListKitTests.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
//
// ASListKitTests.m
// AsyncDisplayKit
//
// Created by Adlai Holler on 12/25/16.
// Copyright © 2016 Facebook. All rights reserved.
//

#import <XCTest/XCTest.h>
#import <AsyncDisplayKit/AsyncDisplayKit.h>
#import "ASListKitTestAdapterDataSource.h"
#import "ASXCTExtensions.h"
#import <JGMethodSwizzler/JGMethodSwizzler.h>

@interface ASListKitTests : XCTestCase

@property (nonatomic, strong) ASCollectionNode *collectionNode;
@property (nonatomic, strong) UICollectionView *collectionView;
@property (nonatomic, strong) IGListAdapter *adapter;
@property (nonatomic, strong) ASListKitTestAdapterDataSource *dataSource;
@property (nonatomic, strong) UICollectionViewFlowLayout *layout;
@property (nonatomic, strong) UIWindow *window;
@property (nonatomic) NSInteger reloadDataCount;

@end

@implementation ASListKitTests

- (void)setUp {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: The default-inserted methods use the brace-at-end-of-name style, so we should bump it down.

[super setUp];

[ASCollectionView swizzleInstanceMethod:@selector(reloadData) withReplacement:JGMethodReplacementProviderBlock {
return JGMethodReplacement(void, ASCollectionView *) {
JGOriginalImplementation(void);
_reloadDataCount++;
};
}];

self.window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];

self.layout = [[UICollectionViewFlowLayout alloc] init];
self.collectionNode = [[ASCollectionNode alloc] initWithCollectionViewLayout:self.layout];
self.collectionNode.frame = self.window.bounds;
self.collectionView = self.collectionNode.view;

[self.window addSubnode:self.collectionNode];

IGListAdapterUpdater *updater = [[IGListAdapterUpdater alloc] init];

self.dataSource = [[ASListKitTestAdapterDataSource alloc] init];
self.adapter = [[IGListAdapter alloc] initWithUpdater:updater
viewController:nil
workingRangeSize:0];
self.adapter.dataSource = self.dataSource;
[self.adapter becomeDataSourceAndDelegateForCollectionNode:self.collectionNode];
XCTAssertNotNil(self.adapter.collectionView, @"Adapter was not bound to collection view. You may have a stale copy of AsyncDisplayKit that was built without IG_LIST_KIT. Clean Builder Folder IMO.");
}

- (void)tearDown {
[super tearDown];
XCTAssert([ASCollectionView deswizzleAllMethods]);
self.reloadDataCount = 0;
self.window = nil;
self.collectionNode = nil;
self.collectionView = nil;
self.adapter = nil;
self.dataSource = nil;
self.layout = nil;
}

- (void)test_whenAdapterUpdated_withObjectsOverflow_thatVisibleObjectsIsSubsetOfAllObjects {
// each section controller returns n items sized 100x10
self.dataSource.objects = @[@1, @2, @3, @4, @5, @6];
XCTestExpectation *e = [self expectationWithDescription:@"Data update completed"];

[self.adapter performUpdatesAnimated:NO completion:^(BOOL finished) {
[e fulfill];
}];

[self waitForExpectationsWithTimeout:1 handler:nil];
self.collectionNode.view.contentOffset = CGPointMake(0, 30);
[self.collectionNode.view layoutIfNeeded];


NSArray *visibleObjects = [[self.adapter visibleObjects] sortedArrayUsingSelector:@selector(compare:)];
NSArray *expectedObjects = @[@3, @4, @5];
XCTAssertEqualObjects(visibleObjects, expectedObjects);
}

- (void)test_whenCollectionViewIsNotInAWindow_updaterDoesNotJustCallReloadData
{
[self.collectionView removeFromSuperview];

[self.collectionView layoutIfNeeded];
self.dataSource.objects = @[@1, @2, @3, @4, @5, @6];
XCTestExpectation *e = [self expectationWithDescription:@"Data update completed"];

[self.adapter performUpdatesAnimated:NO completion:^(BOOL finished) {
[e fulfill];
}];
[self waitForExpectationsWithTimeout:1 handler:nil];
[self.collectionView layoutIfNeeded];

XCTAssertEqual(self.reloadDataCount, 2);
}

@end
13 changes: 13 additions & 0 deletions ASDKListKit/ASDKListKitTests/ASListTestCellNode.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// ASListTestCellNode.h
// AsyncDisplayKit
//
// Created by Adlai Holler on 12/25/16.
// Copyright © 2016 Facebook. All rights reserved.
//

#import <AsyncDisplayKit/AsyncDisplayKit.h>

@interface ASListTestCellNode : ASCellNode

@end
13 changes: 13 additions & 0 deletions ASDKListKit/ASDKListKitTests/ASListTestCellNode.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// ASListTestCellNode.m
// AsyncDisplayKit
//
// Created by Adlai Holler on 12/25/16.
// Copyright © 2016 Facebook. All rights reserved.
//

#import "ASListTestCellNode.h"

@implementation ASListTestCellNode

@end
22 changes: 22 additions & 0 deletions ASDKListKit/ASDKListKitTests/ASListTestObject.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//
// ASListTestObject.h
// AsyncDisplayKit
//
// Created by Adlai Holler on 12/25/16.
// Copyright © 2016 Facebook. All rights reserved.
//

#import <IGListKit/IGListKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface ASListTestObject : NSObject <IGListDiffable, NSCopying>

- (instancetype)initWithKey:(id <NSCopying>)key value:(id)value;

@property (nonatomic, strong, readonly) id key;
@property (nonatomic, strong) id value;

@end

NS_ASSUME_NONNULL_END
46 changes: 46 additions & 0 deletions ASDKListKit/ASDKListKitTests/ASListTestObject.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//
// ASListTestObject.m
// AsyncDisplayKit
//
// Created by Adlai Holler on 12/25/16.
// Copyright © 2016 Facebook. All rights reserved.
//

#import "ASListTestObject.h"

@implementation ASListTestObject

- (instancetype)initWithKey:(id)key value:(id)value {
if (self = [super init]) {
_key = [key copy];
_value = value;
}
return self;
}

- (instancetype)copyWithZone:(NSZone *)zone {
return [[ASListTestObject alloc] initWithKey:self.key value:self.value];
}


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Extra return here. Is there a standard on protocol names? Would it make sense for the pragma mark to say or protocol ?

#pragma mark - IGListDiffable

- (id<NSObject>)diffIdentifier {
return self.key;
}

- (BOOL)isEqualToDiffableObject:(id)object {
if (object == self) {
return YES;
}
if ([object isKindOfClass:[ASListTestObject class]]) {
id k1 = self.key;
id k2 = [object key];
id v1 = self.value;
id v2 = [(ASListTestObject *)object value];
return (v1 == v2 || [v1 isEqual:v2]) && (k1 == k2 || [k1 isEqual:k2]);
}
return NO;
}

@end
18 changes: 18 additions & 0 deletions ASDKListKit/ASDKListKitTests/ASListTestSection.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// ASListTestSection.h
// AsyncDisplayKit
//
// Created by Adlai Holler on 12/25/16.
// Copyright © 2016 Facebook. All rights reserved.
//

#import <IGListKit/IGListKit.h>
#import <AsyncDisplayKit/AsyncDisplayKit.h>

@interface ASListTestSection : IGListSectionController <IGListSectionType, ASSectionController>

@property (nonatomic) NSInteger itemCount;

@property (nonatomic) NSInteger selectedItemIndex;

@end
51 changes: 51 additions & 0 deletions ASDKListKit/ASDKListKitTests/ASListTestSection.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//
// ASListTestSection.m
// AsyncDisplayKit
//
// Created by Adlai Holler on 12/25/16.
// Copyright © 2016 Facebook. All rights reserved.
//

#import "ASListTestSection.h"
#import "ASListTestCellNode.h"

@implementation ASListTestSection

- (instancetype)init {
if (self = [super init]) {
_selectedItemIndex = NSNotFound;
}
return self;
}

- (NSInteger)numberOfItems {
return self.itemCount;
}

- (CGSize)sizeForItemAtIndex:(NSInteger)index {
ASDisplayNodeFailAssert(@"Did not expect %@ to be called.", NSStringFromSelector(_cmd));
return CGSizeMake(100, 10);
}

ASIGSectionControllerCellForIndexImplementation

- (void)didUpdateToObject:(id)object {
if ([object isKindOfClass:[NSNumber class]]) {
self.itemCount = [object integerValue];
}
}

- (void)didSelectItemAtIndex:(NSInteger)index {
self.selectedItemIndex = index;
}

- (ASCellNodeBlock)nodeBlockForItemAtIndex:(NSInteger)index
{
return ^{
ASListTestCellNode *node = [[ASListTestCellNode alloc] init];
node.style.preferredSize = CGSizeMake(100, 10);
return node;
};
}

@end
13 changes: 13 additions & 0 deletions ASDKListKit/ASDKListKitTests/ASListTestSupplementaryNode.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// ASListTestSupplementaryNode.h
// AsyncDisplayKit
//
// Created by Adlai Holler on 12/25/16.
// Copyright © 2016 Facebook. All rights reserved.
//

#import <AsyncDisplayKit/AsyncDisplayKit.h>

@interface ASListTestSupplementaryNode : ASCellNode

@end
13 changes: 13 additions & 0 deletions ASDKListKit/ASDKListKitTests/ASListTestSupplementaryNode.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// ASListTestSupplementaryNode.m
// AsyncDisplayKit
//
// Created by Adlai Holler on 12/25/16.
// Copyright © 2016 Facebook. All rights reserved.
//

#import "ASListTestSupplementaryNode.h"

@implementation ASListTestSupplementaryNode

@end
20 changes: 20 additions & 0 deletions ASDKListKit/ASDKListKitTests/ASListTestSupplementarySource.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// ASListTestSupplementarySource.h
// AsyncDisplayKit
//
// Created by Adlai Holler on 12/25/16.
// Copyright © 2016 Facebook. All rights reserved.
//

#import <IGListKit/IGListKit.h>
#import <AsyncDisplayKit/AsyncDisplayKit.h>

@interface ASListTestSupplementarySource : NSObject <IGListSupplementaryViewSource, ASSupplementaryNodeSource>

@property (nonatomic, strong, readwrite) NSArray<NSString *> *supportedElementKinds;

@property (nonatomic, weak) id<IGListCollectionContext> collectionContext;

@property (nonatomic, weak) IGListSectionController<IGListSectionType> *sectionController;

@end
Loading