1 // Copyright 2016 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 #ifndef BASE_TEST_SCOPED_FEATURE_LIST_H_ 6 #define BASE_TEST_SCOPED_FEATURE_LIST_H_ 7 8 #include <map> 9 #include <memory> 10 #include <string> 11 #include <vector> 12 13 #include "base/feature_list.h" 14 #include "base/memory/ref_counted.h" 15 #include "base/metrics/field_trial.h" 16 17 namespace base { 18 namespace test { 19 20 // ScopedFeatureList resets the global FeatureList instance to a new empty 21 // instance and restores the original instance upon destruction. 22 // Note: Re-using the same object is not allowed. To reset the feature 23 // list and initialize it anew, destroy an existing scoped list and init 24 // a new one. 25 // 26 // ScopedFeatureList needs to be initialized (via one of Init... methods) 27 // before running code that inspects the state of features. In practice this 28 // means: 29 // - In browser tests, one of Init... methods should be called from the 30 // overriden ::testing::Test::SetUp method. For example: 31 // void SetUp() override { 32 // scoped_feature_list_.InitAndEnableFeature(features::kMyFeatureHere); 33 // InProcessBrowserTest::SetUp(); 34 // } 35 class ScopedFeatureList final { 36 public: 37 ScopedFeatureList(); 38 ~ScopedFeatureList(); 39 40 // WARNING: This method will reset any globally configured features to their 41 // default values, which can hide feature interaction bugs. Please use 42 // sparingly. https://crbug.com/713390 43 // Initializes and registers a FeatureList instance with no overrides. 44 void Init(); 45 46 // WARNING: This method will reset any globally configured features to their 47 // default values, which can hide feature interaction bugs. Please use 48 // sparingly. https://crbug.com/713390 49 // Initializes and registers the given FeatureList instance. 50 void InitWithFeatureList(std::unique_ptr<FeatureList> feature_list); 51 52 // WARNING: This method will reset any globally configured features to their 53 // default values, which can hide feature interaction bugs. Please use 54 // sparingly. https://crbug.com/713390 55 // Initializes and registers a FeatureList instance with only the given 56 // enabled and disabled features (comma-separated names). 57 void InitFromCommandLine(const std::string& enable_features, 58 const std::string& disable_features); 59 60 // Initializes and registers a FeatureList instance based on present 61 // FeatureList and overridden with the given enabled and disabled features. 62 // Any feature overrides already present in the global FeatureList will 63 // continue to apply, unless they conflict with the overrides passed into this 64 // method. This is important for testing potentially unexpected feature 65 // interactions. 66 void InitWithFeatures(const std::vector<Feature>& enabled_features, 67 const std::vector<Feature>& disabled_features); 68 69 // Initializes and registers a FeatureList instance based on present 70 // FeatureList and overridden with single enabled feature. 71 void InitAndEnableFeature(const Feature& feature); 72 73 // Initializes and registers a FeatureList instance based on present 74 // FeatureList and overridden with single enabled feature and associated field 75 // trial parameters. 76 // Note: this creates a scoped global field trial list if there is not 77 // currently one. 78 void InitAndEnableFeatureWithParameters( 79 const Feature& feature, 80 const std::map<std::string, std::string>& feature_parameters); 81 82 // Initializes and registers a FeatureList instance based on present 83 // FeatureList and overridden with single disabled feature. 84 void InitAndDisableFeature(const Feature& feature); 85 86 // Initializes and registers a FeatureList instance based on present 87 // FeatureList and overriden with a single feature either enabled or 88 // disabled depending on |enabled|. 89 void InitWithFeatureState(const Feature& feature, bool enabled); 90 91 private: 92 // Initializes and registers a FeatureList instance based on present 93 // FeatureList and overridden with the given enabled and disabled features. 94 // Any feature overrides already present in the global FeatureList will 95 // continue to apply, unless they conflict with the overrides passed into this 96 // method. 97 // Field trials will apply to the enabled features, in the same order. The 98 // number of trials must be less (or equal) than the number of enabled 99 // features. 100 // Trials are expected to outlive the ScopedFeatureList. 101 void InitWithFeaturesAndFieldTrials( 102 const std::vector<Feature>& enabled_features, 103 const std::vector<FieldTrial*>& trials_for_enabled_features, 104 const std::vector<Feature>& disabled_features); 105 106 // Initializes and registers a FeatureList instance based on present 107 // FeatureList and overridden with single enabled feature and associated field 108 // trial override. 109 // |trial| is expected to outlive the ScopedFeatureList. 110 void InitAndEnableFeatureWithFieldTrialOverride(const Feature& feature, 111 FieldTrial* trial); 112 113 bool init_called_ = false; 114 std::unique_ptr<FeatureList> original_feature_list_; 115 scoped_refptr<FieldTrial> field_trial_override_; 116 std::unique_ptr<base::FieldTrialList> field_trial_list_; 117 118 DISALLOW_COPY_AND_ASSIGN(ScopedFeatureList); 119 }; 120 121 } // namespace test 122 } // namespace base 123 124 #endif // BASE_TEST_SCOPED_FEATURE_LIST_H_ 125