mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
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:
committed by
Jeremy Elbourn
parent
ac2f78471e
commit
66c25be710
@@ -58,7 +58,7 @@ export function config(config) {
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
autoWatch: false,
|
||||
|
||||
sauceLabs: {
|
||||
testName: 'material2',
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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'], () => {
|
||||
|
||||
@@ -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));
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user