UNPKG

3.33 kBJavaScriptView Raw
1// bootstrap-tests.js - A tool for updating the test cases in __tests__/fixtures.js
2//
3// 1) Reads __tests__/fixtures.js and looks for a "dynamic part", which should be a list of fields
4// belonging to that file's default export, enclosed in a pair of markers (see "signal" constants
5// below).
6// 2) Imports the same fixtures file and (re-)renders each ReactElement to a static SVG string.
7// 3) On success, overwrites __tests__/fixtures.js with an updated copy.
8//
9// Run with babel-node or using "npm run test:bootstrap".
10
11import path from 'path';
12import { render } from 'enzyme';
13import LineByLineReader from 'line-by-line';
14import reactElementToJsx from 'react-element-to-jsx-string';
15import { writeFileSync } from 'fs';
16import replaceAll from 'replaceall';
17import React from 'react';
18
19const fixturesFile = path.resolve(__dirname, './__tests__/fixtures.js');
20const dynamicPartStartSignal = '// AUTO-GENERATED PART STARTS HERE';
21const dynamicPartEndSignal = '// AUTO-GENERATED PART ENDS HERE';
22
23const fixtures = require(fixturesFile).default;
24
25// Handle recurring data constants
26import { sampleData, sampleData100 } from './__tests__/data';
27const recognizedDataConstants = {
28 sampleData, sampleData100
29};
30const recognizedDataStrings = {};
31for (let dataKey of Object.keys(recognizedDataConstants)) {
32 recognizedDataStrings[dataKey] = markupToOneLine(reactElementToJsx(<div data-value={recognizedDataConstants[dataKey]} />)
33 .replace(/[^{]*\{|\}[^}]*/g, ''));
34}
35
36// Output control
37let outData = '';
38const write = content => { outData += content + '\n'; }
39const save = () => writeFileSync(fixturesFile, outData);
40function writeFixtures() {
41 for (let key of Object.keys(fixtures)) {
42 const jsx = fixtures[key].jsx;
43 const wrapper = render(jsx);
44 let jsxCode = `(${markupToOneLine(reactElementToJsx(jsx))})`;
45 const htmlCode = JSON.stringify(wrapper.html());
46 for (let dataKey of Object.keys(recognizedDataStrings)) {
47 jsxCode = replaceAll(recognizedDataStrings[dataKey], dataKey, jsxCode);
48 }
49 write(`\t${JSON.stringify(key)}: {jsx: ${jsxCode}, svg: ${htmlCode}},`);
50 }
51}
52function markupToOneLine(code) {
53 return code.replace(/\s*[\r\n]\s*/g, ' ').replace(/\s+/g, ' ').replace(/\s*([<>])\s*/g, '$1');
54}
55
56// Input control
57const lr = new LineByLineReader(fixturesFile, {skipEmptyLines: false});
58let inDynamicPart = false, dynamicPartCount = 0, lineCount = 0;
59
60lr.on('line', line => {
61 ++lineCount;
62 if (line === dynamicPartStartSignal) {
63 if (inDynamicPart)
64 throw new LineError('Dynamic part opened again');
65 ++dynamicPartCount;
66 if (dynamicPartCount > 1)
67 throw new LineError('Multiple dynamic parts found');
68 inDynamicPart = true;
69 write(line);
70 try {
71 writeFixtures();
72 } catch(e) {
73 throw new LineError(e);
74 }
75 }
76 else if (line === dynamicPartEndSignal) {
77 if (!inDynamicPart)
78 throw new LineError('Dynamic part closed again');
79 inDynamicPart = false;
80 write(line);
81 }
82 else if (!inDynamicPart)
83 write(line);
84});
85
86lr.on('end', () => {
87 if (inDynamicPart) {
88 throw new LineError('Dynamic part not closed');
89 }
90 if (!dynamicPartCount) {
91 throw new LineError('No dynamic part found in file!');
92 }
93 save();
94});
95
96lr.on('error', function (err) {
97 throw new LineError(err);
98});
99
100class LineError extends Error {
101 constructor(message) {
102 super(`${fixturesFile}:${lineCount}: ${message}`);
103 }
104}
105
\No newline at end of file