Skip to content

Commit

Permalink
fail tests on unhandled rejections
Browse files Browse the repository at this point in the history
(cherry picked from commit d564247)
  • Loading branch information
stefanpenner authored and rwjblue committed Mar 13, 2020
1 parent 3c0e529 commit c30ed27
Show file tree
Hide file tree
Showing 13 changed files with 202 additions and 140 deletions.
2 changes: 1 addition & 1 deletion lib/tasks/addon-install.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class AddonInstallTask extends Task {
run(options) {
const chalk = require('chalk');
let ui = this.ui;
let packageNames = options.packages;
let packageNames = options.packages || [];
let blueprintOptions = options.blueprintOptions || {};
let commandOptions = blueprintOptions;

Expand Down
13 changes: 7 additions & 6 deletions lib/tasks/server/middleware/history-support/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

const path = require('path');
const fs = require('fs');
const promiseFinally = require('promise.prototype.finally');
const cleanBaseURL = require('clean-base-url');

class HistorySupportAddon {
Expand Down Expand Up @@ -48,11 +47,13 @@ class HistorySupportAddon {

let baseURL = options.rootURL === '' ? '/' : cleanBaseURL(options.rootURL || options.baseURL);

app.use((req, res, next) => {
const results = watcher.then(results => {
app.use(async (req, _, next) => {
try {
const results = await watcher;
if (this.shouldHandleRequest(req, options)) {
let assetPath = req.path.slice(baseURL.length);
let isFile = false;

try {
isFile = fs.statSync(path.join(results.directory, assetPath)).isFile();
} catch (err) {
Expand All @@ -62,9 +63,9 @@ class HistorySupportAddon {
req.serveUrl = `${baseURL}index.html`;
}
}
});

promiseFinally(Promise.resolve(results), next);
} finally {
next();
}
});
}

Expand Down
75 changes: 42 additions & 33 deletions lib/tasks/server/middleware/tests-server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ const cleanBaseURL = require('clean-base-url');
const path = require('path');
const fs = require('fs');
const logger = require('heimdalljs-logger')('ember-cli:test-server');
const promiseFinally = require('promise.prototype.finally');

class TestsServerAddon {
module.exports = class TestsServerAddon {
/**
* This addon is used to serve the QUnit or Mocha test runner
* at `baseURL + '/tests'`.
Expand All @@ -27,42 +26,52 @@ class TestsServerAddon {
let baseURL = options.rootURL === '' ? '/' : cleanBaseURL(options.rootURL || options.baseURL);
let testsPath = `${baseURL}tests`;

app.use((req, res, next) => {
const results = watcher.then(results => {
let acceptHeaders = req.headers.accept || [];
let hasHTMLHeader = acceptHeaders.indexOf('text/html') !== -1;
let hasWildcardHeader = acceptHeaders.indexOf('*/*') !== -1;
app.use(async (req, _, next) => {
let results;
let watcherSuccess;

let isForTests = req.path.indexOf(testsPath) === 0;
try {
results = await watcher;
watcherSuccess = true;
} catch (e) {
watcherSuccess = false;
// the build has failed, the middleware can safely be skipped.
// build error reporting is handled by:
// 1. watcher production stderr
// 2. watcher-middleware serving the error page
}

logger.info('isForTests: %o', isForTests);
if (watcherSuccess) {
rewriteRequestUrlIfBasePageIsNeeded(req, testsPath, baseURL, results.directory);
}

if (isForTests && (hasHTMLHeader || hasWildcardHeader) && req.method === 'GET') {
let assetPath = req.path.slice(baseURL.length);
let filePath = path.join(results.directory, assetPath);
next();

if (!fs.existsSync(filePath) || !fs.statSync(filePath).isFile()) {
// N.B., `baseURL` will end with a slash as it went through `cleanBaseURL`
let newURL = `${baseURL}tests/index.html`;
if (config.finally) {
config.finally();
}
});
}
};

logger.info(
'url: %s resolved to path: %s which is not a file. Assuming %s instead',
req.path,
filePath,
newURL
);
req.url = newURL;
}
}
});
function rewriteRequestUrlIfBasePageIsNeeded(req, testsPath, baseURL, directory) {
let acceptHeaders = req.headers.accept || [];
let hasHTMLHeader = acceptHeaders.indexOf('text/html') !== -1;
let hasWildcardHeader = acceptHeaders.indexOf('*/*') !== -1;

promiseFinally(promiseFinally(Promise.resolve(results), next), () => {
if (config.finally) {
config.finally();
}
});
});
let isForTests = req.path.indexOf(testsPath) === 0;

logger.info('isForTests: %o', isForTests);

if (isForTests && (hasHTMLHeader || hasWildcardHeader) && req.method === 'GET') {
let assetPath = req.path.slice(baseURL.length);
let filePath = path.join(directory, assetPath);

if (!fs.existsSync(filePath) || !fs.statSync(filePath).isFile()) {
// N.B., `baseURL` will end with a slash as it went through `cleanBaseURL`
let newURL = `${baseURL}tests/index.html`;
logger.info('url: %s resolved to path: %s which is not a file. Assuming %s instead', req.path, filePath, newURL);
req.url = newURL;
}
}
}

module.exports = TestsServerAddon;
7 changes: 5 additions & 2 deletions lib/utilities/open-editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,17 @@ function openEditor(file) {

let editorArgs = openEditor._env().EDITOR.split(' ');
let editor = editorArgs.shift();
let editProcess = openEditor._spawn(editor, [file].concat(editorArgs), { stdio: 'inherit' });
const args = [file].concat(editorArgs);
let editProcess = openEditor._spawn(editor, args, { stdio: 'inherit' });

return new Promise((resolve, reject) => {
editProcess.on('close', code => {
if (code === 0) {
resolve();
} else {
reject();
reject(
new Error(`Spawn('${editor}', [${args.join(',')}]) exited with a non zero error status code: '${code}'`)
);
}
});
});
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"scripts": {
"docs": "yuidoc",
"lint": "eslint . --cache",
"prepack": "yarn docs",
"test": "node tests/runner",
"test:all": "node tests/runner all",
"test:cover": "nyc node tests/runner all",
Expand Down
54 changes: 26 additions & 28 deletions tests/integration/models/blueprint-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const util = require('util');

const EOL = require('os').EOL;
let root = process.cwd();
let tmproot = path.join(root, 'tmp');
let tempRoot = path.join(root, 'tmp');
const SilentError = require('silent-error');
const mkTmpDirIn = require('../../../lib/utilities/mk-tmp-dir-in');
const td = require('testdouble');
Expand Down Expand Up @@ -244,7 +244,7 @@ describe('Blueprint', function() {
let tmpdir;

beforeEach(async function() {
const dir = await mkTmpDirIn(tmproot);
const dir = await mkTmpDirIn(tempRoot);
tmpdir = dir;
blueprint = new InstrumentedBasicBlueprint(basicBlueprint);
ui = new MockUI();
Expand All @@ -258,8 +258,8 @@ describe('Blueprint', function() {
};
});

afterEach(function() {
return remove(tmproot);
afterEach(async function() {
await remove(tempRoot);
});

it('installs basic files', async function() {
Expand Down Expand Up @@ -599,7 +599,7 @@ describe('Blueprint', function() {
}

beforeEach(async function() {
let dir = await mkTmpDirIn(tmproot);
let dir = await mkTmpDirIn(tempRoot);

tmpdir = dir;
blueprint = new BasicBlueprintClass(basicBlueprint);
Expand All @@ -614,8 +614,8 @@ describe('Blueprint', function() {
refreshUI();
});

afterEach(function() {
return remove(tmproot);
afterEach(async function() {
await remove(tempRoot);
});

it('uninstalls basic files', async function() {
Expand All @@ -637,9 +637,7 @@ describe('Blueprint', function() {

expect(actualFiles.length).to.equal(0);

fs.exists(path.join(tmpdir, 'test.txt'), function(exists) {
expect(exists).to.be.false;
});
expect(fs.existsSync(path.join(tmpdir, 'test.txt'))).to.be.false;
});

it("uninstall doesn't remove non-empty folders", async function() {
Expand Down Expand Up @@ -683,7 +681,7 @@ describe('Blueprint', function() {
}

beforeEach(async function() {
let dir = await mkTmpDirIn(tmproot);
let dir = await mkTmpDirIn(tempRoot);
tmpdir = dir;
blueprint = new InstrumentedBasicBlueprint(basicBlueprint);
project = new MockProject();
Expand All @@ -693,7 +691,7 @@ describe('Blueprint', function() {
};
refreshUI();
await blueprint.install(options);
await resetCalled();
resetCalled();
refreshUI();
});

Expand Down Expand Up @@ -752,8 +750,8 @@ describe('Blueprint', function() {
};
});

afterEach(function() {
return remove(tmproot);
afterEach(async function() {
await remove(tempRoot);
});

it('looks up the `npm-install` task', function() {
Expand Down Expand Up @@ -882,8 +880,8 @@ describe('Blueprint', function() {
};
});

afterEach(function() {
return remove(tmproot);
afterEach(async function() {
await remove(tempRoot);
});

it('looks up the `npm-uninstall` task', function() {
Expand Down Expand Up @@ -922,7 +920,7 @@ describe('Blueprint', function() {
});

afterEach(function() {
return remove(tmproot);
return remove(tempRoot);
});

it('looks up the `npm-uninstall` task', function() {
Expand Down Expand Up @@ -1098,8 +1096,8 @@ describe('Blueprint', function() {
};
});

afterEach(function() {
return remove(tmproot);
afterEach(async function() {
await remove(tempRoot);
});

it('passes a packages array for addBowerPackagesToProject', function() {
Expand Down Expand Up @@ -1150,8 +1148,8 @@ describe('Blueprint', function() {
};
});

afterEach(function() {
return remove(tmproot);
afterEach(async function() {
await remove(tempRoot);
});

it('looks up the `bower-install` task', function() {
Expand Down Expand Up @@ -1244,8 +1242,8 @@ describe('Blueprint', function() {
blueprint = new Blueprint(basicBlueprint);
});

afterEach(function() {
return remove(tmproot);
afterEach(async function() {
await remove(tempRoot);
});

it('passes a packages array for addAddonsToProject', function() {
Expand Down Expand Up @@ -1280,8 +1278,8 @@ describe('Blueprint', function() {
};
});

afterEach(function() {
return remove(tmproot);
afterEach(async function() {
await remove(tempRoot);
});

it('looks up the `addon-install` task', function() {
Expand Down Expand Up @@ -1409,7 +1407,7 @@ describe('Blueprint', function() {
let project;

beforeEach(async function() {
let dir = await mkTmpDirIn(tmproot);
let dir = await mkTmpDirIn(tempRoot);
tmpdir = dir;
blueprint = new Blueprint(basicBlueprint);
project = new MockProject();
Expand All @@ -1421,8 +1419,8 @@ describe('Blueprint', function() {
};
});

afterEach(function() {
return remove(tmproot);
afterEach(async function() {
await remove(tempRoot);
});

it('can lookup other Blueprints from the project blueprintLookupPaths', function() {
Expand Down
4 changes: 3 additions & 1 deletion tests/runner.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
'use strict';

// process.on('unhandledRejection', e => {
// throw e;
// });
const captureExit = require('capture-exit');
captureExit.captureExit();

Expand Down
Loading

0 comments on commit c30ed27

Please sign in to comment.