Skip to content
This repository was archived by the owner on May 26, 2023. It is now read-only.

Commit 677a62c

Browse files
christopherthielenmergify[bot]
authored andcommitted
test: Migrate from karma/jasmine to jest
Why? karma had an entire webpack config baked in and due to webpack depending on an old version of chokidar, tests kept failing. Decided to bite the bullet and remove karma+jasmine+webpack from the project.
1 parent 22932c1 commit 677a62c

23 files changed

+2364
-2621
lines changed

jest.config.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
const NG = process.env.NG || '1.6';
2+
3+
module.exports = {
4+
preset: 'ts-jest',
5+
testEnvironment: 'jsdom',
6+
roots: ['src', 'test'],
7+
testMatch: ['**/__tests__/**/*.[jt]s?(x)', '**/?(*.)+(spec|test).[jt]s?(x)', '**/?*Spec.[jt]s'],
8+
setupFilesAfterEnv: ['./test/jest.init.ts'],
9+
moduleNameMapper: {
10+
'^angular$': '<rootDir>/test/angular/jest-angular.js',
11+
'^jest-angular-import$': `<rootDir>/test/angular/${NG}/angular.js`,
12+
'^angular-animate$': `<rootDir>/test/angular/${NG}/angular-animate.js`,
13+
'^angular-mocks$': `<rootDir>/test/angular/${NG}/angular-mocks.js`,
14+
},
15+
};

