mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-24 14:36:59 +02:00
refactor: convert Jest infrastructure to TS (#6910)
This commit is contained in:
parent
1305977098
commit
dc975fecbf
4 changed files with 59 additions and 86 deletions
148
jest/snapshotPathNormalizer.ts
vendored
Normal file
148
jest/snapshotPathNormalizer.ts
vendored
Normal file
|
@ -0,0 +1,148 @@
|
|||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
|
||||
// Forked from https://github.com/tribou/jest-serializer-path/blob/master/lib/index.js
|
||||
// Added some project-specific handlers
|
||||
|
||||
import _ from 'lodash';
|
||||
import {escapePath} from '@docusaurus/utils';
|
||||
import {version} from '@docusaurus/core/package.json';
|
||||
import os from 'os';
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
|
||||
export function print(
|
||||
val: unknown,
|
||||
serialize: (val: unknown) => string,
|
||||
): string {
|
||||
if (val instanceof Error) {
|
||||
const message = normalizePaths(val.message);
|
||||
const error = new Error(message);
|
||||
const allKeys = [
|
||||
...Object.getOwnPropertyNames(error),
|
||||
...Object.keys(val),
|
||||
] as (keyof Error)[];
|
||||
allKeys.forEach((key) => {
|
||||
error[key] = normalizePaths(val[key]) as never;
|
||||
});
|
||||
return serialize(error);
|
||||
} else if (val && typeof val === 'object') {
|
||||
const normalizedValue = _.cloneDeep(val) as Record<string, unknown>;
|
||||
|
||||
Object.keys(normalizedValue).forEach((key) => {
|
||||
normalizedValue[key] = normalizePaths(normalizedValue[key]);
|
||||
});
|
||||
return serialize(normalizedValue);
|
||||
}
|
||||
return serialize(normalizePaths(val));
|
||||
}
|
||||
|
||||
export function test(val: unknown): boolean {
|
||||
return (
|
||||
(typeof val === 'object' &&
|
||||
val &&
|
||||
Object.keys(val).some((key) =>
|
||||
shouldUpdate((val as Record<string, unknown>)[key]),
|
||||
)) ||
|
||||
// val.message is non-enumerable in an error
|
||||
(val instanceof Error && shouldUpdate(val.message)) ||
|
||||
shouldUpdate(val)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize paths across platforms.
|
||||
* Filters must be ran on all platforms to guard against false positives
|
||||
*/
|
||||
function normalizePaths<T>(value: T): T {
|
||||
if (typeof value !== 'string') {
|
||||
return value;
|
||||
}
|
||||
|
||||
const cwd = process.cwd();
|
||||
const cwdReal = getRealPath(cwd);
|
||||
const tempDir = os.tmpdir();
|
||||
const tempDirReal = getRealPath(tempDir);
|
||||
const homeDir = os.homedir();
|
||||
const homeDirReal = getRealPath(homeDir);
|
||||
|
||||
const homeRelativeToTemp = path.relative(tempDir, homeDir);
|
||||
const homeRelativeToTempReal = path.relative(tempDirReal, homeDir);
|
||||
const homeRealRelativeToTempReal = path.relative(tempDirReal, homeDirReal);
|
||||
const homeRealRelativeToTemp = path.relative(tempDir, homeDirReal);
|
||||
|
||||
const runner: ((val: string) => string)[] = [
|
||||
// Replace process.cwd with <PROJECT_ROOT>
|
||||
(val) => val.split(cwdReal).join('<PROJECT_ROOT>'),
|
||||
(val) => val.split(cwd).join('<PROJECT_ROOT>'),
|
||||
|
||||
// Replace home directory with <TEMP_DIR>
|
||||
(val) => val.split(tempDirReal).join('<TEMP_DIR>'),
|
||||
(val) => val.split(tempDir).join('<TEMP_DIR>'),
|
||||
|
||||
// Replace home directory with <HOME_DIR>
|
||||
(val) => val.split(homeDirReal).join('<HOME_DIR>'),
|
||||
(val) => val.split(homeDir).join('<HOME_DIR>'),
|
||||
|
||||
// handle HOME_DIR nested inside TEMP_DIR
|
||||
(val) =>
|
||||
val
|
||||
.split(`<TEMP_DIR>${path.sep + homeRelativeToTemp}`)
|
||||
.join('<HOME_DIR>'),
|
||||
(val) =>
|
||||
val
|
||||
.split(`<TEMP_DIR>${path.sep + homeRelativeToTempReal}`)
|
||||
.join('<HOME_DIR>'), // untested
|
||||
(val) =>
|
||||
val
|
||||
.split(`<TEMP_DIR>${path.sep + homeRealRelativeToTempReal}`)
|
||||
.join('<HOME_DIR>'),
|
||||
(val) =>
|
||||
val
|
||||
.split(`<TEMP_DIR>${path.sep + homeRealRelativeToTemp}`)
|
||||
.join('<HOME_DIR>'), // untested
|
||||
|
||||
// Replace the Docusaurus version with a stub
|
||||
(val) => val.split(version).join('<CURRENT_VERSION>'),
|
||||
|
||||
// In case the CWD is escaped
|
||||
(val) => val.split(escapePath(cwd)).join('<PROJECT_ROOT>'),
|
||||
|
||||
// Remove win32 drive letters, C:\ -> \
|
||||
(val) => val.replace(/[a-zA-Z]:\\/g, '\\'),
|
||||
|
||||
// Remove duplicate backslashes created from escapePath
|
||||
(val) => val.replace(/\\\\/g, '\\'),
|
||||
|
||||
// Convert win32 backslash's to forward slashes, \ -> /;
|
||||
// ignore some that look like escape sequences.
|
||||
(val) => val.replace(/\\(?!")/g, '/'),
|
||||
];
|
||||
|
||||
let result = value as string;
|
||||
runner.forEach((current) => {
|
||||
result = current(result);
|
||||
});
|
||||
|
||||
return result as T & string;
|
||||
}
|
||||
|
||||
function shouldUpdate(value: unknown) {
|
||||
// return true if value is different from normalized value
|
||||
return typeof value === 'string' && normalizePaths(value) !== value;
|
||||
}
|
||||
|
||||
function getRealPath(pathname: string) {
|
||||
try {
|
||||
// eslint-disable-next-line no-restricted-properties
|
||||
const realPath = fs.realpathSync(pathname);
|
||||
return realPath;
|
||||
} catch (error) {
|
||||
return pathname;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue