Skip to content

feat: add testing utilities for components #2943

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 27, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 19 additions & 32 deletions src/lib/autocomplete/autocomplete.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import {FakeViewportRuler} from '../core/overlay/position/fake-viewport-ruler';
import {MdAutocomplete} from './autocomplete';
import {MdInputContainer} from '../input/input-container';
import {Observable} from 'rxjs/Observable';
import {dispatchFakeEvent} from '../core/testing/dispatch-events';

import 'rxjs/add/operator/map';

describe('MdAutocomplete', () => {
Expand Down Expand Up @@ -63,7 +65,7 @@ describe('MdAutocomplete', () => {
expect(fixture.componentInstance.trigger.panelOpen)
.toBe(false, `Expected panel state to start out closed.`);

dispatchEvent('focus', input);
dispatchFakeEvent(input, 'focus');
fixture.detectChanges();

expect(fixture.componentInstance.trigger.panelOpen)
Expand All @@ -90,11 +92,11 @@ describe('MdAutocomplete', () => {
});

it('should close the panel when blurred', async(() => {
dispatchEvent('focus', input);
dispatchFakeEvent(input, 'focus');
fixture.detectChanges();

fixture.whenStable().then(() => {
dispatchEvent('blur', input);
dispatchFakeEvent(input, 'blur');
fixture.detectChanges();

expect(fixture.componentInstance.trigger.panelOpen)
Expand All @@ -105,7 +107,7 @@ describe('MdAutocomplete', () => {
}));

it('should close the panel when an option is clicked', async(() => {
dispatchEvent('focus', input);
dispatchFakeEvent(input, 'focus');
fixture.detectChanges();

fixture.whenStable().then(() => {
Expand All @@ -121,7 +123,7 @@ describe('MdAutocomplete', () => {
}));

it('should close the panel when a newly created option is clicked', async(() => {
dispatchEvent('focus', input);
dispatchFakeEvent(input, 'focus');
fixture.detectChanges();

fixture.whenStable().then(() => {
Expand Down Expand Up @@ -166,7 +168,7 @@ describe('MdAutocomplete', () => {
});

it('should hide the panel when the options list is empty', async(() => {
dispatchEvent('focus', input);
dispatchFakeEvent(input, 'focus');

fixture.whenStable().then(() => {
fixture.detectChanges();
Expand Down Expand Up @@ -214,7 +216,7 @@ describe('MdAutocomplete', () => {
.toBe(false, `Expected panel state to start out closed.`);

input.value = 'Alabama';
dispatchEvent('input', input);
dispatchFakeEvent(input, 'input');
fixture.detectChanges();

expect(fixture.componentInstance.trigger.panelOpen)
Expand Down Expand Up @@ -467,7 +469,7 @@ describe('MdAutocomplete', () => {
expect(fixture.componentInstance.stateCtrl.touched)
.toBe(false, `Expected control to start out untouched.`);

dispatchEvent('blur', input);
dispatchFakeEvent(input, 'blur');
fixture.detectChanges();

expect(fixture.componentInstance.stateCtrl.touched)
Expand All @@ -487,8 +489,8 @@ describe('MdAutocomplete', () => {
fixture.detectChanges();

input = fixture.debugElement.query(By.css('input')).nativeElement;
DOWN_ARROW_EVENT = new FakeKeyboardEvent(DOWN_ARROW) as KeyboardEvent;
ENTER_EVENT = new FakeKeyboardEvent(ENTER) as KeyboardEvent;
DOWN_ARROW_EVENT = new MockKeyboardEvent(DOWN_ARROW) as KeyboardEvent;
ENTER_EVENT = new MockKeyboardEvent(ENTER) as KeyboardEvent;

fixture.componentInstance.trigger.openPanel();
fixture.detectChanges();
Expand Down Expand Up @@ -549,7 +551,7 @@ describe('MdAutocomplete', () => {
const optionEls =
overlayContainerElement.querySelectorAll('md-option') as NodeListOf<HTMLElement>;

const UP_ARROW_EVENT = new FakeKeyboardEvent(UP_ARROW) as KeyboardEvent;
const UP_ARROW_EVENT = new MockKeyboardEvent(UP_ARROW) as KeyboardEvent;
fixture.componentInstance.trigger._handleKeydown(UP_ARROW_EVENT);

fixture.whenStable().then(() => {
Expand Down Expand Up @@ -615,7 +617,7 @@ describe('MdAutocomplete', () => {
typeInElement('New', input);
fixture.detectChanges();

const SPACE_EVENT = new FakeKeyboardEvent(SPACE) as KeyboardEvent;
const SPACE_EVENT = new MockKeyboardEvent(SPACE) as KeyboardEvent;
fixture.componentInstance.trigger._handleKeydown(DOWN_ARROW_EVENT);
fixture.componentInstance.trigger._handleKeydown(SPACE_EVENT);
fixture.detectChanges();
Expand Down Expand Up @@ -724,7 +726,7 @@ describe('MdAutocomplete', () => {
expect(input.hasAttribute('aria-activedescendant'))
.toBe(false, 'Expected aria-activedescendant to be absent if no active item.');

const DOWN_ARROW_EVENT = new FakeKeyboardEvent(DOWN_ARROW) as KeyboardEvent;
const DOWN_ARROW_EVENT = new MockKeyboardEvent(DOWN_ARROW) as KeyboardEvent;
fixture.componentInstance.trigger._handleKeydown(DOWN_ARROW_EVENT);
fixture.detectChanges();

Expand Down Expand Up @@ -866,7 +868,7 @@ describe('MdAutocomplete', () => {
fixture.detectChanges();

const input = fixture.debugElement.query(By.css('input')).nativeElement;
dispatchEvent('focus', input);
dispatchFakeEvent(input, 'focus');
fixture.detectChanges();

expect(fixture.componentInstance.trigger.panelOpen)
Expand Down Expand Up @@ -995,35 +997,20 @@ class AutocompleteWithoutForms {

}

/**
* TODO: Move this to core testing utility until Angular has event faking
* support.
*
* Dispatches an event from an element.
* @param eventName Name of the event
* @param element The element from which the event will be dispatched.
*/
function dispatchEvent(eventName: string, element: HTMLElement): void {
let event = document.createEvent('Event');
event.initEvent(eventName, true, true);
element.dispatchEvent(event);
}


/**
* Focuses an input, sets its value and dispatches
* the `input` event, simulating the user typing.
* @param value Value to be set on the input.
* @param element Element onto which to set the value.
*/
function typeInElement(value: string, element: HTMLInputElement) {
function typeInElement(value: string, element: HTMLInputElement, autoFocus = true) {
element.focus();
element.value = value;
dispatchEvent('input', element);
dispatchFakeEvent(element, 'input');
}

/** This is a mock keyboard event to test keyboard events in the autocomplete. */
class FakeKeyboardEvent {
class MockKeyboardEvent {
constructor(public keyCode: number) {}
preventDefault() {}
}
8 changes: 1 addition & 7 deletions src/lib/checkbox/checkbox.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {By} from '@angular/platform-browser';
import {MdCheckbox, MdCheckboxChange, MdCheckboxModule} from './checkbox';
import {ViewportRuler} from '../core/overlay/position/viewport-ruler';
import {FakeViewportRuler} from '../core/overlay/position/fake-viewport-ruler';
import {dispatchFakeEvent} from '../core/testing/dispatch-events';


describe('MdCheckbox', () => {
Expand Down Expand Up @@ -785,10 +786,3 @@ class CheckboxWithChangeEvent {
class CheckboxWithFormControl {
formControl = new FormControl();
}

// TODO(devversion): replace with global utility once pull request #2943 is merged.
function dispatchFakeEvent(element: HTMLElement, eventName: string): void {
let event = document.createEvent('Event');
event.initEvent(eventName, true, true);
element.dispatchEvent(event);
}
5 changes: 2 additions & 3 deletions src/lib/core/overlay/scroll/scroll-dispatcher.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {NgModule, Component, ViewChild, ElementRef} from '@angular/core';
import {ScrollDispatcher} from './scroll-dispatcher';
import {OverlayModule} from '../overlay-directives';
import {Scrollable} from './scrollable';
import {dispatchFakeEvent} from '../../testing/dispatch-events';

describe('Scroll Dispatcher', () => {

Expand Down Expand Up @@ -53,9 +54,7 @@ describe('Scroll Dispatcher', () => {
// Emit a scroll event from the scrolling element in our component.
// This event should be picked up by the scrollable directive and notify.
// The notification should be picked up by the service.
const scrollEvent = document.createEvent('UIEvents');
scrollEvent.initUIEvent('scroll', true, true, window, 0);
fixture.componentInstance.scrollingElement.nativeElement.dispatchEvent(scrollEvent);
dispatchFakeEvent(fixture.componentInstance.scrollingElement.nativeElement, 'scroll');

// The scrollable directive should have notified the service immediately.
expect(hasDirectiveScrollNotified).toBe(true);
Expand Down
Loading