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

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

Powered by Google App Engine
This is Rietveld 408576698