blob: c79ebe14c66547b6739b8fa3874e701de99d9d85 [file] [log] [blame]
Siye Liude74ce302019-06-20 20:44:431// Copyright 2019 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 "components/spellcheck/browser/spellcheck_platform.h"
6
7#include <stddef.h>
8
9#include "base/bind.h"
10#include "base/run_loop.h"
11#include "base/single_thread_task_runner.h"
12#include "base/stl_util.h"
13#include "base/strings/string_util.h"
14#include "base/strings/utf_string_conversions.h"
Guillaume Jenkinsac67c3072020-01-28 17:36:5715#include "base/task/post_task.h"
Gabriel Charettedd8d5985e2020-02-26 18:38:3516#include "base/task/thread_pool.h"
Siye Liude74ce302019-06-20 20:44:4317#include "base/test/scoped_feature_list.h"
Gabriel Charettec7108742019-08-23 03:31:4018#include "base/test/task_environment.h"
Siye Liude74ce302019-06-20 20:44:4319#include "base/win/windows_version.h"
Guillaume Jenkins03764e1b2020-01-17 21:47:5920#include "build/build_config.h"
Guillaume Jenkinsac67c3072020-01-28 17:36:5721#include "components/spellcheck/browser/windows_spell_checker.h"
Siye Liude74ce302019-06-20 20:44:4322#include "components/spellcheck/common/spellcheck_features.h"
23#include "components/spellcheck/common/spellcheck_result.h"
Guillaume Jenkins03764e1b2020-01-17 21:47:5924#include "components/spellcheck/spellcheck_buildflags.h"
Siye Liude74ce302019-06-20 20:44:4325#include "content/public/test/test_utils.h"
26#include "testing/gtest/include/gtest/gtest.h"
27
28namespace {
29
Guillaume Jenkinsac67c3072020-01-28 17:36:5730class WindowsSpellCheckerTest : public testing::Test {
Siye Liude74ce302019-06-20 20:44:4331 public:
Guillaume Jenkinsac67c3072020-01-28 17:36:5732 WindowsSpellCheckerTest() {
33 if (spellcheck::WindowsVersionSupportsSpellchecker()) {
Guillaume Jenkins4346eb42020-02-18 17:50:5834 feature_list_.InitAndEnableFeature(
35 spellcheck::kWinUseBrowserSpellChecker);
36
Guillaume Jenkinsac67c3072020-01-28 17:36:5737 win_spell_checker_ = std::make_unique<WindowsSpellChecker>(
Gabriel Charettedd8d5985e2020-02-26 18:38:3538 base::ThreadPool::CreateCOMSTATaskRunner({base::MayBlock()}));
Guillaume Jenkins4346eb42020-02-18 17:50:5839
40 win_spell_checker_->CreateSpellChecker(
41 "en-US", base::BindOnce(
42 &WindowsSpellCheckerTest::SetLanguageCompletionCallback,
43 base::Unretained(this)));
44
45 RunUntilResultReceived();
Guillaume Jenkinsac67c3072020-01-28 17:36:5746 }
47 }
48
Siye Liude74ce302019-06-20 20:44:4349 void RunUntilResultReceived() {
50 if (callback_finished_)
51 return;
52 base::RunLoop run_loop;
53 quit_ = run_loop.QuitClosure();
54 run_loop.Run();
55
56 // reset status
57 callback_finished_ = false;
58 }
59
60 void SetLanguageCompletionCallback(bool result) {
61 set_language_result_ = result;
62 callback_finished_ = true;
63 if (quit_)
64 std::move(quit_).Run();
65 }
66
67 void TextCheckCompletionCallback(
68 const std::vector<SpellCheckResult>& results) {
69 callback_finished_ = true;
70 spell_check_results_ = results;
71 if (quit_)
72 std::move(quit_).Run();
73 }
74
Guillaume Jenkinse00ab0b2020-01-07 22:08:5975#if BUILDFLAG(USE_WIN_HYBRID_SPELLCHECKER)
76 void PerLanguageSuggestionsCompletionCallback(
Guillaume Jenkinse0718052019-12-19 20:06:5077 const spellcheck::PerLanguageSuggestions& suggestions) {
78 callback_finished_ = true;
Guillaume Jenkinse00ab0b2020-01-07 22:08:5979 per_language_suggestions_ = suggestions;
Guillaume Jenkinse0718052019-12-19 20:06:5080 if (quit_)
81 std::move(quit_).Run();
82 }
Guillaume Jenkinse00ab0b2020-01-07 22:08:5983#endif // BUILDFLAG(USE_WIN_HYBRID_SPELLCHECKER)
Guillaume Jenkinse0718052019-12-19 20:06:5084
Siye Liude74ce302019-06-20 20:44:4385 protected:
Guillaume Jenkinsac67c3072020-01-28 17:36:5786 std::unique_ptr<WindowsSpellChecker> win_spell_checker_;
87
Siye Liude74ce302019-06-20 20:44:4388 bool callback_finished_ = false;
Guillaume Jenkinsac67c3072020-01-28 17:36:5789 base::OnceClosure quit_;
Guillaume Jenkins4346eb42020-02-18 17:50:5890 base::test::ScopedFeatureList feature_list_;
Siye Liude74ce302019-06-20 20:44:4391
92 bool set_language_result_;
93 std::vector<SpellCheckResult> spell_check_results_;
Guillaume Jenkinse00ab0b2020-01-07 22:08:5994#if BUILDFLAG(USE_WIN_HYBRID_SPELLCHECKER)
95 spellcheck::PerLanguageSuggestions per_language_suggestions_;
96#endif // BUILDFLAG(USE_WIN_HYBRID_SPELLCHECKER)
Siye Liude74ce302019-06-20 20:44:4397
Gabriel Charettedfa36042019-08-19 17:30:1198 base::test::TaskEnvironment task_environment_{
99 base::test::TaskEnvironment::MainThreadType::UI};
Siye Liude74ce302019-06-20 20:44:43100};
101
Guillaume Jenkins4346eb42020-02-18 17:50:58102TEST_F(WindowsSpellCheckerTest, RequestTextCheck) {
Guillaume Jenkinse0718052019-12-19 20:06:50103 if (!spellcheck::WindowsVersionSupportsSpellchecker()) {
Siye Liude74ce302019-06-20 20:44:43104 return;
Guillaume Jenkinse0718052019-12-19 20:06:50105 }
Siye Liude74ce302019-06-20 20:44:43106
Guillaume Jenkins4346eb42020-02-18 17:50:58107 ASSERT_TRUE(set_language_result_);
Siye Liude74ce302019-06-20 20:44:43108
Guillaume Jenkins4346eb42020-02-18 17:50:58109 static const struct {
110 const char* text_to_check;
111 const char* expected_suggestion;
112 } kTestCases[] = {
113 {"absense", "absence"}, {"becomeing", "becoming"},
114 {"cieling", "ceiling"}, {"definate", "definite"},
115 {"eigth", "eight"}, {"exellent", "excellent"},
116 {"finaly", "finally"}, {"garantee", "guarantee"},
117 {"humerous", "humorous"}, {"imediately", "immediately"},
118 {"jellous", "jealous"}, {"knowlege", "knowledge"},
119 {"lenght", "length"}, {"manuever", "maneuver"},
120 {"naturaly", "naturally"}, {"ommision", "omission"},
121 };
Siye Liude74ce302019-06-20 20:44:43122
Guillaume Jenkins4346eb42020-02-18 17:50:58123 for (size_t i = 0; i < base::size(kTestCases); ++i) {
124 const auto& test_case = kTestCases[i];
125 const base::string16 word(base::ASCIIToUTF16(test_case.text_to_check));
126
127 // Check if the suggested words occur.
128 win_spell_checker_->RequestTextCheck(
129 1, word,
130 base::BindOnce(&WindowsSpellCheckerTest::TextCheckCompletionCallback,
131 base::Unretained(this)));
132 RunUntilResultReceived();
133
134 ASSERT_EQ(1u, spell_check_results_.size())
135 << "RequestTextCheckTests case " << i << ": Wrong number of results";
136
137 const std::vector<base::string16>& suggestions =
138 spell_check_results_.front().replacements;
139 const base::string16 suggested_word(
140 base::ASCIIToUTF16(test_case.expected_suggestion));
141 auto position =
142 std::find_if(suggestions.begin(), suggestions.end(),
143 [&](const base::string16& suggestion) {
144 return suggestion.compare(suggested_word) == 0;
145 });
146
147 ASSERT_NE(suggestions.end(), position) << "RequestTextCheckTests case " << i
148 << ": Expected suggestion not found";
149 }
150}
151
Guillaume Jenkinse0718052019-12-19 20:06:50152#if BUILDFLAG(USE_WIN_HYBRID_SPELLCHECKER)
Guillaume Jenkins4346eb42020-02-18 17:50:58153TEST_F(WindowsSpellCheckerTest, GetPerLanguageSuggestions) {
154 if (!spellcheck::WindowsVersionSupportsSpellchecker()) {
155 return;
156 }
157
158 ASSERT_TRUE(set_language_result_);
159
160 win_spell_checker_->GetPerLanguageSuggestions(
161 base::ASCIIToUTF16("tihs"),
162 base::BindOnce(
163 &WindowsSpellCheckerTest::PerLanguageSuggestionsCompletionCallback,
164 base::Unretained(this)));
165 RunUntilResultReceived();
166
167 ASSERT_EQ(per_language_suggestions_.size(), 1u);
168 ASSERT_GT(per_language_suggestions_[0].size(), 0u);
Siye Liude74ce302019-06-20 20:44:43169}
Guillaume Jenkins4346eb42020-02-18 17:50:58170#endif // BUILDFLAG(USE_WIN_HYBRID_SPELLCHECKER)
Siye Liude74ce302019-06-20 20:44:43171
172} // namespace