|
1 | | -import {describe, expect, it} from "@jest/globals" |
| 1 | +import {beforeEach, describe, expect, it} from "@jest/globals" |
| 2 | +import {FakeSchemaProvider} from "../../test/fake-schema-provider" |
2 | 3 | import {irFixture as ir} from "../../test/ir-model.fixtures.test-utils" |
3 | 4 | import {generationLib} from "../generation-lib" |
4 | 5 | import {SchemaNormalizer} from "./schema-normalizer" |
5 | 6 |
|
6 | 7 | describe("core/input - SchemaNormalizer", () => { |
7 | | - const schemaNormalizer = new SchemaNormalizer({ |
8 | | - extractInlineSchemas: true, |
9 | | - enumExtensibility: "open", |
| 8 | + let schemaProvider: FakeSchemaProvider |
| 9 | + let schemaNormalizer: SchemaNormalizer |
| 10 | + |
| 11 | + beforeEach(() => { |
| 12 | + schemaProvider = new FakeSchemaProvider() |
| 13 | + schemaNormalizer = new SchemaNormalizer( |
| 14 | + { |
| 15 | + extractInlineSchemas: true, |
| 16 | + enumExtensibility: "open", |
| 17 | + }, |
| 18 | + schemaProvider, |
| 19 | + ) |
10 | 20 | }) |
11 | 21 |
|
12 | 22 | it("passes through $ref untouched", () => { |
@@ -512,34 +522,130 @@ describe("core/input - SchemaNormalizer", () => { |
512 | 522 | }), |
513 | 523 | ) |
514 | 524 | }) |
| 525 | + }) |
| 526 | + |
| 527 | + describe("discriminator", () => { |
| 528 | + describe("all alternatives are $ref of type: object", () => { |
| 529 | + it("supports mapping", () => { |
| 530 | + schemaProvider.registerTestRef( |
| 531 | + ir.ref("/components/schemas/Foo"), |
| 532 | + ir.object({properties: {type: ir.string()}}), |
| 533 | + ) |
| 534 | + schemaProvider.registerTestRef( |
| 535 | + ir.ref("/components/schemas/Bar"), |
| 536 | + ir.object({properties: {type: ir.string()}}), |
| 537 | + ) |
| 538 | + |
| 539 | + const actual = schemaNormalizer.normalize({ |
| 540 | + type: "object", |
| 541 | + discriminator: { |
| 542 | + propertyName: "type", |
| 543 | + mapping: { |
| 544 | + foo: "#/components/schemas/Foo", |
| 545 | + bar: "#/components/schemas/Bar", |
| 546 | + }, |
| 547 | + }, |
| 548 | + oneOf: [ |
| 549 | + {$ref: "#/components/schemas/Foo"}, |
| 550 | + {$ref: "#/components/schemas/Bar"}, |
| 551 | + ], |
| 552 | + }) |
| 553 | + |
| 554 | + expect(actual).toStrictEqual( |
| 555 | + ir.union({ |
| 556 | + discriminator: { |
| 557 | + propertyName: "type", |
| 558 | + mapping: { |
| 559 | + foo: ir.ref("/components/schemas/Foo"), |
| 560 | + bar: ir.ref("/components/schemas/Bar"), |
| 561 | + }, |
| 562 | + }, |
| 563 | + schemas: [ |
| 564 | + ir.ref("/components/schemas/Foo"), |
| 565 | + ir.ref("/components/schemas/Bar"), |
| 566 | + ], |
| 567 | + }), |
| 568 | + ) |
| 569 | + }) |
| 570 | + |
| 571 | + it("infers a mapping when none provided", () => { |
| 572 | + schemaProvider.registerTestRef( |
| 573 | + ir.ref("/components/schemas/Foo"), |
| 574 | + ir.object({properties: {type: ir.string()}}), |
| 575 | + ) |
| 576 | + schemaProvider.registerTestRef( |
| 577 | + ir.ref("/components/schemas/Bar"), |
| 578 | + ir.object({properties: {type: ir.string()}}), |
| 579 | + ) |
| 580 | + |
| 581 | + const actual = schemaNormalizer.normalize({ |
| 582 | + type: "object", |
| 583 | + discriminator: { |
| 584 | + propertyName: "type", |
| 585 | + }, |
| 586 | + oneOf: [ |
| 587 | + {$ref: "#/components/schemas/Foo"}, |
| 588 | + {$ref: "#/components/schemas/Bar"}, |
| 589 | + ], |
| 590 | + }) |
515 | 591 |
|
516 | | - it("handles a discriminator", () => { |
| 592 | + expect(actual).toStrictEqual( |
| 593 | + ir.union({ |
| 594 | + discriminator: { |
| 595 | + propertyName: "type", |
| 596 | + mapping: { |
| 597 | + Foo: ir.ref("/components/schemas/Foo"), |
| 598 | + Bar: ir.ref("/components/schemas/Bar"), |
| 599 | + }, |
| 600 | + }, |
| 601 | + schemas: [ |
| 602 | + ir.ref("/components/schemas/Foo"), |
| 603 | + ir.ref("/components/schemas/Bar"), |
| 604 | + ], |
| 605 | + }), |
| 606 | + ) |
| 607 | + }) |
| 608 | + }) |
| 609 | + |
| 610 | + it("ignores the discriminator property where some alternatives are not type: object", () => {}) |
| 611 | + |
| 612 | + it("ignores the discriminator property where no composition is defined", () => { |
517 | 613 | const actual = schemaNormalizer.normalize({ |
518 | 614 | type: "object", |
| 615 | + properties: { |
| 616 | + name: {type: "string"}, |
| 617 | + type: {type: "string"}, |
| 618 | + }, |
519 | 619 | discriminator: { |
520 | 620 | propertyName: "type", |
521 | 621 | mapping: { |
522 | 622 | foo: "#/components/schemas/Foo", |
523 | 623 | bar: "#/components/schemas/Bar", |
524 | 624 | }, |
525 | 625 | }, |
| 626 | + }) |
| 627 | + |
| 628 | + expect(actual).toStrictEqual( |
| 629 | + ir.object({properties: {name: ir.string(), type: ir.string()}}), |
| 630 | + ) |
| 631 | + }) |
| 632 | + |
| 633 | + it("ignores the discriminator property where some alternatives are inline schemas", () => { |
| 634 | + const actual = schemaNormalizer.normalize({ |
| 635 | + type: "object", |
| 636 | + discriminator: { |
| 637 | + propertyName: "type", |
| 638 | + }, |
526 | 639 | oneOf: [ |
527 | | - {$ref: "#/components/schemas/Foo"}, |
| 640 | + {type: "object", properties: {type: {type: "string"}}}, |
528 | 641 | {$ref: "#/components/schemas/Bar"}, |
529 | 642 | ], |
530 | 643 | }) |
531 | 644 |
|
532 | 645 | expect(actual).toStrictEqual( |
533 | 646 | ir.union({ |
534 | | - discriminator: { |
535 | | - propertyName: "type", |
536 | | - mapping: { |
537 | | - foo: ir.ref("/components/schemas/Foo"), |
538 | | - bar: ir.ref("/components/schemas/Bar"), |
539 | | - }, |
540 | | - }, |
541 | 647 | schemas: [ |
542 | | - ir.ref("/components/schemas/Foo"), |
| 648 | + ir.object({properties: {type: ir.string()}}), |
543 | 649 | ir.ref("/components/schemas/Bar"), |
544 | 650 | ], |
545 | 651 | }), |
|
0 commit comments