1 // 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/omnibox/browser/on_device_head_model.h"
6
7 #include "base/files/file_path.h"
8 #include "base/files/file_util.h"
9 #include "base/path_service.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "build/build_config.h"
12 #include "testing/gmock/include/gmock/gmock.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 using testing::ElementsAre;
16 using testing::Pair;
17
18 namespace {
19
20 // The test head model used for unittests contains 14 queries and their scores
21 // shown below; the test model uses 3-bytes address and 2-bytes score so the
22 // highest score is 32767:
23 // ----------------------
24 // Query Score
25 // ----------------------
26 // g 32767
27 // gmail 32766
28 // google maps 32765
29 // google 32764
30 // get out 32763
31 // googler 32762
32 // gamestop 32761
33 // maps 32761
34 // mail 32760
35 // map 32759
36 // 谷歌 32759
37 // ガツガツしてる人 32759
38 // 비데 두꺼비 32759
39 // переводчик 32759
40 // ----------------------
41 // The tree structure for queries above is similar as this:
42 // [ g | ma | 谷歌 | ガツガツしてる人| 비데 두꺼비 | переводчик ]
43 // | |
44 // | [ p | il ]
45 // | |
46 // | [ # | s ]
47 // |
48 // [ # | oogle | mail | et out | amestop ]
49 // |
50 // [ # | _maps | er ]
51
GetTestModelPath()52 base::FilePath GetTestModelPath() {
53 base::FilePath file_path;
54 base::PathService::Get(base::DIR_SOURCE_ROOT, &file_path);
55 file_path = file_path.AppendASCII(
56 "components/test/data/omnibox/on_device_head_test_model_index.bin");
57 return file_path;
58 }
59
60 } // namespace
61
62 class OnDeviceHeadModelTest : public testing::Test {
63 protected:
SetUp()64 void SetUp() override {
65 base::FilePath file_path = GetTestModelPath();
66 ASSERT_TRUE(base::PathExists(file_path));
67 #if defined(OS_WIN)
68 model_filename_ = base::WideToUTF8(file_path.value());
69 #else
70 model_filename_ = file_path.value();
71 #endif
72 ASSERT_FALSE(model_filename_.empty());
73 }
74
TearDown()75 void TearDown() override { model_filename_.clear(); }
76
77 std::string model_filename_;
78 };
79
TEST_F(OnDeviceHeadModelTest,GetSuggestions)80 TEST_F(OnDeviceHeadModelTest, GetSuggestions) {
81 auto suggestions =
82 OnDeviceHeadModel::GetSuggestionsForPrefix(model_filename_, 4, "go");
83 EXPECT_THAT(suggestions,
84 ElementsAre(Pair("google maps", 32765), Pair("google", 32764),
85 Pair("googler", 32762)));
86
87 suggestions =
88 OnDeviceHeadModel::GetSuggestionsForPrefix(model_filename_, 4, "ge");
89 EXPECT_THAT(suggestions, ElementsAre(Pair("get out", 32763)));
90
91 suggestions =
92 OnDeviceHeadModel::GetSuggestionsForPrefix(model_filename_, 4, "ga");
93 EXPECT_THAT(suggestions, ElementsAre(Pair("gamestop", 32761)));
94 }
95
TEST_F(OnDeviceHeadModelTest,NoMatch)96 TEST_F(OnDeviceHeadModelTest, NoMatch) {
97 auto suggestions =
98 OnDeviceHeadModel::GetSuggestionsForPrefix(model_filename_, 4, "x");
99 EXPECT_TRUE(suggestions.empty());
100 }
101
TEST_F(OnDeviceHeadModelTest,MatchTheEndOfSuggestion)102 TEST_F(OnDeviceHeadModelTest, MatchTheEndOfSuggestion) {
103 auto suggestions =
104 OnDeviceHeadModel::GetSuggestionsForPrefix(model_filename_, 4, "ap");
105 EXPECT_TRUE(suggestions.empty());
106 }
107
TEST_F(OnDeviceHeadModelTest,MatchAtTheMiddleOfSuggestion)108 TEST_F(OnDeviceHeadModelTest, MatchAtTheMiddleOfSuggestion) {
109 auto suggestions =
110 OnDeviceHeadModel::GetSuggestionsForPrefix(model_filename_, 4, "st");
111 EXPECT_TRUE(suggestions.empty());
112 }
113
TEST_F(OnDeviceHeadModelTest,EmptyInput)114 TEST_F(OnDeviceHeadModelTest, EmptyInput) {
115 auto suggestions =
116 OnDeviceHeadModel::GetSuggestionsForPrefix(model_filename_, 4, "");
117 EXPECT_TRUE(suggestions.empty());
118 }
119
TEST_F(OnDeviceHeadModelTest,SetMaxSuggestionsToReturn)120 TEST_F(OnDeviceHeadModelTest, SetMaxSuggestionsToReturn) {
121 auto suggestions =
122 OnDeviceHeadModel::GetSuggestionsForPrefix(model_filename_, 5, "g");
123 EXPECT_THAT(suggestions,
124 ElementsAre(Pair("g", 32767), Pair("gmail", 32766),
125 Pair("google maps", 32765), Pair("google", 32764),
126 Pair("get out", 32763)));
127
128 suggestions =
129 OnDeviceHeadModel::GetSuggestionsForPrefix(model_filename_, 2, "ma");
130 EXPECT_THAT(suggestions,
131 ElementsAre(Pair("maps", 32761), Pair("mail", 32760)));
132 }
133
TEST_F(OnDeviceHeadModelTest,NonEnglishLanguage)134 TEST_F(OnDeviceHeadModelTest, NonEnglishLanguage) {
135 // Chinese.
136 auto suggestions =
137 OnDeviceHeadModel::GetSuggestionsForPrefix(model_filename_, 4, "谷");
138 EXPECT_THAT(suggestions, ElementsAre(Pair("谷歌", 32759)));
139
140 // Japanese.
141 suggestions = OnDeviceHeadModel::GetSuggestionsForPrefix(model_filename_, 4,
142 "ガツガツ");
143 EXPECT_THAT(suggestions, ElementsAre(Pair("ガツガツしてる人", 32759)));
144
145 // Korean.
146 suggestions =
147 OnDeviceHeadModel::GetSuggestionsForPrefix(model_filename_, 4, "비데 ");
148 EXPECT_THAT(suggestions, ElementsAre(Pair("비데 두꺼비", 32759)));
149
150 // Russian.
151 suggestions =
152 OnDeviceHeadModel::GetSuggestionsForPrefix(model_filename_, 4, "пере");
153 EXPECT_THAT(suggestions, ElementsAre(Pair("переводчик", 32759)));
154 }
155