Skip to content

Commit ecda5f7

Browse files
timdeschryverbrandonroberts
authored andcommitted
feat(store): warn when same action is registered (#1801)
Closes #1758
1 parent 46678f2 commit ecda5f7

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

modules/store/spec/reducer_creator.spec.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import * as ngCore from '@angular/core';
12
import { on, createReducer, createAction, props, union } from '@ngrx/store';
23
import { expecter } from 'ts-snippet';
34

@@ -86,6 +87,59 @@ import {on} from './modules/store/src/reducer_creator';
8687
state = fooBarReducer(state, bar({ bar: 54 }));
8788
expect(state).toEqual(['[foobar] FOO', '[foobar] BAR']);
8889
});
90+
91+
describe('warning message when the same action type gets registered', () => {
92+
it('should not warn when not violated', () => {
93+
const spy = spyOn(console, 'warn');
94+
95+
const fooBarReducer = createReducer(
96+
[],
97+
on(foo, state => state),
98+
on(bar, state => state)
99+
);
100+
101+
expect(spy).not.toHaveBeenCalled();
102+
});
103+
104+
it('should warn in dev mode', () => {
105+
const spy = spyOn(console, 'warn');
106+
107+
const fooBarReducer = createReducer(
108+
[],
109+
on(foo, state => state),
110+
on(bar, state => state),
111+
on(foo, state => state)
112+
);
113+
114+
expect(spy).toHaveBeenCalledTimes(1);
115+
});
116+
117+
it('should warn in dev mode with multiple actions', () => {
118+
const spy = spyOn(console, 'warn');
119+
120+
const fooBarReducer = createReducer(
121+
[],
122+
on(foo, foo, state => state),
123+
on(bar, state => state)
124+
);
125+
126+
expect(spy).toHaveBeenCalledTimes(1);
127+
});
128+
129+
it('should not warn in prod mode', () => {
130+
spyOn(ngCore, 'isDevMode').and.returnValue(false);
131+
const spy = spyOn(console, 'warn');
132+
133+
const fooBarReducer = createReducer(
134+
[],
135+
on(foo, state => state),
136+
on(bar, state => state),
137+
on(foo, state => state)
138+
);
139+
140+
expect(spy).not.toHaveBeenCalled();
141+
});
142+
});
89143
});
90144
});
91145
});

modules/store/src/reducer_creator.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { isDevMode } from '@angular/core';
12
import { ActionCreator, ActionReducer, ActionType, Action } from './models';
23

34
// Return type of the `on` fn.
@@ -51,8 +52,15 @@ export function createReducer<S>(
5152
...ons: On<S>[]
5253
): ActionReducer<S> {
5354
const map = new Map<string, ActionReducer<S>>();
55+
const devMode = isDevMode();
56+
5457
for (let on of ons) {
5558
for (let type of on.types) {
59+
if (devMode && map.has(type)) {
60+
console.warn(
61+
`@ngrx/store: The provided action type '${type}' is already provided.`
62+
);
63+
}
5664
map.set(type, on.reducer);
5765
}
5866
}

0 commit comments

Comments
 (0)