Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate from Jest to Vitest, update ESLint config and upgrade Execa #821

Merged
merged 11 commits into from
Sep 22, 2023
36 changes: 30 additions & 6 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,41 @@
/* eslint-env node */
module.exports = {
root: true,
extends: ['@storybook/eslint-config-storybook'],
rules: {
'no-use-before-define': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'eslint-comments/disable-enable-pair': 'off',
'import/no-extraneous-dependencies': 'off',
env: {
browser: true,
node: true,
},
extends: [
'eslint:recommended',
'prettier',
'plugin:@typescript-eslint/recommended',
'plugin:import/recommended',
'plugin:import/typescript',
'plugin:json/recommended',
'plugin:react/recommended',
],
parser: '@typescript-eslint/parser',
parserOptions: {
project: ['./tsconfig.eslint.json'],
extraFileExtensions: ['.cjs'],
},
rules: {
'@typescript-eslint/no-empty-function': ['error', { allow: ['arrowFunctions'] }],
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-unused-vars': [
'error',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
ignoreRestSiblings: true,
},
],
},
settings: {
react: {
version: 'detect',
},
},
overrides: [
{
files: ['*.json', 'isChromatic.mjs', 'isChromatic.js', 'isChromatic.cjs', '.eslintrc.cjs'],
Expand Down
3 changes: 1 addition & 2 deletions .storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ module.exports = {
core: {
builder: 'webpack5',
},
webpackFinal: async (config, { configType }) => {
// eslint-disable-next-line no-param-reassign
webpackFinal: async (config) => {
config.resolve = {
...config.resolve,
fallback: {
Expand Down
1 change: 0 additions & 1 deletion .storybook/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ export const decorators = [
(storyFn, { kind }) => {
if (kind.startsWith('CLI/')) {
document.body.style.backgroundColor = '#16242c';
// eslint-disable-next-line react/no-danger
return <code style={style} dangerouslySetInnerHTML={{ __html: ansiHTML(storyFn()) }} />;
}
document.body.style.backgroundColor = 'paleturquoise';
Expand Down
2 changes: 1 addition & 1 deletion bin-src/register.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env node
/* eslint-disable global-require */
/* eslint-disable @typescript-eslint/no-var-requires */

require('dotenv').config();

Expand Down
1 change: 1 addition & 0 deletions bin-src/trace.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { execSync } from 'child_process';
import { describe, expect, it } from 'vitest';

import {
rootDirNote,
Expand Down
2 changes: 1 addition & 1 deletion bin-src/trim-stats-file.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import mockfs from 'mock-fs';
import { afterEach, describe, expect, it } from 'vitest';

import { readStatsFile } from '../node-src/tasks/read-stats-file';
// eslint-disable-next-line jest/no-mocks-import
import * as trimmedFile from './__mocks__/previewStatsJson/preview-stats.trimmed.json';

mockfs({
Expand Down
1 change: 0 additions & 1 deletion bin-src/trim-stats-file.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable no-console */
import { outputFile } from 'fs-extra';
import { readStatsFile } from '../node-src/tasks/read-stats-file';

Expand Down
9 changes: 5 additions & 4 deletions isChromatic.test.js → isChromatic.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-env browser */
import { describe, expect, it } from 'vitest';

const isChromatic = require('./isChromatic');
import isChromatic from './isChromatic';

describe('with window arg', () => {
it('returns false', () => {
Expand All @@ -10,7 +11,7 @@ describe('with window arg', () => {
userAgent: 'Chrome',
},
location: new URL('https://example.com'),
})
} as any as Window)
).toBe(false);
});

Expand All @@ -21,7 +22,7 @@ describe('with window arg', () => {
userAgent: 'Chrome',
},
location: new URL('https://example.com?chromatic=true'),
})
} as any as Window)
).toBe(true);
});

Expand All @@ -32,7 +33,7 @@ describe('with window arg', () => {
userAgent: 'Chromium(Chromatic)',
},
location: new URL('https://example.com'),
})
} as any as Window)
).toBe(true);
});
});
6 changes: 0 additions & 6 deletions jest.config.js

This file was deleted.

6 changes: 4 additions & 2 deletions node-src/git/findAncestorBuildWithCommit.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { beforeEach, describe, expect, it, vi } from 'vitest';

import {
AncestorBuildsQueryResult,
findAncestorBuildWithCommit,
} from './findAncestorBuildWithCommit';

