OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 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 <UIKit/UIKit.h> |
| 6 |
| 7 #include <memory> |
| 8 |
| 9 #include "base/ios/ios_util.h" |
| 10 #include "base/json/json_reader.h" |
| 11 #include "base/mac/scoped_nsobject.h" |
| 12 #include "base/strings/sys_string_conversions.h" |
| 13 #include "base/strings/utf_string_conversions.h" |
| 14 #import "base/test/ios/wait_util.h" |
| 15 #include "base/values.h" |
| 16 #include "components/pref_registry/pref_registry_syncable.h" |
| 17 #include "components/prefs/pref_registry_simple.h" |
| 18 #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h" |
| 19 #import "ios/chrome/browser/ui/contextual_search/contextual_search_controller.h" |
| 20 #import "ios/chrome/browser/ui/contextual_search/js_contextual_search_manager.h" |
| 21 #import "ios/chrome/browser/ui/contextual_search/touch_to_search_permissions_med
iator+testing.h" |
| 22 #import "ios/chrome/browser/web/chrome_web_test.h" |
| 23 #import "ios/web/public/web_state/js/crw_js_injection_manager.h" |
| 24 #import "ios/web/public/web_state/js/crw_js_injection_receiver.h" |
| 25 #import "ios/web/public/web_state/web_state.h" |
| 26 #include "testing/gtest/include/gtest/gtest.h" |
| 27 #include "testing/gtest_mac.h" |
| 28 #import "third_party/ocmock/OCMock/OCMock.h" |
| 29 |
| 30 // Unit tests for the resources/contextualsearch.js JavaScript file. |
| 31 |
| 32 struct ContextualSearchStruct { |
| 33 std::string url; |
| 34 std::string selectedText; |
| 35 std::string surroundingText; |
| 36 int offsetStart; |
| 37 int offsetEnd; |
| 38 }; |
| 39 |
| 40 @interface JsContextualSearchAdditionsManager : CRWJSInjectionManager |
| 41 @end |
| 42 |
| 43 @implementation JsContextualSearchAdditionsManager : CRWJSInjectionManager |
| 44 - (NSString*)scriptPath { |
| 45 return @"contextualsearch_unittest"; |
| 46 } |
| 47 |
| 48 - (NSArray*)dependencies { |
| 49 return @[ [JsContextualSearchManager class] ]; |
| 50 } |
| 51 |
| 52 @end |
| 53 |
| 54 namespace { |
| 55 |
| 56 // HTML that contains script. |
| 57 NSString* kHTMLSentenceWithScript = |
| 58 @"<html><body>" |
| 59 "This is <span id='taphere'>the</span> <script>function ignore() " |
| 60 "{};</script>sentence to select." |
| 61 "</body></html>"; |
| 62 |
| 63 // HTML that contains label to be tapped. |
| 64 NSString* kHTMLSentenceWithLabel = |
| 65 @"<html><body>" |
| 66 "<label>Click <span id='taphere'>me</span> <input type='text'/></label>." |
| 67 "A sentence to select." |
| 68 "</body></html>"; |
| 69 |
| 70 // HTML that contains italic element. |
| 71 NSString* kHTMLWithItalic = |
| 72 @"<html><body>" |
| 73 "This is <span id='taphere'>an</span> <i>italic</i> element." |
| 74 "</body></html>"; |
| 75 |
| 76 // HTML that contains a table. |
| 77 NSString* kHTMLWithTable = |
| 78 @"<html><body>" |
| 79 "<table><tr><td>Left <span id='taphere'>cell</span></td>" |
| 80 "<td>right cell</td></tr></table>" |
| 81 "</body></html>"; |
| 82 |
| 83 // HTML that will trigger an unrelated DOM mutation on tap. |
| 84 NSString* kHTMLWithUnrelatedDOMMutation = |
| 85 @"<html><body>" |
| 86 "<span>This <span style='margin-left:50px' id='taphere'>is</span>" |
| 87 " sentence</span> <span>with <span id='test' attr='before'>mutation</span>" |
| 88 "</span>.</body></html>"; |
| 89 |
| 90 // HTML that will trigger a related DOM mutation on tap. |
| 91 NSString* kHTMLWithRelatedDOMMutation = |
| 92 @"<html><body>" |
| 93 "This <span id='test' attr='before'>" |
| 94 "<span style='margin-left:50px' id='taphere'>is</span></span>" |
| 95 "a sentence with mutation." |
| 96 "</body></html>"; |
| 97 |
| 98 // HTML that will trigger a related DOM mutation on tap. |
| 99 NSString* kHTMLWithRelatedTextMutation = |
| 100 @"<html><body>" |
| 101 "This <span style='margin-left:50px' id='taphere'> text " |
| 102 "<span id='test'>mutation is </span> inside </span>" |
| 103 "a sentence with mutation." |
| 104 "</body></html>"; |
| 105 |
| 106 // HTML that contain a div in the middle of a sentence. |
| 107 NSString* kHTMLWithDiv = |
| 108 @"<html><body>" |
| 109 "This<div>is</div>a <span id='taphere'>sentence</span>." |
| 110 "</body></html>"; |
| 111 |
| 112 // HTML that contain a div in the middle of a sentence. |
| 113 NSString* kHTMLWithSpaceDiv = |
| 114 @"<html><body>" |
| 115 "This <div>is</div>a <span id='taphere'>sentence</span>." |
| 116 "</body></html>"; |
| 117 |
| 118 // HTML that contains prevent default. |
| 119 NSString* kHTMLWithPreventDefault = @"<html><body>" |
| 120 "<div id='interceptor'>" |
| 121 "<span id='taphere'>is</span>" |
| 122 "</div></body></html>"; |
| 123 |
| 124 NSString* kStringWith50Chars = |
| 125 @"Sentence $INDEX containing exactly 50 characters. "; |
| 126 |
| 127 class ContextualSearchJsTest : public ChromeWebTest { |
| 128 public: |
| 129 // Loads the given HTML, then loads the |contextualSearch| JavaScript. |
| 130 void LoadHtml(NSString* html) { |
| 131 ChromeWebTest::LoadHtml(html); |
| 132 [jsUnittestsAdditions_ inject]; |
| 133 } |
| 134 |
| 135 bool GetContextFromId(NSString* elementID, |
| 136 ContextualSearchStruct* searchContext) { |
| 137 id javaScriptResult = ExecuteJavaScript([NSString |
| 138 stringWithFormat:@"document.getElementById('%@').scrollIntoView();" |
| 139 "__gCrWeb.contextualSearch.tapOnElement('%@');", |
| 140 elementID, elementID]); |
| 141 if (!javaScriptResult) |
| 142 return false; |
| 143 const std::string json = base::SysNSStringToUTF8(javaScriptResult); |
| 144 std::unique_ptr<base::Value> parsedResult( |
| 145 base::JSONReader::Read(json, false)); |
| 146 if (!parsedResult.get() || |
| 147 !parsedResult->IsType(base::Value::Type::DICTIONARY)) { |
| 148 return false; |
| 149 } |
| 150 |
| 151 base::DictionaryValue* resultDict = |
| 152 static_cast<base::DictionaryValue*>(parsedResult.get()); |
| 153 const base::DictionaryValue* context = nullptr; |
| 154 if (!resultDict->GetDictionary("context", &context)) { |
| 155 return false; |
| 156 } |
| 157 |
| 158 std::string error; |
| 159 context->GetString("error", &error); |
| 160 if (!error.empty()) { |
| 161 LOG(ERROR) << "GetContext error: " << error; |
| 162 return false; |
| 163 } |
| 164 |
| 165 std::string url, selectedText; |
| 166 context->GetString("url", &searchContext->url); |
| 167 context->GetString("selectedText", &searchContext->selectedText); |
| 168 context->GetString("surroundingText", &searchContext->surroundingText); |
| 169 context->GetInteger("offsetStart", &searchContext->offsetStart); |
| 170 context->GetInteger("offsetEnd", &searchContext->offsetEnd); |
| 171 return true; |
| 172 } |
| 173 |
| 174 id expandHighlight(int start, int end) { |
| 175 return ExecuteJavaScript([NSString |
| 176 stringWithFormat:@"__gCrWeb.contextualSearch.expandHighlight(%d, %d);" |
| 177 "__gCrWeb.contextualSearch.retrieveHighlighted();", |
| 178 start, end]); |
| 179 } |
| 180 |
| 181 id highlight() { |
| 182 return ExecuteJavaScript( |
| 183 @"__gCrWeb.contextualSearch.setHighlighting(true);" |
| 184 "__gCrWeb.contextualSearch.retrieveHighlighted();"); |
| 185 } |
| 186 |
| 187 NSInteger GetMutatedNodeCount() { |
| 188 id output = ExecuteJavaScript( |
| 189 @"__gCrWeb.contextualSearch.getMutatedElementCount();"); |
| 190 return [output integerValue]; |
| 191 } |
| 192 |
| 193 void CheckContextOffsets(const ContextualSearchStruct& searchContext, |
| 194 const std::string& surroundingText) { |
| 195 EXPECT_EQ(searchContext.surroundingText, surroundingText); |
| 196 EXPECT_EQ(searchContext.selectedText, |
| 197 searchContext.surroundingText.substr( |
| 198 searchContext.offsetStart, |
| 199 searchContext.offsetEnd - searchContext.offsetStart)); |
| 200 } |
| 201 |
| 202 NSString* BuildLongTestString(int startIndex, |
| 203 int endIndex, |
| 204 int tapOn, |
| 205 bool newLine) { |
| 206 NSString* longString = @""; |
| 207 for (int i = startIndex; i < endIndex; i++) { |
| 208 NSString* index = [NSString stringWithFormat:@"%06d", i]; |
| 209 if (i == tapOn) { |
| 210 index = |
| 211 [NSString stringWithFormat:@"<span id='taphere'>%@</span>", index]; |
| 212 } |
| 213 NSString* sentence = |
| 214 [kStringWith50Chars stringByReplacingOccurrencesOfString:@"$INDEX" |
| 215 withString:index]; |
| 216 longString = [longString stringByAppendingString:sentence]; |
| 217 if (newLine) { |
| 218 longString = [longString stringByAppendingString:@"<br/>"]; |
| 219 } |
| 220 } |
| 221 return longString; |
| 222 } |
| 223 |
| 224 void SetUp() override { |
| 225 ChromeWebTest::SetUp(); |
| 226 mockDelegate_.reset([[OCMockObject |
| 227 niceMockForProtocol:@protocol(ContextualSearchControllerDelegate)] |
| 228 retain]); |
| 229 jsUnittestsAdditions_ = static_cast<JsContextualSearchAdditionsManager*>( |
| 230 [web_state()->GetJSInjectionReceiver() |
| 231 instanceOfClass:[JsContextualSearchAdditionsManager class]]); |
| 232 TestChromeBrowserState::Builder test_cbs_builder; |
| 233 chrome_browser_state_ = test_cbs_builder.Build(); |
| 234 controller_.reset([[ContextualSearchController alloc] |
| 235 initWithBrowserState:chrome_browser_state_.get() |
| 236 delegate:mockDelegate_]); |
| 237 [controller_ |
| 238 setPermissions:[[MockTouchToSearchPermissionsMediator alloc] |
| 239 initWithBrowserState:chrome_browser_state_.get()]]; |
| 240 [controller_ setWebState:web_state()]; |
| 241 [controller_ enableContextualSearch:YES]; |
| 242 } |
| 243 |
| 244 void TearDown() override { |
| 245 [controller_ close]; |
| 246 // Need to tear down the controller so it deregisters its JS handlers |
| 247 // before |webController_| is destroyed. |
| 248 controller_.reset(); |
| 249 ChromeWebTest::TearDown(); |
| 250 } |
| 251 |
| 252 std::unique_ptr<TestChromeBrowserState> chrome_browser_state_; |
| 253 __unsafe_unretained JsContextualSearchAdditionsManager* jsUnittestsAdditions_; |
| 254 base::scoped_nsobject<ContextualSearchController> controller_; |
| 255 base::scoped_nsobject<id> mockDelegate_; |
| 256 base::scoped_nsobject<id> mockToolbarDelegate_; |
| 257 }; |
| 258 |
| 259 // Test that ignored elements do not trigger CS when tapped. |
| 260 TEST_F(ContextualSearchJsTest, TestIgnoreTapsOnElements) { |
| 261 LoadHtml(kHTMLSentenceWithLabel); |
| 262 ContextualSearchStruct searchContext; |
| 263 ASSERT_FALSE(GetContextFromId(@"taphere", &searchContext)); |
| 264 }; |
| 265 |
| 266 // Test that ingnored element are not included in highlight or surrounding text. |
| 267 TEST_F(ContextualSearchJsTest, TestIgnoreScript) { |
| 268 LoadHtml(kHTMLSentenceWithScript); |
| 269 ContextualSearchStruct searchContext; |
| 270 ASSERT_TRUE(GetContextFromId(@"taphere", &searchContext)); |
| 271 |
| 272 CheckContextOffsets(searchContext, "This is the sentence to select."); |
| 273 id highlighted = expandHighlight(0, searchContext.surroundingText.size()); |
| 274 EXPECT_NSEQ(highlighted, @"This is the sentence to select."); |
| 275 }; |
| 276 |
| 277 // Test that all span element are correctly highlighted. |
| 278 TEST_F(ContextualSearchJsTest, TestHighlightThroughSpan) { |
| 279 LoadHtml(kHTMLWithItalic); |
| 280 ContextualSearchStruct searchContext; |
| 281 ASSERT_TRUE(GetContextFromId(@"taphere", &searchContext)); |
| 282 |
| 283 CheckContextOffsets(searchContext, "This is an italic element."); |
| 284 NSString* highlighted = |
| 285 expandHighlight(0, searchContext.surroundingText.size()); |
| 286 EXPECT_NSEQ(highlighted, @"This is an italic element."); |
| 287 }; |
| 288 |
| 289 // Test that all block element are highlighted. Spaces separating element must |
| 290 // be ignored. |
| 291 TEST_F(ContextualSearchJsTest, TestHighlightThroughBlock) { |
| 292 LoadHtml(kHTMLWithTable); |
| 293 ContextualSearchStruct searchContext; |
| 294 ASSERT_TRUE(GetContextFromId(@"taphere", &searchContext)); |
| 295 |
| 296 CheckContextOffsets(searchContext, "Left cell right cell"); |
| 297 NSString* highlighted = |
| 298 expandHighlight(0, searchContext.surroundingText.size()); |
| 299 EXPECT_NSEQ(highlighted, @"Left cell right cell"); |
| 300 }; |
| 301 |
| 302 // Test that blocks add spaces if there are not arround it. |
| 303 TEST_F(ContextualSearchJsTest, TestHighlightBlockAddsSpace) { |
| 304 LoadHtml(kHTMLWithDiv); |
| 305 ContextualSearchStruct searchContext; |
| 306 ASSERT_TRUE(GetContextFromId(@"taphere", &searchContext)); |
| 307 CheckContextOffsets(searchContext, "This is a sentence."); |
| 308 }; |
| 309 |
| 310 // Test that blocks don't add spaces if there are around it. |
| 311 TEST_F(ContextualSearchJsTest, TestHighlightBlockDontAddsSpace) { |
| 312 LoadHtml(kHTMLWithSpaceDiv); |
| 313 ContextualSearchStruct searchContext; |
| 314 ASSERT_TRUE(GetContextFromId(@"taphere", &searchContext)); |
| 315 CheckContextOffsets(searchContext, "This is a sentence."); |
| 316 }; |
| 317 |
| 318 // Test that related DOM mutation cancels contextual search. |
| 319 TEST_F(ContextualSearchJsTest, TestHighlightRelatedDOMMutation) { |
| 320 LoadHtml(kHTMLWithRelatedDOMMutation); |
| 321 ExecuteJavaScript( |
| 322 @"document.getElementById('test').setAttribute('attr', 'after');"); |
| 323 ASSERT_EQ(1, GetMutatedNodeCount()); |
| 324 ContextualSearchStruct searchContext; |
| 325 ASSERT_FALSE(GetContextFromId(@"taphere", &searchContext)); |
| 326 }; |
| 327 |
| 328 // Test that unrelated DOM mutation does not cancel contextual search. |
| 329 TEST_F(ContextualSearchJsTest, TestHighlightIgnoreUnrelatedDOMMutation) { |
| 330 LoadHtml(kHTMLWithUnrelatedDOMMutation); |
| 331 ExecuteJavaScript( |
| 332 @"document.getElementById('test').setAttribute('attr', 'after');"); |
| 333 ASSERT_EQ(1, GetMutatedNodeCount()); |
| 334 ContextualSearchStruct searchContext; |
| 335 |
| 336 ASSERT_TRUE(GetContextFromId(@"taphere", &searchContext)); |
| 337 }; |
| 338 |
| 339 // Test that DOM mutation with same value does not cancel contextual search. |
| 340 // Mutation should not mark a node as mutated. |
| 341 TEST_F(ContextualSearchJsTest, TestHighlightIgnoreDOMMutationSameAttribute) { |
| 342 LoadHtml(kHTMLWithRelatedDOMMutation); |
| 343 ExecuteJavaScript( |
| 344 @"document.getElementById('test').setAttribute('attr', 'before');"); |
| 345 ASSERT_EQ(0, GetMutatedNodeCount()); |
| 346 ContextualSearchStruct searchContext; |
| 347 |
| 348 ASSERT_TRUE(GetContextFromId(@"taphere", &searchContext)); |
| 349 }; |
| 350 |
| 351 // Test that DOM mutation between different false values does not cancel |
| 352 // contextual search. Mutation should not mark a node as mutated. |
| 353 TEST_F(ContextualSearchJsTest, TestHighlightIgnoreDOMMutationBothFalse) { |
| 354 LoadHtml(kHTMLWithRelatedDOMMutation); |
| 355 ExecuteJavaScript( |
| 356 @"document.getElementById('test').setAttribute('non_attr', '');"); |
| 357 ASSERT_EQ(0, GetMutatedNodeCount()); |
| 358 ContextualSearchStruct searchContext; |
| 359 |
| 360 ASSERT_TRUE(GetContextFromId(@"taphere", &searchContext)); |
| 361 }; |
| 362 |
| 363 // Test that DOM mutation with same text does not cancel contextual search. |
| 364 // Mutation should not mark a node as mutated. |
| 365 TEST_F(ContextualSearchJsTest, TestHighlightIgnoreDOMMutationSameText) { |
| 366 LoadHtml(kHTMLWithRelatedTextMutation); |
| 367 ExecuteJavaScript( |
| 368 @"document.getElementById('test').innerText = 'mutation is ';"); |
| 369 ASSERT_EQ(0, GetMutatedNodeCount()); |
| 370 ContextualSearchStruct searchContext; |
| 371 |
| 372 ASSERT_TRUE(GetContextFromId(@"taphere", &searchContext)); |
| 373 }; |
| 374 |
| 375 // Test that related text DOM mutation prevents contextual search. |
| 376 TEST_F(ContextualSearchJsTest, TestHighlightRelatedDOMMutationText) { |
| 377 LoadHtml(kHTMLWithRelatedTextMutation); |
| 378 ExecuteJavaScript(@"document.getElementById('test').innerText = 'mutated';"); |
| 379 ASSERT_EQ(1, GetMutatedNodeCount()); |
| 380 ContextualSearchStruct searchContext; |
| 381 |
| 382 ASSERT_FALSE(GetContextFromId(@"taphere", &searchContext)); |
| 383 }; |
| 384 |
| 385 // Test that unrelated text DOM mutation doesn't prevent contextual search. |
| 386 TEST_F(ContextualSearchJsTest, TestHighlightUnrelatedDOMMutationTextIgnored) { |
| 387 LoadHtml(kHTMLWithUnrelatedDOMMutation); |
| 388 ExecuteJavaScript(@"document.getElementById('test').innerText = 'mutated';"); |
| 389 ASSERT_EQ(1, GetMutatedNodeCount()); |
| 390 ContextualSearchStruct searchContext; |
| 391 |
| 392 ASSERT_TRUE(GetContextFromId(@"taphere", &searchContext)); |
| 393 }; |
| 394 |
| 395 // Test that two related DOM mutations prevent contextual search. |
| 396 TEST_F(ContextualSearchJsTest, TestHighlightTwoDOMMutations) { |
| 397 LoadHtml(kHTMLWithRelatedDOMMutation); |
| 398 ASSERT_EQ(0, GetMutatedNodeCount()); |
| 399 ExecuteJavaScript( |
| 400 @"document.getElementById('taphere').innerText = 'mutated';" |
| 401 "document.getElementById('test').setAttribute('attr', 'after');"); |
| 402 ASSERT_EQ(2, GetMutatedNodeCount()); |
| 403 ContextualSearchStruct searchContext; |
| 404 |
| 405 ASSERT_FALSE(GetContextFromId(@"taphere", &searchContext)); |
| 406 }; |
| 407 |
| 408 // Test that two related DOM mutations with only one change prevent contextual |
| 409 // search. |
| 410 TEST_F(ContextualSearchJsTest, TestHighlightTwoDOMMutationOneChanging) { |
| 411 LoadHtml(kHTMLWithRelatedDOMMutation); |
| 412 ExecuteJavaScript( |
| 413 @"document.getElementById('taphere').innerText = 'mutated';" |
| 414 "document.getElementById('test').setAttribute('attr', 'before');"); |
| 415 ASSERT_EQ(1, GetMutatedNodeCount()); |
| 416 ContextualSearchStruct searchContext; |
| 417 |
| 418 ASSERT_FALSE(GetContextFromId(@"taphere", &searchContext)); |
| 419 }; |
| 420 |
| 421 // Test that two DOM mutations with same value does not cancel contextual |
| 422 // search. |
| 423 TEST_F(ContextualSearchJsTest, TestHighlightTwoDOMMutationNoChange) { |
| 424 LoadHtml(kHTMLWithRelatedDOMMutation); |
| 425 ExecuteJavaScript( |
| 426 @"document.getElementById('taphere').innerText = 'is';" |
| 427 "document.getElementById('test').setAttribute('attr', 'before');"); |
| 428 ASSERT_EQ(0, GetMutatedNodeCount()); |
| 429 ContextualSearchStruct searchContext; |
| 430 |
| 431 ASSERT_TRUE(GetContextFromId(@"taphere", &searchContext)); |
| 432 }; |
| 433 |
| 434 // Test that non bubbling event does not trigger contextual search. |
| 435 TEST_F(ContextualSearchJsTest, TestHighlightIgnorePreventDefault) { |
| 436 LoadHtml(kHTMLWithPreventDefault); |
| 437 // Enable touch delay. |
| 438 ExecuteJavaScript( |
| 439 @"__gCrWeb.contextualSearch.setBodyTouchListenerDelay(200);"); |
| 440 ContextualSearchStruct searchContext; |
| 441 ExecuteJavaScript(@"document.getElementById('interceptor')." |
| 442 @"addEventListener('touchend', function(event) " |
| 443 @"{event.preventDefault();return false;}, false);"); |
| 444 |
| 445 ASSERT_FALSE(GetContextFromId(@"taphere", &searchContext)); |
| 446 }; |
| 447 |
| 448 TEST_F(ContextualSearchJsTest, Test1500CharactersCenter) { |
| 449 // String should extend 15 sentences to the left and right. |
| 450 NSString* stringHTML = BuildLongTestString(0, 50, 25, true); |
| 451 NSString* expectedHTML = BuildLongTestString(10, 41, -1, false); |
| 452 LoadHtml(stringHTML); |
| 453 ContextualSearchStruct searchContext; |
| 454 ASSERT_TRUE(GetContextFromId(@"taphere", &searchContext)); |
| 455 CheckContextOffsets(searchContext, base::SysNSStringToUTF8(expectedHTML)); |
| 456 }; |
| 457 |
| 458 TEST_F(ContextualSearchJsTest, Test1500CharactersRight) { |
| 459 // There is not enough chars on the left, so string should extend on the |
| 460 // right. |
| 461 NSString* stringHTML = BuildLongTestString(0, 50, 5, true); |
| 462 NSString* expectedHTML = BuildLongTestString(0, 30, -1, false); |
| 463 LoadHtml( |
| 464 [NSString stringWithFormat:@"<html><body>%@</body></html>", stringHTML]); |
| 465 ContextualSearchStruct searchContext; |
| 466 ASSERT_TRUE(GetContextFromId(@"taphere", &searchContext)); |
| 467 CheckContextOffsets(searchContext, base::SysNSStringToUTF8(expectedHTML)); |
| 468 }; |
| 469 |
| 470 TEST_F(ContextualSearchJsTest, Test1500CharactersLeft) { |
| 471 // There is not enough chars on the right, so string should extend on the |
| 472 // left. |
| 473 NSString* stringHTML = BuildLongTestString(0, 50, 45, true); |
| 474 NSString* expectedHTML = BuildLongTestString(20, 50, -1, false); |
| 475 LoadHtml( |
| 476 [NSString stringWithFormat:@"<html><body>%@</body></html>", stringHTML]); |
| 477 ContextualSearchStruct searchContext; |
| 478 ASSERT_TRUE(GetContextFromId(@"taphere", &searchContext)); |
| 479 CheckContextOffsets(searchContext, base::SysNSStringToUTF8(expectedHTML)); |
| 480 }; |
| 481 |
| 482 TEST_F(ContextualSearchJsTest, Test1500CharactersToShort) { |
| 483 // String is too short so the whole string should be in the context. |
| 484 NSString* stringHTML = BuildLongTestString(0, 10, 5, true); |
| 485 NSString* expectedHTML = BuildLongTestString(0, 10, -1, false); |
| 486 // LoadHtml will trim the last space. |
| 487 LoadHtml( |
| 488 [NSString stringWithFormat:@"<html><body>%@</body></html>", stringHTML]); |
| 489 ContextualSearchStruct searchContext; |
| 490 ASSERT_TRUE(GetContextFromId(@"taphere", &searchContext)); |
| 491 CheckContextOffsets(searchContext, base::SysNSStringToUTF8(expectedHTML)); |
| 492 }; |
| 493 } // namespace |
OLD | NEW |