Skip to content

Commit

Permalink
refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
cauemarcondes committed Apr 30, 2020
1 parent 8ed25ce commit 7718f2c
Show file tree
Hide file tree
Showing 8 changed files with 141 additions and 112 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@

import { getBytesRt } from './bytes_rt';
import { isRight } from 'fp-ts/lib/Either';
import { PathReporter } from 'io-ts/lib/PathReporter';

describe('bytesRt', () => {
describe('must accept any amount and unit', () => {
const bytesRt = getBytesRt({
units: ['b', 'mb', 'kb']
});
const bytesRt = getBytesRt({});
describe('it should not accept', () => {
['mb', 1, '1', '5gb', '6tb'].map(input => {
it(`${JSON.stringify(input)}`, () => {
Expand All @@ -30,8 +29,7 @@ describe('bytesRt', () => {
});
describe('must be at least 0b', () => {
const bytesRt = getBytesRt({
min: '0b',
units: ['b', 'mb', 'kb']
min: '0b'
});

describe('it should not accept', () => {
Expand All @@ -42,6 +40,17 @@ describe('bytesRt', () => {
});
});

describe('it should return correct error message', () => {
['-1kb', '5gb', '6tb'].map(input => {
it(`${JSON.stringify(input)}`, () => {
const result = bytesRt.decode(input);
const message = PathReporter.report(result)[0];
expect(message).toEqual('Must be greater than 0b');
expect(isRight(result)).toBeFalsy();
});
});
});

describe('it should accept', () => {
['1b', '2kb', '3mb'].map(input => {
it(`${JSON.stringify(input)}`, () => {
Expand All @@ -50,11 +59,10 @@ describe('bytesRt', () => {
});
});
});
describe('must be between 500b and 1mb', () => {
describe('must be between 500b and 1kb', () => {
const bytesRt = getBytesRt({
min: '500b',
max: '1kb',
units: ['b', 'mb', 'kb']
max: '1kb'
});
describe('it should not accept', () => {
['mb', '-1b', '1b', '499b', '1025b', '2kb', '1mb'].map(input => {
Expand All @@ -63,6 +71,16 @@ describe('bytesRt', () => {
});
});
});
describe('it should return correct error message', () => {
['-1b', '1b', '499b', '1025b', '2kb', '1mb'].map(input => {
it(`${JSON.stringify(input)}`, () => {
const result = bytesRt.decode(input);
const message = PathReporter.report(result)[0];
expect(message).toEqual('Must be between 500b and 1kb');
expect(isRight(result)).toBeFalsy();
});
});
});
describe('it should accept', () => {
['500b', '1024b', '1kb'].map(input => {
it(`${JSON.stringify(input)}`, () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,70 +6,47 @@

import * as t from 'io-ts';
import { either } from 'fp-ts/lib/Either';
import { i18n } from '@kbn/i18n';
import { amountAndUnitToObject } from '../amount_and_unit';
import { getRangeType } from './get_range_type';
import { getRangeTypeMessage } from './get_range_type';

function toBytes(amount: number, unit: string) {
switch (unit) {
case 'b':
return amount;
case 'kb':
return amount * 2 ** 10;
case 'mb':
return amount * 2 ** 20;
case 'b':
default:
return amount;
}
}

export function getBytesRt({
min,
max,
units
}: {
min?: string;
max?: string;
units: string[];
}) {
const { amount: minAmount, unit: minUnit } = min
? amountAndUnitToObject(min)
: { amount: -Infinity, unit: 'b' };

const { amount: maxAmount, unit: maxUnit } = max
? amountAndUnitToObject(max)
: { amount: Infinity, unit: 'mb' };

const message = i18n.translate('xpack.apm.agentConfig.bytes.errorText', {
defaultMessage: `{rangeType, select,
between {Must be between {min} and {max} with unit: {units}}
gt {Must be greater than {min} with unit: {units}}
lt {Must be less than {max} with unit: {units}}
other {Must be an integer with unit: {units}}
}`,
values: {
min,
max,
units: units.join(', '),
rangeType: getRangeType(minAmount, maxAmount)
function amountAndUnitToBytes(value?: string): number | undefined {
if (value) {
const { amount, unit } = amountAndUnitToObject(value);
if (isFinite(amount) && unit) {
return toBytes(amount, unit);
}
});
}
}

export function getBytesRt({ min, max }: { min?: string; max?: string }) {
const minAsBytes = amountAndUnitToBytes(min) ?? -Infinity;
const maxAsBytes = amountAndUnitToBytes(max) ?? Infinity;
const message = getRangeTypeMessage(min, max);

return new t.Type<string, string, unknown>(
'bytesRt',
t.string.is,
(input, context) => {
return either.chain(t.string.validate(input, context), inputAsString => {
const { amount, unit } = amountAndUnitToObject(inputAsString);
const isValidUnit = units.includes(unit);

const inputAsBytes = toBytes(amount, unit);
const minAsBytes = toBytes(minAmount, minUnit);
const maxAsBytes = toBytes(maxAmount, maxUnit);
const inputAsBytes = amountAndUnitToBytes(inputAsString);

const isValidAmount =
inputAsBytes >= minAsBytes && inputAsBytes <= maxAsBytes;
typeof inputAsBytes !== 'undefined' &&
inputAsBytes >= minAsBytes &&
inputAsBytes <= maxAsBytes;

return isValidUnit && isValidAmount
return isValidAmount
? t.success(inputAsString)
: t.failure(input, context, message);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@

import { getDurationRt } from './duration_rt';
import { isRight } from 'fp-ts/lib/Either';
import { PathReporter } from 'io-ts/lib/PathReporter';

describe('getDurationRt', () => {
const units = ['ms', 's', 'm'];
describe('must be at least 1m', () => {
const customDurationRt = getDurationRt({ min: '1m', units });
const customDurationRt = getDurationRt({ min: '1m' });
describe('it should not accept', () => {
[
undefined,
Expand All @@ -30,6 +30,16 @@ describe('getDurationRt', () => {
});
});
});
describe('it should return correct error message', () => {
['0m', '-1m', '1ms', '1s'].map(input => {
it(`${JSON.stringify(input)}`, () => {
const result = customDurationRt.decode(input);
const message = PathReporter.report(result)[0];
expect(message).toEqual('Must be greater than 1m');
expect(isRight(result)).toBeFalsy();
});
});
});
describe('it should accept', () => {
['1m', '2m', '1000m'].map(input => {
it(`${JSON.stringify(input)}`, () => {
Expand All @@ -40,7 +50,7 @@ describe('getDurationRt', () => {
});

describe('must be between 1ms and 1s', () => {
const customDurationRt = getDurationRt({ min: '1ms', max: '1s', units });
const customDurationRt = getDurationRt({ min: '1ms', max: '1s' });

describe('it should not accept', () => {
[
Expand All @@ -65,6 +75,16 @@ describe('getDurationRt', () => {
});
});
});
describe('it should return correct error message', () => {
['-1s', '0s', '2s', '1001ms', '0ms', '-1ms', '0m', '1m'].map(input => {
it(`${JSON.stringify(input)}`, () => {
const result = customDurationRt.decode(input);
const message = PathReporter.report(result)[0];
expect(message).toEqual('Must be between 1ms and 1s');
expect(isRight(result)).toBeFalsy();
});
});
});
describe('it should accept', () => {
['1s', '1ms', '50ms', '1000ms'].map(input => {
it(`${JSON.stringify(input)}`, () => {
Expand All @@ -74,7 +94,7 @@ describe('getDurationRt', () => {
});
});
describe('must be max 1m', () => {
const customDurationRt = getDurationRt({ max: '1m', units });
const customDurationRt = getDurationRt({ max: '1m' });

describe('it should not accept', () => {
[undefined, null, '', 0, 'foo', true, false, '2m', '61s', '60001ms'].map(
Expand All @@ -85,6 +105,16 @@ describe('getDurationRt', () => {
}
);
});
describe('it should return correct error message', () => {
['2m', '61s', '60001ms'].map(input => {
it(`${JSON.stringify(input)}`, () => {
const result = customDurationRt.decode(input);
const message = PathReporter.report(result)[0];
expect(message).toEqual('Must be less than 1m');
expect(isRight(result)).toBeFalsy();
});
});
});
describe('it should accept', () => {
['1m', '0m', '-1m', '60s', '6000ms', '1ms', '1s'].map(input => {
it(`${JSON.stringify(input)}`, () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,63 +7,40 @@
import * as t from 'io-ts';
import { either } from 'fp-ts/lib/Either';
import moment, { unitOfTime } from 'moment';
import { i18n } from '@kbn/i18n';
import { amountAndUnitToObject, AmountAndUnit } from '../amount_and_unit';
import { getRangeType } from './get_range_type';
import { getRangeTypeMessage } from './get_range_type';

function getDuration({ amount, unit }: AmountAndUnit) {
function toMilliseconds({ amount, unit }: AmountAndUnit) {
return moment.duration(amount, unit as unitOfTime.Base);
}

export function getDurationRt({
min,
max,
units
}: {
min?: string;
max?: string;
units: string[];
}) {
const minAmountAndUnit = min && amountAndUnitToObject(min);
const maxAmountAndUnit = max && amountAndUnitToObject(max);

const message = i18n.translate('xpack.apm.agentConfig.duration.errorText', {
defaultMessage: `{rangeType, select,
between {Must be between {min} and {max}}
gt {Must be greater than {min}}
lt {Must be less than {max}}
other {Must be an integer}
}`,
values: {
min,
max,
rangeType: getRangeType(
minAmountAndUnit ? minAmountAndUnit.amount : undefined,
maxAmountAndUnit ? maxAmountAndUnit.amount : undefined
)
function amountAndUnitToMilliseconds(value?: string) {
if (value) {
const { amount, unit } = amountAndUnitToObject(value);
if (isFinite(amount) && unit) {
return toMilliseconds({ amount, unit });
}
});
}
}

export function getDurationRt({ min, max }: { min?: string; max?: string }) {
const minAsMilliseconds = amountAndUnitToMilliseconds(min) ?? -Infinity;
const maxAsMilliseconds = amountAndUnitToMilliseconds(max) ?? Infinity;
const message = getRangeTypeMessage(min, max);

return new t.Type<string, string, unknown>(
'durationRt',
t.string.is,
(input, context) => {
return either.chain(t.string.validate(input, context), inputAsString => {
const { amount, unit } = amountAndUnitToObject(inputAsString);
const inputDuration = getDuration({ amount, unit });

const minDuration = minAmountAndUnit
? getDuration(minAmountAndUnit)
: inputDuration;

const maxDuration = maxAmountAndUnit
? getDuration(maxAmountAndUnit)
: inputDuration;
const inputAsMilliseconds = amountAndUnitToMilliseconds(inputAsString);

const isValidUnit = units.includes(unit);
const isValidAmount =
inputDuration >= minDuration && inputDuration <= maxDuration;
typeof inputAsMilliseconds !== 'undefined' &&
inputAsMilliseconds >= minAsMilliseconds &&
inputAsMilliseconds <= maxAsMilliseconds;

return isValidUnit && isValidAmount
return isValidAmount
? t.success(inputAsString)
: t.failure(input, context, message);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
*/

import { isFinite } from 'lodash';
import { i18n } from '@kbn/i18n';
import { amountAndUnitToObject } from '../amount_and_unit';

export function getRangeType(min?: number, max?: number) {
function getRangeType(min?: number, max?: number) {
if (isFinite(min) && isFinite(max)) {
return 'between';
} else if (isFinite(min)) {
Expand All @@ -15,3 +17,25 @@ export function getRangeType(min?: number, max?: number) {
return 'lt'; // less than
}
}

export function getRangeTypeMessage(
min?: number | string,
max?: number | string
) {
return i18n.translate('xpack.apm.agentConfig.range.errorText', {
defaultMessage: `{rangeType, select,
between {Must be between {min} and {max}}
gt {Must be greater than {min}}
lt {Must be less than {max}}
other {Must be an integer}
}`,
values: {
min,
max,
rangeType: getRangeType(
typeof min === 'string' ? amountAndUnitToObject(min).amount : min,
typeof max === 'string' ? amountAndUnitToObject(max).amount : max
)
}
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import { getIntegerRt } from './integer_rt';
import { isRight } from 'fp-ts/lib/Either';
import { PathReporter } from 'io-ts/lib/PathReporter';

describe('getIntegerRt', () => {
describe('with range', () => {
Expand All @@ -24,6 +25,17 @@ describe('getIntegerRt', () => {
);
});

describe('it should return correct error message', () => {
['-1', '-55', '33000'].map(input => {
it(`${JSON.stringify(input)}`, () => {
const result = integerRt.decode(input);
const message = PathReporter.report(result)[0];
expect(message).toEqual('Must be between 0 and 32000');
expect(isRight(result)).toBeFalsy();
});
});
});

describe('it should accept number between 0 and 32000', () => {
['0', '1000', '32000'].map(input => {
it(`${JSON.stringify(input)}`, () => {
Expand Down
Loading

0 comments on commit 7718f2c

Please sign in to comment.