Skip to content

Commit

Permalink
chore(jest-snapshot): type prettier usage properly (#10505)
Browse files Browse the repository at this point in the history
  • Loading branch information
SimenB committed Sep 13, 2020
1 parent 3dd4a95 commit 7f10a9d
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 33 deletions.
4 changes: 2 additions & 2 deletions packages/jest-snapshot/src/State.ts
Expand Up @@ -62,8 +62,8 @@ export default class SnapshotState {
private _snapshotPath: Config.Path;
private _inlineSnapshots: Array<InlineSnapshot>;
private _uncheckedKeys: Set<string>;
private _getBabelTraverse: () => BabelTraverse;
private _getPrettier: () => null | typeof import('prettier');
private _getBabelTraverse: SnapshotStateOptions['getBabelTraverse'];
private _getPrettier: SnapshotStateOptions['getPrettier'];

added: number;
expand: boolean;
Expand Down
55 changes: 24 additions & 31 deletions packages/jest-snapshot/src/inline_snapshots.ts
Expand Up @@ -8,17 +8,19 @@
import * as path from 'path';
import * as fs from 'graceful-fs';
import semver = require('semver');
import {
CallExpression,
file,
templateElement,
templateLiteral,
} from '@babel/types';
import {file, templateElement, templateLiteral} from '@babel/types';
import type {Frame} from 'jest-message-util';
import type {
CustomParser as PrettierCustomParser,
BuiltInParser as PrettierParser,
BuiltInParserName as PrettierParserName,
} from 'prettier';
import type {Config} from '@jest/types';
import type {BabelTraverse, Prettier} from './types';
import {escapeBacktickString} from './utils';

type PrettierParserMap = Record<PrettierParserName, PrettierParser>;

export type InlineSnapshot = {
snapshot: string;
frame: Frame;
Expand Down Expand Up @@ -59,22 +61,21 @@ export function saveInlineSnapshots(
const saveSnapshotsForFile = (
snapshots: Array<InlineSnapshot>,
sourceFilePath: Config.Path,
prettier: any,
prettier: Prettier,
babelTraverse: BabelTraverse,
) => {
const sourceFile = fs.readFileSync(sourceFilePath, 'utf8');

// Resolve project configuration.
// For older versions of Prettier, do not load configuration.
const config = prettier.resolveConfig
? prettier.resolveConfig.sync(sourceFilePath, {
editorconfig: true,
})
? prettier.resolveConfig.sync(sourceFilePath, {editorconfig: true})
: null;

// Detect the parser for the test file.
// For older versions of Prettier, fallback to a simple parser detection.
const inferredParser = prettier.getFileInfo
// @ts-expect-error
const inferredParser: PrettierParserName = prettier.getFileInfo
? prettier.getFileInfo.sync(sourceFilePath).inferredParser
: (config && config.parser) || simpleDetectParser(sourceFilePath);

Expand Down Expand Up @@ -163,8 +164,8 @@ const indent = (snapshot: string, numIndents: number, indentation: string) => {
};

const getAst = (
parsers: Record<string, (text: string) => any>,
inferredParser: string,
parsers: PrettierParserMap,
inferredParser: PrettierParserName,
text: string,
) => {
// Flow uses a 'Program' parent node, babel expects a 'File'.
Expand All @@ -180,13 +181,9 @@ const getAst = (
const createInsertionParser = (
snapshots: Array<InlineSnapshot>,
snapshotMatcherNames: Array<string>,
inferredParser: string,
inferredParser: PrettierParserName,
babelTraverse: BabelTraverse,
) => (
text: string,
parsers: Record<string, (text: string) => any>,
options: any,
) => {
): PrettierCustomParser => (text, parsers, options) => {
// Workaround for https://github.com/prettier/prettier/issues/3150
options.parser = inferredParser;

Expand All @@ -195,7 +192,7 @@ const createInsertionParser = (

const ast = getAst(parsers, inferredParser, text);
babelTraverse(ast, {
CallExpression({node: {arguments: args, callee}}: {node: CallExpression}) {
CallExpression({node: {arguments: args, callee}}) {
if (
callee.type !== 'MemberExpression' ||
callee.property.type !== 'Identifier' ||
Expand Down Expand Up @@ -247,19 +244,15 @@ const createInsertionParser = (
// This parser formats snapshots to the correct indentation.
const createFormattingParser = (
snapshotMatcherNames: Array<string>,
inferredParser: string,
inferredParser: PrettierParserName,
babelTraverse: BabelTraverse,
) => (
text: string,
parsers: Record<string, (text: string) => any>,
options: any,
) => {
): PrettierCustomParser => (text, parsers, options) => {
// Workaround for https://github.com/prettier/prettier/issues/3150
options.parser = inferredParser;

const ast = getAst(parsers, inferredParser, text);
babelTraverse(ast, {
CallExpression({node: {arguments: args, callee}}: {node: CallExpression}) {
CallExpression({node: {arguments: args, callee}}) {
if (
callee.type !== 'MemberExpression' ||
callee.property.type !== 'Identifier' ||
Expand Down Expand Up @@ -288,10 +281,10 @@ const createFormattingParser = (
snapshot,
Math.ceil(
useSpaces
? callee.loc.start.column / options.tabWidth
? callee.loc.start.column / (options.tabWidth ?? 1)
: callee.loc.start.column / 2, // Each tab is 2 characters.
),
useSpaces ? ' '.repeat(options.tabWidth) : '\t',
useSpaces ? ' '.repeat(options.tabWidth ?? 1) : '\t',
);

const replacementNode = templateLiteral(
Expand All @@ -309,10 +302,10 @@ const createFormattingParser = (
return ast;
};

const simpleDetectParser = (filePath: Config.Path) => {
const simpleDetectParser = (filePath: Config.Path): PrettierParserName => {
const extname = path.extname(filePath);
if (/tsx?$/.test(extname)) {
return 'typescript';
}
return 'babylon';
return 'babel';
};

0 comments on commit 7f10a9d

Please sign in to comment.