build: avoid multiple refreshes when running unit tests locally (#2162)

Avoids Karma running tests multiple times when developing locally, due to it triggering a test run whenever a new file is written to disk. This change switches to manually spawning a Karma server and then running the tests by depending on Gulp's API instead.
This commit is contained in:
Kristiyan Kostadinov
2016-12-13 21:05:42 +01:00
committed by Jeremy Elbourn
parent ac2f78471e
commit 66c25be710
4 changed files with 50 additions and 39 deletions
+1 -1
View File
@@ -58,7 +58,7 @@ export function config(config) {
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
autoWatch: false,
sauceLabs: {
testName: 'material2',
+2
View File
@@ -18,3 +18,5 @@ export const SASS_AUTOPREFIXER_OPTIONS = {
export const NPM_VENDOR_FILES = [
'@angular', 'core-js/client', 'hammerjs', 'rxjs', 'systemjs/dist', 'zone.js/dist'
];
export const COMPONENTS_DIR = join(SOURCE_ROOT, 'lib');
+9 -19
View File
@@ -1,7 +1,7 @@
import {task, watch} from 'gulp';
import * as path from 'path';
import {SOURCE_ROOT, DIST_COMPONENTS_ROOT, PROJECT_ROOT} from '../constants';
import {DIST_COMPONENTS_ROOT, PROJECT_ROOT, COMPONENTS_DIR} from '../constants';
import {sassBuildTask, tsBuildTask, execNodeTask, copyTask, sequenceTask} from '../task_helpers';
import {writeFileSync} from 'fs';
@@ -17,42 +17,32 @@ const rollup = require('rollup').rollup;
// When `tsconfig-spec.json` is used, we are outputting CommonJS modules. This is used
// for unit tests (karma).
/** Path to the root of the Angular Material component library. */
const componentsDir = path.join(SOURCE_ROOT, 'lib');
/** Path to the tsconfig used for ESM output. */
const tsconfigPath = path.relative(PROJECT_ROOT, path.join(componentsDir, 'tsconfig.json'));
const tsconfigPath = path.relative(PROJECT_ROOT, path.join(COMPONENTS_DIR, 'tsconfig.json'));
/** [Watch task] Rebuilds (ESM output) whenever ts, scss, or html sources change. */
task(':watch:components', () => {
watch(path.join(componentsDir, '**/*.ts'), [':build:components:rollup']);
watch(path.join(componentsDir, '**/*.scss'), [':build:components:rollup']);
watch(path.join(componentsDir, '**/*.html'), [':build:components:rollup']);
});
/** [Watch task] Rebuilds for tests (CJS output) whenever ts, scss, or html sources change. */
task(':watch:components:spec', () => {
watch(path.join(componentsDir, '**/*.ts'), [':build:components:spec']);
watch(path.join(componentsDir, '**/*.scss'), [':build:components:scss']);
watch(path.join(componentsDir, '**/*.html'), [':build:components:assets']);
watch(path.join(COMPONENTS_DIR, '**/*.ts'), [':build:components:rollup']);
watch(path.join(COMPONENTS_DIR, '**/*.scss'), [':build:components:rollup']);
watch(path.join(COMPONENTS_DIR, '**/*.html'), [':build:components:rollup']);
});
/** Builds component typescript only (ESM output). */
task(':build:components:ts', tsBuildTask(componentsDir, 'tsconfig-srcs.json'));
task(':build:components:ts', tsBuildTask(COMPONENTS_DIR, 'tsconfig-srcs.json'));
/** Builds components typescript for tests (CJS output). */
task(':build:components:spec', tsBuildTask(componentsDir));
task(':build:components:spec', tsBuildTask(COMPONENTS_DIR));
/** Copies assets (html, markdown) to build output. */
task(':build:components:assets', copyTask([
path.join(componentsDir, '**/*.!(ts|spec.ts)'),
path.join(COMPONENTS_DIR, '**/*.!(ts|spec.ts)'),
path.join(PROJECT_ROOT, 'README.md'),
], DIST_COMPONENTS_ROOT));
/** Builds scss into css. */
task(':build:components:scss', sassBuildTask(DIST_COMPONENTS_ROOT, componentsDir));
task(':build:components:scss', sassBuildTask(DIST_COMPONENTS_ROOT, COMPONENTS_DIR));
/** Builds the UMD bundle for all of Angular Material. */
task(':build:components:rollup', [':build:components:inline'], () => {
+38 -19
View File
@@ -2,10 +2,11 @@ import gulp = require('gulp');
import path = require('path');
import gulpMerge = require('merge2');
import {PROJECT_ROOT} from '../constants';
import {PROJECT_ROOT, COMPONENTS_DIR} from '../constants';
import {sequenceTask} from '../task_helpers';
const karma = require('karma');
const runSequence = require('run-sequence');
/** Copies deps for unit tests to the build output. */
gulp.task(':build:test:vendor', function() {
@@ -32,28 +33,10 @@ gulp.task(':test:deps', sequenceTask(
]
));
/**
* [Watch task] Build unit test dependencies, and rebuild whenever sources are changed.
* This should only be used when running tests locally.
*/
gulp.task(':test:watch', sequenceTask(':test:deps', ':watch:components:spec'));
/** Build unit test dependencies and then inlines resources (html, css) into the JS output. */
gulp.task(':test:deps:inline', sequenceTask(':test:deps', ':inline-resources'));
/**
* [Watch task] Runs the unit tests, rebuilding and re-testing when sources change.
* Does not inline resources.
*
* This task should be used when running unit tests locally.
*/
gulp.task('test', [':test:watch'], (done: () => void) => {
new karma.Server({
configFile: path.join(PROJECT_ROOT, 'test/karma.conf.js')
}, done).start();
});
/**
* Runs the unit tests once with inlined resources (html, css). Does not watch for changes.
*
@@ -65,3 +48,39 @@ gulp.task('test:single-run', [':test:deps:inline'], (done: () => void) => {
singleRun: true
}, done).start();
});
/**
* [Watch task] Runs the unit tests, rebuilding and re-testing when sources change.
* Does not inline resources. Note that this doesn't use Karma's built-in file
* watching. Due to the way our build process is set up, Karma ends up firing
* it's change detection for every file that is written to disk, which causes
* it to run tests multiple time and makes it hard to follow the console output.
* This approach runs the Karma server and then depends on the Gulp API to tell
* Karma when to run the tests.
*
* This task should be used when running unit tests locally.
*/
gulp.task('test', [':test:deps'], () => {
let patternRoot = path.join(COMPONENTS_DIR, '**/*');
// Configure the Karma server and override the autoWatch and singleRun just in case.
let server = new karma.Server({
configFile: path.join(PROJECT_ROOT, 'test/karma.conf.js'),
autoWatch: false,
singleRun: false
});
// Refreshes Karma's file list and schedules a test run.
let runTests = () => {
server.refreshFiles().then(() => server._injector.get('executor').schedule());
};
// Boot up the test server and run the tests whenever a new browser connects.
server.start();
server.on('browser_register', runTests);
// Watch for file changes, rebuild and run the tests.
gulp.watch(patternRoot + '.ts', () => runSequence(':build:components:spec', runTests));
gulp.watch(patternRoot + '.scss', () => runSequence(':build:components:scss', runTests));
gulp.watch(patternRoot + '.html', () => runSequence(':build:components:assets', runTests));
});