Skip to content

Commit ede5786

Browse files
karamhevery
authored andcommitted
refactor(core): remove testing-only style utils from DomAdapters (angular#32291)
PR Close angular#32291
1 parent 46caf88 commit ede5786

File tree

14 files changed

+63
-75
lines changed

14 files changed

+63
-75
lines changed

packages/common/test/directives/ng_if_spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
133133
fixture.detectChanges();
134134
els = fixture.debugElement.queryAll(By.css('span'));
135135
expect(els.length).toEqual(1);
136-
expect(getDOM().hasClass(els[0].nativeElement, 'marker')).toBe(true);
136+
expect(els[0].nativeElement.classList.contains('marker')).toBe(true);
137137

138138
expect(fixture.nativeElement).toHaveText('hello');
139139
}));

packages/common/test/directives/non_bindable_spec.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {Component, Directive} from '@angular/core';
1010
import {ElementRef} from '@angular/core/src/linker/element_ref';
1111
import {ComponentFixture, TestBed, async} from '@angular/core/testing';
1212
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
13+
import {hasClass} from '@angular/platform-browser/testing/src/browser_util';
1314
import {expect} from '@angular/platform-browser/testing/src/matchers';
1415

1516
{
@@ -37,15 +38,15 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
3738
// We must use getDOM().querySelector instead of fixture.query here
3839
// since the elements inside are not compiled.
3940
const span = getDOM().querySelector(fixture.nativeElement, '#child');
40-
expect(getDOM().hasClass(span, 'compiled')).toBeFalsy();
41+
expect(hasClass(span, 'compiled')).toBeFalsy();
4142
}));
4243

4344
it('should trigger directives on the same node', async(() => {
4445
const template = '<div><span id=child ngNonBindable test-dec>{{text}}</span></div>';
4546
const fixture = createTestComponent(template);
4647
fixture.detectChanges();
4748
const span = getDOM().querySelector(fixture.nativeElement, '#child');
48-
expect(getDOM().hasClass(span, 'compiled')).toBeTruthy();
49+
expect(hasClass(span, 'compiled')).toBeTruthy();
4950
}));
5051
});
5152
}

packages/core/test/animation/animation_integration_spec.ts

+10-10
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {TestBed, fakeAsync, flushMicrotasks} from '@angular/core/testing';
1313
import {ɵDomRendererFactory2} from '@angular/platform-browser';
1414
import {ANIMATION_MODULE_TYPE, BrowserAnimationsModule, NoopAnimationsModule} from '@angular/platform-browser/animations';
1515
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
16+
import {hasStyle} from '@angular/platform-browser/testing/src/browser_util';
1617
import {ivyEnabled, modifiedInIvy} from '@angular/private/testing';
1718

1819
const DEFAULT_NAMESPACE_ID = 'id';
@@ -1446,8 +1447,7 @@ const DEFAULT_COMPONENT_ID = '1';
14461447
const player = engine.players.pop();
14471448
player.finish();
14481449

1449-
expect(getDOM().hasStyle(cmp.element.nativeElement, 'background-color', 'green'))
1450-
.toBeTruthy();
1450+
expect(hasStyle(cmp.element.nativeElement, 'background-color', 'green')).toBeTruthy();
14511451
});
14521452

14531453
it('should retain state styles when the underlying DOM structure changes even if there are no insert/remove animations',
@@ -2039,23 +2039,23 @@ const DEFAULT_COMPONENT_ID = '1';
20392039
player.finish();
20402040

20412041
flushMicrotasks();
2042-
expect(getDOM().hasStyle(element, 'color', 'red')).toBeTruthy();
2042+
expect(hasStyle(element, 'color', 'red')).toBeTruthy();
20432043

20442044
cmp.exp = '1';
20452045
cmp.color = 'blue';
20462046
fixture.detectChanges();
20472047
resetLog();
20482048

20492049
flushMicrotasks();
2050-
expect(getDOM().hasStyle(element, 'color', 'blue')).toBeTruthy();
2050+
expect(hasStyle(element, 'color', 'blue')).toBeTruthy();
20512051

20522052
cmp.exp = '1';
20532053
cmp.color = null;
20542054
fixture.detectChanges();
20552055
resetLog();
20562056

20572057
flushMicrotasks();
2058-
expect(getDOM().hasStyle(element, 'color', 'black')).toBeTruthy();
2058+
expect(hasStyle(element, 'color', 'black')).toBeTruthy();
20592059
}));
20602060

