Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2012 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 #include "ui/base/win/tsf_text_store.h" | |
| 6 | |
| 7 #include "base/win/scoped_com_initializer.h" | |
| 8 #include "testing/gtest/include/gtest/gtest.h" | |
| 9 #include "testing/gmock/include/gmock/gmock.h" | |
| 10 #include "ui/base/ime/text_input_client.h" | |
| 11 #include "ui/gfx/rect.h" | |
| 12 | |
| 13 using testing::_; | |
| 14 using testing::Invoke; | |
| 15 using testing::Return; | |
| 16 | |
| 17 namespace ui { | |
| 18 | |
| 19 namespace { | |
| 20 class MockTextInputClient : public TextInputClient { | |
| 21 public: | |
| 22 ~MockTextInputClient() {} | |
| 23 MOCK_METHOD1(SetCompositionText, void(const ui::CompositionText&)); | |
| 24 MOCK_METHOD0(ConfirmCompositionText, void()); | |
| 25 MOCK_METHOD0(ClearCompositionText, void()); | |
| 26 MOCK_METHOD1(InsertText, void(const string16&)); | |
| 27 MOCK_METHOD2(InsertChar, void(char16, int)); | |
| 28 MOCK_CONST_METHOD0(GetTextInputType, ui::TextInputType()); | |
| 29 MOCK_CONST_METHOD0(CanComposeInline, bool()); | |
| 30 MOCK_METHOD0(GetCaretBounds, gfx::Rect()); | |
| 31 MOCK_METHOD2(GetCompositionCharacterBounds, bool(uint32, gfx::Rect*)); | |
| 32 MOCK_METHOD0(HasCompositionText, bool()); | |
| 33 MOCK_METHOD1(GetTextRange, bool(ui::Range*)); | |
| 34 MOCK_METHOD1(GetCompositionTextRange, bool(ui::Range*)); | |
| 35 MOCK_METHOD1(GetSelectionRange, bool(ui::Range*)); | |
| 36 MOCK_METHOD1(SetSelectionRange, bool(const ui::Range&)); | |
| 37 MOCK_METHOD1(DeleteRange, bool(const ui::Range&)); | |
| 38 MOCK_METHOD2(GetTextFromRange, bool(const ui::Range&, string16*)); | |
| 39 MOCK_METHOD0(OnInputMethodChanged, void()); | |
| 40 MOCK_METHOD1(ChangeTextDirectionAndLayoutAlignment, | |
| 41 bool(base::i18n::TextDirection)); | |
| 42 }; | |
| 43 | |
| 44 class MockStoreACPSink : public ITextStoreACPSink { | |
| 45 public: | |
| 46 MockStoreACPSink() : ref_count_(0) { | |
| 47 } | |
| 48 | |
| 49 // IUnknown | |
| 50 virtual ULONG STDMETHODCALLTYPE AddRef() OVERRIDE { | |
| 51 return InterlockedIncrement(&ref_count_); | |
| 52 } | |
| 53 virtual ULONG STDMETHODCALLTYPE Release() OVERRIDE { | |
| 54 const LONG count = InterlockedDecrement(&ref_count_); | |
| 55 if (!count) { | |
| 56 delete this; | |
| 57 return 0; | |
| 58 } | |
| 59 return static_cast<ULONG>(count); | |
| 60 } | |
| 61 virtual HRESULT STDMETHODCALLTYPE QueryInterface( | |
| 62 REFIID iid, void** report) OVERRIDE { | |
| 63 if (iid == IID_IUnknown || iid == IID_ITextStoreACPSink) { | |
| 64 *report = static_cast<ITextStoreACPSink*>(this); | |
| 65 } else { | |
| 66 *report = NULL; | |
| 67 return E_NOINTERFACE; | |
| 68 } | |
| 69 AddRef(); | |
| 70 return S_OK; | |
| 71 } | |
| 72 | |
| 73 // ITextStoreACPSink | |
| 74 MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE, OnTextChange, | |
| 75 HRESULT(DWORD, const TS_TEXTCHANGE*)); | |
| 76 MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, OnSelectionChange, | |
| 77 HRESULT()); | |
| 78 MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE, OnLayoutChange, | |
| 79 HRESULT(TsLayoutCode, TsViewCookie)); | |
| 80 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, OnStatusChange, | |
| 81 HRESULT(DWORD)); | |
| 82 MOCK_METHOD4_WITH_CALLTYPE(STDMETHODCALLTYPE, OnAttrsChange, | |
| 83 HRESULT(LONG, LONG, ULONG, const TS_ATTRID*)); | |
| 84 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, OnLockGranted, | |
| 85 HRESULT(DWORD)); | |
| 86 MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, OnStartEditTransaction, | |
| 87 HRESULT()); | |
| 88 MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, OnEndEditTransaction, | |
| 89 HRESULT()); | |
| 90 | |
| 91 private: | |
| 92 ~MockStoreACPSink() { | |
| 93 } | |
| 94 volatile LONG ref_count_; | |
| 95 }; | |
| 96 | |
| 97 } // namespace | |
| 98 | |
| 99 class TsfTextStoreTest : public testing::Test { | |
| 100 protected: | |
| 101 virtual void SetUp() OVERRIDE { | |
| 102 text_store_ = new TsfTextStore(); | |
| 103 text_store_->AddRef(); | |
| 104 sink_ = new MockStoreACPSink(); | |
| 105 sink_->AddRef(); | |
| 106 EXPECT_EQ(S_OK, | |
| 107 text_store_->AdviseSink(IID_ITextStoreACPSink, | |
|
Yohei Yukawa
2012/08/23 10:16:44
Indent?
horo
2012/08/23 10:36:18
Done.
| |
| 108 sink_, TS_AS_ALL_SINKS)); | |
| 109 text_store_->SetFocusedTextInputClient(0, &text_input_client_); | |
| 110 } | |
| 111 | |
| 112 virtual void TearDown() OVERRIDE { | |
| 113 EXPECT_EQ(S_OK, text_store_->UnadviseSink(sink_)); | |
| 114 sink_->Release(); | |
| 115 text_store_->Release(); | |
| 116 } | |
| 117 | |
| 118 base::win::ScopedCOMInitializer com_initializer_; | |
| 119 MockTextInputClient text_input_client_; | |
| 120 TsfTextStore* text_store_; | |
| 121 MockStoreACPSink* sink_; | |
| 122 }; | |
| 123 | |
| 124 class TsfTextStoreTestCallback { | |
| 125 public: | |
| 126 explicit TsfTextStoreTestCallback(TsfTextStore* text_store) | |
| 127 : text_store_(text_store) { | |
| 128 CHECK(text_store_); | |
| 129 } | |
| 130 virtual ~TsfTextStoreTestCallback() {} | |
| 131 | |
| 132 protected: | |
| 133 // Accessros to the internal state of TsfTextStore. | |
| 134 bool* edit_flag() { return &text_store_->edit_flag_; } | |
| 135 string16* string_buffer() { return &text_store_->string_buffer_; } | |
| 136 size_t* committed_size() { return &text_store_->committed_size_; } | |
| 137 Range* selection() { return &text_store_->selection_; } | |
| 138 CompositionUnderlines* composition_undelines() { | |
| 139 return &text_store_->composition_undelines_; | |
| 140 } | |
| 141 | |
| 142 TsfTextStore* text_store_; | |
| 143 }; | |
| 144 | |
| 145 class SelectionTestCallback : public TsfTextStoreTestCallback { | |
| 146 public: | |
| 147 explicit SelectionTestCallback(TsfTextStore* text_store) | |
| 148 : TsfTextStoreTestCallback(text_store) { | |
| 149 } | |
| 150 | |
| 151 HRESULT ReadLockGranted(DWORD flags) { | |
| 152 *string_buffer() = L""; | |
| 153 *committed_size() = 0; | |
| 154 selection()->set_start(0); | |
| 155 selection()->set_end(0); | |
| 156 | |
| 157 GetSelectionTest(0, 0); | |
| 158 SetSelectionTest(0, 0, TF_E_NOLOCK); | |
| 159 | |
| 160 *string_buffer() = L"012345"; | |
| 161 *committed_size() = 0; | |
| 162 selection()->set_start(0); | |
| 163 selection()->set_end(3); | |
| 164 | |
| 165 GetSelectionTest(0, 3); | |
| 166 SetSelectionTest(0, 0, TF_E_NOLOCK); | |
| 167 | |
| 168 return S_OK; | |
| 169 } | |
| 170 | |
| 171 HRESULT ReadWriteLockGranted(DWORD flags) { | |
| 172 *string_buffer() = L""; | |
| 173 *committed_size() = 0; | |
| 174 selection()->set_start(0); | |
| 175 selection()->set_end(0); | |
| 176 | |
| 177 SetSelectionTest(0, 0, S_OK); | |
| 178 GetSelectionTest(0, 0); | |
| 179 SetSelectionTest(0, 1, TF_E_INVALIDPOS); | |
| 180 GetSelectionTest(0, 0); | |
| 181 SetSelectionTest(1, 0, TF_E_INVALIDPOS); | |
| 182 GetSelectionTest(0, 0); | |
| 183 SetSelectionTest(1, 1, TF_E_INVALIDPOS); | |
| 184 GetSelectionTest(0, 0); | |
| 185 | |
| 186 *string_buffer() = L"012345"; | |
| 187 *committed_size() = 0; | |
| 188 selection()->set_start(0); | |
| 189 selection()->set_end(0); | |
| 190 | |
| 191 SetSelectionTest(0, 0, S_OK); | |
| 192 GetSelectionTest(0, 0); | |
| 193 SetSelectionTest(0, 3, S_OK); | |
| 194 GetSelectionTest(0, 3); | |
| 195 SetSelectionTest(0, 6, S_OK); | |
| 196 GetSelectionTest(0, 6); | |
| 197 SetSelectionTest(0, 7, TF_E_INVALIDPOS); | |
| 198 GetSelectionTest(0, 6); | |
| 199 | |
| 200 SetSelectionTest(3, 0, TF_E_INVALIDPOS); | |
| 201 GetSelectionTest(0, 6); | |
| 202 SetSelectionTest(3, 3, S_OK); | |
| 203 GetSelectionTest(3, 3); | |
| 204 SetSelectionTest(3, 6, S_OK); | |
| 205 GetSelectionTest(3, 6); | |
| 206 SetSelectionTest(3, 7, TF_E_INVALIDPOS); | |
| 207 GetSelectionTest(3, 6); | |
| 208 | |
| 209 SetSelectionTest(6, 0, TF_E_INVALIDPOS); | |
| 210 GetSelectionTest(3, 6); | |
| 211 SetSelectionTest(6, 3, TF_E_INVALIDPOS); | |
| 212 GetSelectionTest(3, 6); | |
| 213 SetSelectionTest(6, 6, S_OK); | |
| 214 GetSelectionTest(6, 6); | |
| 215 SetSelectionTest(6, 7, TF_E_INVALIDPOS); | |
| 216 GetSelectionTest(6, 6); | |
| 217 | |
| 218 return S_OK; | |
| 219 } | |
| 220 | |
| 221 private: | |
| 222 void SetSelectionTest(LONG acp_start, LONG acp_end, HRESULT expected_result) { | |
| 223 TS_SELECTION_ACP selection; | |
| 224 selection.acpStart = acp_start; | |
| 225 selection.acpEnd = acp_end; | |
| 226 selection.style.ase = TS_AE_NONE; | |
| 227 selection.style.fInterimChar = 0; | |
| 228 EXPECT_EQ(expected_result, text_store_->SetSelection(1, &selection)); | |
| 229 } | |
| 230 | |
| 231 void GetSelectionTest(LONG expected_acp_start, LONG expected_acp_end) { | |
| 232 TS_SELECTION_ACP selection; | |
| 233 ULONG fetched; | |
| 234 EXPECT_EQ(S_OK, text_store_->GetSelection(0, 1, &selection, &fetched)); | |
| 235 EXPECT_EQ(1, fetched); | |
| 236 EXPECT_EQ(expected_acp_start, selection.acpStart); | |
| 237 EXPECT_EQ(expected_acp_end, selection.acpEnd); | |
| 238 } | |
| 239 }; | |
| 240 | |
| 241 TEST_F(TsfTextStoreTest, GetStatus) { | |
| 242 TS_STATUS status; | |
| 243 EXPECT_EQ(S_OK, text_store_->GetStatus(&status)); | |
| 244 EXPECT_EQ(0, status.dwDynamicFlags); | |
| 245 EXPECT_EQ(TS_SS_NOHIDDENTEXT, status.dwStaticFlags); | |
| 246 } | |
| 247 | |
| 248 TEST_F(TsfTextStoreTest, SetGetSelectionTest) { | |
| 249 SelectionTestCallback callback(text_store_); | |
| 250 EXPECT_CALL(*sink_, OnLockGranted(_)) | |
| 251 .WillOnce(Invoke(&callback, &SelectionTestCallback::ReadLockGranted)) | |
| 252 .WillOnce(Invoke(&callback, | |
| 253 &SelectionTestCallback::ReadWriteLockGranted)); | |
| 254 | |
| 255 TS_SELECTION_ACP selection_buffer; | |
| 256 ULONG fetched_count; | |
| 257 EXPECT_EQ(TS_E_NOLOCK, | |
| 258 text_store_->GetSelection(0, 1, &selection_buffer, | |
| 259 &fetched_count)); | |
| 260 | |
| 261 HRESULT result; | |
| 262 EXPECT_EQ(S_OK, | |
| 263 text_store_->RequestLock(TS_LF_READ, &result)); | |
| 264 EXPECT_EQ(S_OK, | |
| 265 text_store_->RequestLock(TS_LF_READWRITE, &result)); | |
| 266 } | |
| 267 | |
| 268 class SenarioTestCallback : public TsfTextStoreTestCallback { | |
| 269 public: | |
| 270 explicit SenarioTestCallback(TsfTextStore* text_store) | |
| 271 : TsfTextStoreTestCallback(text_store) { | |
| 272 } | |
| 273 | |
| 274 HRESULT LockGranted1(DWORD flags) { | |
| 275 TS_SELECTION_ACP selection; | |
| 276 selection.acpStart = 0; | |
| 277 selection.acpEnd = 0; | |
| 278 selection.style.ase = TS_AE_NONE; | |
| 279 selection.style.fInterimChar = 0; | |
| 280 EXPECT_EQ(S_OK, | |
| 281 text_store_->SetSelection(1, &selection)); | |
| 282 TS_TEXTCHANGE change; | |
| 283 EXPECT_EQ(S_OK, | |
| 284 text_store_->SetText(0, 0, 0, L"abc", 3, &change)); | |
| 285 EXPECT_EQ(0, change.acpStart); | |
| 286 EXPECT_EQ(0, change.acpOldEnd); | |
| 287 EXPECT_EQ(3, change.acpNewEnd); | |
| 288 | |
| 289 EXPECT_EQ(S_OK, | |
| 290 text_store_->SetText(0, 1, 2, L"xyz", 3, &change)); | |
| 291 EXPECT_EQ(1, change.acpStart); | |
| 292 EXPECT_EQ(2, change.acpOldEnd); | |
| 293 EXPECT_EQ(4, change.acpNewEnd); | |
| 294 | |
| 295 wchar_t buffer[1024]; | |
| 296 ULONG text_buffer_copied; | |
| 297 TS_RUNINFO run_info; | |
| 298 ULONG run_info_buffer_copied; | |
| 299 LONG next_acp; | |
| 300 EXPECT_EQ(S_OK, | |
| 301 text_store_->GetText(0, -1, buffer, 1024, &text_buffer_copied, | |
| 302 &run_info, 1, &run_info_buffer_copied, | |
| 303 &next_acp)); | |
| 304 EXPECT_EQ(5, text_buffer_copied); | |
| 305 EXPECT_EQ(L"axyzc", string16(buffer, buffer + text_buffer_copied)); | |
| 306 EXPECT_EQ(1, run_info_buffer_copied); | |
| 307 EXPECT_EQ(TS_RT_PLAIN, run_info.type); | |
| 308 EXPECT_EQ(5, run_info.uCount); | |
| 309 EXPECT_EQ(5, next_acp); | |
| 310 | |
| 311 composition_undelines()->clear(); | |
| 312 CompositionUnderline underline; | |
| 313 underline.start_offset = 0; | |
| 314 underline.end_offset = 5; | |
| 315 underline.color = SK_ColorBLACK; | |
| 316 underline.thick = false; | |
| 317 composition_undelines()->push_back(underline); | |
| 318 *edit_flag() = true; | |
| 319 *committed_size() = 0; | |
| 320 return S_OK; | |
| 321 } | |
| 322 | |
| 323 void SetCompositionText1(const ui::CompositionText& composition) { | |
| 324 EXPECT_EQ(L"axyzc", composition.text); | |
| 325 EXPECT_EQ(1, composition.selection.start()); | |
| 326 EXPECT_EQ(4, composition.selection.end()); | |
| 327 ASSERT_EQ(1, composition.underlines.size()); | |
| 328 EXPECT_EQ(SK_ColorBLACK, composition.underlines[0].color); | |
| 329 EXPECT_EQ(0, composition.underlines[0].start_offset); | |
| 330 EXPECT_EQ(5, composition.underlines[0].end_offset); | |
| 331 EXPECT_FALSE(composition.underlines[0].thick); | |
| 332 } | |
| 333 | |
| 334 HRESULT LockGranted2(DWORD flags) { | |
| 335 TS_TEXTCHANGE change; | |
| 336 EXPECT_EQ(S_OK, | |
| 337 text_store_->SetText(0, 3, 4, L"ZCP", 3, &change)); | |
| 338 EXPECT_EQ(3, change.acpStart); | |
| 339 EXPECT_EQ(4, change.acpOldEnd); | |
| 340 EXPECT_EQ(6, change.acpNewEnd); | |
| 341 | |
| 342 wchar_t buffer[1024]; | |
| 343 ULONG text_buffer_copied; | |
| 344 TS_RUNINFO run_info; | |
| 345 ULONG run_info_buffer_copied; | |
| 346 LONG next_acp; | |
| 347 EXPECT_EQ(S_OK, | |
| 348 text_store_->GetText(0, -1, buffer, 1024, &text_buffer_copied, | |
| 349 &run_info, 1, &run_info_buffer_copied, | |
| 350 &next_acp)); | |
| 351 EXPECT_EQ(7, text_buffer_copied); | |
| 352 EXPECT_EQ(L"axyZCPc", string16(buffer, buffer + text_buffer_copied)); | |
| 353 EXPECT_EQ(1, run_info_buffer_copied); | |
| 354 EXPECT_EQ(TS_RT_PLAIN, run_info.type); | |
| 355 EXPECT_EQ(7, run_info.uCount); | |
| 356 EXPECT_EQ(7, next_acp); | |
| 357 | |
| 358 composition_undelines()->clear(); | |
| 359 CompositionUnderline underline; | |
| 360 underline.start_offset = 3; | |
| 361 underline.end_offset = 5; | |
| 362 underline.color = SK_ColorBLACK; | |
| 363 underline.thick = true; | |
| 364 composition_undelines()->push_back(underline); | |
| 365 underline.start_offset = 5; | |
| 366 underline.end_offset = 7; | |
| 367 underline.color = SK_ColorBLACK; | |
| 368 underline.thick = false; | |
| 369 composition_undelines()->push_back(underline); | |
| 370 | |
| 371 *edit_flag() = true; | |
| 372 *committed_size() = 3; | |
| 373 | |
| 374 return S_OK; | |
| 375 } | |
| 376 | |
| 377 void InsertText2(const string16& text) { | |
| 378 EXPECT_EQ(L"axy", text); | |
| 379 } | |
| 380 | |
| 381 void SetCompositionText2(const ui::CompositionText& composition) { | |
| 382 EXPECT_EQ(L"ZCPc", composition.text); | |
| 383 EXPECT_EQ(0, composition.selection.start()); | |
| 384 EXPECT_EQ(3, composition.selection.end()); | |
| 385 ASSERT_EQ(2, composition.underlines.size()); | |
| 386 EXPECT_EQ(SK_ColorBLACK, composition.underlines[0].color); | |
| 387 EXPECT_EQ(0, composition.underlines[0].start_offset); | |
| 388 EXPECT_EQ(2, composition.underlines[0].end_offset); | |
| 389 EXPECT_TRUE(composition.underlines[0].thick); | |
| 390 EXPECT_EQ(SK_ColorBLACK, composition.underlines[1].color); | |
| 391 EXPECT_EQ(2, composition.underlines[1].start_offset); | |
| 392 EXPECT_EQ(4, composition.underlines[1].end_offset); | |
| 393 EXPECT_FALSE(composition.underlines[1].thick); | |
| 394 } | |
| 395 | |
| 396 HRESULT LockGranted3(DWORD flags) { | |
| 397 wchar_t buffer[1024]; | |
| 398 ULONG text_buffer_copied; | |
| 399 TS_RUNINFO run_info; | |
| 400 ULONG run_info_buffer_copied; | |
| 401 LONG next_acp; | |
| 402 EXPECT_EQ(S_OK, | |
| 403 text_store_->GetText(0, -1, buffer, 1024, &text_buffer_copied, | |
| 404 &run_info, 1, &run_info_buffer_copied, | |
| 405 &next_acp)); | |
| 406 EXPECT_EQ(7, text_buffer_copied); | |
| 407 EXPECT_EQ(L"axyZCPc", string16(buffer, buffer + text_buffer_copied)); | |
| 408 EXPECT_EQ(1, run_info_buffer_copied); | |
| 409 EXPECT_EQ(TS_RT_PLAIN, run_info.type); | |
| 410 EXPECT_EQ(7, run_info.uCount); | |
| 411 EXPECT_EQ(7, next_acp); | |
| 412 | |
| 413 composition_undelines()->clear(); | |
| 414 *edit_flag() = true; | |
| 415 *committed_size() = 7; | |
| 416 | |
| 417 return S_OK; | |
| 418 } | |
| 419 | |
| 420 void InsertText3(const string16& text) { | |
| 421 EXPECT_EQ(L"ZCPc", text); | |
| 422 } | |
| 423 | |
| 424 void SetCompositionText3(const ui::CompositionText& composition) { | |
| 425 EXPECT_EQ(L"", composition.text); | |
| 426 EXPECT_EQ(0, composition.selection.start()); | |
| 427 EXPECT_EQ(0, composition.selection.end()); | |
| 428 EXPECT_EQ(0, composition.underlines.size()); | |
| 429 } | |
| 430 }; | |
| 431 | |
| 432 TEST_F(TsfTextStoreTest, SenarioTest) { | |
| 433 SenarioTestCallback callback(text_store_); | |
| 434 EXPECT_CALL(text_input_client_, SetCompositionText(_)) | |
| 435 .WillOnce(Invoke(&callback, &SenarioTestCallback::SetCompositionText1)) | |
| 436 .WillOnce(Invoke(&callback, &SenarioTestCallback::SetCompositionText2)) | |
| 437 .WillOnce(Invoke(&callback, &SenarioTestCallback::SetCompositionText3)); | |
| 438 | |
| 439 EXPECT_CALL(text_input_client_, InsertText(_)) | |
| 440 .WillOnce(Invoke(&callback, &SenarioTestCallback::InsertText2)) | |
| 441 .WillOnce(Invoke(&callback, &SenarioTestCallback::InsertText3)); | |
| 442 | |
| 443 EXPECT_CALL(*sink_, OnLockGranted(_)) | |
| 444 .WillOnce(Invoke(&callback, &SenarioTestCallback::LockGranted1)) | |
| 445 .WillOnce(Invoke(&callback, &SenarioTestCallback::LockGranted2)) | |
| 446 .WillOnce(Invoke(&callback, &SenarioTestCallback::LockGranted3)); | |
| 447 | |
| 448 // OnSelectionChange will be called once in LockGranted3(). | |
| 449 EXPECT_CALL(*sink_, OnSelectionChange()) | |
| 450 .WillOnce(Return(S_OK)); | |
| 451 | |
| 452 // OnLayoutChange will be called once in LockGranted3(). | |
| 453 EXPECT_CALL(*sink_, OnLayoutChange(_, _)) | |
| 454 .WillOnce(Return(S_OK)); | |
| 455 | |
| 456 // OnTextChange will be called once in LockGranted3(). | |
| 457 EXPECT_CALL(*sink_, OnTextChange(_, _)) | |
| 458 .WillOnce(Return(S_OK)); | |
| 459 | |
| 460 HRESULT result; | |
| 461 EXPECT_EQ(S_OK, text_store_->RequestLock(TS_LF_READWRITE, &result)); | |
| 462 EXPECT_EQ(S_OK, text_store_->RequestLock(TS_LF_READWRITE, &result)); | |
| 463 EXPECT_EQ(S_OK, text_store_->RequestLock(TS_LF_READWRITE, &result)); | |
| 464 } | |
| 465 | |
| 466 } // namespace ui | |
| OLD | NEW |