diff --git a/package.json b/package.json index edb236b..78b0779 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ngx-remotedata", - "version": "6.0.0", + "version": "6.0.1", "description": "RemoteData: Slaying a UI Antipattern with Angular", "repository": { "type": "git", diff --git a/projects/lib/src/lib/remote-data.spec.ts b/projects/lib/src/lib/remote-data.spec.ts index 5419f2d..95c9be9 100644 --- a/projects/lib/src/lib/remote-data.spec.ts +++ b/projects/lib/src/lib/remote-data.spec.ts @@ -10,9 +10,19 @@ import { mapFailure, isFailure, isInProgress, - chain + chain, + isNotAsked, + isSuccess, + isRemoteData } from './remote-data'; +interface RemoteDataGuardsTestObj { + name: string; + fn: (rd: RemoteData) => boolean; + truth: RemoteData; + falses: any[]; +} + describe('RemoteData', () => { describe('notAsked', () => { it('should have a "NotAsked" tag', () => { @@ -138,4 +148,48 @@ describe('RemoteData', () => { expect(ageResult).toEqual(failure('-3 is an invalid age')); }); }); + + describe('Type Guard', () => { + ([ + { + name: 'isNotAsked', + fn: isNotAsked, + truth: notAsked(), + falses: [success('hola'), null, undefined, 'hola', {}] + }, + { + name: 'isSuccess', + fn: isSuccess, + truth: success(1), + falses: [notAsked(), null, undefined, 'hola', {}] + }, + { + name: 'isFailure', + fn: isFailure, + truth: failure('error!', 9), + falses: [success(9), null, undefined, 77, NaN] + }, + { + name: 'isInProgress', + fn: isInProgress, + truth: inProgress(true), + falses: [failure('error!'), null, undefined, true, []] + }, + { + name: 'isRemoteData', + fn: isRemoteData, + truth: notAsked(), + falses: [null, undefined, true, [], NaN, 8] + } + ] as RemoteDataGuardsTestObj[]).forEach(test => { + describe(test.name, () => { + it('should be true', () => { + expect(test.fn(test.truth)).toBe(true); + }); + it('should be false', () => { + test.falses.forEach(val => expect(test.fn(val)).toBe(false)); + }); + }); + }); + }); }); diff --git a/projects/lib/src/lib/remote-data.ts b/projects/lib/src/lib/remote-data.ts index 919ba95..5853428 100644 --- a/projects/lib/src/lib/remote-data.ts +++ b/projects/lib/src/lib/remote-data.ts @@ -57,6 +57,7 @@ export const isNotAsked = (value: unknown): value is NotAsked => { return ( value !== null && value !== undefined && + (value as object).hasOwnProperty('tag') && (value as RemoteData).tag === 'NotAsked' ); }; @@ -65,6 +66,7 @@ export const isInProgress = (value: unknown): value is InProgress => { return ( value !== null && value !== undefined && + (value as object).hasOwnProperty('tag') && (value as RemoteData).tag === 'InProgress' ); }; @@ -73,6 +75,7 @@ export const isFailure = (value: unknown): value is Failure => { return ( value !== null && value !== undefined && + (value as object).hasOwnProperty('tag') && (value as RemoteData).tag === 'Failure' ); }; @@ -81,6 +84,7 @@ export const isSuccess = (value: unknown): value is Success => { return ( value !== null && value !== undefined && + (value as object).hasOwnProperty('tag') && (value as RemoteData).tag === 'Success' ); }; @@ -88,13 +92,16 @@ export const isSuccess = (value: unknown): value is Success => { export const isRemoteData = ( value: unknown ): value is RemoteData => { + const hasRemoteDataTag = (tag: RemoteData['tag']) => + tag === 'NotAsked' || + tag === 'InProgress' || + tag === 'Success' || + tag === 'Failure'; return ( - (value !== null && - value !== undefined && - (value as RemoteData).tag === 'NotAsked') || - (value as RemoteData).tag === 'InProgress' || - (value as RemoteData).tag === 'Success' || - (value as RemoteData).tag === 'Failure' + value !== null && + value !== undefined && + (value as object).hasOwnProperty('tag') && + hasRemoteDataTag((value as RemoteData).tag) ); };