Skip to content

Commit 5fd1c7b

Browse files
feat(store): add createFeature (#3033)
Closes #2974
1 parent 698bd29 commit 5fd1c7b

File tree

6 files changed

+581
-0
lines changed

6 files changed

+581
-0
lines changed
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import { createFeature, createReducer, Store, StoreModule } from '@ngrx/store';
2+
import { TestBed } from '@angular/core/testing';
3+
import { take } from 'rxjs/operators';
4+
5+
describe('createFeature()', () => {
6+
it('should return passed name and reducer', () => {
7+
const fooName = 'foo';
8+
const fooReducer = createReducer(0);
9+
10+
const { name, reducer } = createFeature({
11+
name: fooName,
12+
reducer: fooReducer,
13+
});
14+
15+
expect(name).toBe(fooName);
16+
expect(reducer).toBe(fooReducer);
17+
});
18+
19+
it('should create a feature selector', () => {
20+
const { selectFooState } = createFeature({
21+
name: 'foo',
22+
reducer: createReducer({ bar: '' }),
23+
});
24+
25+
expect(selectFooState({ foo: { bar: 'baz' } })).toEqual({ bar: 'baz' });
26+
});
27+
28+
describe('nested selectors', () => {
29+
it('should create when feature state is a dictionary', () => {
30+
const initialState = { alpha: 123, beta: { bar: 'baz' }, gamma: false };
31+
32+
const { selectAlpha, selectBeta, selectGamma } = createFeature({
33+
name: 'foo',
34+
reducer: createReducer(initialState),
35+
});
36+
37+
expect(selectAlpha({ foo: initialState })).toEqual(123);
38+
expect(selectBeta({ foo: initialState })).toEqual({ bar: 'baz' });
39+
expect(selectGamma({ foo: initialState })).toEqual(false);
40+
});
41+
42+
it('should return undefined when feature state is not defined', () => {
43+
const { selectX } = createFeature({
44+
name: 'foo',
45+
reducer: createReducer({ x: 'y' }),
46+
});
47+
48+
expect(selectX({})).toBe(undefined);
49+
});
50+
51+
it('should not create when feature state is a primitive value', () => {
52+
const feature = createFeature({ name: 'foo', reducer: createReducer(0) });
53+
54+
expect(Object.keys(feature)).toEqual([
55+
'name',
56+
'reducer',
57+
'selectFooState',
58+
]);
59+
});
60+
61+
it('should not create when feature state is null', () => {
62+
const feature = createFeature({
63+
name: 'foo',
64+
reducer: createReducer(null),
65+
});
66+
67+
expect(Object.keys(feature)).toEqual([
68+
'name',
69+
'reducer',
70+
'selectFooState',
71+
]);
72+
});
73+
74+
it('should not create when feature state is an array', () => {
75+
const feature = createFeature({
76+
name: 'foo',
77+
reducer: createReducer([1, 2, 3]),
78+
});
79+
80+
expect(Object.keys(feature)).toEqual([
81+
'name',
82+
'reducer',
83+
'selectFooState',
84+
]);
85+
});
86+
87+
it('should not create when feature state is a date object', () => {
88+
const feature = createFeature({
89+
name: 'foo',
90+
reducer: createReducer(new Date()),
91+
});
92+
93+
expect(Object.keys(feature)).toEqual([
94+
'name',
95+
'reducer',
96+
'selectFooState',
97+
]);
98+
});
99+
});
100+
101+
it('should set up a feature state', (done) => {
102+
const initialFooState = { x: 1, y: 2, z: 3 };
103+
const fooFeature = createFeature({
104+
name: 'foo',
105+
reducer: createReducer(initialFooState),
106+
});
107+
108+
TestBed.configureTestingModule({
109+
imports: [StoreModule.forRoot({}), StoreModule.forFeature(fooFeature)],
110+
});
111+
112+
TestBed.inject(Store)
113+
.select(fooFeature.name)
114+
.pipe(take(1))
115+
.subscribe((fooState) => {
116+
expect(fooState).toEqual(initialFooState);
117+
done();
118+
});
119+
});
120+
});

modules/store/spec/helpers.spec.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { capitalize } from '../src/helpers';
2+
3+
describe('helpers', () => {
4+
describe('capitalize', () => {
5+
it('should capitalize the text', () => {
6+
expect(capitalize('ngrx')).toEqual('Ngrx');
7+
});
8+
9+
it('should return an empty string when the text is an empty string', () => {
10+
expect(capitalize('')).toEqual('');
11+
});
12+
});
13+
});

0 commit comments

Comments
 (0)