ComponentKitTests/Scope/CKStateScopeComponentBuilderTests.mm (105 lines of code) (raw):
/*
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
#import <XCTest/XCTest.h>
#import <OCMock/OCMock.h>
#import <ComponentKit/CKBuildComponent.h>
#import <ComponentKit/CKComponentController.h>
#import <ComponentKit/CKComponentSubclass.h>
#import <ComponentKit/CKCompositeComponent.h>
#import <ComponentKit/CKComponentScope.h>
#import <ComponentKit/CKComponentInternal.h>
#import <ComponentKit/CKComponentScopeRoot.h>
#import <ComponentKit/CKComponentScopeRootFactory.h>
#import <ComponentKit/CKRootTreeNode.h>
#import <ComponentKit/CKThreadLocalComponentScope.h>
#import "CKStateExposingComponent.h"
#pragma mark - Test Components and Controllers
@interface CKMonkeyComponent : CKComponent
@end
@implementation CKMonkeyComponent
@end
@interface CKMonkeyComponentController : CKComponentController
@end
@implementation CKMonkeyComponentController
@end
@interface CKMonkeyComponentWithAnimations : CKComponent
@end
@implementation CKMonkeyComponentWithAnimations
- (std::vector<CKComponentAnimation>)animationsFromPreviousComponent:(CKComponent *)previousComponent { return {}; }
- (std::vector<CKComponentAnimation>)animationsOnInitialMount { return {}; }
@end
#pragma mark - Tests
@interface CKStateScopeComponentBuilderTests : XCTestCase
@end
@implementation CKStateScopeComponentBuilderTests
#pragma mark - CKBuildComponent
- (void)testThreadLocalStateIsSet
{
auto const root = CKComponentScopeRootWithDefaultPredicates(nil, nil);
CKComponent *(^block)(void) = ^CKComponent *{
XCTAssertEqualObjects(CKThreadLocalComponentScope::currentScope()->stack.top().previousNode, [root rootNode].node());
return [CKComponent new];
};
(void)CKBuildComponent(root, {}, block);
}
- (void)testCorrectComponentIsReturned
{
CKComponent __block *c = nil;
CKComponent *(^block)(void) = ^CKComponent *{
c = [CKComponent new];
return c;
};
const CKBuildComponentResult result = CKBuildComponent(CKComponentScopeRootWithDefaultPredicates(nil, nil), {}, block);
XCTAssertEqualObjects(result.component, c);
}
- (void)testStateIsReacquiredAndNewInitialValueBlockIsNotUsed
{
id state = @12345;
CKComponent *(^block)(void) = ^CKComponent *{
CKComponentScope scope([CKComponent class], nil, ^{ return state; });
(void)scope.state();
return [CKComponent new];
};
const CKBuildComponentResult firstBuildResult = CKBuildComponent(CKComponentScopeRootWithDefaultPredicates(nil, nil), {}, block);
id __block nextState = nil;
CKComponent *(^block2)(void) = ^CKComponent *{
CKComponentScope scope([CKComponent class], nil, ^{ return @67890; });
nextState = scope.state();
return [CKComponent new];
};
(void)CKBuildComponent(firstBuildResult.scopeRoot, {}, block2);
XCTAssertEqualObjects(state, nextState);
}
- (void)testComponentStateIsSetToInitialStateValue
{
CKComponent *(^block)(void) = ^CKComponent *{
return [CKStateExposingComponent new];
};
CKStateExposingComponent *component = (CKStateExposingComponent *)CKBuildComponent(CKComponentScopeRootWithDefaultPredicates(nil, nil), {}, block).component;
XCTAssertEqualObjects(component.state, [CKStateExposingComponent initialState]);
}
- (void)testStatUniqueIdentifierIsNotFoundForComponentWhenClassNamesDoNotMatch
{
id state = @12345;
CKComponent *(^block)(void) = ^CKComponent *{
CKComponentScope scope([CKCompositeComponent class], nil, ^{ return state; });
CKComponent *c = [CKComponent new];
(void)scope.state();
return c;
};
CKComponent *component = CKBuildComponent(CKComponentScopeRootWithDefaultPredicates(nil, nil), {}, block).component;
XCTAssertNil(component.uniqueIdentifier);
}
- (void)testStateUniqueIdentifierIsNotFoundWhenAnotherComponentInTheSameScopeAcquiresItFirst
{
CKComponent __block *innerComponent = nil;
id state = @12345;
CKComponent *(^block)(void) = ^CKComponent *{
CKComponentScope scope([CKComponent class], nil, ^{ return state; });
(void)scope.state();
innerComponent = [CKComponent new];
return [CKComponent new];
};
CKComponent *outerComponent = CKBuildComponent(CKComponentScopeRootWithDefaultPredicates(nil, nil), {}, block).component;
XCTAssertNotNil(innerComponent.uniqueIdentifier);
XCTAssertNil(outerComponent.uniqueIdentifier);
}
@end