github.com/nathanstitt/genqlient@v0.3.1-0.20211028004951-a2bda3c41ab8/internal/integration/integration_test.go (about) 1 // Package integration contains genqlient's integration tests, which run 2 // against a real server (defined in internal/integration/server/server.go). 3 // 4 // These are especially important for cases where we generate nontrivial logic, 5 // such as JSON-unmarshaling. 6 package integration 7 8 import ( 9 "context" 10 "net/http" 11 "testing" 12 "time" 13 14 "github.com/stretchr/testify/assert" 15 "github.com/stretchr/testify/require" 16 17 "github.com/Khan/genqlient/graphql" 18 "github.com/Khan/genqlient/internal/integration/server" 19 ) 20 21 func TestSimpleQuery(t *testing.T) { 22 _ = `# @genqlient 23 query simpleQuery { me { id name luckyNumber } }` 24 25 ctx := context.Background() 26 server := server.RunServer() 27 defer server.Close() 28 client := newRoundtripClient(t, server.URL) 29 30 resp, err := simpleQuery(ctx, client) 31 require.NoError(t, err) 32 33 assert.Equal(t, "1", resp.Me.Id) 34 assert.Equal(t, "Yours Truly", resp.Me.Name) 35 assert.Equal(t, 17, resp.Me.LuckyNumber) 36 } 37 38 func TestServerError(t *testing.T) { 39 _ = `# @genqlient 40 query failingQuery { fail me { id } }` 41 42 ctx := context.Background() 43 server := server.RunServer() 44 defer server.Close() 45 client := newRoundtripClient(t, server.URL) 46 47 resp, err := failingQuery(ctx, client) 48 // As long as we get some response back, we should still return a full 49 // response -- and indeed in this case it should even have another field 50 // (which didn't err) set. 51 assert.Error(t, err) 52 assert.NotNil(t, resp) 53 assert.Equal(t, "1", resp.Me.Id) 54 } 55 56 func TestNetworkError(t *testing.T) { 57 ctx := context.Background() 58 client := newRoundtripClient(t, "https://nothing.invalid/graphql") 59 60 resp, err := failingQuery(ctx, client) 61 // As we guarantee in the README, even on network error you always get a 62 // non-nil response; this is so you can write e.g. 63 // resp, err := failingQuery(ctx) 64 // return resp.Me.Id, err 65 // without a bunch of extra ceremony. 66 assert.Error(t, err) 67 assert.NotNil(t, resp) 68 assert.Equal(t, new(failingQueryResponse), resp) 69 } 70 71 func TestVariables(t *testing.T) { 72 _ = `# @genqlient 73 query queryWithVariables($id: ID!) { user(id: $id) { id name luckyNumber } }` 74 75 ctx := context.Background() 76 server := server.RunServer() 77 defer server.Close() 78 // This doesn't roundtrip successfully because the zero user gets marshaled 79 // as {"id": "", "name": "", ...}, not null. There's really no way to do 80 // this right in Go (without adding `pointer: true` just for this purpose), 81 // and unmarshal(marshal(resp)) == resp should still hold, so we don't 82 // worry about it. 83 client := graphql.NewClient(server.URL, http.DefaultClient) 84 85 resp, err := queryWithVariables(ctx, client, "2") 86 require.NoError(t, err) 87 88 assert.Equal(t, "2", resp.User.Id) 89 assert.Equal(t, "Raven", resp.User.Name) 90 assert.Equal(t, -1, resp.User.LuckyNumber) 91 92 resp, err = queryWithVariables(ctx, client, "374892379482379") 93 require.NoError(t, err) 94 95 assert.Zero(t, resp.User) 96 } 97 98 func TestOmitempty(t *testing.T) { 99 _ = `# @genqlient(omitempty: true) 100 query queryWithOmitempty($id: ID) { 101 user(id: $id) { id name luckyNumber } 102 }` 103 104 ctx := context.Background() 105 server := server.RunServer() 106 defer server.Close() 107 client := newRoundtripClient(t, server.URL) 108 109 resp, err := queryWithOmitempty(ctx, client, "2") 110 require.NoError(t, err) 111 112 assert.Equal(t, "2", resp.User.Id) 113 assert.Equal(t, "Raven", resp.User.Name) 114 assert.Equal(t, -1, resp.User.LuckyNumber) 115 116 // should return default user, not the user with ID "" 117 resp, err = queryWithOmitempty(ctx, client, "") 118 require.NoError(t, err) 119 120 assert.Equal(t, "1", resp.User.Id) 121 assert.Equal(t, "Yours Truly", resp.User.Name) 122 assert.Equal(t, 17, resp.User.LuckyNumber) 123 } 124 125 func TestCustomMarshal(t *testing.T) { 126 _ = `# @genqlient 127 query queryWithCustomMarshal($date: Date!) { 128 usersBornOn(date: $date) { id name birthdate } 129 }` 130 131 ctx := context.Background() 132 server := server.RunServer() 133 defer server.Close() 134 client := newRoundtripClient(t, server.URL) 135 136 resp, err := queryWithCustomMarshal(ctx, client, 137 time.Date(2025, time.January, 1, 12, 34, 56, 789, time.UTC)) 138 require.NoError(t, err) 139 140 assert.Len(t, resp.UsersBornOn, 1) 141 user := resp.UsersBornOn[0] 142 assert.Equal(t, "1", user.Id) 143 assert.Equal(t, "Yours Truly", user.Name) 144 assert.Equal(t, 145 time.Date(2025, time.January, 1, 0, 0, 0, 0, time.UTC), 146 user.Birthdate) 147 148 resp, err = queryWithCustomMarshal(ctx, client, 149 time.Date(2021, time.January, 1, 12, 34, 56, 789, time.UTC)) 150 require.NoError(t, err) 151 assert.Len(t, resp.UsersBornOn, 0) 152 } 153 154 func TestCustomMarshalSlice(t *testing.T) { 155 _ = `# @genqlient 156 query queryWithCustomMarshalSlice($dates: [Date!]!) { 157 usersBornOnDates(dates: $dates) { id name birthdate } 158 }` 159 160 ctx := context.Background() 161 server := server.RunServer() 162 defer server.Close() 163 client := newRoundtripClient(t, server.URL) 164 165 resp, err := queryWithCustomMarshalSlice(ctx, client, 166 []time.Time{time.Date(2025, time.January, 1, 12, 34, 56, 789, time.UTC)}) 167 require.NoError(t, err) 168 169 assert.Len(t, resp.UsersBornOnDates, 1) 170 user := resp.UsersBornOnDates[0] 171 assert.Equal(t, "1", user.Id) 172 assert.Equal(t, "Yours Truly", user.Name) 173 assert.Equal(t, 174 time.Date(2025, time.January, 1, 0, 0, 0, 0, time.UTC), 175 user.Birthdate) 176 177 resp, err = queryWithCustomMarshalSlice(ctx, client, 178 []time.Time{time.Date(2021, time.January, 1, 12, 34, 56, 789, time.UTC)}) 179 require.NoError(t, err) 180 assert.Len(t, resp.UsersBornOnDates, 0) 181 } 182 183 func TestCustomMarshalOptional(t *testing.T) { 184 _ = `# @genqlient 185 query queryWithCustomMarshalOptional( 186 # @genqlient(pointer: true) 187 $date: Date, 188 # @genqlient(pointer: true) 189 $id: ID, 190 ) { 191 userSearch(birthdate: $date, id: $id) { id name birthdate } 192 }` 193 194 ctx := context.Background() 195 server := server.RunServer() 196 defer server.Close() 197 client := newRoundtripClient(t, server.URL) 198 199 date := time.Date(2025, time.January, 1, 12, 34, 56, 789, time.UTC) 200 resp, err := queryWithCustomMarshalOptional(ctx, client, &date, nil) 201 require.NoError(t, err) 202 203 assert.Len(t, resp.UserSearch, 1) 204 user := resp.UserSearch[0] 205 assert.Equal(t, "1", user.Id) 206 assert.Equal(t, "Yours Truly", user.Name) 207 assert.Equal(t, 208 time.Date(2025, time.January, 1, 0, 0, 0, 0, time.UTC), 209 user.Birthdate) 210 211 id := "2" 212 resp, err = queryWithCustomMarshalOptional(ctx, client, nil, &id) 213 require.NoError(t, err) 214 assert.Len(t, resp.UserSearch, 1) 215 user = resp.UserSearch[0] 216 assert.Equal(t, "2", user.Id) 217 assert.Equal(t, "Raven", user.Name) 218 assert.Zero(t, user.Birthdate) 219 } 220 221 func TestInterfaceNoFragments(t *testing.T) { 222 _ = `# @genqlient 223 query queryWithInterfaceNoFragments($id: ID!) { 224 being(id: $id) { id name } 225 me { id name } 226 }` 227 228 ctx := context.Background() 229 server := server.RunServer() 230 defer server.Close() 231 client := newRoundtripClient(t, server.URL) 232 233 resp, err := queryWithInterfaceNoFragments(ctx, client, "1") 234 require.NoError(t, err) 235 236 // We should get the following response: 237 // me: User{Id: 1, Name: "Yours Truly"}, 238 // being: User{Id: 1, Name: "Yours Truly"}, 239 240 assert.Equal(t, "1", resp.Me.Id) 241 assert.Equal(t, "Yours Truly", resp.Me.Name) 242 243 // Check fields both via interface and via type-assertion: 244 assert.Equal(t, "User", resp.Being.GetTypename()) 245 assert.Equal(t, "1", resp.Being.GetId()) 246 assert.Equal(t, "Yours Truly", resp.Being.GetName()) 247 248 user, ok := resp.Being.(*queryWithInterfaceNoFragmentsBeingUser) 249 require.Truef(t, ok, "got %T, not User", resp.Being) 250 assert.Equal(t, "1", user.Id) 251 assert.Equal(t, "Yours Truly", user.Name) 252 253 resp, err = queryWithInterfaceNoFragments(ctx, client, "3") 254 require.NoError(t, err) 255 256 // We should get the following response: 257 // me: User{Id: 1, Name: "Yours Truly"}, 258 // being: Animal{Id: 3, Name: "Fido"}, 259 260 assert.Equal(t, "1", resp.Me.Id) 261 assert.Equal(t, "Yours Truly", resp.Me.Name) 262 263 assert.Equal(t, "Animal", resp.Being.GetTypename()) 264 assert.Equal(t, "3", resp.Being.GetId()) 265 assert.Equal(t, "Fido", resp.Being.GetName()) 266 267 animal, ok := resp.Being.(*queryWithInterfaceNoFragmentsBeingAnimal) 268 require.Truef(t, ok, "got %T, not Animal", resp.Being) 269 assert.Equal(t, "3", animal.Id) 270 assert.Equal(t, "Fido", animal.Name) 271 272 resp, err = queryWithInterfaceNoFragments(ctx, client, "4757233945723") 273 require.NoError(t, err) 274 275 // We should get the following response: 276 // me: User{Id: 1, Name: "Yours Truly"}, 277 // being: null 278 279 assert.Equal(t, "1", resp.Me.Id) 280 assert.Equal(t, "Yours Truly", resp.Me.Name) 281 282 assert.Nil(t, resp.Being) 283 } 284 285 func TestInterfaceListField(t *testing.T) { 286 _ = `# @genqlient 287 query queryWithInterfaceListField($ids: [ID!]!) { 288 beings(ids: $ids) { id name } 289 }` 290 291 ctx := context.Background() 292 server := server.RunServer() 293 defer server.Close() 294 client := newRoundtripClient(t, server.URL) 295 296 resp, err := queryWithInterfaceListField(ctx, client, 297 []string{"1", "3", "12847394823"}) 298 require.NoError(t, err) 299 300 require.Len(t, resp.Beings, 3) 301 302 // We should get the following three beings: 303 // User{Id: 1, Name: "Yours Truly"}, 304 // Animal{Id: 3, Name: "Fido"}, 305 // null 306 307 // Check fields both via interface and via type-assertion: 308 assert.Equal(t, "User", resp.Beings[0].GetTypename()) 309 assert.Equal(t, "1", resp.Beings[0].GetId()) 310 assert.Equal(t, "Yours Truly", resp.Beings[0].GetName()) 311 312 user, ok := resp.Beings[0].(*queryWithInterfaceListFieldBeingsUser) 313 require.Truef(t, ok, "got %T, not User", resp.Beings[0]) 314 assert.Equal(t, "1", user.Id) 315 assert.Equal(t, "Yours Truly", user.Name) 316 317 assert.Equal(t, "Animal", resp.Beings[1].GetTypename()) 318 assert.Equal(t, "3", resp.Beings[1].GetId()) 319 assert.Equal(t, "Fido", resp.Beings[1].GetName()) 320 321 animal, ok := resp.Beings[1].(*queryWithInterfaceListFieldBeingsAnimal) 322 require.Truef(t, ok, "got %T, not Animal", resp.Beings[1]) 323 assert.Equal(t, "3", animal.Id) 324 assert.Equal(t, "Fido", animal.Name) 325 326 assert.Nil(t, resp.Beings[2]) 327 } 328 329 func TestInterfaceListPointerField(t *testing.T) { 330 _ = `# @genqlient 331 query queryWithInterfaceListPointerField($ids: [ID!]!) { 332 # @genqlient(pointer: true) 333 beings(ids: $ids) { 334 __typename id name 335 } 336 }` 337 338 ctx := context.Background() 339 server := server.RunServer() 340 defer server.Close() 341 client := newRoundtripClient(t, server.URL) 342 343 resp, err := queryWithInterfaceListPointerField(ctx, client, 344 []string{"1", "3", "12847394823"}) 345 require.NoError(t, err) 346 347 require.Len(t, resp.Beings, 3) 348 349 // Check fields both via interface and via type-assertion: 350 assert.Equal(t, "User", (*resp.Beings[0]).GetTypename()) 351 assert.Equal(t, "1", (*resp.Beings[0]).GetId()) 352 assert.Equal(t, "Yours Truly", (*resp.Beings[0]).GetName()) 353 354 user, ok := (*resp.Beings[0]).(*queryWithInterfaceListPointerFieldBeingsUser) 355 require.Truef(t, ok, "got %T, not User", *resp.Beings[0]) 356 assert.Equal(t, "1", user.Id) 357 assert.Equal(t, "Yours Truly", user.Name) 358 359 assert.Equal(t, "Animal", (*resp.Beings[1]).GetTypename()) 360 assert.Equal(t, "3", (*resp.Beings[1]).GetId()) 361 assert.Equal(t, "Fido", (*resp.Beings[1]).GetName()) 362 363 animal, ok := (*resp.Beings[1]).(*queryWithInterfaceListPointerFieldBeingsAnimal) 364 require.Truef(t, ok, "got %T, not Animal", resp.Beings[1]) 365 assert.Equal(t, "3", animal.Id) 366 assert.Equal(t, "Fido", animal.Name) 367 368 assert.Nil(t, resp.Beings[2]) 369 } 370 371 func TestFragments(t *testing.T) { 372 _ = `# @genqlient 373 query queryWithFragments($ids: [ID!]!) { 374 beings(ids: $ids) { 375 __typename id 376 ... on Being { id name } 377 ... on Animal { 378 id 379 hair { hasHair } 380 species 381 owner { 382 id 383 ... on Being { name } 384 ... on User { luckyNumber } 385 } 386 } 387 ... on Lucky { luckyNumber } 388 ... on User { hair { color } } 389 } 390 }` 391 392 ctx := context.Background() 393 server := server.RunServer() 394 defer server.Close() 395 client := newRoundtripClient(t, server.URL) 396 397 resp, err := queryWithFragments(ctx, client, []string{"1", "3", "12847394823"}) 398 require.NoError(t, err) 399 400 require.Len(t, resp.Beings, 3) 401 402 // We should get the following three beings: 403 // User{Id: 1, Name: "Yours Truly"}, 404 // Animal{Id: 3, Name: "Fido"}, 405 // null 406 407 // Check fields both via interface and via type-assertion when possible 408 // User has, in total, the fields: __typename id name luckyNumber. 409 assert.Equal(t, "User", resp.Beings[0].GetTypename()) 410 assert.Equal(t, "1", resp.Beings[0].GetId()) 411 assert.Equal(t, "Yours Truly", resp.Beings[0].GetName()) 412 // (hair and luckyNumber we need to cast for) 413 414 user, ok := resp.Beings[0].(*queryWithFragmentsBeingsUser) 415 require.Truef(t, ok, "got %T, not User", resp.Beings[0]) 416 assert.Equal(t, "1", user.Id) 417 assert.Equal(t, "Yours Truly", user.Name) 418 assert.Equal(t, "Black", user.Hair.Color) 419 assert.Equal(t, 17, user.LuckyNumber) 420 421 // Animal has, in total, the fields: 422 // __typename 423 // id 424 // species 425 // owner { 426 // id 427 // name 428 // ... on User { luckyNumber } 429 // } 430 assert.Equal(t, "Animal", resp.Beings[1].GetTypename()) 431 assert.Equal(t, "3", resp.Beings[1].GetId()) 432 // (hair, species, and owner.* we have to cast for) 433 434 animal, ok := resp.Beings[1].(*queryWithFragmentsBeingsAnimal) 435 require.Truef(t, ok, "got %T, not Animal", resp.Beings[1]) 436 assert.Equal(t, "3", animal.Id) 437 assert.Equal(t, SpeciesDog, animal.Species) 438 assert.True(t, animal.Hair.HasHair) 439 440 assert.Equal(t, "1", animal.Owner.GetId()) 441 assert.Equal(t, "Yours Truly", animal.Owner.GetName()) 442 // (luckyNumber we have to cast for, again) 443 444 owner, ok := animal.Owner.(*queryWithFragmentsBeingsAnimalOwnerUser) 445 require.Truef(t, ok, "got %T, not User", animal.Owner) 446 assert.Equal(t, "1", owner.Id) 447 assert.Equal(t, "Yours Truly", owner.Name) 448 assert.Equal(t, 17, owner.LuckyNumber) 449 450 assert.Nil(t, resp.Beings[2]) 451 } 452 453 func TestNamedFragments(t *testing.T) { 454 _ = `# @genqlient 455 fragment AnimalFields on Animal { 456 id 457 hair { hasHair } 458 owner { id ...UserFields ...LuckyFields } 459 } 460 461 fragment MoreUserFields on User { 462 id 463 hair { color } 464 } 465 466 fragment LuckyFields on Lucky { 467 ...MoreUserFields 468 luckyNumber 469 } 470 471 fragment UserFields on User { 472 id 473 ...LuckyFields 474 ...MoreUserFields 475 } 476 477 query queryWithNamedFragments($ids: [ID!]!) { 478 beings(ids: $ids) { 479 __typename id 480 ...AnimalFields 481 ...UserFields 482 } 483 }` 484 485 ctx := context.Background() 486 server := server.RunServer() 487 defer server.Close() 488 client := newRoundtripClient(t, server.URL) 489 490 resp, err := queryWithNamedFragments(ctx, client, []string{"1", "3", "12847394823"}) 491 require.NoError(t, err) 492 493 require.Len(t, resp.Beings, 3) 494 495 // We should get the following three beings: 496 // User{Id: 1, Name: "Yours Truly"}, 497 // Animal{Id: 3, Name: "Fido"}, 498 // null 499 500 // Check fields both via interface and via type-assertion when possible 501 // User has, in total, the fields: __typename id luckyNumber. 502 assert.Equal(t, "User", resp.Beings[0].GetTypename()) 503 assert.Equal(t, "1", resp.Beings[0].GetId()) 504 // (luckyNumber, hair we need to cast for) 505 506 user, ok := resp.Beings[0].(*queryWithNamedFragmentsBeingsUser) 507 require.Truef(t, ok, "got %T, not User", resp.Beings[0]) 508 assert.Equal(t, "1", user.Id) 509 assert.Equal(t, "1", user.UserFields.Id) 510 assert.Equal(t, "1", user.UserFields.MoreUserFields.Id) 511 assert.Equal(t, "1", user.UserFields.LuckyFieldsUser.MoreUserFields.Id) 512 // on UserFields, but we should be able to access directly via embedding: 513 assert.Equal(t, 17, user.LuckyNumber) 514 assert.Equal(t, "Black", user.Hair.Color) 515 assert.Equal(t, "Black", user.UserFields.MoreUserFields.Hair.Color) 516 assert.Equal(t, "Black", user.UserFields.LuckyFieldsUser.MoreUserFields.Hair.Color) 517 518 // Animal has, in total, the fields: 519 // __typename 520 // id 521 // hair { hasHair } 522 // owner { id luckyNumber } 523 assert.Equal(t, "Animal", resp.Beings[1].GetTypename()) 524 assert.Equal(t, "3", resp.Beings[1].GetId()) 525 // (hair.* and owner.* we have to cast for) 526 527 animal, ok := resp.Beings[1].(*queryWithNamedFragmentsBeingsAnimal) 528 require.Truef(t, ok, "got %T, not Animal", resp.Beings[1]) 529 // Check that we filled in *both* ID fields: 530 assert.Equal(t, "3", animal.Id) 531 assert.Equal(t, "3", animal.AnimalFields.Id) 532 // on AnimalFields: 533 assert.True(t, animal.Hair.HasHair) 534 assert.Equal(t, "1", animal.Owner.GetId()) 535 // (luckyNumber we have to cast for, again) 536 537 owner, ok := animal.Owner.(*AnimalFieldsOwnerUser) 538 require.Truef(t, ok, "got %T, not User", animal.Owner) 539 // Check that we filled in *both* ID fields: 540 assert.Equal(t, "1", owner.Id) 541 assert.Equal(t, "1", owner.UserFields.Id) 542 assert.Equal(t, "1", owner.UserFields.MoreUserFields.Id) 543 assert.Equal(t, "1", owner.UserFields.LuckyFieldsUser.MoreUserFields.Id) 544 // on UserFields: 545 assert.Equal(t, 17, owner.LuckyNumber) 546 assert.Equal(t, "Black", owner.UserFields.MoreUserFields.Hair.Color) 547 assert.Equal(t, "Black", owner.UserFields.LuckyFieldsUser.MoreUserFields.Hair.Color) 548 549 // Lucky-based fields we can also get by casting to the fragment-interface. 550 luckyOwner, ok := animal.Owner.(LuckyFields) 551 require.Truef(t, ok, "got %T, not Lucky", animal.Owner) 552 assert.Equal(t, 17, luckyOwner.GetLuckyNumber()) 553 554 assert.Nil(t, resp.Beings[2]) 555 } 556 557 func TestFlatten(t *testing.T) { 558 _ = `# @genqlient 559 # @genqlient(flatten: true) 560 fragment BeingFields on Being { 561 ...InnerBeingFields 562 } 563 564 fragment InnerBeingFields on Being { 565 id 566 name 567 ... on User { 568 # @genqlient(flatten: true) 569 friends { 570 ...FriendsFields 571 } 572 } 573 } 574 575 fragment FriendsFields on User { 576 id 577 name 578 } 579 580 # @genqlient(flatten: true) 581 fragment FlattenedUserFields on User { 582 ...FlattenedLuckyFields 583 } 584 585 # @genqlient(flatten: true) 586 fragment FlattenedLuckyFields on Lucky { 587 ...InnerLuckyFields 588 } 589 590 fragment InnerLuckyFields on Lucky { 591 luckyNumber 592 } 593 594 fragment QueryFragment on Query { 595 beings(ids: $ids) { 596 __typename id 597 ...FlattenedUserFields 598 ... on Animal { 599 # @genqlient(flatten: true) 600 owner { 601 ...BeingFields 602 } 603 } 604 } 605 } 606 607 # @genqlient(flatten: true) 608 query queryWithFlatten( 609 $ids: [ID!]!, 610 ) { 611 ...QueryFragment 612 }` 613 614 ctx := context.Background() 615 server := server.RunServer() 616 defer server.Close() 617 client := newRoundtripClient(t, server.URL) 618 619 resp, err := queryWithFlatten(ctx, client, []string{"1", "3", "12847394823"}) 620 require.NoError(t, err) 621 622 require.Len(t, resp.Beings, 3) 623 624 // We should get the following three beings: 625 // User{Id: 1, Name: "Yours Truly"}, 626 // Animal{Id: 3, Name: "Fido"}, 627 // null 628 629 // Check fields both via interface and via type-assertion when possible 630 // User has, in total, the fields: __typename id luckyNumber. 631 assert.Equal(t, "User", resp.Beings[0].GetTypename()) 632 assert.Equal(t, "1", resp.Beings[0].GetId()) 633 // (luckyNumber we need to cast for) 634 635 user, ok := resp.Beings[0].(*QueryFragmentBeingsUser) 636 require.Truef(t, ok, "got %T, not User", resp.Beings[0]) 637 assert.Equal(t, "1", user.Id) 638 assert.Equal(t, 17, user.InnerLuckyFieldsUser.LuckyNumber) 639 640 // Animal has, in total, the fields: 641 // __typename 642 // id 643 // owner { id name ... on User { friends { id name } } } 644 assert.Equal(t, "Animal", resp.Beings[1].GetTypename()) 645 assert.Equal(t, "3", resp.Beings[1].GetId()) 646 // (owner.* we have to cast for) 647 648 animal, ok := resp.Beings[1].(*QueryFragmentBeingsAnimal) 649 require.Truef(t, ok, "got %T, not Animal", resp.Beings[1]) 650 assert.Equal(t, "3", animal.Id) 651 // on AnimalFields: 652 assert.Equal(t, "1", animal.Owner.GetId()) 653 assert.Equal(t, "Yours Truly", animal.Owner.GetName()) 654 // (friends.* we have to cast for, again) 655 656 owner, ok := animal.Owner.(*InnerBeingFieldsUser) 657 require.Truef(t, ok, "got %T, not User", animal.Owner) 658 assert.Equal(t, "1", owner.Id) 659 assert.Equal(t, "Yours Truly", owner.Name) 660 assert.Len(t, owner.Friends, 1) 661 assert.Equal(t, "2", owner.Friends[0].Id) 662 assert.Equal(t, "Raven", owner.Friends[0].Name) 663 664 assert.Nil(t, resp.Beings[2]) 665 } 666 667 func TestGeneratedCode(t *testing.T) { 668 // TODO(benkraft): Check that gqlgen is up to date too. In practice that's 669 // less likely to be a problem, since it should only change if you update 670 // the schema, likely too add something new, in which case you'll notice. 671 RunGenerateTest(t, "internal/integration/genqlient.yaml") 672 } 673 674 //go:generate go run github.com/Khan/genqlient genqlient.yaml