Skip to content
This repository was archived by the owner on Jun 7, 2021. It is now read-only.

Commit 3715442

Browse files
committed
Improved unit testing support
* added the possibility to filter the unit tests to execute (closes #85) * converted the test spec-bundle to typescript (closes #86)
1 parent f67f56c commit 3715442

File tree

7 files changed

+125
-53
lines changed

7 files changed

+125
-53
lines changed

README.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,10 @@ If the above does not work in your case, then check to make sure that the user a
8181
* `npm run start:hmr`: start the development server with Hot Module Replacement enabled
8282
* `npm run build:prod`: build the production version (in /dist)
8383
* `npm run start:prod`: build and serve the production version
84-
* `npm run watch`: start the development webpack build in watch mode
85-
* `npm run watch:prod`: start the production webpack build in watch mode
86-
* `npm run watch:test`: start the test webpack build in watch mode
87-
* `npm run watch:testd`: start the test webpack build in watch mode with debugging enabled
8884
* `npm run profiling`: generate Webpack profiling information under `reports/profiling`. The stats.json file can be uploaded to http://webpack.github.io/analyse/ for analysis
8985
* `npm test`: run unit tests
86+
* `npm run test-subset src/?`: run a subset of the unit tests where ? is either a specific file or a folder. Only tests matching the given path will be executed. The given path MUST start with src/. The file name (if any specified) MUST contain the file extension
87+
* example: `npm run test-subset src/app/tests/sanity_test_spec.ts`
9088
* `npm run e2e`: run end to end tests
9189
* `npm run e2e:live`: run end to end tests in debug mode: https://github.com/angular/protractor/blob/master/docs/debugging.md
9290
* `npm run ci`: run unit tests and integration tests
@@ -100,6 +98,11 @@ If the above does not work in your case, then check to make sure that the user a
10098
* `npm run outdated`: check for outdated dependencies
10199
* `npm run tsc`: run the TypeScript compiler
102100
* `npm run typings-install`: install TypeScript type definitions using typings
101+
* `npm run watch`: start the development webpack build in watch mode
102+
* `npm run watch:prod`: start the production webpack build in watch mode
103+
* `npm run watch:test`: start the test webpack build in watch mode
104+
* `npm run watch:test-subset`: start the test webpack build in watch mode and filter the tests to execute (see npm test)
105+
* `npm run watch:testd`: start the test webpack build in watch mode with debugging enabled
103106
* `npm run webdriver:start`: start the Webdriver Manager
104107
* `npm run webdriver:update`: update Webdriver
105108

config/helpers.js

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ function rootNode(args) {
2222
function prependExt(extensions, args) {
2323
args = args || [];
2424
if (!Array.isArray(args)) { args = [args] }
25-
return extensions.reduce(function(memo, val) {
26-
return memo.concat(val, args.map(function(prefix) {
25+
return extensions.reduce((memo, val) => {
26+
return memo.concat(val, args.map((prefix) => {
2727
return prefix + val;
2828
}));
2929
}, [""]);
@@ -57,10 +57,43 @@ function reverse(arr) {
5757
return arr.reverse();
5858
}
5959

60+
/**
61+
* Method for removing object properties
62+
*/
63+
const removeObjectProperties = (obj, props) => {
64+
for(let i = 0; i < props.length; i++) {
65+
if(obj.hasOwnProperty(props[i])) {
66+
delete obj[props[i]];
67+
}
68+
}
69+
};
70+
71+
/**
72+
* Retrieve the relative path from the config directory to the path argument value (if provided). That path argument can be passed to only execute a subset of the unit tests (see spec-bundle.ts)
73+
* @param args the arguments to look into
74+
* @returns {*} The relative path from this directory (config) to the location pointed at by the path argument value (if provided), an empty string otherwise
75+
*/
76+
function getTestPath(args) {
77+
for (let i = 0; i < args.length; ++i) {
78+
if (args[i] === "--path--") {
79+
let providedPath = args[i+1] || "";
80+
if(!providedPath.toLocaleLowerCase().startsWith("src/")){
81+
throw new Error("If you want to execute a subset of the unit tests, then the path you provide MUST start with 'src/'");
82+
}
83+
//return path.relative(__dirname, providedPath);
84+
// posix style to get the expected path separator
85+
return path.posix.relative(__dirname, providedPath);
86+
}
87+
}
88+
return "";
89+
}
90+
6091
exports.reverse = reverse;
6192
exports.hasProcessFlag = hasProcessFlag;
6293
exports.root = root;
6394
exports.rootNode = rootNode;
6495
exports.prependExt = prependExt;
6596
exports.prepend = prependExt;
6697
exports.packageSort = packageSort;
98+
exports.getTestPath = getTestPath;
99+
exports.removeObjectProperties = removeObjectProperties;

config/karma.conf.js

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,22 @@ module.exports = (config) => {
2020

2121
// list of files to exclude
2222
exclude: [],
23+
24+
client: {
25+
// can be used to pass arguments to tests (see spec-bundle.ts)
26+
args: [{
27+
// path to the subset of the tests to consider (used to filter the unit tests to execute (see spec-bundle.ts)
28+
testPath: helpers.getTestPath(process.argv),
29+
}],
30+
31+
// other client-side config
32+
captureConsole: true,
33+
},
2334

2435
// list of files / patterns to load in the browser
2536
files: [
2637
{
27-
pattern: helpers.root("config/spec-bundle.js"),
38+
pattern: helpers.root("config/spec-bundle.ts"),
2839
watched: false,
2940
}
3041
],
@@ -37,10 +48,10 @@ module.exports = (config) => {
3748
// preprocess matching files before serving them to the browser
3849
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
3950
preprocessors: {
40-
"./config/spec-bundle.js": [
41-
"coverage",
51+
"./config/spec-bundle.ts": [
4252
"webpack",
4353
"sourcemap",
54+
"coverage",
4455
]
4556
},
4657

@@ -96,10 +107,12 @@ module.exports = (config) => {
96107

97108
// enable / disable watching file and executing tests whenever any file changes
98109
autoWatch: true,
110+
99111
// Continuous Integration mode
100112
// if true, Karma captures browsers, runs the tests and exits
101113
singleRun: false,
102114

115+
// JUnit reporter configuration
103116
junitReporter: {
104117
outputDir: helpers.root("reports/coverage/"),
105118
outputFile: "tests-unit/unit.xml",

config/spec-bundle.js

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

config/spec-bundle.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
"use strict";
2+
3+
/*
4+
* When testing with webpack and ES6, we have to do some extra
5+
* things get testing to work right. Because we are gonna write test
6+
* in ES6 to, we have to compile those as well. That's handled in
7+
* karma.conf.js with the karma-webpack plugin. This is the entry
8+
* file for webpack test. Just like webpack will create a bundle.js
9+
* file for our client, when we run test, it well compile and bundle them
10+
* all here! Crazy huh. So we need to do some setup
11+
*/
12+
// declare const require: any;
13+
declare const __karma__: any;
14+
15+
/* tslint:disable */
16+
const args:any = __karma__.config.args;
17+
const opts:any = args[0];
18+
/* tslint:enable */
19+
20+
Error.stackTraceLimit = Infinity;
21+
22+
const path:any = require("path");
23+
// require("phantomjs-polyfill");
24+
// require("ts-node");
25+
require("core-js");
26+
27+
// load the RxJS operators
28+
require("../src/rxjs-operators");
29+
30+
/*
31+
Ok, this is kinda crazy. We can use the the context method on
32+
require that webpack created in order to tell webpack
33+
what files we actually want to require or import.
34+
Below, context will be an function/object with file names as keys.
35+
using that regex we are saying look in ../src then find
36+
any file that ends with spec.ts and get its path. By passing in true
37+
we say do this recursively
38+
*/
39+
const testsContext:any = require.context("../src", true, /\.spec\.ts/);
40+
41+
// do NOT delete any of the code below, it is necessary to load the unit tests
42+
43+
let modules:any = testsContext.keys();
44+
45+
// check if the user specified a specific test path
46+
let testPath:string = opts.testPath;
47+
48+
// if so then we need to filter out test modules that do not match the provided file/folder path
49+
if (testPath) {
50+
testPath = testPath.toLocaleLowerCase();
51+
testPath = testPath.slice(7);
52+
testPath = path.normalize(testPath);
53+
//console.debug("Filtering the tests to execute. Test file paths must start with: ",testPath);
54+
55+
modules = modules.filter((modulePath:any) => {
56+
modulePath = modulePath.toLocaleLowerCase();
57+
modulePath = path.normalize(modulePath);
58+
const shouldBeIncluded:boolean = modulePath.startsWith(testPath);
59+
return shouldBeIncluded;
60+
});
61+
}
62+
63+
// load the tests
64+
modules.forEach(testsContext);

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
"rxjs": "5.0.0-beta.2"
5656
},
5757
"devDependencies": {
58-
"awesome-typescript-loader": "^0.16.2",
58+
"awesome-typescript-loader": "^0.17.0-rc.5",
5959
"autoprefixer": "^6.3.5",
6060
"typescript": "^1.8.9",
6161
"reflect-metadata": "^0.1.3",
@@ -158,6 +158,7 @@
158158
"start:dev": "npm run server",
159159
"start:prod": "npm run server:prod",
160160
"test": "node --max-old-space-size=4096 ./node_modules/karma/bin/karma start",
161+
"test-subset": "npm run test -- --path--",
161162
"tsc": "tsc",
162163
"typings": "typings",
163164
"typings-install": "typings install",
@@ -166,6 +167,7 @@
166167
"watch:dev:hmr": "npm run watch:dev -- --hot",
167168
"watch:prod": "npm run build:prod -- --watch",
168169
"watch:test": "npm run test -- --auto-watch --no-single-run",
170+
"watch:test-subset": "npm run watch:test -- --path--",
169171
"watch:testd": "npm run test -- --auto-watch --no-single-run --browsers=Chrome",
170172
"webdriver": "webdriver-manager",
171173
"webdriver:start": "webdriver-manager start",

tsconfig.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
"pretty": true,
1717
"sourceMap": true,
1818
"outDir": "./.tmp",
19-
"rootDir": "./src",
2019
"moduleResolution": "node",
2120
"listFiles": false
2221
},

0 commit comments

Comments
 (0)