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 for HyphenatorHost messages. This class |
| 19 // intercepts a HyphenatorHostMsg_OpenDictionary message sent to an |
| 20 // IPC::TestSink object and emulates the HyphenatorMessageFilter class. |
| 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 OnControllMessageReceived |
| 45 // function with a HyphenatorMsg_SetDictionary message. |
| 46 FilePath dictionary_path; |
| 47 if (!PathService::Get(base::DIR_SOURCE_ROOT, &dictionary_path)) |
| 48 return false; |
| 49 dictionary_path = dictionary_path.AppendASCII("third_party"); |
| 50 dictionary_path = dictionary_path.AppendASCII("hyphen"); |
| 51 dictionary_path = dictionary_path.AppendASCII("hyph_en_US.dic"); |
| 52 base::PlatformFile file = base::CreatePlatformFile( |
| 53 dictionary_path, base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ, |
| 54 NULL, NULL); |
| 55 EXPECT_NE(base::kInvalidPlatformFileValue, file); |
| 56 |
| 57 IPC::Message response( |
| 58 0, HyphenatorMsg_SetDictionary::ID, IPC::Message::PRIORITY_NORMAL); |
| 59 IPC::PlatformFileForTransit transit = IPC::GetFileHandleForProcess( |
| 60 file, GetHandle(), false); |
| 61 IPC::ParamTraits<IPC::PlatformFileForTransit>::Write(&response, transit); |
| 62 hyphenator_->OnControlMessageReceived(response); |
| 63 base::ClosePlatformFile(file); |
| 64 return true; |
| 65 } |
| 66 |
| 67 private: |
| 68 base::ProcessHandle GetHandle() const { |
| 69 return base::Process::Current().handle(); |
| 70 } |
| 71 |
| 72 content::Hyphenator* hyphenator_; |
| 73 string16 locale_; |
| 74 }; |
| 75 |
| 76 } // namespace |
| 77 |
13 // A unit test for our hyphenator. This class loads a sample hyphenation | 78 // A unit test for our hyphenator. This class loads a sample hyphenation |
14 // dictionary and hyphenates words. | 79 // dictionary and hyphenates words. |
15 class HyphenatorTest : public testing::Test { | 80 class HyphenatorTest : public testing::Test { |
16 public: | 81 public: |
17 HyphenatorTest() { | 82 HyphenatorTest() { |
18 Initialize(); | |
19 } | 83 } |
20 | 84 |
21 bool Initialize() { | 85 bool Initialize() { |
22 FilePath dictionary_path; | 86 FilePath dictionary_path; |
23 if (!PathService::Get(base::DIR_SOURCE_ROOT, &dictionary_path)) | 87 if (!PathService::Get(base::DIR_SOURCE_ROOT, &dictionary_path)) |
24 return false; | 88 return false; |
25 dictionary_path = dictionary_path.AppendASCII("third_party"); | 89 dictionary_path = dictionary_path.AppendASCII("third_party"); |
26 dictionary_path = dictionary_path.AppendASCII("hyphen"); | 90 dictionary_path = dictionary_path.AppendASCII("hyphen"); |
27 dictionary_path = dictionary_path.AppendASCII("hyph_en_US.dic"); | 91 dictionary_path = dictionary_path.AppendASCII("hyph_en_US.dic"); |
28 base::PlatformFile file = base::CreatePlatformFile( | 92 base::PlatformFile file = base::CreatePlatformFile( |
(...skipping 13 matching lines...) Expand all Loading... |
42 size_t new_position = hyphenator_->ComputeLastHyphenLocation(word, | 106 size_t new_position = hyphenator_->ComputeLastHyphenLocation(word, |
43 position); | 107 position); |
44 EXPECT_LT(new_position, position); | 108 EXPECT_LT(new_position, position); |
45 if (new_position > 0) | 109 if (new_position > 0) |
46 hyphenated_word.insert(new_position, 1, '-'); | 110 hyphenated_word.insert(new_position, 1, '-'); |
47 position = new_position; | 111 position = new_position; |
48 } | 112 } |
49 return hyphenated_word; | 113 return hyphenated_word; |
50 } | 114 } |
51 | 115 |
| 116 bool OpenDictionary(const string16& locale) { |
| 117 hyphenator_.reset(new content::Hyphenator(base::kInvalidPlatformFileValue)); |
| 118 thread_.reset(new content::MockRenderThread()); |
| 119 listener_.reset(new MockListener(hyphenator_.get(), locale)); |
| 120 thread_->sink().AddFilter(listener_.get()); |
| 121 return hyphenator_->Attach(thread_.get(), locale); |
| 122 } |
| 123 |
| 124 size_t GetMessageCount() const { |
| 125 return thread_->sink().message_count(); |
| 126 } |
| 127 |
52 private: | 128 private: |
53 scoped_ptr<content::Hyphenator> hyphenator_; | 129 scoped_ptr<content::Hyphenator> hyphenator_; |
| 130 scoped_ptr<content::MockRenderThread> thread_; |
| 131 scoped_ptr<MockListener> listener_; |
54 }; | 132 }; |
55 | 133 |
56 // Verifies that our hyphenator yields the same hyphenated words as the original | 134 // Verifies that our hyphenator yields the same hyphenated words as the original |
57 // hyphen library does. | 135 // hyphen library does. |
58 TEST_F(HyphenatorTest, HyphenateWords) { | 136 TEST_F(HyphenatorTest, HyphenateWords) { |
59 static const struct { | 137 static const struct { |
60 const char* input; | 138 const char* input; |
61 const char* expected; | 139 const char* expected; |
62 } kTestCases[] = { | 140 } kTestCases[] = { |
63 { "and", "and" }, | 141 { "and", "and" }, |
(...skipping 11 matching lines...) Expand all Loading... |
75 { "comfortably", "com-fort-ably"}, | 153 { "comfortably", "com-fort-ably"}, |
76 { "declination", "dec-li-na-tion" }, | 154 { "declination", "dec-li-na-tion" }, |
77 { "flamingo:", "flamin-go:" }, | 155 { "flamingo:", "flamin-go:" }, |
78 { "lination", "lina-tion" }, | 156 { "lination", "lina-tion" }, |
79 { "reciprocity", "rec-i-proc-i-ty" }, | 157 { "reciprocity", "rec-i-proc-i-ty" }, |
80 { "throughout", "through-out" }, | 158 { "throughout", "through-out" }, |
81 { "undid", "un-did" }, | 159 { "undid", "un-did" }, |
82 { "undone.", "un-done." }, | 160 { "undone.", "un-done." }, |
83 { "unnecessary", "un-nec-es-sary" }, | 161 { "unnecessary", "un-nec-es-sary" }, |
84 }; | 162 }; |
| 163 Initialize(); |
85 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) { | 164 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) { |
86 string16 input = ASCIIToUTF16(kTestCases[i].input); | 165 string16 input = ASCIIToUTF16(kTestCases[i].input); |
87 string16 expected = ASCIIToUTF16(kTestCases[i].expected); | 166 string16 expected = ASCIIToUTF16(kTestCases[i].expected); |
88 EXPECT_EQ(expected, Hyphenate(input)); | 167 EXPECT_EQ(expected, Hyphenate(input)); |
89 } | 168 } |
90 } | 169 } |
| 170 |
| 171 // Verifies that our hyphenator sends a HyphenatorHostMsg_OpenDictionary |
| 172 // message to ask a browser to open a dictionary. Also, this test verifies that |
| 173 // our hyphenator can hyphnate words when the Hyphenator::SetDictionary function |
| 174 // is called. |
| 175 TEST_F(HyphenatorTest, openDictionary) { |
| 176 // Send a HyphenatorHostMsg_OpenDictionary message and verify it is handled by |
| 177 // our MockListner class. |
| 178 EXPECT_TRUE(OpenDictionary(string16())); |
| 179 EXPECT_EQ(0U, GetMessageCount()); |
| 180 |
| 181 // Verify that we can now hyphenate words. When the MockListener class |
| 182 // receives a HyphenatorHostMsg_OpenDictionary message, it calls the |
| 183 // OnControlMessageReceived function with a HyphenatorMsg_SetDictionary |
| 184 // message. So, the Hyphenate function should be able to hyphenate words now. |
| 185 string16 input = ASCIIToUTF16("hyphenation"); |
| 186 string16 expected = ASCIIToUTF16("hy-phen-ation"); |
| 187 EXPECT_EQ(expected, Hyphenate(input)); |
| 188 } |
OLD | NEW |