github.com/aavshr/aws-sdk-go@v1.41.3/private/model/api/passes_test.go (about) 1 //go:build go1.8 && codegen 2 // +build go1.8,codegen 3 4 package api 5 6 import ( 7 "reflect" 8 "strconv" 9 "strings" 10 "testing" 11 ) 12 13 func TestUniqueInputAndOutputs(t *testing.T) { 14 const serviceName = "FooService" 15 16 shamelist[serviceName] = map[string]persistAPIType{ 17 "OpOutputNoRename": { 18 output: true, 19 }, 20 "OpInputNoRename": { 21 input: true, 22 }, 23 "OpBothNoRename": { 24 input: true, 25 output: true, 26 }, 27 } 28 29 cases := [][]struct { 30 expectedInput string 31 expectedOutput string 32 operation string 33 input string 34 output string 35 }{ 36 { 37 { 38 expectedInput: "FooOperationInput", 39 expectedOutput: "FooOperationOutput", 40 operation: "FooOperation", 41 input: "FooInputShape", 42 output: "FooOutputShape", 43 }, 44 { 45 expectedInput: "BarOperationInput", 46 expectedOutput: "BarOperationOutput", 47 operation: "BarOperation", 48 input: "FooInputShape", 49 output: "FooOutputShape", 50 }, 51 }, 52 { 53 { 54 expectedInput: "FooOperationInput", 55 expectedOutput: "FooOperationOutput", 56 operation: "FooOperation", 57 input: "FooInputShape", 58 output: "FooOutputShape", 59 }, 60 { 61 expectedInput: "OpOutputNoRenameInput", 62 expectedOutput: "OpOutputNoRenameOutputShape", 63 operation: "OpOutputNoRename", 64 input: "OpOutputNoRenameInputShape", 65 output: "OpOutputNoRenameOutputShape", 66 }, 67 }, 68 { 69 { 70 expectedInput: "FooOperationInput", 71 expectedOutput: "FooOperationOutput", 72 operation: "FooOperation", 73 input: "FooInputShape", 74 output: "FooOutputShape", 75 }, 76 { 77 expectedInput: "OpInputNoRenameInputShape", 78 expectedOutput: "OpInputNoRenameOutput", 79 operation: "OpInputNoRename", 80 input: "OpInputNoRenameInputShape", 81 output: "OpInputNoRenameOutputShape", 82 }, 83 }, 84 { 85 { 86 expectedInput: "FooOperationInput", 87 expectedOutput: "FooOperationOutput", 88 operation: "FooOperation", 89 input: "FooInputShape", 90 output: "FooOutputShape", 91 }, 92 { 93 expectedInput: "OpInputNoRenameInputShape", 94 expectedOutput: "OpInputNoRenameOutputShape", 95 operation: "OpBothNoRename", 96 input: "OpInputNoRenameInputShape", 97 output: "OpInputNoRenameOutputShape", 98 }, 99 }, 100 } 101 102 for i, c := range cases { 103 t.Run(strconv.Itoa(i), func(t *testing.T) { 104 a := &API{ 105 name: serviceName, 106 Operations: map[string]*Operation{}, 107 Shapes: map[string]*Shape{}, 108 } 109 110 expected := map[string][]string{} 111 for _, op := range c { 112 o := &Operation{ 113 Name: op.operation, 114 ExportedName: op.operation, 115 InputRef: ShapeRef{ 116 API: a, 117 ShapeName: op.input, 118 Shape: &Shape{ 119 API: a, 120 ShapeName: op.input, 121 }, 122 }, 123 OutputRef: ShapeRef{ 124 API: a, 125 ShapeName: op.output, 126 Shape: &Shape{ 127 API: a, 128 ShapeName: op.output, 129 }, 130 }, 131 } 132 o.InputRef.Shape.refs = append(o.InputRef.Shape.refs, &o.InputRef) 133 o.OutputRef.Shape.refs = append(o.OutputRef.Shape.refs, &o.OutputRef) 134 135 a.Operations[o.Name] = o 136 137 a.Shapes[op.input] = o.InputRef.Shape 138 a.Shapes[op.output] = o.OutputRef.Shape 139 140 expected[op.operation] = append(expected[op.operation], 141 op.expectedInput, 142 op.expectedOutput, 143 ) 144 } 145 146 a.fixStutterNames() 147 a.applyShapeNameAliases() 148 a.createInputOutputShapes() 149 for k, v := range expected { 150 if e, ac := v[0], a.Operations[k].InputRef.Shape.ShapeName; e != ac { 151 t.Errorf("Error %s case: Expected %q, but received %q", 152 k, e, ac) 153 } 154 if e, ac := v[1], a.Operations[k].OutputRef.Shape.ShapeName; e != ac { 155 t.Errorf("Error %s case: Expected %q, but received %q", 156 k, e, ac) 157 } 158 } 159 }) 160 161 } 162 } 163 164 func TestCollidingFields(t *testing.T) { 165 cases := map[string]struct { 166 MemberRefs map[string]*ShapeRef 167 Expect []string 168 IsException bool 169 }{ 170 "SimpleMembers": { 171 MemberRefs: map[string]*ShapeRef{ 172 "Code": {}, 173 "Foo": {}, 174 "GoString": {}, 175 "Message": {}, 176 "OrigErr": {}, 177 "SetFoo": {}, 178 "String": {}, 179 "Validate": {}, 180 }, 181 Expect: []string{ 182 "Code", 183 "Foo", 184 "GoString_", 185 "Message", 186 "OrigErr", 187 "SetFoo_", 188 "String_", 189 "Validate_", 190 }, 191 }, 192 "ExceptionShape": { 193 IsException: true, 194 MemberRefs: map[string]*ShapeRef{ 195 "Code": {}, 196 "Message": {}, 197 "OrigErr": {}, 198 "Other": {}, 199 "String": {}, 200 }, 201 Expect: []string{ 202 "Code_", 203 "Message_", 204 "OrigErr_", 205 "Other", 206 "String_", 207 }, 208 }, 209 } 210 211 for k, c := range cases { 212 t.Run(k, func(t *testing.T) { 213 a := &API{ 214 Shapes: map[string]*Shape{ 215 "shapename": { 216 ShapeName: k, 217 MemberRefs: c.MemberRefs, 218 Exception: c.IsException, 219 }, 220 }, 221 } 222 223 a.renameCollidingFields() 224 225 for i, name := range a.Shapes["shapename"].MemberNames() { 226 if e, a := c.Expect[i], name; e != a { 227 t.Errorf("expect %v, got %v", e, a) 228 } 229 } 230 }) 231 } 232 } 233 234 func TestCollidingFields_MaintainOriginalName(t *testing.T) { 235 cases := map[string]struct { 236 MemberRefs map[string]*ShapeRef 237 Expect map[string]*ShapeRef 238 }{ 239 "NoLocationName": { 240 MemberRefs: map[string]*ShapeRef{ 241 "String": {}, 242 }, 243 Expect: map[string]*ShapeRef{ 244 "String_": {LocationName: "String"}, 245 }, 246 }, 247 "ExitingLocationName": { 248 MemberRefs: map[string]*ShapeRef{ 249 "String": {LocationName: "OtherName"}, 250 }, 251 Expect: map[string]*ShapeRef{ 252 "String_": {LocationName: "OtherName"}, 253 }, 254 }, 255 } 256 257 for k, c := range cases { 258 t.Run(k, func(t *testing.T) { 259 a := &API{ 260 Shapes: map[string]*Shape{ 261 "shapename": { 262 ShapeName: k, 263 MemberRefs: c.MemberRefs, 264 }, 265 }, 266 } 267 268 a.renameCollidingFields() 269 270 if e, a := c.Expect, a.Shapes["shapename"].MemberRefs; !reflect.DeepEqual(e, a) { 271 t.Errorf("expect %v, got %v", e, a) 272 } 273 }) 274 } 275 } 276 277 func TestCreateInputOutputShapes(t *testing.T) { 278 meta := Metadata{ 279 APIVersion: "0000-00-00", 280 EndpointPrefix: "rpcservice", 281 JSONVersion: "1.1", 282 Protocol: "json", 283 ServiceAbbreviation: "RPCService", 284 ServiceFullName: "RPC Service", 285 ServiceID: "RPCService", 286 SignatureVersion: "v4", 287 TargetPrefix: "RPCService_00000000", 288 UID: "RPCService-0000-00-00", 289 } 290 291 type OpExpect struct { 292 Input string 293 Output string 294 } 295 296 cases := map[string]struct { 297 API *API 298 ExpectOps map[string]OpExpect 299 ExpectShapes []string 300 }{ 301 "allRename": { 302 API: &API{Metadata: meta, 303 Operations: map[string]*Operation{ 304 "FirstOp": { 305 Name: "FirstOp", 306 InputRef: ShapeRef{ShapeName: "FirstOpRequest"}, 307 OutputRef: ShapeRef{ShapeName: "FirstOpResponse"}, 308 }, 309 "SecondOp": { 310 Name: "SecondOp", 311 InputRef: ShapeRef{ShapeName: "SecondOpRequest"}, 312 OutputRef: ShapeRef{ShapeName: "SecondOpResponse"}, 313 }, 314 }, 315 Shapes: map[string]*Shape{ 316 "FirstOpRequest": { 317 ShapeName: "FirstOpRequest", 318 Type: "structure", 319 }, 320 "FirstOpResponse": { 321 ShapeName: "FirstOpResponse", 322 Type: "structure", 323 }, 324 "SecondOpRequest": { 325 ShapeName: "SecondOpRequest", 326 Type: "structure", 327 }, 328 "SecondOpResponse": { 329 ShapeName: "SecondOpResponse", 330 Type: "structure", 331 }, 332 }, 333 }, 334 ExpectOps: map[string]OpExpect{ 335 "FirstOp": { 336 Input: "FirstOpInput", 337 Output: "FirstOpOutput", 338 }, 339 "SecondOp": { 340 Input: "SecondOpInput", 341 Output: "SecondOpOutput", 342 }, 343 }, 344 ExpectShapes: []string{ 345 "FirstOpInput", 346 "FirstOpOutput", 347 "SecondOpInput", 348 "SecondOpOutput", 349 }, 350 }, 351 "noRename": { 352 API: &API{Metadata: meta, 353 Operations: map[string]*Operation{ 354 "FirstOp": { 355 Name: "FirstOp", 356 InputRef: ShapeRef{ShapeName: "FirstOpInput"}, 357 OutputRef: ShapeRef{ShapeName: "FirstOpOutput"}, 358 }, 359 "SecondOp": { 360 Name: "SecondOp", 361 InputRef: ShapeRef{ShapeName: "SecondOpInput"}, 362 OutputRef: ShapeRef{ShapeName: "SecondOpOutput"}, 363 }, 364 }, 365 Shapes: map[string]*Shape{ 366 "FirstOpInput": { 367 ShapeName: "FirstOpInput", 368 Type: "structure", 369 }, 370 "FirstOpOutput": { 371 ShapeName: "FirstOpOutput", 372 Type: "structure", 373 }, 374 "SecondOpInput": { 375 ShapeName: "SecondOpInput", 376 Type: "structure", 377 }, 378 "SecondOpOutput": { 379 ShapeName: "SecondOpOutput", 380 Type: "structure", 381 }, 382 }, 383 }, 384 ExpectOps: map[string]OpExpect{ 385 "FirstOp": { 386 Input: "FirstOpInput", 387 Output: "FirstOpOutput", 388 }, 389 "SecondOp": { 390 Input: "SecondOpInput", 391 Output: "SecondOpOutput", 392 }, 393 }, 394 ExpectShapes: []string{ 395 "FirstOpInput", 396 "FirstOpOutput", 397 "SecondOpInput", 398 "SecondOpOutput", 399 }, 400 }, 401 "renameWithNested": { 402 API: &API{Metadata: meta, 403 Operations: map[string]*Operation{ 404 "FirstOp": { 405 Name: "FirstOp", 406 InputRef: ShapeRef{ShapeName: "FirstOpWriteMe"}, 407 OutputRef: ShapeRef{ShapeName: "FirstOpReadMe"}, 408 }, 409 "SecondOp": { 410 Name: "SecondOp", 411 InputRef: ShapeRef{ShapeName: "SecondOpWriteMe"}, 412 OutputRef: ShapeRef{ShapeName: "SecondOpReadMe"}, 413 }, 414 }, 415 Shapes: map[string]*Shape{ 416 "FirstOpWriteMe": { 417 ShapeName: "FirstOpWriteMe", 418 Type: "structure", 419 MemberRefs: map[string]*ShapeRef{ 420 "Foo": {ShapeName: "String"}, 421 }, 422 }, 423 "FirstOpReadMe": { 424 ShapeName: "FirstOpReadMe", 425 Type: "structure", 426 MemberRefs: map[string]*ShapeRef{ 427 "Bar": {ShapeName: "Struct"}, 428 "Once": {ShapeName: "Once"}, 429 }, 430 }, 431 "SecondOpWriteMe": { 432 ShapeName: "SecondOpWriteMe", 433 Type: "structure", 434 }, 435 "SecondOpReadMe": { 436 ShapeName: "SecondOpReadMe", 437 Type: "structure", 438 }, 439 "Once": { 440 ShapeName: "Once", 441 Type: "string", 442 }, 443 "String": { 444 ShapeName: "String", 445 Type: "string", 446 }, 447 "Struct": { 448 ShapeName: "Struct", 449 Type: "structure", 450 MemberRefs: map[string]*ShapeRef{ 451 "Foo": {ShapeName: "String"}, 452 "Bar": {ShapeName: "Struct"}, 453 }, 454 }, 455 }, 456 }, 457 ExpectOps: map[string]OpExpect{ 458 "FirstOp": { 459 Input: "FirstOpInput", 460 Output: "FirstOpOutput", 461 }, 462 "SecondOp": { 463 Input: "SecondOpInput", 464 Output: "SecondOpOutput", 465 }, 466 }, 467 ExpectShapes: []string{ 468 "FirstOpInput", 469 "FirstOpOutput", 470 "Once", 471 "SecondOpInput", 472 "SecondOpOutput", 473 "String", 474 "Struct", 475 }, 476 }, 477 "aliasedInput": { 478 API: &API{Metadata: meta, 479 Operations: map[string]*Operation{ 480 "FirstOp": { 481 Name: "FirstOp", 482 InputRef: ShapeRef{ShapeName: "FirstOpRequest"}, 483 OutputRef: ShapeRef{ShapeName: "FirstOpResponse"}, 484 }, 485 }, 486 Shapes: map[string]*Shape{ 487 "FirstOpRequest": { 488 ShapeName: "FirstOpRequest", 489 Type: "structure", 490 AliasedShapeName: true, 491 }, 492 "FirstOpResponse": { 493 ShapeName: "FirstOpResponse", 494 Type: "structure", 495 }, 496 }, 497 }, 498 ExpectOps: map[string]OpExpect{ 499 "FirstOp": { 500 Input: "FirstOpRequest", 501 Output: "FirstOpOutput", 502 }, 503 }, 504 ExpectShapes: []string{ 505 "FirstOpOutput", 506 "FirstOpRequest", 507 }, 508 }, 509 "aliasedOutput": { 510 API: &API{ 511 Metadata: meta, 512 Operations: map[string]*Operation{ 513 "FirstOp": { 514 Name: "FirstOp", 515 InputRef: ShapeRef{ShapeName: "FirstOpRequest"}, 516 OutputRef: ShapeRef{ShapeName: "FirstOpResponse"}, 517 }, 518 }, 519 Shapes: map[string]*Shape{ 520 "FirstOpRequest": { 521 ShapeName: "FirstOpRequest", 522 Type: "structure", 523 }, 524 "FirstOpResponse": { 525 ShapeName: "FirstOpResponse", 526 Type: "structure", 527 AliasedShapeName: true, 528 }, 529 }, 530 }, 531 ExpectOps: map[string]OpExpect{ 532 "FirstOp": { 533 Input: "FirstOpInput", 534 Output: "FirstOpResponse", 535 }, 536 }, 537 ExpectShapes: []string{ 538 "FirstOpInput", "FirstOpResponse", 539 }, 540 }, 541 "resusedShape": { 542 API: &API{ 543 Metadata: meta, 544 Operations: map[string]*Operation{ 545 "FirstOp": { 546 Name: "FirstOp", 547 InputRef: ShapeRef{ShapeName: "FirstOpRequest"}, 548 OutputRef: ShapeRef{ShapeName: "ReusedShape"}, 549 }, 550 }, 551 Shapes: map[string]*Shape{ 552 "FirstOpRequest": { 553 ShapeName: "FirstOpRequest", 554 Type: "structure", 555 MemberRefs: map[string]*ShapeRef{ 556 "Foo": {ShapeName: "ReusedShape"}, 557 "ooF": {ShapeName: "ReusedShapeList"}, 558 }, 559 }, 560 "ReusedShape": { 561 ShapeName: "ReusedShape", 562 Type: "structure", 563 }, 564 "ReusedShapeList": { 565 ShapeName: "ReusedShapeList", 566 Type: "list", 567 MemberRef: ShapeRef{ShapeName: "ReusedShape"}, 568 }, 569 }, 570 }, 571 ExpectOps: map[string]OpExpect{ 572 "FirstOp": { 573 Input: "FirstOpInput", 574 Output: "FirstOpOutput", 575 }, 576 }, 577 ExpectShapes: []string{ 578 "FirstOpInput", 579 "FirstOpOutput", 580 "ReusedShape", 581 "ReusedShapeList", 582 }, 583 }, 584 "aliasedResusedShape": { 585 API: &API{ 586 Metadata: meta, 587 Operations: map[string]*Operation{ 588 "FirstOp": { 589 Name: "FirstOp", 590 InputRef: ShapeRef{ShapeName: "FirstOpRequest"}, 591 OutputRef: ShapeRef{ShapeName: "ReusedShape"}, 592 }, 593 }, 594 Shapes: map[string]*Shape{ 595 "FirstOpRequest": { 596 ShapeName: "FirstOpRequest", 597 Type: "structure", 598 MemberRefs: map[string]*ShapeRef{ 599 "Foo": {ShapeName: "ReusedShape"}, 600 "ooF": {ShapeName: "ReusedShapeList"}, 601 }, 602 }, 603 "ReusedShape": { 604 ShapeName: "ReusedShape", 605 Type: "structure", 606 AliasedShapeName: true, 607 }, 608 "ReusedShapeList": { 609 ShapeName: "ReusedShapeList", 610 Type: "list", 611 MemberRef: ShapeRef{ShapeName: "ReusedShape"}, 612 }, 613 }, 614 }, 615 ExpectOps: map[string]OpExpect{ 616 "FirstOp": { 617 Input: "FirstOpInput", 618 Output: "ReusedShape", 619 }, 620 }, 621 ExpectShapes: []string{ 622 "FirstOpInput", 623 "ReusedShape", 624 "ReusedShapeList", 625 }, 626 }, 627 "unsetInput": { 628 API: &API{Metadata: meta, 629 Operations: map[string]*Operation{ 630 "FirstOp": { 631 Name: "FirstOp", 632 OutputRef: ShapeRef{ShapeName: "FirstOpResponse"}, 633 }, 634 }, 635 Shapes: map[string]*Shape{ 636 "FirstOpResponse": { 637 ShapeName: "FirstOpResponse", 638 Type: "structure", 639 }, 640 }, 641 }, 642 ExpectOps: map[string]OpExpect{ 643 "FirstOp": { 644 Input: "FirstOpInput", 645 Output: "FirstOpOutput", 646 }, 647 }, 648 ExpectShapes: []string{ 649 "FirstOpInput", 650 "FirstOpOutput", 651 }, 652 }, 653 "unsetOutput": { 654 API: &API{Metadata: meta, 655 Operations: map[string]*Operation{ 656 "FirstOp": { 657 Name: "FirstOp", 658 InputRef: ShapeRef{ShapeName: "FirstOpRequest"}, 659 }, 660 }, 661 Shapes: map[string]*Shape{ 662 "FirstOpRequest": { 663 ShapeName: "FirstOpRequest", 664 Type: "structure", 665 }, 666 }, 667 }, 668 ExpectOps: map[string]OpExpect{ 669 "FirstOp": { 670 Input: "FirstOpInput", 671 Output: "FirstOpOutput", 672 }, 673 }, 674 ExpectShapes: []string{ 675 "FirstOpInput", 676 "FirstOpOutput", 677 }, 678 }, 679 "collidingShape": { 680 API: &API{ 681 name: "APIClientName", 682 Metadata: meta, 683 Operations: map[string]*Operation{ 684 "FirstOp": { 685 Name: "FirstOp", 686 InputRef: ShapeRef{ShapeName: "FirstOpRequest"}, 687 }, 688 }, 689 Shapes: map[string]*Shape{ 690 "FirstOpRequest": { 691 ShapeName: "FirstOpRequest", 692 Type: "structure", 693 MemberRefs: map[string]*ShapeRef{ 694 "Foo": {ShapeName: "APIClientName"}, 695 "ooF": {ShapeName: "APIClientNameList"}, 696 }, 697 }, 698 "APIClientName": { 699 ShapeName: "APIClientName", Type: "structure", 700 }, 701 "APIClientNameList": { 702 ShapeName: "APIClientNameList", Type: "list", 703 MemberRef: ShapeRef{ShapeName: "APIClientName"}, 704 }, 705 }, 706 }, 707 ExpectOps: map[string]OpExpect{ 708 "FirstOp": { 709 Input: "FirstOpInput", 710 Output: "FirstOpOutput", 711 }, 712 }, 713 ExpectShapes: []string{ 714 "APIClientNameList", 715 "APIClientName_", 716 "FirstOpInput", 717 "FirstOpOutput", 718 }, 719 }, 720 "MemberShapesWithInputAsSuffix": { 721 API: &API{ 722 name: "APIClientName", 723 Metadata: meta, 724 Operations: map[string]*Operation{ 725 "FirstOp": { 726 Name: "FirstOp", 727 InputRef: ShapeRef{ShapeName: "FirstOpRequest"}, 728 }, 729 }, 730 Shapes: map[string]*Shape{ 731 "FirstOpRequest": { 732 ShapeName: "FirstOpRequest", 733 Type: "structure", 734 MemberRefs: map[string]*ShapeRef{ 735 "Foo": {ShapeName: "APIClientName"}, 736 "ooF": {ShapeName: "FirstOpInput"}, 737 }, 738 }, 739 "APIClientName": { 740 ShapeName: "APIClientName", Type: "structure", 741 }, 742 "FirstOpInput": { 743 ShapeName: "FirstOpInput", Type: "list", 744 MemberRef: ShapeRef{ 745 ShapeName: "APIClientName", 746 }, 747 }, 748 }, 749 }, 750 ExpectOps: map[string]OpExpect{ 751 "FirstOp": { 752 Input: "FirstOpInput", 753 Output: "FirstOpOutput", 754 }, 755 }, 756 ExpectShapes: []string{ 757 "APIClientName_", 758 "FirstOpInput", 759 "FirstOpInput_", 760 "FirstOpOutput", 761 }, 762 }, 763 "MemberShapesWithOutputAsSuffix": { 764 API: &API{ 765 name: "APIClientName", 766 Metadata: meta, 767 Operations: map[string]*Operation{ 768 "FirstOp": { 769 Name: "FirstOp", 770 OutputRef: ShapeRef{ShapeName: "FirstOpResponse"}, 771 }, 772 }, 773 Shapes: map[string]*Shape{ 774 "FirstOpResponse": { 775 ShapeName: "FirstOpResponse", 776 Type: "structure", 777 MemberRefs: map[string]*ShapeRef{ 778 "Foo": {ShapeName: "APIClientName"}, 779 "ooF": {ShapeName: "FirstOpOutput"}, 780 }, 781 }, 782 "APIClientName": { 783 ShapeName: "APIClientName", Type: "structure", 784 }, 785 "FirstOpOutput": { 786 ShapeName: "FirstOpOutput", Type: "list", 787 MemberRef: ShapeRef{ShapeName: "APIClientName"}, 788 }, 789 }, 790 }, 791 ExpectOps: map[string]OpExpect{ 792 "FirstOp": { 793 Input: "FirstOpInput", 794 Output: "FirstOpOutput", 795 }, 796 }, 797 ExpectShapes: []string{ 798 "APIClientName_", 799 "FirstOpInput", 800 "FirstOpOutput", 801 "FirstOpOutput_", 802 }, 803 }, 804 } 805 806 for name, c := range cases { 807 t.Run(name, func(t *testing.T) { 808 a := c.API 809 a.Setup() 810 811 for opName, op := range a.Operations { 812 if e, a := op.InputRef.ShapeName, op.InputRef.Shape.ShapeName; e != a { 813 t.Errorf("expect input ref and shape names to match, %s, %s", e, a) 814 } 815 if e, a := c.ExpectOps[opName].Input, op.InputRef.ShapeName; e != a { 816 t.Errorf("expect %v input shape, got %v", e, a) 817 } 818 819 if e, a := op.OutputRef.ShapeName, op.OutputRef.Shape.ShapeName; e != a { 820 t.Errorf("expect output ref and shape names to match, %s, %s", e, a) 821 } 822 if e, a := c.ExpectOps[opName].Output, op.OutputRef.ShapeName; e != a { 823 t.Errorf("expect %v output shape, got %v", e, a) 824 } 825 } 826 827 if e, a := c.ExpectShapes, a.ShapeNames(); !reflect.DeepEqual(e, a) { 828 t.Errorf("expect %v shapes, got %v", e, a) 829 } 830 }) 831 } 832 } 833 834 func TestValidateShapeNameMethod(t *testing.T) { 835 cases := map[string]struct { 836 inputShapeName string 837 shapeType string 838 expectedShapeName string 839 expectedError string 840 }{ 841 "empty case": { 842 inputShapeName: "", 843 shapeType: "structure", 844 expectedShapeName: "", 845 expectedError: "invalid shape name found", 846 }, 847 "No rename": { 848 inputShapeName: "Sample123Shape", 849 shapeType: "structure", 850 expectedShapeName: "Sample123Shape", 851 }, 852 "starts with underscores": { 853 inputShapeName: "__Sample123Shape", 854 shapeType: "structure", 855 expectedShapeName: "Sample123Shape", 856 }, 857 "Contains underscores": { 858 inputShapeName: "__sample_123_shape__", 859 shapeType: "structure", 860 expectedShapeName: "Sample123Shape", 861 }, 862 "Starts with numeric character": { 863 inputShapeName: "123__sampleShape", 864 shapeType: "structure", 865 expectedShapeName: "", 866 expectedError: "invalid shape name found", 867 }, 868 "Starts with non alphabetic or non underscore character": { 869 inputShapeName: "&&SampleShape", 870 shapeType: "structure", 871 expectedShapeName: "", 872 expectedError: "invalid shape name found", 873 }, 874 "Contains non Alphanumeric or non underscore character": { 875 inputShapeName: "Sample&__Shape", 876 shapeType: "structure", 877 expectedShapeName: "", 878 expectedError: "invalid shape name found", 879 }, 880 "Renamed Shape already exists": { 881 inputShapeName: "__sample_shape", 882 shapeType: "structure", 883 expectedShapeName: "", 884 expectedError: "rename would result in shape name collision", 885 }, 886 "empty case for enums shape type": { 887 inputShapeName: "", 888 shapeType: "string", 889 expectedShapeName: "", 890 expectedError: "invalid shape name found", 891 }, 892 "No rename for enums shape type": { 893 inputShapeName: "Sample123Shape", 894 shapeType: "string", 895 expectedShapeName: "Sample123Shape", 896 }, 897 "starts with underscores for enums shape type": { 898 inputShapeName: "__Sample123Shape", 899 shapeType: "string", 900 expectedShapeName: "Sample123Shape", 901 }, 902 "Contains underscores for enums shape type": { 903 inputShapeName: "__sample_123_shape__", 904 shapeType: "string", 905 expectedShapeName: "Sample123Shape", 906 }, 907 "Starts with numeric character for enums shape type": { 908 inputShapeName: "123__sampleShape", 909 shapeType: "string", 910 expectedShapeName: "", 911 expectedError: "invalid shape name found", 912 }, 913 "Starts with non alphabetic or non underscore character for enums shape type": { 914 inputShapeName: "&&SampleShape", 915 shapeType: "string", 916 expectedShapeName: "", 917 expectedError: "invalid shape name found", 918 }, 919 "Contains non Alphanumeric or non underscore character for enums shape type": { 920 inputShapeName: "Sample&__Shape", 921 shapeType: "string", 922 expectedShapeName: "", 923 expectedError: "invalid shape name found", 924 }, 925 "Renamed Shape already exists for enums shape type": { 926 inputShapeName: "__sample_shape", 927 shapeType: "string", 928 expectedShapeName: "", 929 expectedError: "rename would result in shape name collision", 930 }, 931 } 932 933 for name, c := range cases { 934 operation := "FooOperation" 935 t.Run(name, func(t *testing.T) { 936 a := &API{ 937 Operations: map[string]*Operation{}, 938 Shapes: map[string]*Shape{}, 939 } 940 // add another shape with name SampleShape to check for collision 941 a.Shapes["SampleShape"] = &Shape{ShapeName: "SampleShape"} 942 o := &Operation{ 943 Name: operation, 944 ExportedName: operation, 945 InputRef: ShapeRef{ 946 API: a, 947 ShapeName: c.inputShapeName, 948 Shape: &Shape{ 949 API: a, 950 ShapeName: c.inputShapeName, 951 Type: c.shapeType, 952 Enum: []string{"x"}, 953 }, 954 }, 955 } 956 o.InputRef.Shape.refs = append(o.InputRef.Shape.refs, &o.InputRef) 957 a.Operations[o.Name] = o 958 a.Shapes[c.inputShapeName] = o.InputRef.Shape 959 960 err := a.validateShapeNames() 961 if err != nil || c.expectedError != "" { 962 if err == nil { 963 t.Fatalf("Received no error, expected error with log: \n \t %v ", c.expectedError) 964 } 965 if c.expectedError == "" { 966 t.Fatalf("Expected no error, got %v", err.Error()) 967 } 968 if e, a := err.Error(), c.expectedError; !strings.Contains(e, a) { 969 t.Fatalf("Expected to receive error containing %v, got %v", e, a) 970 } 971 return 972 } 973 974 if e, a := c.expectedShapeName, o.InputRef.Shape.ShapeName; e != a { 975 t.Fatalf("Expected shape name to be %v, got %v", e, a) 976 } 977 }) 978 } 979 }