Angular Directive Testing Challenge: Highlight Specific Text
This challenge focuses on writing unit tests for an Angular directive that highlights specific text within an element. Testing directives is crucial for ensuring component reusability and maintaining code quality, and this exercise will help solidify your understanding of how to effectively test Angular directives in isolation.
Problem Description
You are tasked with creating and testing an Angular directive called highlightText. This directive takes a string as input (highlightText) and highlights any occurrences of that string within the element the directive is applied to. The highlighting should be achieved by wrapping the matched text in a <span class="highlight"> element.
What needs to be achieved:
- Create an Angular directive named
highlightTextthat accepts an@Input()property calledhighlightText. - The directive should iterate through the element's children (text nodes and elements).
- For each text node, it should check if the text contains the
highlightTextstring. - If a match is found, the text node should be replaced with a
<span>element containing the original text, with the matched portion wrapped in another<span>with the classhighlight. - The directive should not modify elements, only text nodes.
Key Requirements:
- The directive must be written in TypeScript.
- The highlighting should be case-sensitive.
- The directive should handle multiple occurrences of the
highlightTextwithin a single text node. - The directive should not affect elements, only text nodes.
- The directive should not modify the element's attributes.
Expected Behavior:
When the directive is applied to an element and the highlightText input is set, any occurrences of the specified text within the element's text nodes should be wrapped in <span class="highlight">.
Edge Cases to Consider:
- Empty
highlightTextinput: No highlighting should occur. highlightTextnot found in the element: No changes should be made.- Element containing only elements (no text nodes): No highlighting should occur.
- Text nodes containing HTML entities (e.g.,
<): The directive should handle these correctly without breaking the HTML. - Text nodes containing newlines or whitespace: The directive should handle these correctly.
Examples
Example 1:
Input: <p>This is a test string with the word test in it.</p>
highlightText: "test"
Output: <p>This is a <span class="highlight">test</span> string with the word <span class="highlight">test</span> in it.</p>
Explanation: The word "test" appears twice in the paragraph and is highlighted in both instances.
Example 2:
Input: <div>Hello world!</div>
highlightText: "Goodbye"
Output: <div>Hello world!</div>
Explanation: The string "Goodbye" is not found in the div, so no changes are made.
Example 3:
Input: <p>This is a test string with the word TEST in it.</p>
highlightText: "test"
Output: <p>This is a test string with the word TEST in it.</p>
Explanation: The string "test" is not found (case-sensitive) so no changes are made.
Constraints
- The directive must be implemented using Angular's built-in
ElementRefandRenderer2. - The tests should use Jasmine and Angular's testing utilities.
- The tests should cover the expected behavior and edge cases described above.
- Performance is not a primary concern for this challenge, but avoid unnecessarily complex or inefficient solutions.
- The directive should only modify the content of the element, not its attributes or structure.
Notes
- Consider using
Renderer2to safely manipulate the DOM. - Think about how to isolate the directive for testing purposes. You'll need to create a test component that uses the directive.
- Use
detectChanges()after applying the directive to ensure that the changes are reflected in the DOM. - Focus on writing clear, concise, and well-documented tests. Test the different scenarios described in the examples and edge cases.
- Remember to import necessary modules and declare the directive in your test module.