Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(269)

Side by Side Diff: chrome/browser/about_flags_unittest.cc

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

Powered by Google App Engine
This is Rietveld 408576698