OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #import "ios/chrome/browser/ui/util/label_link_controller.h" |
| 6 |
| 7 #import "base/mac/scoped_nsobject.h" |
| 8 #include "ios/chrome/browser/ui/util/text_region_mapper.h" |
| 9 #include "testing/gtest/include/gtest/gtest.h" |
| 10 #include "testing/gtest_mac.h" |
| 11 #include "testing/platform_test.h" |
| 12 #include "url/gurl.h" |
| 13 |
| 14 // A simple text region mapper that just returns the mapped bounds for |
| 15 // any range. |
| 16 @interface SimpleTextRegionMapper : NSObject<TextRegionMapper> |
| 17 @end |
| 18 |
| 19 @implementation SimpleTextRegionMapper { |
| 20 CGRect _bounds; |
| 21 } |
| 22 |
| 23 - (instancetype)initWithAttributedString:(NSAttributedString*)string |
| 24 bounds:(CGRect)bounds { |
| 25 if ((self = [super init])) { |
| 26 _bounds = bounds; |
| 27 } |
| 28 return self; |
| 29 } |
| 30 |
| 31 - (NSArray*)rectsForRange:(NSRange)range { |
| 32 return @[ [NSValue valueWithCGRect:_bounds] ]; |
| 33 } |
| 34 |
| 35 @end |
| 36 |
| 37 #define EXPECT_UICOLOR_EQ(A, B) EXPECT_NSEQ([A description], [B description]) |
| 38 |
| 39 namespace { |
| 40 |
| 41 class LabelLinkControllerTest : public PlatformTest { |
| 42 protected: |
| 43 void SetUp() override { |
| 44 label_container_.reset([[UIView alloc] initWithFrame:CGRectZero]); |
| 45 label_.reset([[UILabel alloc] initWithFrame:CGRectZero]); |
| 46 [label_container_ addSubview:label_]; |
| 47 } |
| 48 |
| 49 void setLabelAttrString(NSString* str) { |
| 50 str_.reset([[NSAttributedString alloc] initWithString:str]); |
| 51 [label_ setAttributedText:str_]; |
| 52 } |
| 53 |
| 54 void setLabelAttrStringWithAttr(NSString* str, NSString* attr, id value) { |
| 55 str_.reset([[NSAttributedString alloc] initWithString:str |
| 56 attributes:@{attr : value}]); |
| 57 [label_ setAttributedText:str_]; |
| 58 } |
| 59 |
| 60 base::scoped_nsobject<UIView> label_container_; |
| 61 base::scoped_nsobject<UILabel> label_; |
| 62 base::scoped_nsobject<NSAttributedString> str_; |
| 63 }; |
| 64 |
| 65 TEST_F(LabelLinkControllerTest, TapTest) { |
| 66 setLabelAttrString(@"link tap test"); |
| 67 [label_ sizeToFit]; |
| 68 NSRange linkRange = NSMakeRange(5, 3); // "tap". |
| 69 |
| 70 base::scoped_nsobject<LabelLinkController> llc; |
| 71 GURL url = GURL("http://www.google.com"); |
| 72 __block NSInteger taps = 0; |
| 73 llc.reset([[LabelLinkController alloc] |
| 74 initWithLabel:label_ |
| 75 action:^(const GURL& tappedUrl) { |
| 76 EXPECT_EQ(tappedUrl, url); |
| 77 taps++; |
| 78 }]); |
| 79 [llc setTextMapperClass:[SimpleTextRegionMapper class]]; |
| 80 [llc addLinkWithRange:linkRange url:url]; |
| 81 NSArray* rects = [llc tapRectsForURL:url]; |
| 82 ASSERT_EQ(1UL, [rects count]); |
| 83 CGRect rect = [rects[0] CGRectValue]; |
| 84 |
| 85 CGPoint tapPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect)); |
| 86 [llc tapLabelAtPoint:tapPoint]; |
| 87 EXPECT_EQ(1, taps); |
| 88 } |
| 89 |
| 90 TEST_F(LabelLinkControllerTest, LinkColorTest) { |
| 91 setLabelAttrStringWithAttr(@"link color test", NSForegroundColorAttributeName, |
| 92 [UIColor blueColor]); |
| 93 [label_ sizeToFit]; |
| 94 NSRange linkRange = NSMakeRange(5, 5); // "color". |
| 95 |
| 96 base::scoped_nsobject<LabelLinkController> llc; |
| 97 llc.reset([[LabelLinkController alloc] initWithLabel:label_ action:nullptr]); |
| 98 [llc setTextMapperClass:[SimpleTextRegionMapper class]]; |
| 99 [llc addLinkWithRange:linkRange url:GURL("http://www.google.com")]; |
| 100 |
| 101 // That shouldn't have changed the label's attributes. |
| 102 NSDictionary* attrs = |
| 103 [[label_ attributedText] attributesAtIndex:linkRange.location |
| 104 effectiveRange:nullptr]; |
| 105 EXPECT_UICOLOR_EQ(attrs[NSForegroundColorAttributeName], [UIColor blueColor]); |
| 106 |
| 107 [llc setLinkColor:[UIColor redColor]]; |
| 108 // That should only change the attributes at the link location |
| 109 attrs = [[label_ attributedText] attributesAtIndex:linkRange.location |
| 110 effectiveRange:nullptr]; |
| 111 EXPECT_UICOLOR_EQ(attrs[NSForegroundColorAttributeName], [UIColor redColor]); |
| 112 |
| 113 attrs = [[label_ attributedText] attributesAtIndex:0 effectiveRange:nullptr]; |
| 114 EXPECT_UICOLOR_EQ(attrs[NSForegroundColorAttributeName], [UIColor blueColor]); |
| 115 |
| 116 [llc setLinkColor:[UIColor yellowColor]]; |
| 117 // There shouldn't be a red foreground color attribute any more. |
| 118 attrs = [[label_ attributedText] attributesAtIndex:linkRange.location |
| 119 effectiveRange:nullptr]; |
| 120 EXPECT_UICOLOR_EQ(attrs[NSForegroundColorAttributeName], |
| 121 [UIColor yellowColor]); |
| 122 } |
| 123 |
| 124 TEST_F(LabelLinkControllerTest, LinkUnderlineTest) { |
| 125 setLabelAttrStringWithAttr(@"link underline test", |
| 126 NSUnderlineStyleAttributeName, |
| 127 @(NSUnderlineStyleSingle)); |
| 128 [label_ sizeToFit]; |
| 129 NSRange linkRange = NSMakeRange(5, 9); // "underline". |
| 130 |
| 131 base::scoped_nsobject<LabelLinkController> llc; |
| 132 llc.reset([[LabelLinkController alloc] initWithLabel:label_ action:nullptr]); |
| 133 [llc setTextMapperClass:[SimpleTextRegionMapper class]]; |
| 134 [llc addLinkWithRange:linkRange url:GURL("http://www.google.com")]; |
| 135 |
| 136 // That shouldn't have changed the label's attributes. |
| 137 NSDictionary* attrs = |
| 138 [[label_ attributedText] attributesAtIndex:linkRange.location |
| 139 effectiveRange:nullptr]; |
| 140 EXPECT_NSEQ(attrs[NSUnderlineStyleAttributeName], @(NSUnderlineStyleSingle)); |
| 141 |
| 142 [llc setLinkUnderlineStyle:NSUnderlineStyleDouble]; |
| 143 // That should only change the attributes at the link location |
| 144 attrs = [[label_ attributedText] attributesAtIndex:linkRange.location |
| 145 effectiveRange:nullptr]; |
| 146 EXPECT_NSEQ(attrs[NSUnderlineStyleAttributeName], @(NSUnderlineStyleDouble)); |
| 147 |
| 148 attrs = [[label_ attributedText] attributesAtIndex:0 effectiveRange:nullptr]; |
| 149 EXPECT_NSEQ(attrs[NSUnderlineStyleAttributeName], @(NSUnderlineStyleSingle)); |
| 150 |
| 151 [llc setLinkUnderlineStyle:NSUnderlineStyleThick]; |
| 152 // There shouldn't be a red foreground color attribute any more. |
| 153 attrs = [[label_ attributedText] attributesAtIndex:linkRange.location |
| 154 effectiveRange:nullptr]; |
| 155 EXPECT_NSEQ(attrs[NSUnderlineStyleAttributeName], @(NSUnderlineStyleThick)); |
| 156 |
| 157 [llc setLinkUnderlineStyle:NSUnderlineStyleNone]; |
| 158 // Should see the underlying underline style. |
| 159 attrs = [[label_ attributedText] attributesAtIndex:linkRange.location |
| 160 effectiveRange:nullptr]; |
| 161 EXPECT_NSEQ(attrs[NSUnderlineStyleAttributeName], @(NSUnderlineStyleSingle)); |
| 162 } |
| 163 |
| 164 TEST_F(LabelLinkControllerTest, BoundsChangeTest) { |
| 165 setLabelAttrString(@"bounds change test"); |
| 166 [label_ sizeToFit]; |
| 167 NSRange linkRange = NSMakeRange(7, 6); // "change". |
| 168 |
| 169 base::scoped_nsobject<LabelLinkController> llc; |
| 170 llc.reset([[LabelLinkController alloc] initWithLabel:label_ action:nullptr]); |
| 171 [llc setTextMapperClass:[SimpleTextRegionMapper class]]; |
| 172 GURL url = GURL("http://www.google.com"); |
| 173 [llc addLinkWithRange:linkRange url:url]; |
| 174 |
| 175 NSArray* rects = [llc tapRectsForURL:url]; |
| 176 ASSERT_EQ(1UL, [rects count]); |
| 177 NSValue* rect = rects[0]; |
| 178 EXPECT_TRUE(CGRectContainsRect([rect CGRectValue], [label_ bounds])); |
| 179 |
| 180 // Change the label bounds, expect the links to be recomputed. |
| 181 // (SimpleTextRegionMapper just maps all ranges to the label bounds). |
| 182 CGRect newFrame = CGRectMake(0, 0, 200, 200); |
| 183 [label_ setFrame:newFrame]; |
| 184 rects = [llc tapRectsForURL:url]; |
| 185 ASSERT_EQ(1UL, [rects count]); |
| 186 NSValue* newRect = rects[0]; |
| 187 EXPECT_NSNE(rect, newRect); |
| 188 EXPECT_TRUE(CGRectContainsRect([newRect CGRectValue], newFrame)); |
| 189 } |
| 190 |
| 191 TEST_F(LabelLinkControllerTest, AttributedTextChangeTest) { |
| 192 setLabelAttrString(@"attributed text change test"); |
| 193 [label_ sizeToFit]; |
| 194 NSRange linkRange = NSMakeRange(16, 6); // "change". |
| 195 |
| 196 base::scoped_nsobject<LabelLinkController> llc; |
| 197 llc.reset([[LabelLinkController alloc] initWithLabel:label_ action:nullptr]); |
| 198 [llc setTextMapperClass:[SimpleTextRegionMapper class]]; |
| 199 GURL url = GURL("http://www.google.com"); |
| 200 [llc addLinkWithRange:linkRange url:url]; |
| 201 |
| 202 NSArray* rects = [llc tapRectsForURL:url]; |
| 203 EXPECT_EQ(1UL, [rects count]); |
| 204 |
| 205 setLabelAttrString(@"crazy new attributed text"); |
| 206 // Expect all links to be gone. |
| 207 rects = [llc tapRectsForURL:url]; |
| 208 EXPECT_EQ(0UL, [rects count]); |
| 209 } |
| 210 |
| 211 TEST_F(LabelLinkControllerTest, TextChangeTest) { |
| 212 [label_ setText:@"text change test"]; |
| 213 [label_ sizeToFit]; |
| 214 NSRange linkRange = NSMakeRange(5, 6); // "change". |
| 215 |
| 216 base::scoped_nsobject<LabelLinkController> llc; |
| 217 llc.reset([[LabelLinkController alloc] initWithLabel:label_ action:nullptr]); |
| 218 [llc setTextMapperClass:[SimpleTextRegionMapper class]]; |
| 219 GURL url = GURL("http://www.google.com"); |
| 220 [llc addLinkWithRange:linkRange url:url]; |
| 221 |
| 222 NSArray* rects = [llc tapRectsForURL:url]; |
| 223 EXPECT_EQ(1UL, [rects count]); |
| 224 |
| 225 [label_ setText:@"crazy new text"]; |
| 226 // Expect all links to be gone. |
| 227 rects = [llc tapRectsForURL:url]; |
| 228 EXPECT_EQ(0UL, [rects count]); |
| 229 } |
| 230 |
| 231 TEST_F(LabelLinkControllerTest, LabelStyleInitTest) { |
| 232 [label_ setText:@"style init test"]; |
| 233 [label_ sizeToFit]; |
| 234 NSRange linkRange = NSMakeRange(6, 5); // "init". |
| 235 |
| 236 // Don't use an injected text mapper for this test. |
| 237 base::scoped_nsobject<LabelLinkController> llc; |
| 238 llc.reset([[LabelLinkController alloc] initWithLabel:label_ action:nullptr]); |
| 239 GURL url = GURL("http://www.google.com"); |
| 240 [llc addLinkWithRange:linkRange url:url]; |
| 241 |
| 242 NSArray* rects = [llc tapRectsForURL:url]; |
| 243 ASSERT_EQ(1UL, [rects count]); |
| 244 |
| 245 CGRect linkRect = [rects[0] CGRectValue]; |
| 246 |
| 247 // Make a new label and controller with a very large font size, and |
| 248 // compute the same tap rect. It should be different from the rect computed |
| 249 // above. |
| 250 llc.reset(); |
| 251 label_.reset([[UILabel alloc] initWithFrame:CGRectZero]); |
| 252 [label_ setText:@"style init test"]; |
| 253 [label_ setFont:[UIFont systemFontOfSize:40]]; |
| 254 [label_ sizeToFit]; |
| 255 llc.reset([[LabelLinkController alloc] initWithLabel:label_ action:nullptr]); |
| 256 url = GURL("http://www.google.com"); |
| 257 [llc addLinkWithRange:linkRange url:url]; |
| 258 rects = [llc tapRectsForURL:url]; |
| 259 ASSERT_EQ(1UL, [rects count]); |
| 260 CGRect newLinkRect = [rects[0] CGRectValue]; |
| 261 |
| 262 EXPECT_NSNE(NSStringFromCGRect(linkRect), NSStringFromCGRect(newLinkRect)); |
| 263 } |
| 264 |
| 265 TEST_F(LabelLinkControllerTest, LabelStylePropertyChangeTest) { |
| 266 [label_ setText:@"style change test"]; |
| 267 // Choose a size large enough so that the full text can be laid out with both |
| 268 // fonts in this test. |
| 269 CGSize labelSize = CGSizeMake(400, 50); |
| 270 [label_ setFrame:{CGPointZero, labelSize}]; |
| 271 |
| 272 NSRange linkRange = NSMakeRange(6, 6); // "change". |
| 273 |
| 274 // Don't use an injected text mapper for this test. |
| 275 base::scoped_nsobject<LabelLinkController> llc; |
| 276 llc.reset([[LabelLinkController alloc] initWithLabel:label_ action:nullptr]); |
| 277 GURL url = GURL("http://www.google.com"); |
| 278 [llc addLinkWithRange:linkRange url:url]; |
| 279 |
| 280 NSArray* rects = [llc tapRectsForURL:url]; |
| 281 ASSERT_EQ(1UL, [rects count]); |
| 282 NSValue* smallTextRect = rects[0]; |
| 283 |
| 284 [label_ setFont:[UIFont systemFontOfSize:40]]; |
| 285 // Expect all links to be changed. |
| 286 rects = [llc tapRectsForURL:url]; |
| 287 ASSERT_EQ(1UL, [rects count]); |
| 288 EXPECT_NSNE(smallTextRect, rects[0]); |
| 289 } |
| 290 |
| 291 } // namespace |
OLD | NEW |