Hone logo
Hone
Problems

Testing an Angular Attribute Directive

This challenge focuses on writing unit tests for an Angular attribute directive. Attribute directives are a fundamental part of Angular for manipulating the DOM and adding custom behavior. Effectively testing them ensures they function as intended in various scenarios.

Problem Description

Your task is to write comprehensive unit tests for a pre-existing Angular attribute directive. This directive, HighlightDirective, is designed to change the background color of an HTML element to a specified color when the mouse hovers over it and revert to its original color when the mouse leaves.

You will need to:

  • Create a test component: This component will host the directive in its template, allowing you to interact with and test the directive's behavior.
  • Write tests for the directive:
    • Test that the initial background color is applied correctly.
    • Test that the background color changes when the mouse enters the element.
    • Test that the background color reverts to the original color when the mouse leaves the element.
    • Test with a custom highlight color provided as an @Input.
  • Use Angular Testing Utilities: Leverage tools like TestBed, ComponentFixture, and DebugElement to simulate DOM interactions and inspect element properties.

Key Requirements:

  • The tests should be written in TypeScript.
  • All tests should pass.
  • The directive's functionality should be thoroughly tested.
  • The test component's template should be minimal and focused on demonstrating the directive.

Expected Behavior:

When the tests are run:

  1. The directive should apply its default highlight color (if not specified) or the provided custom color to the host element's background when the mouse hovers over it.
  2. The directive should reset the background color to its initial state (or remove the background style) when the mouse leaves the host element.

Edge Cases to Consider:

  • What happens if the directive is applied to an element that already has a background color set? (The directive should ideally override it during hover and revert appropriately).
  • What if no highlight color is provided?

Examples

Example 1: Default Highlight Color

Directive (Simplified for context):

import { Directive, ElementRef, HostListener, Input, Renderer2 } from '@angular/core';

@Directive({
  selector: '[appHighlight]'
})
export class HighlightDirective {
  @Input() appHighlight: string = 'yellow'; // Default highlight color
  private originalBackgroundColor: string | null = null;

  constructor(private el: ElementRef, private renderer: Renderer2) {}

  @HostListener('mouseenter') onMouseEnter() {
    this.originalBackgroundColor = this.el.nativeElement.style.backgroundColor;
    this.highlight(this.appHighlight);
  }

  @HostListener('mouseleave') onMouseLeave() {
    this.highlight(this.originalBackgroundColor);
  }

  private highlight(color: string | null) {
    this.renderer.setStyle(this.el.nativeElement, 'backgroundColor', color);
  }
}

Test Component Template:

<p appHighlight>Hover over me!</p>

Test Scenario:

  1. Initialize the test component.
  2. The <p> element should have no explicit background color initially.
  3. Simulate a mouseenter event on the <p> element.
  4. Expected Output: The background color of the <p> element should become 'yellow'.

Example 2: Custom Highlight Color

Test Component Template:

<div [appHighlight]="'lightblue'">Hover for lightblue</div>

Test Scenario:

  1. Initialize the test component.
  2. The <div> element should have no explicit background color initially.
  3. Simulate a mouseenter event on the <div> element.
  4. Expected Output: The background color of the <div> element should become 'lightblue'.

Example 3: Reverting to Original Color

Test Component Template:

<span style="background-color: pink;" appHighlight="orange">Hover over me!</span>

Test Scenario:

  1. Initialize the test component.
  2. The <span> element should have an initial background color of 'pink'.
  3. Simulate a mouseenter event on the <span> element. The background should temporarily become 'orange'.
  4. Simulate a mouseleave event on the <span> element.
  5. Expected Output: The background color of the <span> element should revert back to 'pink'.

Constraints

  • Testing Framework: You must use the Angular testing utilities provided by @angular/core/testing.
  • Test Coverage: Aim for comprehensive test coverage of the directive's functionality.
  • TypeScript Version: Use a recent stable version of TypeScript.
  • No External Libraries: Do not introduce external testing libraries beyond those standard with Angular CLI projects.

Notes

  • You will likely need to create a mock component to host your directive within the testing environment.
  • Pay close attention to how you simulate DOM events (mouseenter, mouseleave) using DebugElement.triggerEventHandler.
  • When checking element styles, use DebugElement.styles.
  • Remember to call fixture.detectChanges() after making changes or simulating events to allow Angular to update the view.
  • Consider the order of operations: setting initial styles, triggering events, and then asserting the results.
  • The provided directive is a simplified example. You will be testing an actual, but potentially more complex, directive. You will be given the full directive code to test.
Loading editor...
typescript