Skip to content

Commit fba0dda

Browse files
chore: switch to Jest for unit tests (ngrx#2422)
1 parent 0d6b6af commit fba0dda

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+662
-656
lines changed

.circleci/config.yml

+2-14
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ version: 2
1010
# See https://blog.daemonl.com/2016/02/yaml.html
1111
# To validate changes, use an online parser, eg.
1212
# https://yaml-online-parser.appspot.com/
13-
var_1: &cache_key yarn-cache-{{ checksum "yarn.lock" }}-0.12.3
13+
var_1: &cache_key yarn-cache-{{ checksum "yarn.lock" }}-0.12.4
1414
var_2: &run_in_node
1515
docker:
1616
- image: circleci/node:12.9.1
@@ -75,7 +75,7 @@ jobs:
7575
key: *cache_key
7676

7777
# Build and Test
78-
- run: yarn test
78+
- run: yarn test --maxWorkers=1 --ci
7979

8080
build:
8181
<<: *run_in_node
@@ -109,14 +109,6 @@ jobs:
109109
- run: yarn copy:schematics
110110
- run: git diff --name-only --exit-code ./modules
111111

112-
example-tests:
113-
<<: *run_in_browser
114-
steps:
115-
- checkout
116-
- restore_cache:
117-
key: *cache_key
118-
- run: yarn run example:test --watch=false --runInBand
119-
120112
example-e2e-tests:
121113
<<: *run_in_browser
122114
steps:
@@ -278,9 +270,6 @@ workflows:
278270
- build:
279271
requires:
280272
- test
281-
- example-tests:
282-
requires:
283-
- install
284273
- example-e2e-tests:
285274
requires:
286275
- install
@@ -299,7 +288,6 @@ workflows:
299288
- deploy:
300289
requires:
301290
- docs
302-
- example-tests
303291
- example-e2e-tests
304292
- docs-tests
305293
- build

angular.json

-15
Original file line numberDiff line numberDiff line change
@@ -72,21 +72,6 @@
7272
"browserTarget": "example-app:build"
7373
}
7474
},
75-
"test": {
76-
"builder": "@angular-devkit/build-angular:karma",
77-
"options": {
78-
"main": "projects/example-app/src/test.ts",
79-
"polyfills": "projects/example-app/src/polyfills.ts",
80-
"tsConfig": "projects/example-app/tsconfig.spec.json",
81-
"karmaConfig": "projects/example-app/karma.conf.js",
82-
"styles": ["projects/example-app/src/styles.css"],
83-
"scripts": [],
84-
"assets": [
85-
"projects/example-app/src/favicon.ico",
86-
"projects/example-app/src/assets"
87-
]
88-
}
89-
},
9075
"lint": {
9176
"builder": "@angular-devkit/build-angular:tslint",
9277
"options": {

jest.config.js

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
module.exports = {
2+
rootDir: '.',
3+
setupFilesAfterEnv: ['<rootDir>/setup-jest.ts'],
4+
globals: {
5+
'ts-jest': {
6+
tsConfig: 'tsconfig.json',
7+
stringifyContentPathRegex: '\\.html?$',
8+
astTransformers: [
9+
require.resolve('jest-preset-angular/build/StripStylesTransformer'),
10+
],
11+
},
12+
},
13+
transform: {
14+
'^.+\\.(ts|js|html)$': 'ts-jest',
15+
},
16+
testMatch: [
17+
'<rootDir>/modules/**/*.spec.ts',
18+
'<rootDir>/projects/example-app/**/*.spec.ts'
19+
],
20+
testEnvironment: 'jsdom',
21+
moduleFileExtensions: ['html', 'js', 'json', 'ts'],
22+
coveragePathIgnorePatterns: ['/node_modules/', '/modules/*.*/'],
23+
moduleNameMapper: {
24+
'^@ngrx/(.*)': '<rootDir>/modules/$1',
25+
'^@example-app/(.*)': '<rootDir>/projects/example-app/src/app/$1',
26+
},
27+
transformIgnorePatterns: ['node_modules/(?!@ngrx)'],
28+
modulePathIgnorePatterns: ['dist'],
29+
snapshotSerializers: [
30+
'jest-preset-angular/build/AngularSnapshotSerializer.js',
31+
'jest-preset-angular/build/HTMLCommentSerializer.js',
32+
],
33+
testPathIgnorePatterns: [
34+
'<rootDir>/node_modules/',
35+
'<rootDir>/projects/example-app-cypress'
36+
]
37+
};

modules/data/spec/actions/entity-action-factory.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ describe('EntityActionFactory', () => {
2323
const { entityName, entityOp, data } = action.payload;
2424
expect(entityName).toBe('Hero');
2525
expect(entityOp).toBe(EntityOp.QUERY_ALL);
26-
expect(data).toBeUndefined('no data property');
26+
expect(data).toBeUndefined();
2727
});
2828

2929
it('#create should create an EntityAction with the given data', () => {

modules/data/spec/dataservices/default-data.service.spec.ts

+12-7
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ describe('DefaultDataService', () => {
115115
const req = httpTestingController.expectOne(heroesUrl);
116116
expect(req.request.method).toEqual('GET');
117117

118-
expect(req.request.body).toBeNull('should not send data');
118+
expect(req.request.body).toBeNull();
119119

120120
// Respond with the mock heroes
121121
req.flush(expectedHeroes);
@@ -163,7 +163,7 @@ describe('DefaultDataService', () => {
163163
service.getAll().subscribe(
164164
heroes => fail('getAll succeeded when expected it to fail with a 404'),
165165
err => {
166-
expect(err).toBeDefined('request should have failed');
166+
expect(err).toBeDefined();
167167
expect(err instanceof DataServiceError).toBe(
168168
true,
169169
'is DataServiceError'
@@ -207,7 +207,7 @@ describe('DefaultDataService', () => {
207207
// One request to GET hero from expected URL
208208
const req = httpTestingController.expectOne(heroUrlId1);
209209

210-
expect(req.request.body).toBeNull('should not send data');
210+
expect(req.request.body).toBeNull();
211211

212212
// Respond with the expected hero
213213
req.flush(expectedHero);
@@ -260,7 +260,7 @@ describe('DefaultDataService', () => {
260260
const req = httpTestingController.expectOne(heroesUrl + '?name=B');
261261
expect(req.request.method).toEqual('GET');
262262

263-
expect(req.request.body).toBeNull('should not send data');
263+
expect(req.request.body).toBeNull();
264264

265265
// Respond with the mock heroes
266266
req.flush(expectedHeroes);
@@ -307,7 +307,7 @@ describe('DefaultDataService', () => {
307307
heroes =>
308308
fail('getWithQuery succeeded when expected it to fail with a 404'),
309309
err => {
310-
expect(err).toBeDefined('request should have failed');
310+
expect(err).toBeDefined();
311311
expect(err instanceof DataServiceError).toBe(
312312
true,
313313
'is DataServiceError'
@@ -378,7 +378,7 @@ describe('DefaultDataService', () => {
378378
r => r.method === 'DELETE' && r.url === heroUrlId1
379379
);
380380

381-
expect(req.request.body).toBeNull('should not send data');
381+
expect(req.request.body).toBeNull();
382382

383383
// Respond with empty nonsense object
384384
req.flush({});
@@ -541,7 +541,12 @@ describe('DefaultDataServiceFactory', () => {
541541
collectionResourceUrl: heroesUrl,
542542
},
543543
});
544-
http = jasmine.createSpyObj('HttpClient', ['get', 'delete', 'post', 'put']);
544+
http = {
545+
get: jasmine.createSpy('get'),
546+
delete: jasmine.createSpy('delete'),
547+
post: jasmine.createSpy('post'),
548+
put: jasmine.createSpy('put'),
549+
};
545550
http.get.and.returnValue(of([]));
546551
});
547552

modules/data/spec/dispatchers/entity-dispatcher.spec.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ export function commandDispatchTest(
188188
} = dispatchedAction().payload;
189189
expect(entityOp).toBe(EntityOp.QUERY_ALL);
190190
expect(entityName).toBe('Hero');
191-
expect(mergeStrategy).toBeUndefined('no MergeStrategy');
191+
expect(mergeStrategy).toBeUndefined();
192192
});
193193

194194
it('#getAll({mergeStrategy}) dispatches QUERY_ALL with a MergeStrategy', () => {
@@ -210,7 +210,7 @@ export function commandDispatchTest(
210210
const { entityOp, data, mergeStrategy } = dispatchedAction().payload;
211211
expect(entityOp).toBe(EntityOp.QUERY_BY_KEY);
212212
expect(data).toBe(42);
213-
expect(mergeStrategy).toBeUndefined('no MergeStrategy');
213+
expect(mergeStrategy).toBeUndefined();
214214
});
215215

216216
it('#getByKey(42, {mergeStrategy}) dispatches QUERY_BY_KEY with a MergeStrategy', () => {
@@ -236,7 +236,7 @@ export function commandDispatchTest(
236236
expect(entityOp).toBe(EntityOp.QUERY_MANY);
237237
expect(entityName).toBe('Hero');
238238
expect(data).toEqual({ name: 'B' }, 'params');
239-
expect(mergeStrategy).toBeUndefined('no MergeStrategy');
239+
expect(mergeStrategy).toBeUndefined();
240240
});
241241

242242
it('#getWithQuery(string) dispatches QUERY_MANY', () => {
@@ -251,7 +251,7 @@ export function commandDispatchTest(
251251
expect(entityOp).toBe(EntityOp.QUERY_MANY);
252252
expect(entityName).toBe('Hero');
253253
expect(data).toEqual('name=B', 'params');
254-
expect(mergeStrategy).toBeUndefined('no MergeStrategy');
254+
expect(mergeStrategy).toBeUndefined();
255255
});
256256

257257
it('#getWithQuery(string) dispatches QUERY_MANY with a MergeStrategy', () => {
@@ -281,7 +281,7 @@ export function commandDispatchTest(
281281
} = dispatchedAction().payload;
282282
expect(entityOp).toBe(EntityOp.QUERY_LOAD);
283283
expect(entityName).toBe('Hero');
284-
expect(mergeStrategy).toBeUndefined('no MergeStrategy');
284+
expect(mergeStrategy).toBeUndefined();
285285
});
286286
});
287287

@@ -304,7 +304,7 @@ export function commandDispatchTest(
304304
const { entityOp, data, mergeStrategy } = dispatchedAction().payload;
305305
expect(entityOp).toBe(EntityOp.ADD_ONE);
306306
expect(data).toBe(hero);
307-
expect(mergeStrategy).toBeUndefined('no MergeStrategy');
307+
expect(mergeStrategy).toBeUndefined();
308308
});
309309

310310
it('#addOneToCache can dispatch ADD_ONE and MergeStrategy.IgnoreChanges', () => {

modules/data/spec/effects/entity-cache-effects.spec.ts

+11-7
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ describe('EntityCacheEffects (normal testing)', () => {
3535
mergeStrategy: typeof mergeStrategy;
3636
};
3737

38-
function expectCompletion(completion: any, done: DoneFn) {
38+
function expectCompletion(completion: any, done: any) {
3939
effects.saveEntities$.subscribe(result => {
4040
expect(result).toEqual(completion);
4141
done();
@@ -45,7 +45,11 @@ describe('EntityCacheEffects (normal testing)', () => {
4545
beforeEach(() => {
4646
actions$ = new ReplaySubject<Action>(1);
4747
correlationId = 'CORID42';
48-
logger = jasmine.createSpyObj('Logger', ['error', 'log', 'warn']);
48+
logger = {
49+
error: jasmine.createSpy('error'),
50+
log: jasmine.createSpy('log'),
51+
warn: jasmine.createSpy('warn'),
52+
};
4953
mergeStrategy = undefined;
5054
options = { correlationId, mergeStrategy };
5155

@@ -70,7 +74,7 @@ describe('EntityCacheEffects (normal testing)', () => {
7074
dataService = TestBed.get(EntityCacheDataService);
7175
});
7276

73-
it('should return a SAVE_ENTITIES_SUCCESS with the expected ChangeSet on success', (done: DoneFn) => {
77+
it('should return a SAVE_ENTITIES_SUCCESS with the expected ChangeSet on success', (done: any) => {
7478
const cs = createChangeSet();
7579
const action = new SaveEntities(cs, 'test/save', options);
7680
const completion = new SaveEntitiesSuccess(cs, 'test/save', options);
@@ -81,7 +85,7 @@ describe('EntityCacheEffects (normal testing)', () => {
8185
dataService.setResponse(cs);
8286
});
8387

84-
it('should not emit SAVE_ENTITIES_SUCCESS if cancel arrives in time', (done: DoneFn) => {
88+
it('should not emit SAVE_ENTITIES_SUCCESS if cancel arrives in time', (done: any) => {
8589
const cs = createChangeSet();
8690
const action = new SaveEntities(cs, 'test/save', options);
8791
const cancel = new SaveEntitiesCancel(correlationId, 'Test Cancel');
@@ -97,7 +101,7 @@ describe('EntityCacheEffects (normal testing)', () => {
97101
dataService.setResponse(cs);
98102
});
99103

100-
it('should emit SAVE_ENTITIES_SUCCESS if cancel arrives too late', (done: DoneFn) => {
104+
it('should emit SAVE_ENTITIES_SUCCESS if cancel arrives too late', (done: any) => {
101105
const cs = createChangeSet();
102106
const action = new SaveEntities(cs, 'test/save', options);
103107
const cancel = new SaveEntitiesCancel(correlationId, 'Test Cancel');
@@ -112,7 +116,7 @@ describe('EntityCacheEffects (normal testing)', () => {
112116
setTimeout(() => actions$.next(cancel), 1);
113117
});
114118

115-
it('should emit SAVE_ENTITIES_SUCCESS immediately if no changes to save', (done: DoneFn) => {
119+
it('should emit SAVE_ENTITIES_SUCCESS immediately if no changes to save', (done: any) => {
116120
const action = new SaveEntities({ changes: [] }, 'test/save', options);
117121
effects.saveEntities$.subscribe(result => {
118122
expect(result instanceof SaveEntitiesSuccess).toBe(true);
@@ -122,7 +126,7 @@ describe('EntityCacheEffects (normal testing)', () => {
122126
actions$.next(action);
123127
});
124128

125-
xit('should return a SAVE_ENTITIES_ERROR when data service fails', (done: DoneFn) => {
129+
xit('should return a SAVE_ENTITIES_ERROR when data service fails', (done: any) => {
126130
const cs = createChangeSet();
127131
const action = new SaveEntities(cs, 'test/save', options);
128132
const httpError = { error: new Error('Test Failure'), status: 501 };

modules/data/spec/effects/entity-effects.marbles.spec.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@ describe('EntityEffects (marble testing)', () => {
3232
let logger: Logger;
3333

3434
beforeEach(() => {
35-
logger = jasmine.createSpyObj('Logger', ['error', 'log', 'warn']);
35+
logger = {
36+
error: jasmine.createSpy('error'),
37+
log: jasmine.createSpy('log'),
38+
warn: jasmine.createSpy('warn'),
39+
};
3640

3741
TestBed.configureTestingModule({
3842
providers: [

0 commit comments

Comments
 (0)