jest icon indicating copy to clipboard operation
jest copied to clipboard

fix: execute a global hook for all hooking projects

Open Aetherall opened this issue 1 year ago • 3 comments

Summary

Hi :)

When specifying a global hook in a multi-project setup, the hook function gets the project configuration passed in second parameter. Its very handy to factorize the global hook definition.

Example of the factorized hook i am using ( long and not interesting but for reference )

/// @ddd-ts/tools/jest.setup.ts
import { exec } from "child_process"
import { writeFileSync } from "fs";
import { Config } from "jest";

type ProjectConfig = Config & {
  globals: {
    CURRENT_WORKSPACE: string;
    CURRENT_WORKSPACE_PATH: string;
    CURRENT_WORKSPACE_PRETEST: string;
    CURRENT_WORKSPACE_WAIT: string;
    CURRENT_WORKSPACE_POSTTEST: string;
  }
}

export default async (globalConfig: Config, projectConfig: ProjectConfig) => {
  console.log(`Setting up workspace ${projectConfig.globals.CURRENT_WORKSPACE}`)

  const cwd = projectConfig.globals.CURRENT_WORKSPACE_PATH

  const pretest = projectConfig.globals.CURRENT_WORKSPACE_PRETEST

  if (!pretest) {
    return;
  }

  console.log('[PRETEST] running')
  const pretestProcess = exec(pretest, { cwd })

  await new Promise<void>((resolve, reject) => {
    pretestProcess.on('error', reject)
    pretestProcess.on('exit', (code) => code ? reject() : resolve())
  })
  console.log('[PRETEST] finished')


  const wait = projectConfig.globals.CURRENT_WORKSPACE_WAIT

  if (!wait) {
    return;
  }

  console.log('[WAIT] running')
  const waitProcess = exec(wait, { cwd })

  await new Promise<void>((resolve, reject) => {
    waitProcess.on('error', reject)
    waitProcess.on('exit', (code) => code ? reject() : resolve())
  })
  console.log('[WAIT] finished')
}
/// @ddd-ts/tools/jest.config.ts
import type { Config } from "jest";
import { getPnpmWorkspaces, WorkspaceInfo } from "workspace-tools";

export const config = (workspace: WorkspaceInfo[number]) => ({
  displayName: workspace.name,
  rootDir: `${workspace.path}/src`,
  testEnvironment: "node",
  globals: {
    CURRENT_WORKSPACE: workspace.name,
    CURRENT_WORKSPACE_PATH: workspace.path,
    CURRENT_WORKSPACE_PRETEST: workspace.packageJson.scripts?.["pretest"],
    CURRENT_WORKSPACE_POSTTEST: workspace.packageJson.scripts?.["posttest"],
    CURRENT_WORKSPACE_WAIT: workspace.packageJson.scripts?.["wait"],
  },
  testMatch: ["**/*.spec.ts"],
  globalSetup: "../node_modules/@ddd-ts/tools/jest.setup.ts",
  globalTeardown: "../node_modules/@ddd-ts/tools/jest.teardown.ts",
  transform: {
    "^.+\\.(t|j)sx?$": [
      "@swc/jest",
      {
        jsc: {
          parser: {
            syntax: "typescript",
            decorators: true,
          },
        },
      },
    ],
  },
} satisfies Config);

export default () => {
  const cwd = process.cwd();
  const ws = getPnpmWorkspaces(cwd);
  const current = ws.find((w) => w.path === cwd);

  if (!current) {
    throw new Error("Could not find current workspace");
  }

  return config(current);
};
/// @ddd-ts/tools/jest.workspace.config.ts
import type { Config } from "jest";
import { getPnpmWorkspaces, WorkspaceInfo } from "workspace-tools";

export const config = (workspace: WorkspaceInfo[number]) => ({
  displayName: workspace.name,
  rootDir: `${workspace.path}/src`,
  testEnvironment: "node",
  globals: {
    CURRENT_WORKSPACE: workspace.name,
    CURRENT_WORKSPACE_PATH: workspace.path,
    CURRENT_WORKSPACE_PRETEST: workspace.packageJson.scripts?.["pretest"],
    CURRENT_WORKSPACE_POSTTEST: workspace.packageJson.scripts?.["posttest"],
    CURRENT_WORKSPACE_WAIT: workspace.packageJson.scripts?.["wait"],
  },
  testMatch: ["**/*.spec.ts"],
  globalSetup: "../node_modules/@ddd-ts/tools/jest.setup.ts",
  globalTeardown: "../node_modules/@ddd-ts/tools/jest.teardown.ts",
  transform: {
    "^.+\\.(t|j)sx?$": [
      "@swc/jest",
      {
        jsc: {
          parser: {
            syntax: "typescript",
            decorators: true,
          },
        },
      },
    ],
  },
} satisfies Config);

export default () => {
  const cwd = process.cwd();
  const ws = getPnpmWorkspaces(cwd);
  const current = ws.find((w) => w.path === cwd);

  if (!current) {
    throw new Error("Could not find current workspace");
  }

  return config(current);
};

With such a system, I am able to have a working configuration whether I run tests from the root of my monorepo or one of the packages, through any tooling, and with the capacity to boot the test environment of each package.

However, the current way of checking which global hook to run does not allow to reuse the same file. After a lookup I found out this looks like a very simple issue to solve, so I gave it a shot.

Test plan

I've seen some e2e test folder, but I dont know where should I put this ? Can I add a test case to the existing globalHook suite ?

Thanks for your time !

Aetherall avatar Apr 05 '24 18:04 Aetherall

CLA Not Signed

Deploy Preview for jestjs ready!

Built without sensitive environment variables

Name Link
Latest commit 2fec7eddf7b77daa0ea6aba53bb036e1c97801d8
Latest deploy log https://app.netlify.com/sites/jestjs/deploys/66104b8918b00f000884fcf3
Deploy Preview https://deploy-preview-15009--jestjs.netlify.app
Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

netlify[bot] avatar Apr 05 '24 18:04 netlify[bot]

This PR is stale because it has been open 90 days with no activity. Remove stale label or comment or this will be closed in 30 days.

github-actions[bot] avatar Aug 17 '24 08:08 github-actions[bot]

This PR was closed because it has been stalled for 30 days with no activity. Please open a new PR if the issue is still relevant, linking to this one.

github-actions[bot] avatar Sep 16 '24 08:09 github-actions[bot]

This PR was closed because it has been stalled for 30 days with no activity. Please open a new PR if the issue is still relevant, linking to this one.

github-actions[bot] avatar Sep 16 '24 08:09 github-actions[bot]

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

github-actions[bot] avatar Oct 18 '24 00:10 github-actions[bot]