testem 3.18.0 → 3.19.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,5 @@
1
-
2
-
3
- const execa = require('execa');
4
- const log = require('npmlog');
5
- const Bluebird = require('bluebird');
1
+ const execa = require('execa').execa;
2
+ const log = require('../log');
6
3
  const EventEmitter = require('events').EventEmitter;
7
4
 
8
5
  const isWin = require('./is-win')();
@@ -29,6 +26,15 @@ module.exports = class Process extends EventEmitter {
29
26
 
30
27
  this.process.on('close', this.onClose.bind(this));
31
28
  this.process.on('error', this.onError.bind(this));
29
+
30
+ this.process.then(result => {
31
+ if (result.failed && result.exitCode !== 0 &&
32
+ result.shortMessage.includes(isWin ? 'is not recognized' : 'ENOENT'))
33
+ {
34
+ this.onError(new Error(result.shortMessage), this.stdout, this.stderr);
35
+ }
36
+ return Promise.resolve(result);
37
+ });
32
38
  }
33
39
 
34
40
  onKillTimeout() {
@@ -48,7 +54,7 @@ module.exports = class Process extends EventEmitter {
48
54
 
49
55
  onError(error) {
50
56
  log.warn(this.name + ' errored', error);
51
- this.process = null;
57
+ // this.process = null;
52
58
  this.exitCode = 1;
53
59
  this.emit('processError', error, this.stdout, this.stderr);
54
60
  }
@@ -88,14 +94,14 @@ module.exports = class Process extends EventEmitter {
88
94
  if (!this.process) {
89
95
  log.info('Process ' + this.name + ' already killed.');
90
96
 
91
- return Bluebird.resolve(this.exitCode);
97
+ return Promise.resolve(this.exitCode);
92
98
  }
93
99
 
94
100
  sig = sig || 'SIGTERM';
95
101
 
96
102
  let self = this;
97
103
 
98
- return new Bluebird.Promise(resolve => {
104
+ return new Promise(resolve => {
99
105
  self.process.once('close', (code, sig) => {
100
106
  self.process = null;
101
107
  if (self._killTimer) {
@@ -132,14 +138,18 @@ function kill(p, sig) {
132
138
  args.push('/f');
133
139
  }
134
140
 
135
- execa(command, args).then(result => {
141
+ const killProcess = execa(command, args, { reject: false });
142
+
143
+ killProcess.on('error', err => {
144
+ log.error(err);
145
+ });
146
+
147
+ killProcess.then(result => {
136
148
  // Processes without windows can't be killed without /F, detect and force
137
149
  // kill them directly
138
150
  if (result.stderr.indexOf('can only be terminated forcefully') !== -1) {
139
151
  kill(p, 'SIGKILL');
140
152
  }
141
- }).catch(err => {
142
- log.error(err);
143
153
  });
144
154
  } else {
145
155
  p.kill(sig);
@@ -0,0 +1,130 @@
1
+ function fromCallback(fn) {
2
+ return new Promise((resolve, reject) => {
3
+ fn((err, result) => {
4
+ if (err) {
5
+ reject(err);
6
+ } else {
7
+ resolve(result);
8
+ }
9
+ });
10
+ });
11
+ }
12
+
13
+ async function filter(arr, predicate) {
14
+ const results = await Promise.all(arr.map(item => predicate(item)));
15
+ return arr.filter((_, i) => results[i]);
16
+ }
17
+
18
+ function reduce(arr, reducer, initialValue) {
19
+ return arr.reduce(
20
+ (acc, item) => acc.then(a => reducer(a, item)),
21
+ Promise.resolve(initialValue)
22
+ );
23
+ }
24
+
25
+ function each(arr, fn) {
26
+ return arr.reduce(
27
+ (p, item) => p.then(() => fn(item)),
28
+ Promise.resolve()
29
+ ).then(() => arr);
30
+ }
31
+
32
+ class Disposer {
33
+ constructor(promise, cleanup) {
34
+ this.promise = Promise.resolve(promise);
35
+ this.cleanup = cleanup;
36
+ }
37
+ }
38
+
39
+ function disposer(promise, cleanup) {
40
+ return new Disposer(promise, cleanup);
41
+ }
42
+
43
+ async function using(resource, fn) {
44
+ const isDisposer = resource instanceof Disposer;
45
+ const value = await (isDisposer ? resource.promise : resource);
46
+
47
+ let result, rejected = false, error;
48
+
49
+ try {
50
+ result = await fn(value);
51
+ } catch (err) {
52
+ rejected = true;
53
+ error = err;
54
+ }
55
+
56
+ if (isDisposer) {
57
+ const inspection = {
58
+ isRejected: () => rejected,
59
+ reason: () => error,
60
+ };
61
+
62
+ try {
63
+ await resource.cleanup(value, inspection);
64
+ } catch (cleanupErr) {
65
+ if (!rejected) {
66
+ // Callback succeeded but cleanup failed — surface cleanup error
67
+ throw cleanupErr;
68
+ }
69
+ // Both callback and cleanup failed — suppress cleanup error, re-throw original below
70
+ }
71
+ }
72
+
73
+ if (rejected) {
74
+ throw error;
75
+ }
76
+ return result;
77
+ }
78
+
79
+ function mapLimit(arr, concurrency, fn) {
80
+ if (!isFinite(concurrency) || concurrency >= arr.length) {
81
+ return Promise.all(arr.map(fn));
82
+ }
83
+
84
+ let index = 0;
85
+ let results = new Array(arr.length);
86
+
87
+ function next() {
88
+ let i = index++;
89
+ if (i >= arr.length) {
90
+ return Promise.resolve();
91
+ }
92
+
93
+ return Promise.resolve(fn(arr[i])).then(result => {
94
+ results[i] = result;
95
+ return next();
96
+ });
97
+ }
98
+
99
+ let workers = [];
100
+ for (let w = 0; w < Math.min(concurrency, arr.length); w++) {
101
+ workers.push(next());
102
+ }
103
+
104
+ return Promise.all(workers).then(() => results);
105
+ }
106
+
107
+ async function retry(fn, { max_tries = 3 } = {}) {
108
+ let lastErr;
109
+ for (let i = 0; i < max_tries; i++) {
110
+ try {
111
+ return await fn();
112
+ } catch (e) {
113
+ lastErr = e;
114
+ }
115
+ }
116
+ throw lastErr;
117
+ }
118
+
119
+ function delay(ms) {
120
+ return new Promise(resolve => setTimeout(resolve, ms));
121
+ }
122
+
123
+ function asCallback(cb) {
124
+ return [
125
+ result => { if (cb) { cb(null, result); } return result; },
126
+ err => { if (cb) { cb(err); } throw err; }
127
+ ];
128
+ }
129
+
130
+ module.exports = { fromCallback, filter, reduce, each, mapLimit, retry, delay, asCallback, Disposer, disposer, using };
@@ -4,8 +4,6 @@ const fs = require('fs');
4
4
  const path = require('path');
5
5
  const mkdirp = require('mkdirp');
6
6
  const PassThrough = require('stream').PassThrough;
7
- const Bluebird = require('bluebird');
8
-
9
7
  module.exports = class ReportFile {
10
8
  constructor(reportFile) {
11
9
  this.file = reportFile;
@@ -27,7 +25,7 @@ module.exports = class ReportFile {
27
25
  this.outputStream.on('end', finish);
28
26
  this.outputStream.on('error', finish);
29
27
 
30
- this.closePromise = new Bluebird.Promise((resolve, reject) => {
28
+ this.closePromise = new Promise((resolve, reject) => {
31
29
  this.outputStream.on('finish', resolve);
32
30
  this.outputStream.on('error', reject);
33
31
  });
@@ -1,7 +1,7 @@
1
1
 
2
2
 
3
- const Bluebird = require('bluebird');
4
- const log = require('npmlog');
3
+ const { disposer } = require('./promises');
4
+ const log = require('../log');
5
5
 
6
6
  const reporters = require('../reporters');
7
7
  const isa = require('./isa');
@@ -107,7 +107,7 @@ class Reporter {
107
107
  }
108
108
  }
109
109
 
110
- Reporter.with = (app, stdout, path) => Bluebird.try(() => new Reporter(app, stdout, path)).disposer((reporter, promise) => {
110
+ Reporter.with = (app, stdout, path) => disposer(Promise.resolve(new Reporter(app, stdout, path)), (reporter, promise) => {
111
111
  if (promise.isRejected()) {
112
112
  let err = promise.reason();
113
113
 
@@ -1,6 +1,6 @@
1
1
 
2
2
 
3
- const Bluebird = require('bluebird');
3
+ const { disposer } = require('./promises');
4
4
  const EventEmitter = require('events').EventEmitter;
5
5
 
6
6
  class RunTimeout {
@@ -11,7 +11,7 @@ class RunTimeout {
11
11
  static with(timeout) {
12
12
  let runTimeout = new RunTimeout(timeout);
13
13
 
14
- return runTimeout.start().disposer(() => runTimeout.stop());
14
+ return disposer(runTimeout.start(), () => runTimeout.stop());
15
15
  }
16
16
 
17
17
  start() {
@@ -23,7 +23,7 @@ class RunTimeout {
23
23
  }, this.timeout * 1000);
24
24
  }
25
25
 
26
- return Bluebird.resolve(this);
26
+ return Promise.resolve(this);
27
27
  }
28
28
 
29
29
  setTimedOut() {
@@ -39,7 +39,7 @@ class RunTimeout {
39
39
 
40
40
  try(fn) {
41
41
  if (this.timedOut) {
42
- return Bluebird.reject(new Error('Run timed out.'));
42
+ return Promise.reject(new Error('Run timed out.'));
43
43
  }
44
44
 
45
45
  return fn();
@@ -1,17 +1,17 @@
1
1
 
2
2
 
3
- const Bluebird = require('bluebird');
3
+ const { disposer } = require('./promises');
4
4
  const EventEmitter = require('events').EventEmitter;
5
5
 
6
6
  class SignalListeners extends EventEmitter {
7
7
  static with() {
8
8
  let signalListeners = new this();
9
9
 
10
- return signalListeners.add().disposer(() => signalListeners.remove());
10
+ return disposer(signalListeners.add(), () => signalListeners.remove());
11
11
  }
12
12
  }
13
13
 
14
- SignalListeners.prototype.add = Bluebird.method(function() {
14
+ SignalListeners.prototype.add = function() {
15
15
  this._boundSigInterrupt = () => {
16
16
  this.emit('signal', new Error('Received SIGINT signal'));
17
17
  };
@@ -23,16 +23,18 @@ SignalListeners.prototype.add = Bluebird.method(function() {
23
23
  };
24
24
  process.on('SIGTERM', this._boundSigTerminate);
25
25
 
26
- return this;
27
- });
26
+ return Promise.resolve(this);
27
+ };
28
28
 
29
- SignalListeners.prototype.remove = Bluebird.method(function() {
29
+ SignalListeners.prototype.remove = function() {
30
30
  if (this._boundSigInterrupt) {
31
31
  process.removeListener('SIGINT', this._boundSigInterrupt);
32
32
  }
33
33
  if (this._boundSigTerminate) {
34
34
  process.removeListener('SIGTERM', this._boundSigTerminate);
35
35
  }
36
- });
36
+
37
+ return Promise.resolve();
38
+ };
37
39
 
38
40
  module.exports = SignalListeners;
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "unittest",
8
8
  "browser"
9
9
  ],
10
- "version": "3.18.0",
10
+ "version": "3.19.1",
11
11
  "author": "Toby Ho <airportyh@gmail.com>",
12
12
  "repository": {
13
13
  "type": "git",
@@ -23,24 +23,23 @@
23
23
  "dependencies": {
24
24
  "@xmldom/xmldom": "^0.8.0",
25
25
  "backbone": "^1.1.2",
26
- "bluebird": "^3.4.6",
27
26
  "charm": "^1.0.0",
28
27
  "commander": "^2.6.0",
29
28
  "compression": "^1.7.4",
30
- "consolidate": "^0.16.0",
31
- "execa": "^1.0.0",
29
+ "consolidate": "^1.0.4",
30
+ "execa": "^9.6.1",
32
31
  "express": "^4.10.7",
33
32
  "fireworm": "^0.7.2",
34
- "glob": "^7.0.4",
33
+ "glob": "^13.0.6",
35
34
  "http-proxy": "^1.13.1",
36
35
  "js-yaml": "^3.2.5",
37
36
  "lodash": "^4.17.21",
38
37
  "mkdirp": "^3.0.1",
39
38
  "mustache": "^4.2.0",
40
39
  "node-notifier": "^10.0.0",
41
- "npmlog": "^6.0.0",
42
40
  "printf": "^0.6.1",
43
- "rimraf": "^3.0.2",
41
+ "proc-log": "^5.0.0",
42
+ "rimraf": "^6.1.3",
44
43
  "socket.io": "^4.5.4",
45
44
  "spawn-args": "^0.2.0",
46
45
  "styled_string": "0.0.1",
@@ -59,30 +58,30 @@
59
58
  "scripts": {
60
59
  "install:all": "npm install && npm install phantomjs-prebuilt",
61
60
  "test": "mocha tests/*_tests.js tests/**/*_tests.js",
61
+ "test:verbose": "TESTEM_VERBOSE=1 mocha tests/*_tests.js tests/**/*_tests.js",
62
62
  "cover": "cover run ./node_modules/.bin/_mocha tests/*_tests.js tests/**/*_tests.js; cover report html; open cover_html/index.html",
63
63
  "integration": "node ./bin/run-integration.js",
64
64
  "browser-tests": "cd examples/saucelabs/ && ../../testem.js ci -d",
65
65
  "lint": "eslint ."
66
66
  },
67
67
  "devDependencies": {
68
- "bluebird-retry": "^0.11.0",
69
- "browserify": "^17.0.0",
68
+ "@cypress/request": "^3.0.10",
69
+ "@esbuild-plugins/node-modules-polyfill": "^0.2.2",
70
70
  "chai": "^6.2.2",
71
71
  "chai-files": "^1.2.0",
72
72
  "chai-shallow-deep-equal": "^1.4.4",
73
73
  "cheerio": "1.0.0-rc.12",
74
74
  "dirty-chai": "^3.0.0",
75
+ "esbuild": "^0.25.1",
75
76
  "eslint": "^9.39.4",
76
77
  "eslint-plugin-chai-expect": "^3.1.0",
77
78
  "eslint-plugin-mocha": "^11.2.0",
79
+ "fresh-tape": "^5.5.3",
78
80
  "mocha": "^11.7.5",
79
- "request": "^2.51.0",
80
- "saucie": "^3.3.3",
81
- "shelljs": "^0.8.2",
82
- "sinon": "10.0.0",
81
+ "saucie": "^4.0.1",
82
+ "sinon": "^21.0.3",
83
83
  "sinon-chai": "^4.0.1",
84
- "socket.io-client": "^4.1.2",
85
- "tape": "^5.2.2"
84
+ "socket.io-client": "^4.1.2"
86
85
  },
87
86
  "bin": {
88
87
  "testem": "./testem.js"