diff --git a/modules/store/spec/reducer_creator.spec.ts b/modules/store/spec/reducer_creator.spec.ts index ff2a2d4e7a..d673368162 100644 --- a/modules/store/spec/reducer_creator.spec.ts +++ b/modules/store/spec/reducer_creator.spec.ts @@ -1,3 +1,4 @@ +import * as ngCore from '@angular/core'; import { on, createReducer, createAction, props, union } from '@ngrx/store'; import { expecter } from 'ts-snippet'; @@ -86,6 +87,59 @@ import {on} from './modules/store/src/reducer_creator'; state = fooBarReducer(state, bar({ bar: 54 })); expect(state).toEqual(['[foobar] FOO', '[foobar] BAR']); }); + + describe('warning message when the same action type gets registered', () => { + it('should not warn when not violated', () => { + const spy = spyOn(console, 'warn'); + + const fooBarReducer = createReducer( + [], + on(foo, state => state), + on(bar, state => state) + ); + + expect(spy).not.toHaveBeenCalled(); + }); + + it('should warn in dev mode', () => { + const spy = spyOn(console, 'warn'); + + const fooBarReducer = createReducer( + [], + on(foo, state => state), + on(bar, state => state), + on(foo, state => state) + ); + + expect(spy).toHaveBeenCalledTimes(1); + }); + + it('should warn in dev mode with multiple actions', () => { + const spy = spyOn(console, 'warn'); + + const fooBarReducer = createReducer( + [], + on(foo, foo, state => state), + on(bar, state => state) + ); + + expect(spy).toHaveBeenCalledTimes(1); + }); + + it('should not warn in prod mode', () => { + spyOn(ngCore, 'isDevMode').and.returnValue(false); + const spy = spyOn(console, 'warn'); + + const fooBarReducer = createReducer( + [], + on(foo, state => state), + on(bar, state => state), + on(foo, state => state) + ); + + expect(spy).not.toHaveBeenCalled(); + }); + }); }); }); }); diff --git a/modules/store/src/reducer_creator.ts b/modules/store/src/reducer_creator.ts index 39ecad5396..5be9e06ddb 100644 --- a/modules/store/src/reducer_creator.ts +++ b/modules/store/src/reducer_creator.ts @@ -1,3 +1,4 @@ +import { isDevMode } from '@angular/core'; import { ActionCreator, ActionReducer, ActionType, Action } from './models'; // Return type of the `on` fn. @@ -51,8 +52,15 @@ export function createReducer( ...ons: On[] ): ActionReducer { const map = new Map>(); + const devMode = isDevMode(); + for (let on of ons) { for (let type of on.types) { + if (devMode && map.has(type)) { + console.warn( + `@ngrx/store: The provided action type '${type}' is already provided.` + ); + } map.set(type, on.reducer); } }