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 "webkit/glue/webkit_glue.h" | 5 #include "webkit/glue/webkit_glue.h" |
6 | 6 |
7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
9 #include "base/path_service.h" | 9 #include "base/path_service.h" |
10 #include "base/platform_file.h" | 10 #include "base/platform_file.h" |
11 #include "base/sys_string_conversions.h" | 11 #include "base/sys_string_conversions.h" |
12 #include "base/utf_string_conversions.h" | 12 #include "base/utf_string_conversions.h" |
13 #include "chrome/renderer/spellchecker/spellcheck.h" | 13 #include "chrome/renderer/spellchecker/spellcheck.h" |
14 #include "chrome/common/chrome_paths.h" | 14 #include "chrome/common/chrome_paths.h" |
15 #include "chrome/common/spellcheck_common.h" | 15 #include "chrome/common/spellcheck_common.h" |
16 #include "chrome/common/spellcheck_result.h" | 16 #include "chrome/common/spellcheck_result.h" |
17 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
| 18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebTextCheckingComple
tion.h" |
| 19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebTextCheckingResult
.h" |
18 | 20 |
19 | 21 |
20 namespace { | 22 namespace { |
21 | 23 |
22 FilePath GetHunspellDirectory() { | 24 FilePath GetHunspellDirectory() { |
23 FilePath hunspell_directory; | 25 FilePath hunspell_directory; |
24 if (!PathService::Get(base::DIR_SOURCE_ROOT, &hunspell_directory)) | 26 if (!PathService::Get(base::DIR_SOURCE_ROOT, &hunspell_directory)) |
25 return FilePath(); | 27 return FilePath(); |
26 | 28 |
27 hunspell_directory = hunspell_directory.AppendASCII("third_party"); | 29 hunspell_directory = hunspell_directory.AppendASCII("third_party"); |
28 hunspell_directory = hunspell_directory.AppendASCII("hunspell_dictionaries"); | 30 hunspell_directory = hunspell_directory.AppendASCII("hunspell_dictionaries"); |
29 return hunspell_directory; | 31 return hunspell_directory; |
30 } | 32 } |
31 | 33 |
32 } // namespace | 34 } // namespace |
33 | 35 |
34 class SpellCheckTest : public testing::Test { | 36 class SpellCheckTest : public testing::Test { |
35 public: | 37 public: |
36 SpellCheckTest() { | 38 SpellCheckTest() { |
37 ReinitializeSpellCheck("en-US"); | 39 ReinitializeSpellCheck("en-US"); |
38 } | 40 } |
39 | 41 |
40 void ReinitializeSpellCheck(const std::string& language) { | 42 void ReinitializeSpellCheck(const std::string& language) { |
41 spell_check_.reset(new SpellCheck()); | 43 spell_check_.reset(new SpellCheck()); |
| 44 InitializeSpellCheck(language); |
| 45 } |
42 | 46 |
| 47 void UninitializeSpellCheck() { |
| 48 spell_check_.reset(new SpellCheck()); |
| 49 } |
| 50 |
| 51 void InitializeSpellCheck(const std::string& language) { |
43 FilePath hunspell_directory = GetHunspellDirectory(); | 52 FilePath hunspell_directory = GetHunspellDirectory(); |
44 EXPECT_FALSE(hunspell_directory.empty()); | 53 EXPECT_FALSE(hunspell_directory.empty()); |
45 base::PlatformFile file = base::CreatePlatformFile( | 54 base::PlatformFile file = base::CreatePlatformFile( |
46 SpellCheckCommon::GetVersionedFileName(language, hunspell_directory), | 55 SpellCheckCommon::GetVersionedFileName(language, hunspell_directory), |
47 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ, NULL, NULL); | 56 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ, NULL, NULL); |
48 spell_check_->Init( | 57 spell_check_->Init( |
49 file, std::vector<std::string>(), language); | 58 file, std::vector<std::string>(), language); |
50 } | 59 } |
51 | 60 |
52 virtual ~SpellCheckTest() { | 61 virtual ~SpellCheckTest() { |
53 } | 62 } |
54 | 63 |
55 SpellCheck* spell_check() { return spell_check_.get(); } | 64 SpellCheck* spell_check() { return spell_check_.get(); } |
56 | 65 |
57 #if !defined(OS_MACOSX) | 66 #if !defined(OS_MACOSX) |
58 protected: | 67 protected: |
59 void TestSpellCheckParagraph( | 68 void TestSpellCheckParagraph( |
60 const string16& input, | 69 const string16& input, |
61 const std::vector<SpellCheckResult>& expected) { | 70 const std::vector<SpellCheckResult>& expected) { |
62 std::vector<SpellCheckResult> results; | 71 std::vector<SpellCheckResult> results; |
63 spell_check()->SpellCheckParagraph(input, | 72 spell_check()->SpellCheckParagraph(input, |
64 0, | |
65 &results); | 73 &results); |
66 | 74 |
67 EXPECT_EQ(results.size(), expected.size()); | 75 EXPECT_EQ(results.size(), expected.size()); |
68 size_t size = std::min(results.size(), expected.size()); | 76 size_t size = std::min(results.size(), expected.size()); |
69 for (size_t j = 0; j < size; ++j) { | 77 for (size_t j = 0; j < size; ++j) { |
70 EXPECT_EQ(results[j].type, SpellCheckResult::SPELLING); | 78 EXPECT_EQ(results[j].type, SpellCheckResult::SPELLING); |
71 EXPECT_EQ(results[j].location, expected[j].location); | 79 EXPECT_EQ(results[j].location, expected[j].location); |
72 EXPECT_EQ(results[j].length, expected[j].length); | 80 EXPECT_EQ(results[j].length, expected[j].length); |
73 } | 81 } |
74 } | 82 } |
75 #endif | 83 #endif |
76 | 84 |
77 private: | 85 private: |
78 scoped_ptr<SpellCheck> spell_check_; | 86 scoped_ptr<SpellCheck> spell_check_; |
| 87 MessageLoop loop; |
| 88 }; |
| 89 |
| 90 // A fake completion object for verification. |
| 91 class MockTextCheckingCompletion : public WebKit::WebTextCheckingCompletion { |
| 92 public: |
| 93 MockTextCheckingCompletion() |
| 94 : completion_count_(0) { |
| 95 } |
| 96 |
| 97 virtual void didFinishCheckingText( |
| 98 const WebKit::WebVector<WebKit::WebTextCheckingResult>& results) { |
| 99 completion_count_++; |
| 100 last_results_ = results; |
| 101 } |
| 102 |
| 103 size_t completion_count_; |
| 104 WebKit::WebVector<WebKit::WebTextCheckingResult> last_results_; |
79 }; | 105 }; |
80 | 106 |
81 // Operates unit tests for the webkit_glue::SpellCheckWord() function | 107 // Operates unit tests for the webkit_glue::SpellCheckWord() function |
82 // with the US English dictionary. | 108 // with the US English dictionary. |
83 // The unit tests in this function consist of: | 109 // The unit tests in this function consist of: |
84 // * Tests for the function with empty strings; | 110 // * Tests for the function with empty strings; |
85 // * Tests for the function with a valid English word; | 111 // * Tests for the function with a valid English word; |
86 // * Tests for the function with a valid non-English word; | 112 // * Tests for the function with a valid non-English word; |
87 // * Tests for the function with a valid English word with a preceding | 113 // * Tests for the function with a valid English word with a preceding |
88 // space character; | 114 // space character; |
(...skipping 712 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
801 SpellCheckResult::SPELLING, 135, 3)); | 827 SpellCheckResult::SPELLING, 135, 3)); |
802 expected.push_back(SpellCheckResult( | 828 expected.push_back(SpellCheckResult( |
803 SpellCheckResult::SPELLING, 163, 3)); | 829 SpellCheckResult::SPELLING, 163, 3)); |
804 expected.push_back(SpellCheckResult( | 830 expected.push_back(SpellCheckResult( |
805 SpellCheckResult::SPELLING, 195, 3)); | 831 SpellCheckResult::SPELLING, 195, 3)); |
806 expected.push_back(SpellCheckResult( | 832 expected.push_back(SpellCheckResult( |
807 SpellCheckResult::SPELLING, 298, 3)); | 833 SpellCheckResult::SPELLING, 298, 3)); |
808 | 834 |
809 TestSpellCheckParagraph(text, expected); | 835 TestSpellCheckParagraph(text, expected); |
810 } | 836 } |
| 837 |
| 838 // We also skip RequestSpellCheck tests on Mac, because a system spellchecker |
| 839 // is used on Mac instead of SpellCheck::RequestTextChecking. |
| 840 |
| 841 // Make sure RequestTextChecking does not crash if input is empty. |
| 842 TEST_F(SpellCheckTest, RequestSpellCheckWithEmptyString) { |
| 843 MockTextCheckingCompletion completion; |
| 844 |
| 845 const string16 text = ASCIIToUTF16(""); |
| 846 spell_check()->RequestTextChecking(text, 0, &completion); |
| 847 |
| 848 MessageLoop::current()->RunAllPending(); |
| 849 |
| 850 EXPECT_EQ(completion.completion_count_, 1U); |
| 851 } |
| 852 |
| 853 // A simple test case having no misspellings. |
| 854 TEST_F(SpellCheckTest, RequestSpellCheckWithoutMisspelling) { |
| 855 MockTextCheckingCompletion completion; |
| 856 |
| 857 const string16 text = ASCIIToUTF16("hello"); |
| 858 spell_check()->RequestTextChecking(text, 0, &completion); |
| 859 |
| 860 MessageLoop::current()->RunAllPending(); |
| 861 |
| 862 EXPECT_EQ(completion.completion_count_, 1U); |
| 863 } |
| 864 |
| 865 // A simple test case having one misspelling. |
| 866 TEST_F(SpellCheckTest, RequestSpellCheckWithSingleMisspelling) { |
| 867 MockTextCheckingCompletion completion; |
| 868 |
| 869 const string16 text = ASCIIToUTF16("apple, zz"); |
| 870 spell_check()->RequestTextChecking(text, 0, &completion); |
| 871 |
| 872 MessageLoop::current()->RunAllPending(); |
| 873 |
| 874 EXPECT_EQ(completion.completion_count_, 1U); |
| 875 EXPECT_EQ(completion.last_results_.size(), 1U); |
| 876 EXPECT_EQ(completion.last_results_[0].location, 7); |
| 877 EXPECT_EQ(completion.last_results_[0].length, 2); |
| 878 } |
| 879 |
| 880 // A simple test case having a few misspellings. |
| 881 TEST_F(SpellCheckTest, RequestSpellCheckWithMisspellings) { |
| 882 MockTextCheckingCompletion completion; |
| 883 |
| 884 const string16 text = ASCIIToUTF16("apple, zz, orange, zz"); |
| 885 spell_check()->RequestTextChecking(text, 0, &completion); |
| 886 |
| 887 MessageLoop::current()->RunAllPending(); |
| 888 |
| 889 EXPECT_EQ(completion.completion_count_, 1U); |
| 890 EXPECT_EQ(completion.last_results_.size(), 2U); |
| 891 EXPECT_EQ(completion.last_results_[0].location, 7); |
| 892 EXPECT_EQ(completion.last_results_[0].length, 2); |
| 893 EXPECT_EQ(completion.last_results_[1].location, 19); |
| 894 EXPECT_EQ(completion.last_results_[1].length, 2); |
| 895 } |
| 896 |
| 897 // A test case that multiple requests comes at once. Make sure all |
| 898 // requests are processed. |
| 899 TEST_F(SpellCheckTest, RequestSpellCheckWithMultipleRequests) { |
| 900 MockTextCheckingCompletion completion[3]; |
| 901 |
| 902 const string16 text[3] = { |
| 903 ASCIIToUTF16("what, zz"), |
| 904 ASCIIToUTF16("apple, zz"), |
| 905 ASCIIToUTF16("orange, zz") |
| 906 }; |
| 907 |
| 908 for (int i = 0; i < 3; ++i) |
| 909 spell_check()->RequestTextChecking(text[i], 0, &completion[i]); |
| 910 |
| 911 MessageLoop::current()->RunAllPending(); |
| 912 |
| 913 for (int i = 0; i < 3; ++i) { |
| 914 EXPECT_EQ(completion[i].completion_count_, 1U); |
| 915 EXPECT_EQ(completion[i].last_results_.size(), 1U); |
| 916 EXPECT_EQ(completion[i].last_results_[0].location, 6 + i); |
| 917 EXPECT_EQ(completion[i].last_results_[0].length, 2); |
| 918 } |
| 919 } |
| 920 |
| 921 // A test case that spellchecking is requested before initializing. |
| 922 // In this case, we postpone to post a request. |
| 923 TEST_F(SpellCheckTest, RequestSpellCheckWithoutInitialization) { |
| 924 UninitializeSpellCheck(); |
| 925 |
| 926 MockTextCheckingCompletion completion; |
| 927 const string16 text = ASCIIToUTF16("zz"); |
| 928 |
| 929 spell_check()->RequestTextChecking(text, 0, &completion); |
| 930 |
| 931 // The task will not be posted yet. |
| 932 MessageLoop::current()->RunAllPending(); |
| 933 EXPECT_EQ(completion.completion_count_, 0U); |
| 934 } |
| 935 |
| 936 // Requests several spellchecking before initializing. Except the last one, |
| 937 // posting requests is cancelled and text is rendered as correct one. |
| 938 TEST_F(SpellCheckTest, RequestSpellCheckMultipleTimesWithoutInitialization) { |
| 939 UninitializeSpellCheck(); |
| 940 |
| 941 MockTextCheckingCompletion completion[3]; |
| 942 const string16 text[3] = { |
| 943 ASCIIToUTF16("what, zz"), |
| 944 ASCIIToUTF16("apple, zz"), |
| 945 ASCIIToUTF16("orange, zz") |
| 946 }; |
| 947 |
| 948 // Calls RequestTextchecking a few times. |
| 949 for (int i = 0; i < 3; ++i) |
| 950 spell_check()->RequestTextChecking(text[i], 0, &completion[i]); |
| 951 |
| 952 // The last task will be posted after initialization, however the other |
| 953 // requests should be pressed without spellchecking. |
| 954 MessageLoop::current()->RunAllPending(); |
| 955 for (int i = 0; i < 2; ++i) |
| 956 EXPECT_EQ(completion[i].completion_count_, 1U); |
| 957 EXPECT_EQ(completion[2].completion_count_, 0U); |
| 958 |
| 959 // Checks the last request is processed after initialization. |
| 960 InitializeSpellCheck("en-US"); |
| 961 |
| 962 // Calls PostDelayedSpellCheckTask instead of OnInit here for simplicity. |
| 963 spell_check()->PostDelayedSpellCheckTask(); |
| 964 MessageLoop::current()->RunAllPending(); |
| 965 for (int i = 0; i < 3; ++i) |
| 966 EXPECT_EQ(completion[i].completion_count_, 1U); |
| 967 } |
| 968 |
811 #endif | 969 #endif |
OLD | NEW |