Skip to content

Commit 19401e4

Browse files
committed
directives added
1 parent 1130124 commit 19401e4

3 files changed

Lines changed: 223 additions & 0 deletions

File tree

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
# Testing Attribute Directives
2+
3+
An _attribute directive_ modifies the behavior of an element, component or another directive. Its name reflects the way the directive is applied: as an attribute on a host element.
4+
5+
Create `HighlightDirective`
6+
7+
```bash
8+
npx ng g d highlight
9+
```
10+
11+
```ts
12+
import { Directive, ElementRef, Input, OnChanges } from "@angular/core";
13+
14+
@Directive({
15+
selector: "[appHighlight]",
16+
})
17+
export class HighlightDirective implements OnChanges {
18+
defaultColor = "rgb(211, 211, 211)";
19+
20+
@Input("appHighlight") bgColor = "";
21+
22+
constructor(private el: ElementRef) {
23+
el.nativeElement.style.customProperty = true;
24+
}
25+
26+
ngOnChanges(): void {
27+
this.el.nativeElement.style.backgroundColor =
28+
this.bgColor || this.defaultColor;
29+
}
30+
}
31+
```
32+
33+
The sample application's HighlightDirective sets the background color of an element based on either a data bound color or a default color (lightgray). It also sets a custom property of the element (`customProperty`) to `true` for no reason other than to show that it can.
34+
35+
A directive is going to manipulate the DOM, so iff we want to test a directive we need a DOM to get updated by its use case. The best approach is to create a component that reflects all use cases using the directive.
36+
37+
Update `highlight.directive.spec.ts`
38+
39+
```ts
40+
import { Component } from "@angular/core";
41+
import { HighlightDirective } from "./highlight.directive";
42+
import { ComponentFixture, TestBed } from "@angular/core/testing";
43+
import { By } from "@angular/platform-browser";
44+
45+
@Component({
46+
template: `
47+
<h2 appHighlight="yellow">Something Yellow</h2>
48+
<h2 appHighlight>The default (Gray)</h2>
49+
<h2>No Highlight</h2>
50+
<input #box [appHighlight]="box.value" value="cyan" />
51+
`,
52+
imports: [HighlightDirective],
53+
})
54+
class TestComponent {}
55+
56+
describe("HighlightDirective", () => {
57+
let fixture: ComponentFixture<TestComponent>;
58+
59+
beforeEach(() => {
60+
fixture = TestBed.configureTestingModule({
61+
imports: [HighlightDirective, TestComponent],
62+
}).createComponent(TestComponent);
63+
});
64+
65+
it("should have three highlighted elements", () => {
66+
fixture.detectChanges();
67+
68+
const elements = fixture.debugElement.queryAll(
69+
By.directive(HighlightDirective)
70+
);
71+
72+
expect(elements.length).toBe(3);
73+
});
74+
75+
it('should color 1st <h2> background "yellow"', () => {
76+
fixture.detectChanges();
77+
78+
const elements = fixture.debugElement.queryAll(
79+
By.directive(HighlightDirective)
80+
);
81+
const bgColor = elements[0].nativeElement.style.backgroundColor;
82+
expect(bgColor).toBe("yellow");
83+
});
84+
85+
it("should color 2nd <h2> background w/ default color", () => {
86+
fixture.detectChanges();
87+
88+
const elements = fixture.debugElement.queryAll(
89+
By.directive(HighlightDirective)
90+
);
91+
const dir = elements[1].injector.get(
92+
HighlightDirective
93+
) as HighlightDirective;
94+
const bgColor = elements[1].nativeElement.style.backgroundColor;
95+
expect(bgColor).toBe(dir.defaultColor);
96+
});
97+
98+
it("should bind <input> background to value color", () => {
99+
fixture.detectChanges();
100+
const elements = fixture.debugElement.queryAll(
101+
By.directive(HighlightDirective)
102+
);
103+
104+
const input = elements[2].nativeElement as HTMLInputElement;
105+
expect(input.style.backgroundColor)
106+
.withContext("initial backgroundColor")
107+
.toBe("cyan");
108+
109+
input.value = "green";
110+
111+
// Dispatch a DOM event so thatAngular responds to the input value change
112+
input.dispatchEvent(new Event("input"));
113+
fixture.detectChanges();
114+
115+
expect(input.style.backgroundColor)
116+
.withContext("initial backgroundColor")
117+
.toBe("green");
118+
});
119+
});
120+
```
121+
122+
```bash
123+
npx ng test --include app/highlight.directive.spec.ts
124+
```
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import { Component } from "@angular/core";
2+
import { HighlightDirective } from "./highlight.directive";
3+
import { ComponentFixture, TestBed } from "@angular/core/testing";
4+
import { By } from "@angular/platform-browser";
5+
6+
@Component({
7+
template: `
8+
<h2 appHighlight="yellow">Something Yellow</h2>
9+
<h2 appHighlight>The default (Gray)</h2>
10+
<h2>No Highlight</h2>
11+
<input #box [appHighlight]="box.value" value="cyan" />
12+
`,
13+
imports: [HighlightDirective],
14+
})
15+
class TestComponent {}
16+
17+
describe("HighlightDirective", () => {
18+
let fixture: ComponentFixture<TestComponent>;
19+
20+
beforeEach(() => {
21+
fixture = TestBed.configureTestingModule({
22+
imports: [HighlightDirective, TestComponent],
23+
}).createComponent(TestComponent);
24+
});
25+
26+
it("should have three highlighted elements", () => {
27+
fixture.detectChanges();
28+
29+
const elements = fixture.debugElement.queryAll(
30+
By.directive(HighlightDirective)
31+
);
32+
33+
expect(elements.length).toBe(3);
34+
});
35+
36+
it('should color 1st <h2> background "yellow"', () => {
37+
fixture.detectChanges();
38+
39+
const elements = fixture.debugElement.queryAll(
40+
By.directive(HighlightDirective)
41+
);
42+
const bgColor = elements[0].nativeElement.style.backgroundColor;
43+
expect(bgColor).toBe("yellow");
44+
});
45+
46+
it("should color 2nd <h2> background w/ default color", () => {
47+
fixture.detectChanges();
48+
49+
const elements = fixture.debugElement.queryAll(
50+
By.directive(HighlightDirective)
51+
);
52+
const dir = elements[1].injector.get(
53+
HighlightDirective
54+
) as HighlightDirective;
55+
const bgColor = elements[1].nativeElement.style.backgroundColor;
56+
expect(bgColor).toBe(dir.defaultColor);
57+
});
58+
59+
it("should bind <input> background to value color", () => {
60+
fixture.detectChanges();
61+
const elements = fixture.debugElement.queryAll(
62+
By.directive(HighlightDirective)
63+
);
64+
65+
const input = elements[2].nativeElement as HTMLInputElement;
66+
expect(input.style.backgroundColor)
67+
.withContext("initial backgroundColor")
68+
.toBe("cyan");
69+
70+
input.value = "green";
71+
72+
// Dispatch a DOM event so thatAngular responds to the input value change
73+
input.dispatchEvent(new Event("input"));
74+
fixture.detectChanges();
75+
76+
expect(input.style.backgroundColor)
77+
.withContext("initial backgroundColor")
78+
.toBe("green");
79+
});
80+
});
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { Directive, ElementRef, Input, OnChanges } from '@angular/core';
2+
3+
@Directive({
4+
selector: '[appHighlight]',
5+
})
6+
export class HighlightDirective implements OnChanges {
7+
defaultColor = 'rgb(211, 211, 211)';
8+
9+
@Input('appHighlight') bgColor = '';
10+
11+
constructor(private el: ElementRef) {
12+
el.nativeElement.style.customProperty = true;
13+
}
14+
15+
ngOnChanges(): void {
16+
this.el.nativeElement.style.backgroundColor =
17+
this.bgColor || this.defaultColor;
18+
}
19+
}

0 commit comments

Comments
 (0)