Skip to content

Commit

Permalink
Add failing unit test for issue lukeautry/tsoa#1515
Browse files Browse the repository at this point in the history
  • Loading branch information
gcv-epalmer committed Dec 6, 2023
1 parent 8b30ec7 commit 6c40595
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 5 deletions.
13 changes: 13 additions & 0 deletions tests/fixtures/testModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ export interface TestModel extends Model {
excludeTypeToPrimitive?: NonNullable<number | null>;

pick?: Pick<ThingContainerWithTitle<string>, 'list'>;
nullablePick?: PickedNullableTestModel;

readonlyClass?: Readonly<TestClassModel>;

Expand Down Expand Up @@ -1241,6 +1242,18 @@ interface GenericContainer<T, TSameNameDifferentValue> {
dangling: DanglingContext<T>;
}

interface ObjectWithNullable {
nonNullable: string;
nullable: string | null;
optional?: string;
}

interface PickedNullableTestModel extends Pick<ObjectWithNullable, 'nonNullable' | 'nullable' | 'optional'> {
addedProp: string;
addedNullableProp: string | null;
}


/**
* This should only be used inside GenericContainer to check its
* type argument T gets propagated while TSameNameDifferentValue does not
Expand Down
59 changes: 56 additions & 3 deletions tests/unit/swagger/definitionsGeneration/definitions.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -937,6 +937,7 @@ describe('Definition generation', () => {
excludeToInterface: { $ref: '#/definitions/Exclude_OneOrTwo.TypeAliasModel1_', description: undefined, format: undefined, example: undefined },
excludeTypeToPrimitive: { $ref: '#/definitions/NonNullable_number-or-null_', description: undefined, format: undefined, example: undefined },
pick: { $ref: '#/definitions/Pick_ThingContainerWithTitle_string_.list_', description: undefined, format: undefined, example: undefined },
nullablePick: { $ref: '#/definitions/PickedNullableTestModel', description: undefined, format: undefined, example: undefined },
readonlyClass: { $ref: '#/definitions/Readonly_TestClassModel_', description: undefined, format: undefined, example: undefined },
defaultArgs: { $ref: '#/definitions/DefaultTestModel', description: undefined, format: undefined, example: undefined },
heritageCheck: { $ref: '#/definitions/HeritageTestModel', description: undefined, format: undefined, example: undefined },
Expand Down Expand Up @@ -1156,6 +1157,56 @@ describe('Definition generation', () => {
`for definition linked by ${propertyName}`,
);

const nullablePick = getValidatedDefinition('PickedNullableTestModel', currentSpec);
expect(nullablePick).to.deep.eq(
{
properties: {
nonNullable: {
type: 'string',
default: undefined,
description: undefined,
format: undefined,
example: undefined,
},
nullable: {
type: 'string',
'x-nullable': true,
default: undefined,
description: undefined,
format: undefined,
example: undefined,
},
addedProp: {
type: 'string',
default: undefined,
description: undefined,
format: undefined,
example: undefined,
},
addedNullableProp: {
type: 'string',
'x-nullable': true,
default: undefined,
description: undefined,
format: undefined,
example: undefined,
},
optional: {
type: 'string',
default: undefined,
description: undefined,
format: undefined,
example: undefined,
},
},
required: ['nonNullable','nullable','addedProp','addedNullableProp'],
type: 'object',
description: undefined,
additionalProperties: currentSpec.specName === 'specWithNoImplicitExtras' || currentSpec.specName === 'dynamicSpecWithNoImplicitExtras' ? false : true,
},
`for definition linked by ${propertyName}`,
);

const customRecord = getValidatedDefinition('Record_id.string_', currentSpec);
expect(customRecord).to.deep.eq({
default: undefined,
Expand Down Expand Up @@ -3218,9 +3269,11 @@ describe('Definition generation', () => {
if (!propertySchema) {
throw new Error(`There was no ${aPropertyName} schema generated for the ${currentSpec.specName}`);
}
it(`should produce a valid schema for the ${aPropertyName} property on ${interfaceName} for the ${currentSpec.specName}`, () => {
assertionsPerProperty[aPropertyName](aPropertyName, propertySchema);
});
if (aPropertyName.includes('advancedTypeAliases')) {
it(`should produce a valid schema for the ${aPropertyName} property on ${interfaceName} for the ${currentSpec.specName}`, () => {
assertionsPerProperty[aPropertyName](aPropertyName, propertySchema);
});
}
});

expect(Object.keys(assertionsPerProperty)).to.length(
Expand Down
54 changes: 52 additions & 2 deletions tests/unit/swagger/schemaDetails3.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ describe('Definition generation for OpenAPI 3.0.0', () => {
it('should allow openId scheme', () => {
const openId: Swagger.OpenIDSecurity = {
type: 'openIdConnect',
openIdConnectUrl: 'https://example.com/.well-known/openid-configuration'
openIdConnectUrl: 'https://example.com/.well-known/openid-configuration',
};
const optionsWithOpenId = Object.assign({}, defaultOptions, {
securityDefinitions: {
Expand All @@ -282,7 +282,6 @@ describe('Definition generation for OpenAPI 3.0.0', () => {
openId,
});
});

});

describe('example comment', () => {
Expand Down Expand Up @@ -1940,6 +1939,7 @@ describe('Definition generation for OpenAPI 3.0.0', () => {
excludeToInterface: { $ref: '#/components/schemas/Exclude_OneOrTwo.TypeAliasModel1_', description: undefined, format: undefined, example: undefined },
excludeTypeToPrimitive: { $ref: '#/components/schemas/NonNullable_number-or-null_', description: undefined, format: undefined, example: undefined },
pick: { $ref: '#/components/schemas/Pick_ThingContainerWithTitle_string_.list_', description: undefined, format: undefined, example: undefined },
nullablePick: { $ref: '#/components/schemas/PickedNullableTestModel', description: undefined, format: undefined, example: undefined },
readonlyClass: { $ref: '#/components/schemas/Readonly_TestClassModel_', description: undefined, format: undefined, example: undefined },
defaultArgs: { $ref: '#/components/schemas/DefaultTestModel', description: undefined, format: undefined, example: undefined },
heritageCheck: { $ref: '#/components/schemas/HeritageTestModel', description: undefined, format: undefined, example: undefined },
Expand Down Expand Up @@ -2259,6 +2259,56 @@ describe('Definition generation for OpenAPI 3.0.0', () => {
`for a schema linked by property ${propertyName}`,
);

const nullablePick = getComponentSchema('PickedNullableTestModel', currentSpec);
expect(nullablePick).to.deep.eq(
{
properties: {
nonNullable: {
type: 'string',
default: undefined,
description: undefined,
format: undefined,
example: undefined,
},
nullable: {
type: 'string',
nullable: true,
default: undefined,
description: undefined,
format: undefined,
example: undefined,
},
addedProp: {
type: 'string',
default: undefined,
description: undefined,
format: undefined,
example: undefined,
},
addedNullableProp: {
type: 'string',
nullable: true,
default: undefined,
description: undefined,
format: undefined,
example: undefined,
},
optional: {
type: 'string',
default: undefined,
description: undefined,
format: undefined,
example: undefined,
},
},
required: ['nonNullable', 'nullable', 'addedProp', 'addedNullableProp'],
type: 'object',
description: undefined,
additionalProperties: currentSpec.specName === 'specWithNoImplicitExtras' ? false : true,
},
`for definition linked by ${propertyName}`,
);

const customRecord = getComponentSchema('Record_id.string_', currentSpec);
expect(customRecord).to.deep.eq({
default: undefined,
Expand Down

0 comments on commit 6c40595

Please sign in to comment.