ComponentTextKitApplicationTests/CKTextKitTruncationTests.mm (141 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 <Foundation/Foundation.h>
#import <XCTest/XCTest.h>
#import <ComponentTextKit/CKTextKitContext.h>
#import <ComponentTextKit/CKTextKitTailTruncater.h>
@interface CKTextKitTruncationTests : XCTestCase
@end
@implementation CKTextKitTruncationTests
- (NSString *)_sentenceString
{
return @"90's cray photo booth tote bag bespoke Carles. Plaid wayfarers Odd Future master cleanse tattooed four dollar toast small batch kale chips leggings meh photo booth occupy irony.";
}
- (NSAttributedString *)_sentenceAttributedString
{
return [[NSAttributedString alloc] initWithString:[self _sentenceString] attributes:@{}];
}
- (NSAttributedString *)_simpleTruncationAttributedString
{
return [[NSAttributedString alloc] initWithString:@"..." attributes:@{}];
}
- (void)testEmptyTruncationStringSameAsStraightTextKitTailTruncation
{
CGSize constrainedSize = CGSizeMake(100, 50);
NSAttributedString *attributedString = [self _sentenceAttributedString];
CKTextKitContext *context = [[CKTextKitContext alloc] initWithAttributedString:attributedString
lineBreakMode:NSLineBreakByWordWrapping
maximumNumberOfLines:0
constrainedSize:constrainedSize
layoutManagerFactory:nil];
__block NSRange textKitVisibleRange;
[context performBlockWithLockedTextKitComponents:^(NSLayoutManager *layoutManager, NSTextStorage *textStorage, NSTextContainer *textContainer) {
textKitVisibleRange = [layoutManager characterRangeForGlyphRange:[layoutManager glyphRangeForTextContainer:textContainer]
actualGlyphRange:NULL];
}];
CKTextKitTailTruncater *tailTruncater = [[CKTextKitTailTruncater alloc] initWithContext:context
truncationAttributedString:nil
avoidTailTruncationSet:nil
constrainedSize:constrainedSize];
XCTAssert(NSEqualRanges(textKitVisibleRange, tailTruncater.visibleRanges[0]));
}
- (void)testSimpleTailTruncation
{
CGSize constrainedSize = CGSizeMake(100, 60);
NSAttributedString *attributedString = [self _sentenceAttributedString];
CKTextKitContext *context = [[CKTextKitContext alloc] initWithAttributedString:attributedString
lineBreakMode:NSLineBreakByWordWrapping
maximumNumberOfLines:0
constrainedSize:constrainedSize
layoutManagerFactory:nil];
CKTextKitTailTruncater *tailTruncater = [[CKTextKitTailTruncater alloc] initWithContext:context
truncationAttributedString:[self _simpleTruncationAttributedString]
avoidTailTruncationSet:[NSCharacterSet characterSetWithCharactersInString:@""]
constrainedSize:constrainedSize];
__block NSString *drawnString;
[context performBlockWithLockedTextKitComponents:^(NSLayoutManager *layoutManager, NSTextStorage *textStorage, NSTextContainer *textContainer) {
drawnString = textStorage.string;
}];
NSString *expectedString = @"90's cray photo booth tote bag bespoke Carles. Plaid wayfarers...";
XCTAssertEqualObjects(expectedString, drawnString);
XCTAssert(NSEqualRanges(NSMakeRange(0, 62), tailTruncater.visibleRanges[0]));
}
- (void)testAvoidedCharTailWordBoundaryTruncation
{
CGSize constrainedSize = CGSizeMake(100, 50);
NSAttributedString *attributedString = [self _sentenceAttributedString];
CKTextKitContext *context = [[CKTextKitContext alloc] initWithAttributedString:attributedString
lineBreakMode:NSLineBreakByWordWrapping
maximumNumberOfLines:0
constrainedSize:constrainedSize
layoutManagerFactory:nil];
CKTextKitTailTruncater *tailTruncater = [[CKTextKitTailTruncater alloc] initWithContext:context
truncationAttributedString:[self _simpleTruncationAttributedString]
avoidTailTruncationSet:[NSCharacterSet characterSetWithCharactersInString:@"."]
constrainedSize:constrainedSize];
(void)tailTruncater;
__block NSString *drawnString;
[context performBlockWithLockedTextKitComponents:^(NSLayoutManager *layoutManager, NSTextStorage *textStorage, NSTextContainer *textContainer) {
drawnString = textStorage.string;
}];
// This should have removed the additional "." in the string right after Carles.
NSString *expectedString = @"90's cray photo booth tote bag bespoke Carles...";
XCTAssertEqualObjects(expectedString, drawnString);
}
- (void)testAvoidedCharTailCharBoundaryTruncation
{
CGSize constrainedSize = CGSizeMake(50, 50);
NSAttributedString *attributedString = [self _sentenceAttributedString];
CKTextKitContext *context = [[CKTextKitContext alloc] initWithAttributedString:attributedString
lineBreakMode:NSLineBreakByCharWrapping
maximumNumberOfLines:0
constrainedSize:constrainedSize
layoutManagerFactory:nil];
CKTextKitTailTruncater *tailTruncater = [[CKTextKitTailTruncater alloc] initWithContext:context
truncationAttributedString:[self _simpleTruncationAttributedString]
avoidTailTruncationSet:[NSCharacterSet characterSetWithCharactersInString:@"."]
constrainedSize:constrainedSize];
// So Xcode doesn't yell at me for an unused var...
(void)tailTruncater;
__block NSString *drawnString;
[context performBlockWithLockedTextKitComponents:^(NSLayoutManager *layoutManager, NSTextStorage *textStorage, NSTextContainer *textContainer) {
drawnString = textStorage.string;
}];
// This should have removed the additional "." in the string right after Carles.
NSString *expectedString = @"90's cray photo booth t...";
XCTAssertEqualObjects(expectedString, drawnString);
}
- (void)testHandleZeroHeightConstrainedSize
{
CGSize constrainedSize = CGSizeMake(50, 0);
NSAttributedString *attributedString = [self _sentenceAttributedString];
CKTextKitContext *context = [[CKTextKitContext alloc] initWithAttributedString:attributedString
lineBreakMode:NSLineBreakByCharWrapping
maximumNumberOfLines:0
constrainedSize:constrainedSize
layoutManagerFactory:nil];
XCTAssertNoThrow([[CKTextKitTailTruncater alloc] initWithContext:context
truncationAttributedString:[self _simpleTruncationAttributedString]
avoidTailTruncationSet:[NSCharacterSet characterSetWithCharactersInString:@"."]
constrainedSize:constrainedSize]);
}
- (void)testNoLimitOfMaximumNumberOfLines
{
const NSUInteger maximumNumberOfLines = 0;
NSAttributedString *attributedString = [self _sentenceAttributedString];
CKTextKitRenderer *renderer = [[CKTextKitRenderer alloc]
initWithTextKitAttributes:{
.attributedString = attributedString,
.maximumNumberOfLines = maximumNumberOfLines,
}
constrainedSize:CGSizeMake(50, INFINITY)];
XCTAssertTrue(renderer.lineCount > maximumNumberOfLines);
}
- (void)testEnforcementOfMaximumNumberOfLines
{
const NSUInteger maximumNumberOfLines = 3;
NSAttributedString *attributedString = [self _sentenceAttributedString];
CKTextKitRenderer *renderer = [[CKTextKitRenderer alloc]
initWithTextKitAttributes:{
.attributedString = attributedString,
.maximumNumberOfLines = maximumNumberOfLines,
}
constrainedSize:CGSizeMake(50, INFINITY)];
XCTAssertEqual(renderer.lineCount, maximumNumberOfLines);
}
@end