Skip to content

Commit

Permalink
feat: Add support for minLength and maxLength constraint humanization (
Browse files Browse the repository at this point in the history
…#700)

According to #42 , `minItems` and `maxItems` are not yet rendered in the documentation.
This pull request shows the humazined form of `minItems` and `maxItems` next to the type description.
The [suggestion of fgabolde](#42 (comment)) is followed and "characters" is simply replaced with "items".

![image](https://user-images.githubusercontent.com/1814807/47999845-0a13f900-e104-11e8-9ddc-adab701ec0bb.png)

Some examples are added to the demo.
  • Loading branch information
lscholten authored and RomanHotsiy committed Nov 5, 2018
1 parent b5f3224 commit f40568b
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 12 deletions.
4 changes: 4 additions & 0 deletions demo/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,8 @@ paths:
style: form
schema:
type: array
minItems: 1
maxItems: 3
items:
type: string
enum:
Expand Down Expand Up @@ -784,6 +786,7 @@ components:
photoUrls:
description: The list of URL to a cute photos featuring pet
type: array
maxItems: 20
xml:
name: photoUrl
wrapped: true
Expand All @@ -796,6 +799,7 @@ components:
tags:
description: Tags attached to the pet
type: array
minItems: 1
xml:
name: tag
wrapped: true
Expand Down
32 changes: 32 additions & 0 deletions src/utils/__tests__/openapi.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
detectType,
getOperationSummary,
getStatusCodeType,
humanizeConstraints,
isOperationName,
isPrimitiveType,
mergeParams,
Expand Down Expand Up @@ -321,4 +322,35 @@ describe('Utils', () => {
expect(servers[2].url).toEqual('http://127.0.0.3');
});
});

describe('openapi humanizeConstraints', () => {
const itemConstraintSchema = (
min: number | undefined = undefined,
max: number | undefined = undefined,
) => ({ type: 'array', minItems: min, maxItems: max });

it('should not have a humanized constraint without schema constraints', () => {
expect(humanizeConstraints(itemConstraintSchema())).toHaveLength(0);
});

it('should have a humanized constraint when minItems is set', () => {
expect(humanizeConstraints(itemConstraintSchema(2))).toContain('>= 2 items');
});

it('should have a humanized constraint when maxItems is set', () => {
expect(humanizeConstraints(itemConstraintSchema(undefined, 8))).toContain('<= 8 items');
});

it('should have a humanized constraint when minItems and maxItems are both set', () => {
expect(humanizeConstraints(itemConstraintSchema(2, 8))).toContain('[ 2 .. 8 ] items');
});

it('should have a humanized constraint when minItems and maxItems are the same', () => {
expect(humanizeConstraints(itemConstraintSchema(7, 7))).toContain('7 items');
});

it('should have a humazined constraint when justMinItems is set, and it is equal to 1', () => {
expect(humanizeConstraints(itemConstraintSchema(1))).toContain('non-empty');
});
});
});
39 changes: 27 additions & 12 deletions src/utils/openapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,29 +141,44 @@ export function isNamedDefinition(pointer?: string): boolean {
return /^#\/components\/schemas\/[^\/]+$/.test(pointer || '');
}

export function humanizeConstraints(schema: OpenAPISchema): string[] {
const res: string[] = [];

function humanizeRangeConstraint(
description: string,
min: number | undefined,
max: number | undefined,
): string | undefined {
let stringRange;
if (schema.minLength !== undefined && schema.maxLength !== undefined) {
if (schema.minLength === schema.maxLength) {
stringRange = `${schema.minLength} characters`;
if (min !== undefined && max !== undefined) {
if (min === max) {
stringRange = `${min} ${description}`;
} else {
stringRange = `[ ${schema.minLength} .. ${schema.maxLength} ] characters`;
stringRange = `[ ${min} .. ${max} ] ${description}`;
}
} else if (schema.maxLength !== undefined) {
stringRange = `<= ${schema.maxLength} characters`;
} else if (schema.minLength !== undefined) {
if (schema.minLength === 1) {
} else if (max !== undefined) {
stringRange = `<= ${max} ${description}`;
} else if (min !== undefined) {
if (min === 1) {
stringRange = 'non-empty';
} else {
stringRange = `>= ${schema.minLength} characters`;
stringRange = `>= ${min} ${description}`;
}
}

return stringRange;
}

export function humanizeConstraints(schema: OpenAPISchema): string[] {
const res: string[] = [];

const stringRange = humanizeRangeConstraint('characters', schema.minLength, schema.maxLength);
if (stringRange !== undefined) {
res.push(stringRange);
}

const arrayRange = humanizeRangeConstraint('items', schema.minItems, schema.maxItems);
if (arrayRange !== undefined) {
res.push(arrayRange);
}

let numberRange;
if (schema.minimum !== undefined && schema.maximum !== undefined) {
numberRange = schema.exclusiveMinimum ? '( ' : '[ ';
Expand Down

0 comments on commit f40568b

Please sign in to comment.