Skip to content

Commit be25c23

Browse files
Unit Testing with new features from 6.2.0 (#21)
Also updates to 6.2.0
1 parent 5c4fddd commit be25c23

File tree

6 files changed

+337
-593
lines changed

6 files changed

+337
-593
lines changed

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
},
1616
"private": true,
1717
"dependencies": {
18-
"@angular-redux/form": "^6.1.1",
19-
"@angular-redux/router": "^6.1.0",
20-
"@angular-redux/store": "^6.1.0",
18+
"@angular-redux/form": "^6.2.0",
19+
"@angular-redux/router": "^6.2.0",
20+
"@angular-redux/store": "^6.2.0",
2121
"@angular/common": "^4.0.0",
2222
"@angular/compiler": "^4.0.0",
2323
"@angular/core": "^4.0.0",
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import { TestBed, async } from '@angular/core/testing';
2+
import { NgReduxTestingModule, MockNgRedux } from '@angular-redux/store/testing';
3+
4+
import { Component, Input } from '@angular/core';
5+
import { NgRedux } from '@angular-redux/store';
6+
7+
import { Observable } from 'rxjs/Observable';
8+
import 'rxjs/add/observable/of';
9+
import 'rxjs/add/operator/toArray';
10+
import 'rxjs/add/operator/do';
11+
12+
import { ElephantPageComponent } from './elephant-page.container';
13+
import { AnimalActions } from '../animals/animal.actions';
14+
import { ANIMAL_TYPES } from '../animals/animal.types';
15+
16+
@Component({
17+
selector: 'zoo-animal-list',
18+
template: 'Mock Animal List',
19+
})
20+
class MockAnimalListComponent {
21+
@Input() animalsName: string;
22+
@Input() animals: Observable<any>;
23+
@Input() loading: Observable<boolean>;
24+
@Input() error: Observable<any>;
25+
};
26+
27+
describe('Elephant Page Container', () => {
28+
beforeEach(() => {
29+
TestBed.configureTestingModule({
30+
declarations: [ElephantPageComponent, MockAnimalListComponent],
31+
imports: [NgReduxTestingModule],
32+
providers: [AnimalActions],
33+
}).compileComponents();
34+
35+
MockNgRedux.reset();
36+
});
37+
38+
it('should select some elephants from the Redux store', done => {
39+
const fixture = TestBed.createComponent(ElephantPageComponent);
40+
const elephantPage = fixture.debugElement.componentInstance;
41+
const expectedSequence = [
42+
[ { name: 'I am an Elephant!' } ],
43+
[ { name: 'I am an Elephant!' }, { name: 'I am a second Elephant!' } ]
44+
];
45+
46+
const elephantItemStub = MockNgRedux.getSelectorStub(['elephants', 'items']);
47+
expectedSequence.forEach(value => elephantItemStub.next(value));
48+
elephantItemStub.complete();
49+
50+
elephantPage.animals$
51+
.toArray()
52+
.subscribe(
53+
actualSequence => expect(actualSequence).toEqual(expectedSequence),
54+
null,
55+
done);
56+
});
57+
58+
it('should know when the animals are loading', done => {
59+
const fixture = TestBed.createComponent(ElephantPageComponent);
60+
const elephantPage = fixture.debugElement.componentInstance;
61+
62+
const stub = MockNgRedux.getSelectorStub(['elephants', 'loading']);
63+
stub.next(false);
64+
stub.next(true);
65+
stub.complete();
66+
67+
elephantPage.loading$
68+
.toArray()
69+
.subscribe(
70+
actualSequence => expect(actualSequence).toEqual([ false, true ]),
71+
null,
72+
done);
73+
});
74+
75+
it('should know when there\'s an error', done => {
76+
const fixture = TestBed.createComponent(ElephantPageComponent);
77+
const elephantPage = fixture.debugElement.componentInstance;
78+
79+
const stub = MockNgRedux.getSelectorStub(['elephants', 'error']);
80+
stub.next(false);
81+
stub.next(true);
82+
stub.complete();
83+
84+
elephantPage.error$
85+
.toArray()
86+
.subscribe(
87+
actualSequence => expect(actualSequence).toEqual([ false, true ]),
88+
null,
89+
done);
90+
});
91+
92+
it('should load elephants on creation', () => {
93+
const spy = spyOn(MockNgRedux.mockInstance, 'dispatch');
94+
const fixture = TestBed.createComponent(ElephantPageComponent);
95+
96+
expect(spy).toHaveBeenCalledWith({
97+
type: AnimalActions.LOAD_STARTED,
98+
meta: { animalType: ANIMAL_TYPES.ELEPHANT },
99+
});
100+
});
101+
});

src/app/feedback/feedback-form/feedback-form.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Component, ChangeDetectionStrategy } from '@angular/core';
22
import { Connect } from '@angular-redux/form';
3-
import { NgRedux } from '@angular-redux/store';
3+
import { NgRedux, select } from '@angular-redux/store';
44
import { Observable } from 'rxjs/Observable';
55
import { of } from 'rxjs/observable/of';
66
import { IAppState } from '../../store/root.types';
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { TestBed, async } from '@angular/core/testing';
2+
import { NgReduxTestingModule, MockNgRedux } from '@angular-redux/store/testing';
3+
import { NgRedux } from '@angular-redux/store';
4+
5+
import { Observable } from 'rxjs/Observable';
6+
import 'rxjs/add/observable/of';
7+
import 'rxjs/add/operator/toArray';
8+
import 'rxjs/add/operator/do';
9+
10+
import { FeedbackFormComponent } from './feedback-form.component';
11+
12+
describe('Feedback Form Component', () => {
13+
beforeEach(() => {
14+
TestBed.configureTestingModule({
15+
declarations: [FeedbackFormComponent],
16+
imports: [NgReduxTestingModule],
17+
}).compileComponents();
18+
19+
MockNgRedux.reset();
20+
});
21+
22+
it('should keep track of the number of remaining characters left', (done) => {
23+
const fixture = TestBed.createComponent(FeedbackFormComponent);
24+
const form = fixture.debugElement.componentInstance;
25+
26+
const expectedCharsLeftSequence = [
27+
form.MAX_COMMENT_CHARS - 1,
28+
form.MAX_COMMENT_CHARS - 2,
29+
form.MAX_COMMENT_CHARS - 3,
30+
form.MAX_COMMENT_CHARS - 4,
31+
form.MAX_COMMENT_CHARS - 5,
32+
];
33+
34+
const feedbackCommentsStub = MockNgRedux.getSelectorStub(['feedback', 'comments']);
35+
feedbackCommentsStub.next('h');
36+
feedbackCommentsStub.next('he');
37+
feedbackCommentsStub.next('hel');
38+
feedbackCommentsStub.next('hell');
39+
feedbackCommentsStub.next('hello');
40+
feedbackCommentsStub.complete();
41+
42+
form.charsLeft$
43+
.toArray()
44+
.subscribe(
45+
actualSequence => expect(actualSequence).toEqual(expectedCharsLeftSequence),
46+
null,
47+
done);
48+
});
49+
});
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import { TestBed, async } from '@angular/core/testing';
2+
import { NgReduxTestingModule, MockNgRedux } from '@angular-redux/store/testing';
3+
4+
import { Component, Input } from '@angular/core';
5+
import { NgRedux } from '@angular-redux/store';
6+
7+
import { Observable } from 'rxjs/Observable';
8+
import 'rxjs/add/observable/of';
9+
import 'rxjs/add/operator/toArray';
10+
import 'rxjs/add/operator/do';
11+
12+
import { LionPageComponent } from './lion-page.container';
13+
import { AnimalActions } from '../animals/animal.actions';
14+
import { ANIMAL_TYPES } from '../animals/animal.types';
15+
16+
@Component({
17+
selector: 'zoo-animal-list',
18+
template: 'Mock Animal List',
19+
})
20+
class MockAnimalListComponent {
21+
@Input() animalsName: string;
22+
@Input() animals: Observable<any>;
23+
@Input() loading: Observable<boolean>;
24+
@Input() error: Observable<any>;
25+
};
26+
27+
describe('Lion Page Container', () => {
28+
beforeEach(() => {
29+
TestBed.configureTestingModule({
30+
declarations: [LionPageComponent, MockAnimalListComponent],
31+
imports: [NgReduxTestingModule],
32+
providers: [AnimalActions],
33+
}).compileComponents();
34+
35+
MockNgRedux.reset();
36+
});
37+
38+
it('should select some lions from the Redux store', done => {
39+
const fixture = TestBed.createComponent(LionPageComponent);
40+
const lionPage = fixture.debugElement.componentInstance;
41+
const expectedSequence = [
42+
[ { name: 'I am a Lion!' } ],
43+
[ { name: 'I am a Lion!' }, { name: 'I am a second Lion!' } ]
44+
];
45+
46+
const lionItemsStub = MockNgRedux.getSelectorStub(['lions', 'items']);
47+
expectedSequence.forEach(value => lionItemsStub.next(value));
48+
lionItemsStub.complete();
49+
50+
lionPage.animals$
51+
.toArray()
52+
.subscribe(
53+
actualSequence => expect(actualSequence).toEqual(expectedSequence),
54+
null,
55+
done);
56+
});
57+
58+
it('should know when the animals are loading', done => {
59+
const fixture = TestBed.createComponent(LionPageComponent);
60+
const lionPage = fixture.debugElement.componentInstance;
61+
62+
const lionsLoadingStub = MockNgRedux.getSelectorStub(['lions', 'loading']);
63+
lionsLoadingStub.next(false);
64+
lionsLoadingStub.next(true);
65+
lionsLoadingStub.complete();
66+
67+
lionPage.loading$
68+
.toArray()
69+
.subscribe(
70+
actualSequence => expect(actualSequence).toEqual([ false, true ]),
71+
null,
72+
done);
73+
});
74+
75+
it('should know when there\'s an error', done => {
76+
const fixture = TestBed.createComponent(LionPageComponent);
77+
const lionPage = fixture.debugElement.componentInstance;
78+
const expectedSequence = [ true ];
79+
80+
const lionsErrorStub = MockNgRedux.getSelectorStub(['lions', 'error']);
81+
lionsErrorStub.next(false);
82+
lionsErrorStub.next(true);
83+
lionsErrorStub.complete();
84+
85+
lionPage.error$
86+
.toArray()
87+
.subscribe(
88+
actualSequence => expect(actualSequence).toEqual([ false, true ]),
89+
null,
90+
done);
91+
});
92+
93+
it('should load lions on creation', () => {
94+
const spy = spyOn(MockNgRedux.mockInstance, 'dispatch');
95+
const fixture = TestBed.createComponent(LionPageComponent);
96+
97+
expect(spy).toHaveBeenCalledWith({
98+
type: AnimalActions.LOAD_STARTED,
99+
meta: { animalType: ANIMAL_TYPES.LION },
100+
});
101+
});
102+
});

0 commit comments

Comments
 (0)