1# Copyright 2017 The Abseil Authors. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14"""Tests for flagsaver.""" 15 16from absl import flags 17from absl.testing import absltest 18from absl.testing import flagsaver 19from absl.testing import parameterized 20 21flags.DEFINE_string('flagsaver_test_flag0', 'unchanged0', 'flag to test with') 22flags.DEFINE_string('flagsaver_test_flag1', 'unchanged1', 'flag to test with') 23 24flags.DEFINE_string('flagsaver_test_validated_flag', None, 'flag to test with') 25flags.register_validator('flagsaver_test_validated_flag', lambda x: not x) 26 27flags.DEFINE_string('flagsaver_test_validated_flag1', None, 'flag to test with') 28flags.DEFINE_string('flagsaver_test_validated_flag2', None, 'flag to test with') 29 30INT_FLAG = flags.DEFINE_integer( 31 'flagsaver_test_int_flag', default=1, help='help') 32STR_FLAG = flags.DEFINE_string( 33 'flagsaver_test_str_flag', default='str default', help='help') 34 35MULTI_INT_FLAG = flags.DEFINE_multi_integer('flagsaver_test_multi_int_flag', 36 None, 'flag to test with') 37 38 39@flags.multi_flags_validator( 40 ('flagsaver_test_validated_flag1', 'flagsaver_test_validated_flag2')) 41def validate_test_flags(flag_dict): 42 return (flag_dict['flagsaver_test_validated_flag1'] == 43 flag_dict['flagsaver_test_validated_flag2']) 44 45 46FLAGS = flags.FLAGS 47 48 49@flags.validator('flagsaver_test_flag0') 50def check_no_upper_case(value): 51 return value == value.lower() 52 53 54class _TestError(Exception): 55 """Exception class for use in these tests.""" 56 57 58class CommonUsageTest(absltest.TestCase): 59 """These test cases cover the most common usages of flagsaver.""" 60 61 def test_as_parsed_context_manager(self): 62 # Precondition check, we expect all the flags to start as their default. 63 self.assertEqual('str default', STR_FLAG.value) 64 self.assertFalse(STR_FLAG.present) 65 self.assertEqual(1, INT_FLAG.value) 66 self.assertEqual('unchanged0', FLAGS.flagsaver_test_flag0) 67 self.assertEqual('unchanged1', FLAGS.flagsaver_test_flag1) 68 69 # Flagsaver will also save the state of flags that have been modified. 70 FLAGS.flagsaver_test_flag1 = 'outside flagsaver' 71 72 # Save all existing flag state, and set some flags as if they were parsed on 73 # the command line. Because of this, the new values must be provided as str, 74 # even if the flag type is something other than string. 75 with flagsaver.as_parsed( 76 (STR_FLAG, 'new string value'), # Override using flagholder object. 77 (INT_FLAG, '123'), # Override an int flag (NOTE: must specify as str). 78 flagsaver_test_flag0='new value', # Override using flag name. 79 ): 80 # All the flags have their overridden values. 81 self.assertEqual('new string value', STR_FLAG.value) 82 self.assertTrue(STR_FLAG.present) 83 self.assertEqual(123, INT_FLAG.value) 84 self.assertEqual('new value', FLAGS.flagsaver_test_flag0) 85 # Even if we change other flags, they will reset on context exit. 86 FLAGS.flagsaver_test_flag1 = 'new value 1' 87 88 # The flags have all reset to their pre-flagsaver values. 89 self.assertEqual('str default', STR_FLAG.value) 90 self.assertFalse(STR_FLAG.present) 91 self.assertEqual(1, INT_FLAG.value) 92 self.assertEqual('unchanged0', FLAGS.flagsaver_test_flag0) 93 self.assertEqual('outside flagsaver', FLAGS.flagsaver_test_flag1) 94 95 def test_as_parsed_decorator(self): 96 # flagsaver.as_parsed can also be used as a decorator. 97 @flagsaver.as_parsed((INT_FLAG, '123')) 98 def do_something_with_flags(): 99 self.assertEqual(123, INT_FLAG.value) 100 self.assertTrue(INT_FLAG.present) 101 102 do_something_with_flags() 103 self.assertEqual(1, INT_FLAG.value) 104 self.assertFalse(INT_FLAG.present) 105 106 def test_flagsaver_flagsaver(self): 107 # If you don't want the flags to go through parsing, you can instead use 108 # flagsaver.flagsaver(). With this method, you provide the native python 109 # value you'd like the flags to take on. Otherwise it functions similar to 110 # flagsaver.as_parsed(). 111 @flagsaver.flagsaver((INT_FLAG, 345)) 112 def do_something_with_flags(): 113 self.assertEqual(345, INT_FLAG.value) 114 # Note that because this flag was never parsed, it will not register as 115 # .present unless you manually set that attribute. 116 self.assertFalse(INT_FLAG.present) 117 # If you do chose to modify things about the flag (such as .present) those 118 # changes will still be cleaned up when flagsaver.flagsaver() exits. 119 INT_FLAG.present = True 120 121 self.assertEqual(1, INT_FLAG.value) 122 # flagsaver.flagsaver() restored INT_FLAG.present to the state it was in 123 # before entering the context. 124 self.assertFalse(INT_FLAG.present) 125 126 127class SaveFlagValuesTest(absltest.TestCase): 128 """Test flagsaver.save_flag_values() and flagsaver.restore_flag_values(). 129 130 In this test, we insure that *all* properties of flags get restored. In other 131 tests we only try changing the flag value. 132 """ 133 134 def test_assign_value(self): 135 # First save the flag values. 136 saved_flag_values = flagsaver.save_flag_values() 137 138 # Now mutate the flag's value field and check that it changed. 139 FLAGS.flagsaver_test_flag0 = 'new value' 140 self.assertEqual('new value', FLAGS.flagsaver_test_flag0) 141 142 # Now restore the flag to its original value. 143 flagsaver.restore_flag_values(saved_flag_values) 144 self.assertEqual('unchanged0', FLAGS.flagsaver_test_flag0) 145 146 def test_set_default(self): 147 # First save the flag. 148 saved_flag_values = flagsaver.save_flag_values() 149 150 # Now mutate the flag's default field and check that it changed. 151 FLAGS.set_default('flagsaver_test_flag0', 'new_default') 152 self.assertEqual('new_default', FLAGS['flagsaver_test_flag0'].default) 153 154 # Now restore the flag's default field. 155 flagsaver.restore_flag_values(saved_flag_values) 156 self.assertEqual('unchanged0', FLAGS['flagsaver_test_flag0'].default) 157 158 def test_parse(self): 159 # First save the flag. 160 saved_flag_values = flagsaver.save_flag_values() 161 162 # Sanity check (would fail if called with --flagsaver_test_flag0). 163 self.assertEqual(0, FLAGS['flagsaver_test_flag0'].present) 164 # Now populate the flag and check that it changed. 165 FLAGS['flagsaver_test_flag0'].parse('new value') 166 self.assertEqual('new value', FLAGS['flagsaver_test_flag0'].value) 167 self.assertEqual(1, FLAGS['flagsaver_test_flag0'].present) 168 169 # Now restore the flag to its original value. 170 flagsaver.restore_flag_values(saved_flag_values) 171 self.assertEqual('unchanged0', FLAGS['flagsaver_test_flag0'].value) 172 self.assertEqual(0, FLAGS['flagsaver_test_flag0'].present) 173 174 def test_assign_validators(self): 175 # First save the flag. 176 saved_flag_values = flagsaver.save_flag_values() 177 178 # Sanity check that a validator already exists. 179 self.assertLen(FLAGS['flagsaver_test_flag0'].validators, 1) 180 original_validators = list(FLAGS['flagsaver_test_flag0'].validators) 181 182 def no_space(value): 183 return ' ' not in value 184 185 # Add a new validator. 186 flags.register_validator('flagsaver_test_flag0', no_space) 187 self.assertLen(FLAGS['flagsaver_test_flag0'].validators, 2) 188 189 # Now restore the flag to its original value. 190 flagsaver.restore_flag_values(saved_flag_values) 191 self.assertEqual( 192 original_validators, FLAGS['flagsaver_test_flag0'].validators 193 ) 194 195 196@parameterized.named_parameters( 197 dict( 198 testcase_name='flagsaver.flagsaver', 199 flagsaver_method=flagsaver.flagsaver, 200 ), 201 dict( 202 testcase_name='flagsaver.as_parsed', 203 flagsaver_method=flagsaver.as_parsed, 204 ), 205) 206class NoOverridesTest(parameterized.TestCase): 207 """Test flagsaver.flagsaver and flagsaver.as_parsed without overrides.""" 208 209 def test_context_manager_with_call(self, flagsaver_method): 210 with flagsaver_method(): 211 FLAGS.flagsaver_test_flag0 = 'new value' 212 self.assertEqual('unchanged0', FLAGS.flagsaver_test_flag0) 213 214 def test_context_manager_with_exception(self, flagsaver_method): 215 with self.assertRaises(_TestError): 216 with flagsaver_method(): 217 FLAGS.flagsaver_test_flag0 = 'new value' 218 # Simulate a failed test. 219 raise _TestError('something happened') 220 self.assertEqual('unchanged0', FLAGS.flagsaver_test_flag0) 221 222 def test_decorator_without_call(self, flagsaver_method): 223 @flagsaver_method 224 def mutate_flags(): 225 FLAGS.flagsaver_test_flag0 = 'new value' 226 227 mutate_flags() 228 self.assertEqual('unchanged0', FLAGS.flagsaver_test_flag0) 229 230 def test_decorator_with_call(self, flagsaver_method): 231 @flagsaver_method() 232 def mutate_flags(): 233 FLAGS.flagsaver_test_flag0 = 'new value' 234 235 mutate_flags() 236 self.assertEqual('unchanged0', FLAGS.flagsaver_test_flag0) 237 238 def test_decorator_with_exception(self, flagsaver_method): 239 @flagsaver_method() 240 def raise_exception(): 241 FLAGS.flagsaver_test_flag0 = 'new value' 242 # Simulate a failed test. 243 raise _TestError('something happened') 244 245 self.assertEqual('unchanged0', FLAGS.flagsaver_test_flag0) 246 self.assertRaises(_TestError, raise_exception) 247 self.assertEqual('unchanged0', FLAGS.flagsaver_test_flag0) 248 249 250@parameterized.named_parameters( 251 dict( 252 testcase_name='flagsaver.flagsaver', 253 flagsaver_method=flagsaver.flagsaver, 254 ), 255 dict( 256 testcase_name='flagsaver.as_parsed', 257 flagsaver_method=flagsaver.as_parsed, 258 ), 259) 260class TestStringFlagOverrides(parameterized.TestCase): 261 """Test flagsaver.flagsaver and flagsaver.as_parsed with string overrides. 262 263 Note that these tests can be parameterized because both .flagsaver and 264 .as_parsed expect a str input when overriding a string flag. For non-string 265 flags these two flagsaver methods have separate tests elsewhere in this file. 266 267 Each test is one class of overrides, executed twice. Once as a context 268 manager, and once as a decorator on a mutate_flags() method. 269 """ 270 271 def test_keyword_overrides(self, flagsaver_method): 272 # Context manager: 273 with flagsaver_method(flagsaver_test_flag0='new value'): 274 self.assertEqual('new value', FLAGS.flagsaver_test_flag0) 275 self.assertEqual('unchanged0', FLAGS.flagsaver_test_flag0) 276 277 # Decorator: 278 @flagsaver_method(flagsaver_test_flag0='new value') 279 def mutate_flags(): 280 self.assertEqual('new value', FLAGS.flagsaver_test_flag0) 281 282 mutate_flags() 283 self.assertEqual('unchanged0', FLAGS.flagsaver_test_flag0) 284 285 def test_flagholder_overrides(self, flagsaver_method): 286 with flagsaver_method((STR_FLAG, 'new value')): 287 self.assertEqual('new value', STR_FLAG.value) 288 self.assertEqual('str default', STR_FLAG.value) 289 290 @flagsaver_method((STR_FLAG, 'new value')) 291 def mutate_flags(): 292 self.assertEqual('new value', STR_FLAG.value) 293 294 mutate_flags() 295 self.assertEqual('str default', STR_FLAG.value) 296 297 def test_keyword_and_flagholder_overrides(self, flagsaver_method): 298 with flagsaver_method( 299 (STR_FLAG, 'another value'), flagsaver_test_flag0='new value' 300 ): 301 self.assertEqual('another value', STR_FLAG.value) 302 self.assertEqual('new value', FLAGS.flagsaver_test_flag0) 303 self.assertEqual('str default', STR_FLAG.value) 304 self.assertEqual('unchanged0', FLAGS.flagsaver_test_flag0) 305 306 @flagsaver_method( 307 (STR_FLAG, 'another value'), flagsaver_test_flag0='new value' 308 ) 309 def mutate_flags(): 310 self.assertEqual('another value', STR_FLAG.value) 311 self.assertEqual('new value', FLAGS.flagsaver_test_flag0) 312 313 mutate_flags() 314 self.assertEqual('str default', STR_FLAG.value) 315 self.assertEqual('unchanged0', FLAGS.flagsaver_test_flag0) 316 317 def test_cross_validated_overrides_set_together(self, flagsaver_method): 318 # When the flags are set in the same flagsaver call their validators will 319 # be triggered only once the setting is done. 320 with flagsaver_method( 321 flagsaver_test_validated_flag1='new_value', 322 flagsaver_test_validated_flag2='new_value', 323 ): 324 self.assertEqual('new_value', FLAGS.flagsaver_test_validated_flag1) 325 self.assertEqual('new_value', FLAGS.flagsaver_test_validated_flag2) 326 self.assertIsNone(FLAGS.flagsaver_test_validated_flag1) 327 self.assertIsNone(FLAGS.flagsaver_test_validated_flag2) 328 329 @flagsaver_method( 330 flagsaver_test_validated_flag1='new_value', 331 flagsaver_test_validated_flag2='new_value', 332 ) 333 def mutate_flags(): 334 self.assertEqual('new_value', FLAGS.flagsaver_test_validated_flag1) 335 self.assertEqual('new_value', FLAGS.flagsaver_test_validated_flag2) 336 337 mutate_flags() 338 self.assertIsNone(FLAGS.flagsaver_test_validated_flag1) 339 self.assertIsNone(FLAGS.flagsaver_test_validated_flag2) 340 341 def test_cross_validated_overrides_set_badly(self, flagsaver_method): 342 # Different values should violate the validator. 343 with self.assertRaisesRegex( 344 flags.IllegalFlagValueError, 'Flag validation failed' 345 ): 346 with flagsaver_method( 347 flagsaver_test_validated_flag1='new_value', 348 flagsaver_test_validated_flag2='other_value', 349 ): 350 pass 351 self.assertIsNone(FLAGS.flagsaver_test_validated_flag1) 352 self.assertIsNone(FLAGS.flagsaver_test_validated_flag2) 353 354 @flagsaver_method( 355 flagsaver_test_validated_flag1='new_value', 356 flagsaver_test_validated_flag2='other_value', 357 ) 358 def mutate_flags(): 359 pass 360 361 self.assertRaisesRegex( 362 flags.IllegalFlagValueError, 'Flag validation failed', mutate_flags 363 ) 364 self.assertIsNone(FLAGS.flagsaver_test_validated_flag1) 365 self.assertIsNone(FLAGS.flagsaver_test_validated_flag2) 366 367 def test_cross_validated_overrides_set_separately(self, flagsaver_method): 368 # Setting just one flag will trip the validator as well. 369 with self.assertRaisesRegex( 370 flags.IllegalFlagValueError, 'Flag validation failed' 371 ): 372 with flagsaver_method(flagsaver_test_validated_flag1='new_value'): 373 pass 374 self.assertIsNone(FLAGS.flagsaver_test_validated_flag1) 375 self.assertIsNone(FLAGS.flagsaver_test_validated_flag2) 376 377 @flagsaver_method(flagsaver_test_validated_flag1='new_value') 378 def mutate_flags(): 379 pass 380 381 self.assertRaisesRegex( 382 flags.IllegalFlagValueError, 'Flag validation failed', mutate_flags 383 ) 384 self.assertIsNone(FLAGS.flagsaver_test_validated_flag1) 385 self.assertIsNone(FLAGS.flagsaver_test_validated_flag2) 386 387 def test_validation_exception(self, flagsaver_method): 388 with self.assertRaises(flags.IllegalFlagValueError): 389 with flagsaver_method( 390 flagsaver_test_flag0='new value', 391 flagsaver_test_validated_flag='new value', 392 ): 393 pass 394 self.assertEqual('unchanged0', FLAGS.flagsaver_test_flag0) 395 self.assertIsNone(FLAGS.flagsaver_test_validated_flag) 396 397 @flagsaver_method( 398 flagsaver_test_flag0='new value', 399 flagsaver_test_validated_flag='new value', 400 ) 401 def mutate_flags(): 402 pass 403 404 self.assertRaises(flags.IllegalFlagValueError, mutate_flags) 405 self.assertEqual('unchanged0', FLAGS.flagsaver_test_flag0) 406 self.assertIsNone(FLAGS.flagsaver_test_validated_flag) 407 408 def test_unknown_flag_raises_exception(self, flagsaver_method): 409 self.assertNotIn('this_flag_does_not_exist', FLAGS) 410 411 # Flagsaver raises an error when trying to override a non-existent flag. 412 with self.assertRaises(flags.UnrecognizedFlagError): 413 with flagsaver_method( 414 flagsaver_test_flag0='new value', this_flag_does_not_exist='new value' 415 ): 416 pass 417 self.assertEqual('unchanged0', FLAGS.flagsaver_test_flag0) 418 419 @flagsaver_method( 420 flagsaver_test_flag0='new value', this_flag_does_not_exist='new value' 421 ) 422 def mutate_flags(): 423 pass 424 425 self.assertRaises(flags.UnrecognizedFlagError, mutate_flags) 426 self.assertEqual('unchanged0', FLAGS.flagsaver_test_flag0) 427 428 # Make sure flagsaver didn't create the flag at any point. 429 self.assertNotIn('this_flag_does_not_exist', FLAGS) 430 431 432class AsParsedTest(absltest.TestCase): 433 434 def test_parse_context_manager_sets_present_and_using_default(self): 435 self.assertFalse(INT_FLAG.present) 436 self.assertFalse(STR_FLAG.present) 437 # Note that .using_default_value isn't available on the FlagHolder directly. 438 self.assertTrue(FLAGS[INT_FLAG.name].using_default_value) 439 self.assertTrue(FLAGS[STR_FLAG.name].using_default_value) 440 441 with flagsaver.as_parsed((INT_FLAG, '123'), 442 flagsaver_test_str_flag='new value'): 443 self.assertTrue(INT_FLAG.present) 444 self.assertTrue(STR_FLAG.present) 445 self.assertFalse(FLAGS[INT_FLAG.name].using_default_value) 446 self.assertFalse(FLAGS[STR_FLAG.name].using_default_value) 447 448 self.assertFalse(INT_FLAG.present) 449 self.assertFalse(STR_FLAG.present) 450 self.assertTrue(FLAGS[INT_FLAG.name].using_default_value) 451 self.assertTrue(FLAGS[STR_FLAG.name].using_default_value) 452 453 def test_parse_decorator_sets_present_and_using_default(self): 454 self.assertFalse(INT_FLAG.present) 455 self.assertFalse(STR_FLAG.present) 456 # Note that .using_default_value isn't available on the FlagHolder directly. 457 self.assertTrue(FLAGS[INT_FLAG.name].using_default_value) 458 self.assertTrue(FLAGS[STR_FLAG.name].using_default_value) 459 460 @flagsaver.as_parsed((INT_FLAG, '123'), flagsaver_test_str_flag='new value') 461 def some_func(): 462 self.assertTrue(INT_FLAG.present) 463 self.assertTrue(STR_FLAG.present) 464 self.assertFalse(FLAGS[INT_FLAG.name].using_default_value) 465 self.assertFalse(FLAGS[STR_FLAG.name].using_default_value) 466 467 some_func() 468 self.assertFalse(INT_FLAG.present) 469 self.assertFalse(STR_FLAG.present) 470 self.assertTrue(FLAGS[INT_FLAG.name].using_default_value) 471 self.assertTrue(FLAGS[STR_FLAG.name].using_default_value) 472 473 def test_parse_decorator_with_multi_int_flag(self): 474 self.assertFalse(MULTI_INT_FLAG.present) 475 self.assertIsNone(MULTI_INT_FLAG.value) 476 477 @flagsaver.as_parsed((MULTI_INT_FLAG, ['123', '456'])) 478 def assert_flags_updated(): 479 self.assertTrue(MULTI_INT_FLAG.present) 480 self.assertCountEqual([123, 456], MULTI_INT_FLAG.value) 481 482 assert_flags_updated() 483 self.assertFalse(MULTI_INT_FLAG.present) 484 self.assertIsNone(MULTI_INT_FLAG.value) 485 486 def test_parse_raises_type_error(self): 487 with self.assertRaisesRegex( 488 TypeError, 489 r'flagsaver\.as_parsed\(\) cannot parse flagsaver_test_int_flag\. ' 490 r'Expected a single string or sequence of strings but .*int.* was ' 491 r'provided\.'): 492 manager = flagsaver.as_parsed(flagsaver_test_int_flag=123) # pytype: disable=wrong-arg-types 493 del manager 494 495 496class SetUpTearDownTest(absltest.TestCase): 497 """Example using a single flagsaver in setUp.""" 498 499 def setUp(self): 500 super().setUp() 501 self.saved_flag_values = flagsaver.save_flag_values() 502 503 def tearDown(self): 504 super().tearDown() 505 flagsaver.restore_flag_values(self.saved_flag_values) 506 507 def test_mutate1(self): 508 # Even though other test cases change the flag, it should be 509 # restored to 'unchanged0' if the flagsaver is working. 510 self.assertEqual('unchanged0', FLAGS.flagsaver_test_flag0) 511 FLAGS.flagsaver_test_flag0 = 'changed0' 512 513 def test_mutate2(self): 514 # Even though other test cases change the flag, it should be 515 # restored to 'unchanged0' if the flagsaver is working. 516 self.assertEqual('unchanged0', FLAGS.flagsaver_test_flag0) 517 FLAGS.flagsaver_test_flag0 = 'changed0' 518 519 520@parameterized.named_parameters( 521 dict( 522 testcase_name='flagsaver.flagsaver', 523 flagsaver_method=flagsaver.flagsaver, 524 ), 525 dict( 526 testcase_name='flagsaver.as_parsed', 527 flagsaver_method=flagsaver.as_parsed, 528 ), 529) 530class BadUsageTest(parameterized.TestCase): 531 """Tests that improper usage (such as decorating a class) raise errors.""" 532 533 def test_flag_saver_on_class(self, flagsaver_method): 534 with self.assertRaises(TypeError): 535 536 # WRONG. Don't do this. 537 # Consider the correct usage example in FlagSaverSetUpTearDownUsageTest. 538 @flagsaver_method 539 class FooTest(absltest.TestCase): 540 541 def test_tautology(self): 542 pass 543 544 del FooTest 545 546 def test_flag_saver_call_on_class(self, flagsaver_method): 547 with self.assertRaises(TypeError): 548 549 # WRONG. Don't do this. 550 # Consider the correct usage example in FlagSaverSetUpTearDownUsageTest. 551 @flagsaver_method() 552 class FooTest(absltest.TestCase): 553 554 def test_tautology(self): 555 pass 556 557 del FooTest 558 559 def test_flag_saver_with_overrides_on_class(self, flagsaver_method): 560 with self.assertRaises(TypeError): 561 562 # WRONG. Don't do this. 563 # Consider the correct usage example in FlagSaverSetUpTearDownUsageTest. 564 @flagsaver_method(foo='bar') 565 class FooTest(absltest.TestCase): 566 567 def test_tautology(self): 568 pass 569 570 del FooTest 571 572 def test_multiple_positional_parameters(self, flagsaver_method): 573 with self.assertRaises(ValueError): 574 func_a = lambda: None 575 func_b = lambda: None 576 flagsaver_method(func_a, func_b) 577 578 def test_both_positional_and_keyword_parameters(self, flagsaver_method): 579 with self.assertRaises(ValueError): 580 func_a = lambda: None 581 flagsaver_method(func_a, flagsaver_test_flag0='new value') 582 583 def test_duplicate_holder_parameters(self, flagsaver_method): 584 with self.assertRaises(ValueError): 585 flagsaver_method((INT_FLAG, 45), (INT_FLAG, 45)) 586 587 def test_duplicate_holder_and_kw_parameter(self, flagsaver_method): 588 with self.assertRaises(ValueError): 589 flagsaver_method((INT_FLAG, 45), **{INT_FLAG.name: 45}) 590 591 def test_both_positional_and_holder_parameters(self, flagsaver_method): 592 with self.assertRaises(ValueError): 593 func_a = lambda: None 594 flagsaver_method(func_a, (INT_FLAG, 45)) 595 596 def test_holder_parameters_wrong_shape(self, flagsaver_method): 597 with self.assertRaises(ValueError): 598 flagsaver_method(INT_FLAG) 599 600 def test_holder_parameters_tuple_too_long(self, flagsaver_method): 601 with self.assertRaises(ValueError): 602 # Even if it is a bool flag, it should be a tuple 603 flagsaver_method((INT_FLAG, 4, 5)) 604 605 def test_holder_parameters_tuple_wrong_type(self, flagsaver_method): 606 with self.assertRaises(ValueError): 607 # Even if it is a bool flag, it should be a tuple 608 flagsaver_method((4, INT_FLAG)) 609 610 def test_both_wrong_positional_parameters(self, flagsaver_method): 611 with self.assertRaises(ValueError): 612 func_a = lambda: None 613 flagsaver_method(func_a, STR_FLAG, '45') 614 615 def test_context_manager_no_call(self, flagsaver_method): 616 # The exact exception that's raised appears to be system specific. 617 with self.assertRaises((AttributeError, TypeError)): 618 # Wrong. You must call the flagsaver method before using it as a CM. 619 with flagsaver_method: 620 # We don't expect to get here. A type error should happen when 621 # attempting to enter the context manager. 622 pass 623 624 625if __name__ == '__main__': 626 absltest.main() 627