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 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', {
  3. value: true
  4. });
  5. exports.matcherHint =
  6. exports.matcherErrorMessage =
  7. exports.getLabelPrinter =
  8. exports.pluralize =
  9. exports.diff =
  10. exports.printDiffOrStringify =
  11. exports.ensureExpectedIsNonNegativeInteger =
  12. exports.ensureNumbers =
  13. exports.ensureExpectedIsNumber =
  14. exports.ensureActualIsNumber =
  15. exports.ensureNoExpected =
  16. exports.printWithType =
  17. exports.printExpected =
  18. exports.printReceived =
  19. exports.highlightTrailingWhitespace =
  20. exports.stringify =
  21. exports.SUGGEST_TO_CONTAIN_EQUAL =
  22. exports.DIM_COLOR =
  23. exports.BOLD_WEIGHT =
  24. exports.INVERTED_COLOR =
  25. exports.RECEIVED_COLOR =
  26. exports.EXPECTED_COLOR =
  27. void 0;
  28. var _chalk = _interopRequireDefault(require('chalk'));
  29. var _jestDiff = require('jest-diff');
  30. var _jestGetType = require('jest-get-type');
  31. var _prettyFormat = require('pretty-format');
  32. var _Replaceable = _interopRequireDefault(require('./Replaceable'));
  33. var _deepCyclicCopyReplaceable = _interopRequireDefault(
  34. require('./deepCyclicCopyReplaceable')
  35. );
  36. function _interopRequireDefault(obj) {
  37. return obj && obj.__esModule ? obj : {default: obj};
  38. }
  39. /**
  40. * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
  41. *
  42. * This source code is licensed under the MIT license found in the
  43. * LICENSE file in the root directory of this source tree.
  44. */
  45. /* eslint-disable local/ban-types-eventually */
  46. const {
  47. AsymmetricMatcher,
  48. DOMCollection,
  49. DOMElement,
  50. Immutable,
  51. ReactElement,
  52. ReactTestComponent
  53. } = _prettyFormat.plugins;
  54. const PLUGINS = [
  55. ReactTestComponent,
  56. ReactElement,
  57. DOMElement,
  58. DOMCollection,
  59. Immutable,
  60. AsymmetricMatcher
  61. ];
  62. const EXPECTED_COLOR = _chalk.default.green;
  63. exports.EXPECTED_COLOR = EXPECTED_COLOR;
  64. const RECEIVED_COLOR = _chalk.default.red;
  65. exports.RECEIVED_COLOR = RECEIVED_COLOR;
  66. const INVERTED_COLOR = _chalk.default.inverse;
  67. exports.INVERTED_COLOR = INVERTED_COLOR;
  68. const BOLD_WEIGHT = _chalk.default.bold;
  69. exports.BOLD_WEIGHT = BOLD_WEIGHT;
  70. const DIM_COLOR = _chalk.default.dim;
  71. exports.DIM_COLOR = DIM_COLOR;
  72. const MULTILINE_REGEXP = /\n/;
  73. const SPACE_SYMBOL = '\u{00B7}'; // middle dot
  74. const NUMBERS = [
  75. 'zero',
  76. 'one',
  77. 'two',
  78. 'three',
  79. 'four',
  80. 'five',
  81. 'six',
  82. 'seven',
  83. 'eight',
  84. 'nine',
  85. 'ten',
  86. 'eleven',
  87. 'twelve',
  88. 'thirteen'
  89. ];
  90. const SUGGEST_TO_CONTAIN_EQUAL = _chalk.default.dim(
  91. 'Looks like you wanted to test for object/array equality with the stricter `toContain` matcher. You probably need to use `toContainEqual` instead.'
  92. );
  93. exports.SUGGEST_TO_CONTAIN_EQUAL = SUGGEST_TO_CONTAIN_EQUAL;
  94. const stringify = (object, maxDepth = 10) => {
  95. const MAX_LENGTH = 10000;
  96. let result;
  97. try {
  98. result = (0, _prettyFormat.format)(object, {
  99. maxDepth,
  100. min: true,
  101. plugins: PLUGINS
  102. });
  103. } catch {
  104. result = (0, _prettyFormat.format)(object, {
  105. callToJSON: false,
  106. maxDepth,
  107. min: true,
  108. plugins: PLUGINS
  109. });
  110. }
  111. return result.length >= MAX_LENGTH && maxDepth > 1
  112. ? stringify(object, Math.floor(maxDepth / 2))
  113. : result;
  114. };
  115. exports.stringify = stringify;
  116. const highlightTrailingWhitespace = text =>
  117. text.replace(/\s+$/gm, _chalk.default.inverse('$&')); // Instead of inverse highlight which now implies a change,
  118. // replace common spaces with middle dot at the end of any line.
  119. exports.highlightTrailingWhitespace = highlightTrailingWhitespace;
  120. const replaceTrailingSpaces = text =>
  121. text.replace(/\s+$/gm, spaces => SPACE_SYMBOL.repeat(spaces.length));
  122. const printReceived = object =>
  123. RECEIVED_COLOR(replaceTrailingSpaces(stringify(object)));
  124. exports.printReceived = printReceived;
  125. const printExpected = value =>
  126. EXPECTED_COLOR(replaceTrailingSpaces(stringify(value)));
  127. exports.printExpected = printExpected;
  128. const printWithType = (
  129. name,
  130. value,
  131. print // printExpected or printReceived
  132. ) => {
  133. const type = (0, _jestGetType.getType)(value);
  134. const hasType =
  135. type !== 'null' && type !== 'undefined'
  136. ? `${name} has type: ${type}\n`
  137. : '';
  138. const hasValue = `${name} has value: ${print(value)}`;
  139. return hasType + hasValue;
  140. };
  141. exports.printWithType = printWithType;
  142. const ensureNoExpected = (expected, matcherName, options) => {
  143. if (typeof expected !== 'undefined') {
  144. // Prepend maybe not only for backward compatibility.
  145. const matcherString = (options ? '' : '[.not]') + matcherName;
  146. throw new Error(
  147. matcherErrorMessage(
  148. matcherHint(matcherString, undefined, '', options), // Because expected is omitted in hint above,
  149. // expected is black instead of green in message below.
  150. 'this matcher must not have an expected argument',
  151. printWithType('Expected', expected, printExpected)
  152. )
  153. );
  154. }
  155. };
  156. /**
  157. * Ensures that `actual` is of type `number | bigint`
  158. */
  159. exports.ensureNoExpected = ensureNoExpected;
  160. const ensureActualIsNumber = (actual, matcherName, options) => {
  161. if (typeof actual !== 'number' && typeof actual !== 'bigint') {
  162. // Prepend maybe not only for backward compatibility.
  163. const matcherString = (options ? '' : '[.not]') + matcherName;
  164. throw new Error(
  165. matcherErrorMessage(
  166. matcherHint(matcherString, undefined, undefined, options),
  167. `${RECEIVED_COLOR('received')} value must be a number or bigint`,
  168. printWithType('Received', actual, printReceived)
  169. )
  170. );
  171. }
  172. };
  173. /**
  174. * Ensures that `expected` is of type `number | bigint`
  175. */
  176. exports.ensureActualIsNumber = ensureActualIsNumber;
  177. const ensureExpectedIsNumber = (expected, matcherName, options) => {
  178. if (typeof expected !== 'number' && typeof expected !== 'bigint') {
  179. // Prepend maybe not only for backward compatibility.
  180. const matcherString = (options ? '' : '[.not]') + matcherName;
  181. throw new Error(
  182. matcherErrorMessage(
  183. matcherHint(matcherString, undefined, undefined, options),
  184. `${EXPECTED_COLOR('expected')} value must be a number or bigint`,
  185. printWithType('Expected', expected, printExpected)
  186. )
  187. );
  188. }
  189. };
  190. /**
  191. * Ensures that `actual` & `expected` are of type `number | bigint`
  192. */
  193. exports.ensureExpectedIsNumber = ensureExpectedIsNumber;
  194. const ensureNumbers = (actual, expected, matcherName, options) => {
  195. ensureActualIsNumber(actual, matcherName, options);
  196. ensureExpectedIsNumber(expected, matcherName, options);
  197. };
  198. exports.ensureNumbers = ensureNumbers;
  199. const ensureExpectedIsNonNegativeInteger = (expected, matcherName, options) => {
  200. if (
  201. typeof expected !== 'number' ||
  202. !Number.isSafeInteger(expected) ||
  203. expected < 0
  204. ) {
  205. // Prepend maybe not only for backward compatibility.
  206. const matcherString = (options ? '' : '[.not]') + matcherName;
  207. throw new Error(
  208. matcherErrorMessage(
  209. matcherHint(matcherString, undefined, undefined, options),
  210. `${EXPECTED_COLOR('expected')} value must be a non-negative integer`,
  211. printWithType('Expected', expected, printExpected)
  212. )
  213. );
  214. }
  215. }; // Given array of diffs, return concatenated string:
  216. // * include common substrings
  217. // * exclude change substrings which have opposite op
  218. // * include change substrings which have argument op
  219. // with inverse highlight only if there is a common substring
  220. exports.ensureExpectedIsNonNegativeInteger = ensureExpectedIsNonNegativeInteger;
  221. const getCommonAndChangedSubstrings = (diffs, op, hasCommonDiff) =>
  222. diffs.reduce(
  223. (reduced, diff) =>
  224. reduced +
  225. (diff[0] === _jestDiff.DIFF_EQUAL
  226. ? diff[1]
  227. : diff[0] !== op
  228. ? ''
  229. : hasCommonDiff
  230. ? INVERTED_COLOR(diff[1])
  231. : diff[1]),
  232. ''
  233. );
  234. const isLineDiffable = (expected, received) => {
  235. const expectedType = (0, _jestGetType.getType)(expected);
  236. const receivedType = (0, _jestGetType.getType)(received);
  237. if (expectedType !== receivedType) {
  238. return false;
  239. }
  240. if ((0, _jestGetType.isPrimitive)(expected)) {
  241. // Print generic line diff for strings only:
  242. // * if neither string is empty
  243. // * if either string has more than one line
  244. return (
  245. typeof expected === 'string' &&
  246. typeof received === 'string' &&
  247. expected.length !== 0 &&
  248. received.length !== 0 &&
  249. (MULTILINE_REGEXP.test(expected) || MULTILINE_REGEXP.test(received))
  250. );
  251. }
  252. if (
  253. expectedType === 'date' ||
  254. expectedType === 'function' ||
  255. expectedType === 'regexp'
  256. ) {
  257. return false;
  258. }
  259. if (expected instanceof Error && received instanceof Error) {
  260. return false;
  261. }
  262. if (
  263. expectedType === 'object' &&
  264. typeof expected.asymmetricMatch === 'function'
  265. ) {
  266. return false;
  267. }
  268. if (
  269. receivedType === 'object' &&
  270. typeof received.asymmetricMatch === 'function'
  271. ) {
  272. return false;
  273. }
  274. return true;
  275. };
  276. const MAX_DIFF_STRING_LENGTH = 20000;
  277. const printDiffOrStringify = (
  278. expected,
  279. received,
  280. expectedLabel,
  281. receivedLabel,
  282. expand // CLI options: true if `--expand` or false if `--no-expand`
  283. ) => {
  284. if (
  285. typeof expected === 'string' &&
  286. typeof received === 'string' &&
  287. expected.length !== 0 &&
  288. received.length !== 0 &&
  289. expected.length <= MAX_DIFF_STRING_LENGTH &&
  290. received.length <= MAX_DIFF_STRING_LENGTH &&
  291. expected !== received
  292. ) {
  293. if (expected.includes('\n') || received.includes('\n')) {
  294. return (0, _jestDiff.diffStringsUnified)(expected, received, {
  295. aAnnotation: expectedLabel,
  296. bAnnotation: receivedLabel,
  297. changeLineTrailingSpaceColor: _chalk.default.bgYellow,
  298. commonLineTrailingSpaceColor: _chalk.default.bgYellow,
  299. emptyFirstOrLastLinePlaceholder: '↵',
  300. // U+21B5
  301. expand,
  302. includeChangeCounts: true
  303. });
  304. }
  305. const diffs = (0, _jestDiff.diffStringsRaw)(expected, received, true);
  306. const hasCommonDiff = diffs.some(diff => diff[0] === _jestDiff.DIFF_EQUAL);
  307. const printLabel = getLabelPrinter(expectedLabel, receivedLabel);
  308. const expectedLine =
  309. printLabel(expectedLabel) +
  310. printExpected(
  311. getCommonAndChangedSubstrings(
  312. diffs,
  313. _jestDiff.DIFF_DELETE,
  314. hasCommonDiff
  315. )
  316. );
  317. const receivedLine =
  318. printLabel(receivedLabel) +
  319. printReceived(
  320. getCommonAndChangedSubstrings(
  321. diffs,
  322. _jestDiff.DIFF_INSERT,
  323. hasCommonDiff
  324. )
  325. );
  326. return expectedLine + '\n' + receivedLine;
  327. }
  328. if (isLineDiffable(expected, received)) {
  329. const {replacedExpected, replacedReceived} =
  330. replaceMatchedToAsymmetricMatcher(
  331. (0, _deepCyclicCopyReplaceable.default)(expected),
  332. (0, _deepCyclicCopyReplaceable.default)(received),
  333. [],
  334. []
  335. );
  336. const difference = (0, _jestDiff.diff)(replacedExpected, replacedReceived, {
  337. aAnnotation: expectedLabel,
  338. bAnnotation: receivedLabel,
  339. expand,
  340. includeChangeCounts: true
  341. });
  342. if (
  343. typeof difference === 'string' &&
  344. difference.includes('- ' + expectedLabel) &&
  345. difference.includes('+ ' + receivedLabel)
  346. ) {
  347. return difference;
  348. }
  349. }
  350. const printLabel = getLabelPrinter(expectedLabel, receivedLabel);
  351. const expectedLine = printLabel(expectedLabel) + printExpected(expected);
  352. const receivedLine =
  353. printLabel(receivedLabel) +
  354. (stringify(expected) === stringify(received)
  355. ? 'serializes to the same string'
  356. : printReceived(received));
  357. return expectedLine + '\n' + receivedLine;
  358. }; // Sometimes, e.g. when comparing two numbers, the output from jest-diff
  359. // does not contain more information than the `Expected:` / `Received:` already gives.
  360. // In those cases, we do not print a diff to make the output shorter and not redundant.
  361. exports.printDiffOrStringify = printDiffOrStringify;
  362. const shouldPrintDiff = (actual, expected) => {
  363. if (typeof actual === 'number' && typeof expected === 'number') {
  364. return false;
  365. }
  366. if (typeof actual === 'bigint' && typeof expected === 'bigint') {
  367. return false;
  368. }
  369. if (typeof actual === 'boolean' && typeof expected === 'boolean') {
  370. return false;
  371. }
  372. return true;
  373. };
  374. function replaceMatchedToAsymmetricMatcher(
  375. replacedExpected,
  376. replacedReceived,
  377. expectedCycles,
  378. receivedCycles
  379. ) {
  380. if (!_Replaceable.default.isReplaceable(replacedExpected, replacedReceived)) {
  381. return {
  382. replacedExpected,
  383. replacedReceived
  384. };
  385. }
  386. if (
  387. expectedCycles.includes(replacedExpected) ||
  388. receivedCycles.includes(replacedReceived)
  389. ) {
  390. return {
  391. replacedExpected,
  392. replacedReceived
  393. };
  394. }
  395. expectedCycles.push(replacedExpected);
  396. receivedCycles.push(replacedReceived);
  397. const expectedReplaceable = new _Replaceable.default(replacedExpected);
  398. const receivedReplaceable = new _Replaceable.default(replacedReceived);
  399. expectedReplaceable.forEach((expectedValue, key) => {
  400. const receivedValue = receivedReplaceable.get(key);
  401. if (isAsymmetricMatcher(expectedValue)) {
  402. if (expectedValue.asymmetricMatch(receivedValue)) {
  403. receivedReplaceable.set(key, expectedValue);
  404. }
  405. } else if (isAsymmetricMatcher(receivedValue)) {
  406. if (receivedValue.asymmetricMatch(expectedValue)) {
  407. expectedReplaceable.set(key, receivedValue);
  408. }
  409. } else if (
  410. _Replaceable.default.isReplaceable(expectedValue, receivedValue)
  411. ) {
  412. const replaced = replaceMatchedToAsymmetricMatcher(
  413. expectedValue,
  414. receivedValue,
  415. expectedCycles,
  416. receivedCycles
  417. );
  418. expectedReplaceable.set(key, replaced.replacedExpected);
  419. receivedReplaceable.set(key, replaced.replacedReceived);
  420. }
  421. });
  422. return {
  423. replacedExpected: expectedReplaceable.object,
  424. replacedReceived: receivedReplaceable.object
  425. };
  426. }
  427. function isAsymmetricMatcher(data) {
  428. const type = (0, _jestGetType.getType)(data);
  429. return type === 'object' && typeof data.asymmetricMatch === 'function';
  430. }
  431. const diff = (a, b, options) =>
  432. shouldPrintDiff(a, b) ? (0, _jestDiff.diff)(a, b, options) : null;
  433. exports.diff = diff;
  434. const pluralize = (word, count) =>
  435. (NUMBERS[count] || count) + ' ' + word + (count === 1 ? '' : 's'); // To display lines of labeled values as two columns with monospace alignment:
  436. // given the strings which will describe the values,
  437. // return function which given each string, returns the label:
  438. // string, colon, space, and enough padding spaces to align the value.
  439. exports.pluralize = pluralize;
  440. const getLabelPrinter = (...strings) => {
  441. const maxLength = strings.reduce(
  442. (max, string) => (string.length > max ? string.length : max),
  443. 0
  444. );
  445. return string => `${string}: ${' '.repeat(maxLength - string.length)}`;
  446. };
  447. exports.getLabelPrinter = getLabelPrinter;
  448. const matcherErrorMessage = (
  449. hint,
  450. generic,
  451. specific // incorrect value returned from call to printWithType
  452. ) =>
  453. `${hint}\n\n${_chalk.default.bold('Matcher error')}: ${generic}${
  454. typeof specific === 'string' ? '\n\n' + specific : ''
  455. }`; // Display assertion for the report when a test fails.
  456. // New format: rejects/resolves, not, and matcher name have black color
  457. // Old format: matcher name has dim color
  458. exports.matcherErrorMessage = matcherErrorMessage;
  459. const matcherHint = (
  460. matcherName,
  461. received = 'received',
  462. expected = 'expected',
  463. options = {}
  464. ) => {
  465. const {
  466. comment = '',
  467. expectedColor = EXPECTED_COLOR,
  468. isDirectExpectCall = false,
  469. // seems redundant with received === ''
  470. isNot = false,
  471. promise = '',
  472. receivedColor = RECEIVED_COLOR,
  473. secondArgument = '',
  474. secondArgumentColor = EXPECTED_COLOR
  475. } = options;
  476. let hint = '';
  477. let dimString = 'expect'; // concatenate adjacent dim substrings
  478. if (!isDirectExpectCall && received !== '') {
  479. hint += DIM_COLOR(dimString + '(') + receivedColor(received);
  480. dimString = ')';
  481. }
  482. if (promise !== '') {
  483. hint += DIM_COLOR(dimString + '.') + promise;
  484. dimString = '';
  485. }
  486. if (isNot) {
  487. hint += DIM_COLOR(dimString + '.') + 'not';
  488. dimString = '';
  489. }
  490. if (matcherName.includes('.')) {
  491. // Old format: for backward compatibility,
  492. // especially without promise or isNot options
  493. dimString += matcherName;
  494. } else {
  495. // New format: omit period from matcherName arg
  496. hint += DIM_COLOR(dimString + '.') + matcherName;
  497. dimString = '';
  498. }
  499. if (expected === '') {
  500. dimString += '()';
  501. } else {
  502. hint += DIM_COLOR(dimString + '(') + expectedColor(expected);
  503. if (secondArgument) {
  504. hint += DIM_COLOR(', ') + secondArgumentColor(secondArgument);
  505. }
  506. dimString = ')';
  507. }
  508. if (comment !== '') {
  509. dimString += ' // ' + comment;
  510. }
  511. if (dimString !== '') {
  512. hint += DIM_COLOR(dimString);
  513. }
  514. return hint;
  515. };
  516. exports.matcherHint = matcherHint;