20612061
it('should substitute in values if the provided state match is an object with values', () => {
@@ -2157,9 +2157,9 @@ const DEFAULT_COMPONENT_ID = '1';
21572157
p1.finish();
21582158
flushMicrotasks();
21592159

2160-
expect(getDOM().hasStyle(element, 'color', 'blue')).toBeTruthy();
2161-
expect(getDOM().hasStyle(element, 'fontSize', '50px')).toBeTruthy();
2162-
expect(getDOM().hasStyle(element, 'width', '888px')).toBeTruthy();
2160+
expect(hasStyle(element, 'color', 'blue')).toBeTruthy();
2161+
expect(hasStyle(element, 'fontSize', '50px')).toBeTruthy();
2162+
expect(hasStyle(element, 'width', '888px')).toBeTruthy();
21632163
}));
21642164

21652165
it('should only evaluate final state param substitutions from the expression and state values and not from the transition options ',
@@ -2223,8 +2223,8 @@ const DEFAULT_COMPONENT_ID = '1';
22232223
p1.finish();
22242224
flushMicrotasks();
22252225

2226-
expect(getDOM().hasStyle(element, 'width', '100px')).toBeTruthy();
2227-
expect(getDOM().hasStyle(element, 'height', '100px')).toBeTruthy();
2226+
expect(hasStyle(element, 'width', '100px')).toBeTruthy();
2227+
expect(hasStyle(element, 'height', '100px')).toBeTruthy();
22282228
}));
22292229

