Hone logo
Hone
Problems

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:

  1. Storage: The ArtifactStorage class should maintain an in-memory collection of artifacts.
  2. Add Artifact: A method addArtifact(id: string, data: any) should be implemented to store an artifact. id will be a unique identifier for the artifact, and data can be any JavaScript data type.
  3. Get Artifact: A method getArtifact(id: string): any | undefined should be implemented to retrieve an artifact by its ID. If the artifact does not exist, it should return undefined.
  4. Clear Storage: A method clearStorage() should be implemented to remove all artifacts from the storage.
  5. 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 in getArtifact() returning undefined for all previously stored IDs.

Edge Cases:

  • Storing and retrieving null or undefined as 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 ArtifactStorage class 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 Map or a plain JavaScript object could be suitable.
  • Think about how to ensure the getArtifact method correctly handles cases where an ID might not be present.
  • The any type 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.
Loading editor...
typescript