1#!/usr/bin/env python3 2# Copyright 2014 The Chromium Authors 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6"""Tests for enum_preprocess.py. 7 8This test suite contains various tests for the C++ -> Java enum generator. 9""" 10 11import collections 12from datetime import date 13import unittest 14 15import java_cpp_enum 16from java_cpp_enum import EnumDefinition, GenerateOutput 17from java_cpp_enum import HeaderParser 18from util import java_cpp_utils 19 20 21class TestPreprocess(unittest.TestCase): 22 def testOutput(self): 23 definition = EnumDefinition(original_enum_name='ClassName', 24 enum_package='some.package', 25 entries=[('E1', 1), ('E2', '2 << 2')], 26 comments=[('E2', 'This is a comment.'), 27 ('E1', 'This is a multiple line ' 28 'comment that is really long. ' 29 'This is a multiple line ' 30 'comment that is really ' 31 'really long.')]) 32 output = GenerateOutput('path/to/file', definition) 33 expected = """ 34// Copyright %d The Chromium Authors 35// Use of this source code is governed by a BSD-style license that can be 36// found in the LICENSE file. 37 38// This file is autogenerated by 39// %s 40// From 41// path/to/file 42 43package some.package; 44 45import androidx.annotation.IntDef; 46 47import java.lang.annotation.Retention; 48import java.lang.annotation.RetentionPolicy; 49 50@IntDef({ 51 ClassName.E1, ClassName.E2 52}) 53@Retention(RetentionPolicy.SOURCE) 54public @interface ClassName { 55 /** 56 * %s 57 * really really long. 58 */ 59 int E1 = 1; 60 /** 61 * This is a comment. 62 */ 63 int E2 = 2 << 2; 64} 65""" 66 long_comment = ('This is a multiple line comment that is really long. ' 67 'This is a multiple line comment that is') 68 self.assertEqual( 69 expected % (date.today().year, java_cpp_utils.GetScriptName(), 70 long_comment), output) 71 72 def testParseSimpleEnum(self): 73 test_data = """ 74 // GENERATED_JAVA_ENUM_PACKAGE: test.namespace 75 enum EnumName { 76 VALUE_ZERO, 77 VALUE_ONE, 78 }; 79 """.split('\n') 80 definitions = HeaderParser(test_data).ParseDefinitions() 81 self.assertEqual(1, len(definitions)) 82 definition = definitions[0] 83 self.assertEqual('EnumName', definition.class_name) 84 self.assertEqual('test.namespace', definition.enum_package) 85 self.assertEqual(collections.OrderedDict([('VALUE_ZERO', 0), 86 ('VALUE_ONE', 1)]), 87 definition.entries) 88 89 def testParseBitShifts(self): 90 test_data = """ 91 // GENERATED_JAVA_ENUM_PACKAGE: test.namespace 92 enum EnumName { 93 VALUE_ZERO = 1 << 0, 94 VALUE_ONE = 1 << 1, 95 }; 96 97 // GENERATED_JAVA_ENUM_PACKAGE: test.namespace 98 enum EnumName { 99 ENUM_NAME_ZERO = 1 << 0, 100 ENUM_NAME_ONE = 1 << 1, 101 ENUM_NAME_TWO = ENUM_NAME_ZERO | ENUM_NAME_ONE, 102 }; 103 """.split('\n') 104 definitions = HeaderParser(test_data).ParseDefinitions() 105 self.assertEqual(2, len(definitions)) 106 definition = definitions[0] 107 self.assertEqual('EnumName', definition.class_name) 108 self.assertEqual('test.namespace', definition.enum_package) 109 self.assertEqual(collections.OrderedDict([('VALUE_ZERO', '1 << 0'), 110 ('VALUE_ONE', '1 << 1')]), 111 definition.entries) 112 113 definition = definitions[1] 114 expected_entries = collections.OrderedDict([ 115 ('ZERO', '1 << 0'), 116 ('ONE', '1 << 1'), 117 ('TWO', 'ZERO | ONE')]) 118 self.assertEqual(expected_entries, definition.entries) 119 120 def testParseMultilineEnumEntry(self): 121 test_data = """ 122 // GENERATED_JAVA_ENUM_PACKAGE: bar.namespace 123 enum Foo { 124 VALUE_ZERO = 1 << 0, 125 VALUE_ONE = 126 SymbolKey | FnKey | AltGrKey | MetaKey | AltKey | ControlKey, 127 VALUE_TWO = 1 << 18, 128 }; 129 """.split('\n') 130 expected_entries = collections.OrderedDict([ 131 ('VALUE_ZERO', '1 << 0'), 132 ('VALUE_ONE', 'SymbolKey | FnKey | AltGrKey | MetaKey | AltKey | ' 133 'ControlKey'), 134 ('VALUE_TWO', '1 << 18')]) 135 definitions = HeaderParser(test_data).ParseDefinitions() 136 self.assertEqual(1, len(definitions)) 137 definition = definitions[0] 138 self.assertEqual('Foo', definition.class_name) 139 self.assertEqual('bar.namespace', definition.enum_package) 140 self.assertEqual(expected_entries, definition.entries) 141 142 def testParseEnumEntryWithTrailingMultilineEntry(self): 143 test_data = """ 144 // GENERATED_JAVA_ENUM_PACKAGE: bar.namespace 145 enum Foo { 146 VALUE_ZERO = 1, 147 VALUE_ONE = 148 SymbolKey | FnKey | AltGrKey | MetaKey | 149 AltKey | ControlKey | ShiftKey, 150 }; 151 """.split('\n') 152 expected_entries = collections.OrderedDict([ 153 ('VALUE_ZERO', '1'), 154 ('VALUE_ONE', 'SymbolKey | FnKey | AltGrKey | MetaKey | AltKey | ' 155 'ControlKey | ShiftKey')]) 156 definitions = HeaderParser(test_data).ParseDefinitions() 157 self.assertEqual(1, len(definitions)) 158 definition = definitions[0] 159 self.assertEqual('Foo', definition.class_name) 160 self.assertEqual('bar.namespace', definition.enum_package) 161 self.assertEqual(expected_entries, definition.entries) 162 163 def testParseNoCommaAfterLastEntry(self): 164 test_data = """ 165 // GENERATED_JAVA_ENUM_PACKAGE: bar.namespace 166 enum Foo { 167 VALUE_ZERO = 1, 168 169 // This is a multiline 170 // 171 // comment with an empty line. 172 VALUE_ONE = 2 173 }; 174 """.split('\n') 175 expected_entries = collections.OrderedDict([ 176 ('VALUE_ZERO', '1'), 177 ('VALUE_ONE', '2')]) 178 expected_comments = collections.OrderedDict([ 179 ('VALUE_ONE', 'This is a multiline comment with an empty line.')]) 180 definitions = HeaderParser(test_data).ParseDefinitions() 181 self.assertEqual(1, len(definitions)) 182 definition = definitions[0] 183 self.assertEqual('Foo', definition.class_name) 184 self.assertEqual('bar.namespace', definition.enum_package) 185 self.assertEqual(expected_entries, definition.entries) 186 self.assertEqual(expected_comments, definition.comments) 187 188 def testParseClassNameOverride(self): 189 test_data = """ 190 // GENERATED_JAVA_ENUM_PACKAGE: test.namespace 191 // GENERATED_JAVA_CLASS_NAME_OVERRIDE: OverrideName 192 enum EnumName { 193 FOO 194 }; 195 196 // GENERATED_JAVA_ENUM_PACKAGE: test.namespace 197 // GENERATED_JAVA_CLASS_NAME_OVERRIDE: OtherOverride 198 enum PrefixTest { 199 PREFIX_TEST_A, 200 PREFIX_TEST_B, 201 }; 202 """.split('\n') 203 definitions = HeaderParser(test_data).ParseDefinitions() 204 self.assertEqual(2, len(definitions)) 205 definition = definitions[0] 206 self.assertEqual('OverrideName', definition.class_name) 207 208 definition = definitions[1] 209 self.assertEqual('OtherOverride', definition.class_name) 210 self.assertEqual(collections.OrderedDict([('A', 0), 211 ('B', 1)]), 212 definition.entries) 213 214 def testParsePreservesCommentsWhenPrefixStripping(self): 215 test_data = """ 216 // GENERATED_JAVA_ENUM_PACKAGE: test.namespace 217 enum EnumOne { 218 ENUM_ONE_A = 1, 219 // Comment there 220 ENUM_ONE_B = A, 221 }; 222 223 enum EnumIgnore { 224 C, D, E 225 }; 226 227 // GENERATED_JAVA_ENUM_PACKAGE: other.package 228 // GENERATED_JAVA_PREFIX_TO_STRIP: P_ 229 enum EnumTwo { 230 P_A, 231 // This comment spans 232 // two lines. 233 P_B 234 }; 235 """.split('\n') 236 definitions = HeaderParser(test_data).ParseDefinitions() 237 self.assertEqual(2, len(definitions)) 238 definition = definitions[0] 239 self.assertEqual('EnumOne', definition.class_name) 240 self.assertEqual('test.namespace', definition.enum_package) 241 self.assertEqual(collections.OrderedDict([('A', '1'), 242 ('B', 'A')]), 243 definition.entries) 244 self.assertEqual(collections.OrderedDict([('B', 'Comment there')]), 245 definition.comments) 246 definition = definitions[1] 247 self.assertEqual('EnumTwo', definition.class_name) 248 self.assertEqual('other.package', definition.enum_package) 249 self.assertEqual(collections.OrderedDict( 250 [('B', 'This comment spans two lines.')]), definition.comments) 251 self.assertEqual(collections.OrderedDict([('A', 0), 252 ('B', 1)]), 253 definition.entries) 254 255 def testParseTwoEnums(self): 256 test_data = """ 257 // GENERATED_JAVA_ENUM_PACKAGE: test.namespace 258 enum AnEnum { 259 ENUM_ONE_A = 1, 260 ENUM_ONE_B = A, 261 }; 262 263 enum EnumIgnore { 264 C, D, E 265 }; 266 267 // GENERATED_JAVA_ENUM_PACKAGE: other.package 268 enum EnumTwo { 269 P_A, 270 P_B 271 }; 272 """.split('\n') 273 definitions = HeaderParser(test_data).ParseDefinitions() 274 self.assertEqual(2, len(definitions)) 275 definition = definitions[0] 276 self.assertEqual('AnEnum', definition.class_name) 277 self.assertEqual('test.namespace', definition.enum_package) 278 self.assertEqual(collections.OrderedDict([('ENUM_ONE_A', '1'), 279 ('ENUM_ONE_B', 'A')]), 280 definition.entries) 281 definition = definitions[1] 282 self.assertEqual('EnumTwo', definition.class_name) 283 self.assertEqual('other.package', definition.enum_package) 284 self.assertEqual(collections.OrderedDict([('P_A', 0), 285 ('P_B', 1)]), 286 definition.entries) 287 288 def testParseSingleLineEnum(self): 289 test_data = """ 290 // GENERATED_JAVA_ENUM_PACKAGE: other.package 291 // GENERATED_JAVA_PREFIX_TO_STRIP: P_ 292 enum EnumTwo { P_A, P_B }; 293 """.split('\n') 294 definitions = HeaderParser(test_data).ParseDefinitions() 295 definition = definitions[0] 296 self.assertEqual('EnumTwo', definition.class_name) 297 self.assertEqual('other.package', definition.enum_package) 298 self.assertEqual(collections.OrderedDict([('A', 0), 299 ('B', 1)]), 300 definition.entries) 301 302 def testParseWithStrippingAndRelativeReferences(self): 303 test_data = """ 304 // GENERATED_JAVA_ENUM_PACKAGE: other.package 305 // GENERATED_JAVA_PREFIX_TO_STRIP: P_ 306 enum EnumTwo { 307 P_A = 1, 308 // P_A is old-don't use P_A. 309 P_B = P_A, 310 }; 311 """.split('\n') 312 definitions = HeaderParser(test_data).ParseDefinitions() 313 definition = definitions[0] 314 self.assertEqual('EnumTwo', definition.class_name) 315 self.assertEqual('other.package', definition.enum_package) 316 self.assertEqual(collections.OrderedDict([('A', '1'), 317 ('B', 'A')]), 318 definition.entries) 319 self.assertEqual(collections.OrderedDict([('B', 'A is old-don\'t use A.')]), 320 definition.comments) 321 322 def testParseSingleLineAndRegularEnum(self): 323 test_data = """ 324 // GENERATED_JAVA_ENUM_PACKAGE: test.namespace 325 enum EnumOne { 326 ENUM_ONE_A = 1, 327 // Comment there 328 ENUM_ONE_B = A, 329 }; 330 331 // GENERATED_JAVA_ENUM_PACKAGE: other.package 332 enum EnumTwo { P_A, P_B }; 333 334 // GENERATED_JAVA_ENUM_PACKAGE: test.namespace 335 // GENERATED_JAVA_CLASS_NAME_OVERRIDE: OverrideName 336 enum EnumName { 337 ENUM_NAME_FOO 338 }; 339 """.split('\n') 340 definitions = HeaderParser(test_data).ParseDefinitions() 341 definition = definitions[0] 342 self.assertEqual( 343 collections.OrderedDict([('A', '1'), ('B', 'A')]), definition.entries) 344 self.assertEqual(collections.OrderedDict([('B', 'Comment there')]), 345 definition.comments) 346 347 self.assertEqual(3, len(definitions)) 348 definition = definitions[1] 349 self.assertEqual( 350 collections.OrderedDict([('P_A', 0), ('P_B', 1)]), definition.entries) 351 352 definition = definitions[2] 353 self.assertEqual(collections.OrderedDict([('FOO', 0)]), definition.entries) 354 355 def testParseWithCamelCaseNames(self): 356 test_data = """ 357 // GENERATED_JAVA_ENUM_PACKAGE: test.namespace 358 enum EnumTest { 359 EnumTestA = 1, 360 // comment for EnumTestB. 361 EnumTestB = 2, 362 }; 363 364 // GENERATED_JAVA_ENUM_PACKAGE: test.namespace 365 // GENERATED_JAVA_PREFIX_TO_STRIP: Test 366 enum AnEnum { 367 TestHTTPOption, 368 TestHTTPSOption, 369 }; 370 371 """.split('\n') 372 definitions = HeaderParser(test_data).ParseDefinitions() 373 definition = definitions[0] 374 self.assertEqual( 375 collections.OrderedDict([('A', '1'), ('B', '2')]), 376 definition.entries) 377 self.assertEqual( 378 collections.OrderedDict([('B', 'comment for B.')]), 379 definition.comments) 380 381 definition = definitions[1] 382 self.assertEqual( 383 collections.OrderedDict([('HTTP_OPTION', 0), ('HTTPS_OPTION', 1)]), 384 definition.entries) 385 386 def testParseWithKCamelCaseNames(self): 387 test_data = """ 388 // GENERATED_JAVA_ENUM_PACKAGE: test.namespace 389 enum EnumOne { 390 kEnumOne = 1, 391 // comment for kEnumTwo. 392 kEnumTwo = 2, 393 }; 394 395 // GENERATED_JAVA_ENUM_PACKAGE: test.namespace 396 // GENERATED_JAVA_CLASS_NAME_OVERRIDE: OverrideName 397 enum EnumName { 398 kEnumNameFoo, 399 kEnumNameBar 400 }; 401 402 // GENERATED_JAVA_ENUM_PACKAGE: test.namespace 403 enum EnumName { 404 kEnumNameFoo, 405 kEnumBar, 406 }; 407 408 // GENERATED_JAVA_ENUM_PACKAGE: test.namespace 409 enum Keys { 410 kSymbolKey = 1 << 0, 411 kAltKey = 1 << 1, 412 kUpKey = 1 << 2, 413 kKeyModifiers = kSymbolKey | kAltKey | kUpKey | kKeyModifiers, 414 }; 415 416 // GENERATED_JAVA_ENUM_PACKAGE: test.namespace 417 enum Mixed { 418 kTestVal, 419 kCodecMPEG2 420 }; 421 """.split('\n') 422 definitions = HeaderParser(test_data).ParseDefinitions() 423 definition = definitions[0] 424 self.assertEqual( 425 collections.OrderedDict([('ENUM_ONE', '1'), ('ENUM_TWO', '2')]), 426 definition.entries) 427 self.assertEqual( 428 collections.OrderedDict([('ENUM_TWO', 'comment for ENUM_TWO.')]), 429 definition.comments) 430 431 definition = definitions[1] 432 self.assertEqual( 433 collections.OrderedDict([('FOO', 0), ('BAR', 1)]), 434 definition.entries) 435 436 definition = definitions[2] 437 self.assertEqual( 438 collections.OrderedDict([('ENUM_NAME_FOO', 0), ('ENUM_BAR', 1)]), 439 definition.entries) 440 441 definition = definitions[3] 442 expected_entries = collections.OrderedDict([ 443 ('SYMBOL_KEY', '1 << 0'), 444 ('ALT_KEY', '1 << 1'), 445 ('UP_KEY', '1 << 2'), 446 ('KEY_MODIFIERS', 'SYMBOL_KEY | ALT_KEY | UP_KEY | KEY_MODIFIERS')]) 447 self.assertEqual(expected_entries, definition.entries) 448 449 definition = definitions[4] 450 self.assertEqual( 451 collections.OrderedDict([('TEST_VAL', 0), ('CODEC_MPEG2', 1)]), 452 definition.entries) 453 454 def testParseThrowsOnUnknownDirective(self): 455 test_data = """ 456 // GENERATED_JAVA_UNKNOWN: Value 457 enum EnumName { 458 VALUE_ONE, 459 }; 460 """.split('\n') 461 with self.assertRaises(Exception): 462 HeaderParser(test_data).ParseDefinitions() 463 464 def testParseReturnsEmptyListWithoutDirectives(self): 465 test_data = """ 466 enum EnumName { 467 VALUE_ONE, 468 }; 469 """.split('\n') 470 self.assertEqual([], HeaderParser(test_data).ParseDefinitions()) 471 472 def testParseEnumClass(self): 473 test_data = """ 474 // GENERATED_JAVA_ENUM_PACKAGE: test.namespace 475 enum class Foo { 476 FOO_A, 477 }; 478 """.split('\n') 479 definitions = HeaderParser(test_data).ParseDefinitions() 480 self.assertEqual(1, len(definitions)) 481 definition = definitions[0] 482 self.assertEqual('Foo', definition.class_name) 483 self.assertEqual('test.namespace', definition.enum_package) 484 self.assertEqual(collections.OrderedDict([('A', 0)]), 485 definition.entries) 486 487 def testParseEnumClassOneValueSubstringOfAnother(self): 488 test_data = """ 489 // GENERATED_JAVA_ENUM_PACKAGE: test.namespace 490 enum class SafeBrowsingStatus { 491 kChecking = 0, 492 kEnabled = 1, 493 kDisabled = 2, 494 kDisabledByAdmin = 3, 495 kDisabledByExtension = 4, 496 kEnabledStandard = 5, 497 kEnabledEnhanced = 6, 498 // New enum values must go above here. 499 kMaxValue = kEnabledEnhanced, 500 }; 501 """.split('\n') 502 definitions = HeaderParser(test_data).ParseDefinitions() 503 self.assertEqual(1, len(definitions)) 504 definition = definitions[0] 505 self.assertEqual('SafeBrowsingStatus', definition.class_name) 506 self.assertEqual('test.namespace', definition.enum_package) 507 self.assertEqual( 508 collections.OrderedDict([ 509 ('CHECKING', '0'), 510 ('ENABLED', '1'), 511 ('DISABLED', '2'), 512 ('DISABLED_BY_ADMIN', '3'), 513 ('DISABLED_BY_EXTENSION', '4'), 514 ('ENABLED_STANDARD', '5'), 515 ('ENABLED_ENHANCED', '6'), 516 ('MAX_VALUE', 'ENABLED_ENHANCED'), 517 ]), definition.entries) 518 self.assertEqual( 519 collections.OrderedDict([ 520 ('MAX_VALUE', 'New enum values must go above here.') 521 ]), definition.comments) 522 523 def testParseEnumWithConditionallyDefinedValues(self): 524 test_data = """ 525// GENERATED_JAVA_ENUM_PACKAGE: test.namespace 526// GENERATED_JAVA_PREFIX_TO_STRIP: TERMINATION_STATUS_ 527enum TerminationStatus { 528 // Zero exit status. 529 TERMINATION_STATUS_NORMAL_TERMINATION = 0, 530 // Child hasn't exited yet. 531 TERMINATION_STATUS_STILL_RUNNING = 4, 532#if BUILDFLAG(IS_CHROMEOS) 533 // OOM-killer killed the process on ChromeOS. 534 TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM = 5, 535#endif 536#if BUILDFLAG(IS_ANDROID) 537 // On Android processes are spawned from the system Zygote and we do not get 538 // the termination status. 539 TERMINATION_STATUS_OOM_PROTECTED = 6, 540#endif 541 // Out of memory. 542 TERMINATION_STATUS_OOM = 8, 543#if BUILDFLAG(IS_WIN) 544 // On Windows, the OS terminated process due to code integrity failure. 545 TERMINATION_STATUS_INTEGRITY_FAILURE = 9, 546#endif 547}; 548 """.split('\n') 549 definitions = HeaderParser(test_data).ParseDefinitions() 550 self.assertEqual(1, len(definitions)) 551 definition = definitions[0] 552 self.assertEqual('TerminationStatus', definition.class_name) 553 self.assertEqual('test.namespace', definition.enum_package) 554 self.assertEqual( 555 collections.OrderedDict([ 556 ('NORMAL_TERMINATION', '0'), 557 ('STILL_RUNNING', '4'), 558 # PROCESS_WAS_KILLED_BY_OOM value should not appear here. 559 # 560 # OOM_PROTECTED should appear because the script supports the case 561 # where '#if BUILDFLAG(IS_ANDROID)' is used. 562 ('OOM_PROTECTED', '6'), 563 ('OOM', '8'), 564 # INTEGRITY_FAILURE value should not appear here. 565 ]), 566 definition.entries) 567 self.assertEqual( 568 collections.OrderedDict([ 569 ('NORMAL_TERMINATION', 'Zero exit status.'), 570 ('STILL_RUNNING', 'Child hasn\'t exited yet.'), 571 ('OOM_PROTECTED', 572 'On Android processes are spawned from the system Zygote and we ' + 573 'do not get the termination status.'), 574 ('OOM', 'Out of memory.'), 575 ]), definition.comments) 576 577 def testParseEnumStruct(self): 578 test_data = """ 579 // GENERATED_JAVA_ENUM_PACKAGE: test.namespace 580 enum struct Foo { 581 FOO_A, 582 }; 583 """.split('\n') 584 definitions = HeaderParser(test_data).ParseDefinitions() 585 self.assertEqual(1, len(definitions)) 586 definition = definitions[0] 587 self.assertEqual('Foo', definition.class_name) 588 self.assertEqual('test.namespace', definition.enum_package) 589 self.assertEqual(collections.OrderedDict([('A', 0)]), 590 definition.entries) 591 592 def testParseFixedTypeEnum(self): 593 test_data = """ 594 // GENERATED_JAVA_ENUM_PACKAGE: test.namespace 595 enum Foo : int { 596 FOO_A, 597 }; 598 """.split('\n') 599 definitions = HeaderParser(test_data).ParseDefinitions() 600 self.assertEqual(1, len(definitions)) 601 definition = definitions[0] 602 self.assertEqual('Foo', definition.class_name) 603 self.assertEqual('test.namespace', definition.enum_package) 604 self.assertEqual('int', definition.fixed_type) 605 self.assertEqual(collections.OrderedDict([('A', 0)]), 606 definition.entries) 607 608 def testParseFixedTypeEnumClass(self): 609 test_data = """ 610 // GENERATED_JAVA_ENUM_PACKAGE: test.namespace 611 enum class Foo: unsigned short { 612 FOO_A, 613 }; 614 """.split('\n') 615 definitions = HeaderParser(test_data).ParseDefinitions() 616 self.assertEqual(1, len(definitions)) 617 definition = definitions[0] 618 self.assertEqual('Foo', definition.class_name) 619 self.assertEqual('test.namespace', definition.enum_package) 620 self.assertEqual('unsigned short', definition.fixed_type) 621 self.assertEqual(collections.OrderedDict([('A', 0)]), 622 definition.entries) 623 624 def testParseUnknownFixedTypeRaises(self): 625 test_data = """ 626 // GENERATED_JAVA_ENUM_PACKAGE: test.namespace 627 enum class Foo: foo_type { 628 FOO_A, 629 }; 630 """.split('\n') 631 with self.assertRaises(Exception): 632 HeaderParser(test_data).ParseDefinitions() 633 634 def testParseSimpleMultiLineDirective(self): 635 test_data = """ 636 // GENERATED_JAVA_ENUM_PACKAGE: ( 637 // test.namespace) 638 // GENERATED_JAVA_CLASS_NAME_OVERRIDE: Bar 639 enum Foo { 640 FOO_A, 641 }; 642 """.split('\n') 643 definitions = HeaderParser(test_data).ParseDefinitions() 644 self.assertEqual('test.namespace', definitions[0].enum_package) 645 self.assertEqual('Bar', definitions[0].class_name) 646 647 def testParseMultiLineDirective(self): 648 test_data = """ 649 // GENERATED_JAVA_ENUM_PACKAGE: (te 650 // st.name 651 // space) 652 enum Foo { 653 FOO_A, 654 }; 655 """.split('\n') 656 definitions = HeaderParser(test_data).ParseDefinitions() 657 self.assertEqual('test.namespace', definitions[0].enum_package) 658 659 def testParseMultiLineDirectiveWithOtherDirective(self): 660 test_data = """ 661 // GENERATED_JAVA_ENUM_PACKAGE: ( 662 // test.namespace) 663 // GENERATED_JAVA_CLASS_NAME_OVERRIDE: ( 664 // Ba 665 // r 666 // ) 667 enum Foo { 668 FOO_A, 669 }; 670 """.split('\n') 671 definitions = HeaderParser(test_data).ParseDefinitions() 672 self.assertEqual('test.namespace', definitions[0].enum_package) 673 self.assertEqual('Bar', definitions[0].class_name) 674 675 def testParseMalformedMultiLineDirectiveWithOtherDirective(self): 676 test_data = """ 677 // GENERATED_JAVA_ENUM_PACKAGE: ( 678 // test.name 679 // space 680 // GENERATED_JAVA_CLASS_NAME_OVERRIDE: Bar 681 enum Foo { 682 FOO_A, 683 }; 684 """.split('\n') 685 with self.assertRaises(Exception): 686 HeaderParser(test_data).ParseDefinitions() 687 688 def testParseMalformedMultiLineDirective(self): 689 test_data = """ 690 // GENERATED_JAVA_ENUM_PACKAGE: ( 691 // test.name 692 // space 693 enum Foo { 694 FOO_A, 695 }; 696 """.split('\n') 697 with self.assertRaises(Exception): 698 HeaderParser(test_data).ParseDefinitions() 699 700 def testParseMalformedMultiLineDirectiveShort(self): 701 test_data = """ 702 // GENERATED_JAVA_ENUM_PACKAGE: ( 703 enum Foo { 704 FOO_A, 705 }; 706 """.split('\n') 707 with self.assertRaises(Exception): 708 HeaderParser(test_data).ParseDefinitions() 709 710 def testParseMalformedMultiLineDirectiveMissingBrackets(self): 711 test_data = """ 712 // GENERATED_JAVA_ENUM_PACKAGE: 713 // test.namespace 714 enum Foo { 715 FOO_A, 716 }; 717 """.split('\n') 718 with self.assertRaises(Exception): 719 HeaderParser(test_data).ParseDefinitions() 720 721 def testEnumValueAssignmentNoneDefined(self): 722 definition = EnumDefinition(original_enum_name='c', enum_package='p') 723 definition.AppendEntry('A', None) 724 definition.AppendEntry('B', None) 725 definition.AppendEntry('C', None) 726 definition.Finalize() 727 self.assertEqual(collections.OrderedDict([('A', 0), 728 ('B', 1), 729 ('C', 2)]), 730 definition.entries) 731 732 def testEnumValueAssignmentAllDefined(self): 733 definition = EnumDefinition(original_enum_name='c', enum_package='p') 734 definition.AppendEntry('A', '1') 735 definition.AppendEntry('B', '2') 736 definition.AppendEntry('C', '3') 737 definition.Finalize() 738 self.assertEqual(collections.OrderedDict([('A', '1'), 739 ('B', '2'), 740 ('C', '3')]), 741 definition.entries) 742 743 def testEnumValueAssignmentReferences(self): 744 definition = EnumDefinition(original_enum_name='c', enum_package='p') 745 definition.AppendEntry('A', None) 746 definition.AppendEntry('B', 'A') 747 definition.AppendEntry('C', None) 748 definition.AppendEntry('D', 'C') 749 definition.Finalize() 750 self.assertEqual(collections.OrderedDict([('A', 0), 751 ('B', 0), 752 ('C', 1), 753 ('D', 1)]), 754 definition.entries) 755 756 def testEnumValueAssignmentSet(self): 757 definition = EnumDefinition(original_enum_name='c', enum_package='p') 758 definition.AppendEntry('A', None) 759 definition.AppendEntry('B', '2') 760 definition.AppendEntry('C', None) 761 definition.Finalize() 762 self.assertEqual(collections.OrderedDict([('A', 0), 763 ('B', 2), 764 ('C', 3)]), 765 definition.entries) 766 767 def testEnumValueAssignmentSetReferences(self): 768 definition = EnumDefinition(original_enum_name='c', enum_package='p') 769 definition.AppendEntry('A', None) 770 definition.AppendEntry('B', 'A') 771 definition.AppendEntry('C', 'B') 772 definition.AppendEntry('D', None) 773 definition.Finalize() 774 self.assertEqual(collections.OrderedDict([('A', 0), 775 ('B', 0), 776 ('C', 0), 777 ('D', 1)]), 778 definition.entries) 779 780 def testEnumValueAssignmentRaises(self): 781 definition = EnumDefinition(original_enum_name='c', enum_package='p') 782 definition.AppendEntry('A', None) 783 definition.AppendEntry('B', 'foo') 784 definition.AppendEntry('C', None) 785 with self.assertRaises(Exception): 786 definition.Finalize() 787 788 def testExplicitPrefixStripping(self): 789 definition = EnumDefinition(original_enum_name='c', enum_package='p') 790 definition.AppendEntry('P_A', None) 791 definition.AppendEntry('B', None) 792 definition.AppendEntry('P_C', None) 793 definition.AppendEntry('P_LAST', 'P_C') 794 definition.prefix_to_strip = 'P_' 795 definition.Finalize() 796 self.assertEqual(collections.OrderedDict([('A', 0), 797 ('B', 1), 798 ('C', 2), 799 ('LAST', 2)]), 800 definition.entries) 801 802 def testImplicitPrefixStripping(self): 803 definition = EnumDefinition(original_enum_name='ClassName', 804 enum_package='p') 805 definition.AppendEntry('CLASS_NAME_A', None) 806 definition.AppendEntry('CLASS_NAME_B', None) 807 definition.AppendEntry('CLASS_NAME_C', None) 808 definition.AppendEntry('CLASS_NAME_LAST', 'CLASS_NAME_C') 809 definition.Finalize() 810 self.assertEqual(collections.OrderedDict([('A', 0), 811 ('B', 1), 812 ('C', 2), 813 ('LAST', 2)]), 814 definition.entries) 815 816 def testImplicitPrefixStrippingRequiresAllConstantsToBePrefixed(self): 817 definition = EnumDefinition(original_enum_name='Name', 818 enum_package='p') 819 definition.AppendEntry('A', None) 820 definition.AppendEntry('B', None) 821 definition.AppendEntry('NAME_LAST', None) 822 definition.Finalize() 823 self.assertEqual(['A', 'B', 'NAME_LAST'], list(definition.entries.keys())) 824 825 def testGenerateThrowsOnEmptyInput(self): 826 with self.assertRaises(Exception): 827 original_do_parse = java_cpp_enum.DoParseHeaderFile 828 try: 829 java_cpp_enum.DoParseHeaderFile = lambda _: [] 830 for _ in java_cpp_enum.DoGenerate(['file']): 831 pass 832 finally: 833 java_cpp_enum.DoParseHeaderFile = original_do_parse 834 835 836if __name__ == '__main__': 837 unittest.main() 838