22302230
it('should not flush animations twice when an inner component runs change detection', () => {

packages/core/test/debug/debug_node_spec.ts

+15-14
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {Component, DebugNode, Directive, ElementRef, EmbeddedViewRef, EventEmitt
1212
import {ComponentFixture, TestBed, async} from '@angular/core/testing';
1313
import {By} from '@angular/platform-browser/src/dom/debug/by';
1414
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
15+
import {hasClass} from '@angular/platform-browser/testing/src/browser_util';
1516
import {expect} from '@angular/platform-browser/testing/src/matchers';
1617
import {ivyEnabled} from '@angular/private/testing';
1718

@@ -254,24 +255,24 @@ class TestCmptWithPropBindings {
254255

255256
// The root component has 3 elements in its view.
256257
expect(childEls.length).toEqual(3);
257-
expect(getDOM().hasClass(childEls[0].nativeElement, 'parent')).toBe(true);
258-
expect(getDOM().hasClass(childEls[1].nativeElement, 'parent')).toBe(true);
259-
expect(getDOM().hasClass(childEls[2].nativeElement, 'child-comp-class')).toBe(true);
258+
expect(hasClass(childEls[0].nativeElement, 'parent')).toBe(true);
259+
expect(hasClass(childEls[1].nativeElement, 'parent')).toBe(true);
260+
expect(hasClass(childEls[2].nativeElement, 'child-comp-class')).toBe(true);
260261

261262
const nested = childEls[0].children;
262263
expect(nested.length).toEqual(1);
263-
expect(getDOM().hasClass(nested[0].nativeElement, 'parentnested')).toBe(true);
264+
expect(hasClass(nested[0].nativeElement, 'parentnested')).toBe(true);
264265

265266
const childComponent = childEls[2];
266267

267268
const childCompChildren = childComponent.children;
268269
expect(childCompChildren.length).toEqual(2);
269-
expect(getDOM().hasClass(childCompChildren[0].nativeElement, 'child')).toBe(true);
270-
expect(getDOM().hasClass(childCompChildren[1].nativeElement, 'child')).toBe(true);
270+
expect(hasClass(childCompChildren[0].nativeElement, 'child')).toBe(true);
271+
expect(hasClass(childCompChildren[1].nativeElement, 'child')).toBe(true);
271272

272273
const childNested = childCompChildren[0].children;
273274
expect(childNested.length).toEqual(1);
274-
expect(getDOM().hasClass(childNested[0].nativeElement, 'childnested')).toBe(true);
275+
expect(hasClass(childNested[0].nativeElement, 'childnested')).toBe(true);
275276
});
276277

277278
it('should list conditional component child elements', () => {
@@ -282,8 +283,8 @@ class TestCmptWithPropBindings {
282283

283284
// The root component has 2 elements in its view.
284285
expect(childEls.length).toEqual(2);
285-
expect(getDOM().hasClass(childEls[0].nativeElement, 'parent')).toBe(true);
286-
expect(getDOM().hasClass(childEls[1].nativeElement, 'cond-content-comp-class')).toBe(true);
286+
expect(hasClass(childEls[0].nativeElement, 'parent')).toBe(true);
287+
expect(hasClass(childEls[1].nativeElement, 'cond-content-comp-class')).toBe(true);
287288

288289
const conditionalContentComp = childEls[1];
289290

@@ -353,7 +354,7 @@ class TestCmptWithPropBindings {
353354
const childTestEls = fixture.debugElement.queryAll(By.css('child-comp'));
354355

355356
expect(childTestEls.length).toBe(1);
356-
expect(getDOM().hasClass(childTestEls[0].nativeElement, 'child-comp-class')).toBe(true);
357+
expect(hasClass(childTestEls[0].nativeElement, 'child-comp-class')).toBe(true);
357358
});
358359

359360
it('should query child elements by directive', () => {
@@ -363,10 +364,10 @@ class TestCmptWithPropBindings {
363364
const childTestEls = fixture.debugElement.queryAll(By.directive(MessageDir));
364365

365366
expect(childTestEls.length).toBe(4);
366-
expect(getDOM().hasClass(childTestEls[0].nativeElement, 'parent')).toBe(true);
367-
expect(getDOM().hasClass(childTestEls[1].nativeElement, 'parentnested')).toBe(true);
368-
expect(getDOM().hasClass(childTestEls[2].nativeElement, 'child')).toBe(true);
369-
expect(getDOM().hasClass(childTestEls[3].nativeElement, 'childnested')).toBe(true);
367+
expect(hasClass(childTestEls[0].nativeElement, 'parent')).toBe(true);
368+
expect(hasClass(childTestEls[1].nativeElement, 'parentnested')).toBe(true);
369+
expect(hasClass(childTestEls[2].nativeElement, 'child')).toBe(true);
370+
expect(hasClass(childTestEls[3].nativeElement, 'childnested')).toBe(true);
370371
});
371372

372373
it('should query projected child elements by directive', () => {

packages/core/test/view/element_spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,8 @@ const removeEventListener = '__zone_symbol__removeEventListener' as 'removeEvent
139139
Services.checkAndUpdateView(view);
140140

141141
const el = rootNodes[0];
142-
expect(getDOM().hasClass(el, 'c1')).toBeTruthy();
143-
expect(getDOM().hasClass(el, 'c2')).toBeTruthy();
142+
expect(el.classList.contains('c1')).toBeTruthy();
143+
expect(el.classList.contains('c2')).toBeTruthy();
144144
});
145145
});
146146
});

packages/forms/test/reactive_integration_spec.ts

+1-5
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {ComponentFixture, TestBed, fakeAsync, tick} from '@angular/core/testing'
1111
import {AbstractControl, AsyncValidator, AsyncValidatorFn, COMPOSITION_BUFFER_MODE, FormArray, FormControl, FormControlDirective, FormControlName, FormGroup, FormGroupDirective, FormsModule, NG_ASYNC_VALIDATORS, NG_VALIDATORS, ReactiveFormsModule, Validators} from '@angular/forms';
1212
import {By} from '@angular/platform-browser/src/dom/debug/by';
1313
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
14-
import {dispatchEvent} from '@angular/platform-browser/testing/src/browser_util';
14+
import {dispatchEvent, sortedClassList} from '@angular/platform-browser/testing/src/browser_util';
1515
import {merge, timer} from 'rxjs';
1616
import {tap} from 'rxjs/operators';
1717

@@ -2464,10 +2464,6 @@ class UniqLoginValidator implements AsyncValidator {
24642464
validate(c: AbstractControl) { return uniqLoginAsyncValidator(this.expected)(c); }
24652465
}
24662466

2467-
function sortedClassList(el: HTMLElement) {
2468-
return getDOM().classList(el).sort();
2469-
}
2470-
24712467
@Component({selector: 'form-control-comp', template: `<input type="text" [formControl]="control">`})
24722468
class FormControlComp {
24732469
// TODO(issue/24571): remove '!'.

packages/forms/test/template_integration_spec.ts

+1-7
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {ComponentFixture, TestBed, async, fakeAsync, tick} from '@angular/core/t
1111
import {AbstractControl, AsyncValidator, COMPOSITION_BUFFER_MODE, FormControl, FormsModule, NG_ASYNC_VALIDATORS, NgForm, NgFormSelectorWarning, NgModel} from '@angular/forms';
1212
import {By} from '@angular/platform-browser/src/dom/debug/by';
1313
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
14-
import {dispatchEvent} from '@angular/platform-browser/testing/src/browser_util';
14+
import {dispatchEvent, sortedClassList} from '@angular/platform-browser/testing/src/browser_util';
1515
import {merge} from 'rxjs';
1616

1717
import {NgModelCustomComp, NgModelCustomWrapper} from './value_accessor_integration_spec';
@@ -1924,9 +1924,3 @@ class NgModelChangesForm {
19241924
class NgModelChangeState {
19251925
onNgModelChange = () => {};
19261926
}
1927-
1928-
function sortedClassList(el: HTMLElement) {
1929-
const l = getDOM().classList(el);
1930-
l.sort();
1931-
return l;
1932-
}

packages/platform-browser/src/browser/browser_adapter.ts

+1-8
Original file line numberDiff line numberDiff line change
@@ -196,12 +196,8 @@ export class BrowserDomAdapter extends GenericBrowserDomAdapter {
196196
getElementsByTagName(element: any, name: string): HTMLElement[] {
197197
return element.getElementsByTagName(name);
198198
}
199-
classList(element: any): any[] { return Array.prototype.slice.call(element.classList, 0); }
200199
addClass(element: any, className: string) { element.classList.add(className); }
201200
removeClass(element: any, className: string) { element.classList.remove(className); }
202-
hasClass(element: any, className: string): boolean {
203-
return element.classList.contains(className);
204-
}
205201
setStyle(element: any, styleName: string, styleValue: string) {
206202
element.style[styleName] = styleValue;
207203
}
@@ -210,11 +206,8 @@ export class BrowserDomAdapter extends GenericBrowserDomAdapter {
210206
// see https://github.com/angular/angular/issues/7916
211207
element.style[stylename] = '';
212208
}
209+
213210
getStyle(element: any, stylename: string): string { return element.style[stylename]; }
214-
hasStyle(element: any, styleName: string, styleValue?: string|null): boolean {
215-
const value = this.getStyle(element, styleName) || '';
216-
return styleValue ? value == styleValue : value.length > 0;
217-
}
218211

219212
getAttribute(element: Element, attribute: string): string|null {
220213
return element.getAttribute(attribute);

packages/platform-browser/src/dom/dom_adapter.ts

+5-8
Original file line numberDiff line numberDiff line change
@@ -80,19 +80,16 @@ export abstract class DomAdapter {
8080
abstract getDistributedNodes(el: any): Node[];
8181
abstract clone /*<T extends Node>*/ (node: Node /*T*/): Node /*T*/;
8282
abstract getElementsByTagName(element: any, name: string): HTMLElement[];
83-
abstract classList(element: any): any[];
84-
abstract addClass(element: any, className: string): any;
85-
abstract removeClass(element: any, className: string): any;
86-
abstract hasClass(element: any, className: string): boolean;
87-
abstract setStyle(element: any, styleName: string, styleValue: string): any;
88-
abstract removeStyle(element: any, styleName: string): any;
89-
abstract getStyle(element: any, styleName: string): string;
90-
abstract hasStyle(element: any, styleName: string, styleValue?: string): boolean;
9183

9284
// Used by Meta
9385
abstract getAttribute(element: any, attribute: string): string|null;
9486

9587
// Used by platform-server
88+
abstract addClass(element: any, className: string): any;
89+
abstract removeClass(element: any, className: string): any;
90+
abstract getStyle(element: any, styleName: string): any;
91+
abstract setStyle(element: any, styleName: string, styleValue: string): any;
92+
abstract removeStyle(element: any, styleName: string): any;
9693
abstract setAttribute(element: any, name: string, value: string): any;
9794
abstract setAttributeNS(element: any, ns: string, name: string, value: string): any;
9895
abstract removeAttribute(element: any, attribute: string): any;

packages/platform-browser/testing/src/browser_util.ts

+13
Original file line numberDiff line numberDiff line change
@@ -199,3 +199,16 @@ export function setCookie(name: string, value: string) {
199199
export function supportsWebAnimation(): boolean {
200200
return typeof(<any>Element).prototype['animate'] === 'function';
201201
}
202+
203+
export function hasStyle(element: any, styleName: string, styleValue?: string | null): boolean {
204+
const value = element.style[styleName] || '';
205+
return styleValue ? value == styleValue : value.length > 0;
206+
}
207+
208+
export function hasClass(element: any, className: string): boolean {
209+
return element.classList.contains(className);
210+
}
211+
212+
export function sortedClassList(element: any): any[] {
213+
return Array.prototype.slice.call(element.classList, 0).sort();
214+
}

packages/platform-browser/testing/src/matchers.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
import {Type, ɵglobal as global} from '@angular/core';
1111
import {ComponentFixture} from '@angular/core/testing';
1212
import {By, ɵgetDOM as getDOM} from '@angular/platform-browser';
13-
import {isCommentNode} from './browser_util';
13+
14+
import {hasClass, hasStyle, isCommentNode} from './browser_util';
1415

1516

1617

@@ -186,7 +187,7 @@ _global.beforeEach(function() {
186187
function buildError(isNot: boolean) {
187188
return function(actual: any, className: string) {
188189
return {
189-
pass: getDOM().hasClass(actual, className) == !isNot,
190+
pass: hasClass(actual, className) == !isNot,
190191
get message() {
191192
return `Expected ${actual.outerHTML} ${isNot ? 'not ' : ''}to contain the CSS class "${className}"`;
192193
}
@@ -200,12 +201,11 @@ _global.beforeEach(function() {
200201
compare: function(actual: any, styles: {[k: string]: string}|string) {
201202
let allPassed: boolean;
202203
if (typeof styles === 'string') {
203-
allPassed = getDOM().hasStyle(actual, styles);
204+
allPassed = hasStyle(actual, styles);
204205
} else {
205206
allPassed = Object.keys(styles).length !== 0;
206-
Object.keys(styles).forEach(prop => {
207-
allPassed = allPassed && getDOM().hasStyle(actual, prop, styles[prop]);
208-
});
207+
Object.keys(styles).forEach(
208+
prop => { allPassed = allPassed && hasStyle(actual, prop, styles[prop]); });
209209
}
210210

211211
return {

packages/platform-server/src/domino_adapter.ts

+2-4
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ export class DominoAdapter extends BrowserDomAdapter {
162162
}
163163
element.setAttribute('style', styleAttrValue);
164164
}
165+
165166
setStyle(element: any, styleName: string, styleValue?: string|null) {
166167
styleName = styleName.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
167168
const styleMap = this._readStyleAttribute(element);
@@ -173,14 +174,11 @@ export class DominoAdapter extends BrowserDomAdapter {
173174
// see https://github.com/angular/angular/issues/7916
174175
this.setStyle(element, styleName, '');
175176
}
177+
176178
getStyle(element: any, styleName: string): string {
177179
const styleMap = this._readStyleAttribute(element);
178180
return styleMap[styleName] || '';
179181
}
180-
hasStyle(element: any, styleName: string, styleValue?: string): boolean {
181-
const value = this.getStyle(element, styleName);
182-
return styleValue ? value == styleValue : value.length > 0;
183-
}
184182

185183
dispatchEvent(el: Node, evt: any) {
186184
el.dispatchEvent(evt);

packages/platform-webworker/src/web_workers/worker/worker_adapter.ts

-5
Original file line numberDiff line numberDiff line change
@@ -89,16 +89,11 @@ export class WorkerDomAdapter extends DomAdapter {
8989
getDistributedNodes(el: any): Node[] { throw 'not implemented'; }
9090
clone(node: Node): Node { throw 'not implemented'; }
9191
getElementsByTagName(element: any, name: string): HTMLElement[] { throw 'not implemented'; }
92-
classList(element: any): any[] { throw 'not implemented'; }
9392
addClass(element: any, className: string) { throw 'not implemented'; }
9493
removeClass(element: any, className: string) { throw 'not implemented'; }
95-
hasClass(element: any, className: string): boolean { throw 'not implemented'; }
9694
setStyle(element: any, styleName: string, styleValue: string) { throw 'not implemented'; }
9795
removeStyle(element: any, styleName: string) { throw 'not implemented'; }
9896
getStyle(element: any, styleName: string): string { throw 'not implemented'; }
99-
hasStyle(element: any, styleName: string, styleValue?: string): boolean {
100-
throw 'not implemented';
101-
}
10297
getAttribute(element: any, attribute: string): string { throw 'not implemented'; }
10398
setAttribute(element: any, name: string, value: string) { throw 'not implemented'; }
10499
setAttributeNS(element: any, ns: string, name: string, value: string) { throw 'not implemented'; }

packages/platform-webworker/test/web_workers/worker/renderer_v2_integration_spec.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {platformBrowserDynamicTesting} from '@angular/platform-browser-dynamic/t
1212
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
1313
import {DomRendererFactory2} from '@angular/platform-browser/src/dom/dom_renderer';
1414
import {BrowserTestingModule} from '@angular/platform-browser/testing';
15-
import {browserDetection, dispatchEvent} from '@angular/platform-browser/testing/src/browser_util';
15+
import {browserDetection, dispatchEvent, hasClass} from '@angular/platform-browser/testing/src/browser_util';
1616
import {expect} from '@angular/platform-browser/testing/src/matchers';
1717
import {ClientMessageBrokerFactory} from '@angular/platform-webworker/src/web_workers/shared/client_message_broker';
1818
import {RenderStore} from '@angular/platform-webworker/src/web_workers/shared/render_store';
@@ -109,10 +109,10 @@ let lastCreatedRenderer: Renderer2;
109109
expect(el.tabIndex).toEqual(1);
110110

111111
lastCreatedRenderer.addClass(workerEl, 'a');
112-
expect(getDOM().hasClass(el, 'a')).toBe(true);
112+
expect(hasClass(el, 'a')).toBe(true);
113113

114114
lastCreatedRenderer.removeClass(workerEl, 'a');
115-
expect(getDOM().hasClass(el, 'a')).toBe(false);
115+
expect(hasClass(el, 'a')).toBe(false);
116116

117117
lastCreatedRenderer.setStyle(workerEl, 'width', '10px');
118118
expect(getDOM().getStyle(el, 'width')).toEqual('10px');

0 commit comments

Comments
 (0)