Hone logo
Hone
Problems

Mastering Jest's Test Matchers for Robust Assertions

Testing is a cornerstone of robust software development, and Jest provides a rich set of matchers to help you express your assertions clearly and effectively. This challenge focuses on leveraging Jest's powerful test matchers, particularly those related to matching patterns in strings and arrays, to build comprehensive and reliable tests.

Problem Description

Your task is to write a set of Jest tests for a hypothetical textProcessor function. This function is designed to analyze text inputs and identify specific patterns. You will need to utilize Jest's built-in matchers, including toMatch, toContain, toEqual, toHaveLength, and potentially others, to assert the expected outcomes of various textProcessor scenarios.

Key Requirements:

  • Write Jest tests in TypeScript.
  • Mock or create a simple textProcessor function that takes a string as input and returns an object containing:
    • foundWords: An array of words found in the input string.
    • matchedPattern: A string indicating the first pattern matched (or null if no pattern is found).
    • lineCount: The total number of lines in the input string.
  • Implement tests to cover various aspects of the textProcessor function's output.
  • Specifically, use toMatch to test for specific string patterns, toContain to check for the presence of elements in arrays, and toEqual for deep object comparison.
  • Ensure your tests cover cases with and without matching patterns, different line counts, and varying word occurrences.

Expected Behavior:

Your tests should pass when executed against a correctly implemented textProcessor function. The tests will verify that:

  • The foundWords array contains the expected words.
  • The matchedPattern accurately reflects the pattern identified (or is null).
  • The lineCount is correctly calculated.

Edge Cases to Consider:

  • Empty input strings.
  • Input strings with only whitespace.
  • Input strings with multiple occurrences of the same pattern.
  • Input strings with special characters.

Examples

Example 1: Basic Word and Pattern Matching

// Hypothetical textProcessor implementation (for context, not to be provided in the challenge solution)
const textProcessor = (text: string): { foundWords: string[]; matchedPattern: string | null; lineCount: number } => {
    const lines = text.split('\n');
    const words = text.toLowerCase().match(/\b\w+\b/g) || [];
    let matchedPattern: string | null = null;

    if (text.includes("important")) {
        matchedPattern = "contains_important";
    } else if (text.includes("urgent")) {
        matchedPattern = "contains_urgent";
    }

    return {
        foundWords: words,
        matchedPattern: matchedPattern,
        lineCount: lines.length
    };
};

// Input to the textProcessor
const inputText1 = "This is an important message.\nIt needs your attention.";

// Expected output from textProcessor(inputText1)
/*
{
  foundWords: ["this", "is", "an", "important", "message", "it", "needs", "your", "attention"],
  matchedPattern: "contains_important",
  lineCount: 2
}
*/

Test Assertion Idea:

// Inside a describe block for textProcessor
test('should correctly process basic text with an important pattern', () => {
    const result = textProcessor(inputText1);
    expect(result.foundWords).toContain('important');
    expect(result.foundWords).toHaveLength(9); // Or check for specific words
    expect(result.matchedPattern).toMatch(/important/); // Or toEqual("contains_important")
    expect(result.lineCount).toBe(2);
});

Example 2: No Pattern Match and Empty Input

// Input to the textProcessor
const inputText2 = "This is a regular message.\nNo special keywords here.";
const inputText3 = "";

// Expected output from textProcessor(inputText2)
/*
{
  foundWords: ["this", "is", "a", "regular", "message", "no", "special", "keywords", "here"],
  matchedPattern: null,
  lineCount: 2
}
*/

// Expected output from textProcessor(inputText3)
/*
{
  foundWords: [],
  matchedPattern: null,
  lineCount: 1 // or 0 depending on split behavior, adjust expectations
}
*/

Test Assertion Idea:

// Inside a describe block for textProcessor
test('should return null for matchedPattern when no pattern is found', () => {
    const result = textProcessor(inputText2);
    expect(result.matchedPattern).toBeNull();
});

test('should handle empty input string gracefully', () => {
    const result = textProcessor(inputText3);
    expect(result.foundWords).toEqual([]);
    expect(result.matchedPattern).toBeNull();
    expect(result.lineCount).toBe(1); // Assuming split('') results in ['']
});

Example 3: Multiple Patterns and Specific Word Check

// Input to the textProcessor
const inputText4 = "This is an urgent update.\nIt is very important information.";

// Expected output from textProcessor(inputText4) (assuming 'important' takes precedence)
/*
{
  foundWords: ["this", "is", "an", "urgent", "update", "it", "is", "very", "important", "information"],
  matchedPattern: "contains_important", // or "contains_urgent" if logic differs
  lineCount: 2
}
*/

Test Assertion Idea:

// Inside a describe block for textProcessor
test('should prioritize the first matched pattern if multiple exist', () => {
    const result = textProcessor(inputText4);
    // Assuming 'important' check comes before 'urgent' in the actual implementation
    expect(result.matchedPattern).toEqual("contains_important");
});

test('should correctly identify all words and line count', () => {
    const result = textProcessor(inputText4);
    expect(result.foundWords).toEqual(["this", "is", "an", "urgent", "update", "it", "is", "very", "important", "information"]);
    expect(result.lineCount).toBe(2);
});

Constraints

  • The textProcessor function will be tested in a Jest environment.
  • Your solution should consist solely of Jest test files (.test.ts or .spec.ts).
  • You do not need to implement the textProcessor function itself, but you should assume its existence and define its return type for your tests.
  • Tests should be clear, readable, and follow standard Jest conventions.
  • Aim for at least 5 distinct test cases covering the scenarios outlined.

Notes

  • Consider how String.prototype.split('\n') handles trailing newlines.
  • Think about the definition of a "word" for your foundWords array (e.g., alphanumeric characters).
  • The exact pattern matching logic in the hypothetical textProcessor is up to your interpretation based on the examples, but your tests should reflect a consistent logic.
  • Focus on demonstrating your understanding and application of Jest's matchers. You can create a simple stub textProcessor within your test file for demonstration purposes if needed, but the core of the challenge is writing the tests.
Loading editor...
typescript