| OLD | NEW | 
|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "chrome/browser/about_flags.h" | 5 #include "chrome/browser/about_flags.h" | 
| 6 | 6 | 
| 7 #include <stdint.h> | 7 #include <map> | 
| 8 #include <utility> | 8 #include <set> | 
|  | 9 #include <string> | 
| 9 | 10 | 
| 10 #include "base/feature_list.h" | 11 #include "base/feature_list.h" | 
| 11 #include "base/files/file_path.h" | 12 #include "base/files/file_path.h" | 
| 12 #include "base/format_macros.h" | 13 #include "base/format_macros.h" | 
| 13 #include "base/path_service.h" | 14 #include "base/path_service.h" | 
| 14 #include "base/prefs/pref_registry_simple.h" |  | 
| 15 #include "base/prefs/testing_pref_service.h" |  | 
| 16 #include "base/strings/string_number_conversions.h" | 15 #include "base/strings/string_number_conversions.h" | 
| 17 #include "base/strings/string_split.h" |  | 
| 18 #include "base/strings/stringprintf.h" | 16 #include "base/strings/stringprintf.h" | 
| 19 #include "base/strings/utf_string_conversions.h" | 17 #include "base/strings/utf_string_conversions.h" | 
| 20 #include "base/values.h" | 18 #include "base/values.h" | 
| 21 #include "chrome/common/chrome_switches.h" | 19 #include "components/flags_ui/feature_entry.h" | 
| 22 #include "chrome/grit/chromium_strings.h" |  | 
| 23 #include "components/flags_ui/flags_ui_pref_names.h" |  | 
| 24 #include "components/flags_ui/pref_service_flags_storage.h" |  | 
| 25 #include "content/public/common/content_switches.h" |  | 
| 26 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" | 
| 27 #include "third_party/libxml/chromium/libxml_utils.h" | 21 #include "third_party/libxml/chromium/libxml_utils.h" | 
| 28 | 22 | 
| 29 using flags_ui::FeatureEntry; |  | 
| 30 |  | 
| 31 namespace about_flags { | 23 namespace about_flags { | 
| 32 | 24 | 
| 33 namespace { | 25 namespace { | 
| 34 | 26 | 
| 35 const char kFlags1[] = "flag1"; |  | 
| 36 const char kFlags2[] = "flag2"; |  | 
| 37 const char kFlags3[] = "flag3"; |  | 
| 38 const char kFlags4[] = "flag4"; |  | 
| 39 const char kFlags5[] = "flag5"; |  | 
| 40 const char kFlags6[] = "flag6"; |  | 
| 41 const char kFlags7[] = "flag7"; |  | 
| 42 |  | 
| 43 const char kSwitch1[] = "switch"; |  | 
| 44 const char kSwitch2[] = "switch2"; |  | 
| 45 const char kSwitch3[] = "switch3"; |  | 
| 46 const char kSwitch6[] = "switch6"; |  | 
| 47 const char kValueForSwitch2[] = "value_for_switch2"; |  | 
| 48 |  | 
| 49 const char kMultiSwitch1[] = "multi_switch1"; |  | 
| 50 const char kMultiSwitch2[] = "multi_switch2"; |  | 
| 51 const char kValueForMultiSwitch2[] = "value_for_multi_switch2"; |  | 
| 52 |  | 
| 53 const char kEnableDisableValue1[] = "value1"; |  | 
| 54 const char kEnableDisableValue2[] = "value2"; |  | 
| 55 |  | 
| 56 typedef base::HistogramBase::Sample Sample; | 27 typedef base::HistogramBase::Sample Sample; | 
| 57 typedef std::map<std::string, Sample> SwitchToIdMap; | 28 typedef std::map<std::string, Sample> SwitchToIdMap; | 
| 58 | 29 | 
| 59 // This is a helper function to the ReadEnumFromHistogramsXml(). | 30 // This is a helper function to the ReadEnumFromHistogramsXml(). | 
| 60 // Extracts single enum (with integer values) from histograms.xml. | 31 // Extracts single enum (with integer values) from histograms.xml. | 
| 61 // Expects |reader| to point at given enum. | 32 // Expects |reader| to point at given enum. | 
| 62 // Returns map { value => label }. | 33 // Returns map { value => label }. | 
| 63 // Returns empty map on error. | 34 // Returns empty map on error. | 
| 64 std::map<Sample, std::string> ParseEnumFromHistogramsXml( | 35 std::map<Sample, std::string> ParseEnumFromHistogramsXml( | 
| 65     const std::string& enum_name, | 36     const std::string& enum_name, | 
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 192   return path; | 163   return path; | 
| 193 #endif | 164 #endif | 
| 194 } | 165 } | 
| 195 | 166 | 
| 196 // Get all associated switches corresponding to defined about_flags.cc entries. | 167 // Get all associated switches corresponding to defined about_flags.cc entries. | 
| 197 // Does not include information about FEATURE_VALUE entries. | 168 // Does not include information about FEATURE_VALUE entries. | 
| 198 std::set<std::string> GetAllSwitchesForTesting() { | 169 std::set<std::string> GetAllSwitchesForTesting() { | 
| 199   std::set<std::string> result; | 170   std::set<std::string> result; | 
| 200 | 171 | 
| 201   size_t num_entries = 0; | 172   size_t num_entries = 0; | 
| 202   const FeatureEntry* entries = | 173   const flags_ui::FeatureEntry* entries = | 
| 203       testing::GetFeatureEntries(&num_entries); | 174       testing::GetFeatureEntries(&num_entries); | 
| 204 | 175 | 
| 205   for (size_t i = 0; i < num_entries; ++i) { | 176   for (size_t i = 0; i < num_entries; ++i) { | 
| 206     const FeatureEntry& entry = entries[i]; | 177     const flags_ui::FeatureEntry& entry = entries[i]; | 
| 207     switch (entry.type) { | 178     switch (entry.type) { | 
| 208       case FeatureEntry::SINGLE_VALUE: | 179       case flags_ui::FeatureEntry::SINGLE_VALUE: | 
| 209       case FeatureEntry::SINGLE_DISABLE_VALUE: | 180       case flags_ui::FeatureEntry::SINGLE_DISABLE_VALUE: | 
| 210         result.insert(entry.command_line_switch); | 181         result.insert(entry.command_line_switch); | 
| 211         break; | 182         break; | 
| 212       case FeatureEntry::MULTI_VALUE: | 183       case flags_ui::FeatureEntry::MULTI_VALUE: | 
| 213         for (int j = 0; j < entry.num_choices; ++j) { | 184         for (int j = 0; j < entry.num_choices; ++j) { | 
| 214           result.insert(entry.choices[j].command_line_switch); | 185           result.insert(entry.choices[j].command_line_switch); | 
| 215         } | 186         } | 
| 216         break; | 187         break; | 
| 217       case FeatureEntry::ENABLE_DISABLE_VALUE: | 188       case flags_ui::FeatureEntry::ENABLE_DISABLE_VALUE: | 
| 218         result.insert(entry.command_line_switch); | 189         result.insert(entry.command_line_switch); | 
| 219         result.insert(entry.disable_command_line_switch); | 190         result.insert(entry.disable_command_line_switch); | 
| 220         break; | 191         break; | 
| 221       case FeatureEntry::FEATURE_VALUE: | 192       case flags_ui::FeatureEntry::FEATURE_VALUE: | 
| 222         break; | 193         break; | 
| 223     } | 194     } | 
| 224   } | 195   } | 
| 225   return result; | 196   return result; | 
| 226 } | 197 } | 
| 227 | 198 | 
| 228 }  // anonymous namespace | 199 }  // anonymous namespace | 
| 229 | 200 | 
| 230 const FeatureEntry::Choice kMultiChoices[] = { |  | 
| 231   { IDS_PRODUCT_NAME, "", "" }, |  | 
| 232   { IDS_PRODUCT_NAME, kMultiSwitch1, "" }, |  | 
| 233   { IDS_PRODUCT_NAME, kMultiSwitch2, kValueForMultiSwitch2 }, |  | 
| 234 }; |  | 
| 235 |  | 
| 236 const base::Feature kTestFeature{"FeatureName", |  | 
| 237                                  base::FEATURE_ENABLED_BY_DEFAULT}; |  | 
| 238 |  | 
| 239 // The entries that are set for these tests. The 3rd entry is not supported on |  | 
| 240 // the current platform, all others are. |  | 
| 241 static FeatureEntry kEntries[] = { |  | 
| 242     {kFlags1, IDS_PRODUCT_NAME, IDS_PRODUCT_NAME, |  | 
| 243      0,  // Ends up being mapped to the current platform. |  | 
| 244      FeatureEntry::SINGLE_VALUE, kSwitch1, "", nullptr, nullptr, nullptr, |  | 
| 245      nullptr, 0}, |  | 
| 246     {kFlags2, IDS_PRODUCT_NAME, IDS_PRODUCT_NAME, |  | 
| 247      0,  // Ends up being mapped to the current platform. |  | 
| 248      FeatureEntry::SINGLE_VALUE, kSwitch2, kValueForSwitch2, nullptr, nullptr, |  | 
| 249      nullptr, nullptr, 0}, |  | 
| 250     {kFlags3, IDS_PRODUCT_NAME, IDS_PRODUCT_NAME, |  | 
| 251      0,  // This ends up enabling for an OS other than the current. |  | 
| 252      FeatureEntry::SINGLE_VALUE, kSwitch3, "", nullptr, nullptr, nullptr, |  | 
| 253      nullptr, 0}, |  | 
| 254     {kFlags4, IDS_PRODUCT_NAME, IDS_PRODUCT_NAME, |  | 
| 255      0,  // Ends up being mapped to the current platform. |  | 
| 256      FeatureEntry::MULTI_VALUE, "", "", "", "", nullptr, kMultiChoices, |  | 
| 257      arraysize(kMultiChoices)}, |  | 
| 258     {kFlags5, IDS_PRODUCT_NAME, IDS_PRODUCT_NAME, |  | 
| 259      0,  // Ends up being mapped to the current platform. |  | 
| 260      FeatureEntry::ENABLE_DISABLE_VALUE, kSwitch1, kEnableDisableValue1, |  | 
| 261      kSwitch2, kEnableDisableValue2, nullptr, nullptr, 3}, |  | 
| 262     {kFlags6, IDS_PRODUCT_NAME, IDS_PRODUCT_NAME, 0, |  | 
| 263      FeatureEntry::SINGLE_DISABLE_VALUE, kSwitch6, "", nullptr, nullptr, |  | 
| 264      nullptr, nullptr, 0}, |  | 
| 265     {kFlags7, IDS_PRODUCT_NAME, IDS_PRODUCT_NAME, |  | 
| 266      0,  // Ends up being mapped to the current platform. |  | 
| 267      FeatureEntry::FEATURE_VALUE, nullptr, nullptr, nullptr, nullptr, |  | 
| 268      &kTestFeature, nullptr, 3}, |  | 
| 269 }; |  | 
| 270 |  | 
| 271 class AboutFlagsTest : public ::testing::Test { |  | 
| 272  protected: |  | 
| 273   AboutFlagsTest() : flags_storage_(&prefs_) { |  | 
| 274     prefs_.registry()->RegisterListPref( |  | 
| 275         flags_ui::prefs::kEnabledLabsExperiments); |  | 
| 276     testing::ClearState(); |  | 
| 277   } |  | 
| 278 |  | 
| 279   void SetUp() override { |  | 
| 280     for (size_t i = 0; i < arraysize(kEntries); ++i) |  | 
| 281       kEntries[i].supported_platforms = GetCurrentPlatform(); |  | 
| 282 |  | 
| 283     int os_other_than_current = 1; |  | 
| 284     while (os_other_than_current == GetCurrentPlatform()) |  | 
| 285       os_other_than_current <<= 1; |  | 
| 286     kEntries[2].supported_platforms = os_other_than_current; |  | 
| 287 |  | 
| 288     testing::SetFeatureEntries(kEntries, arraysize(kEntries)); |  | 
| 289   } |  | 
| 290 |  | 
| 291   void TearDown() override { testing::SetFeatureEntries(nullptr, 0); } |  | 
| 292 |  | 
| 293   TestingPrefServiceSimple prefs_; |  | 
| 294   flags_ui::PrefServiceFlagsStorage flags_storage_; |  | 
| 295 }; |  | 
| 296 |  | 
| 297 |  | 
| 298 TEST_F(AboutFlagsTest, NoChangeNoRestart) { |  | 
| 299   EXPECT_FALSE(IsRestartNeededToCommitChanges()); |  | 
| 300   SetFeatureEntryEnabled(&flags_storage_, kFlags1, false); |  | 
| 301   EXPECT_FALSE(IsRestartNeededToCommitChanges()); |  | 
| 302 |  | 
| 303   // kFlags6 is enabled by default, so enabling should not require a restart. |  | 
| 304   SetFeatureEntryEnabled(&flags_storage_, kFlags6, true); |  | 
| 305   EXPECT_FALSE(IsRestartNeededToCommitChanges()); |  | 
| 306 } |  | 
| 307 |  | 
| 308 TEST_F(AboutFlagsTest, ChangeNeedsRestart) { |  | 
| 309   EXPECT_FALSE(IsRestartNeededToCommitChanges()); |  | 
| 310   SetFeatureEntryEnabled(&flags_storage_, kFlags1, true); |  | 
| 311   EXPECT_TRUE(IsRestartNeededToCommitChanges()); |  | 
| 312 } |  | 
| 313 |  | 
| 314 // Tests that disabling a default enabled entry requires a restart. |  | 
| 315 TEST_F(AboutFlagsTest, DisableChangeNeedsRestart) { |  | 
| 316   EXPECT_FALSE(IsRestartNeededToCommitChanges()); |  | 
| 317   SetFeatureEntryEnabled(&flags_storage_, kFlags6, false); |  | 
| 318   EXPECT_TRUE(IsRestartNeededToCommitChanges()); |  | 
| 319 } |  | 
| 320 |  | 
| 321 TEST_F(AboutFlagsTest, MultiFlagChangeNeedsRestart) { |  | 
| 322   const FeatureEntry& entry = kEntries[3]; |  | 
| 323   ASSERT_EQ(kFlags4, entry.internal_name); |  | 
| 324   EXPECT_FALSE(IsRestartNeededToCommitChanges()); |  | 
| 325   // Enable the 2nd choice of the multi-value. |  | 
| 326   SetFeatureEntryEnabled(&flags_storage_, entry.NameForChoice(2), true); |  | 
| 327   EXPECT_TRUE(IsRestartNeededToCommitChanges()); |  | 
| 328   testing::ClearState(); |  | 
| 329   EXPECT_FALSE(IsRestartNeededToCommitChanges()); |  | 
| 330   // Enable the default choice now. |  | 
| 331   SetFeatureEntryEnabled(&flags_storage_, entry.NameForChoice(0), true); |  | 
| 332   EXPECT_TRUE(IsRestartNeededToCommitChanges()); |  | 
| 333 } |  | 
| 334 |  | 
| 335 TEST_F(AboutFlagsTest, AddTwoFlagsRemoveOne) { |  | 
| 336   // Add two entries, check they're there. |  | 
| 337   SetFeatureEntryEnabled(&flags_storage_, kFlags1, true); |  | 
| 338   SetFeatureEntryEnabled(&flags_storage_, kFlags2, true); |  | 
| 339 |  | 
| 340   const base::ListValue* entries_list = |  | 
| 341       prefs_.GetList(flags_ui::prefs::kEnabledLabsExperiments); |  | 
| 342   ASSERT_TRUE(entries_list != nullptr); |  | 
| 343 |  | 
| 344   ASSERT_EQ(2u, entries_list->GetSize()); |  | 
| 345 |  | 
| 346   std::string s0; |  | 
| 347   ASSERT_TRUE(entries_list->GetString(0, &s0)); |  | 
| 348   std::string s1; |  | 
| 349   ASSERT_TRUE(entries_list->GetString(1, &s1)); |  | 
| 350 |  | 
| 351   EXPECT_TRUE(s0 == kFlags1 || s1 == kFlags1); |  | 
| 352   EXPECT_TRUE(s0 == kFlags2 || s1 == kFlags2); |  | 
| 353 |  | 
| 354   // Remove one entry, check the other's still around. |  | 
| 355   SetFeatureEntryEnabled(&flags_storage_, kFlags2, false); |  | 
| 356 |  | 
| 357   entries_list = prefs_.GetList(flags_ui::prefs::kEnabledLabsExperiments); |  | 
| 358   ASSERT_TRUE(entries_list != nullptr); |  | 
| 359   ASSERT_EQ(1u, entries_list->GetSize()); |  | 
| 360   ASSERT_TRUE(entries_list->GetString(0, &s0)); |  | 
| 361   EXPECT_TRUE(s0 == kFlags1); |  | 
| 362 } |  | 
| 363 |  | 
| 364 TEST_F(AboutFlagsTest, AddTwoFlagsRemoveBoth) { |  | 
| 365   // Add two entries, check the pref exists. |  | 
| 366   SetFeatureEntryEnabled(&flags_storage_, kFlags1, true); |  | 
| 367   SetFeatureEntryEnabled(&flags_storage_, kFlags2, true); |  | 
| 368   const base::ListValue* entries_list = |  | 
| 369       prefs_.GetList(flags_ui::prefs::kEnabledLabsExperiments); |  | 
| 370   ASSERT_TRUE(entries_list != nullptr); |  | 
| 371 |  | 
| 372   // Remove both, the pref should have been removed completely. |  | 
| 373   SetFeatureEntryEnabled(&flags_storage_, kFlags1, false); |  | 
| 374   SetFeatureEntryEnabled(&flags_storage_, kFlags2, false); |  | 
| 375   entries_list = prefs_.GetList(flags_ui::prefs::kEnabledLabsExperiments); |  | 
| 376   EXPECT_TRUE(entries_list == nullptr || entries_list->GetSize() == 0); |  | 
| 377 } |  | 
| 378 |  | 
| 379 TEST_F(AboutFlagsTest, ConvertFlagsToSwitches) { |  | 
| 380   SetFeatureEntryEnabled(&flags_storage_, kFlags1, true); |  | 
| 381 |  | 
| 382   base::CommandLine command_line(base::CommandLine::NO_PROGRAM); |  | 
| 383   command_line.AppendSwitch("foo"); |  | 
| 384 |  | 
| 385   EXPECT_TRUE(command_line.HasSwitch("foo")); |  | 
| 386   EXPECT_FALSE(command_line.HasSwitch(kSwitch1)); |  | 
| 387 |  | 
| 388   ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels); |  | 
| 389 |  | 
| 390   EXPECT_TRUE(command_line.HasSwitch("foo")); |  | 
| 391   EXPECT_TRUE(command_line.HasSwitch(kSwitch1)); |  | 
| 392   EXPECT_TRUE(command_line.HasSwitch(switches::kFlagSwitchesBegin)); |  | 
| 393   EXPECT_TRUE(command_line.HasSwitch(switches::kFlagSwitchesEnd)); |  | 
| 394 |  | 
| 395   base::CommandLine command_line2(base::CommandLine::NO_PROGRAM); |  | 
| 396 |  | 
| 397   ConvertFlagsToSwitches(&flags_storage_, &command_line2, kNoSentinels); |  | 
| 398 |  | 
| 399   EXPECT_TRUE(command_line2.HasSwitch(kSwitch1)); |  | 
| 400   EXPECT_FALSE(command_line2.HasSwitch(switches::kFlagSwitchesBegin)); |  | 
| 401   EXPECT_FALSE(command_line2.HasSwitch(switches::kFlagSwitchesEnd)); |  | 
| 402 } |  | 
| 403 |  | 
| 404 base::CommandLine::StringType CreateSwitch(const std::string& value) { |  | 
| 405 #if defined(OS_WIN) |  | 
| 406   return base::ASCIIToUTF16(value); |  | 
| 407 #else |  | 
| 408   return value; |  | 
| 409 #endif |  | 
| 410 } |  | 
| 411 |  | 
| 412 TEST_F(AboutFlagsTest, CompareSwitchesToCurrentCommandLine) { |  | 
| 413   SetFeatureEntryEnabled(&flags_storage_, kFlags1, true); |  | 
| 414 |  | 
| 415   const std::string kDoubleDash("--"); |  | 
| 416 |  | 
| 417   base::CommandLine command_line(base::CommandLine::NO_PROGRAM); |  | 
| 418   command_line.AppendSwitch("foo"); |  | 
| 419 |  | 
| 420   base::CommandLine new_command_line(base::CommandLine::NO_PROGRAM); |  | 
| 421   ConvertFlagsToSwitches(&flags_storage_, &new_command_line, kAddSentinels); |  | 
| 422 |  | 
| 423   EXPECT_FALSE(AreSwitchesIdenticalToCurrentCommandLine(new_command_line, |  | 
| 424                                                         command_line, nullptr)); |  | 
| 425   { |  | 
| 426     std::set<base::CommandLine::StringType> difference; |  | 
| 427     EXPECT_FALSE(AreSwitchesIdenticalToCurrentCommandLine( |  | 
| 428         new_command_line, command_line, &difference)); |  | 
| 429     EXPECT_EQ(1U, difference.size()); |  | 
| 430     EXPECT_EQ(1U, difference.count(CreateSwitch(kDoubleDash + kSwitch1))); |  | 
| 431   } |  | 
| 432 |  | 
| 433   ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels); |  | 
| 434 |  | 
| 435   EXPECT_TRUE(AreSwitchesIdenticalToCurrentCommandLine(new_command_line, |  | 
| 436                                                        command_line, nullptr)); |  | 
| 437   { |  | 
| 438     std::set<base::CommandLine::StringType> difference; |  | 
| 439     EXPECT_TRUE(AreSwitchesIdenticalToCurrentCommandLine( |  | 
| 440         new_command_line, command_line, &difference)); |  | 
| 441     EXPECT_TRUE(difference.empty()); |  | 
| 442   } |  | 
| 443 |  | 
| 444   // Now both have flags but different. |  | 
| 445   SetFeatureEntryEnabled(&flags_storage_, kFlags1, false); |  | 
| 446   SetFeatureEntryEnabled(&flags_storage_, kFlags2, true); |  | 
| 447 |  | 
| 448   base::CommandLine another_command_line(base::CommandLine::NO_PROGRAM); |  | 
| 449   ConvertFlagsToSwitches(&flags_storage_, &another_command_line, kAddSentinels); |  | 
| 450 |  | 
| 451   EXPECT_FALSE(AreSwitchesIdenticalToCurrentCommandLine( |  | 
| 452       new_command_line, another_command_line, nullptr)); |  | 
| 453   { |  | 
| 454     std::set<base::CommandLine::StringType> difference; |  | 
| 455     EXPECT_FALSE(AreSwitchesIdenticalToCurrentCommandLine( |  | 
| 456         new_command_line, another_command_line, &difference)); |  | 
| 457     EXPECT_EQ(2U, difference.size()); |  | 
| 458     EXPECT_EQ(1U, difference.count(CreateSwitch(kDoubleDash + kSwitch1))); |  | 
| 459     EXPECT_EQ(1U, |  | 
| 460               difference.count(CreateSwitch(kDoubleDash + kSwitch2 + "=" + |  | 
| 461                                             kValueForSwitch2))); |  | 
| 462   } |  | 
| 463 } |  | 
| 464 |  | 
| 465 TEST_F(AboutFlagsTest, RemoveFlagSwitches) { |  | 
| 466   std::map<std::string, base::CommandLine::StringType> switch_list; |  | 
| 467   switch_list[kSwitch1] = base::CommandLine::StringType(); |  | 
| 468   switch_list[switches::kFlagSwitchesBegin] = base::CommandLine::StringType(); |  | 
| 469   switch_list[switches::kFlagSwitchesEnd] = base::CommandLine::StringType(); |  | 
| 470   switch_list["foo"] = base::CommandLine::StringType(); |  | 
| 471 |  | 
| 472   SetFeatureEntryEnabled(&flags_storage_, kFlags1, true); |  | 
| 473 |  | 
| 474   // This shouldn't do anything before ConvertFlagsToSwitches() wasn't called. |  | 
| 475   RemoveFlagsSwitches(&switch_list); |  | 
| 476   ASSERT_EQ(4u, switch_list.size()); |  | 
| 477   EXPECT_TRUE(ContainsKey(switch_list, kSwitch1)); |  | 
| 478   EXPECT_TRUE(ContainsKey(switch_list, switches::kFlagSwitchesBegin)); |  | 
| 479   EXPECT_TRUE(ContainsKey(switch_list, switches::kFlagSwitchesEnd)); |  | 
| 480   EXPECT_TRUE(ContainsKey(switch_list, "foo")); |  | 
| 481 |  | 
| 482   // Call ConvertFlagsToSwitches(), then RemoveFlagsSwitches() again. |  | 
| 483   base::CommandLine command_line(base::CommandLine::NO_PROGRAM); |  | 
| 484   command_line.AppendSwitch("foo"); |  | 
| 485   ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels); |  | 
| 486   RemoveFlagsSwitches(&switch_list); |  | 
| 487 |  | 
| 488   // Now the about:flags-related switch should have been removed. |  | 
| 489   ASSERT_EQ(1u, switch_list.size()); |  | 
| 490   EXPECT_TRUE(ContainsKey(switch_list, "foo")); |  | 
| 491 } |  | 
| 492 |  | 
| 493 TEST_F(AboutFlagsTest, RemoveFlagSwitches_Features) { |  | 
| 494   struct { |  | 
| 495     int enabled_choice;  // 0: default, 1: enabled, 2: disabled. |  | 
| 496     const char* existing_enable_features; |  | 
| 497     const char* existing_disable_features; |  | 
| 498     const char* expected_enable_features; |  | 
| 499     const char* expected_disable_features; |  | 
| 500   } cases[] = { |  | 
| 501       // Default value: Should not affect existing flags. |  | 
| 502       {0, nullptr, nullptr, nullptr, nullptr}, |  | 
| 503       {0, "A,B", "C", "A,B", "C"}, |  | 
| 504       // "Enable" option: should only affect enabled list. |  | 
| 505       {1, nullptr, nullptr, "FeatureName", nullptr}, |  | 
| 506       {1, "A,B", "C", "A,B,FeatureName", "C"}, |  | 
| 507       // "Disable" option: should only affect disabled list. |  | 
| 508       {2, nullptr, nullptr, nullptr, "FeatureName"}, |  | 
| 509       {2, "A,B", "C", "A,B", "C,FeatureName"}, |  | 
| 510   }; |  | 
| 511 |  | 
| 512   for (size_t i = 0; i < arraysize(cases); ++i) { |  | 
| 513     SCOPED_TRACE(base::StringPrintf( |  | 
| 514         "Test[%" PRIuS "]: %d [%s] [%s]", i, cases[i].enabled_choice, |  | 
| 515         cases[i].existing_enable_features ? cases[i].existing_enable_features |  | 
| 516                                           : "null", |  | 
| 517         cases[i].existing_disable_features ? cases[i].existing_disable_features |  | 
| 518                                            : "null")); |  | 
| 519 |  | 
| 520     base::CommandLine command_line(base::CommandLine::NO_PROGRAM); |  | 
| 521     if (cases[i].existing_enable_features) { |  | 
| 522       command_line.AppendSwitchASCII(switches::kEnableFeatures, |  | 
| 523                                      cases[i].existing_enable_features); |  | 
| 524     } |  | 
| 525     if (cases[i].existing_disable_features) { |  | 
| 526       command_line.AppendSwitchASCII(switches::kDisableFeatures, |  | 
| 527                                      cases[i].existing_disable_features); |  | 
| 528     } |  | 
| 529 |  | 
| 530     testing::ClearState(); |  | 
| 531 |  | 
| 532     const std::string entry_name = base::StringPrintf( |  | 
| 533         "%s%s%d", kFlags7, flags_ui::testing::kMultiSeparator, |  | 
| 534         cases[i].enabled_choice); |  | 
| 535     SetFeatureEntryEnabled(&flags_storage_, entry_name, true); |  | 
| 536 |  | 
| 537     ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels); |  | 
| 538     auto switch_list = command_line.GetSwitches(); |  | 
| 539     EXPECT_EQ(cases[i].expected_enable_features != nullptr, |  | 
| 540               ContainsKey(switch_list, switches::kEnableFeatures)); |  | 
| 541     if (cases[i].expected_enable_features) |  | 
| 542       EXPECT_EQ(CreateSwitch(cases[i].expected_enable_features), |  | 
| 543                 switch_list[switches::kEnableFeatures]); |  | 
| 544 |  | 
| 545     EXPECT_EQ(cases[i].expected_disable_features != nullptr, |  | 
| 546               ContainsKey(switch_list, switches::kDisableFeatures)); |  | 
| 547     if (cases[i].expected_disable_features) |  | 
| 548       EXPECT_EQ(CreateSwitch(cases[i].expected_disable_features), |  | 
| 549                 switch_list[switches::kDisableFeatures]); |  | 
| 550 |  | 
| 551     // RemoveFlagsSwitches() should result in the original values for these |  | 
| 552     // switches. |  | 
| 553     switch_list = command_line.GetSwitches(); |  | 
| 554     RemoveFlagsSwitches(&switch_list); |  | 
| 555     EXPECT_EQ(cases[i].existing_enable_features != nullptr, |  | 
| 556               ContainsKey(switch_list, switches::kEnableFeatures)); |  | 
| 557     if (cases[i].existing_enable_features) |  | 
| 558       EXPECT_EQ(CreateSwitch(cases[i].existing_enable_features), |  | 
| 559                 switch_list[switches::kEnableFeatures]); |  | 
| 560     EXPECT_EQ(cases[i].existing_disable_features != nullptr, |  | 
| 561               ContainsKey(switch_list, switches::kEnableFeatures)); |  | 
| 562     if (cases[i].existing_disable_features) |  | 
| 563       EXPECT_EQ(CreateSwitch(cases[i].existing_disable_features), |  | 
| 564                 switch_list[switches::kDisableFeatures]); |  | 
| 565   } |  | 
| 566 } |  | 
| 567 |  | 
| 568 // Tests enabling entries that aren't supported on the current platform. |  | 
| 569 TEST_F(AboutFlagsTest, PersistAndPrune) { |  | 
| 570   // Enable entries 1 and 3. |  | 
| 571   SetFeatureEntryEnabled(&flags_storage_, kFlags1, true); |  | 
| 572   SetFeatureEntryEnabled(&flags_storage_, kFlags3, true); |  | 
| 573   base::CommandLine command_line(base::CommandLine::NO_PROGRAM); |  | 
| 574   EXPECT_FALSE(command_line.HasSwitch(kSwitch1)); |  | 
| 575   EXPECT_FALSE(command_line.HasSwitch(kSwitch3)); |  | 
| 576 |  | 
| 577   // Convert the flags to switches. Entry 3 shouldn't be among the switches |  | 
| 578   // as it is not applicable to the current platform. |  | 
| 579   ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels); |  | 
| 580   EXPECT_TRUE(command_line.HasSwitch(kSwitch1)); |  | 
| 581   EXPECT_FALSE(command_line.HasSwitch(kSwitch3)); |  | 
| 582 |  | 
| 583   // FeatureEntry 3 should show still be persisted in preferences though. |  | 
| 584   const base::ListValue* entries_list = |  | 
| 585       prefs_.GetList(flags_ui::prefs::kEnabledLabsExperiments); |  | 
| 586   ASSERT_TRUE(entries_list); |  | 
| 587   EXPECT_EQ(2U, entries_list->GetSize()); |  | 
| 588   std::string s0; |  | 
| 589   ASSERT_TRUE(entries_list->GetString(0, &s0)); |  | 
| 590   EXPECT_EQ(kFlags1, s0); |  | 
| 591   std::string s1; |  | 
| 592   ASSERT_TRUE(entries_list->GetString(1, &s1)); |  | 
| 593   EXPECT_EQ(kFlags3, s1); |  | 
| 594 } |  | 
| 595 |  | 
| 596 // Tests that switches which should have values get them in the command |  | 
| 597 // line. |  | 
| 598 TEST_F(AboutFlagsTest, CheckValues) { |  | 
| 599   // Enable entries 1 and 2. |  | 
| 600   SetFeatureEntryEnabled(&flags_storage_, kFlags1, true); |  | 
| 601   SetFeatureEntryEnabled(&flags_storage_, kFlags2, true); |  | 
| 602   base::CommandLine command_line(base::CommandLine::NO_PROGRAM); |  | 
| 603   EXPECT_FALSE(command_line.HasSwitch(kSwitch1)); |  | 
| 604   EXPECT_FALSE(command_line.HasSwitch(kSwitch2)); |  | 
| 605 |  | 
| 606   // Convert the flags to switches. |  | 
| 607   ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels); |  | 
| 608   EXPECT_TRUE(command_line.HasSwitch(kSwitch1)); |  | 
| 609   EXPECT_EQ(std::string(), command_line.GetSwitchValueASCII(kSwitch1)); |  | 
| 610   EXPECT_TRUE(command_line.HasSwitch(kSwitch2)); |  | 
| 611   EXPECT_EQ(std::string(kValueForSwitch2), |  | 
| 612             command_line.GetSwitchValueASCII(kSwitch2)); |  | 
| 613 |  | 
| 614   // Confirm that there is no '=' in the command line for simple switches. |  | 
| 615   std::string switch1_with_equals = std::string("--") + |  | 
| 616                                     std::string(kSwitch1) + |  | 
| 617                                     std::string("="); |  | 
| 618 #if defined(OS_WIN) |  | 
| 619   EXPECT_EQ(base::string16::npos, |  | 
| 620             command_line.GetCommandLineString().find( |  | 
| 621                 base::ASCIIToUTF16(switch1_with_equals))); |  | 
| 622 #else |  | 
| 623   EXPECT_EQ(std::string::npos, |  | 
| 624             command_line.GetCommandLineString().find(switch1_with_equals)); |  | 
| 625 #endif |  | 
| 626 |  | 
| 627   // And confirm there is a '=' for switches with values. |  | 
| 628   std::string switch2_with_equals = std::string("--") + |  | 
| 629                                     std::string(kSwitch2) + |  | 
| 630                                     std::string("="); |  | 
| 631 #if defined(OS_WIN) |  | 
| 632   EXPECT_NE(base::string16::npos, |  | 
| 633             command_line.GetCommandLineString().find( |  | 
| 634                 base::ASCIIToUTF16(switch2_with_equals))); |  | 
| 635 #else |  | 
| 636   EXPECT_NE(std::string::npos, |  | 
| 637             command_line.GetCommandLineString().find(switch2_with_equals)); |  | 
| 638 #endif |  | 
| 639 |  | 
| 640   // And it should persist. |  | 
| 641   const base::ListValue* entries_list = |  | 
| 642       prefs_.GetList(flags_ui::prefs::kEnabledLabsExperiments); |  | 
| 643   ASSERT_TRUE(entries_list); |  | 
| 644   EXPECT_EQ(2U, entries_list->GetSize()); |  | 
| 645   std::string s0; |  | 
| 646   ASSERT_TRUE(entries_list->GetString(0, &s0)); |  | 
| 647   EXPECT_EQ(kFlags1, s0); |  | 
| 648   std::string s1; |  | 
| 649   ASSERT_TRUE(entries_list->GetString(1, &s1)); |  | 
| 650   EXPECT_EQ(kFlags2, s1); |  | 
| 651 } |  | 
| 652 |  | 
| 653 // Tests multi-value type entries. |  | 
| 654 TEST_F(AboutFlagsTest, MultiValues) { |  | 
| 655   const FeatureEntry& entry = kEntries[3]; |  | 
| 656   ASSERT_EQ(kFlags4, entry.internal_name); |  | 
| 657 |  | 
| 658   // Initially, the first "deactivated" option of the multi entry should |  | 
| 659   // be set. |  | 
| 660   { |  | 
| 661     base::CommandLine command_line(base::CommandLine::NO_PROGRAM); |  | 
| 662     ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels); |  | 
| 663     EXPECT_FALSE(command_line.HasSwitch(kMultiSwitch1)); |  | 
| 664     EXPECT_FALSE(command_line.HasSwitch(kMultiSwitch2)); |  | 
| 665   } |  | 
| 666 |  | 
| 667   // Enable the 2nd choice of the multi-value. |  | 
| 668   SetFeatureEntryEnabled(&flags_storage_, entry.NameForChoice(2), true); |  | 
| 669   { |  | 
| 670     base::CommandLine command_line(base::CommandLine::NO_PROGRAM); |  | 
| 671     ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels); |  | 
| 672     EXPECT_FALSE(command_line.HasSwitch(kMultiSwitch1)); |  | 
| 673     EXPECT_TRUE(command_line.HasSwitch(kMultiSwitch2)); |  | 
| 674     EXPECT_EQ(std::string(kValueForMultiSwitch2), |  | 
| 675               command_line.GetSwitchValueASCII(kMultiSwitch2)); |  | 
| 676   } |  | 
| 677 |  | 
| 678   // Disable the multi-value entry. |  | 
| 679   SetFeatureEntryEnabled(&flags_storage_, entry.NameForChoice(0), true); |  | 
| 680   { |  | 
| 681     base::CommandLine command_line(base::CommandLine::NO_PROGRAM); |  | 
| 682     ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels); |  | 
| 683     EXPECT_FALSE(command_line.HasSwitch(kMultiSwitch1)); |  | 
| 684     EXPECT_FALSE(command_line.HasSwitch(kMultiSwitch2)); |  | 
| 685   } |  | 
| 686 } |  | 
| 687 |  | 
| 688 // Tests that disable flags are added when an entry is disabled. |  | 
| 689 TEST_F(AboutFlagsTest, DisableFlagCommandLine) { |  | 
| 690   // Nothing selected. |  | 
| 691   { |  | 
| 692     base::CommandLine command_line(base::CommandLine::NO_PROGRAM); |  | 
| 693     ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels); |  | 
| 694     EXPECT_FALSE(command_line.HasSwitch(kSwitch6)); |  | 
| 695   } |  | 
| 696 |  | 
| 697   // Disable the entry 6. |  | 
| 698   SetFeatureEntryEnabled(&flags_storage_, kFlags6, false); |  | 
| 699   { |  | 
| 700     base::CommandLine command_line(base::CommandLine::NO_PROGRAM); |  | 
| 701     ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels); |  | 
| 702     EXPECT_TRUE(command_line.HasSwitch(kSwitch6)); |  | 
| 703   } |  | 
| 704 |  | 
| 705   // Enable entry 6. |  | 
| 706   SetFeatureEntryEnabled(&flags_storage_, kFlags6, true); |  | 
| 707   { |  | 
| 708     base::CommandLine command_line(base::CommandLine::NO_PROGRAM); |  | 
| 709     ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels); |  | 
| 710     EXPECT_FALSE(command_line.HasSwitch(kSwitch6)); |  | 
| 711   } |  | 
| 712 } |  | 
| 713 |  | 
| 714 TEST_F(AboutFlagsTest, EnableDisableValues) { |  | 
| 715   const FeatureEntry& entry = kEntries[4]; |  | 
| 716   ASSERT_EQ(kFlags5, entry.internal_name); |  | 
| 717 |  | 
| 718   // Nothing selected. |  | 
| 719   { |  | 
| 720     base::CommandLine command_line(base::CommandLine::NO_PROGRAM); |  | 
| 721     ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels); |  | 
| 722     EXPECT_FALSE(command_line.HasSwitch(kSwitch1)); |  | 
| 723     EXPECT_FALSE(command_line.HasSwitch(kSwitch2)); |  | 
| 724   } |  | 
| 725 |  | 
| 726   // "Enable" option selected. |  | 
| 727   SetFeatureEntryEnabled(&flags_storage_, entry.NameForChoice(1), true); |  | 
| 728   { |  | 
| 729     base::CommandLine command_line(base::CommandLine::NO_PROGRAM); |  | 
| 730     ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels); |  | 
| 731     EXPECT_TRUE(command_line.HasSwitch(kSwitch1)); |  | 
| 732     EXPECT_FALSE(command_line.HasSwitch(kSwitch2)); |  | 
| 733     EXPECT_EQ(kEnableDisableValue1, command_line.GetSwitchValueASCII(kSwitch1)); |  | 
| 734   } |  | 
| 735 |  | 
| 736   // "Disable" option selected. |  | 
| 737   SetFeatureEntryEnabled(&flags_storage_, entry.NameForChoice(2), true); |  | 
| 738   { |  | 
| 739     base::CommandLine command_line(base::CommandLine::NO_PROGRAM); |  | 
| 740     ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels); |  | 
| 741     EXPECT_FALSE(command_line.HasSwitch(kSwitch1)); |  | 
| 742     EXPECT_TRUE(command_line.HasSwitch(kSwitch2)); |  | 
| 743     EXPECT_EQ(kEnableDisableValue2, command_line.GetSwitchValueASCII(kSwitch2)); |  | 
| 744   } |  | 
| 745 |  | 
| 746   // "Default" option selected, same as nothing selected. |  | 
| 747   SetFeatureEntryEnabled(&flags_storage_, entry.NameForChoice(0), true); |  | 
| 748   { |  | 
| 749     base::CommandLine command_line(base::CommandLine::NO_PROGRAM); |  | 
| 750     ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels); |  | 
| 751     EXPECT_FALSE(command_line.HasSwitch(kMultiSwitch1)); |  | 
| 752     EXPECT_FALSE(command_line.HasSwitch(kMultiSwitch2)); |  | 
| 753   } |  | 
| 754 } |  | 
| 755 |  | 
| 756 TEST_F(AboutFlagsTest, FeatureValues) { |  | 
| 757   const FeatureEntry& entry = kEntries[6]; |  | 
| 758   ASSERT_EQ(kFlags7, entry.internal_name); |  | 
| 759 |  | 
| 760   struct { |  | 
| 761     int enabled_choice; |  | 
| 762     const char* existing_enable_features; |  | 
| 763     const char* existing_disable_features; |  | 
| 764     const char* expected_enable_features; |  | 
| 765     const char* expected_disable_features; |  | 
| 766   } cases[] = { |  | 
| 767       // Nothing selected. |  | 
| 768       {-1, nullptr, nullptr, "", ""}, |  | 
| 769       // "Default" option selected, same as nothing selected. |  | 
| 770       {0, nullptr, nullptr, "", ""}, |  | 
| 771       // "Enable" option selected. |  | 
| 772       {1, nullptr, nullptr, "FeatureName", ""}, |  | 
| 773       // "Disable" option selected. |  | 
| 774       {2, nullptr, nullptr, "", "FeatureName"}, |  | 
| 775       // "Enable" option should get added to the existing list. |  | 
| 776       {1, "Foo,Bar", nullptr, "Foo,Bar,FeatureName", ""}, |  | 
| 777       // "Disable" option should get added to the existing list. |  | 
| 778       {2, nullptr, "Foo,Bar", "", "Foo,Bar,FeatureName"}, |  | 
| 779   }; |  | 
| 780 |  | 
| 781   for (size_t i = 0; i < arraysize(cases); ++i) { |  | 
| 782     SCOPED_TRACE(base::StringPrintf( |  | 
| 783         "Test[%" PRIuS "]: %d [%s] [%s]", i, cases[i].enabled_choice, |  | 
| 784         cases[i].existing_enable_features ? cases[i].existing_enable_features |  | 
| 785                                           : "null", |  | 
| 786         cases[i].existing_disable_features ? cases[i].existing_disable_features |  | 
| 787                                            : "null")); |  | 
| 788 |  | 
| 789     if (cases[i].enabled_choice != -1) { |  | 
| 790       SetFeatureEntryEnabled( |  | 
| 791           &flags_storage_, entry.NameForChoice(cases[i].enabled_choice), true); |  | 
| 792     } |  | 
| 793 |  | 
| 794     base::CommandLine command_line(base::CommandLine::NO_PROGRAM); |  | 
| 795     if (cases[i].existing_enable_features) { |  | 
| 796       command_line.AppendSwitchASCII(switches::kEnableFeatures, |  | 
| 797                                      cases[i].existing_enable_features); |  | 
| 798     } |  | 
| 799     if (cases[i].existing_disable_features) { |  | 
| 800       command_line.AppendSwitchASCII(switches::kDisableFeatures, |  | 
| 801                                      cases[i].existing_disable_features); |  | 
| 802     } |  | 
| 803 |  | 
| 804     ConvertFlagsToSwitches(&flags_storage_, &command_line, kAddSentinels); |  | 
| 805     EXPECT_EQ(cases[i].expected_enable_features, |  | 
| 806               command_line.GetSwitchValueASCII(switches::kEnableFeatures)); |  | 
| 807     EXPECT_EQ(cases[i].expected_disable_features, |  | 
| 808               command_line.GetSwitchValueASCII(switches::kDisableFeatures)); |  | 
| 809   } |  | 
| 810 } |  | 
| 811 |  | 
| 812 // Makes sure there are no separators in any of the entry names. | 201 // Makes sure there are no separators in any of the entry names. | 
| 813 TEST_F(AboutFlagsTest, NoSeparators) { | 202 TEST(AboutFlagsTest, NoSeparators) { | 
| 814   testing::SetFeatureEntries(nullptr, 0); |  | 
| 815   size_t count; | 203   size_t count; | 
| 816   const FeatureEntry* entries = testing::GetFeatureEntries(&count); | 204   const flags_ui::FeatureEntry* entries = testing::GetFeatureEntries(&count); | 
| 817   for (size_t i = 0; i < count; ++i) { | 205   for (size_t i = 0; i < count; ++i) { | 
| 818     std::string name = entries[i].internal_name; | 206     std::string name = entries[i].internal_name; | 
| 819     EXPECT_EQ(std::string::npos, name.find(flags_ui::testing::kMultiSeparator)) | 207     EXPECT_EQ(std::string::npos, name.find(flags_ui::testing::kMultiSeparator)) | 
| 820         << i; | 208         << i; | 
| 821   } | 209   } | 
| 822 } | 210 } | 
| 823 | 211 | 
| 824 TEST_F(AboutFlagsTest, GetFlagFeatureEntries) { |  | 
| 825   base::ListValue supported_entries; |  | 
| 826   base::ListValue unsupported_entries; |  | 
| 827   GetFlagFeatureEntries(&flags_storage_, kGeneralAccessFlagsOnly, |  | 
| 828                         &supported_entries, &unsupported_entries); |  | 
| 829   // All |kEntries| except for |kFlags3| should be supported. |  | 
| 830   EXPECT_EQ(6u, supported_entries.GetSize()); |  | 
| 831   EXPECT_EQ(1u, unsupported_entries.GetSize()); |  | 
| 832   EXPECT_EQ(arraysize(kEntries), |  | 
| 833             supported_entries.GetSize() + unsupported_entries.GetSize()); |  | 
| 834 } |  | 
| 835 |  | 
| 836 class AboutFlagsHistogramTest : public ::testing::Test { | 212 class AboutFlagsHistogramTest : public ::testing::Test { | 
| 837  protected: | 213  protected: | 
| 838   // This is a helper function to check that all IDs in enum LoginCustomFlags in | 214   // This is a helper function to check that all IDs in enum LoginCustomFlags in | 
| 839   // histograms.xml are unique. | 215   // histograms.xml are unique. | 
| 840   void SetSwitchToHistogramIdMapping(const std::string& switch_name, | 216   void SetSwitchToHistogramIdMapping(const std::string& switch_name, | 
| 841                                      const Sample switch_histogram_id, | 217                                      const Sample switch_histogram_id, | 
| 842                                      std::map<std::string, Sample>* out_map) { | 218                                      std::map<std::string, Sample>* out_map) { | 
| 843     const std::pair<std::map<std::string, Sample>::iterator, bool> status = | 219     const std::pair<std::map<std::string, Sample>::iterator, bool> status = | 
| 844         out_map->insert(std::make_pair(switch_name, switch_histogram_id)); | 220         out_map->insert(std::make_pair(switch_name, switch_histogram_id)); | 
| 845     if (!status.second) { | 221     if (!status.second) { | 
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 922     EXPECT_TRUE(enum_entry != histograms_xml_switches_ids.end() && | 298     EXPECT_TRUE(enum_entry != histograms_xml_switches_ids.end() && | 
| 923                 enum_entry->first == flag) | 299                 enum_entry->first == flag) | 
| 924         << "histograms.xml enum LoginCustomFlags doesn't contain switch '" | 300         << "histograms.xml enum LoginCustomFlags doesn't contain switch '" | 
| 925         << flag << "' (value=" << uma_id | 301         << flag << "' (value=" << uma_id | 
| 926         << " expected). Consider adding entry:\n" | 302         << " expected). Consider adding entry:\n" | 
| 927         << "  " << GetHistogramEnumEntryText(flag, uma_id); | 303         << "  " << GetHistogramEnumEntryText(flag, uma_id); | 
| 928   } | 304   } | 
| 929 } | 305 } | 
| 930 | 306 | 
| 931 }  // namespace about_flags | 307 }  // namespace about_flags | 
| OLD | NEW | 
|---|