Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/renderer/hyphenator/hyphenator.h" | 5 #include "content/renderer/hyphenator/hyphenator.h" |
| 6 | 6 |
| 7 #include "base/path_service.h" | 7 #include "base/path_service.h" |
| 8 #include "base/platform_file.h" | 8 #include "base/platform_file.h" |
| 9 #include "base/utf_string_conversions.h" | 9 #include "base/utf_string_conversions.h" |
| 10 #include "content/common/hyphenator_messages.h" | |
| 11 #include "content/public/test/mock_render_thread.h" | |
| 12 #include "ipc/ipc_listener.h" | |
| 10 #include "testing/gtest/include/gtest/gtest.h" | 13 #include "testing/gtest/include/gtest/gtest.h" |
| 11 #include "third_party/hyphen/hyphen.h" | 14 #include "third_party/hyphen/hyphen.h" |
| 12 | 15 |
| 16 namespace { | |
| 17 | |
| 18 // A mock message listener that listens HyphenatorHost messages. This class | |
|
tony
2012/08/22 19:05:50
Nit: that listens _for_ HyphenatorHost messages
Hironori Bono
2012/08/27 06:57:28
Done. Thanks for fixing my typo.
| |
| 19 // intercepts a HyphenatorHostMsg_OpenDictionary message sent to an | |
| 20 // IPC::TestSink object and emulates a browser process. | |
| 21 class MockListener : public IPC::Listener { | |
| 22 public: | |
| 23 MockListener(content::Hyphenator* hyphenator, const string16& locale) | |
| 24 : hyphenator_(hyphenator), | |
| 25 locale_(locale) { | |
| 26 } | |
| 27 virtual ~MockListener() { | |
| 28 } | |
| 29 | |
| 30 // IPC::ChannelProxy::MessageFilter implementation. | |
| 31 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { | |
| 32 if (message.type() != HyphenatorHostMsg_OpenDictionary::ID) | |
| 33 return false; | |
| 34 | |
| 35 // Retrieve the locale parameter directly because HyphenatorHost messages | |
| 36 // are internal messages and unit tests cannot access its member functions, | |
| 37 // i.e. unit tests cannot call the HyphenatorHostMsg_OpenDictionary::Read | |
| 38 // function. | |
| 39 PickleIterator iter(message); | |
| 40 string16 locale; | |
| 41 EXPECT_TRUE(message.ReadString16(&iter, &locale)); | |
| 42 EXPECT_EQ(locale_, locale); | |
| 43 | |
| 44 // Open the default dictionary and call the Hyphenator::SetDictionary | |
| 45 // function instead of sending a HyphenatorMsg_SetDictionary message. (The | |
| 46 // Hyphenator class posts a task when it receives the message, i.e. sending | |
| 47 // the message makes this unit test flaky.) | |
| 48 FilePath dictionary_path; | |
| 49 if (!PathService::Get(base::DIR_SOURCE_ROOT, &dictionary_path)) | |
| 50 return false; | |
| 51 dictionary_path = dictionary_path.AppendASCII("third_party"); | |
| 52 dictionary_path = dictionary_path.AppendASCII("hyphen"); | |
| 53 dictionary_path = dictionary_path.AppendASCII("hyph_en_US.dic"); | |
| 54 base::PlatformFile file = base::CreatePlatformFile( | |
| 55 dictionary_path, base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ, | |
| 56 NULL, NULL); | |
| 57 hyphenator_->SetDictionary(file); | |
| 58 return true; | |
| 59 } | |
| 60 | |
| 61 private: | |
| 62 content::Hyphenator* hyphenator_; | |
| 63 string16 locale_; | |
| 64 }; | |
| 65 | |
| 66 } // namespace | |
| 67 | |
| 13 // A unit test for our hyphenator. This class loads a sample hyphenation | 68 // A unit test for our hyphenator. This class loads a sample hyphenation |
| 14 // dictionary and hyphenates words. | 69 // dictionary and hyphenates words. |
| 15 class HyphenatorTest : public testing::Test { | 70 class HyphenatorTest : public testing::Test { |
| 16 public: | 71 public: |
| 17 HyphenatorTest() { | 72 HyphenatorTest() { |
| 18 Initialize(); | |
| 19 } | 73 } |
| 20 | 74 |
| 21 bool Initialize() { | 75 bool Initialize() { |
| 22 FilePath dictionary_path; | 76 FilePath dictionary_path; |
| 23 if (!PathService::Get(base::DIR_SOURCE_ROOT, &dictionary_path)) | 77 if (!PathService::Get(base::DIR_SOURCE_ROOT, &dictionary_path)) |
| 24 return false; | 78 return false; |
| 25 dictionary_path = dictionary_path.AppendASCII("third_party"); | 79 dictionary_path = dictionary_path.AppendASCII("third_party"); |
| 26 dictionary_path = dictionary_path.AppendASCII("hyphen"); | 80 dictionary_path = dictionary_path.AppendASCII("hyphen"); |
| 27 dictionary_path = dictionary_path.AppendASCII("hyph_en_US.dic"); | 81 dictionary_path = dictionary_path.AppendASCII("hyph_en_US.dic"); |
| 28 base::PlatformFile file = base::CreatePlatformFile( | 82 base::PlatformFile file = base::CreatePlatformFile( |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 42 size_t new_position = hyphenator_->ComputeLastHyphenLocation(word, | 96 size_t new_position = hyphenator_->ComputeLastHyphenLocation(word, |
| 43 position); | 97 position); |
| 44 EXPECT_LT(new_position, position); | 98 EXPECT_LT(new_position, position); |
| 45 if (new_position > 0) | 99 if (new_position > 0) |
| 46 hyphenated_word.insert(new_position, 1, '-'); | 100 hyphenated_word.insert(new_position, 1, '-'); |
| 47 position = new_position; | 101 position = new_position; |
| 48 } | 102 } |
| 49 return hyphenated_word; | 103 return hyphenated_word; |
| 50 } | 104 } |
| 51 | 105 |
| 106 bool OpenDictionary(const string16& locale) { | |
| 107 hyphenator_.reset(new content::Hyphenator(base::kInvalidPlatformFileValue)); | |
| 108 thread_.reset(new content::MockRenderThread()); | |
| 109 listener_.reset(new MockListener(hyphenator_.get(), locale)); | |
| 110 thread_->sink().AddFilter(listener_.get()); | |
| 111 return hyphenator_->Attach(thread_.get(), locale); | |
| 112 } | |
| 113 | |
| 114 size_t GetMessageCount() const { | |
| 115 return thread_->sink().message_count(); | |
| 116 } | |
| 117 | |
| 52 private: | 118 private: |
| 53 scoped_ptr<content::Hyphenator> hyphenator_; | 119 scoped_ptr<content::Hyphenator> hyphenator_; |
| 120 scoped_ptr<content::MockRenderThread> thread_; | |
| 121 scoped_ptr<MockListener> listener_; | |
| 54 }; | 122 }; |
| 55 | 123 |
| 56 // Verifies that our hyphenator yields the same hyphenated words as the original | 124 // Verifies that our hyphenator yields the same hyphenated words as the original |
| 57 // hyphen library does. | 125 // hyphen library does. |
| 58 TEST_F(HyphenatorTest, HyphenateWords) { | 126 TEST_F(HyphenatorTest, HyphenateWords) { |
| 59 static const struct { | 127 static const struct { |
| 60 const char* input; | 128 const char* input; |
| 61 const char* expected; | 129 const char* expected; |
| 62 } kTestCases[] = { | 130 } kTestCases[] = { |
| 63 { "and", "and" }, | 131 { "and", "and" }, |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 75 { "comfortably", "com-fort-ably"}, | 143 { "comfortably", "com-fort-ably"}, |
| 76 { "declination", "dec-li-na-tion" }, | 144 { "declination", "dec-li-na-tion" }, |
| 77 { "flamingo:", "flamin-go:" }, | 145 { "flamingo:", "flamin-go:" }, |
| 78 { "lination", "lina-tion" }, | 146 { "lination", "lina-tion" }, |
| 79 { "reciprocity", "rec-i-proc-i-ty" }, | 147 { "reciprocity", "rec-i-proc-i-ty" }, |
| 80 { "throughout", "through-out" }, | 148 { "throughout", "through-out" }, |
| 81 { "undid", "un-did" }, | 149 { "undid", "un-did" }, |
| 82 { "undone.", "un-done." }, | 150 { "undone.", "un-done." }, |
| 83 { "unnecessary", "un-nec-es-sary" }, | 151 { "unnecessary", "un-nec-es-sary" }, |
| 84 }; | 152 }; |
| 153 Initialize(); | |
| 85 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) { | 154 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) { |
| 86 string16 input = ASCIIToUTF16(kTestCases[i].input); | 155 string16 input = ASCIIToUTF16(kTestCases[i].input); |
| 87 string16 expected = ASCIIToUTF16(kTestCases[i].expected); | 156 string16 expected = ASCIIToUTF16(kTestCases[i].expected); |
| 88 EXPECT_EQ(expected, Hyphenate(input)); | 157 EXPECT_EQ(expected, Hyphenate(input)); |
| 89 } | 158 } |
| 90 } | 159 } |
| 160 | |
| 161 // Verifies that our hyphenator sends a HyphenatorHostMsg_OpenDictionary | |
| 162 // message to ask a browser to open a dictionary. Also, this test verifies that | |
| 163 // our hyphenator can hyphnate words when the Hyphenator::SetDictionary function | |
| 164 // is called. | |
| 165 TEST_F(HyphenatorTest, openDictionary) { | |
| 166 // Send a HyphenatorHostMsg_OpenDictionary message and verify it is handled by | |
| 167 // our MockListner class. | |
| 168 EXPECT_TRUE(OpenDictionary(string16())); | |
| 169 EXPECT_EQ(0U, GetMessageCount()); | |
| 170 | |
| 171 // Verify that we can now hyphenate words. When the MockListener class | |
| 172 // receives a HyphenatorHostMsg_OpenDictionary message, it calls the | |
| 173 // Hyphenator::SetDictionary function to attach the hyphenation dictionary. | |
| 174 // So, the Hyphenate function should hyphenate words now. | |
| 175 string16 input = ASCIIToUTF16("hyphenation"); | |
| 176 string16 expected = ASCIIToUTF16("hy-phen-ation"); | |
| 177 EXPECT_EQ(expected, Hyphenate(input)); | |
| 178 } | |
| OLD | NEW |