Chromium Code Reviews| Index: base/test/scoped_feature_list_unittest.cc | 
| diff --git a/base/test/scoped_feature_list_unittest.cc b/base/test/scoped_feature_list_unittest.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..7e20ed8aafcf766c240b65ed4ae479afd19b43be | 
| --- /dev/null | 
| +++ b/base/test/scoped_feature_list_unittest.cc | 
| @@ -0,0 +1,124 @@ | 
| +// Copyright 2017 The Chromium Authors. All rights reserved. | 
| +// Use of this source code is governed by a BSD-style license that can be | 
| +// found in the LICENSE file. | 
| + | 
| +#include "base/test/scoped_feature_list.h" | 
| + | 
| +#include <string> | 
| +#include "testing/gtest/include/gtest/gtest.h" | 
| + | 
| +namespace { | 
| + | 
| +static void ExpectFeatures(const std::string& enabled_features, | 
| 
 
Ilya Sherman
2017/04/21 22:43:34
nit: No need for 'static' in an anonymous namespac
 
 | 
| + const std::string& disabled_features) { | 
| + base::FeatureList* list = base::FeatureList::GetInstance(); | 
| + std::string actual_enabled_features; | 
| + std::string actual_disabled_features; | 
| + | 
| + list->GetFeatureOverrides(&actual_enabled_features, | 
| + &actual_disabled_features); | 
| + | 
| + EXPECT_EQ(enabled_features, actual_enabled_features); | 
| + EXPECT_EQ(disabled_features, actual_disabled_features); | 
| +} | 
| + | 
| +} // namespace | 
| + | 
| +namespace base { | 
| + | 
| +class ScopedFeatureListTest : public testing::Test { | 
| + public: | 
| + ScopedFeatureListTest() { | 
| + // Clear default feature list. | 
| + std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList); | 
| + feature_list->InitializeFromCommandLine("", ""); | 
| 
 
Ilya Sherman
2017/04/21 22:43:34
nit: Prefer std::string() to "" for empty strings.
 
 | 
| + original_feature_list_ = base::FeatureList::ClearInstanceForTesting(); | 
| + base::FeatureList::SetInstance(std::move(feature_list)); | 
| + } | 
| + | 
| + void TearDown() override { | 
| 
 
Ilya Sherman
2017/04/21 22:43:34
Please do this work in the destructor rather than
 
 | 
| + // Restore feature list. | 
| + if (original_feature_list_) { | 
| + base::FeatureList::ClearInstanceForTesting(); | 
| + base::FeatureList::RestoreInstanceForTesting( | 
| + std::move(original_feature_list_)); | 
| + } | 
| + } | 
| + | 
| + private: | 
| + std::unique_ptr<FeatureList> original_feature_list_; | 
| 
 
Ilya Sherman
2017/04/21 22:43:34
Please document this member variable.
 
 | 
| +}; | 
| + | 
| +const Feature kTestFeature1{"TestFeature1", FEATURE_DISABLED_BY_DEFAULT}; | 
| +const Feature kTestFeature2{"TestFeature2", FEATURE_DISABLED_BY_DEFAULT}; | 
| 
 
Ilya Sherman
2017/04/21 22:43:34
nit: Please move these into the anonymous namespac
 
 | 
| + | 
| +TEST_F(ScopedFeatureListTest, BasicScoped) { | 
| + ExpectFeatures("", ""); | 
| + EXPECT_FALSE(FeatureList::IsEnabled(kTestFeature1)); | 
| + { | 
| + test::ScopedFeatureList feature_list1; | 
| + feature_list1.InitFromCommandLine("TestFeature1", ""); | 
| + ExpectFeatures("TestFeature1", ""); | 
| + EXPECT_TRUE(FeatureList::IsEnabled(kTestFeature1)); | 
| + } | 
| + ExpectFeatures("", ""); | 
| + EXPECT_FALSE(FeatureList::IsEnabled(kTestFeature1)); | 
| +} | 
| + | 
| +TEST_F(ScopedFeatureListTest, EnableFeatureOverrideDisable) { | 
| + test::ScopedFeatureList feature_list1; | 
| + feature_list1.InitWithFeatures({}, {kTestFeature1}); | 
| + | 
| + { | 
| + test::ScopedFeatureList feature_list2; | 
| + feature_list2.InitWithFeatures({kTestFeature1}, {}); | 
| + ExpectFeatures("TestFeature1", ""); | 
| + } | 
| +} | 
| + | 
| +TEST_F(ScopedFeatureListTest, FeatureOverrideNotMakeDuplicate) { | 
| + test::ScopedFeatureList feature_list1; | 
| + feature_list1.InitWithFeatures({}, {kTestFeature1}); | 
| + | 
| + { | 
| + test::ScopedFeatureList feature_list2; | 
| + feature_list2.InitWithFeatures({}, {kTestFeature1}); | 
| + ExpectFeatures("", "TestFeature1"); | 
| + } | 
| +} | 
| 
 
Ilya Sherman
2017/04/21 22:43:34
Please also test that if the feature is overridden
 
 | 
| + | 
| +TEST_F(ScopedFeatureListTest, FeatureOverrideKeepsOtherExistingFeature) { | 
| + test::ScopedFeatureList feature_list1; | 
| + feature_list1.InitWithFeatures({}, {kTestFeature1}); | 
| + | 
| + { | 
| + test::ScopedFeatureList feature_list2; | 
| + feature_list2.InitWithFeatures({}, {kTestFeature2}); | 
| + EXPECT_FALSE(FeatureList::IsEnabled(kTestFeature1)); | 
| + EXPECT_FALSE(FeatureList::IsEnabled(kTestFeature2)); | 
| + } | 
| +} | 
| + | 
| +TEST_F(ScopedFeatureListTest, FeatureOverrideKeepsOtherExistingFeature2) { | 
| + test::ScopedFeatureList feature_list1; | 
| + feature_list1.InitWithFeatures({}, {kTestFeature1}); | 
| + | 
| + { | 
| + test::ScopedFeatureList feature_list2; | 
| + feature_list2.InitWithFeatures({kTestFeature2}, {}); | 
| + ExpectFeatures("TestFeature2", "TestFeature1"); | 
| + } | 
| +} | 
| + | 
| +TEST_F(ScopedFeatureListTest, FeatureOverrideKeepsOtherExistingDefaultFeature) { | 
| + test::ScopedFeatureList feature_list1; | 
| + feature_list1.InitFromCommandLine("*TestFeature1", ""); | 
| + | 
| + { | 
| + test::ScopedFeatureList feature_list2; | 
| + feature_list2.InitWithFeatures({}, {kTestFeature2}); | 
| + ExpectFeatures("*TestFeature1", "TestFeature2"); | 
| + } | 
| +} | 
| + | 
| +} // namespace base |