Swiftgram/AsyncDisplayKitTests/ASTextKitTests.mm
Hannah Troisi c857e809f4 Clean up header comments (for consistent Facebook licensing info) (#1741)
[Licensing] Clean up header comments (for consistent Facebook licensing info)
2016-06-11 23:31:39 -07:00

198 lines
8.0 KiB
Plaintext

//
// ASTextKitTests.mm
// AsyncDisplayKit
//
// 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 <UIKit/UIKit.h>
#import <XCTest/XCTest.h>
#import <FBSnapshotTestCase/FBSnapshotTestController.h>
#import "ASTextKitEntityAttribute.h"
#import "ASTextKitAttributes.h"
#import "ASTextKitRenderer.h"
#import "ASTextKitRenderer+Positioning.h"
@interface ASTextKitTests : XCTestCase
@end
static UITextView *UITextViewWithAttributes(const ASTextKitAttributes &attributes,
const CGSize constrainedSize,
NSDictionary *linkTextAttributes)
{
UITextView *textView = [[UITextView alloc] initWithFrame:{ .size = constrainedSize }];
textView.backgroundColor = [UIColor clearColor];
textView.textContainer.lineBreakMode = attributes.lineBreakMode;
textView.textContainer.lineFragmentPadding = 0.f;
textView.textContainer.maximumNumberOfLines = attributes.maximumNumberOfLines;
textView.textContainerInset = UIEdgeInsetsZero;
textView.layoutManager.usesFontLeading = NO;
textView.attributedText = attributes.attributedString;
textView.linkTextAttributes = linkTextAttributes;
return textView;
}
static UIImage *UITextViewImageWithAttributes(const ASTextKitAttributes &attributes,
const CGSize constrainedSize,
NSDictionary *linkTextAttributes)
{
UITextView *textView = UITextViewWithAttributes(attributes, constrainedSize, linkTextAttributes);
UIGraphicsBeginImageContextWithOptions(constrainedSize, NO, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
{
[textView.layer renderInContext:context];
}
CGContextRestoreGState(context);
UIImage *snapshot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return snapshot;
}
static UIImage *ASTextKitImageWithAttributes(const ASTextKitAttributes &attributes, const CGSize constrainedSize)
{
ASTextKitRenderer *renderer = [[ASTextKitRenderer alloc] initWithTextKitAttributes:attributes
constrainedSize:constrainedSize];
UIGraphicsBeginImageContextWithOptions(constrainedSize, NO, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
{
[renderer drawInContext:context bounds:{.size = constrainedSize}];
}
CGContextRestoreGState(context);
UIImage *snapshot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return snapshot;
}
// linkTextAttributes are only applied to UITextView
static BOOL checkAttributes(const ASTextKitAttributes &attributes, const CGSize constrainedSize, NSDictionary *linkTextAttributes)
{
FBSnapshotTestController *controller = [[FBSnapshotTestController alloc] init];
UIImage *labelImage = UITextViewImageWithAttributes(attributes, constrainedSize, linkTextAttributes);
UIImage *textKitImage = ASTextKitImageWithAttributes(attributes, constrainedSize);
return [controller compareReferenceImage:labelImage toImage:textKitImage tolerance:0.0 error:nil];
}
@implementation ASTextKitTests
- (void)testSimpleStrings
{
ASTextKitAttributes attributes {
.attributedString = [[NSAttributedString alloc] initWithString:@"hello" attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:12]}]
};
XCTAssert(checkAttributes(attributes, { 100, 100 }, nil));
}
- (void)testChangingAPropertyChangesHash
{
NSAttributedString *as = [[NSAttributedString alloc] initWithString:@"hello" attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:12]}];
ASTextKitAttributes attrib1 {
.attributedString = as,
.lineBreakMode = NSLineBreakByClipping,
};
ASTextKitAttributes attrib2 {
.attributedString = as,
};
XCTAssertNotEqual(attrib1.hash(), attrib2.hash(), @"Hashes should differ when NSLineBreakByClipping changes.");
}
- (void)testSameStringHashesSame
{
ASTextKitAttributes attrib1 {
.attributedString = [[NSAttributedString alloc] initWithString:@"hello" attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:12]}],
};
ASTextKitAttributes attrib2 {
.attributedString = [[NSAttributedString alloc] initWithString:@"hello" attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:12]}],
};
XCTAssertEqual(attrib1.hash(), attrib2.hash(), @"Hashes should be the same!");
}
- (void)testStringsWithVariableAttributes
{
NSMutableAttributedString *attrStr = [[NSMutableAttributedString alloc] initWithString:@"hello" attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:12]}];
for (int i = 0; i < attrStr.length; i++) {
// Color each character something different
CGFloat factor = ((CGFloat)i) / ((CGFloat)attrStr.length);
[attrStr addAttribute:NSForegroundColorAttributeName
value:[UIColor colorWithRed:factor
green:1.0 - factor
blue:0.0
alpha:1.0]
range:NSMakeRange(i, 1)];
}
ASTextKitAttributes attributes {
.attributedString = attrStr
};
XCTAssert(checkAttributes(attributes, { 100, 100 }, nil));
}
- (void)testLinkInTextUsesForegroundColor
{
NSDictionary *linkTextAttributes = @{ NSForegroundColorAttributeName : [UIColor redColor],
// UITextView adds underline by default and we can't get rid of it
// so we have to choose a style and color and match it in the text kit version
// for this test
NSUnderlineStyleAttributeName : @(NSUnderlineStyleSingle),
NSUnderlineColorAttributeName: [UIColor blueColor],
};
NSDictionary *textAttributes = @{NSFontAttributeName : [UIFont systemFontOfSize:12],
};
NSString *prefixString = @"click ";
NSString *linkString = @"this link";
NSString *textString = [prefixString stringByAppendingString:linkString];
NSMutableAttributedString *attrStr = [[NSMutableAttributedString alloc] initWithString:textString attributes:textAttributes];
NSURL *linkURL = [NSURL URLWithString:@"https://github.com/facebook/AsyncDisplayKit/issues/967"];
NSRange selectedRange = (NSRange){prefixString.length, linkString.length};
[attrStr addAttribute:NSLinkAttributeName value:linkURL range:selectedRange];
for (NSString *attributeName in linkTextAttributes.keyEnumerator) {
[attrStr addAttribute:attributeName
value:linkTextAttributes[attributeName]
range:selectedRange];
}
ASTextKitAttributes textKitattributes {
.attributedString = attrStr
};
XCTAssert(checkAttributes(textKitattributes, { 100, 100 }, linkTextAttributes));
}
- (void)testRectsForRangeBeyondTruncationSizeReturnsNonZeroNumberOfRects
{
NSAttributedString *attributedString =
[[NSAttributedString alloc]
initWithString:@"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. " attributes:@{ASTextKitEntityAttributeName : [[ASTextKitEntityAttribute alloc] initWithEntity:@"entity"]}];
ASTextKitRenderer *renderer =
[[ASTextKitRenderer alloc]
initWithTextKitAttributes:{
.attributedString = attributedString,
.maximumNumberOfLines = 1,
.truncationAttributedString = [[NSAttributedString alloc] initWithString:@"... Continue Reading"]
}
constrainedSize:{ 100, 100 }];
XCTAssert([renderer rectsForTextRange:NSMakeRange(0, attributedString.length) measureOption:ASTextKitRendererMeasureOptionBlock].count > 0);
}
@end