|
12 | 12 | # See the License for the specific language governing permissions and |
13 | 13 | # limitations under the License. |
14 | 14 |
|
15 | | -"""Unit tests for --enable_features CLI option.""" |
16 | | - |
17 | 15 | from __future__ import annotations |
18 | 16 |
|
19 | 17 | import click |
@@ -42,45 +40,96 @@ class TestApplyFeatureOverrides: |
42 | 40 |
|
43 | 41 | def test_single_feature(self): |
44 | 42 | """Single feature name is applied correctly.""" |
45 | | - _apply_feature_overrides(("JSON_SCHEMA_FOR_FUNC_DECL",)) |
| 43 | + _apply_feature_overrides(enable_features=("JSON_SCHEMA_FOR_FUNC_DECL",)) |
46 | 44 | assert is_feature_enabled(FeatureName.JSON_SCHEMA_FOR_FUNC_DECL) |
47 | 45 |
|
48 | 46 | def test_comma_separated_features(self): |
49 | 47 | """Comma-separated feature names are applied correctly.""" |
50 | | - _apply_feature_overrides(( |
51 | | - "JSON_SCHEMA_FOR_FUNC_DECL,PROGRESSIVE_SSE_STREAMING", |
52 | | - )) |
| 48 | + _apply_feature_overrides( |
| 49 | + enable_features=("JSON_SCHEMA_FOR_FUNC_DECL,PROGRESSIVE_SSE_STREAMING",) |
| 50 | + ) |
53 | 51 | assert is_feature_enabled(FeatureName.JSON_SCHEMA_FOR_FUNC_DECL) |
54 | 52 | assert is_feature_enabled(FeatureName.PROGRESSIVE_SSE_STREAMING) |
55 | 53 |
|
56 | 54 | def test_multiple_flag_values(self): |
57 | 55 | """Multiple --enable_features flags are applied correctly.""" |
58 | | - _apply_feature_overrides(( |
59 | | - "JSON_SCHEMA_FOR_FUNC_DECL", |
60 | | - "PROGRESSIVE_SSE_STREAMING", |
61 | | - )) |
| 56 | + _apply_feature_overrides( |
| 57 | + enable_features=( |
| 58 | + "JSON_SCHEMA_FOR_FUNC_DECL", |
| 59 | + "PROGRESSIVE_SSE_STREAMING", |
| 60 | + ) |
| 61 | + ) |
62 | 62 | assert is_feature_enabled(FeatureName.JSON_SCHEMA_FOR_FUNC_DECL) |
63 | 63 | assert is_feature_enabled(FeatureName.PROGRESSIVE_SSE_STREAMING) |
64 | 64 |
|
65 | 65 | def test_whitespace_handling(self): |
66 | 66 | """Whitespace around feature names is stripped.""" |
67 | | - _apply_feature_overrides((" JSON_SCHEMA_FOR_FUNC_DECL , COMPUTER_USE ",)) |
| 67 | + _apply_feature_overrides( |
| 68 | + enable_features=(" JSON_SCHEMA_FOR_FUNC_DECL , COMPUTER_USE ",) |
| 69 | + ) |
68 | 70 | assert is_feature_enabled(FeatureName.JSON_SCHEMA_FOR_FUNC_DECL) |
69 | 71 | assert is_feature_enabled(FeatureName.COMPUTER_USE) |
70 | 72 |
|
71 | 73 | def test_empty_string_ignored(self): |
72 | 74 | """Empty strings in the list are ignored.""" |
73 | | - _apply_feature_overrides(("",)) |
| 75 | + _apply_feature_overrides(enable_features=("",)) |
74 | 76 | # No error should be raised |
75 | 77 |
|
76 | 78 | def test_unknown_feature_warns(self, capsys): |
77 | 79 | """Unknown feature names emit a warning.""" |
78 | | - _apply_feature_overrides(("UNKNOWN_FEATURE_XYZ",)) |
| 80 | + _apply_feature_overrides(enable_features=("UNKNOWN_FEATURE_XYZ",)) |
79 | 81 | captured = capsys.readouterr() |
80 | 82 | assert "WARNING" in captured.err |
81 | 83 | assert "UNKNOWN_FEATURE_XYZ" in captured.err |
82 | 84 | assert "Valid names are:" in captured.err |
83 | 85 |
|
| 86 | + def test_single_disable_feature(self): |
| 87 | + """Single feature name is disabled correctly.""" |
| 88 | + # First enable a feature |
| 89 | + _apply_feature_overrides(enable_features=("JSON_SCHEMA_FOR_FUNC_DECL",)) |
| 90 | + assert is_feature_enabled(FeatureName.JSON_SCHEMA_FOR_FUNC_DECL) |
| 91 | + |
| 92 | + # Then disable it |
| 93 | + _apply_feature_overrides(disable_features=("JSON_SCHEMA_FOR_FUNC_DECL",)) |
| 94 | + assert not is_feature_enabled(FeatureName.JSON_SCHEMA_FOR_FUNC_DECL) |
| 95 | + |
| 96 | + def test_comma_separated_disable_features(self): |
| 97 | + """Comma-separated feature names are disabled correctly.""" |
| 98 | + # First enable features |
| 99 | + _apply_feature_overrides( |
| 100 | + enable_features=("JSON_SCHEMA_FOR_FUNC_DECL,PROGRESSIVE_SSE_STREAMING",) |
| 101 | + ) |
| 102 | + |
| 103 | + # Then disable them |
| 104 | + _apply_feature_overrides( |
| 105 | + disable_features=( |
| 106 | + "JSON_SCHEMA_FOR_FUNC_DECL,PROGRESSIVE_SSE_STREAMING", |
| 107 | + ) |
| 108 | + ) |
| 109 | + assert not is_feature_enabled(FeatureName.JSON_SCHEMA_FOR_FUNC_DECL) |
| 110 | + assert not is_feature_enabled(FeatureName.PROGRESSIVE_SSE_STREAMING) |
| 111 | + |
| 112 | + def test_disable_overrides_enable(self): |
| 113 | + """Disable is applied after enable, so disable wins for same feature.""" |
| 114 | + _apply_feature_overrides( |
| 115 | + enable_features=("JSON_SCHEMA_FOR_FUNC_DECL",), |
| 116 | + disable_features=("JSON_SCHEMA_FOR_FUNC_DECL",), |
| 117 | + ) |
| 118 | + # disable_features is processed after enable_features |
| 119 | + assert not is_feature_enabled(FeatureName.JSON_SCHEMA_FOR_FUNC_DECL) |
| 120 | + |
| 121 | + def test_enable_and_disable_different_features(self): |
| 122 | + """Enable and disable can be used together for different features.""" |
| 123 | + # First enable a feature that we'll disable |
| 124 | + _apply_feature_overrides(enable_features=("PROGRESSIVE_SSE_STREAMING",)) |
| 125 | + |
| 126 | + _apply_feature_overrides( |
| 127 | + enable_features=("JSON_SCHEMA_FOR_FUNC_DECL",), |
| 128 | + disable_features=("PROGRESSIVE_SSE_STREAMING",), |
| 129 | + ) |
| 130 | + assert is_feature_enabled(FeatureName.JSON_SCHEMA_FOR_FUNC_DECL) |
| 131 | + assert not is_feature_enabled(FeatureName.PROGRESSIVE_SSE_STREAMING) |
| 132 | + |
84 | 133 |
|
85 | 134 | class TestFeatureOptionsDecorator: |
86 | 135 | """Tests for feature_options decorator.""" |
@@ -195,3 +244,64 @@ def my_test_command(): |
195 | 244 | "my_test_command" in my_test_command.name |
196 | 245 | or my_test_command.callback.__name__ == "my_test_command" |
197 | 246 | ) |
| 247 | + |
| 248 | + def test_decorator_adds_disable_features_option(self): |
| 249 | + """Decorator adds --disable_features option to command.""" |
| 250 | + |
| 251 | + @click.command() |
| 252 | + @feature_options() |
| 253 | + def test_cmd(): |
| 254 | + pass |
| 255 | + |
| 256 | + runner = CliRunner() |
| 257 | + result = runner.invoke(test_cmd, ["--help"]) |
| 258 | + assert "--disable_features" in result.output |
| 259 | + |
| 260 | + def test_disable_features_applied_before_command(self): |
| 261 | + """Features are disabled before the command function runs.""" |
| 262 | + # First enable the feature via override |
| 263 | + _apply_feature_overrides(enable_features=("JSON_SCHEMA_FOR_FUNC_DECL",)) |
| 264 | + |
| 265 | + feature_was_disabled = [] |
| 266 | + |
| 267 | + @click.command() |
| 268 | + @feature_options() |
| 269 | + def test_cmd(): |
| 270 | + feature_was_disabled.append( |
| 271 | + not is_feature_enabled(FeatureName.JSON_SCHEMA_FOR_FUNC_DECL) |
| 272 | + ) |
| 273 | + |
| 274 | + runner = CliRunner() |
| 275 | + runner.invoke( |
| 276 | + test_cmd, |
| 277 | + ["--disable_features=JSON_SCHEMA_FOR_FUNC_DECL"], |
| 278 | + catch_exceptions=False, |
| 279 | + ) |
| 280 | + assert feature_was_disabled == [True] |
| 281 | + |
| 282 | + def test_enable_and_disable_together(self): |
| 283 | + """Both --enable_features and --disable_features work together.""" |
| 284 | + feature_states = [] |
| 285 | + |
| 286 | + @click.command() |
| 287 | + @feature_options() |
| 288 | + def test_cmd(): |
| 289 | + feature_states.append( |
| 290 | + is_feature_enabled(FeatureName.JSON_SCHEMA_FOR_FUNC_DECL) |
| 291 | + ) |
| 292 | + feature_states.append( |
| 293 | + is_feature_enabled(FeatureName.PROGRESSIVE_SSE_STREAMING) |
| 294 | + ) |
| 295 | + |
| 296 | + runner = CliRunner() |
| 297 | + runner.invoke( |
| 298 | + test_cmd, |
| 299 | + [ |
| 300 | + "--enable_features=JSON_SCHEMA_FOR_FUNC_DECL", |
| 301 | + "--disable_features=PROGRESSIVE_SSE_STREAMING", |
| 302 | + ], |
| 303 | + catch_exceptions=False, |
| 304 | + ) |
| 305 | + # JSON_SCHEMA_FOR_FUNC_DECL should be enabled |
| 306 | + # PROGRESSIVE_SSE_STREAMING should be disabled |
| 307 | + assert feature_states == [True, False] |
0 commit comments