1 // Copyright 2017 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/language/core/browser/baseline_language_model.h"
6 
7 #include <cmath>
8 
9 #include "components/language/core/browser/url_language_histogram.h"
10 #include "components/prefs/pref_registry_simple.h"
11 #include "components/prefs/testing_pref_service.h"
12 #include "testing/gmock/include/gmock/gmock.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 
15 namespace language {
16 
17 using testing::ElementsAre;
18 using Ld = BaselineLanguageModel::LanguageDetails;
19 
20 constexpr static float kFloatEps = 0.00001f;
21 constexpr static char kAcceptPref[] = "intl.accept_languages";
22 
23 class BaselineLanguageModelTest : public testing::Test {
24  protected:
SetUp()25   void SetUp() override {
26     // The URL language histogram and accept language list are inputs to the
27     // baseline model.
28     UrlLanguageHistogram::RegisterProfilePrefs(prefs_.registry());
29     prefs_.registry()->RegisterStringPref(kAcceptPref, std::string());
30   }
31 
32   TestingPrefServiceSimple prefs_;
33 };
34 
35 // Compares LanguageDetails.
36 MATCHER_P(EqualsLd, lang_details, "") {
37   return arg.lang_code == lang_details.lang_code &&
38          std::abs(arg.score - lang_details.score) < kFloatEps;
39 }
40 
41 // Check the minimum model: just a UI language.
TEST_F(BaselineLanguageModelTest,UiOnly)42 TEST_F(BaselineLanguageModelTest, UiOnly) {
43   BaselineLanguageModel model(&prefs_, "en", kAcceptPref);
44   EXPECT_THAT(model.GetLanguages(), ElementsAre(EqualsLd(Ld("en", 1.0f))));
45 }
46 
47 // Check with UI language and language browsing history.
TEST_F(BaselineLanguageModelTest,UiAndHist)48 TEST_F(BaselineLanguageModelTest, UiAndHist) {
49   // Simulate many website visits, as there is a minimum frequency threshold for
50   // histogram languages.
51   UrlLanguageHistogram hist(&prefs_);
52   for (int i = 0; i < 100; ++i) {
53     hist.OnPageVisited("it");
54     hist.OnPageVisited("it");
55     hist.OnPageVisited("de");
56   }
57 
58   BaselineLanguageModel model(&prefs_, "en", kAcceptPref);
59   EXPECT_THAT(model.GetLanguages(), ElementsAre(EqualsLd(Ld("en", 1.0f)),
60                                                 EqualsLd(Ld("it", 1.0f / 2)),
61                                                 EqualsLd(Ld("de", 1.0f / 3))));
62 }
63 
64 // Check with UI language and accept languages.
TEST_F(BaselineLanguageModelTest,UiAndAccept)65 TEST_F(BaselineLanguageModelTest, UiAndAccept) {
66   prefs_.SetString(kAcceptPref, "ja,fr");
67 
68   BaselineLanguageModel model(&prefs_, "en", kAcceptPref);
69   EXPECT_THAT(model.GetLanguages(), ElementsAre(EqualsLd(Ld("en", 1.0f)),
70                                                 EqualsLd(Ld("ja", 1.0f / 2)),
71                                                 EqualsLd(Ld("fr", 1.0f / 3))));
72 }
73 
74 // Check with all three sources.
TEST_F(BaselineLanguageModelTest,UiAndHistAndAccept)75 TEST_F(BaselineLanguageModelTest, UiAndHistAndAccept) {
76   // Simulate many website visits, as there is a minimum frequency threshold for
77   // histogram languages.
78   UrlLanguageHistogram hist(&prefs_);
79   for (int i = 0; i < 100; ++i) {
80     hist.OnPageVisited("it");
81     hist.OnPageVisited("it");
82     hist.OnPageVisited("de");
83   }
84 
85   prefs_.SetString(kAcceptPref, "ja,fr");
86 
87   BaselineLanguageModel model(&prefs_, "en", kAcceptPref);
88   EXPECT_THAT(
89       model.GetLanguages(),
90       ElementsAre(EqualsLd(Ld("en", 1.0f)), EqualsLd(Ld("it", 1.0f / 2)),
91                   EqualsLd(Ld("de", 1.0f / 3)), EqualsLd(Ld("ja", 1.0f / 4)),
92                   EqualsLd(Ld("fr", 1.0f / 5))));
93 }
94 
95 // Check that repeats among sources are ignored.
TEST_F(BaselineLanguageModelTest,Repeats)96 TEST_F(BaselineLanguageModelTest, Repeats) {
97   // Simulate many website visits, as there is a minimum frequency threshold for
98   // histogram languages.
99   UrlLanguageHistogram hist(&prefs_);
100   for (int i = 0; i < 100; ++i) {
101     hist.OnPageVisited("en");
102     hist.OnPageVisited("en");
103     hist.OnPageVisited("it");
104   }
105 
106   prefs_.SetString(kAcceptPref, "en,ja,it");
107 
108   BaselineLanguageModel model(&prefs_, "en", kAcceptPref);
109   EXPECT_THAT(model.GetLanguages(), ElementsAre(EqualsLd(Ld("en", 1.0f)),
110                                                 EqualsLd(Ld("it", 1.0f / 2)),
111                                                 EqualsLd(Ld("ja", 1.0f / 3))));
112 }
113 
114 // Check that regions are not backed off.
TEST_F(BaselineLanguageModelTest,Regions)115 TEST_F(BaselineLanguageModelTest, Regions) {
116   // Simulate many website visits, as there is a minimum frequency threshold for
117   // histogram languages.
118   UrlLanguageHistogram hist(&prefs_);
119   for (int i = 0; i < 100; ++i) {
120     hist.OnPageVisited("en-AU");
121     hist.OnPageVisited("en-AU");
122     hist.OnPageVisited("en-CA");
123   }
124 
125   prefs_.SetString(kAcceptPref, "en-GB");
126 
127   BaselineLanguageModel model(&prefs_, "en", kAcceptPref);
128   EXPECT_THAT(
129       model.GetLanguages(),
130       ElementsAre(EqualsLd(Ld("en", 1.0f)), EqualsLd(Ld("en-AU", 1.0f / 2)),
131                   EqualsLd(Ld("en-CA", 1.0f / 3)),
132                   EqualsLd(Ld("en-GB", 1.0f / 4))));
133 }
134 
135 }  // namespace language
136