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 "base/feature_list.h"
6
7 #include <stddef.h>
8
9 #include <algorithm>
10 #include <utility>
11
12 #include "base/format_macros.h"
13 #include "base/macros.h"
14 #include "base/memory/ptr_util.h"
15 #include "base/metrics/field_trial.h"
16 #include "base/strings/string_util.h"
17 #include "base/strings/stringprintf.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19
20 namespace base {
21
22 namespace {
23
24 const char kFeatureOnByDefaultName[] = "OnByDefault";
25 struct Feature kFeatureOnByDefault {
26 kFeatureOnByDefaultName, FEATURE_ENABLED_BY_DEFAULT
27 };
28
29 const char kFeatureOffByDefaultName[] = "OffByDefault";
30 struct Feature kFeatureOffByDefault {
31 kFeatureOffByDefaultName, FEATURE_DISABLED_BY_DEFAULT
32 };
33
SortFeatureListString(const std::string & feature_list)34 std::string SortFeatureListString(const std::string& feature_list) {
35 std::vector<std::string> features =
36 FeatureList::SplitFeatureListString(feature_list);
37 std::sort(features.begin(), features.end());
38 return JoinString(features, ",");
39 }
40
41 } // namespace
42
43 class FeatureListTest : public testing::Test {
44 public:
FeatureListTest()45 FeatureListTest() : feature_list_(nullptr) {
46 RegisterFeatureListInstance(WrapUnique(new FeatureList));
47 }
~FeatureListTest()48 ~FeatureListTest() override { ClearFeatureListInstance(); }
49
RegisterFeatureListInstance(std::unique_ptr<FeatureList> feature_list)50 void RegisterFeatureListInstance(std::unique_ptr<FeatureList> feature_list) {
51 FeatureList::ClearInstanceForTesting();
52 feature_list_ = feature_list.get();
53 FeatureList::SetInstance(std::move(feature_list));
54 }
ClearFeatureListInstance()55 void ClearFeatureListInstance() {
56 FeatureList::ClearInstanceForTesting();
57 feature_list_ = nullptr;
58 }
59
feature_list()60 FeatureList* feature_list() { return feature_list_; }
61
62 private:
63 // Weak. Owned by the FeatureList::SetInstance().
64 FeatureList* feature_list_;
65
66 DISALLOW_COPY_AND_ASSIGN(FeatureListTest);
67 };
68
TEST_F(FeatureListTest,DefaultStates)69 TEST_F(FeatureListTest, DefaultStates) {
70 EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOnByDefault));
71 EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOffByDefault));
72 }
73
TEST_F(FeatureListTest,InitializeFromCommandLine)74 TEST_F(FeatureListTest, InitializeFromCommandLine) {
75 struct {
76 const char* enable_features;
77 const char* disable_features;
78 bool expected_feature_on_state;
79 bool expected_feature_off_state;
80 } test_cases[] = {
81 {"", "", true, false},
82 {"OffByDefault", "", true, true},
83 {"OffByDefault", "OnByDefault", false, true},
84 {"OnByDefault,OffByDefault", "", true, true},
85 {"", "OnByDefault,OffByDefault", false, false},
86 // In the case an entry is both, disable takes precedence.
87 {"OnByDefault", "OnByDefault,OffByDefault", false, false},
88 };
89
90 for (size_t i = 0; i < arraysize(test_cases); ++i) {
91 const auto& test_case = test_cases[i];
92 SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]: [%s] [%s]", i,
93 test_case.enable_features,
94 test_case.disable_features));
95
96 ClearFeatureListInstance();
97 std::unique_ptr<FeatureList> feature_list(new FeatureList);
98 feature_list->InitializeFromCommandLine(test_case.enable_features,
99 test_case.disable_features);
100 RegisterFeatureListInstance(std::move(feature_list));
101
102 EXPECT_EQ(test_case.expected_feature_on_state,
103 FeatureList::IsEnabled(kFeatureOnByDefault))
104 << i;
105 EXPECT_EQ(test_case.expected_feature_off_state,
106 FeatureList::IsEnabled(kFeatureOffByDefault))
107 << i;
108 }
109 }
110
TEST_F(FeatureListTest,CheckFeatureIdentity)111 TEST_F(FeatureListTest, CheckFeatureIdentity) {
112 // Tests that CheckFeatureIdentity() correctly detects when two different
113 // structs with the same feature name are passed to it.
114
115 // Call it twice for each feature at the top of the file, since the first call
116 // makes it remember the entry and the second call will verify it.
117 EXPECT_TRUE(feature_list()->CheckFeatureIdentity(kFeatureOnByDefault));
118 EXPECT_TRUE(feature_list()->CheckFeatureIdentity(kFeatureOnByDefault));
119 EXPECT_TRUE(feature_list()->CheckFeatureIdentity(kFeatureOffByDefault));
120 EXPECT_TRUE(feature_list()->CheckFeatureIdentity(kFeatureOffByDefault));
121
122 // Now, call it with a distinct struct for |kFeatureOnByDefaultName|, which
123 // should return false.
124 struct Feature kFeatureOnByDefault2 {
125 kFeatureOnByDefaultName, FEATURE_ENABLED_BY_DEFAULT
126 };
127 EXPECT_FALSE(feature_list()->CheckFeatureIdentity(kFeatureOnByDefault2));
128 }
129
TEST_F(FeatureListTest,FieldTrialOverrides)130 TEST_F(FeatureListTest, FieldTrialOverrides) {
131 struct {
132 FeatureList::OverrideState trial1_state;
133 FeatureList::OverrideState trial2_state;
134 } test_cases[] = {
135 {FeatureList::OVERRIDE_DISABLE_FEATURE,
136 FeatureList::OVERRIDE_DISABLE_FEATURE},
137 {FeatureList::OVERRIDE_DISABLE_FEATURE,
138 FeatureList::OVERRIDE_ENABLE_FEATURE},
139 {FeatureList::OVERRIDE_ENABLE_FEATURE,
140 FeatureList::OVERRIDE_DISABLE_FEATURE},
141 {FeatureList::OVERRIDE_ENABLE_FEATURE,
142 FeatureList::OVERRIDE_ENABLE_FEATURE},
143 };
144
145 FieldTrial::ActiveGroup active_group;
146 for (size_t i = 0; i < arraysize(test_cases); ++i) {
147 const auto& test_case = test_cases[i];
148 SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]", i));
149
150 ClearFeatureListInstance();
151
152 FieldTrialList field_trial_list(nullptr);
153 std::unique_ptr<FeatureList> feature_list(new FeatureList);
154
155 FieldTrial* trial1 = FieldTrialList::CreateFieldTrial("TrialExample1", "A");
156 FieldTrial* trial2 = FieldTrialList::CreateFieldTrial("TrialExample2", "B");
157 feature_list->RegisterFieldTrialOverride(kFeatureOnByDefaultName,
158 test_case.trial1_state, trial1);
159 feature_list->RegisterFieldTrialOverride(kFeatureOffByDefaultName,
160 test_case.trial2_state, trial2);
161 RegisterFeatureListInstance(std::move(feature_list));
162
163 // Initially, neither trial should be active.
164 EXPECT_FALSE(FieldTrialList::IsTrialActive(trial1->trial_name()));
165 EXPECT_FALSE(FieldTrialList::IsTrialActive(trial2->trial_name()));
166
167 const bool expected_enabled_1 =
168 (test_case.trial1_state == FeatureList::OVERRIDE_ENABLE_FEATURE);
169 EXPECT_EQ(expected_enabled_1, FeatureList::IsEnabled(kFeatureOnByDefault));
170 // The above should have activated |trial1|.
171 EXPECT_TRUE(FieldTrialList::IsTrialActive(trial1->trial_name()));
172 EXPECT_FALSE(FieldTrialList::IsTrialActive(trial2->trial_name()));
173
174 const bool expected_enabled_2 =
175 (test_case.trial2_state == FeatureList::OVERRIDE_ENABLE_FEATURE);
176 EXPECT_EQ(expected_enabled_2, FeatureList::IsEnabled(kFeatureOffByDefault));
177 // The above should have activated |trial2|.
178 EXPECT_TRUE(FieldTrialList::IsTrialActive(trial1->trial_name()));
179 EXPECT_TRUE(FieldTrialList::IsTrialActive(trial2->trial_name()));
180 }
181 }
182
TEST_F(FeatureListTest,FieldTrialAssociateUseDefault)183 TEST_F(FeatureListTest, FieldTrialAssociateUseDefault) {
184 FieldTrialList field_trial_list(nullptr);
185 std::unique_ptr<FeatureList> feature_list(new FeatureList);
186
187 FieldTrial* trial1 = FieldTrialList::CreateFieldTrial("TrialExample1", "A");
188 FieldTrial* trial2 = FieldTrialList::CreateFieldTrial("TrialExample2", "B");
189 feature_list->RegisterFieldTrialOverride(
190 kFeatureOnByDefaultName, FeatureList::OVERRIDE_USE_DEFAULT, trial1);
191 feature_list->RegisterFieldTrialOverride(
192 kFeatureOffByDefaultName, FeatureList::OVERRIDE_USE_DEFAULT, trial2);
193 RegisterFeatureListInstance(std::move(feature_list));
194
195 // Initially, neither trial should be active.
196 EXPECT_FALSE(FieldTrialList::IsTrialActive(trial1->trial_name()));
197 EXPECT_FALSE(FieldTrialList::IsTrialActive(trial2->trial_name()));
198
199 // Check the feature enabled state is its default.
200 EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOnByDefault));
201 // The above should have activated |trial1|.
202 EXPECT_TRUE(FieldTrialList::IsTrialActive(trial1->trial_name()));
203 EXPECT_FALSE(FieldTrialList::IsTrialActive(trial2->trial_name()));
204
205 // Check the feature enabled state is its default.
206 EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOffByDefault));
207 // The above should have activated |trial2|.
208 EXPECT_TRUE(FieldTrialList::IsTrialActive(trial1->trial_name()));
209 EXPECT_TRUE(FieldTrialList::IsTrialActive(trial2->trial_name()));
210 }
211
TEST_F(FeatureListTest,CommandLineTakesPrecedenceOverFieldTrial)212 TEST_F(FeatureListTest, CommandLineTakesPrecedenceOverFieldTrial) {
213 ClearFeatureListInstance();
214
215 FieldTrialList field_trial_list(nullptr);
216 std::unique_ptr<FeatureList> feature_list(new FeatureList);
217
218 // The feature is explicitly enabled on the command-line.
219 feature_list->InitializeFromCommandLine(kFeatureOffByDefaultName, "");
220
221 // But the FieldTrial would set the feature to disabled.
222 FieldTrial* trial = FieldTrialList::CreateFieldTrial("TrialExample2", "A");
223 feature_list->RegisterFieldTrialOverride(
224 kFeatureOffByDefaultName, FeatureList::OVERRIDE_DISABLE_FEATURE, trial);
225 RegisterFeatureListInstance(std::move(feature_list));
226
227 EXPECT_FALSE(FieldTrialList::IsTrialActive(trial->trial_name()));
228 // Command-line should take precedence.
229 EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOffByDefault));
230 // Since the feature is on due to the command-line, and not as a result of the
231 // field trial, the field trial should not be activated (since the Associate*
232 // API wasn't used.)
233 EXPECT_FALSE(FieldTrialList::IsTrialActive(trial->trial_name()));
234 }
235
TEST_F(FeatureListTest,IsFeatureOverriddenFromCommandLine)236 TEST_F(FeatureListTest, IsFeatureOverriddenFromCommandLine) {
237 ClearFeatureListInstance();
238
239 FieldTrialList field_trial_list(nullptr);
240 std::unique_ptr<FeatureList> feature_list(new FeatureList);
241
242 // No features are overridden from the command line yet
243 EXPECT_FALSE(feature_list->IsFeatureOverriddenFromCommandLine(
244 kFeatureOnByDefaultName, FeatureList::OVERRIDE_DISABLE_FEATURE));
245 EXPECT_FALSE(feature_list->IsFeatureOverriddenFromCommandLine(
246 kFeatureOnByDefaultName, FeatureList::OVERRIDE_ENABLE_FEATURE));
247 EXPECT_FALSE(feature_list->IsFeatureOverriddenFromCommandLine(
248 kFeatureOffByDefaultName, FeatureList::OVERRIDE_DISABLE_FEATURE));
249 EXPECT_FALSE(feature_list->IsFeatureOverriddenFromCommandLine(
250 kFeatureOffByDefaultName, FeatureList::OVERRIDE_ENABLE_FEATURE));
251
252 // Now, enable |kFeatureOffByDefaultName| via the command-line.
253 feature_list->InitializeFromCommandLine(kFeatureOffByDefaultName, "");
254
255 // It should now be overridden for the enabled group.
256 EXPECT_FALSE(feature_list->IsFeatureOverriddenFromCommandLine(
257 kFeatureOffByDefaultName, FeatureList::OVERRIDE_DISABLE_FEATURE));
258 EXPECT_TRUE(feature_list->IsFeatureOverriddenFromCommandLine(
259 kFeatureOffByDefaultName, FeatureList::OVERRIDE_ENABLE_FEATURE));
260
261 // Register a field trial to associate with the feature and ensure that the
262 // results are still the same.
263 feature_list->AssociateReportingFieldTrial(
264 kFeatureOffByDefaultName, FeatureList::OVERRIDE_ENABLE_FEATURE,
265 FieldTrialList::CreateFieldTrial("Trial1", "A"));
266 EXPECT_FALSE(feature_list->IsFeatureOverriddenFromCommandLine(
267 kFeatureOffByDefaultName, FeatureList::OVERRIDE_DISABLE_FEATURE));
268 EXPECT_TRUE(feature_list->IsFeatureOverriddenFromCommandLine(
269 kFeatureOffByDefaultName, FeatureList::OVERRIDE_ENABLE_FEATURE));
270
271 // Now, register a field trial to override |kFeatureOnByDefaultName| state
272 // and check that the function still returns false for that feature.
273 feature_list->RegisterFieldTrialOverride(
274 kFeatureOnByDefaultName, FeatureList::OVERRIDE_DISABLE_FEATURE,
275 FieldTrialList::CreateFieldTrial("Trial2", "A"));
276 EXPECT_FALSE(feature_list->IsFeatureOverriddenFromCommandLine(
277 kFeatureOnByDefaultName, FeatureList::OVERRIDE_DISABLE_FEATURE));
278 EXPECT_FALSE(feature_list->IsFeatureOverriddenFromCommandLine(
279 kFeatureOnByDefaultName, FeatureList::OVERRIDE_ENABLE_FEATURE));
280 RegisterFeatureListInstance(std::move(feature_list));
281
282 // Check the expected feature states for good measure.
283 EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOffByDefault));
284 EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOnByDefault));
285 }
286
TEST_F(FeatureListTest,AssociateReportingFieldTrial)287 TEST_F(FeatureListTest, AssociateReportingFieldTrial) {
288 struct {
289 const char* enable_features;
290 const char* disable_features;
291 bool expected_enable_trial_created;
292 bool expected_disable_trial_created;
293 } test_cases[] = {
294 // If no enable/disable flags are specified, no trials should be created.
295 {"", "", false, false},
296 // Enabling the feature should result in the enable trial created.
297 {kFeatureOffByDefaultName, "", true, false},
298 // Disabling the feature should result in the disable trial created.
299 {"", kFeatureOffByDefaultName, false, true},
300 };
301
302 const char kTrialName[] = "ForcingTrial";
303 const char kForcedOnGroupName[] = "ForcedOn";
304 const char kForcedOffGroupName[] = "ForcedOff";
305
306 for (size_t i = 0; i < arraysize(test_cases); ++i) {
307 const auto& test_case = test_cases[i];
308 SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]: [%s] [%s]", i,
309 test_case.enable_features,
310 test_case.disable_features));
311
312 ClearFeatureListInstance();
313
314 FieldTrialList field_trial_list(nullptr);
315 std::unique_ptr<FeatureList> feature_list(new FeatureList);
316 feature_list->InitializeFromCommandLine(test_case.enable_features,
317 test_case.disable_features);
318
319 FieldTrial* enable_trial = nullptr;
320 if (feature_list->IsFeatureOverriddenFromCommandLine(
321 kFeatureOffByDefaultName, FeatureList::OVERRIDE_ENABLE_FEATURE)) {
322 enable_trial = base::FieldTrialList::CreateFieldTrial(kTrialName,
323 kForcedOnGroupName);
324 feature_list->AssociateReportingFieldTrial(
325 kFeatureOffByDefaultName, FeatureList::OVERRIDE_ENABLE_FEATURE,
326 enable_trial);
327 }
328 FieldTrial* disable_trial = nullptr;
329 if (feature_list->IsFeatureOverriddenFromCommandLine(
330 kFeatureOffByDefaultName, FeatureList::OVERRIDE_DISABLE_FEATURE)) {
331 disable_trial = base::FieldTrialList::CreateFieldTrial(
332 kTrialName, kForcedOffGroupName);
333 feature_list->AssociateReportingFieldTrial(
334 kFeatureOffByDefaultName, FeatureList::OVERRIDE_DISABLE_FEATURE,
335 disable_trial);
336 }
337 EXPECT_EQ(test_case.expected_enable_trial_created, enable_trial != nullptr);
338 EXPECT_EQ(test_case.expected_disable_trial_created,
339 disable_trial != nullptr);
340 RegisterFeatureListInstance(std::move(feature_list));
341
342 EXPECT_FALSE(FieldTrialList::IsTrialActive(kTrialName));
343 if (disable_trial) {
344 EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOffByDefault));
345 EXPECT_TRUE(FieldTrialList::IsTrialActive(kTrialName));
346 EXPECT_EQ(kForcedOffGroupName, disable_trial->group_name());
347 } else if (enable_trial) {
348 EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOffByDefault));
349 EXPECT_TRUE(FieldTrialList::IsTrialActive(kTrialName));
350 EXPECT_EQ(kForcedOnGroupName, enable_trial->group_name());
351 }
352 }
353 }
354
TEST_F(FeatureListTest,GetFeatureOverrides)355 TEST_F(FeatureListTest, GetFeatureOverrides) {
356 ClearFeatureListInstance();
357 FieldTrialList field_trial_list(nullptr);
358 std::unique_ptr<FeatureList> feature_list(new FeatureList);
359 feature_list->InitializeFromCommandLine("A,X", "D");
360
361 FieldTrial* trial = FieldTrialList::CreateFieldTrial("Trial", "Group");
362 feature_list->RegisterFieldTrialOverride(kFeatureOffByDefaultName,
363 FeatureList::OVERRIDE_ENABLE_FEATURE,
364 trial);
365
366 RegisterFeatureListInstance(std::move(feature_list));
367
368 std::string enable_features;
369 std::string disable_features;
370 FeatureList::GetInstance()->GetFeatureOverrides(&enable_features,
371 &disable_features);
372 EXPECT_EQ("A,OffByDefault<Trial,X", SortFeatureListString(enable_features));
373 EXPECT_EQ("D", SortFeatureListString(disable_features));
374 }
375
TEST_F(FeatureListTest,GetFeatureOverrides_UseDefault)376 TEST_F(FeatureListTest, GetFeatureOverrides_UseDefault) {
377 ClearFeatureListInstance();
378 FieldTrialList field_trial_list(nullptr);
379 std::unique_ptr<FeatureList> feature_list(new FeatureList);
380 feature_list->InitializeFromCommandLine("A,X", "D");
381
382 FieldTrial* trial = FieldTrialList::CreateFieldTrial("Trial", "Group");
383 feature_list->RegisterFieldTrialOverride(
384 kFeatureOffByDefaultName, FeatureList::OVERRIDE_USE_DEFAULT, trial);
385
386 RegisterFeatureListInstance(std::move(feature_list));
387
388 std::string enable_features;
389 std::string disable_features;
390 FeatureList::GetInstance()->GetFeatureOverrides(&enable_features,
391 &disable_features);
392 EXPECT_EQ("*OffByDefault<Trial,A,X", SortFeatureListString(enable_features));
393 EXPECT_EQ("D", SortFeatureListString(disable_features));
394 }
395
TEST_F(FeatureListTest,GetFieldTrial)396 TEST_F(FeatureListTest, GetFieldTrial) {
397 ClearFeatureListInstance();
398 FieldTrialList field_trial_list(nullptr);
399 FieldTrial* trial = FieldTrialList::CreateFieldTrial("Trial", "Group");
400 std::unique_ptr<FeatureList> feature_list(new FeatureList);
401 feature_list->RegisterFieldTrialOverride(
402 kFeatureOnByDefaultName, FeatureList::OVERRIDE_USE_DEFAULT, trial);
403 RegisterFeatureListInstance(std::move(feature_list));
404
405 EXPECT_EQ(trial, FeatureList::GetFieldTrial(kFeatureOnByDefault));
406 EXPECT_EQ(nullptr, FeatureList::GetFieldTrial(kFeatureOffByDefault));
407 }
408
TEST_F(FeatureListTest,InitializeFromCommandLine_WithFieldTrials)409 TEST_F(FeatureListTest, InitializeFromCommandLine_WithFieldTrials) {
410 ClearFeatureListInstance();
411 FieldTrialList field_trial_list(nullptr);
412 FieldTrialList::CreateFieldTrial("Trial", "Group");
413 std::unique_ptr<FeatureList> feature_list(new FeatureList);
414 feature_list->InitializeFromCommandLine("A,OffByDefault<Trial,X", "D");
415 RegisterFeatureListInstance(std::move(feature_list));
416
417 EXPECT_FALSE(FieldTrialList::IsTrialActive("Trial"));
418 EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOffByDefault));
419 EXPECT_TRUE(FieldTrialList::IsTrialActive("Trial"));
420 }
421
TEST_F(FeatureListTest,InitializeFromCommandLine_UseDefault)422 TEST_F(FeatureListTest, InitializeFromCommandLine_UseDefault) {
423 ClearFeatureListInstance();
424 FieldTrialList field_trial_list(nullptr);
425 FieldTrialList::CreateFieldTrial("T1", "Group");
426 FieldTrialList::CreateFieldTrial("T2", "Group");
427 std::unique_ptr<FeatureList> feature_list(new FeatureList);
428 feature_list->InitializeFromCommandLine(
429 "A,*OffByDefault<T1,*OnByDefault<T2,X", "D");
430 RegisterFeatureListInstance(std::move(feature_list));
431
432 EXPECT_FALSE(FieldTrialList::IsTrialActive("T1"));
433 EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOffByDefault));
434 EXPECT_TRUE(FieldTrialList::IsTrialActive("T1"));
435
436 EXPECT_FALSE(FieldTrialList::IsTrialActive("T2"));
437 EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOnByDefault));
438 EXPECT_TRUE(FieldTrialList::IsTrialActive("T2"));
439 }
440
TEST_F(FeatureListTest,InitializeInstance)441 TEST_F(FeatureListTest, InitializeInstance) {
442 ClearFeatureListInstance();
443
444 std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
445 FeatureList::SetInstance(std::move(feature_list));
446 EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOnByDefault));
447 EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOffByDefault));
448
449 // Initialize from command line if we haven't yet.
450 FeatureList::InitializeInstance("", kFeatureOnByDefaultName);
451 EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOnByDefault));
452 EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOffByDefault));
453
454 // Do not initialize from commandline if we have already.
455 FeatureList::InitializeInstance(kFeatureOffByDefaultName, "");
456 EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOnByDefault));
457 EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOffByDefault));
458 }
459
TEST_F(FeatureListTest,UninitializedInstance_IsEnabledReturnsFalse)460 TEST_F(FeatureListTest, UninitializedInstance_IsEnabledReturnsFalse) {
461 ClearFeatureListInstance();
462 // This test case simulates the calling pattern found in code which does not
463 // explicitly initialize the features list.
464 // All IsEnabled() calls should return the default value in this scenario.
465 EXPECT_EQ(nullptr, FeatureList::GetInstance());
466 EXPECT_TRUE(FeatureList::IsEnabled(kFeatureOnByDefault));
467 EXPECT_EQ(nullptr, FeatureList::GetInstance());
468 EXPECT_FALSE(FeatureList::IsEnabled(kFeatureOffByDefault));
469 }
470
471 } // namespace base
472