Hone logo
Hone
Problems

Jest Module Cache Implementation

You are tasked with implementing a custom module cache mechanism for Jest. This will allow you to control how modules are loaded and cached during test execution, which can be crucial for advanced testing scenarios like mocking specific module versions or isolating tests.

Problem Description

Jest internally caches modules to speed up test execution. However, for certain advanced testing needs, you might want to implement your own caching logic or override Jest's default behavior. This challenge involves creating a mechanism that intercepts module loading and applies a custom caching strategy before Jest's default cache is consulted.

Your goal is to create a Jest transformer or plugin that:

  1. Intercepts Module Loading: Before Jest loads any module, your solution should have an opportunity to check its own cache.
  2. Custom Caching Logic: If the module is found in your custom cache, return the cached version. Otherwise, let Jest proceed with its normal loading and caching process.
  3. Populate Custom Cache: After Jest successfully loads a module and it's not found in your custom cache, add the loaded module to your custom cache for future use.
  4. Integration with Jest: Ensure your solution integrates seamlessly with Jest's configuration.

Key Requirements:

  • The solution must be implemented in TypeScript.
  • The custom cache should store module content (e.g., transformed code).
  • The solution should allow configuration through jest.config.js.
  • It should demonstrate how to cache a JavaScript or TypeScript module.

Expected Behavior:

When Jest attempts to require a module, your custom cache should be checked first. If a match is found, the cached content is returned. If not, Jest's default module resolution and caching will occur. After Jest successfully loads and caches the module, your custom cache should be updated.

Edge Cases:

  • Modules that are dynamically required.
  • Modules that are not transformed (plain JavaScript/TypeScript).
  • Multiple test files requiring the same module.

Examples

Example 1: Caching a simple utility module

Imagine a utility module utils.js that exports a function add(a, b).

Input: A Jest test file that requires ./utils.js multiple times.

Output: The add function from utils.js is returned by your custom cache on subsequent require calls, preventing Jest from re-resolving and re-transforming the module.

Explanation: The first time ./utils.js is encountered, it's loaded by Jest and then added to your custom cache. Subsequent calls will retrieve it directly from your custom cache.

Example 2: Caching a module that is being mocked

Consider a module api.js that makes network requests. You might want to cache its initial state or a specific mocked version.

Input: A Jest test suite where api.js is required and potentially mocked.

Output: Your custom cache ensures that the same instance or transformed version of api.js is used across different tests within the suite, allowing for consistent mocking.

Explanation: After Jest loads api.js (possibly in its original or a pre-mocked state), your cache stores this version. Any subsequent require for api.js within the same execution context will retrieve this cached version, ensuring that mock implementations applied earlier persist or that the same module factory is used.

Constraints

  • The solution must be written in TypeScript.
  • The custom cache should be a simple in-memory object or Map for demonstration purposes.
  • The solution should integrate with Jest's module loader and transformers.
  • Focus on caching the transformed module content as Jest typically caches the output of transformers.

Notes

This challenge requires understanding Jest's internal module loading mechanisms. You might need to explore Jest's Resolver and Transform interfaces. Consider how to hook into the module loading pipeline. A good starting point might be implementing a custom Jest transformer that also manages a cache. You could also explore Jest's jest-runtime API if you need deeper access. The goal is to augment or precede Jest's default caching, not necessarily to replace it entirely.

Loading editor...
typescript