Software zum Installieren eines Smart-Mirror Frameworks , zum Nutzen von hochschulrelevanten Informationen, auf einem Raspberry-Pi.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.js 8.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', {
  3. value: true
  4. });
  5. exports.default = void 0;
  6. function _chalk() {
  7. const data = _interopRequireDefault(require('chalk'));
  8. _chalk = function () {
  9. return data;
  10. };
  11. return data;
  12. }
  13. function _emittery() {
  14. const data = _interopRequireDefault(require('emittery'));
  15. _emittery = function () {
  16. return data;
  17. };
  18. return data;
  19. }
  20. function _exit() {
  21. const data = _interopRequireDefault(require('exit'));
  22. _exit = function () {
  23. return data;
  24. };
  25. return data;
  26. }
  27. function _throat() {
  28. const data = _interopRequireDefault(require('throat'));
  29. _throat = function () {
  30. return data;
  31. };
  32. return data;
  33. }
  34. function _jestUtil() {
  35. const data = require('jest-util');
  36. _jestUtil = function () {
  37. return data;
  38. };
  39. return data;
  40. }
  41. function _jestWorker() {
  42. const data = require('jest-worker');
  43. _jestWorker = function () {
  44. return data;
  45. };
  46. return data;
  47. }
  48. var _runTest = _interopRequireDefault(require('./runTest'));
  49. function _interopRequireDefault(obj) {
  50. return obj && obj.__esModule ? obj : {default: obj};
  51. }
  52. function _defineProperty(obj, key, value) {
  53. if (key in obj) {
  54. Object.defineProperty(obj, key, {
  55. value: value,
  56. enumerable: true,
  57. configurable: true,
  58. writable: true
  59. });
  60. } else {
  61. obj[key] = value;
  62. }
  63. return obj;
  64. }
  65. const TEST_WORKER_PATH = require.resolve('./testWorker');
  66. class TestRunner {
  67. constructor(globalConfig, context) {
  68. _defineProperty(this, '_globalConfig', void 0);
  69. _defineProperty(this, '_context', void 0);
  70. _defineProperty(this, 'eventEmitter', new (_emittery().default)());
  71. _defineProperty(
  72. this,
  73. '__PRIVATE_UNSTABLE_API_supportsEventEmitters__',
  74. true
  75. );
  76. _defineProperty(this, 'isSerial', void 0);
  77. this._globalConfig = globalConfig;
  78. this._context = context || {};
  79. }
  80. async runTests(tests, watcher, onStart, onResult, onFailure, options) {
  81. return await (options.serial
  82. ? this._createInBandTestRun(tests, watcher, onStart, onResult, onFailure)
  83. : this._createParallelTestRun(
  84. tests,
  85. watcher,
  86. onStart,
  87. onResult,
  88. onFailure
  89. ));
  90. }
  91. async _createInBandTestRun(tests, watcher, onStart, onResult, onFailure) {
  92. process.env.JEST_WORKER_ID = '1';
  93. const mutex = (0, _throat().default)(1);
  94. return tests.reduce(
  95. (promise, test) =>
  96. mutex(() =>
  97. promise
  98. .then(async () => {
  99. if (watcher.isInterrupted()) {
  100. throw new CancelRun();
  101. }
  102. let sendMessageToJest; // Remove `if(onStart)` in Jest 27
  103. if (onStart) {
  104. await onStart(test);
  105. return (0, _runTest.default)(
  106. test.path,
  107. this._globalConfig,
  108. test.context.config,
  109. test.context.resolver,
  110. this._context,
  111. undefined
  112. );
  113. } else {
  114. // `deepCyclicCopy` used here to avoid mem-leak
  115. sendMessageToJest = (eventName, args) =>
  116. this.eventEmitter.emit(
  117. eventName,
  118. (0, _jestUtil().deepCyclicCopy)(args, {
  119. keepPrototype: false
  120. })
  121. );
  122. await this.eventEmitter.emit('test-file-start', [test]);
  123. return (0, _runTest.default)(
  124. test.path,
  125. this._globalConfig,
  126. test.context.config,
  127. test.context.resolver,
  128. this._context,
  129. sendMessageToJest
  130. );
  131. }
  132. })
  133. .then(result => {
  134. if (onResult) {
  135. return onResult(test, result);
  136. } else {
  137. return this.eventEmitter.emit('test-file-success', [
  138. test,
  139. result
  140. ]);
  141. }
  142. })
  143. .catch(err => {
  144. if (onFailure) {
  145. return onFailure(test, err);
  146. } else {
  147. return this.eventEmitter.emit('test-file-failure', [test, err]);
  148. }
  149. })
  150. ),
  151. Promise.resolve()
  152. );
  153. }
  154. async _createParallelTestRun(tests, watcher, onStart, onResult, onFailure) {
  155. const resolvers = new Map();
  156. for (const test of tests) {
  157. if (!resolvers.has(test.context.config.name)) {
  158. resolvers.set(test.context.config.name, {
  159. config: test.context.config,
  160. serializableModuleMap: test.context.moduleMap.toJSON()
  161. });
  162. }
  163. }
  164. const worker = new (_jestWorker().Worker)(TEST_WORKER_PATH, {
  165. exposedMethods: ['worker'],
  166. forkOptions: {
  167. stdio: 'pipe'
  168. },
  169. maxRetries: 3,
  170. numWorkers: this._globalConfig.maxWorkers,
  171. setupArgs: [
  172. {
  173. serializableResolvers: Array.from(resolvers.values())
  174. }
  175. ]
  176. });
  177. if (worker.getStdout()) worker.getStdout().pipe(process.stdout);
  178. if (worker.getStderr()) worker.getStderr().pipe(process.stderr);
  179. const mutex = (0, _throat().default)(this._globalConfig.maxWorkers); // Send test suites to workers continuously instead of all at once to track
  180. // the start time of individual tests.
  181. const runTestInWorker = test =>
  182. mutex(async () => {
  183. if (watcher.isInterrupted()) {
  184. return Promise.reject();
  185. } // Remove `if(onStart)` in Jest 27
  186. if (onStart) {
  187. await onStart(test);
  188. } else {
  189. await this.eventEmitter.emit('test-file-start', [test]);
  190. }
  191. const promise = worker.worker({
  192. config: test.context.config,
  193. context: {
  194. ...this._context,
  195. changedFiles:
  196. this._context.changedFiles &&
  197. Array.from(this._context.changedFiles),
  198. sourcesRelatedToTestsInChangedFiles:
  199. this._context.sourcesRelatedToTestsInChangedFiles &&
  200. Array.from(this._context.sourcesRelatedToTestsInChangedFiles)
  201. },
  202. globalConfig: this._globalConfig,
  203. path: test.path
  204. });
  205. if (promise.UNSTABLE_onCustomMessage) {
  206. // TODO: Get appropriate type for `onCustomMessage`
  207. promise.UNSTABLE_onCustomMessage(([event, payload]) => {
  208. this.eventEmitter.emit(event, payload);
  209. });
  210. }
  211. return promise;
  212. });
  213. const onError = async (err, test) => {
  214. // Remove `if(onFailure)` in Jest 27
  215. if (onFailure) {
  216. await onFailure(test, err);
  217. } else {
  218. await this.eventEmitter.emit('test-file-failure', [test, err]);
  219. }
  220. if (err.type === 'ProcessTerminatedError') {
  221. console.error(
  222. 'A worker process has quit unexpectedly! ' +
  223. 'Most likely this is an initialization error.'
  224. );
  225. (0, _exit().default)(1);
  226. }
  227. };
  228. const onInterrupt = new Promise((_, reject) => {
  229. watcher.on('change', state => {
  230. if (state.interrupted) {
  231. reject(new CancelRun());
  232. }
  233. });
  234. });
  235. const runAllTests = Promise.all(
  236. tests.map(test =>
  237. runTestInWorker(test)
  238. .then(result => {
  239. if (onResult) {
  240. return onResult(test, result);
  241. } else {
  242. return this.eventEmitter.emit('test-file-success', [
  243. test,
  244. result
  245. ]);
  246. }
  247. })
  248. .catch(error => onError(error, test))
  249. )
  250. );
  251. const cleanup = async () => {
  252. const {forceExited} = await worker.end();
  253. if (forceExited) {
  254. console.error(
  255. _chalk().default.yellow(
  256. 'A worker process has failed to exit gracefully and has been force exited. ' +
  257. 'This is likely caused by tests leaking due to improper teardown. ' +
  258. 'Try running with --detectOpenHandles to find leaks.'
  259. )
  260. );
  261. }
  262. };
  263. return Promise.race([runAllTests, onInterrupt]).then(cleanup, cleanup);
  264. }
  265. on(eventName, listener) {
  266. return this.eventEmitter.on(eventName, listener);
  267. }
  268. }
  269. exports.default = TestRunner;
  270. class CancelRun extends Error {
  271. constructor(message) {
  272. super(message);
  273. this.name = 'CancelRun';
  274. }
  275. }