From cf0722c76da5b4e9f02f0e8dd80969db1ed1d5f5 Mon Sep 17 00:00:00 2001 From: Marcis Date: Tue, 10 Mar 2020 10:05:04 +0200 Subject: [PATCH] Adds `Undefined` type --- .github/workflows/npmpublish.yml | 30 +++++++++---------- package.json | 2 +- src/assert.js | 2 +- src/assert.test.js | 2 +- src/typeCheck.js | 8 ++++-- src/typeCheck.test.js | 27 ++++++++++++++++++ src/types/Undefined.js | 10 +++++++ src/types/Undefined.test.js | 49 ++++++++++++++++++++++++++++++++ src/types/index.js | 2 ++ 9 files changed, 111 insertions(+), 21 deletions(-) create mode 100644 src/types/Undefined.js create mode 100644 src/types/Undefined.test.js diff --git a/.github/workflows/npmpublish.yml b/.github/workflows/npmpublish.yml index 40e015d..bbce5f5 100644 --- a/.github/workflows/npmpublish.yml +++ b/.github/workflows/npmpublish.yml @@ -31,18 +31,18 @@ jobs: env: NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} - publish-gpr: - needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v1 - with: - node-version: 12 - registry-url: https://npm.pkg.github.com/ - scope: '@marcisbee' - - run: npm ci - - run: npm run build - - run: npm publish - env: - NODE_AUTH_TOKEN: ${{secrets.GH_TOKEN}} + # publish-gpr: + # needs: build + # runs-on: ubuntu-latest + # steps: + # - uses: actions/checkout@v2 + # - uses: actions/setup-node@v1 + # with: + # node-version: 12 + # registry-url: https://npm.pkg.github.com/ + # scope: '@marcisbee' + # - run: npm ci + # - run: npm run build + # - run: npm publish + # env: + # NODE_AUTH_TOKEN: ${{secrets.GH_TOKEN}} diff --git a/package.json b/package.json index fb286ab..83aca46 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "letype", - "version": "1.0.3", + "version": "1.1.0", "description": "Type checker for any data structures", "main": "dist/letype.js", "module": "dist/letype.js", diff --git a/src/assert.js b/src/assert.js index 954b8aa..4b2bae1 100644 --- a/src/assert.js +++ b/src/assert.js @@ -7,7 +7,7 @@ import typeCheck from './typeCheck'; */ export default function assert(value, ...typeList) { if (typeList && typeList.length === 1) { - if (!typeCheck(value, typeList[0])) { + if (!typeCheck(value, typeList[0], [], true)) { throw new TypeError('Type checker found some type mismatches!'); } } else diff --git a/src/assert.test.js b/src/assert.test.js index fd165a8..e372361 100644 --- a/src/assert.test.js +++ b/src/assert.test.js @@ -25,7 +25,7 @@ describe('assert', () => { assert('value', String); expect(mockedTypeCheck).toHaveBeenCalledTimes(1); - expect(mockedTypeCheck).toHaveBeenCalledWith('value', String); + expect(mockedTypeCheck).toHaveBeenCalledWith('value', String, [], true); }); test('should call `typeCheck()` once if multiple types are present, first valid', () => { diff --git a/src/typeCheck.js b/src/typeCheck.js index 5462331..5091cb3 100644 --- a/src/typeCheck.js +++ b/src/typeCheck.js @@ -7,9 +7,11 @@ import CustomType from './types/Custom'; * @param {boolean} silent * @returns {boolean} */ -export default function typeCheck(value, type, path = [], silent = false) { - if (typeof type === 'function' && type.constructor instanceof CustomType) { - const { parse } = type(); +export default function typeCheck(value, type, path = [], silent = true) { + if (typeof type === 'function' && type.prototype instanceof CustomType) { + // @ts-ignore + // eslint-disable-next-line new-cap + const { parse } = new type(); if (typeof parse === 'function') return parse(value); } diff --git a/src/typeCheck.test.js b/src/typeCheck.test.js index 29fbc88..87662b0 100644 --- a/src/typeCheck.test.js +++ b/src/typeCheck.test.js @@ -1,5 +1,12 @@ /* eslint-disable no-new-func */ import typeCheck from './typeCheck'; +import CustomType from './types/Custom'; + +class MockAny extends CustomType { + parse() { + return true; + } +} // eslint-disable-next-line no-console console.error = jest.fn(); @@ -13,6 +20,26 @@ describe('typeCheck', () => { expect(typeCheck instanceof Function).toBe(true); }); + describe('CustomType', () => { + test.only('should call `parse` method on `CustomType`', () => { + MockAny.prototype.parse = jest.fn(); + typeCheck('CustomValue', MockAny); + + expect(MockAny.prototype.parse).toHaveBeenCalledTimes(1); + expect(MockAny.prototype.parse).toHaveBeenCalledWith('CustomValue'); + }); + + test.only('should return output of parse method as `true`', () => { + MockAny.prototype.parse = jest.fn().mockImplementation(() => true); + expect(typeCheck('CustomValue', MockAny)).toBe(true); + }); + + test.only('should return output of parse method as `false`', () => { + MockAny.prototype.parse = jest.fn().mockImplementation(() => false); + expect(typeCheck('CustomValue', MockAny)).toBe(false); + }); + }); + describe('String', () => { test.each([ 'Value', diff --git a/src/types/Undefined.js b/src/types/Undefined.js new file mode 100644 index 0000000..b653e70 --- /dev/null +++ b/src/types/Undefined.js @@ -0,0 +1,10 @@ +import CustomType from './Custom'; + +export default class Undefined extends CustomType { + /** + * @param {any} value + */ + parse(value) { + return typeof value === 'undefined'; + } +} diff --git a/src/types/Undefined.test.js b/src/types/Undefined.test.js new file mode 100644 index 0000000..ba4eba1 --- /dev/null +++ b/src/types/Undefined.test.js @@ -0,0 +1,49 @@ +import CustomType from './Custom'; +import Undefined from './Undefined'; + +describe('Undefined', () => { + afterEach(() => { + jest.resetAllMocks(); + }); + + test('should extend `CustomType`', () => { + expect(Undefined.prototype instanceof CustomType).toBe(true); + }); + + test('should return `true` with value ``', () => { + // @ts-ignore + const output = new Undefined().parse(); + + expect(output).toBe(true); + }); + + test('should return `true` with value `undefined`', () => { + const output = new Undefined().parse(undefined); + + expect(output).toBe(true); + }); + + test('should return `false` with value "1"', () => { + const output = new Undefined().parse('1'); + + expect(output).toBe(false); + }); + + test('should return `false` with value `0`', () => { + const output = new Undefined().parse(0); + + expect(output).toBe(false); + }); + + test('should return `false` with value `null`', () => { + const output = new Undefined().parse(null); + + expect(output).toBe(false); + }); + + test('should return `false` with value `NaN`', () => { + const output = new Undefined().parse(NaN); + + expect(output).toBe(false); + }); +}); diff --git a/src/types/index.js b/src/types/index.js index 8d37e5c..7eb7445 100644 --- a/src/types/index.js +++ b/src/types/index.js @@ -1,11 +1,13 @@ import Any from './Any'; import Or from './Or'; import Custom from './Custom'; +import Undefined from './Undefined'; const types = { Any, Or, Custom, + Undefined, }; export default types;