sync-flow-tests.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. "use strict";
  2. const fs = require("fs");
  3. const flowParser = require("flow-parser");
  4. const globby = require("globby");
  5. const mkdirp = require("mkdirp");
  6. const path = require("path");
  7. const rimraf = require("rimraf");
  8. const DEFAULT_SPEC_CONTENT = "run_spec(__dirname);\n";
  9. const SPEC_FILE_NAME = "jsfmt.spec.js";
  10. const FLOW_TESTS_DIR = path.join(__dirname, "..", "tests", "flow");
  11. function tryParse(file, content) {
  12. const ast = flowParser.parse(content, {
  13. esproposal_class_instance_fields: true,
  14. esproposal_class_static_fields: true,
  15. esproposal_export_star_as: true
  16. });
  17. if (ast.errors.length > 0) {
  18. const line = ast.errors[0].loc.start.line;
  19. const column = ast.errors[0].loc.start.column;
  20. const message = ast.errors[0].message;
  21. return `${file}:${line}:${column}: ${message}`;
  22. }
  23. return null;
  24. }
  25. function syncTests(syncDir) {
  26. const specFiles = globby.sync(
  27. path.join(FLOW_TESTS_DIR, "**", SPEC_FILE_NAME)
  28. );
  29. const filesToCopy = globby.sync(path.join(syncDir, "**/*.js"));
  30. if (filesToCopy.length === 0) {
  31. throw new Error(
  32. [
  33. "Couldn't find any files to copy.",
  34. `Please make sure that \`${syncDir}\` exists and contains the flow tests.`
  35. ].join("\n")
  36. );
  37. }
  38. const specContents = specFiles.reduce((obj, specFile) => {
  39. obj[specFile] = fs.readFileSync(specFile, "utf8");
  40. return obj;
  41. }, {});
  42. const skipped = [];
  43. rimraf.sync(FLOW_TESTS_DIR);
  44. filesToCopy.forEach(file => {
  45. const content = fs.readFileSync(file, "utf8");
  46. const parseError = tryParse(file, content);
  47. if (parseError) {
  48. skipped.push(parseError);
  49. return;
  50. }
  51. const newFile = path.join(FLOW_TESTS_DIR, path.relative(syncDir, file));
  52. const dirname = path.dirname(newFile);
  53. const specFile = path.join(dirname, SPEC_FILE_NAME);
  54. const specContent = specContents[specFile] || DEFAULT_SPEC_CONTENT;
  55. mkdirp.sync(dirname);
  56. fs.writeFileSync(newFile, content);
  57. fs.writeFileSync(specFile, specContent);
  58. });
  59. return skipped;
  60. }
  61. function run(argv) {
  62. if (argv.length !== 1) {
  63. console.error(
  64. [
  65. "You must provide the path to a flow tests directory to sync from!",
  66. "Example: node scripts/sync-flow-tests.js ../flow/tests/"
  67. ].join("\n")
  68. );
  69. return 1;
  70. }
  71. const syncDir = argv[0];
  72. let skipped = [];
  73. try {
  74. skipped = syncTests(syncDir);
  75. } catch (error) {
  76. console.error(`Failed to sync.\n${error}`);
  77. return 1;
  78. }
  79. if (skipped.length > 0) {
  80. console.log(
  81. [
  82. "Some files were skipped due to syntax errors.",
  83. "This is expected since flow tests for handling invalid code,",
  84. "but that's not interesting for Prettier's tests.",
  85. "This is the skipped stuff:",
  86. ""
  87. ]
  88. .concat(skipped, "")
  89. .join("\n")
  90. );
  91. }
  92. console.log(
  93. [
  94. "Done syncing! Now you need to:",
  95. "",
  96. `1. Optional: Adjust some ${SPEC_FILE_NAME} files.`,
  97. "2. Run `jest -u` to create snapshots.",
  98. "3. Run `git diff` to check how tests and snapshots have changed",
  99. "4. Take a look at new snapshots to see if they're OK."
  100. ].join("\n")
  101. );
  102. return 0;
  103. }
  104. if (require.main === module) {
  105. const exitCode = run(process.argv.slice(2));
  106. process.exit(exitCode);
  107. }