SnapshotResolver.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', {
  3. value: true
  4. });
  5. exports.isSnapshotPath =
  6. exports.buildSnapshotResolver =
  7. exports.EXTENSION =
  8. exports.DOT_EXTENSION =
  9. void 0;
  10. var path = _interopRequireWildcard(require('path'));
  11. var _chalk = _interopRequireDefault(require('chalk'));
  12. var _transform = require('@jest/transform');
  13. var _jestUtil = require('jest-util');
  14. function _interopRequireDefault(obj) {
  15. return obj && obj.__esModule ? obj : {default: obj};
  16. }
  17. function _getRequireWildcardCache(nodeInterop) {
  18. if (typeof WeakMap !== 'function') return null;
  19. var cacheBabelInterop = new WeakMap();
  20. var cacheNodeInterop = new WeakMap();
  21. return (_getRequireWildcardCache = function (nodeInterop) {
  22. return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
  23. })(nodeInterop);
  24. }
  25. function _interopRequireWildcard(obj, nodeInterop) {
  26. if (!nodeInterop && obj && obj.__esModule) {
  27. return obj;
  28. }
  29. if (obj === null || (typeof obj !== 'object' && typeof obj !== 'function')) {
  30. return {default: obj};
  31. }
  32. var cache = _getRequireWildcardCache(nodeInterop);
  33. if (cache && cache.has(obj)) {
  34. return cache.get(obj);
  35. }
  36. var newObj = {};
  37. var hasPropertyDescriptor =
  38. Object.defineProperty && Object.getOwnPropertyDescriptor;
  39. for (var key in obj) {
  40. if (key !== 'default' && Object.prototype.hasOwnProperty.call(obj, key)) {
  41. var desc = hasPropertyDescriptor
  42. ? Object.getOwnPropertyDescriptor(obj, key)
  43. : null;
  44. if (desc && (desc.get || desc.set)) {
  45. Object.defineProperty(newObj, key, desc);
  46. } else {
  47. newObj[key] = obj[key];
  48. }
  49. }
  50. }
  51. newObj.default = obj;
  52. if (cache) {
  53. cache.set(obj, newObj);
  54. }
  55. return newObj;
  56. }
  57. /**
  58. * Copyright (c) Meta Platforms, Inc. and affiliates.
  59. *
  60. * This source code is licensed under the MIT license found in the
  61. * LICENSE file in the root directory of this source tree.
  62. */
  63. const EXTENSION = 'snap';
  64. exports.EXTENSION = EXTENSION;
  65. const DOT_EXTENSION = `.${EXTENSION}`;
  66. exports.DOT_EXTENSION = DOT_EXTENSION;
  67. const isSnapshotPath = path => path.endsWith(DOT_EXTENSION);
  68. exports.isSnapshotPath = isSnapshotPath;
  69. const cache = new Map();
  70. const buildSnapshotResolver = async (
  71. config,
  72. localRequire = (0, _transform.createTranspilingRequire)(config)
  73. ) => {
  74. const key = config.rootDir;
  75. const resolver =
  76. cache.get(key) ??
  77. (await createSnapshotResolver(await localRequire, config.snapshotResolver));
  78. cache.set(key, resolver);
  79. return resolver;
  80. };
  81. exports.buildSnapshotResolver = buildSnapshotResolver;
  82. async function createSnapshotResolver(localRequire, snapshotResolverPath) {
  83. return typeof snapshotResolverPath === 'string'
  84. ? createCustomSnapshotResolver(snapshotResolverPath, localRequire)
  85. : createDefaultSnapshotResolver();
  86. }
  87. function createDefaultSnapshotResolver() {
  88. return {
  89. resolveSnapshotPath: testPath =>
  90. path.join(
  91. path.join(path.dirname(testPath), '__snapshots__'),
  92. path.basename(testPath) + DOT_EXTENSION
  93. ),
  94. resolveTestPath: snapshotPath =>
  95. path.resolve(
  96. path.dirname(snapshotPath),
  97. '..',
  98. path.basename(snapshotPath, DOT_EXTENSION)
  99. ),
  100. testPathForConsistencyCheck: path.posix.join(
  101. 'consistency_check',
  102. '__tests__',
  103. 'example.test.js'
  104. )
  105. };
  106. }
  107. async function createCustomSnapshotResolver(
  108. snapshotResolverPath,
  109. localRequire
  110. ) {
  111. const custom = (0, _jestUtil.interopRequireDefault)(
  112. await localRequire(snapshotResolverPath)
  113. ).default;
  114. const keys = [
  115. ['resolveSnapshotPath', 'function'],
  116. ['resolveTestPath', 'function'],
  117. ['testPathForConsistencyCheck', 'string']
  118. ];
  119. keys.forEach(([propName, requiredType]) => {
  120. if (typeof custom[propName] !== requiredType) {
  121. throw new TypeError(mustImplement(propName, requiredType));
  122. }
  123. });
  124. const customResolver = {
  125. resolveSnapshotPath: testPath =>
  126. custom.resolveSnapshotPath(testPath, DOT_EXTENSION),
  127. resolveTestPath: snapshotPath =>
  128. custom.resolveTestPath(snapshotPath, DOT_EXTENSION),
  129. testPathForConsistencyCheck: custom.testPathForConsistencyCheck
  130. };
  131. verifyConsistentTransformations(customResolver);
  132. return customResolver;
  133. }
  134. function mustImplement(propName, requiredType) {
  135. return `${_chalk.default.bold(
  136. `Custom snapshot resolver must implement a \`${propName}\` as a ${requiredType}.`
  137. )}\nDocumentation: https://jestjs.io/docs/configuration#snapshotresolver-string`;
  138. }
  139. function verifyConsistentTransformations(custom) {
  140. const resolvedSnapshotPath = custom.resolveSnapshotPath(
  141. custom.testPathForConsistencyCheck
  142. );
  143. const resolvedTestPath = custom.resolveTestPath(resolvedSnapshotPath);
  144. if (resolvedTestPath !== custom.testPathForConsistencyCheck) {
  145. throw new Error(
  146. _chalk.default.bold(
  147. `Custom snapshot resolver functions must transform paths consistently, i.e. expects resolveTestPath(resolveSnapshotPath('${custom.testPathForConsistencyCheck}')) === ${resolvedTestPath}`
  148. )
  149. );
  150. }
  151. }