package.json

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,16 @@
1515
"bundle_router": "rollup -c --environment ROUTER && rollup -c --environment ROUTER,MINIFY",
1616
"bundle_events": "rollup -c --environment EVENTS && rollup -c --environment EVENTS,MINIFY",
1717
"bundle_resolve": "rollup -c --environment RESOLVE && rollup -c --environment RESOLVE,MINIFY",
18-
"test": "tsc && npm run test:ng16 && npm run test:ng15 && npm run test:ng14 && npm run test:ng13 && npm run test:ng12",
19-
"test:ng12": "karma start --ngversion 1.2",
20-
"test:ng13": "karma start --ngversion 1.3",
21-
"test:ng14": "karma start --ngversion 1.4",
22-
"test:ng15": "karma start --ngversion 1.5",
23-
"test:ng16": "karma start --ngversion 1.6",
18+
"test": "tsc && NG=1.6 jest && NG=1.5 jest && NG=1.4 jest && NG=1.3 jest && NG=1.2 jest",
19+
"test:debug": "node --inspect ./node_modules/.bin/jest --runInBand --watch",
20+
"test:ng12": "NG=1.2 jest",
21+
"test:ng13": "NG=1.3 jest",
22+
"test:ng14": "NG=1.4 jest",
23+
"test:ng15": "NG=1.5 jest",
24+
"test:ng16": "NG=1.6 jest",
2425
"test:downstream": "test_downstream_projects",
25-
"watch": "karma start --singleRun=false --autoWatch=true --autoWatchInterval=1",
26-
"debug": "karma start --singleRun=false --autoWatch=true --autoWatchInterval=1 --browsers=Chrome",
26+
"watch": "jest --watch",
27+
"debug": "npm run test:debug",
2728
"docs": "generate_docs",
2829
"docs:publish": "generate_docs && publish_docs",
2930
"release": "release --deps @uirouter/core && node ./scripts/npm_angular_ui_router_release.js && node ./scripts/bower_release.js",
@@ -81,31 +82,22 @@
8182
"@types/angular": "1.6.57",
8283
"@types/angular-animate": "^1.5.10",
8384
"@types/angular-mocks": "^1.7.0",
84-
"@types/jasmine": "^3.5.10",
85+
"@types/jest": "^25.2.3",
8586
"@uirouter/publish-scripts": "^2.3.48",
8687
"dts-downlevel": "^0.3.0",
87-
"fork-ts-checker-webpack-plugin": "^4.1.3",
8888
"husky": "^4.2.5",
89-
"jasmine-core": "^3.5.0",
90-
"karma": "^4.4.1",
91-
"karma-chrome-launcher": "^3.1.0",
92-
"karma-jasmine": "^2.0.1",
93-
"karma-mocha-reporter": "^2.2.5",
94-
"karma-sourcemap-loader": "^0.3.7",
95-
"karma-super-dots-reporter": "^0.2.0",
96-
"karma-webpack": "^4.0.2",
89+
"jest": "^26.0.1",
9790
"lodash": "^4.17.15",
9891
"prettier": "^2.0.5",
9992
"pretty-quick": "^2.0.1",
10093
"rollup": "^1.27.14",
10194
"rollup-plugin-node-resolve": "^5.2.0",
10295
"rollup-plugin-sourcemaps": "^0.5.0",
10396
"rollup-plugin-uglify": "^6.0.4",
104-
"ts-loader": "^7.0.1",
97+
"ts-jest": "^26.0.0",
10598
"tslint": "^6.1.2",
10699
"tslint-eslint-rules": "^5.4.0",
107-
"typescript": "^3.6.4",
108-
"webpack": "^4.43.0"
100+
"typescript": "^3.6.4"
109101
},
110102
"husky": {
111103
"hooks": {

test/angular/jest-angular.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// This setup is used to inject specific versions of angularjs to test against
2+
3+
// Jest is configured to alias `import * as angular from 'angular'` to this file in jest.config.js.
4+
// This file then imports angularjs bundle via the 'jest-angular-import' module alias which maps to
5+
// a specific version of the angularjs bundle.
6+
// It then exports the window.angular for use in tests that import from 'angular'
7+
8+
require('jest-angular-import');
9+
module.exports = window.angular;

test/index.js

Lines changed: 0 additions & 9 deletions
This file was deleted.

test/jest.init.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
const noop = () => {};
2+
Object.defineProperty(window, 'scrollTo', { value: noop, writable: true });
3+
4+
import 'angular';
5+
import 'angular-mocks';
6+
import 'angular-animate';
7+
import './util/testUtilsNg1';
8+
9+
require('../src/index');

test/ng1StateBuilderSpec.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,21 @@ describe('Ng1 StateBuilder', function () {
2121
const config = { url: '/foo', templateUrl: '/foo.html', controller: 'FooController', parent: parent };
2222
const built = builder.builder('views')(config);
2323

24-
expect(built.$default).not.toEqualData(config);
25-
expect(built.$default).toEqualData({
26-
templateUrl: '/foo.html',
27-
controller: 'FooController',
28-
resolveAs: '$resolve',
29-
});
24+
expect(built.$default).not.toEqual(config);
25+
expect(built.$default).toEqual(
26+
expect.objectContaining({
27+
templateUrl: '/foo.html',
28+
controller: 'FooController',
29+
resolveAs: '$resolve',
30+
})
31+
);
3032
});
3133

3234
it('It should use the views object to build views, when defined', function () {
3335
const config = { a: { foo: 'bar', controller: 'FooController' } };
3436
const builtViews = builder.builder('views')({ parent: parent, views: config });
35-
expect(builtViews.a.foo).toEqualData(config.a.foo);
36-
expect(builtViews.a.controller).toEqualData(config.a.controller);
37+
expect(builtViews.a.foo).toEqual(config.a.foo);
38+
expect(builtViews.a.controller).toEqual(config.a.controller);
3739
});
3840

3941
it('should not allow a view config with both component and template keys', inject(function ($injector) {

test/resolveSpec.ts

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1+
import { IPromise } from 'angular';
12
import * as angular from 'angular';
2-
import './util/matchers';
33
import './util/testUtilsNg1';
44

55
declare var inject;
66
import Spy = jasmine.Spy;
7-
import './util/matchers';
8-
import { resolvedValue, resolvedError, caught } from './util/testUtilsNg1';
7+
import { resolvedValue, resolvedError, caught, testablePromise } from './util/testUtilsNg1';
98
import { ResolveContext, StateObject, PathNode, omit, pick, inherit, forEach } from '@uirouter/core';
109
import { UIRouter, Resolvable, services, StateDeclaration } from '@uirouter/core';
1110
import '../src/legacy/resolveService';
@@ -214,6 +213,10 @@ function makePath(names: string[]): PathNode[] {
214213
return names.map((name) => new PathNode(statesMap[name]));
215214
}
216215

216+
function isResolved(promise: IPromise<any>) {
217+
return !!testablePromise(promise).$$resolved;
218+
}
219+
217220
describe('Resolvables system:', function () {
218221
beforeEach(inject(function ($transitions, $injector) {
219222
emptyPath = [];
@@ -290,7 +293,7 @@ describe('$resolve', function () {
290293
const fun: Spy = jasmine.createSpy('fun');
291294
fun.and.returnValue(42);
292295
const r = $r.resolve({ fun: ['$resolve', fun] });
293-
expect(r).not.toBeResolved();
296+
expect(isResolved(r)).toBe(false);
294297
tick();
295298
expect(resolvedValue(r)).toEqual({ fun: 42 });
296299
expect(fun).toHaveBeenCalled();
@@ -304,7 +307,7 @@ describe('$resolve', function () {
304307
const fun = jasmine.createSpy('fun').and.returnValue(d.promise);
305308
const r = $r.resolve({ fun: ['$resolve', fun] });
306309
tick();
307-
expect(r).not.toBeResolved();
310+
expect(isResolved(r)).toBe(false);
308311
d.resolve('async');
309312
tick();
310313
expect(resolvedValue(r)).toEqual({ fun: 'async' });
@@ -333,19 +336,19 @@ describe('$resolve', function () {
333336

334337
const r = $r.resolve({ a: ['b', 'c', a], b: ['c', b], c: [c] });
335338
tick();
336-
expect(r).not.toBeResolved();
339+
expect(isResolved(r)).toBe(false);
337340
expect(a).not.toHaveBeenCalled();
338341
expect(b).not.toHaveBeenCalled();
339342
expect(c).toHaveBeenCalled();
340343
cd.resolve('cc');
341344
tick();
342-
expect(r).not.toBeResolved();
345+
expect(isResolved(r)).toBe(false);
343346
expect(a).not.toHaveBeenCalled();
344347
expect(b).toHaveBeenCalled();
345348
expect(b.calls.mostRecent().args).toEqual(['cc']);
346349
bd.resolve('bb');
347350
tick();
348-
expect(r).not.toBeResolved();
351+
expect(isResolved(r)).toBe(false);
349352
expect(a).toHaveBeenCalled();
350353
expect(a.calls.mostRecent().args).toEqual(['bb', 'cc']);
351354
ad.resolve('aa');
@@ -418,7 +421,7 @@ describe('$resolve', function () {
418421
r
419422
);
420423
tick();
421-
expect(r).toBeResolved();
424+
expect(isResolved(r)).toBe(true);
422425
expect(resolvedValue(s)).toEqual({ fun: true, games: true });
423426
});
424427

@@ -561,8 +564,8 @@ describe('$resolve', function () {
561564
const s = $r.resolve({ b: [b] }, {}, r);
562565
bd.resolve('bbb');
563566
tick();
564-
expect(r).not.toBeResolved();
565-
expect(s).not.toBeResolved();
567+
expect(isResolved(r)).toBe(false);
568+
expect(isResolved(s)).toBe(false);
566569
cd.resolve('ccc');
567570
tick();
568571
expect(resolvedValue(r)).toEqual({ c: 'ccc' });
@@ -571,9 +574,9 @@ describe('$resolve', function () {
571574

572575
it('rejects missing dependencies but does not fail synchronously', function () {
573576
const r = $r.resolve({ fun: function (invalid) {} });
574-
expect(r).not.toBeResolved();
577+
expect(isResolved(r)).toBe(false);
575578
tick();
576-
expect(resolvedError(r)).toMatch(/unknown provider/i);
579+
expect(resolvedError(r).toString()).toMatch(/unknown provider/i);
577580
});
578581

579582
it('propagates exceptions thrown by the functions as a rejection', function () {
@@ -582,7 +585,7 @@ describe('$resolve', function () {
582585
throw 'i want cake';
583586
},
584587
});
585-
expect(r).not.toBeResolved();
588+
expect(isResolved(r)).toBe(false);
586589
tick();
587590
expect(resolvedError(r)).toBe('i want cake');
588591
});
@@ -614,7 +617,7 @@ describe('$resolve', function () {
614617
},
615618
});
616619
tick();
617-
expect(r).toBeResolved();
620+
expect(isResolved(r)).toBe(true);
618621
const a = jasmine.createSpy('a');
619622
const s = $r.resolve({ a: [a] }, {}, r);
620623
tick();
@@ -707,14 +710,14 @@ describe('Integration: Resolvables system', () => {
707710
$transitions.onStart({ to: 'J' }, ($transition$) => {
708711
const ctx = new ResolveContext($transition$.treeChanges().to);
709712
return invokeLater(function (_J) {}, ctx).then(function () {
710-
expect(counts._J).toEqualData(1);
713+
expect(counts._J).toEqual(1);
711714
return $state.target('K');
712715
});
713716
});
714717
$state.go('J');
715718
$rootScope.$digest();
716719
expect($state.current.name).toBe('K');
717-
expect(counts._J).toEqualData(1);
720+
expect(counts._J).toEqual(1);
718721
});
719722

720723
// Test for https://github.com/angular-ui/ui-router/issues/3546

0 commit comments

Comments
 (0)