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

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

Powered by Google App Engine
This is Rietveld 408576698