Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: display multipleOf constrains #1065

Merged
merged 7 commits into from
Dec 8, 2019
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions demo/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,7 @@ components:
type: number
description: Average amount of honey produced per day in ounces
example: 3.14
multipleOf: .01
required:
- honeyPerDay
Id:
Expand Down
21 changes: 18 additions & 3 deletions src/utils/__tests__/openapi.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,8 @@ describe('Utils', () => {
const itemConstraintSchema = (
min: number | undefined = undefined,
max: number | undefined = undefined,
) => ({ type: 'array', minItems: min, maxItems: max });
multipleOf: number | undefined = undefined,
) => ({ type: 'array', minItems: min, maxItems: max, multipleOf });

it('should not have a humanized constraint without schema constraints', () => {
expect(humanizeConstraints(itemConstraintSchema())).toHaveLength(0);
Expand All @@ -355,9 +356,21 @@ describe('Utils', () => {
expect(humanizeConstraints(itemConstraintSchema(7, 7))).toContain('7 items');
});

it('should have a humazined constraint when justMinItems is set, and it is equal to 1', () => {
it('should have a humanized constraint when justMinItems is set, and it is equal to 1', () => {
expect(humanizeConstraints(itemConstraintSchema(1))).toContain('non-empty');
});

it('should have a humanized constraint when multipleOf is set, and it is in format of /^0\\.0*1$/', () => {
expect(humanizeConstraints(itemConstraintSchema(undefined, undefined, 0.01))).toContain(
'decimals <= 2 digits',
);
});

it('should have a humanized constraint when multipleOf is set, and it is in format other than /^0\\.0*1$/', () => {
expect(humanizeConstraints(itemConstraintSchema(undefined, undefined, 0.5))).toContain(
'multiple of 0.5',
);
});
});

describe('OpenAPI pluralizeType', () => {
Expand Down Expand Up @@ -387,7 +400,9 @@ describe('Utils', () => {
expect(pluralizeType('objects (Pet)')).toEqual('objects (Pet)');
expect(pluralizeType('strings <email>')).toEqual('strings <email>');
expect(pluralizeType('objects or strings')).toEqual('objects or strings');
expect(pluralizeType('objects (Pet) or numbers <int64>')).toEqual('objects (Pet) or numbers <int64>');
expect(pluralizeType('objects (Pet) or numbers <int64>')).toEqual(
'objects (Pet) or numbers <int64>',
);
});
});

Expand Down
16 changes: 16 additions & 0 deletions src/utils/openapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,17 @@ export function isNamedDefinition(pointer?: string): boolean {
return /^#\/components\/schemas\/[^\/]+$/.test(pointer || '');
}

function humanizeMultipleOfConstraint(multipleOf: number | undefined): string | undefined {
if (multipleOf === undefined) {
return;
}
const strigifiedMultipleOf = multipleOf.toString(10);
if (!/^0\.0*1$/.test(strigifiedMultipleOf)) {
return `multiple of ${multipleOf}`;
}
return `decimals <= ${strigifiedMultipleOf.split('.')[1].length} digits`;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nanov @adamaltman What do you think if we change it to n decimals max instead of decimals <= n?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, I have nothing against it.

The only thing i might thing of is that we may provide those hardcoded strings as configurations options to allow internationalisation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

having this in mind having strings as decimals <= {{x}} are some how easier to manage, translation wise speaking without introduction of (simple) templating system or a i18n solution.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are both wrong actually. I'm glad that you brought it up.

Decimals is the concept. Decimal, from the dictionary:

a fraction whose denominator is a power of ten and whose numerator is expressed by figures placed to the right of a decimal point.

What we're talking about here specifically is called decimal places.

So it should be like this:

  • decimal places <= n
  • n decimal places max

However, in the second phrase, n decimal places max the places must turn singular if n == 1.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we decide to go with the second option we could go with the good old:

  • n decimal place(s) max

As some languages have also a double form ( ie. singular, double, and plural ) i think it is better to use simpler descriptions in order to make internationalization simpler, with minimal overhead when the time comes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've taken your first suggestion and implemented it, I took the time to see how much effort would it be to implement mini translating system, and it seems as a straight forward task ( can work similar to the theme option ) and for our use case it can be done with zero-dependencies.

The question here is should i implement it here, or do a new PR for it?

}

function humanizeRangeConstraint(
description: string,
min: number | undefined,
Expand Down Expand Up @@ -406,6 +417,11 @@ export function humanizeConstraints(schema: OpenAPISchema): string[] {
res.push(arrayRange);
}

const multipleOfConstraint = humanizeMultipleOfConstraint(schema.multipleOf);
if (multipleOfConstraint !== undefined) {
res.push(multipleOfConstraint);
}

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