Utilities for managing test environments in monorepo setups, including process.cwd() mocking and project directory discovery.
Provides utilities for working with monorepo workspaces in tests, specifically helpers to mock process.cwd() for consistent test environments across different package locations.
/**
* Utility for working with monorepo workspaces in tests
* Provides helpers to mock process.cwd() for consistent test environments
* @param options - Configuration object with dirname property
* @returns Object with correctCWD method for setting up Jest spies
*/
function useMonorepo(options: { dirname: string }): {
correctCWD(): void;
};Configuration:
interface MonorepoOptions {
/** Directory path to find the project root from */
dirname: string;
}
interface MonorepoHelpers {
/** Sets up Jest spies to mock process.cwd() to the project root */
correctCWD(): void;
}Usage Examples:
import { useMonorepo } from "@graphql-codegen/testing";
describe("Plugin Tests in Monorepo", () => {
const { correctCWD } = useMonorepo({
dirname: __dirname
});
// Automatically sets up beforeEach and afterEach hooks
correctCWD();
it("should work with correct working directory", () => {
// process.cwd() now returns the project root
const currentDir = process.cwd();
// Test plugin behavior that depends on working directory
const result = plugin.loadConfig();
expect(result.success).toBe(true);
});
});
// Manual usage without automatic hooks
describe("Custom Working Directory Tests", () => {
const monorepoUtils = useMonorepo({ dirname: __dirname });
it("should handle custom directory setup", () => {
// Manually control when to set up directory mocking
monorepoUtils.correctCWD();
// Test code that needs specific working directory
const config = loadConfigFromCwd();
expect(config).toBeDefined();
});
});Project Directory Discovery:
The useMonorepo function uses an internal findProjectDir helper that:
dirname, walks up the directory treepackage.json files to identify project rootsprocess.cwd()Jest Integration:
The correctCWD() method sets up Jest hooks:
process.cwd() that returns the discovered project rootprocess.cwd() implementationInternal Implementation:
// Internal helper function (not exported)
function findProjectDir(dirname: string): string | never {
const originalDirname = dirname;
const cwd = process.cwd();
const stopDir = resolve(cwd, '..');
while (dirname !== stopDir) {
try {
if (existsSync(resolve(dirname, 'package.json'))) {
return dirname;
}
dirname = resolve(dirname, '..');
} catch (e) {
// Continue traversal on filesystem errors
}
}
throw new Error(`Couldn't find project's root from: ${originalDirname}`);
}Real-World Use Cases:
// Testing GraphQL Codegen plugins in monorepo
describe("TypeScript Plugin", () => {
const { correctCWD } = useMonorepo({ dirname: __dirname });
correctCWD();
it("should load codegen config from project root", async () => {
// Plugin tries to load codegen.yml from process.cwd()
const result = await plugin(schema, [], {}, {
outputFile: 'generated/types.ts'
});
// With correct CWD, relative paths resolve properly
expect(result.content).toContain('export interface');
});
});
// Testing configuration loading
describe("Config Loading", () => {
const { correctCWD } = useMonorepo({
dirname: path.join(__dirname, '../../')
});
correctCWD();
it("should find config files relative to project root", () => {
const config = loadGraphQLConfig();
expect(config.schema).toBeDefined();
expect(config.generates).toBeDefined();
});
});
// Testing file output paths
describe("File Generation", () => {
const { correctCWD } = useMonorepo({ dirname: __dirname });
correctCWD();
it("should generate files with correct paths", async () => {
const result = await generateCode({
outputDir: './generated',
schema: testSchema
});
// Paths resolve correctly from project root
expect(result.files).toContain('generated/types.ts');
});
});Directory Not Found:
When findProjectDir cannot locate a package.json file:
// Throws descriptive error with original search path
throw new Error(`Couldn't find project's root from: ${originalDirname}`);Jest Spy Management:
The correctCWD() method properly manages Jest spies:
process.cwd() in afterEachFilesystem Errors: The directory traversal gracefully handles filesystem access errors:
package.json is found after complete traversalThis utility is essential for GraphQL Codegen plugin testing in monorepo environments where the working directory affects configuration loading, file resolution, and output path calculation.