Jest Artifact Storage
This challenge focuses on creating a robust artifact storage mechanism within your Jest test suite. In many real-world applications, tests generate artifacts like screenshots, network logs, or generated data. Efficiently storing and retrieving these artifacts is crucial for debugging and analysis. This problem requires you to build a simple, yet effective, in-memory storage system for these test artifacts.
Problem Description
You need to implement a TypeScript class, ArtifactStorage, that can store and retrieve various types of artifacts generated during your Jest tests. This class should provide methods to add artifacts, retrieve them by a unique identifier, and clear the storage.
Key Requirements:
- Storage: The
ArtifactStorageclass should maintain an in-memory collection of artifacts. - Add Artifact: A method
addArtifact(id: string, data: any)should be implemented to store an artifact.idwill be a unique identifier for the artifact, anddatacan be any JavaScript data type. - Get Artifact: A method
getArtifact(id: string): any | undefinedshould be implemented to retrieve an artifact by its ID. If the artifact does not exist, it should returnundefined. - Clear Storage: A method
clearStorage()should be implemented to remove all artifacts from the storage. - Type Safety: The solution should leverage TypeScript for strong typing.
Expected Behavior:
- Adding an artifact with a new ID should store it.
- Adding an artifact with an existing ID should overwrite the previous artifact.
- Retrieving an artifact with a valid ID should return the stored data.
- Retrieving an artifact with an invalid ID should return
undefined. - Calling
clearStorage()should result ingetArtifact()returningundefinedfor all previously stored IDs.
Edge Cases:
- Storing and retrieving
nullorundefinedas artifact data. - Storing and retrieving complex data structures (objects, arrays).
- Attempting to retrieve from an empty storage.
Examples
Example 1:
const storage = new ArtifactStorage();
storage.addArtifact('screenshot-1', Buffer.from('some image data'));
storage.addArtifact('log-2', { message: 'User logged in' });
console.log(storage.getArtifact('screenshot-1'));
// Expected Output: <Buffer 73 6f 6d 65 20 69 6d 61 67 65 20 64 61 74 61>
console.log(storage.getArtifact('log-2'));
// Expected Output: { message: 'User logged in' }
console.log(storage.getArtifact('non-existent-id'));
// Expected Output: undefined
Explanation: We add two artifacts with different IDs and data types. We then successfully retrieve them and demonstrate retrieving a non-existent artifact.
Example 2:
const storage = new ArtifactStorage();
storage.addArtifact('config', { setting: 'enabled' });
storage.addArtifact('config', { setting: 'disabled' }); // Overwriting
console.log(storage.getArtifact('config'));
// Expected Output: { setting: 'disabled' }
Explanation: We overwrite an artifact by adding another artifact with the same ID. The retrieval reflects the latest stored data.
Example 3:
const storage = new ArtifactStorage();
storage.addArtifact('data-a', 123);
storage.clearStorage();
console.log(storage.getArtifact('data-a'));
// Expected Output: undefined
Explanation: We store an artifact, clear the storage, and then attempt to retrieve it, confirming that the storage has been emptied.
Constraints
- The
ArtifactStorageclass should be implemented in a single TypeScript file. - The artifact data (
any) can be any valid JavaScript value (primitives, objects, arrays, functions, Buffers, etc.). - The storage is expected to be in-memory, so no persistence to disk or external services is required for this challenge.
- The solution should be performant for a moderate number of artifacts (up to a few thousand).
Notes
- Consider how you will manage the collection of artifacts internally. A
Mapor a plain JavaScript object could be suitable. - Think about how to ensure the
getArtifactmethod correctly handles cases where an ID might not be present. - The
anytype for artifact data is intentionally broad to allow flexibility, but in a real-world scenario, you might want to consider more specific union types or generics if the types of artifacts are known. - This storage is intended for use within test execution, so considerations like thread safety or concurrent access are not a primary concern for this challenge.