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

Side by Side Diff: components/flags_ui/flags_state_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: Rebase 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
« no previous file with comments | « components/flags_ui/flags_state.cc ('k') | components/flags_ui/flags_ui_switches.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 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/flags_ui/flags_state.h"
6
7 #include <map>
8 #include <set>
9 #include <string>
10
11 #include "base/bind.h"
12 #include "base/feature_list.h"
13 #include "base/format_macros.h"
14 #include "base/prefs/pref_registry_simple.h"
15 #include "base/prefs/testing_pref_service.h"
16 #include "base/stl_util.h"
17 #include "base/strings/stringprintf.h"
18 #include "base/strings/utf_string_conversions.h"
19 #include "base/values.h"
20 #include "components/flags_ui/feature_entry.h"
21 #include "components/flags_ui/flags_ui_pref_names.h"
22 #include "components/flags_ui/flags_ui_switches.h"
23 #include "components/flags_ui/pref_service_flags_storage.h"
24 #include "grit/components_strings.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26
27 namespace flags_ui {
28
29 namespace {
30
31 const char kFlags1[] = "flag1";
32 const char kFlags2[] = "flag2";
33 const char kFlags3[] = "flag3";
34 const char kFlags4[] = "flag4";
35 const char kFlags5[] = "flag5";
36 const char kFlags6[] = "flag6";
37 const char kFlags7[] = "flag7";
38
39 const char kSwitch1[] = "switch";
40 const char kSwitch2[] = "switch2";
41 const char kSwitch3[] = "switch3";
42 const char kSwitch6[] = "switch6";
43 const char kValueForSwitch2[] = "value_for_switch2";
44
45 const char kMultiSwitch1[] = "multi_switch1";
46 const char kMultiSwitch2[] = "multi_switch2";
47 const char kValueForMultiSwitch2[] = "value_for_multi_switch2";
48
49 const char kEnableDisableValue1[] = "value1";
50 const char kEnableDisableValue2[] = "value2";
51
52 const char kEnableFeatures[] = "dummy-enable-features";
53 const char kDisableFeatures[] = "dummy-disable-features";
54
55 // Those have to be valid ids for the translation system but the value are
56 // never used, so pick one at random from the current component.
57 const int kDummyNameId = IDS_FLAGS_UI_WARNING_HEADER;
58 const int kDummyDescriptionId = IDS_FLAGS_UI_WARNING_TEXT;
59
60 bool SkipFeatureEntry(const FeatureEntry& feature_entry) {
61 return false;
62 }
63
64 } // namespace
65
66 const FeatureEntry::Choice kMultiChoices[] = {
67 {kDummyDescriptionId, "", ""},
68 {kDummyDescriptionId, kMultiSwitch1, ""},
69 {kDummyDescriptionId, kMultiSwitch2, kValueForMultiSwitch2},
70 };
71
72 const base::Feature kTestFeature{"FeatureName",
73 base::FEATURE_ENABLED_BY_DEFAULT};
74
75 // The entries that are set for these tests. The 3rd entry is not supported on
76 // the current platform, all others are.
77 static FeatureEntry kEntries[] = {
78 {kFlags1, kDummyNameId, kDummyDescriptionId,
79 0, // Ends up being mapped to the current platform.
80 FeatureEntry::SINGLE_VALUE, kSwitch1, "", nullptr, nullptr, nullptr,
81 nullptr, 0},
82 {kFlags2, kDummyNameId, kDummyDescriptionId,
83 0, // Ends up being mapped to the current platform.
84 FeatureEntry::SINGLE_VALUE, kSwitch2, kValueForSwitch2, nullptr, nullptr,
85 nullptr, nullptr, 0},
86 {kFlags3, kDummyNameId, kDummyDescriptionId,
87 0, // This ends up enabling for an OS other than the current.
88 FeatureEntry::SINGLE_VALUE, kSwitch3, "", nullptr, nullptr, nullptr,
89 nullptr, 0},
90 {kFlags4, kDummyNameId, kDummyDescriptionId,
91 0, // Ends up being mapped to the current platform.
92 FeatureEntry::MULTI_VALUE, "", "", "", "", nullptr, kMultiChoices,
93 arraysize(kMultiChoices)},
94 {kFlags5, kDummyNameId, kDummyDescriptionId,
95 0, // Ends up being mapped to the current platform.
96 FeatureEntry::ENABLE_DISABLE_VALUE, kSwitch1, kEnableDisableValue1,
97 kSwitch2, kEnableDisableValue2, nullptr, nullptr, 3},
98 {kFlags6, kDummyNameId, kDummyDescriptionId, 0,
99 FeatureEntry::SINGLE_DISABLE_VALUE, kSwitch6, "", nullptr, nullptr,
100 nullptr, nullptr, 0},
101 {kFlags7, kDummyNameId, kDummyDescriptionId,
102 0, // Ends up being mapped to the current platform.
103 FeatureEntry::FEATURE_VALUE, nullptr, nullptr, nullptr, nullptr,
104 &kTestFeature, nullptr, 3},
105 };
106
107 class FlagsStateTest : public ::testing::Test {
108 protected:
109 FlagsStateTest() : flags_storage_(&prefs_) {
110 prefs_.registry()->RegisterListPref(prefs::kEnabledLabsExperiments);
111
112 for (size_t i = 0; i < arraysize(kEntries); ++i)
113 kEntries[i].supported_platforms = FlagsState::GetCurrentPlatform();
114
115 int os_other_than_current = 1;
116 while (os_other_than_current == FlagsState::GetCurrentPlatform())
117 os_other_than_current <<= 1;
118 kEntries[2].supported_platforms = os_other_than_current;
119 flags_state_.reset(new FlagsState(kEntries, arraysize(kEntries)));
120 }
121
122 TestingPrefServiceSimple prefs_;
123 PrefServiceFlagsStorage flags_storage_;
124 scoped_ptr<FlagsState> flags_state_;
125 };
126
127 TEST_F(FlagsStateTest, NoChangeNoRestart) {
128 EXPECT_FALSE(flags_state_->IsRestartNeededToCommitChanges());
129 flags_state_->SetFeatureEntryEnabled(&flags_storage_, kFlags1, false);
130 EXPECT_FALSE(flags_state_->IsRestartNeededToCommitChanges());
131
132 // kFlags6 is enabled by default, so enabling should not require a restart.
133 flags_state_->SetFeatureEntryEnabled(&flags_storage_, kFlags6, true);
134 EXPECT_FALSE(flags_state_->IsRestartNeededToCommitChanges());
135 }
136
137 TEST_F(FlagsStateTest, ChangeNeedsRestart) {
138 EXPECT_FALSE(flags_state_->IsRestartNeededToCommitChanges());
139 flags_state_->SetFeatureEntryEnabled(&flags_storage_, kFlags1, true);
140 EXPECT_TRUE(flags_state_->IsRestartNeededToCommitChanges());
141 }
142
143 // Tests that disabling a default enabled entry requires a restart.
144 TEST_F(FlagsStateTest, DisableChangeNeedsRestart) {
145 EXPECT_FALSE(flags_state_->IsRestartNeededToCommitChanges());
146 flags_state_->SetFeatureEntryEnabled(&flags_storage_, kFlags6, false);
147 EXPECT_TRUE(flags_state_->IsRestartNeededToCommitChanges());
148 }
149
150 TEST_F(FlagsStateTest, MultiFlagChangeNeedsRestart) {
151 const FeatureEntry& entry = kEntries[3];
152 ASSERT_EQ(kFlags4, entry.internal_name);
153 EXPECT_FALSE(flags_state_->IsRestartNeededToCommitChanges());
154 // Enable the 2nd choice of the multi-value.
155 flags_state_->SetFeatureEntryEnabled(&flags_storage_, entry.NameForChoice(2),
156 true);
157 EXPECT_TRUE(flags_state_->IsRestartNeededToCommitChanges());
158 flags_state_->Reset();
159 EXPECT_FALSE(flags_state_->IsRestartNeededToCommitChanges());
160 // Enable the default choice now.
161 flags_state_->SetFeatureEntryEnabled(&flags_storage_, entry.NameForChoice(0),
162 true);
163 EXPECT_TRUE(flags_state_->IsRestartNeededToCommitChanges());
164 }
165
166 TEST_F(FlagsStateTest, AddTwoFlagsRemoveOne) {
167 // Add two entries, check they're there.
168 flags_state_->SetFeatureEntryEnabled(&flags_storage_, kFlags1, true);
169 flags_state_->SetFeatureEntryEnabled(&flags_storage_, kFlags2, true);
170
171 const base::ListValue* entries_list =
172 prefs_.GetList(prefs::kEnabledLabsExperiments);
173 ASSERT_TRUE(entries_list != nullptr);
174
175 ASSERT_EQ(2u, entries_list->GetSize());
176
177 std::string s0;
178 ASSERT_TRUE(entries_list->GetString(0, &s0));
179 std::string s1;
180 ASSERT_TRUE(entries_list->GetString(1, &s1));
181
182 EXPECT_TRUE(s0 == kFlags1 || s1 == kFlags1);
183 EXPECT_TRUE(s0 == kFlags2 || s1 == kFlags2);
184
185 // Remove one entry, check the other's still around.
186 flags_state_->SetFeatureEntryEnabled(&flags_storage_, kFlags2, false);
187
188 entries_list = prefs_.GetList(prefs::kEnabledLabsExperiments);
189 ASSERT_TRUE(entries_list != nullptr);
190 ASSERT_EQ(1u, entries_list->GetSize());
191 ASSERT_TRUE(entries_list->GetString(0, &s0));
192 EXPECT_TRUE(s0 == kFlags1);
193 }
194
195 TEST_F(FlagsStateTest, AddTwoFlagsRemoveBoth) {
196 // Add two entries, check the pref exists.
197 flags_state_->SetFeatureEntryEnabled(&flags_storage_, kFlags1, true);
198 flags_state_->SetFeatureEntryEnabled(&flags_storage_, kFlags2, true);
199 const base::ListValue* entries_list =
200 prefs_.GetList(prefs::kEnabledLabsExperiments);
201 ASSERT_TRUE(entries_list != nullptr);
202
203 // Remove both, the pref should have been removed completely.
204 flags_state_->SetFeatureEntryEnabled(&flags_storage_, kFlags1, false);
205 flags_state_->SetFeatureEntryEnabled(&flags_storage_, kFlags2, false);
206 entries_list = prefs_.GetList(prefs::kEnabledLabsExperiments);
207 EXPECT_TRUE(entries_list == nullptr || entries_list->GetSize() == 0);
208 }
209
210 TEST_F(FlagsStateTest, ConvertFlagsToSwitches) {
211 flags_state_->SetFeatureEntryEnabled(&flags_storage_, kFlags1, true);
212
213 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
214 command_line.AppendSwitch("foo");
215
216 EXPECT_TRUE(command_line.HasSwitch("foo"));
217 EXPECT_FALSE(command_line.HasSwitch(kSwitch1));
218
219 flags_state_->ConvertFlagsToSwitches(&flags_storage_, &command_line,
220 kAddSentinels, kEnableFeatures,
221 kDisableFeatures);
222
223 EXPECT_TRUE(command_line.HasSwitch("foo"));
224 EXPECT_TRUE(command_line.HasSwitch(kSwitch1));
225 EXPECT_TRUE(command_line.HasSwitch(switches::kFlagSwitchesBegin));
226 EXPECT_TRUE(command_line.HasSwitch(switches::kFlagSwitchesEnd));
227
228 base::CommandLine command_line2(base::CommandLine::NO_PROGRAM);
229
230 flags_state_->ConvertFlagsToSwitches(&flags_storage_, &command_line2,
231 kNoSentinels, kEnableFeatures,
232 kDisableFeatures);
233
234 EXPECT_TRUE(command_line2.HasSwitch(kSwitch1));
235 EXPECT_FALSE(command_line2.HasSwitch(switches::kFlagSwitchesBegin));
236 EXPECT_FALSE(command_line2.HasSwitch(switches::kFlagSwitchesEnd));
237 }
238
239 base::CommandLine::StringType CreateSwitch(const std::string& value) {
240 #if defined(OS_WIN)
241 return base::ASCIIToUTF16(value);
242 #else
243 return value;
244 #endif
245 }
246
247 TEST_F(FlagsStateTest, CompareSwitchesToCurrentCommandLine) {
248 flags_state_->SetFeatureEntryEnabled(&flags_storage_, kFlags1, true);
249
250 const std::string kDoubleDash("--");
251
252 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
253 command_line.AppendSwitch("foo");
254
255 base::CommandLine new_command_line(base::CommandLine::NO_PROGRAM);
256 flags_state_->ConvertFlagsToSwitches(&flags_storage_, &new_command_line,
257 kAddSentinels, kEnableFeatures,
258 kDisableFeatures);
259
260 EXPECT_FALSE(FlagsState::AreSwitchesIdenticalToCurrentCommandLine(
261 new_command_line, command_line, nullptr, nullptr, nullptr));
262 {
263 std::set<base::CommandLine::StringType> difference;
264 EXPECT_FALSE(FlagsState::AreSwitchesIdenticalToCurrentCommandLine(
265 new_command_line, command_line, &difference, nullptr, nullptr));
266 EXPECT_EQ(1U, difference.size());
267 EXPECT_EQ(1U, difference.count(CreateSwitch(kDoubleDash + kSwitch1)));
268 }
269
270 flags_state_->ConvertFlagsToSwitches(&flags_storage_, &command_line,
271 kAddSentinels, kEnableFeatures,
272 kDisableFeatures);
273
274 EXPECT_TRUE(FlagsState::AreSwitchesIdenticalToCurrentCommandLine(
275 new_command_line, command_line, nullptr, nullptr, nullptr));
276 {
277 std::set<base::CommandLine::StringType> difference;
278 EXPECT_TRUE(FlagsState::AreSwitchesIdenticalToCurrentCommandLine(
279 new_command_line, command_line, &difference, nullptr, nullptr));
280 EXPECT_TRUE(difference.empty());
281 }
282
283 // Now both have flags but different.
284 flags_state_->SetFeatureEntryEnabled(&flags_storage_, kFlags1, false);
285 flags_state_->SetFeatureEntryEnabled(&flags_storage_, kFlags2, true);
286
287 base::CommandLine another_command_line(base::CommandLine::NO_PROGRAM);
288 flags_state_->ConvertFlagsToSwitches(&flags_storage_, &another_command_line,
289 kAddSentinels, kEnableFeatures,
290 kDisableFeatures);
291
292 EXPECT_FALSE(FlagsState::AreSwitchesIdenticalToCurrentCommandLine(
293 new_command_line, another_command_line, nullptr, nullptr, nullptr));
294 {
295 std::set<base::CommandLine::StringType> difference;
296 EXPECT_FALSE(FlagsState::AreSwitchesIdenticalToCurrentCommandLine(
297 new_command_line, another_command_line, &difference, nullptr, nullptr));
298 EXPECT_EQ(2U, difference.size());
299 EXPECT_EQ(1U, difference.count(CreateSwitch(kDoubleDash + kSwitch1)));
300 EXPECT_EQ(1U, difference.count(CreateSwitch(kDoubleDash + kSwitch2 + "=" +
301 kValueForSwitch2)));
302 }
303 }
304
305 TEST_F(FlagsStateTest, RemoveFlagSwitches) {
306 std::map<std::string, base::CommandLine::StringType> switch_list;
307 switch_list[kSwitch1] = base::CommandLine::StringType();
308 switch_list[switches::kFlagSwitchesBegin] = base::CommandLine::StringType();
309 switch_list[switches::kFlagSwitchesEnd] = base::CommandLine::StringType();
310 switch_list["foo"] = base::CommandLine::StringType();
311
312 flags_state_->SetFeatureEntryEnabled(&flags_storage_, kFlags1, true);
313
314 // This shouldn't do anything before ConvertFlagsToSwitches() wasn't called.
315 flags_state_->RemoveFlagsSwitches(&switch_list);
316 ASSERT_EQ(4u, switch_list.size());
317 EXPECT_TRUE(ContainsKey(switch_list, kSwitch1));
318 EXPECT_TRUE(ContainsKey(switch_list, switches::kFlagSwitchesBegin));
319 EXPECT_TRUE(ContainsKey(switch_list, switches::kFlagSwitchesEnd));
320 EXPECT_TRUE(ContainsKey(switch_list, "foo"));
321
322 // Call ConvertFlagsToSwitches(), then RemoveFlagsSwitches() again.
323 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
324 command_line.AppendSwitch("foo");
325 flags_state_->ConvertFlagsToSwitches(&flags_storage_, &command_line,
326 kAddSentinels, kEnableFeatures,
327 kDisableFeatures);
328 flags_state_->RemoveFlagsSwitches(&switch_list);
329
330 // Now the about:flags-related switch should have been removed.
331 ASSERT_EQ(1u, switch_list.size());
332 EXPECT_TRUE(ContainsKey(switch_list, "foo"));
333 }
334
335 TEST_F(FlagsStateTest, RemoveFlagSwitches_Features) {
336 struct {
337 int enabled_choice; // 0: default, 1: enabled, 2: disabled.
338 const char* existing_enable_features;
339 const char* existing_disable_features;
340 const char* expected_enable_features;
341 const char* expected_disable_features;
342 } cases[] = {
343 // Default value: Should not affect existing flags.
344 {0, nullptr, nullptr, nullptr, nullptr},
345 {0, "A,B", "C", "A,B", "C"},
346 // "Enable" option: should only affect enabled list.
347 {1, nullptr, nullptr, "FeatureName", nullptr},
348 {1, "A,B", "C", "A,B,FeatureName", "C"},
349 // "Disable" option: should only affect disabled list.
350 {2, nullptr, nullptr, nullptr, "FeatureName"},
351 {2, "A,B", "C", "A,B", "C,FeatureName"},
352 };
353
354 for (size_t i = 0; i < arraysize(cases); ++i) {
355 SCOPED_TRACE(base::StringPrintf(
356 "Test[%" PRIuS "]: %d [%s] [%s]", i, cases[i].enabled_choice,
357 cases[i].existing_enable_features ? cases[i].existing_enable_features
358 : "null",
359 cases[i].existing_disable_features ? cases[i].existing_disable_features
360 : "null"));
361
362 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
363 if (cases[i].existing_enable_features) {
364 command_line.AppendSwitchASCII(kEnableFeatures,
365 cases[i].existing_enable_features);
366 }
367 if (cases[i].existing_disable_features) {
368 command_line.AppendSwitchASCII(kDisableFeatures,
369 cases[i].existing_disable_features);
370 }
371
372 flags_state_->Reset();
373
374 const std::string entry_name = base::StringPrintf(
375 "%s%s%d", kFlags7, testing::kMultiSeparator, cases[i].enabled_choice);
376 flags_state_->SetFeatureEntryEnabled(&flags_storage_, entry_name, true);
377
378 flags_state_->ConvertFlagsToSwitches(&flags_storage_, &command_line,
379 kAddSentinels, kEnableFeatures,
380 kDisableFeatures);
381 auto switch_list = command_line.GetSwitches();
382 EXPECT_EQ(cases[i].expected_enable_features != nullptr,
383 ContainsKey(switch_list, kEnableFeatures));
384 if (cases[i].expected_enable_features)
385 EXPECT_EQ(CreateSwitch(cases[i].expected_enable_features),
386 switch_list[kEnableFeatures]);
387
388 EXPECT_EQ(cases[i].expected_disable_features != nullptr,
389 ContainsKey(switch_list, kDisableFeatures));
390 if (cases[i].expected_disable_features)
391 EXPECT_EQ(CreateSwitch(cases[i].expected_disable_features),
392 switch_list[kDisableFeatures]);
393
394 // RemoveFlagsSwitches() should result in the original values for these
395 // switches.
396 switch_list = command_line.GetSwitches();
397 flags_state_->RemoveFlagsSwitches(&switch_list);
398 EXPECT_EQ(cases[i].existing_enable_features != nullptr,
399 ContainsKey(switch_list, kEnableFeatures));
400 if (cases[i].existing_enable_features)
401 EXPECT_EQ(CreateSwitch(cases[i].existing_enable_features),
402 switch_list[kEnableFeatures]);
403 EXPECT_EQ(cases[i].existing_disable_features != nullptr,
404 ContainsKey(switch_list, kEnableFeatures));
405 if (cases[i].existing_disable_features)
406 EXPECT_EQ(CreateSwitch(cases[i].existing_disable_features),
407 switch_list[kDisableFeatures]);
408 }
409 }
410
411 // Tests enabling entries that aren't supported on the current platform.
412 TEST_F(FlagsStateTest, PersistAndPrune) {
413 // Enable entries 1 and 3.
414 flags_state_->SetFeatureEntryEnabled(&flags_storage_, kFlags1, true);
415 flags_state_->SetFeatureEntryEnabled(&flags_storage_, kFlags3, true);
416 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
417 EXPECT_FALSE(command_line.HasSwitch(kSwitch1));
418 EXPECT_FALSE(command_line.HasSwitch(kSwitch3));
419
420 // Convert the flags to switches. Entry 3 shouldn't be among the switches
421 // as it is not applicable to the current platform.
422 flags_state_->ConvertFlagsToSwitches(&flags_storage_, &command_line,
423 kAddSentinels, kEnableFeatures,
424 kDisableFeatures);
425 EXPECT_TRUE(command_line.HasSwitch(kSwitch1));
426 EXPECT_FALSE(command_line.HasSwitch(kSwitch3));
427
428 // FeatureEntry 3 should show still be persisted in preferences though.
429 const base::ListValue* entries_list =
430 prefs_.GetList(prefs::kEnabledLabsExperiments);
431 ASSERT_TRUE(entries_list);
432 EXPECT_EQ(2U, entries_list->GetSize());
433 std::string s0;
434 ASSERT_TRUE(entries_list->GetString(0, &s0));
435 EXPECT_EQ(kFlags1, s0);
436 std::string s1;
437 ASSERT_TRUE(entries_list->GetString(1, &s1));
438 EXPECT_EQ(kFlags3, s1);
439 }
440
441 // Tests that switches which should have values get them in the command
442 // line.
443 TEST_F(FlagsStateTest, CheckValues) {
444 // Enable entries 1 and 2.
445 flags_state_->SetFeatureEntryEnabled(&flags_storage_, kFlags1, true);
446 flags_state_->SetFeatureEntryEnabled(&flags_storage_, kFlags2, true);
447 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
448 EXPECT_FALSE(command_line.HasSwitch(kSwitch1));
449 EXPECT_FALSE(command_line.HasSwitch(kSwitch2));
450
451 // Convert the flags to switches.
452 flags_state_->ConvertFlagsToSwitches(&flags_storage_, &command_line,
453 kAddSentinels, kEnableFeatures,
454 kDisableFeatures);
455 EXPECT_TRUE(command_line.HasSwitch(kSwitch1));
456 EXPECT_EQ(std::string(), command_line.GetSwitchValueASCII(kSwitch1));
457 EXPECT_TRUE(command_line.HasSwitch(kSwitch2));
458 EXPECT_EQ(std::string(kValueForSwitch2),
459 command_line.GetSwitchValueASCII(kSwitch2));
460
461 // Confirm that there is no '=' in the command line for simple switches.
462 std::string switch1_with_equals =
463 std::string("--") + std::string(kSwitch1) + std::string("=");
464 #if defined(OS_WIN)
465 EXPECT_EQ(base::string16::npos, command_line.GetCommandLineString().find(
466 base::ASCIIToUTF16(switch1_with_equals)));
467 #else
468 EXPECT_EQ(std::string::npos,
469 command_line.GetCommandLineString().find(switch1_with_equals));
470 #endif
471
472 // And confirm there is a '=' for switches with values.
473 std::string switch2_with_equals =
474 std::string("--") + std::string(kSwitch2) + std::string("=");
475 #if defined(OS_WIN)
476 EXPECT_NE(base::string16::npos, command_line.GetCommandLineString().find(
477 base::ASCIIToUTF16(switch2_with_equals)));
478 #else
479 EXPECT_NE(std::string::npos,
480 command_line.GetCommandLineString().find(switch2_with_equals));
481 #endif
482
483 // And it should persist.
484 const base::ListValue* entries_list =
485 prefs_.GetList(prefs::kEnabledLabsExperiments);
486 ASSERT_TRUE(entries_list);
487 EXPECT_EQ(2U, entries_list->GetSize());
488 std::string s0;
489 ASSERT_TRUE(entries_list->GetString(0, &s0));
490 EXPECT_EQ(kFlags1, s0);
491 std::string s1;
492 ASSERT_TRUE(entries_list->GetString(1, &s1));
493 EXPECT_EQ(kFlags2, s1);
494 }
495
496 // Tests multi-value type entries.
497 TEST_F(FlagsStateTest, MultiValues) {
498 const FeatureEntry& entry = kEntries[3];
499 ASSERT_EQ(kFlags4, entry.internal_name);
500
501 // Initially, the first "deactivated" option of the multi entry should
502 // be set.
503 {
504 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
505 flags_state_->ConvertFlagsToSwitches(&flags_storage_, &command_line,
506 kAddSentinels, kEnableFeatures,
507 kDisableFeatures);
508 EXPECT_FALSE(command_line.HasSwitch(kMultiSwitch1));
509 EXPECT_FALSE(command_line.HasSwitch(kMultiSwitch2));
510 }
511
512 // Enable the 2nd choice of the multi-value.
513 flags_state_->SetFeatureEntryEnabled(&flags_storage_, entry.NameForChoice(2),
514 true);
515 {
516 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
517 flags_state_->ConvertFlagsToSwitches(&flags_storage_, &command_line,
518 kAddSentinels, kEnableFeatures,
519 kDisableFeatures);
520 EXPECT_FALSE(command_line.HasSwitch(kMultiSwitch1));
521 EXPECT_TRUE(command_line.HasSwitch(kMultiSwitch2));
522 EXPECT_EQ(std::string(kValueForMultiSwitch2),
523 command_line.GetSwitchValueASCII(kMultiSwitch2));
524 }
525
526 // Disable the multi-value entry.
527 flags_state_->SetFeatureEntryEnabled(&flags_storage_, entry.NameForChoice(0),
528 true);
529 {
530 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
531 flags_state_->ConvertFlagsToSwitches(&flags_storage_, &command_line,
532 kAddSentinels, kEnableFeatures,
533 kDisableFeatures);
534 EXPECT_FALSE(command_line.HasSwitch(kMultiSwitch1));
535 EXPECT_FALSE(command_line.HasSwitch(kMultiSwitch2));
536 }
537 }
538
539 // Tests that disable flags are added when an entry is disabled.
540 TEST_F(FlagsStateTest, DisableFlagCommandLine) {
541 // Nothing selected.
542 {
543 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
544 flags_state_->ConvertFlagsToSwitches(&flags_storage_, &command_line,
545 kAddSentinels, kEnableFeatures,
546 kDisableFeatures);
547 EXPECT_FALSE(command_line.HasSwitch(kSwitch6));
548 }
549
550 // Disable the entry 6.
551 flags_state_->SetFeatureEntryEnabled(&flags_storage_, kFlags6, false);
552 {
553 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
554 flags_state_->ConvertFlagsToSwitches(&flags_storage_, &command_line,
555 kAddSentinels, kEnableFeatures,
556 kDisableFeatures);
557 EXPECT_TRUE(command_line.HasSwitch(kSwitch6));
558 }
559
560 // Enable entry 6.
561 flags_state_->SetFeatureEntryEnabled(&flags_storage_, kFlags6, true);
562 {
563 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
564 flags_state_->ConvertFlagsToSwitches(&flags_storage_, &command_line,
565 kAddSentinels, kEnableFeatures,
566 kDisableFeatures);
567 EXPECT_FALSE(command_line.HasSwitch(kSwitch6));
568 }
569 }
570
571 TEST_F(FlagsStateTest, EnableDisableValues) {
572 const FeatureEntry& entry = kEntries[4];
573 ASSERT_EQ(kFlags5, entry.internal_name);
574
575 // Nothing selected.
576 {
577 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
578 flags_state_->ConvertFlagsToSwitches(&flags_storage_, &command_line,
579 kAddSentinels, kEnableFeatures,
580 kDisableFeatures);
581 EXPECT_FALSE(command_line.HasSwitch(kSwitch1));
582 EXPECT_FALSE(command_line.HasSwitch(kSwitch2));
583 }
584
585 // "Enable" option selected.
586 flags_state_->SetFeatureEntryEnabled(&flags_storage_, entry.NameForChoice(1),
587 true);
588 {
589 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
590 flags_state_->ConvertFlagsToSwitches(&flags_storage_, &command_line,
591 kAddSentinels, kEnableFeatures,
592 kDisableFeatures);
593 EXPECT_TRUE(command_line.HasSwitch(kSwitch1));
594 EXPECT_FALSE(command_line.HasSwitch(kSwitch2));
595 EXPECT_EQ(kEnableDisableValue1, command_line.GetSwitchValueASCII(kSwitch1));
596 }
597
598 // "Disable" option selected.
599 flags_state_->SetFeatureEntryEnabled(&flags_storage_, entry.NameForChoice(2),
600 true);
601 {
602 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
603 flags_state_->ConvertFlagsToSwitches(&flags_storage_, &command_line,
604 kAddSentinels, kEnableFeatures,
605 kDisableFeatures);
606 EXPECT_FALSE(command_line.HasSwitch(kSwitch1));
607 EXPECT_TRUE(command_line.HasSwitch(kSwitch2));
608 EXPECT_EQ(kEnableDisableValue2, command_line.GetSwitchValueASCII(kSwitch2));
609 }
610
611 // "Default" option selected, same as nothing selected.
612 flags_state_->SetFeatureEntryEnabled(&flags_storage_, entry.NameForChoice(0),
613 true);
614 {
615 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
616 flags_state_->ConvertFlagsToSwitches(&flags_storage_, &command_line,
617 kAddSentinels, kEnableFeatures,
618 kDisableFeatures);
619 EXPECT_FALSE(command_line.HasSwitch(kMultiSwitch1));
620 EXPECT_FALSE(command_line.HasSwitch(kMultiSwitch2));
621 }
622 }
623
624 TEST_F(FlagsStateTest, FeatureValues) {
625 const FeatureEntry& entry = kEntries[6];
626 ASSERT_EQ(kFlags7, entry.internal_name);
627
628 struct {
629 int enabled_choice;
630 const char* existing_enable_features;
631 const char* existing_disable_features;
632 const char* expected_enable_features;
633 const char* expected_disable_features;
634 } cases[] = {
635 // Nothing selected.
636 {-1, nullptr, nullptr, "", ""},
637 // "Default" option selected, same as nothing selected.
638 {0, nullptr, nullptr, "", ""},
639 // "Enable" option selected.
640 {1, nullptr, nullptr, "FeatureName", ""},
641 // "Disable" option selected.
642 {2, nullptr, nullptr, "", "FeatureName"},
643 // "Enable" option should get added to the existing list.
644 {1, "Foo,Bar", nullptr, "Foo,Bar,FeatureName", ""},
645 // "Disable" option should get added to the existing list.
646 {2, nullptr, "Foo,Bar", "", "Foo,Bar,FeatureName"},
647 };
648
649 for (size_t i = 0; i < arraysize(cases); ++i) {
650 SCOPED_TRACE(base::StringPrintf(
651 "Test[%" PRIuS "]: %d [%s] [%s]", i, cases[i].enabled_choice,
652 cases[i].existing_enable_features ? cases[i].existing_enable_features
653 : "null",
654 cases[i].existing_disable_features ? cases[i].existing_disable_features
655 : "null"));
656
657 if (cases[i].enabled_choice != -1) {
658 flags_state_->SetFeatureEntryEnabled(
659 &flags_storage_, entry.NameForChoice(cases[i].enabled_choice), true);
660 }
661
662 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
663 if (cases[i].existing_enable_features) {
664 command_line.AppendSwitchASCII(kEnableFeatures,
665 cases[i].existing_enable_features);
666 }
667 if (cases[i].existing_disable_features) {
668 command_line.AppendSwitchASCII(kDisableFeatures,
669 cases[i].existing_disable_features);
670 }
671
672 flags_state_->ConvertFlagsToSwitches(&flags_storage_, &command_line,
673 kAddSentinels, kEnableFeatures,
674 kDisableFeatures);
675 EXPECT_EQ(cases[i].expected_enable_features,
676 command_line.GetSwitchValueASCII(kEnableFeatures));
677 EXPECT_EQ(cases[i].expected_disable_features,
678 command_line.GetSwitchValueASCII(kDisableFeatures));
679 }
680 }
681
682 TEST_F(FlagsStateTest, GetFlagFeatureEntries) {
683 base::ListValue supported_entries;
684 base::ListValue unsupported_entries;
685 flags_state_->GetFlagFeatureEntries(&flags_storage_, kGeneralAccessFlagsOnly,
686 &supported_entries, &unsupported_entries,
687 base::Bind(&SkipFeatureEntry));
688 // All |kEntries| except for |kFlags3| should be supported.
689 EXPECT_EQ(6u, supported_entries.GetSize());
690 EXPECT_EQ(1u, unsupported_entries.GetSize());
691 EXPECT_EQ(arraysize(kEntries),
692 supported_entries.GetSize() + unsupported_entries.GetSize());
693 }
694
695 } // namespace flags_ui
OLDNEW
« no previous file with comments | « components/flags_ui/flags_state.cc ('k') | components/flags_ui/flags_ui_switches.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698