From 473df15f0539e5ec0db2744b251df90058fbf112 Mon Sep 17 00:00:00 2001 From: Piotr Szlachciak Date: Thu, 8 Aug 2019 10:33:24 +0200 Subject: [PATCH] Add asInteger (#22) --- sanitizers/README.md | 12 +++++++++ sanitizers/package.json | 2 +- sanitizers/src/asInteger.ts | 10 ++++++++ sanitizers/src/index.ts | 1 + sanitizers/test/asInteger.test.ts | 42 +++++++++++++++++++++++++++++++ 5 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 sanitizers/src/asInteger.ts create mode 100644 sanitizers/test/asInteger.test.ts diff --git a/sanitizers/README.md b/sanitizers/README.md index f37535e..d3f7873 100644 --- a/sanitizers/README.md +++ b/sanitizers/README.md @@ -24,6 +24,7 @@ yarn add @restless/sanitizers - [`cast`](#cast) - [`asString`](#asstring) - [`asNumber`](#assumber) +- [`asInteger`](#asinteger) - [`asBoolean`](#asboolean) - [`asMatching`](#asmatching) - [`asObject`](#asobject) @@ -64,6 +65,17 @@ asNumber('boo', 'path') // Result.error([{expected: 'number', path: 'path'}]) asNumber({}, 'path') // Result.error([{expected: 'number', path: 'path'}]) ``` +### `asInteger` + +Same as [`asNumber`](#asnumber), but does not accept floating point values. + +```javascript +asInteger('123', 'path') // Result.ok(123) +asInteger(0.2, 'path') // Result.error([{expected: 'integer', path: 'path'}]) +asInteger('boo', 'path') // Result.error([{expected: 'integer', path: 'path'}]) +asInteger({}, 'path') // Result.error([{expected: 'integer', path: 'path'}]) +``` + ### `asBoolean` Accepts any value that is a number or a string that represents a boolean (`"true"` or `"false"`). Returns a number. diff --git a/sanitizers/package.json b/sanitizers/package.json index 234c78f..51faf45 100644 --- a/sanitizers/package.json +++ b/sanitizers/package.json @@ -1,6 +1,6 @@ { "name": "@restless/sanitizers", - "version": "0.2.0", + "version": "0.2.1", "author": "Piotr Szlachciak ", "description": "Data sanitization in a functional way", "license": "Unlicense", diff --git a/sanitizers/src/asInteger.ts b/sanitizers/src/asInteger.ts new file mode 100644 index 0000000..4eedb3e --- /dev/null +++ b/sanitizers/src/asInteger.ts @@ -0,0 +1,10 @@ +import { asChecked } from './asChecked' +import { asNumber } from './asNumber' +import { withErrorMessage } from './withErrorMessage' + +const isInteger = (num: number) => num === Math.floor(num) + +export const asInteger = withErrorMessage( + asChecked(asNumber, isInteger), + 'integer' +) diff --git a/sanitizers/src/index.ts b/sanitizers/src/index.ts index d5adac4..63322e2 100644 --- a/sanitizers/src/index.ts +++ b/sanitizers/src/index.ts @@ -3,6 +3,7 @@ export { asArray } from './asArray' export { asBoolean } from './asBoolean' export { asChecked } from './asChecked' export { asFlatMapped } from './asFlatMapped' +export { asInteger } from './asInteger' export { asMapped } from './asMapped' export { asMatching } from './asMatching' export { asNumber } from './asNumber' diff --git a/sanitizers/test/asInteger.test.ts b/sanitizers/test/asInteger.test.ts new file mode 100644 index 0000000..6337c7b --- /dev/null +++ b/sanitizers/test/asInteger.test.ts @@ -0,0 +1,42 @@ +import { expect } from 'chai' +import { asInteger, Result } from '../src' + +describe('asInteger', () => { + it('sanitizes strings containing integers', async () => { + const result = asInteger('-123', '') + expect(result).to.deep.equal(Result.ok(-123)) + }) + + it('does not accept non-integer strings', async () => { + const result = asInteger('12abc', 'path') + expect(result).to.deep.equal( + Result.error([{ path: 'path', expected: 'integer' }]) + ) + }) + + it('sanitizes integers', async () => { + const result = asInteger(123, '') + expect(result).to.deep.equal(Result.ok(123)) + }) + + it('does not accept floating point values', async () => { + const result = asInteger(123.45, 'path') + expect(result).to.deep.equal( + Result.error([{ path: 'path', expected: 'integer' }]) + ) + }) + + it('does not accept NaN', async () => { + const result = asInteger(NaN, 'path') + expect(result).to.deep.equal( + Result.error([{ path: 'path', expected: 'integer' }]) + ) + }) + + it('does not accept types other than integer or string', async () => { + const result = asInteger(true, 'path') + expect(result).to.deep.equal( + Result.error([{ path: 'path', expected: 'integer' }]) + ) + }) +})