jest.mock('./git', () => ({
vi.mock('./git', () => ({
commitExists: (hash) => hash.match(/exists/),
}));

Expand All @@ -19,7 +21,7 @@ const makeResult = (ancestorBuilds: Build[]): AncestorBuildsQueryResult => ({
});

describe('findAncestorBuildWithCommit', () => {
const client = { runQuery: jest.fn() } as any;
const client = { runQuery: vi.fn() } as any;
beforeEach(() => {
client.runQuery.mockReset();
});
Expand Down
4 changes: 1 addition & 3 deletions node-src/git/findAncestorBuildWithCommit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,21 +54,19 @@ export async function findAncestorBuildWithCommit(
): Promise<AncestorBuildsQueryResult['app']['build']['ancestorBuilds'][0] | null> {
let skip = 0;
while (skip < limit) {
// eslint-disable-next-line no-await-in-loop
const { app } = await client.runQuery<AncestorBuildsQueryResult>(AncestorBuildsQuery, {
buildNumber,
skip,
limit: Math.min(page, limit - skip),
});

// eslint-disable-next-line no-await-in-loop
const results = await Promise.all(
app.build.ancestorBuilds.map(async (build) => {
const exists = await commitExists(build.commit);
return [build, exists] as const;
})
);
const result = results.find(([build, exists]) => exists);
const result = results.find(([_, exists]) => exists);

if (result) return result[0];

Expand Down
6 changes: 4 additions & 2 deletions node-src/git/getChangedFilesWithReplacement.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { beforeEach, describe, expect, it, vi } from 'vitest';

import { getChangedFilesWithReplacement } from './getChangedFilesWithReplacement';
import TestLogger from '../lib/testLogger';

jest.mock('./git', () => ({
vi.mock('./git', () => ({
getChangedFiles: (hash) => {
if (hash.match(/exists/)) return ['changed', 'files'];
throw new Error(`fatal: bad object ${hash}`);
Expand All @@ -10,7 +12,7 @@ jest.mock('./git', () => ({
}));

describe('getChangedFilesWithReplacements', () => {
const client = { runQuery: jest.fn() } as any;
const client = { runQuery: vi.fn() } as any;
beforeEach(() => {
client.runQuery.mockReset();
});
Expand Down
14 changes: 8 additions & 6 deletions node-src/git/getCommitAndBranch.test.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import envCi from 'env-ci';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';

import * as git from './git';

import getCommitAndBranch from './getCommitAndBranch';

jest.mock('env-ci');
jest.mock('./git');
vi.mock('env-ci');
vi.mock('./git');

const getBranch = <jest.MockedFunction<typeof git.getBranch>>git.getBranch;
const getCommit = <jest.MockedFunction<typeof git.getCommit>>git.getCommit;
const hasPreviousCommit = <jest.MockedFunction<typeof git.hasPreviousCommit>>git.hasPreviousCommit;
const getBranch = vi.mocked(git.getBranch);
const getCommit = vi.mocked(git.getCommit);
const hasPreviousCommit = vi.mocked(git.hasPreviousCommit);

const log = { info: jest.fn(), warn: jest.fn(), debug: jest.fn() };
const log = { info: vi.fn(), warn: vi.fn(), debug: vi.fn() };

const processEnv = process.env;
beforeEach(() => {
Expand Down
18 changes: 7 additions & 11 deletions node-src/git/getParentCommits.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/* eslint-disable jest/expect-expect */
import { exec } from 'child_process';
import process from 'process';
import { promisify } from 'util';
import tmp from 'tmp-promise';
import { promisify } from 'util';
import { beforeAll, describe, expect, it, vi } from 'vitest';

import { getCommit } from './git';
import { getParentCommits } from './getParentCommits';
Expand All @@ -15,10 +15,6 @@ import simpleLoopDescription from './mocks/simple-loop';
import threeParentsDescription from './mocks/three-parents';
import twoRootsDescription from './mocks/two-roots';

// Bumping up the Jest timeout for this file because it is timing out sometimes
// I think this just a bit of a slow file due to git stuff, takes ~2-3s on my computer.
jest.setTimeout(30 * 1000);

const descriptions = {
simpleLoop: simpleLoopDescription,
longLine: longLineDescription,
Expand Down Expand Up @@ -63,7 +59,7 @@ async function checkoutCommit(name, branch, { dirname, runGit, commitMap }) {
return commitMap[name].hash;
}

const log = { debug: jest.fn() };
const log = { debug: vi.fn() };
const options = {};

// This is built in from TypeScript 4.5
Expand All @@ -76,16 +72,16 @@ interface Repository {
}

const repositories: Record<string, Repository> = {};
beforeAll(async () =>
Promise.all(
beforeAll(async () => {
await Promise.all(
Object.keys(descriptions).map(async (key) => {
const dirname = (await tmp.dir({ unsafeCleanup: true, prefix: `chromatictest-` })).path;
const runGit = makeRunGit(dirname);
const commitMap = await generateGitRepository(runGit, descriptions[key]);
repositories[key] = { dirname, runGit, commitMap };
})
)
);
);
});

describe('getParentCommits', () => {
it('returns no baseline when there are no builds for the app', async () => {
Expand Down
13 changes: 8 additions & 5 deletions node-src/git/git.test.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
import execa from 'execa';
import { execaCommand } from 'execa';
import { describe, expect, it, vi } from 'vitest';

import { getSlug } from './git';

const execaCommand = jest.spyOn(execa, 'command');
vi.mock('execa');

const command = vi.mocked(execaCommand);

describe('getSlug', () => {
it('returns the slug portion of the git url', async () => {
execaCommand.mockImplementation(
command.mockImplementation(
() => Promise.resolve({ all: '[email protected]:chromaui/chromatic-cli.git' }) as any
);
expect(await getSlug()).toBe('chromaui/chromatic-cli');

execaCommand.mockImplementation(
command.mockImplementation(
() => Promise.resolve({ all: 'https://github.com/chromaui/chromatic-cli' }) as any
);
expect(await getSlug()).toBe('chromaui/chromatic-cli');

execaCommand.mockImplementation(
command.mockImplementation(
() => Promise.resolve({ all: 'https://gitlab.com/foo/bar.baz.git' }) as any
);
expect(await getSlug()).toBe('foo/bar.baz');
Expand Down
4 changes: 2 additions & 2 deletions node-src/git/git.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import execa from 'execa';
import { execaCommand } from 'execa';
import { EOL } from 'os';
import pLimit from 'p-limit';
import { file as tmpFile } from 'tmp-promise';
Expand All @@ -13,7 +13,7 @@ const newline = /\r\n|\r|\n/; // Git may return \n even on Windows, so we can't

export async function execGitCommand(command: string) {
try {
const { all } = await execa.command(command, {
const { all } = await execaCommand(command, {
env: { LANG: 'C', LC_ALL: 'C' }, // make sure we're speaking English
timeout: 20000, // 20 seconds
all: true, // interleave stdout and stderr
Expand Down
2 changes: 1 addition & 1 deletion node-src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export async function run({
}): Promise<Output> {
const sessionId = uuid();
const env = getEnv();
const log = createLogger(env);
const log = createLogger();

const pkgInfo = await readPkgUp({ cwd: process.cwd() });
if (!pkgInfo) {
Expand Down
2 changes: 0 additions & 2 deletions node-src/io/GraphQLClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,7 @@ export default class GraphQLClient {
// Throw an error to retry the query if it's safe to do so, otherwise bail
if (err.extensions && err.extensions.code === RETRYABLE_ERROR_CODE) throw err;

// eslint-disable-next-line no-param-reassign
err.name = err.name || 'GraphQLError';
// eslint-disable-next-line no-param-reassign
err.at = `${err.path.join('.')} ${err.locations
.map((l) => `${l.line}:${l.column}`)
.join(', ')}`;
Expand Down
1 change: 0 additions & 1 deletion node-src/lib/NonTTYRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ export default class NonTTYRenderer {
}

render() {
// eslint-disable-next-line no-restricted-syntax
for (const task of this.tasks) {
let lastData;
task.subscribe((event) => {
Expand Down
3 changes: 1 addition & 2 deletions node-src/lib/compareBaseline.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import path from 'path';
import { describe, expect, it } from 'vitest';

import { compareBaseline } from './compareBaseline';
import { getDependencies } from './getDependencies';
import TestLogger from './testLogger';

jest.setTimeout(30 * 1000);

const getContext: any = (baselineCommits: string[]) => ({
log: new TestLogger(),
git: { baselineCommits },
Expand Down
1 change: 0 additions & 1 deletion node-src/lib/compareBaseline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ export const compareBaseline = async (
const baselineDependencies = await getDependencies(ctx, baselineConfig);

ctx.log.debug({ ...baselineConfig, baselineDependencies }, `Found baseline dependencies`);
// eslint-disable-next-line no-restricted-syntax
for (const dependency of xor(baselineDependencies, headDependencies)) {
// Strip the version number so we get a set of package names.
changedDependencyNames.add(dependency.split('@@')[0]);
Expand Down
8 changes: 5 additions & 3 deletions node-src/lib/compress.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { existsSync } from 'fs';
import mockFs from 'mock-fs';
import fs from 'fs-extra';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';

import makeZipFile from './compress';
import TestLogger from './testLogger';

beforeEach(() => {
jest.clearAllMocks();
vi.clearAllMocks();
});

afterEach(() => {
Expand All @@ -27,7 +29,7 @@ describe('makeZipFile', () => {

const result = await makeZipFile(testContext);

expect(fs.existsSync(result.path)).toBeTruthy();
expect(existsSync(result.path)).toBeTruthy();
expect(result.size).toBeGreaterThan(0);
});

Expand Down
Loading
Loading