testUtils.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /**
  2. * Copyright (c) 2016-present, Facebook, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the BSD-style license found in the
  6. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. */
  9. /* global expect, describe, it */
  10. 'use strict';
  11. const fs = require('fs');
  12. const path = require('path');
  13. function runInlineTest(module, options, input, expectedOutput) {
  14. // Handle ES6 modules using default export for the transform
  15. const transform = module.default ? module.default : module;
  16. // Jest resets the module registry after each test, so we need to always get
  17. // a fresh copy of jscodeshift on every test run.
  18. let jscodeshift = require('./core');
  19. if (module.parser) {
  20. jscodeshift = jscodeshift.withParser(module.parser);
  21. }
  22. const output = transform(
  23. input,
  24. {
  25. jscodeshift,
  26. stats: () => {},
  27. },
  28. options || {}
  29. );
  30. expect((output || '').trim()).toEqual(expectedOutput.trim());
  31. }
  32. exports.runInlineTest = runInlineTest;
  33. /**
  34. * Utility function to run a jscodeshift script within a unit test. This makes
  35. * several assumptions about the environment:
  36. *
  37. * - `dirName` contains the name of the directory the test is located in. This
  38. * should normally be passed via __dirname.
  39. * - The test should be located in a subdirectory next to the transform itself.
  40. * Commonly tests are located in a directory called __tests__.
  41. * - `transformName` contains the filename of the transform being tested,
  42. * excluding the .js extension.
  43. * - `testFilePrefix` optionally contains the name of the file with the test
  44. * data. If not specified, it defaults to the same value as `transformName`.
  45. * This will be suffixed with ".input.js" for the input file and ".output.js"
  46. * for the expected output. For example, if set to "foo", we will read the
  47. * "foo.input.js" file, pass this to the transform, and expect its output to
  48. * be equal to the contents of "foo.output.js".
  49. * - Test data should be located in a directory called __testfixtures__
  50. * alongside the transform and __tests__ directory.
  51. */
  52. function runTest(dirName, transformName, options, testFilePrefix) {
  53. if (!testFilePrefix) {
  54. testFilePrefix = transformName;
  55. }
  56. const fixtureDir = path.join(dirName, '..', '__testfixtures__');
  57. const inputPath = path.join(fixtureDir, testFilePrefix + '.input.js');
  58. const source = fs.readFileSync(inputPath, 'utf8');
  59. const expectedOutput = fs.readFileSync(
  60. path.join(fixtureDir, testFilePrefix + '.output.js'),
  61. 'utf8'
  62. );
  63. // Assumes transform is one level up from __tests__ directory
  64. const module = require(path.join(dirName, '..', transformName + '.js'));
  65. runInlineTest(module, options, {
  66. path: inputPath,
  67. source
  68. }, expectedOutput);
  69. }
  70. exports.runTest = runTest;
  71. /**
  72. * Handles some boilerplate around defining a simple jest/Jasmine test for a
  73. * jscodeshift transform.
  74. */
  75. function defineTest(dirName, transformName, options, testFilePrefix) {
  76. const testName = testFilePrefix
  77. ? `transforms correctly using "${testFilePrefix}" data`
  78. : 'transforms correctly';
  79. describe(transformName, () => {
  80. it(testName, () => {
  81. runTest(dirName, transformName, options, testFilePrefix);
  82. });
  83. });
  84. }
  85. exports.defineTest = defineTest;
  86. function defineInlineTest(module, options, input, expectedOutput, testName) {
  87. it(testName || 'transforms correctly', () => {
  88. runInlineTest(module, options, {
  89. source: input
  90. }, expectedOutput);
  91. });
  92. }
  93. exports.defineInlineTest = defineInlineTest;