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